Update to v4.2.1

Change-Id: I47cef2be94299220d80265d949a95b58eee2c23b
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..57d88b9
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,523 @@
+name: CI
+
+on:
+  push:
+    paths-ignore:
+      - 'CHANGES*'
+      - 'Doc/**'
+      - 'appveyor.yml'
+  pull_request:
+    branches: master
+    paths-ignore:
+      - 'CHANGES*'
+      - 'Doc/**'
+      - 'appveyor.yml'
+
+permissions:
+  contents: read
+
+jobs:
+  build:
+
+    # When continue-on-error is true for an individual build, that build can fail (it'll show red),
+    # but it won't fail the overall build
+    continue-on-error: ${{ matrix.continue-on-error || false }}
+
+    runs-on: ${{ matrix.os || 'ubuntu-20.04' }}
+
+    # By default, the name of the build is the language used and SWIG options, but matrix entries
+    # can define the additional "desc" field with any additional information to include in the name.
+    name: ${{ matrix.SWIGLANG || 'none' }}${{ matrix.PY2 }} ${{ matrix.ENGINE}} ${{ matrix.VER }} ${{ matrix.SWIG_FEATURES }} ${{ (matrix.compiler || 'gcc') }}${{ matrix.GCC }} ${{ matrix.CPPSTD }} ${{ matrix.CSTD }} ${{ matrix.EXTRA_CXXFLAGS }} ${{ matrix.desc }} ${{ matrix.continue-on-error && '(can fail)' }}
+
+    strategy:
+      matrix:
+        include:
+        - SWIGLANG: ""
+          CPPFLAGS: "-DDOH_POISON"
+        - SWIGLANG: ""
+          GCC: 7
+          CPPSTD: c++98
+          CSTD: c90
+        - SWIGLANG: ""
+          GCC: 7
+        - SWIGLANG: ""
+          GCC: 8
+        - SWIGLANG: ""
+          GCC: 9
+        - SWIGLANG: ""
+          GCC: 10
+        - SWIGLANG: ""
+          GCC: 11
+        - SWIGLANG: ""
+          GCC: 12
+          os: ubuntu-22.04
+        - SWIGLANG: ""
+          GCC: 13
+          os: ubuntu-22.04
+        - SWIGLANG: ""
+          compiler: clang
+          os: ubuntu-22.04
+        - SWIGLANG: csharp
+        - SWIGLANG: d
+          VER: 'ldc'
+          CPPSTD: c++14
+        - SWIGLANG: d
+          VER: 'gdmd'
+          CPPSTD: c++11
+        - SWIGLANG: d
+          VER: '2.103.1'
+          CPPSTD: c++17
+        - SWIGLANG: go
+          VER: '1.6'
+          CSTD: gnu11
+        - SWIGLANG: go
+          VER: '1.8'
+        - SWIGLANG: go
+          VER: '1.12'
+          CSTD: gnu11
+        - SWIGLANG: go
+          VER: '1.17'
+        - SWIGLANG: guile
+        - SWIGLANG: guile
+          VER: '2.2'
+        - SWIGLANG: guile
+          VER: '3.0'
+        - SWIGLANG: java
+        - SWIGLANG: javascript
+          ENGINE: jsc
+          VER: '4.0'
+        - SWIGLANG: javascript
+          ENGINE: napi
+          VER: '18'
+          CPPSTD: c++11
+        #- SWIGLANG: javascript
+        #  ENGINE: node
+        #  VER: '6'
+        #  CPPSTD: c++11
+        #  os: ubuntu-18.04
+        #- SWIGLANG: javascript
+        #  ENGINE: node
+        #  VER: '8'
+        #  CPPSTD: c++11
+        #  os: ubuntu-18.04
+        #- SWIGLANG: javascript
+        #  ENGINE: node
+        #  VER: '10'
+        #  CPPSTD: c++11
+        #  os: ubuntu-18.04
+        - SWIGLANG: javascript
+          ENGINE: node
+          VER: '12'
+          CPPSTD: c++11
+        - SWIGLANG: lua
+        - SWIGLANG: lua
+          VER: '5.3'
+        - SWIGLANG: octave
+          CPPSTD: c++11
+        - SWIGLANG: octave
+          os: ubuntu-22.04 # Octave 6.4.0
+          CPPSTD: c++11
+        - SWIGLANG: perl5
+        - SWIGLANG: php
+          VER: '8.0'
+        - SWIGLANG: php
+          VER: '8.1'
+        - SWIGLANG: php
+          VER: '8.2'
+        - SWIGLANG: php
+          VER: '8.3'
+        - SWIGLANG: python
+          PY2: 2
+        #- SWIGLANG: python
+        #  VER: '3.3'
+        #  os: ubuntu-18.04 # Python < 3.5 not available for 20.04.
+        #- SWIGLANG: python
+        #  VER: '3.4'
+        #  os: ubuntu-18.04 # Python < 3.5 not available for 20.04.
+        - SWIGLANG: python
+          VER: '3.5'
+        - SWIGLANG: python
+          VER: '3.6'
+        - SWIGLANG: python
+          VER: '3.7'
+        - SWIGLANG: python
+          VER: '3.8'
+        - SWIGLANG: python
+          VER: '3.9'
+        - SWIGLANG: python
+          VER: '3.10'
+        - SWIGLANG: python
+          VER: '3.11'
+        - SWIGLANG: python
+          VER: '3.12'
+          CSTD: gnu99
+        - SWIGLANG: python
+          PY2: 2
+          SWIG_FEATURES: -builtin
+        - SWIGLANG: python
+          PY2: 2
+          SWIG_FEATURES: -builtin -O
+        - SWIGLANG: python
+          SWIG_FEATURES: -builtin
+        - SWIGLANG: python
+          SWIG_FEATURES: -builtin -O
+        - SWIGLANG: python
+          EXTRA_CXXFLAGS: -DPy_LIMITED_API=0x03040000
+          CPPSTD: c++20
+          GCC: 13
+          os: ubuntu-22.04
+        - SWIGLANG: r
+        - SWIGLANG: ruby
+          VER: '2.0'
+        - SWIGLANG: ruby
+          VER: '2.1'
+        - SWIGLANG: ruby
+          VER: '2.2'
+        - SWIGLANG: ruby
+          VER: '2.3'
+        - SWIGLANG: ruby
+          VER: '2.4'
+        - SWIGLANG: ruby
+          VER: '2.5'
+        - SWIGLANG: ruby
+          VER: '2.6'
+        - SWIGLANG: ruby
+          VER: '2.7'
+        - SWIGLANG: ruby
+          VER: '3.0'
+          CPPSTD: c++11
+        - SWIGLANG: ruby
+          VER: '3.1'
+          CPPSTD: c++11
+        - SWIGLANG: ruby
+          CPPSTD: c++11
+          VER: '3.2.2' # import_fragments testcase started to fail on upgrade to 3.2.3, see https://github.com/swig/swig/issues/2800
+        - SWIGLANG: scilab
+          VER: '5.5.2'
+        - SWIGLANG: scilab
+          VER: '6.0.2'
+        - SWIGLANG: scilab
+          os: ubuntu-22.04 # scilab 6.1.1
+        - SWIGLANG: scilab
+          VER: '2023.0.0'
+        - SWIGLANG: tcl
+        # c++11 testing
+        - SWIGLANG: csharp
+          CPPSTD: c++11
+        - SWIGLANG: go
+          VER: '1.17'
+          CPPSTD: c++11
+          CSTD: gnu11
+        - SWIGLANG: guile
+          CPPSTD: c++11
+        - SWIGLANG: java
+          CPPSTD: c++11
+        - SWIGLANG: javascript
+          ENGINE: jsc
+          VER: '4.1'
+          os: ubuntu-22.04
+          CPPSTD: c++11
+        - SWIGLANG: javascript
+          ENGINE: node
+          VER: '14'
+          CPPSTD: c++11
+        - SWIGLANG: lua
+          CPPSTD: c++11
+        - SWIGLANG: perl5
+          CPPSTD: c++11
+        - SWIGLANG: php
+          CPPSTD: c++11
+          CSTD: gnu11
+        - SWIGLANG: python
+          CPPSTD: c++11
+        - SWIGLANG: r
+          CPPSTD: c++11
+        - SWIGLANG: ruby
+          CPPSTD: c++11
+          VER: '3.3'
+        - SWIGLANG: ruby
+          CPPSTD: c++11
+        - SWIGLANG: scilab
+          CPPSTD: c++11
+        - SWIGLANG: tcl
+          CPPSTD: c++11
+        # c++14 testing
+        - SWIGLANG: csharp
+          CPPSTD: c++14
+        - SWIGLANG: go
+          VER: '1.17'
+          CPPSTD: c++14
+          CSTD: gnu11
+        - SWIGLANG: guile
+          CPPSTD: c++14
+        - SWIGLANG: java
+          CPPSTD: c++14
+        - SWIGLANG: javascript
+          ENGINE: node
+          VER: '16'
+          CPPSTD: c++14
+        - SWIGLANG: lua
+          CPPSTD: c++14
+        - SWIGLANG: octave
+          CPPSTD: c++14
+        - SWIGLANG: perl5
+          CPPSTD: c++14
+        - SWIGLANG: php
+          CPPSTD: c++14
+          CSTD: gnu11
+        - SWIGLANG: python
+          CPPSTD: c++14
+        - SWIGLANG: r
+          CPPSTD: c++14
+        - SWIGLANG: ruby
+          CPPSTD: c++14
+        - SWIGLANG: scilab
+          CPPSTD: c++14
+        - SWIGLANG: tcl
+          CPPSTD: c++14
+        # c++17 testing (using gcc13)
+        - SWIGLANG: csharp
+          CPPSTD: c++17
+          GCC: 13
+        - SWIGLANG: go
+          VER: '1.17'
+          CPPSTD: c++17
+          GCC: 13
+          CSTD: gnu17
+        - SWIGLANG: guile
+          CPPSTD: c++17
+          GCC: 13
+        - SWIGLANG: java
+          CPPSTD: c++17
+          GCC: 13
+        - SWIGLANG: javascript
+          ENGINE: node
+          VER: '18'
+          CPPSTD: c++17
+          GCC: 13
+        - SWIGLANG: lua
+          CPPSTD: c++17
+          GCC: 13
+        - SWIGLANG: octave
+          CPPSTD: c++17
+          GCC: 13
+        - SWIGLANG: perl5
+          CPPSTD: c++17
+          GCC: 13
+        - SWIGLANG: php
+          CPPSTD: c++17
+          CSTD: gnu17
+          GCC: 13
+        - SWIGLANG: python
+          CPPSTD: c++17
+          GCC: 13
+        - SWIGLANG: r
+          CPPSTD: c++17
+          GCC: 13
+        - SWIGLANG: ruby
+          CPPSTD: c++17
+          GCC: 13
+        - SWIGLANG: scilab
+          CPPSTD: c++17
+          GCC: 13
+        - SWIGLANG: tcl
+          CPPSTD: c++17
+          GCC: 13
+        # c++20 testing (using gcc13)
+        - SWIGLANG: python
+          CPPSTD: c++20
+          GCC: 13
+          os: ubuntu-22.04
+        - SWIGLANG: javascript
+          ENGINE: napi
+          VER: '20'
+          CPPSTD: c++20
+          GCC: 13
+          os: ubuntu-22.04
+        - SWIGLANG: javascript
+          ENGINE: node
+          VER: '20'
+          CPPSTD: c++20
+          GCC: 13
+          os: ubuntu-22.04
+        # Experimental languages (these are allowed to fail)
+        - SWIGLANG: mzscheme
+          continue-on-error: true
+        - SWIGLANG: ocaml
+          CPPSTD: c++17
+          GCC: 13
+          os: ubuntu-22.04 # ocaml-4.08 in ubuntu-20.04 doesn't work
+          continue-on-error: true
+      # Run all of them, as opposed to aborting when one fails
+      fail-fast: false
+
+    env:
+      SWIGLANG: ${{ matrix.SWIGLANG }}
+      PY2: ${{ matrix.PY2 }}
+      VER: ${{ matrix.VER }}
+      ENGINE: ${{ matrix.ENGINE }}
+      SWIG_FEATURES: ${{ matrix.SWIG_FEATURES }}
+      GCC: ${{ matrix.GCC }}
+      CSTD: ${{ matrix.CSTD }}
+      CPPSTD: ${{ matrix.CPPSTD }}
+      CPPFLAGS: ${{ matrix.CPPFLAGS }}
+      EXTRA_CXXFLAGS: ${{ matrix.EXTRA_CXXFLAGS }}
+
+    steps:
+    - name: Machine Info
+      run: |
+          echo "nproc..."
+          nproc --all
+          echo "uname..."
+          uname --all
+          echo "meminfo..."
+          cat /proc/meminfo
+          echo "lsb-release..."
+          cat /etc/lsb-release
+
+    - name: Checkout
+      uses: actions/checkout@v4
+      with:
+        show-progress: false
+        submodules: recursive
+
+    - name: Install CCache
+      uses: hendrikmuhs/ccache-action@v1
+      with:
+        key: ${{ matrix.os || 'ubuntu-20.04' }}-${{ matrix.compiler || 'gcc' }}${{ matrix.GCC }}
+
+# Uncomment to debug via ssh, see https://github.com/mxschmitt/action-tmate
+#    - name: Setup tmate session
+#      uses: mxschmitt/action-tmate@v3
+
+    - name: Install Dependencies
+      run: |
+          set -x
+          export PATH="/usr/lib/ccache:/usr/local/opt/ccache/libexec:$PATH"
+          echo PATH="$PATH" >> $GITHUB_ENV
+
+          source $GITHUB_WORKSPACE/Tools/GHA-linux-install.sh
+          echo WITHLANG="$WITHLANG" >> $GITHUB_ENV
+
+          case $(uname) in
+              Linux)
+                  cpu_count=$(nproc)
+                  ;;
+
+              Darwin)
+                  cpu_count=$(sysctl -n hw.ncpu)
+                  ;;
+
+              *)
+                  cpu_count=1
+                  ;;
+          esac
+
+          if [[ $cpu_count != 1 ]]; then
+            echo SWIGJOBS=-j$cpu_count >> $GITHUB_ENV
+          fi
+
+          if test '${{ matrix.compiler }}' = 'clang'; then
+            CC="clang"
+            CXX="clang++"
+
+            CFLAGS="$CFLAGS -fPIE"
+            CXXFLAGS="$CXXFLAGS -fPIE"
+          elif test -n "$GCC"; then
+            CC="gcc-$GCC"
+            CXX="g++-$GCC"
+          else
+            CC="gcc"
+            CXX="g++"
+          fi
+
+          export CC CXX
+
+          echo CC="$CC" >> $GITHUB_ENV
+          echo CXX="$CXX" >> $GITHUB_ENV
+
+          ls -la $(which $CC) $(which $CXX)
+          $CC --version
+          $CXX --version
+
+    - name: Configure
+      run: |
+          source $GITHUB_WORKSPACE/Tools/CI-linux-environment.sh
+          set -x
+
+          if [[ -z "$CSTD" ]]; then
+            case "$CPPSTD" in
+              c++11) export CSTD=c11 ;;
+              c++14) export CSTD=c11 ;;
+              c++17) export CSTD=c17 ;;
+              c++20) export CSTD=c17 ;;
+            esac
+            echo CSTD="$CSTD" >> $GITHUB_ENV
+          fi
+          if test -z "$CPPSTD"; then CONFIGOPTS+=("--disable-cpp11-testing"); fi
+          if test -n "$CPPSTD"; then CONFIGOPTS+=("CXXFLAGS=-std=$CPPSTD $CXXFLAGS"); fi
+          if test -n "$CSTD"; then CONFIGOPTS+=("CFLAGS=-std=$CSTD $CFLAGS"); fi
+          if test -n "$SWIGLANG"; then CONFIGOPTS+=(--without-alllang --with-$WITHLANG); fi
+          echo "${CONFIGOPTS[@]}"
+          ./autogen.sh && mkdir -p build/build && cd build/build && ../../configure "${CONFIGOPTS[@]}"
+
+    - name: Build
+      working-directory: build/build
+      run: |
+          set -x
+          make -s $SWIGJOBS
+          ./swig -version && ./swig -pcreversion
+
+    - name: Test
+      working-directory: build/build
+      run: |
+          source $GITHUB_WORKSPACE/Tools/CI-linux-environment.sh
+          set -x
+
+          if test -z "$SWIGLANG"; then
+            make $SWIGJOBS check-ccache
+            make $SWIGJOBS check-errors-test-suite
+          else
+            case "$SWIGLANG" in
+              javascript)
+                case "$ENGINE" in
+                  v8 | jsc)
+                    # Running tests using v8 or jsc involves creating a custom
+                    # interpreter in Tools/javascript, which is currently broken
+                    # for parallel builds (we attempt to update this interpreter
+                    # while running, resulting in "Text file busy" error).
+                    unset SWIGJOBS
+                esac
+                ;;
+              ocaml)
+                # `make check-ocaml-test-suite` fails with parallel make with:
+                #
+                # File "swig.ml", line 1:
+                # Error: Could not find the .cmi file for interface swig.mli.
+                #
+                # Apparently we ought to be using `ocamldep` to generate make
+                # dependencies.
+                unset SWIGJOBS
+                ;;
+            esac
+
+            # Stricter compile flags for examples. Various headers and SWIG generated code prevents full use of -pedantic.
+            cflags="$($GITHUB_WORKSPACE/Tools/testflags.py --language $SWIGLANG --cflags --std=$CSTD --compiler=$CC) $EXTRA_CFLAGS"
+            cxxflags="$($GITHUB_WORKSPACE/Tools/testflags.py --language $SWIGLANG --cxxflags --std=$CPPSTD --compiler=$CC) $EXTRA_CXXFLAGS"
+            make check-$SWIGLANG-version
+            make check-$SWIGLANG-enabled
+            make $SWIGJOBS check-$SWIGLANG-examples CFLAGS="$cflags" CXXFLAGS="$cxxflags"
+            make $SWIGJOBS check-$SWIGLANG-test-suite CFLAGS="$cflags" CXXFLAGS="$cxxflags"
+          fi
+
+    - name: Install
+      working-directory: build/build
+      run: |
+          set -x
+          if test -z "$SWIGLANG"; then sudo make install && swig -version && ccache-swig -V; fi
+
+    - name: Clean
+      working-directory: build/build
+      run: |
+          set -x
+          make check-maintainer-clean && ../../configure
diff --git a/.github/workflows/nuget.yml b/.github/workflows/nuget.yml
new file mode 100644
index 0000000..05eb57a
--- /dev/null
+++ b/.github/workflows/nuget.yml
@@ -0,0 +1,63 @@
+name: Windows Nuget Build
+
+on:
+  push:
+    paths-ignore:
+      - 'CHANGES*'
+      - 'Doc/**'
+      - 'appveyor.yml'
+  pull_request:
+    branches: master
+    paths-ignore:
+      - 'CHANGES*'
+      - 'Doc/**'
+      - 'appveyor.yml'
+
+permissions:
+  contents: read  #  to fetch code (actions/checkout)
+
+jobs:
+  build:
+
+    runs-on: windows-2019
+
+    steps:
+    - name: Checkout
+      uses: actions/checkout@v4
+      with:
+        show-progress: false
+        submodules: recursive
+
+    - name: Install Dependencies
+      shell: powershell
+      run: |
+          nuget install CMake-win64 -Version 3.15.5 -OutputDirectory C:\Tools\CMake
+          nuget install Bison -Version 3.7.4 -OutputDirectory C:\Tools\bison
+          nuget install PCRE2 -Version 10.39 -OutputDirectory C:\Tools\pcre2
+
+    - name: Build
+      shell: powershell
+      run: |
+          $env:PATH="C:\Tools\CMake\CMake-win64.3.15.5\bin;C:\Tools\bison\Bison.3.7.4\bin;" + $env:PATH
+          $PCRE_ROOT="C:\Tools\pcre2\PCRE2.10.39.0"
+          $PCRE_PLATFORM="x64"
+          $WORKING_DIR=(Get-Location).ToString() -replace "\\","/"
+          cmake -G "Visual Studio 16 2019" -A "x64" `
+          -DCMAKE_INSTALL_PREFIX="$WORKING_DIR/install2" `
+          -DCMAKE_C_FLAGS="/DPCRE2_STATIC" `
+          -DCMAKE_CXX_FLAGS="/DPCRE2_STATIC" `
+          -DPCRE2_INCLUDE_DIR="$PCRE_ROOT/include" `
+          -DPCRE2_LIBRARY="$PCRE_ROOT/lib/pcre2-8-static.lib" `
+          -S . -B build
+          cmake --build build --config Release
+
+    - name: Install
+      shell: powershell
+      run: |
+          cmake --install build --config Release
+
+    - name: Test
+      shell: powershell
+      working-directory: install2/bin
+      run: |
+          swig.exe -version
diff --git a/.gitignore b/.gitignore
index 7063594..2e676e9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -68,7 +68,6 @@
 CCache/config.status
 CCache/config_win32.h
 Examples/Makefile
-Examples/d/example.mk
 Examples/guile/Makefile
 Examples/test-suite/*/Makefile
 Examples/xml/Makefile
@@ -81,7 +80,6 @@
 config.log
 config.status
 preinst-swig
-swig.spec
 
 # Build Artifacts
 .dirstamp
@@ -149,6 +147,8 @@
 
 # Java
 Examples/test-suite/java/*/
+Examples/test-suite/java/expected.txt
+Examples/test-suite/java/got.txt
 Examples/java/*/*.java
 !Examples/java/*/runme.java
 Examples/java/doxygen/javadocs
@@ -157,6 +157,14 @@
 Examples/test-suite/javascript/*/
 *.gyp
 
+# Lua
+Examples/lua/dual/dual
+Examples/lua/dual/swigluarun.h
+Examples/lua/embed/embed
+Examples/lua/embed2/embed2
+Examples/lua/embed3/embed3
+Examples/lua/embed3/swigluarun.h
+
 # OCaml
 Examples/test-suite/ocaml/*.ml*
 Examples/test-suite/ocaml/*.cm*
@@ -172,6 +180,8 @@
 # Octave
 swigexample*.oct
 Examples/test-suite/octave/*.oct
+Examples/test-suite/octave/octheaders.hpp
+Examples/test-suite/octave/octheaders.hpp.gch
 
 # Perl5
 Examples/test-suite/perl5/*.pm
@@ -179,11 +189,8 @@
 
 # PHP
 Examples/test-suite/php/php_*.h
-Examples/test-suite/php/*.php
-!Examples/test-suite/php/*runme.php
-!Examples/test-suite/php/skel.php
 Examples/php/*/php_*.h
-Examples/php/*/example.php
+Examples/php/pragmas/example.php
 
 # Python
 #   Based on https://github.com/github/gitignore/blob/master/Python.gitignore
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index c9cbd78..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,509 +0,0 @@
-language: cpp
-matrix:
-  include:
-    - compiler: clang
-      os: linux
-      env: SWIGLANG=
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG= GCC=4.4
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG= GCC=4.6
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG= GCC=4.7
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG= GCC=4.8
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG= GCC=4.9
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG= GCC=6
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG= GCC=7
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG= GCC=8
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG= GCC=9
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=csharp
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=d
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=go VER=1.3
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=go VER=1.8
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=go VER=1.12
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=guile
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=java
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=javascript ENGINE=node VER=0.10
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=javascript ENGINE=node VER=4 CPP11=1
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=javascript ENGINE=node VER=6 CPP11=1
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=javascript ENGINE=node VER=8 CPP11=1
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=javascript ENGINE=node VER=10 CPP11=1
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=javascript ENGINE=jsc
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=javascript ENGINE=v8
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=lua
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=lua VER=5.3
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=mzscheme
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=ocaml
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=octave SWIGJOBS=-j2
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=perl5
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=php VER=7.0
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=php VER=7.1
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=php VER=7.2
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=php VER=7.3
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=python # 2.7
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=python PY3=3 VER=3.2
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=python PY3=3 VER=3.3
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=python PY3=3 VER=3.4
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=python PY3=3 VER=3.5
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=python PY3=3 VER=3.6
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=python PY3=3 VER=3.7
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=python SWIG_FEATURES=-builtin
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=python SWIG_FEATURES="-builtin -O"
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=python SWIG_FEATURES=-builtin GCC=6 CPP11=1
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=python SWIG_FEATURES=-builtin GCC=6 CPP11=1 PY3=3 VER=3.7
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.4
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.5
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.7
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=python SWIG_FEATURES="-builtin -O" PY3=3 VER=3.7
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=python SWIG_FEATURES=-builtin PY3=3 VER=3.7 SWIGOPTPY3=
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=python SWIG_FEATURES=-O
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=python SWIG_FEATURES=-O PY3=3 VER=3.7
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=r
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=ruby VER=1.9
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=ruby VER=2.0
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=ruby VER=2.1
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=ruby VER=2.2
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=ruby VER=2.3
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=ruby VER=2.4
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=ruby VER=2.5
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=ruby VER=2.6
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=scilab
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=tcl
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=csharp CPP11=1
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=go VER=1.6 CPP11=1
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=java CPP11=1
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=octave SWIGJOBS=-j2 VER=4.4 CPP11=1
-      sudo: required
-      dist: trusty
-    - os: linux
-      env: SWIGLANG=python CPP11=1
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=r CPP11=1 # Note: making 'R CMD SHLIB' use a different compiler is non-trivial
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=ruby CPP11=1
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=tcl CPP11=1
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=csharp GCC=6 CPP14=1
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=go VER=1.6 GCC=6 CPP14=1
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=java GCC=6 CPP14=1
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=python GCC=6 CPP14=1
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=ruby GCC=6 CPP14=1
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=tcl GCC=6 CPP14=1
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=java GCC=7 CPP14=1
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=python GCC=7 CPP14=1
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=csharp GCC=8 CPP17=1
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=java GCC=8 CPP17=1
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=python GCC=8 CPP17=1 PY3=3 VER=3.7
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=csharp GCC=9 CPP17=1
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=java GCC=9 CPP17=1
-      sudo: required
-      dist: xenial
-    - os: linux
-      env: SWIGLANG=python GCC=9 CPP17=1 PY3=3 VER=3.7
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: osx
-      env: SWIGLANG=
-    - compiler: clang
-      os: osx
-      env: SWIGLANG=
-    - compiler: clang
-      os: osx
-      env: SWIGLANG=csharp
-    - compiler: clang
-      os: osx
-      env: SWIGLANG=go
-    - compiler: clang
-      os: osx
-      env: SWIGLANG=guile
-    - compiler: clang
-      os: osx
-      env: SWIGLANG=java
-    - compiler: clang
-      os: osx
-      env: SWIGLANG=lua
-    - compiler: clang
-      os: osx
-      env: SWIGLANG=octave SWIGJOBS=-j2
-    - compiler: clang
-      os: osx
-      env: SWIGLANG=perl5
-    - compiler: clang
-      os: osx
-      env: SWIGLANG=python
-    - compiler: clang
-      os: osx
-      env: SWIGLANG=python PY3=3
-    - compiler: clang
-      os: osx
-      env: SWIGLANG=ruby
-    - compiler: clang
-      os: osx
-      env: SWIGLANG=tcl
-    - compiler: clang
-      os: osx
-      env: SWIGLANG=java CPP17=1
-      osx_image: xcode10.2
-    - compiler: clang
-      os: osx
-      env: SWIGLANG=python PY3=3 CPP17=1
-      osx_image: xcode10.2
-
-  allow_failures:
-    # seg fault in director_basic testcase
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=php VER=7.2
-      sudo: required
-      dist: xenial
-    # Sometimes hits the Travis 50 minute time limit
-    - compiler: clang
-      os: osx
-      env: SWIGLANG=octave SWIGJOBS=-j2
-    # Experimental languages
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=mzscheme
-      sudo: required
-      dist: xenial
-    - compiler: gcc
-      os: linux
-      env: SWIGLANG=ocaml
-      sudo: required
-      dist: xenial
-
-before_install:
-  - date -u
-  - uname -a
-  - if test "$TRAVIS_OS_NAME" = "linux"; then lscpu && cat /proc/cpuinfo | grep "model name" && cat /proc/meminfo | grep MemTotal; fi
-  - if test "$TRAVIS_OS_NAME" = "osx"; then sysctl -a | grep brand_string; fi
-  # Travis overrides CC environment with compiler predefined values
-  - if test -n "$GCC"; then export CC="gcc-$GCC" && export CXX="g++-$GCC"; fi
-install:
-  - if test "$TRAVIS_OS_NAME" = "linux"; then source Tools/travis-linux-install.sh; fi
-  - if test "$TRAVIS_OS_NAME" = "osx"; then source Tools/travis-osx-install.sh; fi
-  - ls -la $(which $CC) $(which $CXX) && $CC --version && $CXX --version
-script:
-  - echo 'Configuring...' && echo -en 'travis_fold:start:script.1\\r'
-  - if test -n "$CPP11"; then CONFIGOPTS+=(--enable-cpp11-testing --without-maximum-compile-warnings "CXXFLAGS=-std=c++11 -Wall -Wextra" "CFLAGS=-std=c11 -Wall -Wextra") && export CSTD=c11 && export CPPSTD=c++11; fi
-  - if test -n "$CPP14"; then CONFIGOPTS+=(--enable-cpp11-testing --without-maximum-compile-warnings "CXXFLAGS=-std=c++14 -Wall -Wextra" "CFLAGS=-std=c11 -Wall -Wextra") && export CSTD=c11 && export CPPSTD=c++14; fi
-  - if test -n "$CPP17"; then CONFIGOPTS+=(--enable-cpp11-testing --without-maximum-compile-warnings "CXXFLAGS=-std=c++17 -Wall -Wextra" "CFLAGS=-std=c17 -Wall -Wextra") && export CSTD=c17 && export CPPSTD=c++17; fi
-  - if test -n "$SWIGLANG"; then CONFIGOPTS+=(--without-alllang --with-$WITHLANG); fi
-  - echo "${CONFIGOPTS[@]}"
-  - ./autogen.sh && mkdir -p build/build && cd build/build && ../../configure "${CONFIGOPTS[@]}"
-  - echo -en 'travis_fold:end:script.1\\r'
-  - make -s $SWIGJOBS
-  - ./swig -version && ./swig -pcreversion
-  - if test -z "$SWIGLANG"; then make -s $SWIGJOBS check-ccache; fi
-  - if test -z "$SWIGLANG"; then make -s $SWIGJOBS check-errors-test-suite; fi
-  - echo 'Installing...' && echo -en 'travis_fold:start:script.2\\r'
-  - if test -z "$SWIGLANG"; then sudo make -s install && swig -version && ccache-swig -V; fi
-  - echo -en 'travis_fold:end:script.2\\r'
-  # Stricter compile flags for examples. Various headers and SWIG generated code prevents full use of -pedantic.
-  - if test -n "$SWIGLANG"; then cflags=$($TRAVIS_BUILD_DIR/Tools/testflags.py --language $SWIGLANG --cflags --std=$CSTD --compiler=$CC) && echo $cflags; fi
-  - if test -n "$SWIGLANG"; then cxxflags=$($TRAVIS_BUILD_DIR/Tools/testflags.py --language $SWIGLANG --cxxflags --std=$CPPSTD --compiler=$CC) && echo $cxxflags; fi
-  - if test -n "$SWIGLANG"; then make -s check-$SWIGLANG-version; fi
-  - if test -n "$SWIGLANG"; then make check-$SWIGLANG-enabled; fi
-  - if test -n "$SWIGLANG"; then make $SWIGJOBS check-$SWIGLANG-examples CFLAGS="$cflags" CXXFLAGS="$cxxflags"; fi
-  - if test -n "$SWIGLANG"; then make $SWIGJOBS check-$SWIGLANG-test-suite CFLAGS="$cflags" CXXFLAGS="$cxxflags"; fi
-  - echo 'Cleaning...' && echo -en 'travis_fold:start:script.3\\r'
-  - make check-maintainer-clean && ../../configure $CONFIGOPTS
-  - echo -en 'travis_fold:end:script.3\\r'
diff --git a/ANNOUNCE b/ANNOUNCE
index 495f101..dfc1cf7 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,8 +1,8 @@
-*** ANNOUNCE: SWIG 4.0.1 (21 Aug 2019) ***
+*** ANNOUNCE: SWIG 4.2.1 (24 Feb 2024) ***
 
-http://www.swig.org
+https://www.swig.org
 
-We're pleased to announce SWIG-4.0.1, the latest SWIG release.
+We're pleased to announce SWIG-4.2.1, the latest SWIG release.
 
 What is SWIG?
 =============
@@ -19,20 +19,20 @@
 Release Notes
 =============
 Detailed release notes are available with the release and are also
-published on the SWIG web site at http://swig.org/release.html.
+published on the SWIG web site at https://swig.org/release.html.
 
 Availability
 ============
 The release is available for download on Sourceforge at
 
-     http://prdownloads.sourceforge.net/swig/swig-4.0.1.tar.gz
+     https://prdownloads.sourceforge.net/swig/swig-4.2.1.tar.gz
 
 A Windows version is also available at
 
-     http://prdownloads.sourceforge.net/swig/swigwin-4.0.1.zip
+     https://prdownloads.sourceforge.net/swig/swigwin-4.2.1.zip
 
 Please report problems with this release to the swig-devel mailing list,
-details at http://www.swig.org/mail.html.
+details at https://www.swig.org/mail.html.
 
 --- The SWIG Developers
 
diff --git a/Android.bp b/Android.bp
index 52636f6..c0aaea7 100644
--- a/Android.bp
+++ b/Android.bp
@@ -32,12 +32,7 @@
         "Source/Doxygen/doxytranslator.cxx",
         "Source/Doxygen/javadoc.cxx",
         "Source/Doxygen/pydoc.cxx",
-        "Source/Modules/allegrocl.cxx",
         "Source/Modules/allocate.cxx",
-        "Source/Modules/browser.cxx",
-        "Source/Modules/cffi.cxx",
-        "Source/Modules/chicken.cxx",
-        "Source/Modules/clisp.cxx",
         "Source/Modules/contract.cxx",
         "Source/Modules/csharp.cxx",
         "Source/Modules/d.cxx",
@@ -51,7 +46,6 @@
         "Source/Modules/lang.cxx",
         "Source/Modules/lua.cxx",
         "Source/Modules/main.cxx",
-        "Source/Modules/modula3.cxx",
         "Source/Modules/mzscheme.cxx",
         "Source/Modules/nested.cxx",
         "Source/Modules/ocaml.cxx",
@@ -59,16 +53,13 @@
         "Source/Modules/overload.cxx",
         "Source/Modules/perl5.cxx",
         "Source/Modules/php.cxx",
-        "Source/Modules/pike.cxx",
         "Source/Modules/python.cxx",
         "Source/Modules/r.cxx",
         "Source/Modules/ruby.cxx",
         "Source/Modules/scilab.cxx",
-        "Source/Modules/s-exp.cxx",
         "Source/Modules/swigmain.cxx",
         "Source/Modules/tcl8.cxx",
         "Source/Modules/typepass.cxx",
-        "Source/Modules/uffi.cxx",
         "Source/Modules/utils.cxx",
         "Source/Modules/xml.cxx",
         "Source/Preprocessor/cpp.c",
diff --git a/CCache/README.swig b/CCache/README.swig
index aea0f3d..82055d1 100644
--- a/CCache/README.swig
+++ b/CCache/README.swig
@@ -2,7 +2,7 @@
 debian patches 01-02, 04-14, see the debian/patches subdirectory. The ccache-win32-2.4 modifications
 to ccache-2.4 have also been merged in.
 
-Changes have been made to support cacheing the output from SWIG. The ability to cache c/c++ compiler 
+Changes have been made to support caching the output from SWIG. The ability to cache c/c++ compiler 
 output has been retained.
 
 Additional features added are the CCACHE_VERBOSE and CCACHE_SWIG environment variables, see docs.
diff --git a/CCache/ccache.c b/CCache/ccache.c
index c5c5103..48b16ee 100644
--- a/CCache/ccache.c
+++ b/CCache/ccache.c
@@ -735,13 +735,15 @@
 	}
 
 	/* send the cpp stderr, if applicable */
-	fd_cpp_stderr = open(cpp_stderr, O_RDONLY | O_BINARY);
-	if (fd_cpp_stderr != -1) {
-		copy_fd(fd_cpp_stderr, 2);
-		close(fd_cpp_stderr);
-		unlink(cpp_stderr);
-		free(cpp_stderr);
-		cpp_stderr = NULL;
+	if (cpp_stderr) {
+		fd_cpp_stderr = open(cpp_stderr, O_RDONLY | O_BINARY);
+		if (fd_cpp_stderr != -1) {
+			copy_fd(fd_cpp_stderr, 2);
+			close(fd_cpp_stderr);
+			unlink(cpp_stderr);
+			free(cpp_stderr);
+			cpp_stderr = NULL;
+		}
 	}
 
 	/* send the stderr */
@@ -1089,7 +1091,7 @@
 				}
 				*p = 0;
 			}
-			else  {
+			else {
 				int len = p - default_depfile_name;
 				
 				p = x_malloc(len + 3);
diff --git a/CCache/ccache.yo b/CCache/ccache.yo
index 2477662..fd5ba89 100644
--- a/CCache/ccache.yo
+++ b/CCache/ccache.yo
@@ -409,7 +409,7 @@
 
 If you wish to report a problem or make a suggestion then please email
 the SWIG developers on the swig-devel mailing list, see
-url(http://www.swig.org/mail.html)(http://www.swig.org/mail.html)
+url(https://www.swig.org/mail.html)(https://www.swig.org/mail.html)
 
 ccache is released under the GNU General Public License version 2 or
 later. Please see the file COPYING for license details.
diff --git a/CCache/config.h.in b/CCache/config.h.in
index 5b7748b..2a9a9cf 100644
--- a/CCache/config.h.in
+++ b/CCache/config.h.in
@@ -28,9 +28,6 @@
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
 /* Define to 1 if you have the `mkstemp' function. */
 #undef HAVE_MKSTEMP
 
@@ -49,6 +46,9 @@
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
+/* Define to 1 if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
 /* Define to 1 if you have the <stdlib.h> header file. */
 #undef HAVE_STDLIB_H
 
@@ -111,11 +111,10 @@
 /* Define my program name */
 #undef PROGRAM_NAME
 
-/* Define to 1 if you have the ANSI C header files. */
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
+   required in a freestanding environment). This macro is provided for
+   backward compatibility; new code need not use it. */
 #undef STDC_HEADERS
 
-/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
-#undef TIME_WITH_SYS_TIME
-
 /* Define _GNU_SOURCE so that we get all necessary prototypes */
 #undef _GNU_SOURCE
diff --git a/CCache/configure b/CCache/configure
index b863aea..66f60da 100755
--- a/CCache/configure
+++ b/CCache/configure
@@ -1,9 +1,10 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for ccache-swig 0.0.
+# Generated by GNU Autoconf 2.71 for ccache-swig 0.0.
 #
 #
-# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
+# Inc.
 #
 #
 # This configure script is free software; the Free Software Foundation
@@ -14,14 +15,16 @@
 
 # Be more Bourne compatible
 DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+as_nop=:
+if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
   emulate sh
   NULLCMD=:
   # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
   setopt NO_GLOB_SUBST
-else
+else $as_nop
   case `(set -o) 2>/dev/null` in #(
   *posix*) :
     set -o posix ;; #(
@@ -31,46 +34,46 @@
 fi
 
 
+
+# Reset variables that may have inherited troublesome values from
+# the environment.
+
+# IFS needs to be set, to space, tab, and newline, in precisely that order.
+# (If _AS_PATH_WALK were called with IFS unset, it would have the
+# side effect of setting IFS to empty, thus disabling word splitting.)
+# Quoting is to prevent editors from complaining about space-tab.
 as_nl='
 '
 export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
-    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='print -r --'
-  as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='printf %s\n'
-  as_echo_n='printf %s'
-else
-  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
-    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
-    as_echo_n='/usr/ucb/echo -n'
-  else
-    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
-    as_echo_n_body='eval
-      arg=$1;
-      case $arg in #(
-      *"$as_nl"*)
-	expr "X$arg" : "X\\(.*\\)$as_nl";
-	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
-      esac;
-      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
-    '
-    export as_echo_n_body
-    as_echo_n='sh -c $as_echo_n_body as_echo'
-  fi
-  export as_echo_body
-  as_echo='sh -c $as_echo_body as_echo'
-fi
+IFS=" ""	$as_nl"
+
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# Ensure predictable behavior from utilities with locale-dependent output.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# We cannot yet rely on "unset" to work, but we need these variables
+# to be unset--not just set to an empty or harmless value--now, to
+# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
+# also avoids known problems related to "unset" and subshell syntax
+# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
+for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
+do eval test \${$as_var+y} \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+
+# Ensure that fds 0, 1, and 2 are open.
+if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
+if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
+if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi
 
 # The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
+if ${PATH_SEPARATOR+false} :; then
   PATH_SEPARATOR=:
   (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
     (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
@@ -79,13 +82,6 @@
 fi
 
 
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" ""	$as_nl"
-
 # Find who we are.  Look in the path if we contain no directory separator.
 as_myself=
 case $0 in #((
@@ -94,8 +90,12 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    test -r "$as_dir$0" && as_myself=$as_dir$0 && break
   done
 IFS=$as_save_IFS
 
@@ -107,30 +107,10 @@
   as_myself=$0
 fi
 if test ! -f "$as_myself"; then
-  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
   exit 1
 fi
 
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there.  '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
-  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
 # Use a proper internal environment variable to ensure we don't fall
   # into an infinite loop, continuously re-executing ourselves.
@@ -152,20 +132,22 @@
 exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
 # Admittedly, this is quite paranoid, since all the known shells bail
 # out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
-as_fn_exit 255
+printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
   fi
   # We don't want this to propagate to other subprocesses.
           { _as_can_reexec=; unset _as_can_reexec;}
 if test "x$CONFIG_SHELL" = x; then
-  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  as_bourne_compatible="as_nop=:
+if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
   emulate sh
   NULLCMD=:
   # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '\${1+\"\$@\"}'='\"\$@\"'
   setopt NO_GLOB_SUBST
-else
+else \$as_nop
   case \`(set -o) 2>/dev/null\` in #(
   *posix*) :
     set -o posix ;; #(
@@ -185,42 +167,52 @@
 as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
 as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
 as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
-if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+if ( set x; as_fn_ret_success y && test x = \"\$1\" )
+then :
 
-else
+else \$as_nop
   exitcode=1; echo positional parameters were not saved.
 fi
 test x\$exitcode = x0 || exit 1
+blah=\$(echo \$(echo blah))
+test x\"\$blah\" = xblah || exit 1
 test -x / || exit 1"
   as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
   as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
   eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
-  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
-test \$(( 1 + 1 )) = 2 || exit 1"
-  if (eval "$as_required") 2>/dev/null; then :
+  test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1"
+  if (eval "$as_required") 2>/dev/null
+then :
   as_have_required=yes
-else
+else $as_nop
   as_have_required=no
 fi
-  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null
+then :
 
-else
+else $as_nop
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 as_found=false
 for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
   as_found=:
   case $as_dir in #(
 	 /*)
 	   for as_base in sh bash ksh sh5; do
 	     # Try only shells that exist, to save several forks.
-	     as_shell=$as_dir/$as_base
+	     as_shell=$as_dir$as_base
 	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
-		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+		    as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null
+then :
   CONFIG_SHELL=$as_shell as_have_required=yes
-		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+		   if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null
+then :
   break 2
 fi
 fi
@@ -228,14 +220,21 @@
        esac
   as_found=false
 done
-$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
-	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
-  CONFIG_SHELL=$SHELL as_have_required=yes
-fi; }
 IFS=$as_save_IFS
+if $as_found
+then :
+
+else $as_nop
+  if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null
+then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi
+fi
 
 
-      if test "x$CONFIG_SHELL" != x; then :
+      if test "x$CONFIG_SHELL" != x
+then :
   export CONFIG_SHELL
              # We cannot yet assume a decent shell, so we have to provide a
 # neutralization value for shells without unset; and this also
@@ -253,18 +252,19 @@
 exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
 # Admittedly, this is quite paranoid, since all the known shells bail
 # out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
 exit 255
 fi
 
-    if test x$as_have_required = xno; then :
-  $as_echo "$0: This script requires a shell more modern than all"
-  $as_echo "$0: the shells that I found on your system."
-  if test x${ZSH_VERSION+set} = xset ; then
-    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
-    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+    if test x$as_have_required = xno
+then :
+  printf "%s\n" "$0: This script requires a shell more modern than all"
+  printf "%s\n" "$0: the shells that I found on your system."
+  if test ${ZSH_VERSION+y} ; then
+    printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later."
   else
-    $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
+    printf "%s\n" "$0: Please tell bug-autoconf@gnu.org about your system,
 $0: including any error possibly output before this
 $0: message. Then install a modern shell, or manually run
 $0: the script under such a shell if you do have one."
@@ -291,6 +291,7 @@
 }
 as_unset=as_fn_unset
 
+
 # as_fn_set_status STATUS
 # -----------------------
 # Set $? to STATUS, without forking.
@@ -308,6 +309,14 @@
   as_fn_set_status $1
   exit $1
 } # as_fn_exit
+# as_fn_nop
+# ---------
+# Do nothing but, unlike ":", preserve the value of $?.
+as_fn_nop ()
+{
+  return $?
+}
+as_nop=as_fn_nop
 
 # as_fn_mkdir_p
 # -------------
@@ -322,7 +331,7 @@
     as_dirs=
     while :; do
       case $as_dir in #(
-      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
       *) as_qdir=$as_dir;;
       esac
       as_dirs="'$as_qdir' $as_dirs"
@@ -331,7 +340,7 @@
 	 X"$as_dir" : 'X\(//\)[^/]' \| \
 	 X"$as_dir" : 'X\(//\)$' \| \
 	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
+printf "%s\n" X"$as_dir" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
 	    s//\1/
 	    q
@@ -370,12 +379,13 @@
 # advantage of any shell optimizations that allow amortized linear growth over
 # repeated appends, instead of the typical quadratic growth present in naive
 # implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
+then :
   eval 'as_fn_append ()
   {
     eval $1+=\$2
   }'
-else
+else $as_nop
   as_fn_append ()
   {
     eval $1=\$$1\$2
@@ -387,18 +397,27 @@
 # Perform arithmetic evaluation on the ARGs, and store the result in the
 # global $as_val. Take advantage of shells that can avoid forks. The arguments
 # must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
+then :
   eval 'as_fn_arith ()
   {
     as_val=$(( $* ))
   }'
-else
+else $as_nop
   as_fn_arith ()
   {
     as_val=`expr "$@" || test $? -eq 1`
   }
 fi # as_fn_arith
 
+# as_fn_nop
+# ---------
+# Do nothing but, unlike ":", preserve the value of $?.
+as_fn_nop ()
+{
+  return $?
+}
+as_nop=as_fn_nop
 
 # as_fn_error STATUS ERROR [LINENO LOG_FD]
 # ----------------------------------------
@@ -410,9 +429,9 @@
   as_status=$1; test $as_status -eq 0 && as_status=1
   if test "$4"; then
     as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-  $as_echo "$as_me: error: $2" >&2
+  printf "%s\n" "$as_me: error: $2" >&2
   as_fn_exit $as_status
 } # as_fn_error
 
@@ -439,7 +458,7 @@
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
 	 X"$0" : 'X\(//\)$' \| \
 	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
+printf "%s\n" X/"$0" |
     sed '/^.*\/\([^/][^/]*\)\/*$/{
 	    s//\1/
 	    q
@@ -483,7 +502,7 @@
       s/-\n.*//
     ' >$as_me.lineno &&
   chmod +x "$as_me.lineno" ||
-    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+    { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
 
   # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
   # already done that, so ensure we don't try to do so again and fall
@@ -497,6 +516,10 @@
   exit
 }
 
+
+# Determine whether it's possible to make 'echo' print without a newline.
+# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
+# for compatibility with existing Makefiles.
 ECHO_C= ECHO_N= ECHO_T=
 case `echo -n x` in #(((((
 -n*)
@@ -510,6 +533,13 @@
   ECHO_N='-n';;
 esac
 
+# For backward compatibility with old third-party macros, we provide
+# the shell variables $as_echo and $as_echo_n.  New code should use
+# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
+as_echo='printf %s\n'
+as_echo_n='printf %s'
+
+
 rm -f conf$$ conf$$.exe conf$$.file
 if test -d conf$$.dir; then
   rm -f conf$$.dir/conf$$.file
@@ -585,44 +615,38 @@
 ac_unique_file="ccache.h"
 # Factoring default headers for most tests.
 ac_includes_default="\
-#include <stdio.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
+#include <stddef.h>
+#ifdef HAVE_STDIO_H
+# include <stdio.h>
 #endif
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#ifdef STDC_HEADERS
+#ifdef HAVE_STDLIB_H
 # include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-# endif
 #endif
 #ifdef HAVE_STRING_H
-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
-#  include <memory.h>
-# endif
 # include <string.h>
 #endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
 #ifdef HAVE_INTTYPES_H
 # include <inttypes.h>
 #endif
 #ifdef HAVE_STDINT_H
 # include <stdint.h>
 #endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif"
 
+ac_header_c_list=
 ac_subst_vars='LTLIBOBJS
 LIBOBJS
-EGREP
-GREP
 PROGRAM_NAME
 INSTALL_DATA
 INSTALL_SCRIPT
@@ -756,8 +780,6 @@
   *)    ac_optarg=yes ;;
   esac
 
-  # Accept the important Cygnus configure options, so we can diagnose typos.
-
   case $ac_dashdash$ac_option in
   --)
     ac_dashdash=yes ;;
@@ -798,9 +820,9 @@
     ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid feature name: $ac_useropt"
+      as_fn_error $? "invalid feature name: \`$ac_useropt'"
     ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
       *"
 "enable_$ac_useropt"
@@ -824,9 +846,9 @@
     ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid feature name: $ac_useropt"
+      as_fn_error $? "invalid feature name: \`$ac_useropt'"
     ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
       *"
 "enable_$ac_useropt"
@@ -1037,9 +1059,9 @@
     ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid package name: $ac_useropt"
+      as_fn_error $? "invalid package name: \`$ac_useropt'"
     ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
       *"
 "with_$ac_useropt"
@@ -1053,9 +1075,9 @@
     ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid package name: $ac_useropt"
+      as_fn_error $? "invalid package name: \`$ac_useropt'"
     ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
       *"
 "with_$ac_useropt"
@@ -1099,9 +1121,9 @@
 
   *)
     # FIXME: should be removed in autoconf 3.0.
-    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2
     expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
-      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+      printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2
     : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
     ;;
 
@@ -1117,7 +1139,7 @@
   case $enable_option_checking in
     no) ;;
     fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
-    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+    *)     printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
   esac
 fi
 
@@ -1181,7 +1203,7 @@
 	 X"$as_myself" : 'X\(//\)[^/]' \| \
 	 X"$as_myself" : 'X\(//\)$' \| \
 	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_myself" |
+printf "%s\n" X"$as_myself" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
 	    s//\1/
 	    q
@@ -1344,9 +1366,9 @@
 case "$ac_dir" in
 .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
 *)
-  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
   # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
   case $ac_top_builddir_sub in
   "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
   *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
@@ -1374,7 +1396,8 @@
 ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
 
     cd "$ac_dir" || { ac_status=$?; continue; }
-    # Check for guested configure.
+    # Check for configure.gnu first; this name is used for a wrapper for
+    # Metaconfig's "Configure" on case-insensitive file systems.
     if test -f "$ac_srcdir/configure.gnu"; then
       echo &&
       $SHELL "$ac_srcdir/configure.gnu" --help=recursive
@@ -1382,7 +1405,7 @@
       echo &&
       $SHELL "$ac_srcdir/configure" --help=recursive
     else
-      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+      printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi || ac_status=$?
     cd "$ac_pwd" || { ac_status=$?; break; }
   done
@@ -1392,9 +1415,9 @@
 if $ac_init_version; then
   cat <<\_ACEOF
 ccache-swig configure 0.0
-generated by GNU Autoconf 2.69
+generated by GNU Autoconf 2.71
 
-Copyright (C) 2012 Free Software Foundation, Inc.
+Copyright (C) 2021 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it.
 _ACEOF
@@ -1411,14 +1434,14 @@
 ac_fn_c_try_compile ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext
+  rm -f conftest.$ac_objext conftest.beam
   if { { ac_try="$ac_compile"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_compile") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -1426,14 +1449,15 @@
     cat conftest.er1 >&5
     mv -f conftest.er1 conftest.err
   fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } && {
 	 test -z "$ac_c_werror_flag" ||
 	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then :
+       } && test -s conftest.$ac_objext
+then :
   ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
 	ac_retval=1
@@ -1455,7 +1479,7 @@
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -1463,14 +1487,15 @@
     cat conftest.er1 >&5
     mv -f conftest.er1 conftest.err
   fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } > conftest.i && {
 	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
 	 test ! -s conftest.err
-       }; then :
+       }
+then :
   ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
     ac_retval=1
@@ -1486,14 +1511,14 @@
 ac_fn_c_try_link ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext conftest$ac_exeext
+  rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext
   if { { ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_link") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -1501,17 +1526,18 @@
     cat conftest.er1 >&5
     mv -f conftest.er1 conftest.err
   fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } && {
 	 test -z "$ac_c_werror_flag" ||
 	 test ! -s conftest.err
        } && test -s conftest$ac_exeext && {
 	 test "$cross_compiling" = yes ||
 	 test -x conftest$ac_exeext
-       }; then :
+       }
+then :
   ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
 	ac_retval=1
@@ -1526,135 +1552,6 @@
 
 } # ac_fn_c_try_link
 
-# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists, giving a warning if it cannot be compiled using
-# the include files in INCLUDES and setting the cache variable VAR
-# accordingly.
-ac_fn_c_check_header_mongrel ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if eval \${$3+:} false; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-else
-  # Is the header compilable?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
-$as_echo_n "checking $2 usability... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_header_compiler=yes
-else
-  ac_header_compiler=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
-$as_echo "$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
-$as_echo_n "checking $2 presence... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <$2>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  ac_header_preproc=yes
-else
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
-$as_echo "$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
-  yes:no: )
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
-$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-    ;;
-  no:yes:* )
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
-$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
-$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
-$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
-$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-    ;;
-esac
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  eval "$3=\$ac_header_compiler"
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_header_mongrel
-
-# ac_fn_c_try_run LINENO
-# ----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
-# that executables *can* be run.
-ac_fn_c_try_run ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
-  { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: program exited with status $ac_status" >&5
-       $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_retval=$ac_status
-fi
-  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_run
-
 # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
 # -------------------------------------------------------
 # Tests whether HEADER exists and can be compiled using the include files in
@@ -1662,26 +1559,28 @@
 ac_fn_c_check_header_compile ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+printf %s "checking for $2... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $4
 #include <$2>
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   eval "$3=yes"
-else
+else $as_nop
   eval "$3=no"
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_header_compile
@@ -1692,11 +1591,12 @@
 ac_fn_c_check_func ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+printf %s "checking for $2... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 /* Define $2 to an innocuous variant, in case <limits.h> declares $2.
@@ -1704,16 +1604,9 @@
 #define $2 innocuous_$2
 
 /* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $2 (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
+   which can conflict with char $2 (); below.  */
 
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
+#include <limits.h>
 #undef $2
 
 /* Override any GCC internal prototype to avoid an error.
@@ -1731,35 +1624,99 @@
 #endif
 
 int
-main ()
+main (void)
 {
 return $2 ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   eval "$3=yes"
-else
+else $as_nop
   eval "$3=no"
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 fi
 eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_func
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to run conftest.$ac_ext, and return whether this succeeded. Assumes that
+# executables *can* be run.
+ac_fn_c_try_run ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }
+then :
+  ac_retval=0
+else $as_nop
+  printf "%s\n" "$as_me: program exited with status $ac_status" >&5
+       printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_retval=$ac_status
+fi
+  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+ac_configure_args_raw=
+for ac_arg
+do
+  case $ac_arg in
+  *\'*)
+    ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+  esac
+  as_fn_append ac_configure_args_raw " '$ac_arg'"
+done
+
+case $ac_configure_args_raw in
+  *$as_nl*)
+    ac_safe_unquote= ;;
+  *)
+    ac_unsafe_z='|&;<>()$`\\"*?[ ''	' # This string ends in space, tab.
+    ac_unsafe_a="$ac_unsafe_z#~"
+    ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g"
+    ac_configure_args_raw=`      printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;;
+esac
+
 cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
 It was created by ccache-swig $as_me 0.0, which was
-generated by GNU Autoconf 2.69.  Invocation command line was
+generated by GNU Autoconf 2.71.  Invocation command line was
 
-  $ $0 $@
+  $ $0$ac_configure_args_raw
 
 _ACEOF
 exec 5>>config.log
@@ -1792,8 +1749,12 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    $as_echo "PATH: $as_dir"
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    printf "%s\n" "PATH: $as_dir"
   done
 IFS=$as_save_IFS
 
@@ -1828,7 +1789,7 @@
     | -silent | --silent | --silen | --sile | --sil)
       continue ;;
     *\'*)
-      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+      ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
     esac
     case $ac_pass in
     1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
@@ -1863,11 +1824,13 @@
 # WARNING: Use '\'' to represent an apostrophe within the trap.
 # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
 trap 'exit_status=$?
+  # Sanitize IFS.
+  IFS=" ""	$as_nl"
   # Save into config.log some information that might help in debugging.
   {
     echo
 
-    $as_echo "## ---------------- ##
+    printf "%s\n" "## ---------------- ##
 ## Cache variables. ##
 ## ---------------- ##"
     echo
@@ -1878,8 +1841,8 @@
     case $ac_val in #(
     *${as_nl}*)
       case $ac_var in #(
-      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
       esac
       case $ac_var in #(
       _ | IFS | as_nl) ;; #(
@@ -1903,7 +1866,7 @@
 )
     echo
 
-    $as_echo "## ----------------- ##
+    printf "%s\n" "## ----------------- ##
 ## Output variables. ##
 ## ----------------- ##"
     echo
@@ -1911,14 +1874,14 @@
     do
       eval ac_val=\$$ac_var
       case $ac_val in
-      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
       esac
-      $as_echo "$ac_var='\''$ac_val'\''"
+      printf "%s\n" "$ac_var='\''$ac_val'\''"
     done | sort
     echo
 
     if test -n "$ac_subst_files"; then
-      $as_echo "## ------------------- ##
+      printf "%s\n" "## ------------------- ##
 ## File substitutions. ##
 ## ------------------- ##"
       echo
@@ -1926,15 +1889,15 @@
       do
 	eval ac_val=\$$ac_var
 	case $ac_val in
-	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	*\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
 	esac
-	$as_echo "$ac_var='\''$ac_val'\''"
+	printf "%s\n" "$ac_var='\''$ac_val'\''"
       done | sort
       echo
     fi
 
     if test -s confdefs.h; then
-      $as_echo "## ----------- ##
+      printf "%s\n" "## ----------- ##
 ## confdefs.h. ##
 ## ----------- ##"
       echo
@@ -1942,8 +1905,8 @@
       echo
     fi
     test "$ac_signal" != 0 &&
-      $as_echo "$as_me: caught signal $ac_signal"
-    $as_echo "$as_me: exit $exit_status"
+      printf "%s\n" "$as_me: caught signal $ac_signal"
+    printf "%s\n" "$as_me: exit $exit_status"
   } >&5
   rm -f core *.core core.conftest.* &&
     rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
@@ -1957,63 +1920,48 @@
 # confdefs.h avoids OS command line length limits that DEFS can exceed.
 rm -f -r conftest* confdefs.h
 
-$as_echo "/* confdefs.h */" > confdefs.h
+printf "%s\n" "/* confdefs.h */" > confdefs.h
 
 # Predefined preprocessor variables.
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_NAME "$PACKAGE_NAME"
-_ACEOF
+printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
-_ACEOF
+printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_VERSION "$PACKAGE_VERSION"
-_ACEOF
+printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_STRING "$PACKAGE_STRING"
-_ACEOF
+printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
-_ACEOF
+printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_URL "$PACKAGE_URL"
-_ACEOF
+printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h
 
 
 # Let the site file select an alternate cache file if it wants to.
 # Prefer an explicitly selected file to automatically selected ones.
-ac_site_file1=NONE
-ac_site_file2=NONE
 if test -n "$CONFIG_SITE"; then
-  # We do not want a PATH search for config.site.
-  case $CONFIG_SITE in #((
-    -*)  ac_site_file1=./$CONFIG_SITE;;
-    */*) ac_site_file1=$CONFIG_SITE;;
-    *)   ac_site_file1=./$CONFIG_SITE;;
-  esac
+  ac_site_files="$CONFIG_SITE"
 elif test "x$prefix" != xNONE; then
-  ac_site_file1=$prefix/share/config.site
-  ac_site_file2=$prefix/etc/config.site
+  ac_site_files="$prefix/share/config.site $prefix/etc/config.site"
 else
-  ac_site_file1=$ac_default_prefix/share/config.site
-  ac_site_file2=$ac_default_prefix/etc/config.site
+  ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
 fi
-for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+
+for ac_site_file in $ac_site_files
 do
-  test "x$ac_site_file" = xNONE && continue
-  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
-$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+  case $ac_site_file in #(
+  */*) :
+     ;; #(
+  *) :
+    ac_site_file=./$ac_site_file ;;
+esac
+  if test -f "$ac_site_file" && test -r "$ac_site_file"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;}
     sed 's/^/| /' "$ac_site_file" >&5
     . "$ac_site_file" \
-      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+      || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "failed to load site script $ac_site_file
 See \`config.log' for more details" "$LINENO" 5; }
   fi
@@ -2023,19 +1971,434 @@
   # Some versions of bash will fail to source /dev/null (special files
   # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
   if test /dev/null != "$cache_file" && test -f "$cache_file"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
-$as_echo "$as_me: loading cache $cache_file" >&6;}
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+printf "%s\n" "$as_me: loading cache $cache_file" >&6;}
     case $cache_file in
       [\\/]* | ?:[\\/]* ) . "$cache_file";;
       *)                      . "./$cache_file";;
     esac
   fi
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
-$as_echo "$as_me: creating cache $cache_file" >&6;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+printf "%s\n" "$as_me: creating cache $cache_file" >&6;}
   >$cache_file
 fi
 
+# Test code for whether the C compiler supports C89 (global declarations)
+ac_c_conftest_c89_globals='
+/* Does the compiler advertise C89 conformance?
+   Do not test the value of __STDC__, because some compilers set it to 0
+   while being otherwise adequately conformant. */
+#if !defined __STDC__
+# error "Compiler does not advertise C89 conformance"
+#endif
+
+#include <stddef.h>
+#include <stdarg.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7 src/conf.sh.  */
+struct buf { int x; };
+struct buf * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not \xHH hex character constants.
+   These do not provoke an error unfortunately, instead are silently treated
+   as an "x".  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously \x00 != x always comes out true, for an
+   array size at least.  It is necessary to write \x00 == 0 to get something
+   that is true only with -std.  */
+int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) '\''x'\''
+int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int),
+               int, int);'
+
+# Test code for whether the C compiler supports C89 (body of main).
+ac_c_conftest_c89_main='
+ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]);
+'
+
+# Test code for whether the C compiler supports C99 (global declarations)
+ac_c_conftest_c99_globals='
+// Does the compiler advertise C99 conformance?
+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
+# error "Compiler does not advertise C99 conformance"
+#endif
+
+#include <stdbool.h>
+extern int puts (const char *);
+extern int printf (const char *, ...);
+extern int dprintf (int, const char *, ...);
+extern void *malloc (size_t);
+
+// Check varargs macros.  These examples are taken from C99 6.10.3.5.
+// dprintf is used instead of fprintf to avoid needing to declare
+// FILE and stderr.
+#define debug(...) dprintf (2, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+  int x = 1234;
+  int y = 5678;
+  debug ("Flag");
+  debug ("X = %d\n", x);
+  showlist (The first, second, and third items.);
+  report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+  #error "your preprocessor is broken"
+#endif
+#if BIG_OK
+#else
+  #error "your preprocessor is broken"
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
+struct incomplete_array
+{
+  int datasize;
+  double data[];
+};
+
+struct named_init {
+  int number;
+  const wchar_t *name;
+  double average;
+};
+
+typedef const char *ccp;
+
+static inline int
+test_restrict (ccp restrict text)
+{
+  // See if C++-style comments work.
+  // Iterate through items via the restricted pointer.
+  // Also check for declarations in for loops.
+  for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i)
+    continue;
+  return 0;
+}
+
+// Check varargs and va_copy.
+static bool
+test_varargs (const char *format, ...)
+{
+  va_list args;
+  va_start (args, format);
+  va_list args_copy;
+  va_copy (args_copy, args);
+
+  const char *str = "";
+  int number = 0;
+  float fnumber = 0;
+
+  while (*format)
+    {
+      switch (*format++)
+	{
+	case '\''s'\'': // string
+	  str = va_arg (args_copy, const char *);
+	  break;
+	case '\''d'\'': // int
+	  number = va_arg (args_copy, int);
+	  break;
+	case '\''f'\'': // float
+	  fnumber = va_arg (args_copy, double);
+	  break;
+	default:
+	  break;
+	}
+    }
+  va_end (args_copy);
+  va_end (args);
+
+  return *str && number && fnumber;
+}
+'
+
+# Test code for whether the C compiler supports C99 (body of main).
+ac_c_conftest_c99_main='
+  // Check bool.
+  _Bool success = false;
+  success |= (argc != 0);
+
+  // Check restrict.
+  if (test_restrict ("String literal") == 0)
+    success = true;
+  char *restrict newvar = "Another string";
+
+  // Check varargs.
+  success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234);
+  test_varargs_macros ();
+
+  // Check flexible array members.
+  struct incomplete_array *ia =
+    malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+  ia->datasize = 10;
+  for (int i = 0; i < ia->datasize; ++i)
+    ia->data[i] = i * 1.234;
+
+  // Check named initializers.
+  struct named_init ni = {
+    .number = 34,
+    .name = L"Test wide string",
+    .average = 543.34343,
+  };
+
+  ni.number = 58;
+
+  int dynamic_array[ni.number];
+  dynamic_array[0] = argv[0][0];
+  dynamic_array[ni.number - 1] = 543;
+
+  // work around unused variable warnings
+  ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\''
+	 || dynamic_array[ni.number - 1] != 543);
+'
+
+# Test code for whether the C compiler supports C11 (global declarations)
+ac_c_conftest_c11_globals='
+// Does the compiler advertise C11 conformance?
+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L
+# error "Compiler does not advertise C11 conformance"
+#endif
+
+// Check _Alignas.
+char _Alignas (double) aligned_as_double;
+char _Alignas (0) no_special_alignment;
+extern char aligned_as_int;
+char _Alignas (0) _Alignas (int) aligned_as_int;
+
+// Check _Alignof.
+enum
+{
+  int_alignment = _Alignof (int),
+  int_array_alignment = _Alignof (int[100]),
+  char_alignment = _Alignof (char)
+};
+_Static_assert (0 < -_Alignof (int), "_Alignof is signed");
+
+// Check _Noreturn.
+int _Noreturn does_not_return (void) { for (;;) continue; }
+
+// Check _Static_assert.
+struct test_static_assert
+{
+  int x;
+  _Static_assert (sizeof (int) <= sizeof (long int),
+                  "_Static_assert does not work in struct");
+  long int y;
+};
+
+// Check UTF-8 literals.
+#define u8 syntax error!
+char const utf8_literal[] = u8"happens to be ASCII" "another string";
+
+// Check duplicate typedefs.
+typedef long *long_ptr;
+typedef long int *long_ptr;
+typedef long_ptr long_ptr;
+
+// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1.
+struct anonymous
+{
+  union {
+    struct { int i; int j; };
+    struct { int k; long int l; } w;
+  };
+  int m;
+} v1;
+'
+
+# Test code for whether the C compiler supports C11 (body of main).
+ac_c_conftest_c11_main='
+  _Static_assert ((offsetof (struct anonymous, i)
+		   == offsetof (struct anonymous, w.k)),
+		  "Anonymous union alignment botch");
+  v1.i = 2;
+  v1.w.k = 5;
+  ok |= v1.i != 5;
+'
+
+# Test code for whether the C compiler supports C11 (complete).
+ac_c_conftest_c11_program="${ac_c_conftest_c89_globals}
+${ac_c_conftest_c99_globals}
+${ac_c_conftest_c11_globals}
+
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  ${ac_c_conftest_c99_main}
+  ${ac_c_conftest_c11_main}
+  return ok;
+}
+"
+
+# Test code for whether the C compiler supports C99 (complete).
+ac_c_conftest_c99_program="${ac_c_conftest_c89_globals}
+${ac_c_conftest_c99_globals}
+
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  ${ac_c_conftest_c99_main}
+  return ok;
+}
+"
+
+# Test code for whether the C compiler supports C89 (complete).
+ac_c_conftest_c89_program="${ac_c_conftest_c89_globals}
+
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  return ok;
+}
+"
+
+as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H"
+as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H"
+as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H"
+as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H"
+as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H"
+as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H"
+as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H"
+as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H"
+as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H"
+
+# Auxiliary files required by this configure script.
+ac_aux_files="install-sh"
+
+# Locations in which to look for auxiliary files.
+ac_aux_dir_candidates="${srcdir}${PATH_SEPARATOR}${srcdir}/..${PATH_SEPARATOR}${srcdir}/../.."
+
+# Search for a directory containing all of the required auxiliary files,
+# $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates.
+# If we don't find one directory that contains all the files we need,
+# we report the set of missing files from the *first* directory in
+# $ac_aux_dir_candidates and give up.
+ac_missing_aux_files=""
+ac_first_candidate=:
+printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in $ac_aux_dir_candidates
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+  as_found=:
+
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}:  trying $as_dir" >&5
+  ac_aux_dir_found=yes
+  ac_install_sh=
+  for ac_aux in $ac_aux_files
+  do
+    # As a special case, if "install-sh" is required, that requirement
+    # can be satisfied by any of "install-sh", "install.sh", or "shtool",
+    # and $ac_install_sh is set appropriately for whichever one is found.
+    if test x"$ac_aux" = x"install-sh"
+    then
+      if test -f "${as_dir}install-sh"; then
+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}install-sh found" >&5
+        ac_install_sh="${as_dir}install-sh -c"
+      elif test -f "${as_dir}install.sh"; then
+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}install.sh found" >&5
+        ac_install_sh="${as_dir}install.sh -c"
+      elif test -f "${as_dir}shtool"; then
+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}shtool found" >&5
+        ac_install_sh="${as_dir}shtool install -c"
+      else
+        ac_aux_dir_found=no
+        if $ac_first_candidate; then
+          ac_missing_aux_files="${ac_missing_aux_files} install-sh"
+        else
+          break
+        fi
+      fi
+    else
+      if test -f "${as_dir}${ac_aux}"; then
+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}${ac_aux} found" >&5
+      else
+        ac_aux_dir_found=no
+        if $ac_first_candidate; then
+          ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}"
+        else
+          break
+        fi
+      fi
+    fi
+  done
+  if test "$ac_aux_dir_found" = yes; then
+    ac_aux_dir="$as_dir"
+    break
+  fi
+  ac_first_candidate=false
+
+  as_found=false
+done
+IFS=$as_save_IFS
+if $as_found
+then :
+
+else $as_nop
+  as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5
+fi
+
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+if test -f "${ac_aux_dir}config.guess"; then
+  ac_config_guess="$SHELL ${ac_aux_dir}config.guess"
+fi
+if test -f "${ac_aux_dir}config.sub"; then
+  ac_config_sub="$SHELL ${ac_aux_dir}config.sub"
+fi
+if test -f "$ac_aux_dir/configure"; then
+  ac_configure="$SHELL ${ac_aux_dir}configure"
+fi
+
 # Check that the precious variables saved in the cache have kept the same
 # value.
 ac_cache_corrupted=false
@@ -2046,12 +2409,12 @@
   eval ac_new_val=\$ac_env_${ac_var}_value
   case $ac_old_set,$ac_new_set in
     set,)
-      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
       ac_cache_corrupted=: ;;
     ,set)
-      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
       ac_cache_corrupted=: ;;
     ,);;
     *)
@@ -2060,24 +2423,24 @@
 	ac_old_val_w=`echo x $ac_old_val`
 	ac_new_val_w=`echo x $ac_new_val`
 	if test "$ac_old_val_w" != "$ac_new_val_w"; then
-	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
-$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
 	  ac_cache_corrupted=:
 	else
-	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
-$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
 	  eval $ac_var=\$ac_old_val
 	fi
-	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
-$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
-	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
-$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+printf "%s\n" "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+printf "%s\n" "$as_me:   current value: \`$ac_new_val'" >&2;}
       fi;;
   esac
   # Pass precious variables to config.status.
   if test "$ac_new_set" = set; then
     case $ac_new_val in
-    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
     *) ac_arg=$ac_var=$ac_new_val ;;
     esac
     case " $ac_configure_args " in
@@ -2087,11 +2450,12 @@
   fi
 done
 if $ac_cache_corrupted; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
-$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
-  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file'
+	    and start over" "$LINENO" 5
 fi
 ## -------------------- ##
 ## Main body of script. ##
@@ -2107,14 +2471,23 @@
 
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: Configuring ccache" >&5
-$as_echo "$as_me: Configuring ccache" >&6;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: Configuring ccache" >&5
+printf "%s\n" "$as_me: Configuring ccache" >&6;}
 
 ac_config_headers="$ac_config_headers config.h"
 
 ac_config_files="$ac_config_files config_win32.h"
 
 
+
+
+
+
+
+
+
+
+
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -2123,11 +2496,12 @@
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
@@ -2135,11 +2509,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -2150,11 +2528,11 @@
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -2163,11 +2541,12 @@
   ac_ct_CC=$CC
   # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_CC"; then
   ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
 else
@@ -2175,11 +2554,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -2190,11 +2573,11 @@
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
   if test "x$ac_ct_CC" = x; then
@@ -2202,8 +2585,8 @@
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     CC=$ac_ct_CC
@@ -2216,11 +2599,12 @@
           if test -n "$ac_tool_prefix"; then
     # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
@@ -2228,11 +2612,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -2243,11 +2631,11 @@
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -2256,11 +2644,12 @@
 if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
@@ -2269,15 +2658,19 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
        ac_prog_rejected=yes
        continue
      fi
     ac_cv_prog_CC="cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -2293,18 +2686,18 @@
     # However, it has the same basename, so the bogon will be chosen
     # first if we set CC to just the basename; use the full file name.
     shift
-    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+    ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@"
   fi
 fi
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -2315,11 +2708,12 @@
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
@@ -2327,11 +2721,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -2342,11 +2740,11 @@
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -2359,11 +2757,12 @@
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_CC"; then
   ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
 else
@@ -2371,11 +2770,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -2386,11 +2789,11 @@
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -2402,8 +2805,8 @@
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     CC=$ac_ct_CC
@@ -2411,25 +2814,129 @@
 fi
 
 fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args.
+set dummy ${ac_tool_prefix}clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}clang"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
 
 
-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "clang", so it can be a program name with args.
+set dummy clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="clang"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+
+
+test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "no acceptable C compiler found in \$PATH
 See \`config.log' for more details" "$LINENO" 5; }
 
 # Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
 set X $ac_compile
 ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
+for ac_option in --version -v -V -qversion -version; do
   { { ac_try="$ac_compiler $ac_option >&5"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_compiler $ac_option >&5") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -2439,7 +2946,7 @@
     cat conftest.er1 >&5
   fi
   rm -f conftest.er1 conftest.err
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
 done
 
@@ -2447,7 +2954,7 @@
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
@@ -2459,9 +2966,9 @@
 # Try to create an executable without -o first, disregard a.out.
 # It will help us diagnose broken compilers, and finding out an intuition
 # of exeext.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
-$as_echo_n "checking whether the C compiler works... " >&6; }
-ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+printf %s "checking whether the C compiler works... " >&6; }
+ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
 
 # The possible output files:
 ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
@@ -2482,11 +2989,12 @@
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_link_default") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
   # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
 # So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
 # in a Makefile.  We should not override ac_cv_exeext if it was cached,
@@ -2503,7 +3011,7 @@
 	# certainly right.
 	break;;
     *.* )
-	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no;
 	then :; else
 	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
 	fi
@@ -2519,44 +3027,46 @@
 done
 test "$ac_cv_exeext" = no && ac_cv_exeext=
 
-else
+else $as_nop
   ac_file=''
 fi
-if test -z "$ac_file"; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-$as_echo "$as_me: failed program was:" >&5
+if test -z "$ac_file"
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "C compiler cannot create executables
 See \`config.log' for more details" "$LINENO" 5; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
-$as_echo_n "checking for C compiler default output file name... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
-$as_echo "$ac_file" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+printf %s "checking for C compiler default output file name... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+printf "%s\n" "$ac_file" >&6; }
 ac_exeext=$ac_cv_exeext
 
 rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
 ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
-$as_echo_n "checking for suffix of executables... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+printf %s "checking for suffix of executables... " >&6; }
 if { { ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_link") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
   # If both `conftest.exe' and `conftest' are `present' (well, observable)
 # catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
 # work properly (i.e., refer to `conftest.exe'), while it won't with
@@ -2570,15 +3080,15 @@
     * ) break;;
   esac
 done
-else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+else $as_nop
+  { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "cannot compute suffix of executables: cannot compile and link
 See \`config.log' for more details" "$LINENO" 5; }
 fi
 rm -f conftest conftest$ac_cv_exeext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
-$as_echo "$ac_cv_exeext" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+printf "%s\n" "$ac_cv_exeext" >&6; }
 
 rm -f conftest.$ac_ext
 EXEEXT=$ac_cv_exeext
@@ -2587,7 +3097,7 @@
 /* end confdefs.h.  */
 #include <stdio.h>
 int
-main ()
+main (void)
 {
 FILE *f = fopen ("conftest.out", "w");
  return ferror (f) || fclose (f) != 0;
@@ -2599,8 +3109,8 @@
 ac_clean_files="$ac_clean_files conftest.out"
 # Check that the compiler produces executables we can run.  If not, either
 # the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
-$as_echo_n "checking whether we are cross compiling... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+printf %s "checking whether we are cross compiling... " >&6; }
 if test "$cross_compiling" != yes; then
   { { ac_try="$ac_link"
 case "(($ac_try" in
@@ -2608,10 +3118,10 @@
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_link") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
   if { ac_try='./conftest$ac_cv_exeext'
   { { case "(($ac_try" in
@@ -2619,39 +3129,40 @@
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_try") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; }; then
     cross_compiling=no
   else
     if test "$cross_compiling" = maybe; then
 	cross_compiling=yes
     else
-	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run C compiled programs.
+	{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot run C compiled programs.
 If you meant to cross compile, use \`--host'.
 See \`config.log' for more details" "$LINENO" 5; }
     fi
   fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
-$as_echo "$cross_compiling" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+printf "%s\n" "$cross_compiling" >&6; }
 
 rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
 ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
-$as_echo_n "checking for suffix of object files... " >&6; }
-if ${ac_cv_objext+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+printf %s "checking for suffix of object files... " >&6; }
+if test ${ac_cv_objext+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
@@ -2665,11 +3176,12 @@
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_compile") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
   for ac_file in conftest.o conftest.obj conftest.*; do
   test -f "$ac_file" || continue;
   case $ac_file in
@@ -2678,31 +3190,32 @@
        break;;
   esac
 done
-else
-  $as_echo "$as_me: failed program was:" >&5
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "cannot compute suffix of object files: cannot compile
 See \`config.log' for more details" "$LINENO" 5; }
 fi
 rm -f conftest.$ac_cv_objext conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
-$as_echo "$ac_cv_objext" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+printf "%s\n" "$ac_cv_objext" >&6; }
 OBJEXT=$ac_cv_objext
 ac_objext=$OBJEXT
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if ${ac_cv_c_compiler_gnu+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5
+printf %s "checking whether the compiler supports GNU C... " >&6; }
+if test ${ac_cv_c_compiler_gnu+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 #ifndef __GNUC__
        choke me
@@ -2712,29 +3225,33 @@
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_compiler_gnu=yes
-else
+else $as_nop
   ac_compiler_gnu=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 ac_cv_c_compiler_gnu=$ac_compiler_gnu
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
-$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; }
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
 if test $ac_compiler_gnu = yes; then
   GCC=yes
 else
   GCC=
 fi
-ac_test_CFLAGS=${CFLAGS+set}
+ac_test_CFLAGS=${CFLAGS+y}
 ac_save_CFLAGS=$CFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
-$as_echo_n "checking whether $CC accepts -g... " >&6; }
-if ${ac_cv_prog_cc_g+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+printf %s "checking whether $CC accepts -g... " >&6; }
+if test ${ac_cv_prog_cc_g+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_save_c_werror_flag=$ac_c_werror_flag
    ac_c_werror_flag=yes
    ac_cv_prog_cc_g=no
@@ -2743,57 +3260,60 @@
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_prog_cc_g=yes
-else
+else $as_nop
   CFLAGS=""
       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
 
-else
+else $as_nop
   ac_c_werror_flag=$ac_save_c_werror_flag
 	 CFLAGS="-g"
 	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_prog_cc_g=yes
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    ac_c_werror_flag=$ac_save_c_werror_flag
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
-$as_echo "$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+printf "%s\n" "$ac_cv_prog_cc_g" >&6; }
+if test $ac_test_CFLAGS; then
   CFLAGS=$ac_save_CFLAGS
 elif test $ac_cv_prog_cc_g = yes; then
   if test "$GCC" = yes; then
@@ -2808,94 +3328,144 @@
     CFLAGS=
   fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if ${ac_cv_prog_cc_c89+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+ac_prog_cc_stdc=no
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5
+printf %s "checking for $CC option to enable C11 features... " >&6; }
+if test ${ac_cv_prog_cc_c11+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c11=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c11_program
+_ACEOF
+for ac_arg in '' -std=gnu11
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c11=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c11" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
+
+if test "x$ac_cv_prog_cc_c11" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c11" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5
+printf "%s\n" "$ac_cv_prog_cc_c11" >&6; }
+     CC="$CC $ac_cv_prog_cc_c11"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11
+  ac_prog_cc_stdc=c11
+fi
+fi
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5
+printf %s "checking for $CC option to enable C99 features... " >&6; }
+if test ${ac_cv_prog_cc_c99+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c99_program
+_ACEOF
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99=
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c99=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
+
+if test "x$ac_cv_prog_cc_c99" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c99" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+printf "%s\n" "$ac_cv_prog_cc_c99" >&6; }
+     CC="$CC $ac_cv_prog_cc_c99"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
+  ac_prog_cc_stdc=c99
+fi
+fi
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5
+printf %s "checking for $CC option to enable C89 features... " >&6; }
+if test ${ac_cv_prog_cc_c89+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_cv_prog_cc_c89=no
 ac_save_CC=$CC
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-struct stat;
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
-{
-  return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
-   inside strings and character constants.  */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
-}
+$ac_c_conftest_c89_program
 _ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
 do
   CC="$ac_save_CC $ac_arg"
-  if ac_fn_c_try_compile "$LINENO"; then :
+  if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_prog_cc_c89=$ac_arg
 fi
-rm -f core conftest.err conftest.$ac_objext
+rm -f core conftest.err conftest.$ac_objext conftest.beam
   test "x$ac_cv_prog_cc_c89" != "xno" && break
 done
 rm -f conftest.$ac_ext
 CC=$ac_save_CC
-
 fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
-  x)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
-  xno)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
-  *)
-    CC="$CC $ac_cv_prog_cc_c89"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c89" != xno; then :
 
+if test "x$ac_cv_prog_cc_c89" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c89" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+printf "%s\n" "$ac_cv_prog_cc_c89" >&6; }
+     CC="$CC $ac_cv_prog_cc_c89"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
+  ac_prog_cc_stdc=c89
+fi
 fi
 
 ac_ext=c
@@ -2909,40 +3479,36 @@
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
-$as_echo_n "checking how to run the C preprocessor... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+printf %s "checking how to run the C preprocessor... " >&6; }
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
 fi
 if test -z "$CPP"; then
-  if ${ac_cv_prog_CPP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-      # Double quotes because CPP needs to be expanded
-    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+  if test ${ac_cv_prog_CPP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+      # Double quotes because $CC needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp
     do
       ac_preproc_ok=false
 for ac_c_preproc_warn_flag in '' yes
 do
   # Use a header file that comes with gcc, so configuring glibc
   # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp. "Syntax error" is here to catch this case.
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
+#include <limits.h>
 		     Syntax error
 _ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
+if ac_fn_c_try_cpp "$LINENO"
+then :
 
-else
+else $as_nop
   # Broken: fails on valid input.
 continue
 fi
@@ -2954,10 +3520,11 @@
 /* end confdefs.h.  */
 #include <ac_nonexistent.h>
 _ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
+if ac_fn_c_try_cpp "$LINENO"
+then :
   # Broken: success on invalid input.
 continue
-else
+else $as_nop
   # Passes both tests.
 ac_preproc_ok=:
 break
@@ -2967,7 +3534,8 @@
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
 rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
+if $ac_preproc_ok
+then :
   break
 fi
 
@@ -2979,29 +3547,24 @@
 else
   ac_cv_prog_CPP=$CPP
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
-$as_echo "$CPP" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+printf "%s\n" "$CPP" >&6; }
 ac_preproc_ok=false
 for ac_c_preproc_warn_flag in '' yes
 do
   # Use a header file that comes with gcc, so configuring glibc
   # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp. "Syntax error" is here to catch this case.
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
+#include <limits.h>
 		     Syntax error
 _ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
+if ac_fn_c_try_cpp "$LINENO"
+then :
 
-else
+else $as_nop
   # Broken: fails on valid input.
 continue
 fi
@@ -3013,10 +3576,11 @@
 /* end confdefs.h.  */
 #include <ac_nonexistent.h>
 _ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
+if ac_fn_c_try_cpp "$LINENO"
+then :
   # Broken: success on invalid input.
 continue
-else
+else $as_nop
   # Passes both tests.
 ac_preproc_ok=:
 break
@@ -3026,11 +3590,12 @@
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
 rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
+if $ac_preproc_ok
+then :
 
-else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+else $as_nop
+  { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
 See \`config.log' for more details" "$LINENO" 5; }
 fi
@@ -3041,36 +3606,9 @@
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-ac_aux_dir=
-for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
-  if test -f "$ac_dir/install-sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install-sh -c"
-    break
-  elif test -f "$ac_dir/install.sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install.sh -c"
-    break
-  elif test -f "$ac_dir/shtool"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/shtool install -c"
-    break
-  fi
-done
-if test -z "$ac_aux_dir"; then
-  as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
-fi
-
-# These three variables are undocumented and unsupported,
-# and are intended to be withdrawn in a future Autoconf release.
-# They can cause serious problems if a builder's source tree is in a directory
-# whose full name contains unusual characters.
-ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
-ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
-ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
 
 
-# Find a good install program.  We prefer a C program (faster),
+  # Find a good install program.  We prefer a C program (faster),
 # so one script is as good as another.  But avoid the broken or
 # incompatible versions:
 # SysV /etc/install, /usr/sbin/install
@@ -3084,20 +3622,25 @@
 # OS/2's system install, which has a completely different semantic
 # ./install, which can be erroneously created by make from ./install.sh.
 # Reject install programs that cannot install multiple files.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
-$as_echo_n "checking for a BSD-compatible install... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+printf %s "checking for a BSD-compatible install... " >&6; }
 if test -z "$INSTALL"; then
-if ${ac_cv_path_install+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+if test ${ac_cv_path_install+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    # Account for people who put trailing slashes in PATH elements.
-case $as_dir/ in #((
-  ./ | .// | /[cC]/* | \
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    # Account for fact that we put trailing slashes in our PATH walk.
+case $as_dir in #((
+  ./ | /[cC]/* | \
   /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
   ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
   /usr/ucb/* ) ;;
@@ -3107,13 +3650,13 @@
     # by default.
     for ac_prog in ginstall scoinst install; do
       for ac_exec_ext in '' $ac_executable_extensions; do
-	if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then
 	  if test $ac_prog = install &&
-	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
 	    # AIX install.  It has an incompatible calling convention.
 	    :
 	  elif test $ac_prog = install &&
-	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
 	    # program-specific install script used by HP pwplus--don't use.
 	    :
 	  else
@@ -3121,12 +3664,12 @@
 	    echo one > conftest.one
 	    echo two > conftest.two
 	    mkdir conftest.dir
-	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	    if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" &&
 	      test -s conftest.one && test -s conftest.two &&
 	      test -s conftest.dir/conftest.one &&
 	      test -s conftest.dir/conftest.two
 	    then
-	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c"
 	      break 3
 	    fi
 	  fi
@@ -3142,7 +3685,7 @@
 rm -rf conftest.one conftest.two conftest.dir
 
 fi
-  if test "${ac_cv_path_install+set}" = set; then
+  if test ${ac_cv_path_install+y}; then
     INSTALL=$ac_cv_path_install
   else
     # As a last resort, use the slow shell script.  Don't cache a
@@ -3152,8 +3695,8 @@
     INSTALL=$ac_install_sh
   fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
-$as_echo "$INSTALL" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+printf "%s\n" "$INSTALL" >&6; }
 
 # Use test -z because SunOS4 sh mishandles braces in ${var-val}.
 # It thinks the first close brace ends the variable substitution.
@@ -3171,7 +3714,7 @@
 # Double any \ or $.
 # By default was `s,x,x', remove it if useless.
 ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
-program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+program_transform_name=`printf "%s\n" "$program_transform_name" | sed "$ac_script"`
  # for program_transform_name
 
 
@@ -3187,13 +3730,11 @@
 fi
 
 
-cat >>confdefs.h <<_ACEOF
-#define PROGRAM_NAME "$PROGRAM_NAME"
-_ACEOF
+printf "%s\n" "#define PROGRAM_NAME \"$PROGRAM_NAME\"" >>confdefs.h
 
 
 
-$as_echo "#define _GNU_SOURCE 1" >>confdefs.h
+printf "%s\n" "#define _GNU_SOURCE 1" >>confdefs.h
 
 
 # If GCC, turn on warnings.
@@ -3207,19 +3748,20 @@
 
 ac_header_dirent=no
 for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
-  as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
-$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
-if eval \${$as_ac_Header+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  as_ac_Header=`printf "%s\n" "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
+printf %s "checking for $ac_hdr that defines DIR... " >&6; }
+if eval test \${$as_ac_Header+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <sys/types.h>
 #include <$ac_hdr>
 
 int
-main ()
+main (void)
 {
 if ((DIR *) 0)
 return 0;
@@ -3227,19 +3769,21 @@
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   eval "$as_ac_Header=yes"
-else
+else $as_nop
   eval "$as_ac_Header=no"
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 eval ac_res=\$$as_ac_Header
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Header"\" = x"yes"
+then :
   cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+#define `printf "%s\n" "HAVE_$ac_hdr" | $as_tr_cpp` 1
 _ACEOF
 
 ac_header_dirent=$ac_hdr; break
@@ -3248,11 +3792,12 @@
 done
 # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
 if test $ac_header_dirent = dirent.h; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
-$as_echo_n "checking for library containing opendir... " >&6; }
-if ${ac_cv_search_opendir+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+printf %s "checking for library containing opendir... " >&6; }
+if test ${ac_cv_search_opendir+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_func_search_save_LIBS=$LIBS
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -3260,56 +3805,59 @@
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char opendir ();
 int
-main ()
+main (void)
 {
 return opendir ();
   ;
   return 0;
 }
 _ACEOF
-for ac_lib in '' dir; do
+for ac_lib in '' dir
+do
   if test -z "$ac_lib"; then
     ac_res="none required"
   else
     ac_res=-l$ac_lib
     LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
   fi
-  if ac_fn_c_try_link "$LINENO"; then :
+  if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_search_opendir=$ac_res
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext
-  if ${ac_cv_search_opendir+:} false; then :
+  if test ${ac_cv_search_opendir+y}
+then :
   break
 fi
 done
-if ${ac_cv_search_opendir+:} false; then :
+if test ${ac_cv_search_opendir+y}
+then :
 
-else
+else $as_nop
   ac_cv_search_opendir=no
 fi
 rm conftest.$ac_ext
 LIBS=$ac_func_search_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
-$as_echo "$ac_cv_search_opendir" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+printf "%s\n" "$ac_cv_search_opendir" >&6; }
 ac_res=$ac_cv_search_opendir
-if test "$ac_res" != no; then :
+if test "$ac_res" != no
+then :
   test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 
 fi
 
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
-$as_echo_n "checking for library containing opendir... " >&6; }
-if ${ac_cv_search_opendir+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+printf %s "checking for library containing opendir... " >&6; }
+if test ${ac_cv_search_opendir+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_func_search_save_LIBS=$LIBS
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -3317,92 +3865,61 @@
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char opendir ();
 int
-main ()
+main (void)
 {
 return opendir ();
   ;
   return 0;
 }
 _ACEOF
-for ac_lib in '' x; do
+for ac_lib in '' x
+do
   if test -z "$ac_lib"; then
     ac_res="none required"
   else
     ac_res=-l$ac_lib
     LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
   fi
-  if ac_fn_c_try_link "$LINENO"; then :
+  if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_search_opendir=$ac_res
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext
-  if ${ac_cv_search_opendir+:} false; then :
+  if test ${ac_cv_search_opendir+y}
+then :
   break
 fi
 done
-if ${ac_cv_search_opendir+:} false; then :
+if test ${ac_cv_search_opendir+y}
+then :
 
-else
+else $as_nop
   ac_cv_search_opendir=no
 fi
 rm conftest.$ac_ext
 LIBS=$ac_func_search_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
-$as_echo "$ac_cv_search_opendir" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+printf "%s\n" "$ac_cv_search_opendir" >&6; }
 ac_res=$ac_cv_search_opendir
-if test "$ac_res" != no; then :
+if test "$ac_res" != no
+then :
   test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 
 fi
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
-$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
-if ${ac_cv_header_time+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <sys/types.h>
-#include <sys/time.h>
-#include <time.h>
 
-int
-main ()
-{
-if ((struct tm *) 0)
-return 0;
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_header_time=yes
-else
-  ac_cv_header_time=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
-$as_echo "$ac_cv_header_time" >&6; }
-if test $ac_cv_header_time = yes; then
-
-$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
-
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5
-$as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; }
-if ${ac_cv_header_sys_wait_h+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for sys/wait.h that is POSIX.1 compatible" >&5
+printf %s "checking for sys/wait.h that is POSIX.1 compatible... " >&6; }
+if test ${ac_cv_header_sys_wait_h+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <sys/types.h>
@@ -3415,7 +3932,7 @@
 #endif
 
 int
-main ()
+main (void)
 {
   int s;
   wait (&s);
@@ -3424,343 +3941,160 @@
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_header_sys_wait_h=yes
-else
+else $as_nop
   ac_cv_header_sys_wait_h=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5
-$as_echo "$ac_cv_header_sys_wait_h" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_sys_wait_h" >&5
+printf "%s\n" "$ac_cv_header_sys_wait_h" >&6; }
 if test $ac_cv_header_sys_wait_h = yes; then
 
-$as_echo "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
+printf "%s\n" "#define HAVE_SYS_WAIT_H 1" >>confdefs.h
 
 fi
 
 
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
-$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if ${ac_cv_path_GREP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -z "$GREP"; then
-  ac_path_GREP_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+ac_header= ac_cache=
+for ac_item in $ac_header_c_list
 do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in grep ggrep; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_GREP" || continue
-# Check for GNU ac_path_GREP and select it if it is found.
-  # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
-  ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    $as_echo 'GREP' >> "conftest.nl"
-    "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    as_fn_arith $ac_count + 1 && ac_count=$as_val
-    if test $ac_count -gt ${ac_path_GREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_GREP="$ac_path_GREP"
-      ac_path_GREP_max=$ac_count
+  if test $ac_cache; then
+    ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default"
+    if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then
+      printf "%s\n" "#define $ac_item 1" >> confdefs.h
     fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-      $ac_path_GREP_found && break 3
-    done
-  done
-  done
-IFS=$as_save_IFS
-  if test -z "$ac_cv_path_GREP"; then
-    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+    ac_header= ac_cache=
+  elif test $ac_header; then
+    ac_cache=$ac_item
+  else
+    ac_header=$ac_item
   fi
-else
-  ac_cv_path_GREP=$GREP
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
-$as_echo "$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
-$as_echo_n "checking for egrep... " >&6; }
-if ${ac_cv_path_EGREP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
-   then ac_cv_path_EGREP="$GREP -E"
-   else
-     if test -z "$EGREP"; then
-  ac_path_EGREP_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in egrep; do
-    for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
-      as_fn_executable_p "$ac_path_EGREP" || continue
-# Check for GNU ac_path_EGREP and select it if it is found.
-  # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
-  ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
-  ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
-  while :
-  do
-    cat "conftest.in" "conftest.in" >"conftest.tmp"
-    mv "conftest.tmp" "conftest.in"
-    cp "conftest.in" "conftest.nl"
-    $as_echo 'EGREP' >> "conftest.nl"
-    "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
-    diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
-    as_fn_arith $ac_count + 1 && ac_count=$as_val
-    if test $ac_count -gt ${ac_path_EGREP_max-0}; then
-      # Best one so far, save it but keep looking for a better one
-      ac_cv_path_EGREP="$ac_path_EGREP"
-      ac_path_EGREP_max=$ac_count
-    fi
-    # 10*(2^10) chars as input seems more than enough
-    test $ac_count -gt 10 && break
-  done
-  rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
-      $ac_path_EGREP_found && break 3
-    done
-  done
-  done
-IFS=$as_save_IFS
-  if test -z "$ac_cv_path_EGREP"; then
-    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
-  fi
-else
-  ac_cv_path_EGREP=$EGREP
-fi
-
-   fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
-$as_echo "$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
-$as_echo_n "checking for ANSI C header files... " >&6; }
-if ${ac_cv_header_stdc+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_header_stdc=yes
-else
-  ac_cv_header_stdc=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
-  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "memchr" >/dev/null 2>&1; then :
-
-else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "free" >/dev/null 2>&1; then :
-
-else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-  if test "$cross_compiling" = yes; then :
-  :
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
-		   (('a' <= (c) && (c) <= 'i') \
-		     || ('j' <= (c) && (c) <= 'r') \
-		     || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
-  int i;
-  for (i = 0; i < 256; i++)
-    if (XOR (islower (i), ISLOWER (i))
-	|| toupper (i) != TOUPPER (i))
-      return 2;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-
-else
-  ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
-$as_echo "$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-$as_echo "#define STDC_HEADERS 1" >>confdefs.h
-
-fi
-
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
-		  inttypes.h stdint.h unistd.h
-do :
-  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
-"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
 done
 
 
-for ac_header in ctype.h strings.h stdlib.h string.h pwd.h sys/time.h
-do :
-  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
+
+
+
+
+
+
+if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes
+then :
+
+printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "ctype.h" "ac_cv_header_ctype_h" "$ac_includes_default"
+if test "x$ac_cv_header_ctype_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_CTYPE_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "strings.h" "ac_cv_header_strings_h" "$ac_includes_default"
+if test "x$ac_cv_header_strings_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_STRINGS_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_STDLIB_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default"
+if test "x$ac_cv_header_string_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_STRING_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "pwd.h" "ac_cv_header_pwd_h" "$ac_includes_default"
+if test "x$ac_cv_header_pwd_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_PWD_H 1" >>confdefs.h
+
+fi
+ac_fn_c_check_header_compile "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_time_h" = xyes
+then :
+  printf "%s\n" "#define HAVE_SYS_TIME_H 1" >>confdefs.h
 
 fi
 
-done
 
-
-for ac_func in realpath snprintf vsnprintf vasprintf asprintf mkstemp
-do :
-  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
+ac_fn_c_check_func "$LINENO" "realpath" "ac_cv_func_realpath"
+if test "x$ac_cv_func_realpath" = xyes
+then :
+  printf "%s\n" "#define HAVE_REALPATH 1" >>confdefs.h
 
 fi
-done
-
-for ac_func in gethostname getpwuid
-do :
-  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
+ac_fn_c_check_func "$LINENO" "snprintf" "ac_cv_func_snprintf"
+if test "x$ac_cv_func_snprintf" = xyes
+then :
+  printf "%s\n" "#define HAVE_SNPRINTF 1" >>confdefs.h
 
 fi
-done
-
-for ac_func in utimes
-do :
-  ac_fn_c_check_func "$LINENO" "utimes" "ac_cv_func_utimes"
-if test "x$ac_cv_func_utimes" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_UTIMES 1
-_ACEOF
+ac_fn_c_check_func "$LINENO" "vsnprintf" "ac_cv_func_vsnprintf"
+if test "x$ac_cv_func_vsnprintf" = xyes
+then :
+  printf "%s\n" "#define HAVE_VSNPRINTF 1" >>confdefs.h
 
 fi
-done
+ac_fn_c_check_func "$LINENO" "vasprintf" "ac_cv_func_vasprintf"
+if test "x$ac_cv_func_vasprintf" = xyes
+then :
+  printf "%s\n" "#define HAVE_VASPRINTF 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "asprintf" "ac_cv_func_asprintf"
+if test "x$ac_cv_func_asprintf" = xyes
+then :
+  printf "%s\n" "#define HAVE_ASPRINTF 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "mkstemp" "ac_cv_func_mkstemp"
+if test "x$ac_cv_func_mkstemp" = xyes
+then :
+  printf "%s\n" "#define HAVE_MKSTEMP 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_func "$LINENO" "gethostname" "ac_cv_func_gethostname"
+if test "x$ac_cv_func_gethostname" = xyes
+then :
+  printf "%s\n" "#define HAVE_GETHOSTNAME 1" >>confdefs.h
+
+fi
+ac_fn_c_check_func "$LINENO" "getpwuid" "ac_cv_func_getpwuid"
+if test "x$ac_cv_func_getpwuid" = xyes
+then :
+  printf "%s\n" "#define HAVE_GETPWUID 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_func "$LINENO" "utimes" "ac_cv_func_utimes"
+if test "x$ac_cv_func_utimes" = xyes
+then :
+  printf "%s\n" "#define HAVE_UTIMES 1" >>confdefs.h
+
+fi
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for compar_fn_t in stdlib.h" >&5
-$as_echo_n "checking for compar_fn_t in stdlib.h... " >&6; }
-if ${ccache_cv_COMPAR_FN_T+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for compar_fn_t in stdlib.h" >&5
+printf %s "checking for compar_fn_t in stdlib.h... " >&6; }
+if test ${ccache_cv_COMPAR_FN_T+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
     cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <stdlib.h>
 int
-main ()
+main (void)
 {
 
 void test_fn(void) { qsort(NULL, 0, 0, (__compar_fn_t)NULL); }
@@ -3769,35 +4103,41 @@
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ccache_cv_COMPAR_FN_T=yes
-else
+else $as_nop
   ccache_cv_COMPAR_FN_T=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ccache_cv_COMPAR_FN_T" >&5
-$as_echo "$ccache_cv_COMPAR_FN_T" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ccache_cv_COMPAR_FN_T" >&5
+printf "%s\n" "$ccache_cv_COMPAR_FN_T" >&6; }
 if test x"$ccache_cv_COMPAR_FN_T" = x"yes"; then
 
-$as_echo "#define HAVE_COMPAR_FN_T 1" >>confdefs.h
+printf "%s\n" "#define HAVE_COMPAR_FN_T 1" >>confdefs.h
 
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C99 vsnprintf" >&5
-$as_echo_n "checking for C99 vsnprintf... " >&6; }
-if ${ccache_cv_HAVE_C99_VSNPRINTF+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C99 vsnprintf" >&5
+printf %s "checking for C99 vsnprintf... " >&6; }
+if test ${ccache_cv_HAVE_C99_VSNPRINTF+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
 
-if test "$cross_compiling" = yes; then :
+if test "$cross_compiling" = yes
+then :
   ccache_cv_HAVE_C99_VSNPRINTF=cross
-else
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 #include <sys/types.h>
 #include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 void foo(const char *format, ...) {
        va_list ap;
        int len;
@@ -3812,12 +4152,13 @@
 
        exit(0);
 }
-main() { foo("hello"); }
+int main(void) { foo("hello"); }
 
 _ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
+if ac_fn_c_try_run "$LINENO"
+then :
   ccache_cv_HAVE_C99_VSNPRINTF=yes
-else
+else $as_nop
   ccache_cv_HAVE_C99_VSNPRINTF=no
 fi
 rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
@@ -3825,30 +4166,33 @@
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ccache_cv_HAVE_C99_VSNPRINTF" >&5
-$as_echo "$ccache_cv_HAVE_C99_VSNPRINTF" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ccache_cv_HAVE_C99_VSNPRINTF" >&5
+printf "%s\n" "$ccache_cv_HAVE_C99_VSNPRINTF" >&6; }
 if test x"$ccache_cv_HAVE_C99_VSNPRINTF" = x"yes"; then
 
-$as_echo "#define HAVE_C99_VSNPRINTF 1" >>confdefs.h
+printf "%s\n" "#define HAVE_C99_VSNPRINTF 1" >>confdefs.h
 
 fi
 
 # Check whether --enable-zlib was given.
-if test "${enable_zlib+set}" = set; then :
+if test ${enable_zlib+y}
+then :
   enableval=$enable_zlib;
-else
+else $as_nop
   enable_zlib=yes
 fi
 
 
 if test x"$enable_zlib" = x"yes"; then
-    ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
-if test "x$ac_cv_header_zlib_h" = xyes; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gzdopen in -lz" >&5
-$as_echo_n "checking for gzdopen in -lz... " >&6; }
-if ${ac_cv_lib_z_gzdopen+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+    ac_fn_c_check_header_compile "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_zlib_h" = xyes
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for gzdopen in -lz" >&5
+printf %s "checking for gzdopen in -lz... " >&6; }
+if test ${ac_cv_lib_z_gzdopen+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lz  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -3857,39 +4201,37 @@
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char gzdopen ();
 int
-main ()
+main (void)
 {
 return gzdopen ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_z_gzdopen=yes
-else
+else $as_nop
   ac_cv_lib_z_gzdopen=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzdopen" >&5
-$as_echo "$ac_cv_lib_z_gzdopen" >&6; }
-if test "x$ac_cv_lib_z_gzdopen" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_gzdopen" >&5
+printf "%s\n" "$ac_cv_lib_z_gzdopen" >&6; }
+if test "x$ac_cv_lib_z_gzdopen" = xyes
+then :
   LIBS="-lz $LIBS"
 
-$as_echo "#define ENABLE_ZLIB 1" >>confdefs.h
+printf "%s\n" "#define ENABLE_ZLIB 1" >>confdefs.h
 
 fi
 
 fi
 
-
 fi
 
 ac_config_files="$ac_config_files Makefile"
@@ -3921,8 +4263,8 @@
     case $ac_val in #(
     *${as_nl}*)
       case $ac_var in #(
-      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
       esac
       case $ac_var in #(
       _ | IFS | as_nl) ;; #(
@@ -3952,15 +4294,15 @@
      /^ac_cv_env_/b end
      t clear
      :clear
-     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/
      t end
      s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
      :end' >>confcache
 if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
   if test -w "$cache_file"; then
     if test "x$cache_file" != "x/dev/null"; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
-$as_echo "$as_me: updating cache $cache_file" >&6;}
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+printf "%s\n" "$as_me: updating cache $cache_file" >&6;}
       if test ! -f "$cache_file" || test -h "$cache_file"; then
 	cat confcache >"$cache_file"
       else
@@ -3974,8 +4316,8 @@
       fi
     fi
   else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
-$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;}
   fi
 fi
 rm -f confcache
@@ -3992,7 +4334,7 @@
 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
   # 1. Remove the extension, and $U if already installed.
   ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
-  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"`
   # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
   #    will be set to the directory where LIBOBJS objects are built.
   as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
@@ -4008,8 +4350,8 @@
 ac_write_fail=0
 ac_clean_files_save=$ac_clean_files
 ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
-$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;}
 as_write_fail=0
 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
 #! $SHELL
@@ -4032,14 +4374,16 @@
 
 # Be more Bourne compatible
 DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+as_nop=:
+if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
   emulate sh
   NULLCMD=:
   # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
   setopt NO_GLOB_SUBST
-else
+else $as_nop
   case `(set -o) 2>/dev/null` in #(
   *posix*) :
     set -o posix ;; #(
@@ -4049,46 +4393,46 @@
 fi
 
 
+
+# Reset variables that may have inherited troublesome values from
+# the environment.
+
+# IFS needs to be set, to space, tab, and newline, in precisely that order.
+# (If _AS_PATH_WALK were called with IFS unset, it would have the
+# side effect of setting IFS to empty, thus disabling word splitting.)
+# Quoting is to prevent editors from complaining about space-tab.
 as_nl='
 '
 export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
-    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='print -r --'
-  as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='printf %s\n'
-  as_echo_n='printf %s'
-else
-  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
-    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
-    as_echo_n='/usr/ucb/echo -n'
-  else
-    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
-    as_echo_n_body='eval
-      arg=$1;
-      case $arg in #(
-      *"$as_nl"*)
-	expr "X$arg" : "X\\(.*\\)$as_nl";
-	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
-      esac;
-      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
-    '
-    export as_echo_n_body
-    as_echo_n='sh -c $as_echo_n_body as_echo'
-  fi
-  export as_echo_body
-  as_echo='sh -c $as_echo_body as_echo'
-fi
+IFS=" ""	$as_nl"
+
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# Ensure predictable behavior from utilities with locale-dependent output.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# We cannot yet rely on "unset" to work, but we need these variables
+# to be unset--not just set to an empty or harmless value--now, to
+# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
+# also avoids known problems related to "unset" and subshell syntax
+# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
+for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
+do eval test \${$as_var+y} \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+
+# Ensure that fds 0, 1, and 2 are open.
+if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
+if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
+if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi
 
 # The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
+if ${PATH_SEPARATOR+false} :; then
   PATH_SEPARATOR=:
   (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
     (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
@@ -4097,13 +4441,6 @@
 fi
 
 
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" ""	$as_nl"
-
 # Find who we are.  Look in the path if we contain no directory separator.
 as_myself=
 case $0 in #((
@@ -4112,8 +4449,12 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    test -r "$as_dir$0" && as_myself=$as_dir$0 && break
   done
 IFS=$as_save_IFS
 
@@ -4125,30 +4466,10 @@
   as_myself=$0
 fi
 if test ! -f "$as_myself"; then
-  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
   exit 1
 fi
 
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there.  '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
-  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
 
 # as_fn_error STATUS ERROR [LINENO LOG_FD]
@@ -4161,13 +4482,14 @@
   as_status=$1; test $as_status -eq 0 && as_status=1
   if test "$4"; then
     as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-  $as_echo "$as_me: error: $2" >&2
+  printf "%s\n" "$as_me: error: $2" >&2
   as_fn_exit $as_status
 } # as_fn_error
 
 
+
 # as_fn_set_status STATUS
 # -----------------------
 # Set $? to STATUS, without forking.
@@ -4194,18 +4516,20 @@
   { eval $1=; unset $1;}
 }
 as_unset=as_fn_unset
+
 # as_fn_append VAR VALUE
 # ----------------------
 # Append the text in VALUE to the end of the definition contained in VAR. Take
 # advantage of any shell optimizations that allow amortized linear growth over
 # repeated appends, instead of the typical quadratic growth present in naive
 # implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
+then :
   eval 'as_fn_append ()
   {
     eval $1+=\$2
   }'
-else
+else $as_nop
   as_fn_append ()
   {
     eval $1=\$$1\$2
@@ -4217,12 +4541,13 @@
 # Perform arithmetic evaluation on the ARGs, and store the result in the
 # global $as_val. Take advantage of shells that can avoid forks. The arguments
 # must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
+then :
   eval 'as_fn_arith ()
   {
     as_val=$(( $* ))
   }'
-else
+else $as_nop
   as_fn_arith ()
   {
     as_val=`expr "$@" || test $? -eq 1`
@@ -4253,7 +4578,7 @@
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
 	 X"$0" : 'X\(//\)$' \| \
 	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
+printf "%s\n" X/"$0" |
     sed '/^.*\/\([^/][^/]*\)\/*$/{
 	    s//\1/
 	    q
@@ -4275,6 +4600,10 @@
 as_cr_digits='0123456789'
 as_cr_alnum=$as_cr_Letters$as_cr_digits
 
+
+# Determine whether it's possible to make 'echo' print without a newline.
+# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
+# for compatibility with existing Makefiles.
 ECHO_C= ECHO_N= ECHO_T=
 case `echo -n x` in #(((((
 -n*)
@@ -4288,6 +4617,12 @@
   ECHO_N='-n';;
 esac
 
+# For backward compatibility with old third-party macros, we provide
+# the shell variables $as_echo and $as_echo_n.  New code should use
+# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
+as_echo='printf %s\n'
+as_echo_n='printf %s'
+
 rm -f conf$$ conf$$.exe conf$$.file
 if test -d conf$$.dir; then
   rm -f conf$$.dir/conf$$.file
@@ -4329,7 +4664,7 @@
     as_dirs=
     while :; do
       case $as_dir in #(
-      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
       *) as_qdir=$as_dir;;
       esac
       as_dirs="'$as_qdir' $as_dirs"
@@ -4338,7 +4673,7 @@
 	 X"$as_dir" : 'X\(//\)[^/]' \| \
 	 X"$as_dir" : 'X\(//\)$' \| \
 	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
+printf "%s\n" X"$as_dir" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
 	    s//\1/
 	    q
@@ -4401,7 +4736,7 @@
 # values after options handling.
 ac_log="
 This file was extended by ccache-swig $as_me 0.0, which was
-generated by GNU Autoconf 2.69.  Invocation command line was
+generated by GNU Autoconf 2.71.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -4459,14 +4794,16 @@
 Report bugs to the package provider."
 
 _ACEOF
+ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"`
+ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"`
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
 ccache-swig config.status 0.0
-configured by $0, generated by GNU Autoconf 2.69,
+configured by $0, generated by GNU Autoconf 2.71,
   with options \\"\$ac_cs_config\\"
 
-Copyright (C) 2012 Free Software Foundation, Inc.
+Copyright (C) 2021 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
 
@@ -4504,15 +4841,15 @@
   -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
     ac_cs_recheck=: ;;
   --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
-    $as_echo "$ac_cs_version"; exit ;;
+    printf "%s\n" "$ac_cs_version"; exit ;;
   --config | --confi | --conf | --con | --co | --c )
-    $as_echo "$ac_cs_config"; exit ;;
+    printf "%s\n" "$ac_cs_config"; exit ;;
   --debug | --debu | --deb | --de | --d | -d )
     debug=: ;;
   --file | --fil | --fi | --f )
     $ac_shift
     case $ac_optarg in
-    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
     '') as_fn_error $? "missing file argument" ;;
     esac
     as_fn_append CONFIG_FILES " '$ac_optarg'"
@@ -4520,7 +4857,7 @@
   --header | --heade | --head | --hea )
     $ac_shift
     case $ac_optarg in
-    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
     esac
     as_fn_append CONFIG_HEADERS " '$ac_optarg'"
     ac_need_defaults=false;;
@@ -4529,7 +4866,7 @@
     as_fn_error $? "ambiguous option: \`$1'
 Try \`$0 --help' for more information.";;
   --help | --hel | -h )
-    $as_echo "$ac_cs_usage"; exit ;;
+    printf "%s\n" "$ac_cs_usage"; exit ;;
   -q | -quiet | --quiet | --quie | --qui | --qu | --q \
   | -silent | --silent | --silen | --sile | --sil | --si | --s)
     ac_cs_silent=: ;;
@@ -4557,7 +4894,7 @@
 if \$ac_cs_recheck; then
   set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
   shift
-  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6
   CONFIG_SHELL='$SHELL'
   export CONFIG_SHELL
   exec "\$@"
@@ -4571,7 +4908,7 @@
   sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
 ## Running $as_me. ##
 _ASBOX
-  $as_echo "$ac_log"
+  printf "%s\n" "$ac_log"
 } >&5
 
 _ACEOF
@@ -4598,8 +4935,8 @@
 # We use the long form for the default assignment because of an extremely
 # bizarre bug on SunOS 4.1.3.
 if $ac_need_defaults; then
-  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
-  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+  test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files
+  test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers
 fi
 
 # Have a temporary directory for convenience.  Make it in the build tree
@@ -4935,7 +5272,7 @@
 	   esac ||
 	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
       esac
-      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
       as_fn_append ac_file_inputs " '$ac_f'"
     done
 
@@ -4943,17 +5280,17 @@
     # use $as_me), people would be surprised to read:
     #    /* config.h.  Generated by config.status.  */
     configure_input='Generated from '`
-	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	  printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
 	`' by configure.'
     if test x"$ac_file" != x-; then
       configure_input="$ac_file.  $configure_input"
-      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
-$as_echo "$as_me: creating $ac_file" >&6;}
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+printf "%s\n" "$as_me: creating $ac_file" >&6;}
     fi
     # Neutralize special characters interpreted by sed in replacement strings.
     case $configure_input in #(
     *\&* | *\|* | *\\* )
-       ac_sed_conf_input=`$as_echo "$configure_input" |
+       ac_sed_conf_input=`printf "%s\n" "$configure_input" |
        sed 's/[\\\\&|]/\\\\&/g'`;; #(
     *) ac_sed_conf_input=$configure_input;;
     esac
@@ -4970,7 +5307,7 @@
 	 X"$ac_file" : 'X\(//\)[^/]' \| \
 	 X"$ac_file" : 'X\(//\)$' \| \
 	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$ac_file" |
+printf "%s\n" X"$ac_file" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
 	    s//\1/
 	    q
@@ -4994,9 +5331,9 @@
 case "$ac_dir" in
 .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
 *)
-  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
   # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
   case $ac_top_builddir_sub in
   "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
   *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
@@ -5053,8 +5390,8 @@
 case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
 *datarootdir*) ac_datarootdir_seen=yes;;
 *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
-$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
   ac_datarootdir_hack='
@@ -5097,9 +5434,9 @@
   { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
   { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
       "$ac_tmp/out"`; test -z "$ac_out"; } &&
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
 which seems to be undefined.  Please make sure it is defined" >&5
-$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
 which seems to be undefined.  Please make sure it is defined" >&2;}
 
   rm -f "$ac_tmp/stdin"
@@ -5115,20 +5452,20 @@
   #
   if test x"$ac_file" != x-; then
     {
-      $as_echo "/* $configure_input  */" \
+      printf "%s\n" "/* $configure_input  */" >&1 \
       && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
     } >"$ac_tmp/config.h" \
       || as_fn_error $? "could not create $ac_file" "$LINENO" 5
     if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
-$as_echo "$as_me: $ac_file is unchanged" >&6;}
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+printf "%s\n" "$as_me: $ac_file is unchanged" >&6;}
     else
       rm -f "$ac_file"
       mv "$ac_tmp/config.h" "$ac_file" \
 	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
     fi
   else
-    $as_echo "/* $configure_input  */" \
+    printf "%s\n" "/* $configure_input  */" >&1 \
       && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
       || as_fn_error $? "could not create -" "$LINENO" 5
   fi
@@ -5169,7 +5506,8 @@
   $ac_cs_success || as_fn_exit 1
 fi
 if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
-$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
 fi
 
+
diff --git a/CCache/configure.ac b/CCache/configure.ac
index e1c7618..9afd49e 100644
--- a/CCache/configure.ac
+++ b/CCache/configure.ac
@@ -1,12 +1,12 @@
 dnl Process this file with autoconf to produce a configure script.
 
-AC_INIT([ccache-swig], [0.0]) # Get version from SWIG in ccache_swig_config.h.in
-AC_PREREQ(2.52)
+AC_INIT([ccache-swig],[0.0]) # Get version from SWIG in ccache_swig_config.h.in
+AC_PREREQ([2.60])
 AC_CONFIG_SRCDIR([ccache.h])
 
 AC_MSG_NOTICE([Configuring ccache])
 
-AC_CONFIG_HEADER(config.h)
+AC_CONFIG_HEADERS([config.h])
 AC_CONFIG_FILES([config_win32.h])
 
 dnl Checks for programs.
@@ -41,7 +41,7 @@
 fi
 
 AC_HEADER_DIRENT
-AC_HEADER_TIME
+
 AC_HEADER_SYS_WAIT
 
 AC_CHECK_HEADERS(ctype.h strings.h stdlib.h string.h pwd.h sys/time.h)
@@ -51,21 +51,21 @@
 AC_CHECK_FUNCS(utimes)
 
 AC_CACHE_CHECK([for compar_fn_t in stdlib.h],ccache_cv_COMPAR_FN_T, [
-    AC_TRY_COMPILE(
-[#include <stdlib.h>],
-[
+    AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <stdlib.h>]], [[
 void test_fn(void) { qsort(NULL, 0, 0, (__compar_fn_t)NULL); }
-],
-	ccache_cv_COMPAR_FN_T=yes,ccache_cv_COMPAR_FN_T=no)])
+]])],[ccache_cv_COMPAR_FN_T=yes],[ccache_cv_COMPAR_FN_T=no])])
 if test x"$ccache_cv_COMPAR_FN_T" = x"yes"; then
    AC_DEFINE(HAVE_COMPAR_FN_T, 1, [ ])
 fi
 
 dnl Note: This could be replaced by AC_FUNC_SNPRINTF() in the autoconf macro archive
 AC_CACHE_CHECK([for C99 vsnprintf],ccache_cv_HAVE_C99_VSNPRINTF,[
-AC_TRY_RUN([
+AC_RUN_IFELSE([AC_LANG_SOURCE([[
 #include <sys/types.h>
 #include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 void foo(const char *format, ...) { 
        va_list ap;
        int len;
@@ -80,9 +80,8 @@
 
        exit(0);
 }
-main() { foo("hello"); }
-],
-ccache_cv_HAVE_C99_VSNPRINTF=yes,ccache_cv_HAVE_C99_VSNPRINTF=no,ccache_cv_HAVE_C99_VSNPRINTF=cross)])
+int main(void) { foo("hello"); }
+]])],[ccache_cv_HAVE_C99_VSNPRINTF=yes],[ccache_cv_HAVE_C99_VSNPRINTF=no],[ccache_cv_HAVE_C99_VSNPRINTF=cross])])
 if test x"$ccache_cv_HAVE_C99_VSNPRINTF" = x"yes"; then
     AC_DEFINE(HAVE_C99_VSNPRINTF, 1, [ ])
 fi
diff --git a/CCache/execute.c b/CCache/execute.c
index 6df025e..8c65e0c 100644
--- a/CCache/execute.c
+++ b/CCache/execute.c
@@ -137,7 +137,7 @@
 	_dup2(fd, 2);
 	_close(fd);
 
-	/* Spawn process (_exec* familly doesn't return) */
+	/* Spawn process (_exec* family doesn't return) */
 	status = _spawnv(_P_WAIT, argv[0], (const char **)argv);
 
 	/* Restore descriptors */
diff --git a/CCache/mdfour.c b/CCache/mdfour.c
index b098e02..1d4060c 100644
--- a/CCache/mdfour.c
+++ b/CCache/mdfour.c
@@ -24,8 +24,6 @@
    It assumes that a int is at least 32 bits long
 */
 
-static struct mdfour *m;
-
 #define MASK32 (0xffffffff)
 
 #define F(X,Y,Z) ((((X)&(Y)) | ((~(X))&(Z))))
@@ -38,12 +36,12 @@
 #define ROUND3(a,b,c,d,k,s) a = lshift((a + H(b,c,d) + M[k] + 0x6ED9EBA1)&MASK32,s)
 
 /* this applies md4 to 64 byte chunks */
-static void mdfour64(uint32 *M)
+static void mdfour64(struct mdfour *md, uint32 *M)
 {
 	uint32 AA, BB, CC, DD;
 	uint32 A,B,C,D;
 
-	A = m->A; B = m->B; C = m->C; D = m->D; 
+	A = md->A; B = md->B; C = md->C; D = md->D;
 	AA = A; BB = B; CC = C; DD = D;
 
         ROUND1(A,B,C,D,  0,  3);  ROUND1(D,A,B,C,  1,  7);  
@@ -80,7 +78,7 @@
 	A &= MASK32; B &= MASK32; 
 	C &= MASK32; D &= MASK32;
 
-	m->A = A; m->B = B; m->C = C; m->D = D;
+	md->A = A; md->B = B; md->C = C; md->D = D;
 }
 
 static void copy64(uint32 *M, const unsigned char *in)
@@ -88,8 +86,8 @@
 	int i;
 
 	for (i=0;i<16;i++)
-		M[i] = (in[i*4+3]<<24) | (in[i*4+2]<<16) |
-			(in[i*4+1]<<8) | (in[i*4+0]<<0);
+		M[i] = ((uint32)in[i*4+3]<<24) | ((uint32)in[i*4+2]<<16) |
+			((uint32)in[i*4+1]<<8) | ((uint32)in[i*4+0]<<0);
 }
 
 static void copy4(unsigned char *out,uint32 x)
@@ -111,15 +109,15 @@
 }
 
 
-static void mdfour_tail(const unsigned char *in, int n)
+static void mdfour_tail(struct mdfour *md, const unsigned char *in, int n)
 {
 	unsigned char buf[128];
 	uint32 M[16];
 	uint32 b;
 
-	m->totalN += n;
+	md->totalN += n;
 
-	b = m->totalN * 8;
+	b = md->totalN * 8;
 
 	memset(buf, 0, 128);
 	if (n) memcpy(buf, in, n);
@@ -128,13 +126,13 @@
 	if (n <= 55) {
 		copy4(buf+56, b);
 		copy64(M, buf);
-		mdfour64(M);
+		mdfour64(md, M);
 	} else {
 		copy4(buf+120, b); 
 		copy64(M, buf);
-		mdfour64(M);
+		mdfour64(md, M);
 		copy64(M, buf+64);
-		mdfour64(M);
+		mdfour64(md, M);
 	}
 }
 
@@ -142,10 +140,8 @@
 {
 	uint32 M[16];
 
-	m = md;
-
 	if (in == NULL) {
-		mdfour_tail(md->tail, md->tail_len);
+		mdfour_tail(md, md->tail, md->tail_len);
 		return;
 	}
 
@@ -158,18 +154,18 @@
 		in += len;
 		if (md->tail_len == 64) {
 			copy64(M, md->tail);
-			mdfour64(M);
-			m->totalN += 64;
+			mdfour64(md, M);
+			md->totalN += 64;
 			md->tail_len = 0;
 		}
 	}
 
 	while (n >= 64) {
 		copy64(M, in);
-		mdfour64(M);
+		mdfour64(md, M);
 		in += 64;
 		n -= 64;
-		m->totalN += 64;
+		md->totalN += 64;
 	}
 
 	if (n) {
@@ -181,12 +177,10 @@
 
 void mdfour_result(struct mdfour *md, unsigned char *out)
 {
-	m = md;
-
-	copy4(out, m->A);
-	copy4(out+4, m->B);
-	copy4(out+8, m->C);
-	copy4(out+12, m->D);
+	copy4(out, md->A);
+	copy4(out+4, md->B);
+	copy4(out+8, md->C);
+	copy4(out+12, md->D);
 }
 
 
@@ -272,7 +266,12 @@
 	printf("\n");
 }
 #endif
-
+/*
+ * To test:
+ *   gcc -DTEST_MDFOUR mdfour.c -o mdfourexe && ./mdfourexe <somefile>
+ * then compare against a reference, such as:
+ *   openssl dgst -md4 <somefile>
+ */
  int main(int argc, char *argv[])
 {
 	file_checksum1(argv[1]);
diff --git a/CCache/snprintf.c b/CCache/snprintf.c
index 9bf8a81..1a76c7d 100644
--- a/CCache/snprintf.c
+++ b/CCache/snprintf.c
@@ -16,7 +16,7 @@
  * for string length.  This covers a nasty loophole.
  *
  * The other functions are there to prevent NULL pointers from
- * causing nast effects.
+ * causing nasty effects.
  *
  * More Recently:
  *  Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43
@@ -30,7 +30,7 @@
  *    probably requires libm on most operating systems.  Don't yet
  *    support the exponent (e,E) and sigfig (g,G).  Also, fmtint()
  *    was pretty badly broken, it just wasn't being exercised in ways
- *    which showed it, so that's been fixed.  Also, formated the code
+ *    which showed it, so that's been fixed.  Also, formatted the code
  *    to mutt conventions, and removed dead code left over from the
  *    original.  Also, there is now a builtin-test, just compile with:
  *           gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm
diff --git a/CCache/web/index.html b/CCache/web/index.html
index 4af8391..bc46916 100644
--- a/CCache/web/index.html
+++ b/CCache/web/index.html
@@ -34,7 +34,7 @@
 
 You can get this release from the <a href="http://ccache.samba.org/ftp/ccache/">download directory</a> 
 
-<p>NOTE! This release changes the hash input slighly, so you will
+<p>NOTE! This release changes the hash input slightly, so you will
 probably find that you will not get any hits against your existing
 cache when you upgrade.
 
diff --git a/CHANGES b/CHANGES
index 7fd6b6d..ccd8a07 100644
--- a/CHANGES
+++ b/CHANGES
@@ -5,6 +5,2767 @@
 Issue # numbers mentioned below can be found on Github. For more details, add
 the issue number to the end of the URL: https://github.com/swig/swig/issues/
 
+Version 4.2.0 (30 Dec 2023)
+===========================
+
+2023-12-24: degasus
+	    [Python] #2494 Fix integer overflow / undefined behavior for python
+            castmode on sizeof(long)==8 platforms for implicit conversions around
+            edge cases of LONG_MAX and ULONG_MAX, for example:
+
+              void as_l(long x); // C interface
+
+            Usage from Python:
+
+              lmaxd = math.nextafter(float(2**63), 0.0) # LONG_MAX == 2**63-1
+              # Now below correctly raises a TypeError due to the overflow
+              as_l(math.nextafter(lmaxd, float('inf')))
+
+2023-12-21: olly
+	    [PHP] `%feature("php:allowdynamicproperties", 0) Foo;` is now handled as
+	    the feature being off to match other boolean features.  Previously
+	    any value set was treated as on.
+
+2023-12-20: treitmayr
+            [Ruby] #2033 Fix missing checks for negative numbers when passing numbers
+            to unsigned long/unsigned long long C types.
+
+2023-12-20: crhilton
+            [C#] #2722 Add support the "cs:defaultargs" feature.
+
+            This adds a way to wrap C++ functions that have default arguments
+            with an equivalent C# function with default arguments, instead of
+            generating an overloaded C# method for each defaulted argument.
+
+2023-12-20: vadz, vadimcn, wangito33, wsfulton, clintonstimpson
+            [Python] #1613 #1687 #1727 #2190 #2727 #2428 Add support for the Python stable
+            ABI using default Python options. Code is generated that compiles when
+            setting the C macro Py_LIMITED_API to 0x03040000 (at C/C++ compile time).
+            Note that the -builtin, -fast (used by -O) options are not supported.
+
+2023-12-20: wsfulton
+            [Python] More efficient input string marshalling for Python 3.
+
+            Previously a copy of a string was made while converting from a Python 3
+            string to a char * or std::string. This copy is no longer needed making
+            string marshalling more efficient. Does not apply to the stable ABI
+            targetting Python < 3.10 where a copy is still required where the stable
+            ABI does not provide PyUnicode_AsUTF8AndSize.
+
+2023-12-20: wsfulton
+            #2190 Replace SWIG_Python_str_AsChar with SWIG_PyUnicode_AsUTF8AndSize.
+
+            SWIG_Python_str_AsChar has undefined behaviour when Py_LIMITED_API is defined
+            as it returns a pointer to a string in a PyBytes object that no longer exists.
+
+            SWIG_PyUnicode_AsUTF8AndSize is an efficient replacement, but requires a
+            different API and the caller to decrement the refcount on the intermediate
+            PyObject in the Py_LIMITED_API < 0x030A0000 implementation. The alternative
+            would have required copying the returned char * string as was done in a
+            previous implementation requiring a call to the defunct SWIG_Python_str_DelForPy3
+            function.
+
+	    *** POTENTIAL INCOMPATIBILITY ***
+
+2023-12-14: PaulObermeier
+	    [Tcl] #2730 Rename SWIG's Tcl_GetBoolFromObj() since Tcl 8.7 (TIP 618)
+	    introduces a function with the same name.
+
+	    [Tcl] #2729 Use Tcl_GetString() instead of Tcl_GetStringFromObj(..., NULL)
+	    for compatibility with Tcl 9.
+
+2023-12-03: olly
+	    [Ocaml] Remove -suffix command line option which has emitted a
+	    deprecation warning since SWIG 3.0.4 - if you want to specify
+	    a different filename extension for generated C++ files use -cppext
+	    instead, which works for all SWIG target language backends.
+
+2023-12-01: saiarcot895
+            [Python] #2413 Prevent potential multi-threading crash; gracefully exit running
+            daemon threads on main thread exit.
+
+2023-11-24: wsfulton
+            Add support for parsing C++20 constexpr destructors.
+
+2023-11-19: olly
+	    Fix handling of constant expressions containing < and > to not
+	    drop parentheses around the subexpression as doing so can change
+	    its value in some cases.
+
+2023-11-18: yasamoka, jmarrec
+            [Python] #2639 Add std_filesystem.i for wrapping std::filesystem::path
+            with pathlib.Path.
+
+2023-11-17: chrstphrchvz
+	    [Tcl] #2711 Fix -Wmissing-braces warning in generated code.
+
+2023-11-17: chrstphrchvz
+	    [Tcl] #2710 Stop using Tcl's CONST macro.  It's no longer needed
+	    and is set to be deprecated in Tcl 8.7, and removed in Tcl 9.0.
+
+2023-11-08: wsfulton
+            [C#] Replace empty() method with IsEmpty property for std::vector, std::list, std::map
+            containers for consistency across all containers.
+
+            The empty() method is actually still wrapped, but as a private proxy method. For backwards
+            compatibility, the method can be made public again using %csmethodmodifiers for all
+            vectors as follows:
+
+              %extend std::vector {
+                %csmethodmodifiers empty() const "public"
+              }
+              %include "std_vector.i"
+
+            or alternatively for each individual %template instantiation as follows:
+
+              %csmethodmodifiers std::vector<double>::empty() const "public"
+              %template(VectorDouble) std::vector<double>;
+
+
+	    *** POTENTIAL INCOMPATIBILITY ***
+
+2023-11-08: wsfulton
+            [C#] Add std_unordered_set.i for wrapping std::std_unordered_set, implementing
+            C# System.Collections.Generic.ISet<>.
+
+2023-11-09: olly
+	    #2591 SWIG now supports command line options -std=cXX and
+	    -std=c++XX to specify the C/C++ standards version.  The only effect
+	    of these options is to set appropriate values for __STDC_VERSION__
+	    and __cplusplus respectively, which is useful if you're wrapping
+	    headers which have preprocessor checks based on their values.
+
+2023-11-09: olly
+	    SWIG now defines __STDC__ to 1 to match the behaviour of ISO C/C++
+	    compilers - previously it had an empty value.
+
+	    *** POTENTIAL INCOMPATIBILITY ***
+
+2023-11-09: olly
+	    When -c++ is used, SWIG now defines __cplusplus to be 199711L (the
+	    value for C++98) by default - previously its value was set to
+	    __cplusplus.
+
+	    *** POTENTIAL INCOMPATIBILITY ***
+
+2023-11-08: emmenlau
+            #2480 [C#] Add std_unordered_map.i for wrapping std::std_unordered_map, implementing
+            C# System.Collections.Generic.IDictionary<>.
+
+2023-11-06: wsfulton
+            [D, Java] Add the dbegin option to the %module directive for generating code at
+            the beginning of every D file. Similarly javabegin for Java. This enables one
+            to add a common comment at the start of each D/Java file.
+
+2023-11-06: wsfulton
+            [C#] #2681 Support nullable reference types. A generic C# option to the
+            %module directive allows one to add in any code at the beginning of every
+            C# file. This can add the #nullable enable preprocessor directive at the beginning
+            of every C# file in order to enable nullable reference types as follows:
+
+              %module(csbegin="#nullable enable\n") mymodule
+
+2023-10-21: wsfulton
+            [Python] #1783 Don't swallow all exceptions into a NotImplemented return
+            when wrapping operators which are marked with %pythonmaybecall. Corrects the
+            implementation of PEP 207.
+
+2023-10-18: wsfulton
+            [C#, D] #902 Use the C++11 enum base, that is, the underlying enum
+            type.
+
+            For C#, it is used as the underlying type in the generated C# enum.
+            For D, it is used as the enum base type in the generated D enum.
+
+2023-10-16: wsfulton
+            #2687 Another using declarations fix for inheritance hierarchies more than
+            two deep and the using declarations are overloaded. Using declarations
+            from a base class' base were not available for use in the target
+            language when the using declaration was before a method declaration.
+
+2023-10-11: wsfulton
+            [C#, D, Go, Guile, Java, Javascript, Lua, Ocaml, R, Racket] #1680
+            carrays.i library modified to use size_t instead of int for the functions
+            provided by %array_functions and %array_class.
+
+            If the old types are required for backwards compatibility, use %apply to
+            restore the old types as follows:
+
+              %include "carrays.i"
+              %apply int { size_t nelements, size_t index }
+              ... %array_functions and %array_class ...
+              %clear size_t nelements, size_t index; # To be safe in case used elsewhere
+
+	    *** POTENTIAL INCOMPATIBILITY ***
+
+2023-10-11: olly
+	    [PHP] #2685 Fix testcase director_finalizer to work with PHP 8.3.
+
+2023-10-06: wsfulton
+            #2307 std::vector::capacity and std::vector::reserve signature changes.
+
+            Java api changes from:
+              public long capacity() { ... }
+              public void reserve(long n) { ... }
+            to:
+              public int capacity() { ... }
+              public void reserve(int n) { ... }
+            to fit in with the usual Java convention of using int for container
+            indexing and sizing.
+
+            The original api for std::vector::reserve can be also be made available via
+            %extend to add in an overloaded method as follows:
+
+              %include <std_vector.i>
+              %extend std::vector {
+                void reserve(jlong n) throw (std::length_error, std::out_of_range) {
+                  if (n < 0)
+                    throw std::out_of_range("vector reserve size must be positive");
+                  self->reserve(n);
+                }
+              }
+
+            This change is partially driven by the need to seamlessly support the full
+            64-bit range for size_t generically, apart from the customisations for the
+            STL containers, by using:
+
+              %apply unsigned long long { size_t };
+              %apply const unsigned long long & { const size_t & };
+
+	    *** POTENTIAL INCOMPATIBILITY ***
+
+2023-10-05: wsfulton
+            [C#] #2379 Defining SWIGWORDSIZE64 now applies the (unsigned)
+            long long typemaps to (unsigned) long for a better match on systems
+            where long is 64-bits. A new "Type mapping" section has been added into
+            the CSharp.html documentation covering this and marshalling of primitive
+            types. C (unsigned) long handling remains as is by default, that is,
+            marshall as 32-bit.
+
+            The INPUT[], OUTPUT[], INOUT[], FIXED[] typemaps for long and unsigned long
+            in arrays_csharp.i can now be used and compiled on 64-bit platforms where
+            sizeof(long) != sizeof(int). Requires SWIGWORDSIZE64 to be defined.
+
+2023-09-27: wsfulton
+            [Java] #646 #649 Defining SWIGWORDSIZE64 now applies the (unsigned)
+            long long typemaps to (unsigned) long for a better match on systems
+            where long is 64-bits.
+
+2023-09-18: christophe-calmejane
+            #2631 C++17 std::map fix for values that are not default constructible.
+            Enhancements for all target languages except Python and Ruby.
+
+2023-09-14: mmomtchev
+            #2675 #2676 Temporary variable zero initialisation in the wrappers for
+            consistency with handling pointers.
+
+2023-09-11: emmenlau
+            #2394 Add support to preprocessor for true and false. Note that this
+            is for C++ not C.
+
+2023-09-11: wsfulton
+            [R] #2605 Complete transition to rtypecheck typemaps from hard coded
+            logic. Also see entry dated 2022-10-28 for swig-4.1.1. The rtypecheck
+            typemaps implement typechecking in R for each function parameter using
+            functions such as is.numeric, is.character, is.logical, is.null etc.
+
+2023-09-09: wsfulton
+            https://sourceforge.net/p/swig/bugs/919/
+
+            Fix incorrect variable setters being generated when wrapping arrays.
+            A setter is no longer generated if the type of the array members
+            are non-assignable.
+
+2023-09-09: wsfulton
+            Non-assignable detection fixes when wrapping const member variables.
+            Const member variables such as the following are non-assignable by
+            by default:
+
+              char * const x;
+              const int x;
+              const int x[1];
+
+            but not:
+
+              const char * x;
+
+            Variable setters are not generated when wrapping these non-assignable
+            variables and classes containing such non-assignable variables.
+
+2023-09-07: wsfulton
+            Non-assignable detection fixes when wrapping rvalue reference variables.
+            Rvalue reference variables such as the following are non-assignable by
+            by default:
+
+              X &&v;
+
+            Variable setters are not generated when wrapping these non-assignable
+            variables and classes containing such non-assignable variables.
+
+2023-09-06: wsfulton
+            Non-assignable detection fixes when wrapping reference variables.
+            Reference variables such as the following are non-assignable by
+            by default:
+
+              int &v;
+
+            Variable setters are not generated when wrapping these non-assignable
+            variables and classes containing such non-assignable variables.
+
+2023-09-06: wsfulton
+            Assignment operator detection fixes when wrapping static member
+            variables.
+
+2023-09-06: wsfulton
+            #1416 Implicit assignment operator detection fixes.
+
+            A class that does not have an explicit assignment operator does not
+            have an implicit assignment operator if a member variable is not
+            assignable. Similarly should one of the base classes also not be
+            assignable. Detection of these scenarios has been fixed so that when
+            wrapping a variable that is not assignable, a variable setter is not
+            generated in order to avoid a compiler error.
+
+            Template instantiation via %template is required in order for this to
+            work for templates that are not assignable.
+
+2023-09-03: wsfulton
+            https://sourceforge.net/p/swig/bugs/1006/
+            Fix incorrect variable setters being generated when the type of the
+            variable is not assignable, due to variable type inheriting a private
+            assignment operator further up the inheritance chain (further up than
+            the immediate base).
+
+2023-09-03: wsfulton
+            [Guile, Ocaml, Perl] Don't attempt to generate a setter when wrapping
+            variables which have a private assignment operator as assignment is not
+            possible. This now matches the behaviour of all the other target languages.
+
+2023-09-02: wsfulton
+            Fix problems wrapping deleted destructors. Derived classes are not
+            constructible, so don't attempt to generate default constructor or
+            copy constructor wrappers.
+
+              struct StackOnly1 {
+                // Only constructible on the stack
+                ~StackOnly1() = delete;
+              };
+              struct StackOnlyDerived1 : StackOnly1 {
+                // this class is not constructible due to deleted base destructor
+              };
+
+2023-09-02: wsfulton
+            Fix %copyctor feature when used on classes with deleted copy constructors.
+            A default constructor wrapper was sometimes incorrectly generated.
+
+2023-09-02: wsfulton
+            #1644 Fix wrapping types passed by value where the type has a deleted
+            default constructor.
+
+2023-08-16: shadchin
+            [Python] #2665 Fix missing-field-initializers warning to provide support
+            for python-3.12.
+
+2023-08-09: olly
+	    [Ruby] Remove -feature command line option which has been
+	    deprecated since SWIG 1.3.32 in 2007.  Use -initname instead.
+
+2023-08-06: wsfulton
+            Add support for using declarations to introduce templated member
+            methods and for inheriting templated constructors, such as:
+
+              struct Base {
+                // templated constructor
+                template <typename T> Base(const T &t, const char *s) {}
+                // templated member method
+                template <typename T> void template_method(const T &t, const char *s) {}
+              };
+
+              %template(Base) Base::Base<int>;
+              %template(template_method) Base::template_method<double>;
+
+              struct Derived : Base {
+                using Base::Base;
+                using Base::template_method;
+              };
+
+            Previously the templated methods and constructors were ignored and
+            not introduced into the Derived class.
+
+2023-08-04: wsfulton
+            Fix using declarations for inheritance hierarchies more than
+            two deep and the using declarations are overloaded. Using declarations
+            from a base class' base were not available for use in the target
+            language. For example in the code below, Using1::usingmethod(int i)
+            was not wrapped for use in Using3:
+
+              struct Using1 {
+              protected:
+                void usingmethod(int i) {}
+              };
+              struct Using2 : Using1 {
+              protected:
+                void usingmethod(int i, int j) {}
+                using Using1::usingmethod;
+              };
+              struct Using3 : Using2 {
+                void usingmethod(int i, int j, int k) {}
+                using Using2::usingmethod;
+              };
+
+            Similarly for C++11 using declarations for inheriting constructors.
+
+2023-08-02: wsfulton
+            https://sourceforge.net/p/swig/bugs/932/
+            Fix missing constructor generation due to abstract class test
+            failure when a method is declared in the class along with a
+            using declaration and the using declaration is declared before
+            the method that implemented the pure virtual method, such as:
+
+              struct ConcreteDerived : AbstractBase {
+                ConcreteDerived() {} // was not wrapped
+                using AbstractBase::f;
+                virtual void f(int n) override {}
+              };
+
+2023-08-02: olly
+	    [PHP] Implement overloading between different integer types and
+	    between double and float.
+
+2023-07-29: wsfulton
+            https://sourceforge.net/p/swig/bugs/678/
+            Fix %copyctor used on class hierarchies with non-const copy
+            constructors. Previously SWIG always attempted to call a copy
+            constructor taking a const reference parameter instead of a
+            non-const reference parameter.
+
+2023-07-28: wsfulton
+            #2541 Fix overloading of templated constructors and %copyctor.
+
+2023-07-21: wsfulton
+            Don't generate a default constructor wrapper when a class has a
+            templated constructor, as there isn't actually an implied default
+            constructor. For example:
+
+              struct TConstructor3 {
+                template<typename T> TConstructor3(T val) {}
+              };
+
+            Previously wrappers were generated for a non-existent default
+            constructor which failed to compile.
+
+2023-07-15: wsfulton
+            C++11 using declarations for inheriting constructors has now been
+            extended to support the directors feature.
+
+2023-07-13: wsfulton
+            C++11 using declarations for inheriting constructors support now
+            also includes inheriting implicitly defined default constructors
+            from the base class.
+
+2023-07-04: wsfulton
+            #2641 Add support for C++11 using declarations for inheriting
+            constructors.
+
+2023-06-30: wsfulton
+            #2640 Fix syntax error parsing an expression which calls a function
+            with no parameters within additional brackets.
+
+2023-06-27: mmomtchev
+            [Javascript] #2545 New Javascript generator targeting the Node.js
+            binary stable ABI Node-API.
+
+2023-06-27: olly
+	    [Java] Completely remove pragmas which were deprecated in 2002 and
+	    have triggered an error since SWIG 2.0:
+
+	    moduleimport		Use the moduleimports pragma
+	    moduleinterface		Use the moduleinterfaces pragma
+	    modulemethodmodifiers	Use %javamethodmodifiers
+	    allshadowimport		Use %typemap(javaimports)
+	    allshadowcode		Use %typemap(javacode)
+	    allshadowbase		Use %typemap(javabase)
+	    allshadowinterface		Use %typemap(javainterfaces)
+	    allshadowclassmodifiers	Use %typemap(javaclassmodifiers)
+	    shadowcode			Use %typemap(javacode)
+	    shadowimport		Use %typemap(javaimports)
+	    shadowbase			Use %typemap(javabase)
+	    shadowinterface		Use %typemap(javainterfaces)
+	    shadowclassmodifiers	Use %typemap(javaclassmodifiers)
+
+2023-06-24: wsfulton
+            #2616 https://sourceforge.net/p/swig/bugs/1102/ Fix directors and
+            allprotected mode and using declarations. Previously SWIG either
+            seg faulted or generated code that did not compile.
+
+2023-06-20: olly
+	    #2486 Fix handling of template in array size, which was being
+	    rejected by SWIG because the type string contains '<' not followed
+	    by '('.  Drop this check as it should be unnecessary now since the
+	    fixes that ensure that template parameters are enclosed within
+	    '<(' and ')>'.
+
+2023-06-16: olly
+	    [Java] Remove deprecated command line options which have done
+	    nothing except emit a deprecation message since 2002 or before:
+
+	    -jnic / -jnicpp	JNI calling convention now automatic.
+	    -nofinalize		Use javafinalize typemap instead.
+	    -proxy / -shadow	Now on by default.
+
+2023-06-16: olly
+	    [Guile] Drop support for -Linkage ltdlmod which was only useful
+	    for Guile <= 1.4 which we no longer support.
+
+2023-06-15: olly
+	    [Guile] The -gh and -scm command line options have been removed.
+	    These have done nothing except emit a message since 2013 when
+	    SWIG dropped support for generating bindings which used GH.
+
+2023-06-15: olly
+	    Remove pointer.i from the SWIG library.  It's been a dummy file
+	    which has done nothing except %echo a deprecation message since
+	    2002.  The replacement is cpointer.i.
+
+2023-06-15: olly
+	    SWIG will no longer fall back to using the include path to find the
+	    input file, which has been deprecated and emitted a warning since
+	    SWIG 1.3.37 (2009-01-13).  This makes the behaviour of SWIG the
+	    same as C/C++ compilers and works with ccache.
+
+2023-06-15: olly
+	    Remove features deprecated in SWIG 1.x and 2.x.  Most of these have
+	    emitted a deprecation warning or error for well over a decade and
+	    have replacements with fewer shortcomings so we expect users will
+	    have migrated away from them long ago, but in case you need
+	    them replacements are noted below:
+
+	    %addmethods		Use %extend instead.
+	    %attribute_ref      Use %attributeref instead (NB: If called with
+				4 parameters, the 3rd and 4th need switching).
+	    %disabledoc		Use Doxygen support instead.
+	    %doconly		Use Doxygen support instead.
+	    %enabledoc		Use Doxygen support instead.
+	    %except		Use %exception instead.
+	    %extern		Use %import instead.
+	    %localstyle		Use Doxygen support instead.
+	    %name		Use %rename instead.
+	    %new		Use %newobject instead.
+	    %out		%apply OUTPUT typemap rule instead.
+	    %readonly		Use %immutable instead.
+	    %readwrite		Use %mutable instead.
+	    %section		Use Doxygen support instead.
+	    %style		Use Doxygen support instead.
+	    %subsection		Use Doxygen support instead.
+	    %subsubsection	Use Doxygen support instead.
+	    %text		Use Doxygen support instead.
+	    %title		Use Doxygen support instead.
+	    %typemap(except)	Use %exception instead.
+	    %typemap(ignore)	Use %typemap(in,numinputs=0) instead.
+	    %val		Use typemaps instead.
+	    -debug_template	Use -debug-template instead.
+	    -debug_typemap	Use -debug-typemap instead.
+	    -dump_classes	Use -debug-classes instead.
+	    -dump_memory	Use -debug-memory instead.
+	    -dump_module	Use -debug-module 4 instead.
+	    -dump_parse_module	Use -debug-module 1 instead.
+	    -dump_parse_top	Use -debug-top 1 instead.
+	    -dump_tags		Use -debug-tags instead.
+	    -dump_top		Use -debug-top 4 instead.
+	    -dump_tree		Use -debug-top 4 instead.
+	    -dump_typedef	Use -debug-typedef instead.
+	    -dump_xml		Use -xmlout /dev/stdout instead.
+	    -make_default	On by default since SWIG 1.3.7 (2001-09-03).
+	    -makedefault	On by default since SWIG 1.3.7 (2001-09-03).
+	    -no_default		Use %nodefaultctor/%nodedefaultdtor instead.
+	    -nodefault		Use %nodefaultctor/%nodedefaultdtor instead.
+	    -noextern option	On by default since SWIG 1.3.26 (2005-10-09).
+	    -noruntime		Type sharing happens via target lang global.
+	    -runtime		Type sharing happens via target lang global.
+	    -show_templates	Use -debug-template instead.
+	    -tm_debug		Use -debug-typemap instead.
+	    -xml out.xml	Use -xml -o out.xml instead.
+	    BOTH typemap rule	Use INOUT typemap rule instead.
+	    SWIG_INTRUSIVE_PTR(PROXYCLASS, TYPE)
+				Use %intrusive_ptr(TYPE) instead.
+	    SWIG_INTRUSIVE_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE)
+				Use %intrusive_ptr(TYPE) instead.
+	    SWIG_INTRUSIVE_PTR_NO_WRAP(PROXYCLASS, TYPE)
+				Use %intrusive_ptr_no_wrap(TYPE) instead.
+	    SWIG_INTRUSIVE_PTR_DERIVED_NO_WRAP(PROXYCLASS, BASECLASSTYPE, TYPE)
+				Use %intrusive_ptr_no_wrap(TYPE) instead.
+	    SWIG_SHARED_PTR(PROXYCLASS, TYPE)
+				Use %shared_ptr(TYPE) instead.
+	    SWIG_SHARED_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE...)
+				Use %shared_ptr(TYPE) instead.
+	    SWIG_STD_VECTOR_SPECIALIZE(CSTYPE, CTYPE)
+				Use SWIG_STD_VECTOR_ENHANCED(CTYPE) instead.
+	    SWIG_STD_VECTOR_SPECIALIZE_MINIMUM(CSTYPE, CTYPE)
+				No longer required - remove uses.
+	    specialize_std_map_on_both
+				No longer required - remove uses.
+	    specialize_std_map_on_key
+				No longer required - remove uses.
+	    specialize_std_map_on_value
+				No longer required - remove uses.
+
+2023-06-15: olly
+	    [Guile] Fix freearg typemaps to go with char **INOUT and char
+	    *INOUT in typemaps.  Previously the char **INOUT typemap would
+	    leak memory if must_free$argnum was true, and the char *INOUT
+	    typemap would generate code that didn't compile.
+
+2023-06-07: olly
+	    #2630 Fix preprocessor handling of a slash immediately followed by
+	    a single quote, which wasn't getting recognised as starting a
+	    character literal.
+
+2023-06-07: olly
+	    #2630 Fix parsing of <= and >= in templated lambda.
+
+	    Skipping between matching delimiters is now done at the token level
+	    rather than the character level.
+
+2023-06-02: mmomtchev
+	    [Javascript] #2622 Fix support for %typemap(default) and improve
+	    support for default arguments in general.
+
+2023-06-01: olly
+	    [Perl] #2470 Fix some integer truncation warnings in generated
+	    wrappers.
+
+2023-05-30: olly
+	    [Lua] Fix bug when passing a Lua number to a C++ function expected
+	    std::string.  Order of evaluation of C++ function arguments is not
+	    defined, and if lua_rawlen() was called before lua_tostring() then
+	    it would return 0 (because the value was still a number) and an
+	    empty string would be passed.
+
+2023-05-30: mmomtchev
+	    [Javascript] #2618 Fix handling of C++ pointer to member function.
+
+2023-05-25: olly
+	    #1032 Allow typename disambiguator in:
+
+	    using typename NodeT::links_type;
+
+2023-05-25: olly
+	    SWIG now discriminates between long double, double and float
+	    constants.  For example, this means that for target languages which
+	    support a separate float type (such as C# and D) this will now
+	    create a float constant instead of a double constant in the target
+	    language:
+
+	    #define PI_ISH 3.1414f
+
+2023-05-25: olly
+	    C++11 `auto` variables and `decltype()` can now deduce the
+	    type of some expressions which involve literals of built-in types.
+
+2023-05-25: olly
+	    #1125 Support parsing C++11 auto variables.  This uses the
+	    existing type deduction code from decltype so has the same
+	    limitations, and such variables will only actually be wrapped
+	    when SWIG can deduce the type.
+
+2023-05-23: olly
+	    [Ruby] Fix deprecation warnings about ANYARGS when compiling
+	    C++ code for SWIG-generated Ruby wrappers with Ruby 3.x.
+
+	    This is a recurrence of a problem fixed in 4.0.2.  Our fix was
+	    conditional on RB_METHOD_DEFINITION_DECL being defined, but Ruby
+	    3.0 stopped defining this.
+
+2023-05-23: olly
+	    #2606 Improve error output when SWIG reaches EOF while looking for
+	    a closing delimiter.  This is reported with an error like:
+
+	    Error: Missing '}'. Reached end of input.
+
+	    We now exit after reporting this and so no longer report a second
+	    more generic error like:
+
+	    Error: Syntax error in input(1).
+
+2023-05-22: mmomtchev
+	    [Javascript] #2600 Improve test coverage by adding _runme.js files
+	    for 22 test cases.
+
+2023-05-20: erezgeva
+	    [C#, D, Java, Javascript, Guile, Scilab] #2552 Implement argcargv.i
+            library multi-argument typemaps.
+
+2023-05-20: erezgeva
+	    [D] #56 #2538 #2570 The generated code now works with recent D releases:
+            adds override keyword on overridden methods.
+
+            Support is now working using DMD, gcc D and LLVM D compilers.
+
+2023-05-20: olly
+	    Support deducing the type for decltype(false) and
+	    decltype(true).
+
+2023-05-19: olly
+	    #2446 Add support for auto without trailing return type, which is a
+	    C++14 feature.
+
+2023-05-19: olly
+	    SWIG no longer defines preprocessor symbols corresponding to
+	    command line options (e.g. `-module blah` was resulting in
+	    `SWIGOPT_MODULE` being set to `blah`).  This feature was added in
+	    2001 so that "[m]odules can look for these symbols to alter their
+	    code generation if needed", but it's never been used for that
+	    purpose in over 20 years, and has never been documented outside of
+	    CHANGES.
+
+2023-05-18: olly
+	    #2591 Add new -U command line option to undefine a preprocessor
+	    symbol.
+
+2023-05-18: olly
+	    #1589 #2335 Support parsing arbitrary expression in decltype.
+
+	    Use parser error recovery to skip to the closing matching `)` and
+	    issue a warning that we can't deduce the decltype for the
+	    expression (like we already do for any expression which isn't a
+	    simple variable or similar).
+
+2023-05-12: mmomtchev, erezgeva
+	    [Javascript] #2561 Support check typemaps for Javascript.
+
+2023-05-12: olly
+	    [Java] #2556 Suppress Java removal warnings on finalize method.
+	    SWIG will need to stop relying on finalize methods, but we know
+	    that and meanwhile these warnings make the testsuite output very
+	    noisy.
+
+2023-05-11: olly
+	    #302 #2079 #2474 Parse storage class more flexibly.
+
+	    Previously we had a hard-coded list of allowed combinations in the
+	    grammar, but this suffers from combinatorial explosion, and results
+	    in a vague `Syntax error in input` error for invalid (and missing)
+	    combinations.
+
+	    This means we now support a number of cases which are valid C++ but
+	    weren't supported, including `friend constexpr` and `virtual
+	    explicit`.
+
+2023-05-08: olly
+	    #1567 Add support for std::string_view (new in C++17) for C#, Java,
+	    Lua, Perl, PHP, Python, Ruby and Tcl.
+
+2023-05-08: olly
+	    [PHP] #2544 Wrap overloaded method with both static and non-static
+	    forms.  We now wrap this as a non-static method in PHP, which means
+	    the static form is only callable via an object.
+
+	    Previously this case could end up wrapped as static or non-static
+	    in PHP.  If it was wrapped as static, attempting to call non-static
+	    overloaded forms would crash with a segmentation fault.
+
+2023-05-06: mmomtchev, wsfulton
+            #2550 Fix typedef/using declarations to a typedef struct/class.
+
+2023-05-04: erezgeva
+	    [D] #2538 Drop support for D1/Tango, which was discontinued in
+	    2012.  Wrappers for D2/Phobos are now generated by default, though
+	    the -d2 command line option is still accepted (and now ignored) for
+	    backward compatibility.
+
+	    *** POTENTIAL INCOMPATIBILITY ***
+
+2023-04-27: olly
+	    #2502 Allow using snprintf() instead of sprintf() in wrappers.
+
+	    We aim to produce code that works with C90 or C++98 so we can't
+	    assume snprintf() is available, but it almost always is (even
+	    on systems from before it was standardised) so having a way to
+	    use it is helpful.
+
+	    We enable this automatically if the compiler claims conformance
+	    with at least C99 or C++11. It can also be enabled manually by
+	    defining SWIG_HAVE_SNPRINTF.  Define SWIG_NO_SNPRINTF to disable
+	    completely.
+
+	    The fallback is to call sprintf() without a buffer size check,
+	    which is what we've done until now.  Adding a check after the
+	    call seems of limited benefit - if the buffer was overflowed
+	    then it's too late to block it, and most of our uses either have a
+	    fixed maximum possible size or dynamically allocate a buffer that's
+	    large enough.
+
+2023-04-26: mmomtchev
+	    [Javascript] Take into account numinputs when counting arguments.
+
+2023-04-24: olly
+	    [PHP] Add throws typemaps for std:string* and const std::string*.
+
+2023-04-23: olly
+	    [Javascript] #2453 The testsuite and examples now select which
+	    Javascript engine to test based on what was detected by configure.
+	    Previously they'd always test with node you specified a different
+	    engine (e.g. with `ENGINE=jsc` on the make command line).  Now you
+	    only need to specify ENGINE if you have more than one engine
+	    installed.
+
+2023-04-23: olly
+	    [Javascript] Turn on C++ output when wrapping for node, like
+	    we already do when wrapping for V8-without-node.
+
+	    The testsuite was masking this bug by using SWIG options
+	    `-v8 -DBUILDING_NODE_EXTENSION=1` rather than `-node` when testing
+	    with nodejs, while the javascript examples were masking this by
+	    all getting processed with -c++.
+
+	    This shouldn't be an incompatible change for users, as if you're
+	    wrapping a C API you'd have to be working around the problem before
+	    this change (like our testsuite and examples were), and this change
+	    shouldn't break your workaround - it just makes it unnecessary.
+
+2023-04-21: mmomtchev
+	    [Javascript] Fix naming of internal C++ helper for wrapping
+	    variables for node to use the "getter" naming scheme rather
+	    than the function wrapping one.  In practice this didn't actually
+	    cause problems because Node wrappers are always compiled as C++
+	    and the parameters are always different even if the names are
+	    the same.
+
+2023-04-21: olly
+	    [PHP] Support INPUT,INOUT,OUTPUT for std::string&.
+
+	    By default SWIG/PHP wraps std::string& as a pass-by-reference PHP
+	    string parameter, but sometimes such a parameter is only for input
+	    or only for output, so add support for the named typemaps that other
+	    target languages support.
+
+2023-04-21: degasus
+	    #2519 Fix CanCastAsInteger range check to clear errno first to fix
+	    bogus failures for valid inputs.if errno is set.
+
+2023-04-21: ZackerySpytz
+	    [OCaml] #1439 Fix reference typemaps for std::string
+
+2023-04-21: olly
+	    #2183 Fix #ifdef and #ifndef to work inside a %define.  Previously
+	    they were silently ignored in this context (but #if defined already
+	    worked here if you need a workaround which works for older
+	    versions).
+
+2023-04-20: erezgeva
+	    [Go] #2533 Implement argcargv.i library for Go.
+
+2023-04-19: davidcl
+            [Scilab] Add support for Scilab 2023.x.
+	    Introduce a new `-gatewayxml6` option to generate XML with full
+	    function names.
+
+2023-04-19: mmomtchev
+	    https://sourceforge.net/p/swig/bugs/1163/ #1882 #2525
+	    Fix preprocessor expansion when a macro expands to the name of
+	    another macro which takes parameters from the input following the
+	    original macro expansion.
+
+2023-04-19: wildmaples
+	    [Ruby] #2527 Fix "undefining the allocator of T_DATA" warning seen
+	    with Ruby 3.2.
+
+2023-04-18: davidcl
+	    [Scilab] #894 extract values with ":" for typemap (int* IN, int IN_SIZE)
+
+2023-04-14: olly
+	    [PHP7] Support for PHP7 has been removed.  PHP7 security support
+	    ended 2022-11-28 so it doesn't make sense to include support for
+	    it in the SWIG 4.2.x release series.
+
+	    *** POTENTIAL INCOMPATIBILITY ***
+
+2023-04-05: wsfulton
+            [Python] #2515 Add support for all STL containers to be constructible from a Python set.
+
+            The previous implementation used the Python Sequence Protocol to convert from Python types
+            to STL containers. The new implementation uses the Python Iterator Protocol instead and
+            thereby can convert from a Python set too.
+
+2023-03-25: alatina
+            [Octave] #2512 Add support for Octave 8.1.
+
+2023-03-22: wsfulton
+            [C#] #2478 Minor enhancements to std::array wrappers in std_array.i.
+
+2023-03-13: wsfulton
+            Improved error checking when using %template to instantiate templates within
+            the correct scope.
+
+            1. When a template is instantiated via %template and uses the unary scope
+            operator ::, an error occurs if the instantiation is attempted within a
+            namespace that does not enclose the instantiated template.
+            For example, the following will now error as ::test::max is not enclosed within test1:
+
+            Error: '::test::max' resolves to 'test::max' and was incorrectly instantiated in
+            scope 'test1' instead of within scope 'test'.
+              namespace test1 {
+                %template(maxchar) ::test::max<char>;
+              }
+
+            2. SWIG previously failed to always detect a template did not exist when using
+            %template. In particular when instantiating a global template incorrectly within
+            namespace. The code below now correctly emits an error:
+
+            Error: Template 'test5::GlobalVector' undefined.
+              namespace test5 {
+              }
+              template<typename T> struct GlobalVector {};
+              %template(GVI) test5::GlobalVector<int>;
+
+2023-03-13: wsfulton
+            Error out if an attempt is made to define a class using the unary scope
+            operator ::. The following is not legal C++ and now results in an error:
+
+            Error: Using the unary scope operator :: in class definition '::Space2::B' is invalid.
+              namespace Space2 {
+                struct B;
+              }
+              struct ::Space2::B {};
+
+2023-03-08: wsfulton
+            Fix duplicate const in generated code when template instantiation type is const
+            and use of template parameter is also explicitly const, such as:
+
+              template <typename T> struct Conster {
+                void cccc1(T const& t) {}
+              };
+              %template(ConsterInt) Conster<const int>;
+
+            Above previously led to generated code:
+              (arg1)->cccc1((int const const &)*arg2);
+            instead of
+              (arg1)->cccc1((int const &)*arg2);
+
+2023-03-01: wsfulton
+            Partial template specialization fixes to support default arguments from the primary
+            template's parameter list.
+
+              template<class Y, class T=int> struct X { void primary() {} };
+              // Previously the specialization below resulted in:
+              // Error: Inconsistent argument count in template partial specialization. 1 2
+              template<class YY> struct X<YY*> { void special(YY*) {} };
+
+              // Both of these correctly wrap the partially specialized template
+              %template(StringPtr) X<const char *>;
+              %template(ShortPtr) X<short *, int>;
+
+2023-02-15: wsfulton
+            #1300 Further partial template specialization fixes.
+            Fixes when templates are used as a template parameter in a partially specialized
+            instantiation such as:
+
+              template<typename V> struct Vect {};
+              template<class T, typename TT> class Foo { ... };
+              template<class TS, typename TTS> class Foo<Vect<TS>, TTS> { ... };
+              %template(VectInt) Vect<int>;
+              %template(FooVectIntDouble) Foo<Vect<int>, double>; // was previously attempting to use primary template
+
+            Also fixes partial specialization where the same template parameter name is used twice,
+            for example:
+
+              template<typename X, typename Y> struct H { ... };
+              template<typename T> struct H<T, T> { ... };
+              %template(HInts) H<int, int>; // was previously attempting to use primary template
+
+2023-01-27: jschueller
+	    #2492 [python] Fix unused parameter warnings for self parameter in
+	    generated C/C++ wrapper code.
+
+2023-01-14: wsfulton
+            Fix deduction of partially specialized template parameters when the specialized
+            parameter is non-trivial, used in a wrapped method and the type to %template uses
+            typedefs. For example:
+
+              typedef double & DoubleRef;
+              template <typename T> struct XX {};
+              template <typename T> struct XX<T &> { void fn(T t) {} };
+              %template(XXD) XX<DoubleRef>;
+
+            The type of the parameter in the instantiated template for fn is now correctly deduced
+            as double.
+
+2023-01-03: wsfulton
+            #983 Fix seg fault when instantiating templates with parameters that are function
+            parameters containing templates, such as:
+
+              %template(MyC) C<int(std::vector<int>)>;
+
+2023-01-03: wsfulton
+            Complete support for C++11 variadic function templates. Support was previously limited
+            to just one template parameter. Now zero or more template parameters are supported
+            in the %template instantiation.
+
+2022-12-29: wsfulton
+            #1863 Syntax error fixes parsing more elaborate parameter pack arguments that are
+            used in function pointers, member function pointers:
+
+              template <typename... V> struct VariadicParms {
+                void ParmsFuncPtrPtr(int (*)(V*...)) {}
+                void ParmsFuncPtrPtrRef(int (*)(V*&...)) {}
+                void ParmsFuncPtrPtrRValueRef(int (*)(V*&&...)) {}
+                void ParmsFuncPtrRef(int (*)(V&...)) {}
+                void ParmsFuncPtrRValueRef(int (*)(V&&...)) {}
+
+                void ParmsMemFuncPtrPtr(int (KlassMemFuncs::*)(V*...)) {}
+                void ParmsMemFuncPtrPtrRef(int (KlassMemFuncs::*)(V*&...)) {}
+                void ParmsMemFuncPtrPtrRValueRef(int (KlassMemFuncs::*)(V*&&...)) {}
+                void ParmsMemFuncPtrRef(int (KlassMemFuncs::*)(V&...)) {}
+                void ParmsMemFuncPtrRValueRef(int (KlassMemFuncs::*)(V&&...)) {}
+              };
+
+              %template(VariadicParms0) VariadicParms<>;
+              %template(VariadicParms1) VariadicParms<A>;
+
+            Also in various other places such as within noexcept specifiers:
+
+              template<typename T, typename... Args>
+              void emplace(Args &&... args) noexcept(
+                  std::is_nothrow_constructible<T, Args &&...>::value);
+
+2022-12-27: wsfulton
+            Fix instantiation of variadic class templates containing parameter pack arguments that
+            are function pointers.
+
+              template <typename... V> struct VariadicParms {
+                void ParmsFuncPtrVal(int (*)(V...)) {}
+              };
+
+              %template(VariadicParms0) VariadicParms<>;
+              %template(VariadicParms1) VariadicParms<A>;
+
+2022-12-23: wsfulton
+            #1863 Fix syntax error parsing variadic templates containing parameter pack arguments that
+            are function pointers.
+
+2022-12-22: wsfulton
+            Complete support for C++11 variadic class templates. Support was previously limited
+            to just one template parameter. Now zero or more template parameters are supported.
+
+2022-12-06: wsfulton
+            #1636 Fix syntax error for misplaced Doxygen comment after struct/class member.
+            Fix syntax error using Doxygen member groups syntax, "///*}", when used after
+            final struct/class member.
+
+2022-12-05: wsfulton
+            #2023 Fix garbled Doxygen post comments in parameter lists.
+            Fix syntax error parsing a trailing Doxygen comment in parameter lists.
+
+2022-12-03: wsfulton
+            #1609 Fix syntax error parsing of Doxygen comments after last enum item.
+
+2022-12-03: wsfulton
+            #1715 Fix syntax error parsing of unconventionally placed Doxygen post
+            comments for enum items.
+
+2022-12-02: wsfulton
+            #624 #1021 Improved template template parameters support. Previously, specifying more
+            than one simple template template parameter resulted in a parse error. Now
+            multiple template template parameters are working including instantiation with
+            %template. Example:
+
+              template <template<template<class> class, class> class Op, template<class> class X, class Y>
+              class C { ... };
+
+2022-11-26: wsfulton
+            #1589 #1590 Slightly better decltype() support for expressions, such as:
+
+              int i;
+              ...  decltype(&i) ...
+
+            These result in a warning for non-trivial expressions which SWIG cannot evaluate:
+
+              Warning 344: Unable to deduce decltype for '&i'.
+
+            See 'Type Inference' in CPlusPlus.html for workarounds.
+
+2022-11-22: wsfulton
+	    #366 #1037 Fix seg fault handling template parameter expressions
+	    containing '<=' or '>='.
+
+2022-11-18: wsfulton
+            Duplicate class template instantiations via %template now issue a warning and are ignored.
+
+                %template(Aint) A<int>;
+                %template(Aint2) A<int>; // Now ignored and issues a warning
+
+            example.i:7: Warning 404: Duplicate template instantiation of 'A< int >' with name 'Aint2' ignored,
+            example.i:6: Warning 404: previous instantiation of 'A< int >' with name 'Aint'.
+
+            A single empty template instantiation before a named instantiation is the one exception
+            for allowing duplicate template instantiations as the empty template instantiation does not
+            create a wrapper for the template, it merely adds the instantiation into SWIG's internal
+            type system.
+            Duplicate empty template instantiations are quietly ignored.
+
+                %template() B<int>;
+                %template(Bint) B<int>; // OK
+
+                %template() C<int>;
+                %template() C<int>; // Quietly ignored now
+                %template(Cint) C<int>; // OK
+
+            Note that default template parameters are considered when looking for duplicates such as:
+
+                template <typename T, typename U = short> struct D {};
+                %template(Dint) D<int>;
+                %template(Dintshort) D<int, short>;
+
+            example.i:7: Warning 404: Duplicate template instantiation of 'D< int,short >' with name 'Dintshort' ignored,
+            example.i:6: Warning 404: previous instantiation of 'D< int >' with name 'Dint'.
+
+            Note that the following always was ignored, but that was because the chosen name was a
+            duplicate rather than the template being a duplicate:
+
+                %template(Eint) E<int>;
+                %template(Eint) E<int>; // Always has been ignored as a redefined identifier
+
+            The old warning was:
+
+            example.i:7: Warning 302: Identifier 'Eint' redefined (ignored) (Renamed from 'E< int >'),
+            example.i:6: Warning 302: previous definition of 'Eint' (Renamed from 'E< int >').
+
+	    *** POTENTIAL INCOMPATIBILITY ***
+
+Version 4.1.1 (30 Nov 2022)
+===========================
+
+2022-11-29: bero
+            Fix mismatch between #pragma GCC diagnostic push and pop statements
+
+2022-11-26: wsfulton
+            #2449 Fix undefined behaviour in ccache-swig calculating md4 hashes and possibly
+            also handling errors when CCACHE_CPP2 is set.
+
+2022-11-25: wsfulton
+            #961 Fix syntax error parsing unnamed template parameters with a default value.
+
+2022-11-25: olly
+	    #2447 Fix undefined behaviour in swig's parser when handling
+	    default parameter expressions containing method calls.
+
+2022-11-13: olly
+	    [PHP] #2419 Update the documentation to reflect that SWIG 4.1.0
+	    dropped support for -noproxy when generating PHP wrappers.
+
+2022-11-05: wsfulton
+            #2417 Fix -swiglib for Windows when building with CMake.
+
+2022-11-02: wsfulton
+            #2418 Fix infinite loop handling non-type template parameters.
+
+            Fixes infinite loop due to () brackets in a non-type template
+            parameter containing an expression.
+
+2022-10-28: wsfulton
+            [R] R rtypecheck typemaps
+
+            Further switch to use rtypecheck typemaps instead of hard coded logic.
+            The full switch to typemaps is deferred until swig-4.2 as it can't be fully
+            backwards compatible. For now a warning is provided to help the
+            transition. It provides the full typemap that should be placed into
+            a user's interface file, for example:
+
+            %typemap("rtype") int32_t * "integer"
+            void testmethod(int32_t * i);
+            void testmethod();
+
+            If there is no rtypecheck typemap for int32_t *, the warning shown is:
+
+              example.i:7: Warning 750: Optional rtypecheck code is deprecated. Add the
+              following typemap to fix as the next version of SWIG will not work without it:
+              %typemap("rtypecheck") int32_t * %{ (is.integer($arg) || is.numeric($arg)) %}
+
+            The warning is shown for any code that previously used "numeric", "integer" or
+            "character" for the rtype typemap. Copying the rtypecheck typemap as
+            shown into the user interface file will provide the appropriate fix and
+            the warning will disappear. This is important to do as swig-4.2 will
+            not be able to provide this helpful warning.
+
+2022-10-27: wsfulton
+            [R] Allow NULL to be used in overloaded functions taking shared_ptr.
+            Also fixes special variable $argtype expansion in rtypecheck typemaps.
+
+2022-10-26: wsfulton
+            [R] Improve R wrapper error message when calling overloaded methods
+            when incorrect types passed are passed to the overloaded methods.
+
+            Old unhelpful error message:
+              Error in f(...) : could not find function "f"
+
+            Example of new improved error message:
+              Error in use_count(k) :
+                cannot find overloaded function for use_count with argtypes (NULL)
+
+2022-10-26: wsfulton
+            [R] #2386 Fix memory leak in R shared_ptr wrappers.
+            Fix leak when a cast up a class inheritance chain is required.
+
+Version 4.1.0 (24 Oct 2022)
+===========================
+
+2022-10-24: wsfulton, AndLLA
+            [R] #2386 Fix problems in shared_ptr wrappers where the class names
+            were not consistent when using the shared_ptr template or the actual
+            underlying type.
+
+2022-10-24: wsfulton
+            [R] Add support for special variable replacement in the $typemap()
+            special variable macro for R specific typemaps (rtype, rtypecheck,
+            scoercein, scoereout).
+
+2022-10-24: wsfulton
+	    [R] Polymorphism in the wrappers was only working for C++ classes,
+            now this works for C++ structs too.
+
+2022-10-19: olly
+	    [Lua] #2126 Fix type resolution between multiple SWIG-wrapped
+	    modules.
+
+2022-10-17: wsfulton
+            [R] #2385 Add support for std::vector<std::vector<std::string>>.
+
+2022-10-14: murillo128
+	    [Javascript] #2109 Tweak unsigned long and unsigned long long typemaps
+            to create a v8::Number instead of v8::Integer if the value exceeds
+            the size of v8::Integer. Note that the v8::Number value will be
+            imprecise if the value is > MAX_SAFE_INTEGER.
+
+2022-10-14: olly
+	    [R] Arrange that destructors of local C++ objects in the wrapper
+	    function get run on SWIG_fail (which calls Rf_error() which calls
+	    longjmp()).
+
+2022-10-14: olly
+	    [Lua] Arrange that destructors of local C++ objects in the wrapper
+	    function get run on SWIG_fail (which calls lua_error() which calls
+	    longjmp()).
+
+2022-10-13: wsfulton
+            [R] Add missing SWIGTYPE *const& typemaps for supporting pointers
+            by const reference.
+
+2022-10-10: wsfulton
+            #2160 Fix compile error when using templates with more than one template
+            parameter and used as an input parameter in a virtual method in a
+            director class (problem affecting most of the scripting languages).
+
+2022-10-10: treitmayr, wsfulton
+            [Python, Ruby] #1811 #1823 Fix invalid code generated in some cases when
+            returning a pointer or reference to a director-enabled class instance.
+            This previously only worked in very simple cases, now return types are
+            resolved to fix. A bug in template instantiations using pointers also
+            works now.
+
+2022-10-06: wsfulton
+	    [CFFI] #1966 #2200 Remove code for Common Lisp CFFI.  We dropped support
+	    for it in SWIG 4.0.0 by disabling it as the first stage. This is the
+            final stage for complete removal as there has been no meaningful
+            progress to revive it to the status of experimental language.
+
+2022-10-06: olly
+	    [Python] #2390 Remove deprecated and apparently useless defarg.swg
+
+	    The only documentation is in the file itself and describes a Python
+	    wrapper around the C function defined here, but digging though the
+	    git history this Python wrapper doesn't seem to have ever actually
+	    been generated by SWIG.
+
+	    This file was also marked as deprecated in 2005.
+
+2022-10-06: wsfulton
+            [Java] #2048 Fix quoting for doxygen \image command to quote the output
+            file name generated into the html src attribute.
+
+2022-10-05: benjamin-sch
+            [Python] added an interpreter counter to fix deinitialization
+            issues if multiple subinterpreters are used
+
+2022-10-05: olly, wsfulton
+            #672 Add support for parsing C++11 final classes such as:
+
+              class X final {};
+
+            This no longer gives a syntax error.
+
+2022-10-05: wsfulton
+            [OCaml] Fix %rename for enum items. Previously the rename had no effect.
+
+2022-10-05: olly
+	    #1465 Report errors in preprocessor expressions by default
+
+	    Until now SWIG quietly ignored such errors unless -Wextra (or -Wall
+	    which implies -Wextra) was passed, but this is unhelpful as it tends
+	    to hide genuine problems.  To illustrate this point, enabling this
+	    warning by default revealed a typo in the preproc_defined.i
+	    testcase in SWIG's own testsuite.
+
+	    If you really don't want to see this warning, you can suppress it
+	    with command line option -w202 or by using this in your interface
+	    file:
+
+	    %warnfilter(SWIGWARN_PP_EVALUATION);
+
+	    Both will work with older versions of SWIG too.
+
+2022-10-04: olly
+	    #1050 Consistently define SWIG_VERSION both at SWIG-time and in
+	    the generated wrapper.  Best practice remains to check at SWIG-time
+	    where possible because that results in smaller generated wrapper
+	    sources.
+
+	    SWIGGO and SWIGJAVASCRIPT are now defined in the generated wrappers
+	    to match behaviour for all other target languages.
+
+	    The undocumented SWIGVERSION macro is no longer defined.
+
+2022-09-29: olly
+	    #2303 SWIG's internal hash tables now use a better hash function.
+
+	    The old hash function only considerd the last five characters
+	    plus the least significant bit of the last-but-sixth character,
+	    which as you might guess generated a lot of many-way collisions.
+
+	    This change seems to give about a 4% reduction in wallclock time
+	    for processing li_std_list_wrap.i from the testsuite for Python.
+	    The hash collision rate for this example drops from 39% to 0!
+
+2022-09-29: wsfulton
+            #2303 Type tables are now output in a fixed order whereas previously
+            the order may change with any minor input code change. This shouldn't
+            affect users except SWIG_TypePrettyName may output a different C/C++
+            typedef to a type - it's used mostly for showing errors when the type
+            passed to a function is wrong.
+
+2022-09-29: olly
+	    [PHP] Dynamic class properties are no longer supported by default.
+
+	    Historically PHP has supported dynamic class properties and SWIG
+	    has implemented them too (because we implement the magic __get(),
+	    __set() and __isset() methods we need to include explicit
+	    handling).
+
+	    PHP 8.2 deprecates dynamic class properties - initially they'll
+	    warn, and apparently they'll not work by default in PHP 9.0:
+	    https://wiki.php.net/rfc/deprecate_dynamic_properties
+
+	    In PHP code dynamic properties can be enabled for a class by
+	    marking that class with the attribute `#[AllowDynamicProperties]`.
+
+	    To follow this PHP change, in SWIG you now need to specify
+	    `%feature("php:allowdynamicproperties", 1) Foo;` (or
+	    `%feature("php:allowdynamicproperties", 1)` to enable it for
+	    all wrapped classes).  Unknown features are ignored, so you can add
+	    it unconditionally and it'll work with older SWIG too.
+
+	    *** POTENTIAL INCOMPATIBILITY ***
+
+2022-09-19: wsfulton
+            #1484 Fixes for class inheritance with the same name in different namespaces
+            such as:
+
+              namespace A { class Bar {}; }
+              namespace B { template<typename T, typename U> class Bar : public A::Bar {}; }
+
+2022-09-19: wsfulton
+            #2316 Remove swig.spec file and srcrpm makefile target. These are very out of date
+            and don't seem to be used by RPM based Linux distributions which have their
+            own version of swig.spec.
+
+2022-09-17: wsfulton
+            [Go, Guile, Racket, Scilab] Add throws typemaps for std::string so that thrown
+            string exception messages can be seen.
+
+2022-09-17: wsfulton
+            [Racket] Add throws typemaps for char * so that thrown string exception
+            messages can be seen from Racket.
+
+2022-09-17: wsfulton
+            [Javascript, Octave, R] Improve exceptions for %catches and exception
+            specifications for native types. String exception messages are shown as
+            the exception message instead of just the type of the exception.
+
+2022-09-17: wsfulton
+            Add missing typecheck typemaps for std::auto_ptr and std::unique_ptr to
+            fix overloading when using these types.
+
+2022-09-17: wsfulton
+            [Guile] Add error checking to SWIGTYPE and SWIGTYPE & in typemaps to prevent
+            seg faults when passing #nil to these parameter types.
+
+2022-09-16: wsfulton
+            #999 Provide SWIGTYPE MOVE typemaps in swigmove.i for implementing full
+            move semantics when passing parameters by value.
+
+2022-08-31: wsfulton
+            #999 Improve move semantics when using rvalue references.
+            The SWIGTYPE && input typemaps now assume the object has been moved.
+
+            These typemaps have been changed assuming that after the function call,
+            the rvalue reference parameter has been moved. The parameter's proxy class
+            that owns the C++ object thus has the underlying pointer set to null
+            so that the (moved from, but still valid) C++ object cannot be used again
+            and the object is additionally deleted.
+
+            *** POTENTIAL INCOMPATIBILITY ***
+
+2022-08-28: wsfulton
+            [Octave] SWIG now marshals a C/C++ NULL pointer into the null matrix, [].
+            SWIG has always marshalled the null matrix into a NULL pointer; this remains
+            and now we have consistency in representing a NULL pointer.
+
+2022-08-26: wsfulton
+            [Racket] SWIG now marshals a C/C++ NULL pointer into a null value by calling
+            scheme_make_null(), so that scheme's null? is true for a NULL C/C++ pointer value.
+
+2022-08-18: wsfulton
+            [Racket] Add support for std::unique_ptr in std_unique_ptr.i.
+            Add support for std::auto_ptr in std_auto_ptr.i.
+
+2022-08-13: wsfulton
+            [Guile] Add support for std::unique_ptr in std_unique_ptr.i.
+            Add support for std::auto_ptr in std_auto_ptr.i.
+
+2022-08-11: wsfulton
+            [Lua] Add support for std::unique_ptr in std_unique_ptr.i.
+            Add support for std::auto_ptr in std_auto_ptr.i.
+
+2022-08-05: wsfulton
+            [D] Fix occasional undefined behaviour with inheritance hierarchies, particularly
+            when using virtual inheritance as the pointers weren't correctly upcast from derived
+            class to base class when stored in the base's proxy class.
+
+2022-08-05: wsfulton
+            [D] Add support for std::unique_ptr in std_unique_ptr.i.
+            Add support for std::auto_ptr in std_auto_ptr.i.
+
+2022-08-03: wsfulton
+            [Javascript] Add support for std::unique_ptr in std_unique_ptr.i.
+            Add support for std::auto_ptr in std_auto_ptr.i.
+
+2022-08-02: wsfulton
+            [Octave] Add support for std::unique_ptr in std_unique_ptr.i.
+            Add support for std::auto_ptr in std_auto_ptr.i.
+
+2022-08-01: wsfulton
+            [Python] Add initialisers for additional members in PyHeapTypeObject
+            (builtin mode) for Python-3.11 - _ht_tpname, _spec_cache.
+
+2022-07-30: wsfulton
+            C++20 has deprecated std::basic_string<>::reserve() and the C++11 method
+            std::basic_string<>::shrink_to_fit() is a replacement that can be used.
+            std_string.i and std_wstring.i provided wrappers for reserve with the following
+            template instantiations:
+
+              %template(string) std::basic_string<char>;
+              %template(wstring) std::basic_string<wchar_t>;
+
+            The reserve method is no longer wrapped, however the shrink_to_fit() method
+            can be used as an alternative from the target language (the generated wrappers
+            call reserve() instead if C++<=20).
+
+            Note that std::basic_string<>::reserve(size_t n) is still wrapped unchanged.
+
+            *** POTENTIAL INCOMPATIBILITY ***
+
+2022-07-30: wsfulton
+            [Tcl] Add support for std::unique_ptr in std_unique_ptr.i.
+            Add support for std::auto_ptr in std_auto_ptr.i.
+
+2022-07-27: ZackerySpytz, olly
+	    #1678 Support parsing C++20 templated lambdas.
+
+2022-07-27: ZackerySpytz, olly
+	    #1622 Add support for the C++20 spaceship operator (<=>).
+
+2022-07-26: olly
+	    [Tcl] https://sourceforge.net/p/swig/bugs/977/
+	    Fix handling of long long on 32-bit platforms.  This fix raises
+	    SWIG's minimum supported Tcl version to 8.4.0 (which was released
+	    just under 20 years ago).
+
+2022-07-26: olly
+            Fix incorrect operator precedence in preprocessor expressions.
+
+2022-07-25: olly
+	    Support for C++14 binary integer literals in preprocessor expressions.
+
+2022-07-20: wsfulton
+            [C#, Java] Ensure the order of interfaces generated in proxy interfaces for the
+            %interface family of macros is the same as that parsed from the bases in C++.
+
+2022-07-20: jicks, Ingener74, olly
+	    #422 [Python] Fix mishandling of a Python class inheriting from
+	    multiple SWIG-wrapped director classes.
+
+2022-07-19: wsfulton
+            #692 [C#, Java, Perl, Python, Ruby] std::unique_ptr and std::auto_ptr typemaps
+            provided for inputs types in std_unique_ptr.i and std_auto_ptr.i.
+
+            Now these smart pointers can be used as input parameters to functions. A proxy
+            class instance transfers memory ownership of the underlying C++ object from the
+            proxy class to a smart pointer instance passed to the wrapped function.
+
+2022-07-19: jschueller
+	    [Python] #2314 Drop support for Python 3.2.
+
+2022-07-19: olly
+	    Remove remaining support code for classic macos, which has not been
+	    supported by Apple for over 20 years now.
+
+2022-07-12: wsfulton
+            #999 Performance optimisation for parameters passed by value that are C++11 movable.
+            The C++ wrappers create a temporary variable for a parameter to be passed to a
+            function. This is initially default constructed and then copy assigned from the
+            instance being passed in from the target language. This is unchanged, however,
+            when the temporary variable is passed to the wrapped function, it is now done using
+            std::move. If the type is move constructible, the move constructor will be used
+            instead of the copy constructor.
+
+2022-07-12: wsfulton
+            [Perl] Add std::auto_ptr support in std_auto_ptr.i library file.
+
+2022-07-12: erezgeva
+            [Perl] Add std::unique_ptr support in std_unique_ptr.i library file.
+
+2022-07-07: jmarrec
+	    #1158 #2286 Add basic support for C++11 attributes.  These are now
+	    crudely ignored by SWIG's parser's tokeniser, which is better than
+	    failing with a parse error.
+
+2022-07-05: ianlancetaylor
+	    [Go] #2245 Handle NULL pointers for string* conversions.
+	    Rearrange generation of director methods and rename
+	    receiver argument from p to swig_p.
+
+2022-07-03: wsfulton
+            #999 Performance optimisation for directors for classes passed by value. The directorin
+            typemaps in the director methods now use std::move on the input parameter when
+            copying the object from the stack to the heap prior to the callback into the target
+            language, thereby taking advantage of move semantics if available.
+
+2022-07-02: wsfulton
+            #1722 [C#, Java, Python, Ruby] Add std::unique_ptr support. Ported from std::auto_ptr.
+            Use the %unique_ptr(T) macro as follows for usage std::unique_ptr<T>. For example, for
+            a class called Klass:
+
+              %include "std_unique_ptr.i"
+              %unique_ptr(Klass)
+
+            Support is currently limited to only returning a std::unique_ptr from a function.
+
+2022-06-29: wsfulton
+            #999 #1044 Enhance SWIGTYPE "out" typemaps to use std::move when copying
+            objects, thereby making use of move semantics when wrapping a function returning
+            by value if the returned type supports move semantics.
+
+            Wrapping functions that return move only types 'by value' now work out the box
+            without having to provide custom typemaps.
+
+            The implementation removed all casts in the "out" typemaps to allow the compiler to
+            appropriately choose calling a move constructor, where possible, otherwise a copy
+            constructor. The implementation also required modifying SwigValueWrapper to
+            change a cast operator from:
+
+              SwigValueWrapper::operator T&() const;
+
+            to
+
+              #if __cplusplus >=201103L
+                SwigValueWrapper::operator T&&() const;
+              #else
+                SwigValueWrapper::operator T&() const;
+              #endif
+
+            This is not backwards compatible for C++11 and later when using the valuewrapper feature
+            if a cast is explicitly being made in user supplied "out" typemaps. Suggested change
+            in custom "out" typemaps for C++11 and later code:
+
+            1. Try remove the cast altogether to let the compiler use an appropriate implicit cast.
+            2. Change the cast, for example, from static_cast<X &> to static_cast<X &&>, using the
+               __cplusplus macro if all versions of C++ need to be supported.
+
+            *** POTENTIAL INCOMPATIBILITY ***
+
+2022-06-15: wsfulton
+            #2039 Add move assignment operator to SwigValueWrapper used by the
+            valuewrapper feature.
+
+2022-06-04: sethrj
+            Enhance $typemap to support typemap attributes.
+
+              $typemap(method:attribute, typepattern)
+
+            For example:
+
+              %typemap(cstype, out="object") XClass "XClass"
+              %typemap(cscode) BarClass %{
+                $typemap(cstype:out, XClass) bar() {
+                  return null;
+                }
+
+              which expands to
+
+                object bar() {
+                  return null;
+                }
+
+2022-05-30: wsfulton
+            [C#, D] Add new special variable expansion: $imfuncname.
+            Expands to the function name called in the intermediary class.
+
+2022-05-30: LindleyF
+            [Java] #2042 Add new special variable expansion: $imfuncname.
+            Expands to the function name called in the intermediary class.
+
+2022-05-28: jkuebart
+            [Java] On some versions of Android, specifically Android 6,
+            detaching the current thread from the JVM after every invocation
+            causes a memory leak.
+
+            Offer SWIG_JAVA_DETACH_ON_THREAD_END to configure a behaviour
+            where the JVM is only detached in the thread destructor.
+
+            See https://developer.android.com/training/articles/perf-jni#threads.
+
+2022-05-27: xypron
+            [Python] #2277 Define PY_SSIZE_T_CLEAN macro before #include "Python.h" as
+            recommended in Python 3.7 and later.
+
+            To avoid this macro definition, add the following to your interface file so
+            that SWIG_NO_PY_SSIZE_T_CLEAN is defined at the beginning of the C++ wrappers:
+
+              %begin %{
+              #define SWIG_NO_PY_SSIZE_T_CLEAN
+              %}
+
+2022-05-26: rokups
+            [C#] #1323 Modify SwigDerivedClassHasMethod for a more efficient director
+            implementation when calling virtual methods that are not overridden.
+
+2022-05-15: erezgeva, eiselekd
+            [Lua, Perl, Octave, PHP, Tcl] #2275 #2276 #2283 Add argcargv.i library containing
+            (int ARGC, char **ARGV) multi-argument typemaps.
+
+            Document this library in Typemaps.html.
+
+2022-05-07: KrisThielemans
+            [Python] Fix "too many initializers for 'PyHeapTypeObject'" errors
+            using PyPy 3.8 and later.
+
+2022-05-04: wsfulton
+            [C#] Add C# wchar_t * director typemaps
+
+2022-04-20: cminyard
+	    Fix an issue where newlines were not properly generated
+	    for godirectorin typemaps.  If you have a virtual function
+	    not assigned to zero, in some cases it won't generate a
+	    newline and you will see errors:
+	      example.go:1508:3: expected ';', found swig_r
+	    when compiling the go code.
+
+	    Also add an example of using goin and godirectorin and add
+	    a test for this situation.
+
+2022-04-29: jason-daly, JerryJoyce, wsfulton
+	    [C#] #1233 Add wchar_t * and std::wstring Unicode string support on Linux.
+
+2022-04-11: robinst
+	    #2257 Fix new Ruby 3.2 warning "undefining the allocator of T_DATA
+	    class swig_runtime_data".
+
+2022-04-07: olly
+	    #1750 SWIG now recognises and ignores Doxygen group commands `@{` and `@}`.
+
+2022-04-06: wsfulton
+            ./configure now enables C++11 and later C++ standards testing by default (when
+            running: 'make check').
+
+            The options to control this testing are the same:
+
+              ./configure --enable-cpp11-testing
+              ./configure --disable-cpp11-testing
+
+            But the former is now the default and the latter can be used to turn off C++11 and
+            later C++ standards testing.
+
+2022-04-06: wsfulton
+            [Python] #1635 The "autodoc" feature no longer overrides Doxygen comments
+            in the generated docstring.
+
+            If a "docstring" feature is present it will still override a Doxygen comment.
+            If the "autodoc" feature is also present, the combined "autodoc" and "docstring"
+            will override the Doxygen comment. If no "docstring" is present then the
+            "autodoc" feature will not be generated when there is a Doxygen comment.
+
+            This way the "autodoc" feature can be specified and used to provide documentation
+            for 'missing' Doxygen comments.
+
+            *** POTENTIAL INCOMPATIBILITY ***
+
+2022-04-01: olly
+	    Remove undocumented and non-functional -browse command line option.
+
+2022-03-26: eltoder
+            [Python] #1684 Use different capsule names with and without -builtin
+
+            Types generated with and without -builtin are not compatible. Mixing
+            them in a common type list leads to crashes. Avoid this by using
+            different capsule names: "type_pointer_capsule" without -builtin and
+            "type_pointer_capsule_builtin" with.
+
+2022-03-25: wsfulton
+            The debug command line options that display parse tree nodes
+            (-debug-module, -debug-top, -debug-symtabs) now display previously hidden
+            linked list pointers which are useful for debugging parse trees.
+
+            Added new command line option -debug-quiet. This suppresses the display
+            of most linked list pointers and symbol table pointers in the parse tree nodes.
+
+            The keys in the parse tree node are now shown in alphabetical order.
+
+2022-03-24: wsfulton
+            #2244 Fix using declaration in derived class bugs when all the base
+            class's overloaded methods were overridden in the derived class -
+            fixes "multiply defined" errors.
+
+2022-03-23: wsfulton
+            [Python] #1779 The -py3 option is deprecated and now has no effect on the
+            code generated. Use of this option results in a deprecated warning.
+            The related SWIGPYTHON_PY3 macro that this option defined is no longer generated.
+
+            Note that %pythonnondynamic feature generates a metaclass that works on both
+            Python 2 and Python 3.
+
+2022-03-21: wsfulton
+            [Python] #1779 pyabc.i for abstract base classes now supports versions of
+            Python prior to 3.3 by using the collection module for these older versions.
+            Python-3.3 and later continue to use the collections.abc module.
+            The -py3 option no longer has any effect on the %pythonabc feature.
+
+2022-03-21: jschueller, jim-easterbrook, wsfulton
+            [Python] #2137 C++ static member functions no longer generate a "flattened"
+            name in the Python module. For example:
+
+              s = example.Spam()
+              s.foo()               # Spam::foo() via an instance
+              example.Spam.foo()    # Spam::foo() using class method
+              example.Spam_foo()    # Spam::foo() "flattened" name
+
+            The "flattened" name is no longer generated, but can be generated
+            by using the new -flatstaticmethod option.
+
+            *** POTENTIAL INCOMPATIBILITY ***
+
+2022-03-18: ianlancetaylor
+	    [Go] #337 Implement %extend base methods in child classes.
+
+2022-03-17: olly
+	    [Python] #1779 SWIG's Python test-suite and examples are now
+	    run with Python 3 by default.  To run them with Python 2, set
+	    PY2 to a non-empty value, e.g.:
+
+	    make check-python-test-suite PY2=1
+
+2022-03-16: olly
+	    [Go] #683 -intgosize is now optional - if not specified the
+	    generated C/C++ wrapper code will use ptrdiff_t for intgo and
+	    size_t for uintgo.
+
+2022-03-15: ianlancetaylor
+	    [Go] Add typemaps for std::string*.
+
+2022-03-15: ianlancetaylor
+	    [Go] Don't convert arrays to pointers if there is a "gotype"
+	    typemap entry.
+
+2022-03-15: ianlancetaylor
+	    [Go] Add documentation note about Go and C++ exceptions.
+
+2022-03-12: wsfulton
+            #1524 %interface family of macros no longer contain the getter/setter
+            methods for wrapping variables. The interface only contains
+            virtual and non-virtual instance methods, that is, no static methods.
+            Enums are also no longer added to the interface (affects Java only where
+            they were missing from the proxy class, C# never had them in the interface).
+
+            *** POTENTIAL INCOMPATIBILITY ***
+
+2022-03-12: wsfulton
+            #1277 Fixes for the family of %interface macros, %interface,
+            %interface_impl and %interface_custom fixes for overloaded methods
+            in an inheritance chain.
+
+            When C++ methods are not able to be overloaded in a derived class,
+            such as when they differ by just const, or the target language
+            parameters types are identical even when the C++ parameter types
+            are different, SWIG will ignore one of the overloaded methods with
+            a warning. A %ignore is required to explicitly ignore one of the
+            overloaded methods to avoid the warning message. Methods added
+            in the derived classes due to one of the %interface macros are now
+            similarly ignored/not added to the derived class.
+
+            The methods added to the derived classes can now also be modified
+            via %feature and %rename.
+
+2022-03-08: ianlancetaylor
+	    [Go] Treat a nil argument as a NULL pointer.
+
+2022-03-08: ianlancetaylor
+	    [Go] Add documentation notes about thread local storage.
+
+2022-03-08: olly
+	    #1006 SWIG now copes with an interface filename specified on the
+	    command line which contains a closing parenthesis `)`, and more
+	    generally with attributes to `%include` and `%import` which
+	    are quoted and contain parentheses.
+
+2022-03-07: Omar Medina
+	    [Tcl] https://sourceforge.net/p/swig/bugs/1290/
+	    Fix SWIG_AsWCharPtrAndSize() to actually assign to result
+	    variable.  It looks like SWIG/Tcl wide character handling is
+	    currently fundamentally broken except on systems which use wide
+	    characters as the system encoding, but this should fix wrapping
+	    functions which take a wide string as a parameter on Microsoft
+	    Windows.
+
+2022-03-07: olly
+	    [Javascript] #682 Fix handling of functions which take void*.
+
+2022-03-06: olly
+	    SWIG should now reliably exit with status 0 if the run was
+	    successful and status 1 if there was an error (or a warning and
+	    -Werror was in effect).
+
+	    Previously in some situations SWIG would try to exit with the
+	    status set to the number of errors encountered, but that's
+	    problematic - for example if there were 256 errors this would
+	    result in exit status 0 on most platforms.  Also some error
+	    statuses have special meanings e.g. those defined by <sysexits.h>.
+	    Also SWIG/Javascript tried to exit with status -1 in a few places
+	    (which typically results in exit status 255).
+
+2022-03-05: wsfulton
+            #1441 Fix using declaration in derived class incorrectly introducing a method
+            from a base class when the using declaration is declared before the method
+            declaration. Problem occurred when within a namespace and the parameter types
+            in the method signatures were not fully qualified.
+
+2022-03-05: ianlancetaylor
+	    [Go] Treat non-const references as pointers.
+
+2022-03-05: ianlancetaylor
+	    In SWIG Go testsuite, fail test if "go build" fails.
+
+2022-03-03: olly
+	    #1901 #2223 SWIG should now always exit cleanly if memory
+	    allocation fails, including removing any output files created
+	    during the current run.
+
+	    Previously most places in the code didn't check for a NULL return
+	    from malloc()/realloc()/calloc() at all, typically resulting in
+	    undefined behaviour; some places used assert() to check for a NULL
+	    return (which is a misuse of assert() and such checks disappear if
+	    built with NDEBUG defined leaving us back with undefined
+	    behaviour).
+
+2022-03-03: olly
+	    #891 Report errors for typemap attributes without a value
+	    (previously SWIG segfaulted) and for typemap types with a value
+	    (previously the value was quietly ignored).
+
+	    The old way of specifying a language name in the typemap attributes
+	    is no longer supported (it has been deprecated for 16 years).
+
+2022-03-02: geographika, wsfulton
+            [Python] #1951 Add Python variable annotations support.
+
+            Both function annotations and variable annotations are turned on using the
+            "python:annotations" feature. Example:
+
+              %feature("python:annotations", "c");
+
+              struct V {
+                float val;
+              };
+
+            The generated code contains a variable annotation containing the C float type:
+
+              class V(object):
+                  val: "float" = property(_example.V_val_get, _example.V_val_set)
+                  ...
+
+            Python 3.5 and earlier do not support variable annotations, so variable
+            annotations can be turned off with a "python:annotations:novar" feature flag.
+            Example turning on function annotations but not variable annotations globally:
+
+              %feature("python:annotations", "c");
+              %feature("python:annotations:novar");
+
+            or via the command line:
+
+              -features python:annotations=c,python:annotations:novar
+
+            *** POTENTIAL INCOMPATIBILITY ***
+
+2022-02-27: wsfulton
+            [Python] #735 #1561 Function annotations containing C/C++ types are no longer
+            generated when using the -py3 option. Function annotations support has been
+            moved to a feature to provide finer grained control. It can be turned on
+            globally by adding:
+
+              %feature("python:annotations", "c");
+
+            or by using the command line argument:
+
+              -features python:annotations=c
+
+            Also see entry dated 2022-03-02, regarding variable annotations.
+
+            *** POTENTIAL INCOMPATIBILITY ***
+
+2022-02-26: wsfulton
+            #655 #1840 Add new warning WARN_LANG_USING_NAME_DIFFERENT to warn when a
+            method introduced by a using declaration in a derived class cannot
+            be used due to a conflict in names.
+
+2022-02-24: olly
+	    #1465 An invalid preprocessor expression is reported as a pair of
+	    warnings with the second giving a more detailed message from the
+	    expression evaluator.  Previously SWIG prefixed the second message
+	    with "Error:" - that was confusing as it's actually only a warning
+	    by default so we've now dropped this prefix.
+
+	    Before:
+
+	    x.i:1: Warning 202: Could not evaluate expression '1.2'
+	    x.i:1: Warning 202: Error: 'Floating point constant in preprocessor expression'
+
+	    Now:
+
+	    x.i:1: Warning 202: Could not evaluate expression '1.2'
+	    x.i:1: Warning 202: Floating point constant in preprocessor expression
+
+2022-02-23: olly
+	    #1384 Fix a preprocessor expression evaluation bug.  A
+	    subexpression in parentheses lost its string/int type flag and
+	    instead used whatever type was left in the stack entry from
+	    previous use.  In practice we mostly got away with this because
+	    most preprocessor expressions are integer, but it could have
+	    resulted in a preprocessor expression incorrectly evaluating as
+	    zero.  If -Wextra was in use you got a warning:
+
+	    Warning 202: Error: 'Can't mix strings and integers in expression'
+
+2022-02-21: davidcl
+	    [Scilab] Improve 5.5.2, 6.0.0 and 6.1.0 support.
+
+	    For Scilab 5, long names are reduced to small names preserving the 
+	    class prefix and accessor suffix (get or set).
+
+	    For Scilab 6, long names with the class prefix and accessor suffix
+	    should be used on the user code.
+
+	    The `-targetversion` option has been removed as the generated code
+	    now detects the Scilab version in loader.sce or builder.sce.
+
+	    *** POTENTIAL INCOMPATIBILITY ***
+
+2022-02-20: wsfulton
+            Fix %warnfilter warning suppress for warning 315 SWIGWARN_PARSE_USING_UNDEF.
+
+2022-02-17: olly
+	    [PHP] https://sourceforge.net/p/swig/bugs/1211/
+	    Fix to call cleanup code in exception situations and not to invoke
+	    the freearg typemap twice in certain situations.
+
+2022-02-15: olly
+	    #300 #368 Improve parser handling of % followed immediately by
+	    an identifier.  If it's not a recognised directive the scanner
+	    now emits MODULO and then rescans what follows, and if the parser
+	    then gives a syntax error we report it as an unknown directive.
+	    This means that `a%b` is now allowed in an expression, and that
+	    things like `%std::vector<std::string>` now give an error rather
+	    than being quietly ignored.
+
+2022-02-11: adr26
+            [Python] #2154 Fix memory leak.
+
+            SWIG python objects were being freed after the corresponding SWIG
+            module information was destroyed in Python 3, causing leaks when as
+            a result the object destructor could not be invoked. To prevent this
+            misordering, SWIG python objects now obtain a reference to the
+            Python capsule wrapping the module information, so that the module
+            information is correctly destroyed after all SWIG python objects
+            have been freed (and corresponding destructors invoked).
+
+2022-02-10: olly
+	    [Tcl] https://sourceforge.net/p/swig/bugs/1207/
+	    https://sourceforge.net/p/swig/bugs/1213/
+
+	    Fix Tcl generic input typemap for std::vector.
+
+2022-02-07: sethrj
+            #2196 Add alternative syntax for specifying fragments in typemaps.
+
+            New syntax:
+              %typemap("in", fragment="frag1", fragment="frag2", fragment="frag3") {...}
+            which is equivalent to:
+              %typemap(in, fragment="frag1,frag2,frag3") {...}
+
+
+2022-02-07: olly
+	    #1806 Remove support for the "command" encoder, which was mostly
+	    intended for use in `%rename` - most uses can be achieved using
+	    the "regex" encoder, so we recommend using that instead.
+
+	    The "command" encoder suffers from a number of issues - as the
+	    documentation for it admitted, "[it] is extremely slow compared to
+	    all the other [encoders] as it involves spawning a separate process
+	    and using it for many declarations is not recommended" and that it
+	    "should generally be avoided because of performance
+	    considerations".
+
+	    But it's also not portable.  The design assumes that `/bin/sh`
+	    supports `<<<` but that's a bash-specific feature so it doesn't
+	    work on platforms where `/bin/sh` is not bash - it fails on
+	    Debian, Ubuntu and probably some other Linux distros, plus most
+	    non-Linux platforms.  Microsoft Windows doesn't even have a
+	    /bin/sh as standard.
+
+	    Finally, no escaping of the passed string is done, so it has
+	    potential security issues (though at least with %rename the input
+	    is limited to valid C/C++ symbol names).
+
+2022-02-06: olly
+	    #2193 -DFOO on the SWIG command line now sets FOO to 1 for
+	    consistency with C/C++ compiler preprocessors.  Previously
+	    SWIG set FOO to an empty value.
+
+	    Existing invocations of SWIG with `-DFOO` where the empty value
+	    matters can be updated to `-DFOO=` which should work with both
+	    old and new releases of SWIG.
+
+	    *** POTENTIAL INCOMPATIBILITY ***
+
+2022-02-06: sethrj
+	    #2194 Classes that are non-assignable due to const data or const
+	    reference members are now automatically detected.
+
+2022-02-04: friedrichatgc
+	    [Octave] #1672 Fix for isobject for Octave 4.4 - 6.0.
+
+2022-02-03: olly
+	    [C#] #283 #998 Fix memory leak in directorin typemap for
+	    std::string.
+
+2022-02-03: olly
+	    [Python] #967 Make `self` parameter available to user typemaps.
+
+2022-02-03: teythoon
+	    [Python] #801 Fix -Wunused-parameter warnings with builtin,
+
+2022-02-03: teythoon
+	    #801 Fix -Wstrict-prototypes warnings in generated pointer
+	    functions.
+
+2022-02-03: olly
+	    #660 https://sourceforge.net/p/swig/bugs/1081/
+	    Default parameter values containing method calls are now parsed and
+	    handled - e.g. `x->foo(3,4)` and `y.z()`.
+
+2022-02-02: olly
+	    [Ruby] https://sourceforge.net/p/swig/bugs/1136/ Fix remove of prefix
+	    from method name to only remove it at the start.
+
+2022-02-01: olly
+	    #231 Handle returning an object by reference in a C++ trailing
+	    return type.
+
+2022-02-01: davidcl
+            [Scilab] #745 use SWIG_<module>_Init() as a C module init function.
+
+2022-02-01: olly
+	    [OCaml] #2083 Fix to work when CAML_SAFE_STRING is on, which it is
+	    by default in recent Ocaml releases.
+
+2022-01-31: mreeez
+	    https://sourceforge.net/p/swig/bugs/1147/
+	    Fix copyToR() generated for a struct in a namespace.
+
+2022-01-29: fschlimb
+	    #655 Better handling of using declarations.
+
+2022-01-29: dontpanic92
+	    [Go] #676 Fix code generated for a C++ class with a non-capitalised
+	    name.
+
+2022-01-26: trex58
+	    #1919 #1921 #1923 Various fixes for AIX portability.
+
+2022-01-26: olly
+	    #1935 Don't crash on an unclosed HTML tag in a doxygen comment
+	    when -doxygen is specified.
+
+2022-01-25: olly
+	    Constant expressions now support member access with `.` such as
+	    `foo.bar`.  Previous this only worked in a case like `x->foo.bar`.
+
+2022-01-25: olly
+	    #2091 Support most cases of `sizeof` applied to an expression
+	    in constant expressions.  Previously there was only support for
+	    `sizeof(<type>)` and expressions which syntactically look like a
+	    type (such as `sizeof(foo)`).
+
+2022-01-25: olly
+	    #80 #635 https://sourceforge.net/p/swig/bugs/1139/
+	    Add support for parsing common cases of `<` and `>` comparisons
+	    in constant expressions.  Adding full support for these seems hard
+	    to do without introducing conflicts into the parser grammar, but in
+	    fact all reported cases have had parentheses around the comparison
+	    and we can support that with a few restrictions on the left side of
+	    `<`.
+
+2022-01-25: wsfulton
+            New warning 327 for extern templates, eg:
+
+              extern template class std::vector<int>;
+              extern template void Func<int>();
+
+            results in warning
+
+              example.i:3: Warning 327: Extern template ignored.
+              example.i:4: Warning 327: Extern template ignored.
+
+            Extern template classes previously resulted in warning 320.
+
+2022-01-24: romintomasetti
+            #2131 #2157 C++11 extern function template parsing error fix.
+
+2022-01-21: wsfulton
+            #2120 #2138 Replace legacy PCRE dependency with PCRE2.
+            This requires changes for building SWIG from source. See updated
+            html documentation in Preface.html and Windows.html. Updated
+            instructions are also shown when running ./configure if PCRE2 is not
+            found. Note that debian based systems can install PCRE2 using:
+
+              apt install libpcre2-dev
+
+            Note that https://github.com/swig/swig/wiki/Getting-Started also has
+            updated information for building from source.
+
+2022-01-19: olly
+	    [PHP] #2027 Automatically generate PHP type declarations for PHP 8.
+	    The generate code still compiles for PHP 7.x, but without type
+	    declarations since PHP 7.x has much more limited type declaration
+	    support.
+
+2022-01-18: olly
+	    [Perl] #1629 Perl 5.8.0 is now the oldest version we aim to support.
+
+2022-01-14: wsfulton
+            [Python] Fix %callback and specifying the callback function as a
+            static member function using Python staticmethod syntax, such as
+            Klass.memberfunction instead of Klass_memberfunction when using
+            -builtin and -fastproxy.
+
+2022-01-11: wsfulton
+            [Python] Accept keyword arguments accessing static member functions when
+            using -builtin and kwargs feature and Python class staticmethod syntax.
+            The missing keyword argument support was only when using the
+            class staticmethod syntax, such as Klass.memberfunction, and not when
+            using the flat static method syntax, such as Klass_memberfunction.
+
+2022-01-04: juierror
+            [Go] #2045 Add support for std::array in std_array.i.
+
+2021-12-18: olly
+	    [PHP] Add PHP keyword 'readonly' (added in 8.1) to the list SWIG
+	    knows to automatically rename.  This keyword is special in that PHP
+	    allows it to be used as a function (or method) name.
+
+2021-12-07: vstinner
+            [Python] #2116 Python 3.11 support: use Py_SET_TYPE()
+
+2021-12-05: rwf1
+            [Octave] #2020 #1893 Add support for Octave 6 up to and including 6.4.
+            Also add support for compiling with -Bsymbolic which is used by default
+            by mkoctfile.
+
+2021-12-02: jsenn
+            [Python] #2102 Fixed crashes when using embedded Python interpreters. 
+
+2021-11-12: wsfulton
+            [Javascript] v8 and node only. Fix mismatched new char[] and free()
+            when wrapping C code char arrays. Now calloc is now used instead of
+            new char[] in SWIG_AsCharPtrAndSize.
+
+2021-10-03: ajrh1
+            [Perl] #2074: Avoid -Wmisleading-indentation in generated code
+            when using gcc11.
+
+2021-10-03: jschueller
+            [CMake] #2065: Add option to enable or disable PCRE support.
+
+2021-09-16: ianlancetaylor
+            [Go] Improved _cgo_panic implementation.
+
+2021-09-16: ianlancetaylor
+            [Go] Don't use crosscall2 for panicking. Instead rely on documented
+            and exported interfaces.
+
+2021-09-14: ianlancetaylor
+            [Go] Remove -no-cgo option (long unsupported in Go)
+
+2021-05-04: olly
+	    [PHP] #2014 Throw PHP exceptions instead of using PHP errors
+
+	    PHP exceptions can be caught and handled if desired, but if they
+	    aren't caught then PHP exits in much the same way as it does for a
+	    PHP error.
+
+	    In particular this means parameter type errors and some other cases
+	    in SWIG-generated wrappers now throw a PHP exception, which matches
+	    how PHP's native parameter handling deals with similar situations.
+
+	    `SWIG_ErrorCode()`, `SWIG_ErrorMsg()`, `SWIG_FAIL()` and `goto thrown;`
+	    are no longer supported (these are really all internal implementation
+	    details and none are documented aside from brief mentions in CHANGES
+	    for the first three).  I wasn't able to find any uses in user interface
+	    files at least in FOSS code via code search tools.
+
+	    If you are using these:
+
+	    Use `SWIG_PHP_Error(code,msg);` instead of `SWIG_ErrorCode(code);
+	    SWIG_ErrorMsg(msg);` (which will throw a PHP exception in SWIG >= 4.1
+	    and do the same as the individual calls in older SWIG).
+
+	    `SWIG_FAIL();` and `goto thrown;` can typically be replaced with
+	    `SWIG_fail;`.  This will probably also work with older SWIG, but
+	    please test with your wrappers if this is important to you.
+
+	    *** POTENTIAL INCOMPATIBILITY ***
+
+2021-05-17: adr26
+            [Python] #1985 Fix memory leaks:
+
+            1. Python object references were being incorrectly retained by
+            SwigPyClientData, causing swig_varlink_dealloc() never to run / free
+            memory. SwigPyClientData_New() / SwigPyClientData_Del() were updated
+            to fix the object reference counting, causing swig_varlink_dealloc()
+            to run and the memory swig_varlink owns to be freed.
+
+            2. SwigPyClientData itself was not freed by SwigPyClientData_Del(),
+            causing another heap leak. The required free() was added to
+            SwigPyClientData_Del()
+
+            3. Fix reference counting/leak of python cached type query
+
+            4. Fix reference counting/leak of SwigPyObject dict (-builtin)
+
+            5. Python object reference counting fixes for out-of-memory
+            scenarios were added to: SWIG_Python_RaiseOrModifyTypeError(),
+            SWIG_Python_AppendOutput(), SwigPyClientData_New(),
+            SwigPyObject_get___dict__() and SwigPyObject_format()
+
+            6. Add error handling for PyModule_AddObject() to
+            SWIG_Python_SetModule() (failure could be caused by OOM or a name
+            clash caused by malicious code)
+
+2021-05-13: olly
+	    [UFFI] #2009 Remove code for Common Lisp UFFI.  We dropped support
+	    for it in SWIG 4.0.0 and nobody has stepped forward to revive it in
+	    over 2 years.
+
+2021-05-13: olly
+	    [S-EXP] #2009 Remove code for Common Lisp S-Exp.  We dropped
+	    support for it in SWIG 4.0.0 and nobody has stepped forward to
+	    revive it in over 2 years.
+
+2021-05-13: olly
+	    [Pike] #2009 Remove code for Pike.  We dropped support for it in
+	    SWIG 4.0.0 and nobody has stepped forward to revive it in over 2
+	    years.
+
+2021-05-13: olly
+	    [Modula3] #2009 Remove code for Modula3.  We dropped support for it
+	    in SWIG 4.0.0 and nobody has stepped forward to revive it in over 2
+	    years.
+
+2021-05-13: olly
+	    [CLISP] #2009 Remove code for GNU Common Lisp.  We dropped support
+	    for it in SWIG 4.0.0 and nobody has stepped forward to revive it in
+	    over 2 years.
+
+2021-05-13: olly
+	    [Chicken] #2009 Remove code for Chicken.  We dropped support for it
+	    in SWIG 4.0.0 and nobody has stepped forward to revive it in over 2
+	    years.
+
+2021-05-13: olly
+	    [Allegrocl] #2009 Remove code for Allegro Common Lisp.  We dropped
+	    support for it in SWIG 4.0.0 and nobody has stepped forward to
+	    revive it in over 2 years.
+
+2021-05-04: olly
+	    [PHP] #1982 #1457 https://sourceforge.net/p/swig/bugs/1339/
+	    SWIG now only use PHP's C API to implement its wrappers, and no
+	    longer generates PHP code to define classes.  The wrappers should
+	    be almost entirely compatible with those generated before, but
+	    faster and without some previously hard-to-fix bugs.
+
+	    The main notable difference is SWIG no longer generates a .php
+	    wrapper at all by default (only if %pragma(php) code=... or
+	    %pragma(php) include=... are specified in the interface file).
+	    This also means you need to load the module via extension=...
+	    in php.ini, rather than letting the dl() in the generated
+	    .php wrapper load it (but dl() has only worked for command-line
+	    PHP for some years now).
+
+	    *** POTENTIAL INCOMPATIBILITY ***
+
+2021-04-30: olly
+	    #1984 Remove support for $source and $target.
+	    These were officially deprecated in 2001, and attempts to use them have
+	    resulted in a warning (including a pointer to what to update them to)
+	    for most if not all of that time.
+
+2021-04-27: wsfulton
+            #1987 [Java] Fix %interface family of macros for returning by const
+            pointer reference.
+
+2021-04-19: olly
+	    Fix use of uninitialised variable in the generated code for an
+	    empty typecheck typemap, such as the dummy one we include for
+	    std::initializer_list.
+
+2021-04-12: olly
+	    #1777 [Python] Specifying -py3 now generates a check for Python
+	    version >= 3.0.
+
+2021-03-26: olly
+	    [PHP] Add PHP keywords 'fn' (added in 7.4) and 'match' (added in
+	    8.0) to the list SWIG knows to automatically rename.
+
+2021-03-23: wsfulton
+            #1942 [Python] Fix compilation error in wrappers when using -builtin
+            and wrapping varargs in constructors.
+
+2021-03-22: goto40
+            #1977 Fix handling of template template parameters.
+
+2021-03-21: olly
+	    #1929, #1978 [PHP] Add support for PHP 8.
+
+2021-03-19: wsfulton
+            #1610 Remove -ansi from default compilation flags.
+
+2021-03-19: dot-asm
+            #1934 [Java] Clean up typemaps for long long arrays.
+
+2021-03-19: olly
+	    #1527 [PHP] Improve PHP object creation in directorin case.
+	    Reportedly the code we were using in this case gave segfaults in
+	    PHP 7.2 and later - we've been unable to reproduce these, but the
+	    new approach is also simpler and should be bit faster too.
+
+2021-03-18: olly
+	    #1655 [PHP] Fix char* typecheck typemap to accept PHP Null like the
+	    corresponding in typemap does.
+
+2021-03-18: olly
+	    #1900, #1905 [PHP] Fix wrapping of overloaded directed methods with
+	    non-void return.
+
+2021-03-11: murillo128
+            #1498 [Javascript] Support type conversion.
+
+2021-03-06: nshmyrev
+            #872 [Javascript] Various typemap issues in arrays_javascript.i fixed.
+
+2021-03-03: vaughamhong
+            #577 [Javascript] Implemented SetModule/GetModule for JSC to allow type sharing
+            across modules.
+
+2021-03-01: xantares, Oliver Buchtala, geographika
+            #1040 Add support for building SWIG with CMake. See documentation in Windows.html.
+
+2021-03-01: vadz
+            #1952 Fix incorrect warning "Unknown Doxygen command: ."
+
+2021-02-28: p2k
+            #969 [Javascript] v8/node - prevent crash calling a constructor without new keyword.
+
+2021-02-28: alecmev
+            #405 #1121 [Javascript] Fix OUTPUT typemaps on methods that don't return void.
+            The output value is appended to the return value.
+
+2021-02-26: murillo128, wsfulton
+            #1269 [Javascript] Fix handling of large positive unsigned long and
+            unsigned long long values.
+
+2021-02-24: tomleavy, yegorich, tungntpham
+            #1746 [Javascript] Add support for Node v12, v14 and v16.
+            SWIG support for Node is now for v6 and later only.
+
+2020-02-09: ZackerySpytz
+            #1872 Fix typos in attribute2ref macros.
+
+2020-10-10: wsfulton
+            [Javascript] Fix so that ccomplex.i interface to file can be used.
+
+2020-10-10: wsfulton
+            #252 complex can now be used as a C identifier and doesn't give a syntax error.
+
+2020-10-10: lpsinger
+            #1770 Correct C complex support.
+            _Complex is now parsed as a keyword rather than complex as per the C99 standard.
+            The complex macro is available in the ccomplex.i library file along with other
+            complex number handling provided by the complex.h header.
+
+2020-10-07: ZackerySpytz
+            [Python] #1812 Fix the error handling for the PyObject_GetBuffer() calls in
+            pybuffer.i.
+
+2020-10-07: treitmayr
+            #1824 Add missing space in director method declaration returning
+            const pointer.
+
+2020-10-07: adelva1984
+            #1859 Remove all (two) exceptions from SWIG executable.
+
+2020-09-25: wsfulton
+            [C#, Java] #1874 Add ability to change the modifiers for the interface
+            generated when using the %interface macros.
+
+            For C# use the 'csinterfacemodifiers' typemap.
+            For Java use the 'javainterfacemodifiers' typemap.
+
+            For example:
+
+              %typemap(csinterfacemodifiers) X "internal interface"
+
+2020-09-24: geefr
+            [C#] #1868 Fix wchar_t* csvarout typemap for member variable wrappers.
+
+2020-08-28: wsfulton
+            [Java] #1862 Fix crashes in swig_connect_director during director class construction
+            when using the director class from multiple threads - a race condition initialising
+            block scope static variables. The fix is guaranteed when using C++11, but most
+            compilers also fix it when using C++03/C++98.
+
+2020-08-16: wsfulton
+            [Python] Add missing initializer for member '_heaptypeobject::ht_module' when using
+            -builtin to complete Python 3.9 support.
+
+2020-08-16: wsfulton
+            [Python] Remove PyEval_InitThreads() call for Python 3.7 and later as Python calls
+            it automatically now. This removes a deprecation warning when using Python 3.9.
+
+2020-08-15: wsfulton
+            [Python] All Python examples and tests are written to be Python 2 and Python 3
+            compatible, removing the need for 2to3 to run the examples or test-suite.
+
+2020-08-13: wsfulton
+            [C#] Add support for void *VOID_INT_PTR for member variables.
+
+2020-07-29: chrisburr
+            #1843 [Python] Compilation error fix in SwigPyBuiltin_SetMetaType when using PyPy.
+
+2020-06-14: ZackerySpytz
+            #1642 #1809 Fix virtual comparison operators in director classes by removing an
+            incorrect space in the function name (for example, operator= = is now operator==).
+
+Version 4.0.2 (8 Jun 2020)
+==========================
+
+2020-06-07  vigsterkr
+            [Ruby] #1717 Nil fix mangling strings
+
+2020-06-07  vadz
+            #1748 Fix doxygen comments quoting issue
+
+2020-06-07  munoah
+            #1800 Escape spaces in file paths for dependencies (-M -MM etc)
+
+2020-06-06  andreas-schwab
+            [Ruby] #1801 Fix encoding on big endian systems when wrapping std::wstring.
+
+2020-05-31  kwwette
+            [Octave] #1789 error handling improvements and return error code on exit for SWIG wrapped modules.
+
+2020-05-30  msteinbeck
+            [D] #1593 Replace broken imports when using newer versions of D.
+
+2020-05-29: ZackerySpytz
+            [Python] #1716 Performance improvements when converting strings when using Python >= 3.3.
+
+2020-05-28: ZackerySpytz
+            #1776 Quite dramatically decrease run times when generating very large interface files by changing
+            some internal memory pool sizes.
+
+2020-05-28: mcfarljm
+            #1788 Fix handling of Doxygen \endlink command.
+
+2020-05-24: vapier
+            [Javascript] #1796 Fix pkg-config invocation in configure.
+
+2020-04-30: kwwette
+            [Octave] Fix exception raising for newer Octave versions
+            Since (at least) Octave 5.1.0, the Octave error() function now raises a C++ exception,
+            which if uncaught immediately exits a SWIG wrapper function, bypassing any cleanup code
+            that may appear after a "fail:" label. This patch adds a "try { ... } catch(...) { }"
+            block around the contents of SWIG wrapper functions to first execute the cleanup code
+            before rethrowing any exception raised. It is backward compatible with earlier versions
+            of Octave where error() does not raise an exception, which will still branch to the
+            "fail:" block to execute cleanup code if an error is encountered.
+
+            Note that the new "try { ... } catch(...) { }" block will localise any local variables
+            used in typemaps that were NOT declared through SWIG's %typemap(...) syntax, so it's
+            possible this could break existing SWIG wrappers which were implicitly sharing local
+            variables between typemaps. This can be fixed, however, by declaring local variables
+            which need to be shared between typemaps through SWIG's %typemap(...) syntax.
+
+2020-02-18: ryannevell
+            [Lua] #1728 Add support for LUA lightuserdata to SWIG_Lua_ConvertPtr.
+
+2020-02-18: dmach
+            [Ruby] #1725 Fix gcc -Wcatch-value warnings.
+
+2020-02-14: treitmayr
+            #1724 Fix wrapping of abstract user-defined conversion operators.
+
+2020-02-13: ddurham2
+            [Python] #1512 Fix memleak when using STL containers of shared_ptr objects.
+
+2020-02-06: wsfulton
+            [Python] #1673 #1674 Fix setting 'this' when extending a proxy class with __slots__.
+
+2020-01-31: vadz
+            [Ruby] #1651 Add std::auto_ptr<> typemaps.
+
+2020-01-31: ZackerySpytz
+            [Python] #1700 The Python C API functions PyBytes_AsStringAndSize() and
+            PyString_AsStringAndSize() are now checked for failure.
+
+2020-01-31: vadz
+            [Python] #1710 Fix crash parsing empty docstrings.
+
+2020-01-30: Alzathar
+            [R] #910 #914 Fix R memory leak on exception.
+
+2020-01-30: richardbeare
+            [R] #1511 Fix bug wrapping functions. These were previously incorrectly wrapped as if
+            they were variables. This happened when 'get' or 'set' was in the name of the function
+            or method, but sometimes also in some other circumstances. If you were using R
+            attribute syntax to access these methods, you'll need to switch to calling them as R
+            methods.
+
+            *** POTENTIAL INCOMPATIBILITY ***
+
+2020-01-24: etse-dignitas, wsfulton
+            [C#, D, Java] #1533 Fix upcasting for shared_ptr's of templated types.
+
+2020-01-16: mcfarljm
+            #1643 #1654 When using -doxygen, fix segfault when nameless parameters or vararg parameters
+            are used.
+
+2020-01-16: mcfarljm
+            #1632 #1659 Fix newline handling for doxygen "///" comments.
+
+2020-01-14: mcfarljm
+            #1647 #1656 Fix crash handling empty doxygen comments.
+
+2020-01-14: mcfarljm
+            #1608 Improve doxygen support.
+            - Add support for \param[] commands such as: \param[in].
+            - Optional arguments are marked as 'optional' in pydoc.
+            - Improve support for \code commands so that other languages are supported as code blocks.
+              Support added for java, c and py.  For example Python: \code{.py} ... \endcode
+            - Fix doxygen handling of \em and \p tags for Python.
+
+2020-01-13: wsfulton
+            [Python] #1595 Python -builtin constructors silently ignored keyword arguments.
+            Instead of silently ignoring them, now a "TypeError: f() takes no keyword arguments"
+            exception is thrown if keyword arguments are used. Hence constructors and normal methods/
+            functions behave in the same way. Note, -keyword should be used with -builtin to obtain
+            keyword argument support.
+
+2020-01-05: jschueller shadchin
+            [Python] #1670 #1696 Add missing field initializers introduced in python 3.8:
+            tp_vectorcall and tp_print.
+
+2020-01-05: friedrichatgc
+            [Octave] #1688 Change swig_this() to use size_t instead of long for compatibility
+            with Windows 64 bit.
+
+2020-01-05: treitmayr
+            [Ruby] #1692 #1689 Add support for Ruby 2.7
+
+2019-12-30: treitmayr
+            [Ruby] #1653 #1668 Fix code generated when using -globalmodule option.
+
+2019-12-29: ZackerySpytz
+            [OCaml] #1686 Fix compilation errors with OCaml 4.09.0.
+
+2019-12-10: wsfulton
+            #1679 Fix parsing of C++11 identifiers with special meaning (final and override) when
+            they are used as part of the scope name of an identifier, such as a namespace name.
+
+2019-11-26: wsfulton
+            [C#] #1628 'out' or 'ref' used in a cstype typemap was not always stripped out in parts
+            of director code generation.
+
+2019-11-01: wsfulton
+            [Python] #1595 Fix bug in support for keyword arguments (kwargs feature or -keyword)
+            when using -builtin. The fix is in the argument error checking when wrapping zero
+            argument constructors only.
+
+Version 4.0.1 (21 Aug 2019)
+===========================
+
+2019-08-20: TekuConcept
+            [Javascript] #1535 Add %native support to Javascript.
+
+2019-08-20: bkotzz
+            [Java] #1616 Add SWIG_JavaIllegalStateException to support throwing
+            java.lang.IllegalStateException from JNI code.
+
+2019-08-19: sjml
+            [Lua] #1596 tostring output changes to show the underlying C/C++ pointer.
+
+2019-08-08: rokups
+            [C#, Java] #1601 Fix invalid code generated for "%constant enum EnumType.
+
+2019-08-07: wsfulton
+            [Python] Fix method overloading of methods that take STL containers of different
+            types. The following usage (using std::vector) would fail when using -builtin:
+
+              %include <std_string.i>
+              %include <std_vector.i>
+
+              %inline %{
+              struct X {};
+              %}
+
+              %template(VectorX) std::vector<X>;
+              %template(VectorInt) std::vector<int>;
+
+              %inline %{
+              using namespace std;
+              string VectorOverload(vector<X> v);
+              string VectorOverload(vector<int> v);
+              %}
+
+            The following would incorrectly fail:
+
+              s = VectorOverload([1, 2, 3])
+
+            With:
+
+              Traceback (most recent call last):
+                File "runme3.py", line 20, in <module>
+                  ret = VectorOverload([1, 2, 3])
+              TypeError: Wrong number or type of arguments for overloaded function 'VectorOverload'.
+                Possible C/C++ prototypes are:
+                  VectorOverload(std::vector< Number,std::allocator< Number > >)
+                  VectorOverload(std::vector< int,std::allocator< int > >)
+
+            The problem was due to some error handling that was not cleared during typechecking.
+            In this case an error was not cleared when the elements in the list failed the
+            typecheck for converting to X. Only occurs in Python 3+.
+
+            In some combinations of overloaded methods, the following type of error message would
+            occur:
+
+              RuntimeError: in sequence element 0
+
+              The above exception was the direct cause of the following exception:
+
+              Traceback (most recent call last):
+                File "runme3.py", line 23, in <module>
+                  check(VectorOverload(v), "vector<X>")
+              SystemError: <built-in function VectorOverload> returned a result with an error set
+
+2019-08-01: wsfulton
+            #1602 Fix regression in 4.0.0 where a template function containing a parameter
+            with the same name as the function name led to the parameter name used in the
+            target language being incorrectly modified.
+
+2019-07-29: wsfulton
+            Remove all generated files on error. Previously generated files were not removed,
+            potentially breaking Makefiles using file dependencies, especially when -Werror
+            (warnings as errors) was used.
+
+2019-07-23: smithx
+            [C#] #1530 #1532 Fix marshalling of std::wstring to C#.
+
+2019-07-18: gicmo
+            [Python] #1587 Python 3.8 support - remove use of deprecated PyObject_GC_UnTrack.
+
+2019-07-18: cher-nov
+            [Python] #1573 Generated Python code uses consistent string quoting style - double
+            quotes.
+
+2019-07-16: geefr
+            [C#] #616 #1576 Fix C# bool INPUT[], bool OUTPUT[], bool INOUT[] typemaps to marshall
+            as 1-byte.
+
+2019-07-12: vadz
+            [C#, Java] #1568 #1583 Fix std::set<> typemaps for primitive types.
+
+2019-07-12: vadz
+            #1566 #1584 Regression in 4.0.0 - fix missing value for first item of enums with
+            trailing comma.
+
+2019-07-11: mcfarljm
+            #1548 #1578 Fix segfault in Doxygen parser parsing empty lines in some commands like
+            \code.
+
+2019-07-09: IsaacPascual
+            [C#, Java] #1570 Fix name of generated C#/Java classes for %interface macros
+            in swiginterface.i when wrapping nested C++ classes.
+
+2019-07-05: wsfulton
+            [Python] #1547 Whitespace fixes in Doxygen translated comments into pydoc comments
+            for Sphinx compatibility.
+
+2019-06-28: wsfulton
+            [MzScheme, OCaml] #1559 $arg and $input were incorrectly substituted in the
+            argout typemap when two or more arguments were present.
+
+2019-06-24: wsfulton
+            [Python, Ruby] #1538 Remove the UnknownExceptionHandler class in order to be
+            C++17 compliant as it uses std::unexpected_handler which was removed in C++17.
+            This class was intended for director exception handling but was never used by
+            SWIG and was never documented.
+
+            *** POTENTIAL INCOMPATIBILITY ***
+
+2019-06-06: bkotzz
+            [Java] #1552 Improve performance in Java std::vector constructor wrapper that takes
+            a native Java array as input.
+
+2019-06-03: olly
+	    [Python] Fix regression in implicit_conv handling of tuples,
+	    introduced in SWIG 4.0.0.  Fixes #1553, reported by Alexandre
+	    Duret-Lutz.
+
+2019-05-24: wsfulton
+            [Octave] Fix detection of Octave on MacOS.
+
+2019-05-24: opoplawski
+            [Octave] #1522 Adapt OCTAVE_LDFLAGS for Octave 5.1.
+
+2019-05-22: ferdynator
+	    [PHP] #1528 Don't add a closing '?>' PHP tag to generated files.
+	    PSR-2 says it MUST be omitted for files containing only PHP.
+
 Version 4.0.0 (27 Apr 2019)
 ===========================
 
@@ -603,7 +3364,7 @@
               -fastunpack   Faster unpacking of function arguments in C/C++ wrappers.
               -modern       Use Python 2.3 features such as object and property.
               -modernargs   Use Python 2.3 C APIs for unpacking arguments in tuples.
-              -noproxydel   Stop generating a proxy __del__ method for backwards compatiblity.
+              -noproxydel   Stop generating a proxy __del__ method for backwards compatibility.
               -safecstrings No discernable difference
 
             The following options have been removed altogether:
@@ -2853,7 +5614,7 @@
 
 2014-09-12: olly
 	    [PHP] Add support for specifying any PHP interfaces a wrapped class
-	    implements, e.g.: %typemap("phpinterfaces") MyIterator "Iterator";
+	    implements, e.g.: %typemap("phpinterfaces") MyIterator "Iterator"
 
 2014-09-11: olly
 	    [PHP] Fix throwing a PHP exception through C++ from a subclassed
@@ -3018,7 +5779,7 @@
             project has been further extended. The C++11 support is comprehensive, but by no means complete
             or without limitations. Full details for each new feature in C++11 is covered in the
             CPlusPlus11.html chapter in the documentation which is included in SWIG and also available
-            online at http://www.swig.org/Doc3.0/CPlusPlus11.html.
+            online at https://www.swig.org/Doc3.0/CPlusPlus11.html.
 
 2014-03-14: v-for-vandal
             [Lua] Numerous Lua improvements:
@@ -5500,7 +8261,7 @@
 
 2010-02-27: wsfulton
             License code changes: SWIG Source is GPL-v3 and library code license is now clearer
-            and is provided under a very permissive license. See http://www.swig.org/legal.html.
+            and is provided under a very permissive license. See https://www.swig.org/legal.html.
 
 2010-02-13: wsfulton
             [Ruby] A few fixes for compiling under ruby-1.9.x including patch from 'Nibble'.
@@ -8112,8 +10873,8 @@
             javabase/csbase typemap, eg in the following, 'Me' will be the base class,
             no matter what Foo is really derived from in the C++ layer.
 
-              %typemap(javabase, replace="1") Foo "Me";
-              %typemap(csbase, replace="1") Foo "Me";
+              %typemap(javabase, replace="1") Foo "Me"
+              %typemap(csbase, replace="1") Foo "Me"
 
             Previously it was not possible for the javabase/csbase typemaps to override the C++ base.
 
@@ -9600,7 +12361,7 @@
 	    solutions is to write:
 
 	      %typemap(in) A * {...}
-  	      %typemap(freeag) A * "";
+  	      %typemap(freeag) A * ""
 
 	    overload 'freearg' with an empty definition.
 
@@ -9907,7 +12668,7 @@
 	      foo(1)   // Ok
 	      foo(1.0) // Ok
 	      foo(1.3) // Error
-	      a = Ai(4)
+	      ai = Ai(4)
               foo(ai)  // Ok
 
             The castmode, which can be enabled either with the
@@ -11030,20 +13791,20 @@
 	      then the typemap will be inserted without the block
 	      imposed by the brackets, similar to
 
-	       %typemap(in) Hello "...";
+	       %typemap(in) Hello "..."
 
 	      So, why you don't just use the quote style?, because:
 	      
 	         1.- The quote style doesn't get preprocessed, for example
 	      
-	              %typemap(in) Hello "$1= SWIG_macro($1);";
+	              %typemap(in) Hello "$1= SWIG_macro($1);"
 	      
 	             here, SWIG_macro doesn't get expanded
 
                  2.- Inside a quote typemap, you have to use 
                      quotes carefully
 
-		      %typemap(in) Hello "$1 = \"hello\" ";
+		      %typemap(in) Hello "$1 = \"hello\" "
 
 		 3.- You can't make emacs and/or other editors
 		     to indent inside a string!. 
@@ -11083,7 +13844,7 @@
 
 	     Now there are also more uniform directive names for the 
 	     ones based in features, for example, for the old
-	     %newobject directive now we have tree directives defined:
+	     %newobject directive now we have three directives defined:
 	     
 
 	     #define %newobject        %feature("new")
@@ -11245,7 +14006,7 @@
 
 	      %define hello(name, Type)
 	      %define name ## a(Type)
-	      %typemap(in) Type "hello;";
+	      %typemap(in) Type "hello;"
 	      %enddef
 	      %enddef
 	      
@@ -12262,7 +15023,7 @@
 	      array or vector.
 
 	      Also, a PySwigPacked object was adding to carry a member
-	      method pointer, but this is probably a temporal solution
+	      method pointer, but this is probably a temporary solution
 	      until a more general object for methods is added.
 
 	      Be aware that to simplify maintaining and compatibility
@@ -13241,7 +16002,7 @@
             whereupon the default of 0 was used. You can get the same behaviour for C
             code by using the "default" typemap:
 
-              %typemap(default) int val "$1 = 0;";
+              %typemap(default) int val "$1 = 0;"
               %{
               void foo(int val);
               %}
@@ -13570,9 +16331,11 @@
 	    specifiers from the C type.  This makes it possible, for instance, to control
 	    whether a C "char" argument takes a Lisp character or a Lisp integer value.
 	    The default (taking Lisp characters) is done by these built-in typemaps:
-	      %typemap(ffitype) char ":char"; %typemap(lisptype) char "character";
+	      %typemap(ffitype) char ":char"
+	      %typemap(lisptype) char "character"
 	    If char means an integer instead, use these typemaps:
-	      %typemap(ffitype) char ":char"; %typemap(lisptype) char "integer";
+	      %typemap(ffitype) char ":char"
+	      %typemap(lisptype) char "integer"
 
 08/22/2004: wsfulton
             As discussed in bug #772453, the SWIG library directory is now installed
@@ -15102,7 +17865,7 @@
                   virtual f2();
                 };
 
-	    This can be dissabled by using the '-nodirprot' option.
+	    This can be disabled by using the '-nodirprot' option.
 
 	    - The feature 'nodirector' is working now at the top level,
 	    so, it must work for all the languages:
@@ -18590,9 +21353,9 @@
             shadowinterface
             
             Note that it is possible to target a particular proxy class:
-            %typemap(javaimports) Foo "import java.util.*";
+            %typemap(javaimports) Foo "import java.util.*"
             or a particular type wrapper class:
-            %typemap(javaimports) double* "import java.math.*";
+            %typemap(javaimports) double* "import java.math.*"
             Note that $javaclassname in these typemaps are substituted with either the proxy 
             classname when using proxy classes or the SWIGTYPE class name.
 
@@ -19330,8 +22093,8 @@
             typemap must exactly match up with the "in" or "ignore"
             typemap.  For example:
 
-                 %typemap(in) (char *data, int len) { ... };
-                 %typemap(freearg) char *data { ... }; 
+                 %typemap(in) (char *data, int len) { ... }
+                 %typemap(freearg) char *data { ... }
 
                  void foo(char *data, int len);
 
@@ -20787,7 +23550,7 @@
 
             Second, a typemap can force a no-match by defining
 
-             %typemap(in) sometype "pass";
+             %typemap(in) sometype "pass"
 
             If this is used, the typemap system will *not* record a
             typemap match for "sometype".   This can be used to block
@@ -20795,7 +23558,7 @@
             a typemap feature for some type, you could do this.
 
                // Do not allow global variables of type 'const char *' to be set.
-               %typemap(varin) const char * "pass";
+               %typemap(varin) const char * "pass"
 
             It might also be possible to use this to do subtle and
             strange things with typemaps.  For example, if you wanted to
@@ -20809,8 +23572,8 @@
                     ... return a value ...
                 }
                 /* Block unqualified typemaps defined above */
-                %typemap(ignore) const blah * "pass";
-                %typemap(argout) const blah * "pass";
+                %typemap(ignore) const blah * "pass"
+                %typemap(argout) const blah * "pass"
                 %typemap(in)     const blah * {
                     ... get input value ...
                 }
@@ -21587,7 +24350,7 @@
            %typemap directive can now accept nearly arbitrary keyword parameters.
            For example:
 
-              %typemap(in,parse="i",doc="integer") int "...";
+              %typemap(in,parse="i",doc="integer") int "..."
 
            The purpose of the keyword parameters is to supply code generation
            hints to the target language module.   The intepretation of the
@@ -23665,7 +26428,7 @@
           Typemaps can now be specified using string literals like
           this:
 
-              %typemap(in) int "$target = SvIV($source);";
+              %typemap(in) int "$target = SvIV($source);"
 
           When code is specified like this, it is *NOT* enclosed
           inside a local scope (as with older typemap declarations).
diff --git a/CHANGES.current b/CHANGES.current
index ab69e09..f44ab05 100644
--- a/CHANGES.current
+++ b/CHANGES.current
@@ -4,142 +4,142 @@
 Issue # numbers mentioned below can be found on Github. For more details, add
 the issue number to the end of the URL: https://github.com/swig/swig/issues/
 
-Version 4.0.1 (21 Aug 2019)
+Version 4.2.1 (24 Feb 2024)
 ===========================
 
-2019-08-20: TekuConcept
-            [Javascript] #1535 Add %native support to Javascript.
+2024-02-23: wsfulton
+            #2814 Correctly ignore duplicate template instantiation (when the
+            duplicate contains typedef'd template parameters).
 
-2019-08-20: bkotzz
-            [Java] #1616 Add SWIG_JavaIllegalStateException to support throwing
-            java.lang.IllegalStateException from JNI code.
+2024-02-22: erezgeva
+            [Ruby, Octave, R] #2284 Fix segfault shrinking STL containers.
 
-2019-08-19: sjml
-            [Lua] #1596 tostring output changes to show the underlying C/C++ pointer.
+2024-02-22: simark
+	    Fix -Wundef warning about testing the value of __cplusplus when
+	    compiling SWIG-generated C code.  Warning introduced by a change in
+	    SWIG 4.2.0.
 
-2019-08-08: rokups
-            [C#, Java] #1601 Fix invalid code generated for "%constant enum EnumType.
+2024-02-21: olly
+	    #2808 [PHP] Fix memory leak when getting or setting a PHP
+	    attribute which wraps a C++ member variable.  Bug introduced in
+	    SWIG 4.1.0.
 
-2019-08-07: wsfulton
-            [Python] Fix method overloading of methods that take STL containers of different
-            types. The following usage (using std::vector) would fail when using -builtin:
+2024-02-18: wsfulton
+            #2745 Fix for wrapping STL containers that are static member variables
+            or global variables (most scripting languages). Previously a copy of the
+            STL container was made into a target language container when reading the
+            variable. Changes, such as adjusting an element or adding/erasing
+            elements, were made to the copy of the container rather the actual
+            underlying C++ container. Also applies to const reference STL static
+            members.
 
-              %include <std_string.i>
-              %include <std_vector.i>
+            If you really need the old behaviour, add in the typemap that used
+            to provide it. For example, for std::list< int > and
+            const std::list< int >&, use:
 
-              %inline %{
-              struct X {};
-              %}
+              %typemap(varout,noblock=1,fragment="SWIG_" "Traits" "_" {std::list< int >})
+                  std::list< int >, const std::list< int >&  {
+                $result = swig::from(static_cast< std::list< int > >($1));
+              }
 
-              %template(VectorX) std::vector<X>;
-              %template(VectorInt) std::vector<int>;
+	    *** POTENTIAL INCOMPATIBILITY ***
 
-              %inline %{
-              using namespace std;
-              string VectorOverload(vector<X> v);
-              string VectorOverload(vector<int> v);
-              %}
+2024-02-15: olly
+	    Improve type deduction for enum values in expressions.
 
-            The following would incorrectly fail:
+2024-02-15: rlaboiss
+	    #2799 [Octave] Add support for Octave 9.0; fix warnings about use
+	    of deprecated Octave APIs with Octave 7 and later.
 
-              s = VectorOverload([1, 2, 3])
+2024-02-14: olly
+	    SWIG now warns and ignores if %constant is used with an implicit
+	    type which SWIG can't deduce.
 
-            With:
+2024-02-13: olly
+	    Fix type deduction for certain cases involving C-style casts, or
+	    which are syntactically like a C-style cast applied to an unary
+	    operator, such as: (7)*6
 
-              Traceback (most recent call last):
-                File "runme3.py", line 20, in <module>
-                  ret = VectorOverload([1, 2, 3])
-              TypeError: Wrong number or type of arguments for overloaded function 'VectorOverload'.
-                Possible C/C++ prototypes are:
-                  VectorOverload(std::vector< Number,std::allocator< Number > >)
-                  VectorOverload(std::vector< int,std::allocator< int > >)
+2024-02-13: olly
+	    #2796 Fix handling of enum initialised by expression including a
+	    cast to a typedef-ed type.  Regression introduced in 4.2.0.
 
-            The problem was due to some error handling that was not cleared during typehecking.
-            In this case an error was not cleared when the elements in the list failed the
-            typecheck for converting to X. Only occurs in Python 3+.
+2024-02-09: wsfulton
+            #2794 Fix SwigType_isvariadic assertion to add support for variadic
+            templated functions in a template.
 
-            In some combinations of overloaded methods, the following type of error message would
-            occur:
+2024-02-08: wsfulton
+            #2761 [Tcl] Fix assert in SWIG_Tcl_ConvertPtrFromString().
 
-              RuntimeError: in sequence element 0
+2024-02-03: wsfulton
+            #1897 [C#, Java] Fix crash handling enums with same name in different
+            namespaces.
 
-              The above exception was the direct cause of the following exception:
+2024-02-01: wsfulton
+            #2781 Correctly report line number warnings/errors for base classes that
+            are templates.
 
-              Traceback (most recent call last):
-                File "runme3.py", line 23, in <module>
-                  check(VectorOverload(v), "vector<X>")
-              SystemError: <built-in function VectorOverload> returned a result with an error set
+2024-01-31: olly
+	    Fix assertion failure and segfault trying to use %constant to
+	    deduce the type of a "float _Complex" constant.
 
-2019-08-01: wsfulton
-            #1602 Fix regression in 4.0.0 where a template function containing a parameter
-            with the same name as the function name led to the parameter name used in the
-            target language being incorrectly modified.
+2024-01-31: jim-easterbrook
+            #2771 [Python] builtin fixes to handle NULL values passed to slots using
+            functype: ssizeobjargproc and ternaryfunc.
 
-2019-07-29: wsfulton
-            Remove all generated files on error. Previously generated files were not removed,
-            potentially breaking Makefiles using file dependencies, especially when -Werror
-            (warnings as errors) was used.
+2024-01-31: olly
+	    [Java] #2766 Fix segfault trying to wrap a constant whose type is unknown
+	    to SWIG with "%javaconst(1);" enabled.
 
-2019-07-23: smithx
-            [C#] #1530 #1532 Fix marshalling of std::wstring to C#.
+2024-01-31: wsfulton
+            #2768 Fix seg fault handling upcasting when using %shared_ptr on some
+            templates.
 
-2019-07-18: gicmo
-            [Python] #1587 Python 3.8 support - remove use of deprecated PyObject_GC_UnTrack.
+2024-01-31: olly
+	    #2783 Fix incorrectly deduced type for function call.  Regression
+	    introduced in 4.2.0.
 
-2019-07-18: cher-nov
-            [Python] #1573 Generated Python code uses consistent string quoting style - double
-            quotes.
+2024-01-27: wsfulton
+            [Python] Fix compilation error when wrapping two or more classes that
+            have the same friend operator overload when the classes are in a namespace.
 
-2019-07-16: geefr
-            [C#] #616 #1576 Fix C# bool INPUT[], bool OUTPUT[], bool INOUT[] typemaps to marshall
-            as 1-byte.
+2024-01-15: wsfulton
+            https://sourceforge.net/p/swig/bugs/960/
+            https://sourceforge.net/p/swig/bugs/807/
+            Fix so that friend operators within a namespace can be correctly ignored
+            or renamed.
 
-2019-07-12: vadz
-            [C#, Java] #1568 #1583 Fix std::set<> typemaps for primitive types.
+2024-01-15: wsfulton
+            Wrap friend functions that are defined or declared within a namespace.
+            Previously unqualified friend definitions/declarations in a namespace were
+            ignored.
 
-2019-07-12: vadz
-            #1566 #1584 Regression in 4.0.0 - fix missing value for first item of enums with
-            trailing comma.
+            The visibility of unqualified friend functions in C++ is somewhat quirky
+            and the documentation has been enhanced to aid wrapping of friends.
 
-2019-07-11: mcfarljm
-            #1548 #1578 Fix segfault in Doxygen parser parsing empty lines in some commands like
-            \code.
+2024-01-12: wsfulton
+            #2749 Fix seg fault handling friend constructor/destructor declarations.
 
-2019-07-09: IsaacPascual
-            [C#, Java] #1570 Fix name of generated C#/Java classes for %interface macros
-            in swiginterface.i when wrapping nested C++ classes.
+2024-01-12: olly
+	    [Ruby, Tcl] #2751 Fix -external-runtime output to define
+	    SWIG_snprintf (bug introduced in 4.2.0).
 
-2019-07-05: wsfulton
-            [Python] #1547 Whitespace fixes in Doxygen translated comments into pydoc comments
-            for Sphinx compatibility.
+2024-01-12: olly
+	    Improve preprocessor warning for use of an undefined function-like
+	    macro. SWIG now warns:
 
-2019-06-28: wsfulton
-            [MzScheme, OCaml] #1559 $arg and $input were incorrectly substituted in the
-            argout typemap when two or more arguments were present.
+	    Warning 202: Could not evaluate expression 'MY_VERSION_AT_LEAST(1,2,3)'
+	    Warning 202: Use of undefined function-like macro
 
-2019-06-24: wsfulton
-            [Python, Ruby] #1538 Remove the UnknownExceptionHandler class in order to be
-            C++17 compliant as it uses std::unexpected_handler which was removed in C++17.
-            This class was intended for director exception handling but was never used by
-            SWIG and was never documented.
+	    instead of:
 
-            *** POTENTIAL INCOMPATIBILITY ***
+	    Warning 202: Could not evaluate expression 'MY_VERSION_AT_LEAST(1,2,3)'
+	    Warning 202: Syntax error: expected operator
 
-2019-06-06: bkotzz
-            [Java] #1552 Improve performance in Java std::vector constructor wrapper that takes
-            a native Java array as input.
+2024-01-11: PaulObermeier
+	    [Tcl] Improve support for Tcl 9.0.  All examples and tests now pass
+	    with Tcl 9.0.b1.
 
-2019-06-03: olly
-	    [Python] Fix regression in implicit_conv handling of tuples,
-	    introduced in SWIG 4.0.0.  Fixes #1553, reported by Alexandre
-	    Duret-Lutz.
-
-2019-05-24: wsfulton
-            [Octave] Fix detection of Octave on MacOS.
-
-2019-05-24: opoplawski
-            [Octave] #1522 Adapt OCTAVE_LDFLAGS for Octave 5.1.
-
-2019-05-22: ferdynator
-	    [PHP] #1528 Don't add a closing '?>' PHP tag to generated files.
-	    PSR-2 says it MUST be omitted for files containing only PHP.
+2024-01-06: wsfulton
+            [Python] #2744 Regression fix - add in missing SwigPyIterator_T fragment for
+            SwigPyIteratorClosed_T when using %import on an instantiated std::map.
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..21e0694
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,169 @@
+cmake_minimum_required (VERSION 3.13)
+
+set (CMAKE_BUILD_TYPE Release CACHE STRING "Build type")
+
+project (swig)
+
+if (POLICY CMP0074)
+  cmake_policy (SET CMP0074 NEW)
+endif()
+
+file (STRINGS configure.ac line LIMIT_COUNT 1 REGEX "AC_INIT\\(.*\\)" )
+if (line MATCHES "AC_INIT\\(\\[(.*)\\],[ \t]*\\[(.*)\\],[ \t]*\\[(.*)\\]\\)" )
+  set (SWIG_VERSION ${CMAKE_MATCH_2})
+  set (PACKAGE_BUGREPORT ${CMAKE_MATCH_3})
+else ()
+  message (SEND_ERROR "Could not parse version from configure.ac")
+endif ()
+
+set (SWIG_ROOT ${PROJECT_SOURCE_DIR})
+
+if (WIN32)
+  set (SWIG_LIB bin/Lib)
+else ()
+  set (SWIG_LIB share/swig/${SWIG_VERSION})
+endif ()
+# Project wide configuration variables
+# ------------------------------------
+
+set (SWIG_SOURCE_DIR ${SWIG_ROOT}/Source CACHE INTERNAL "Path of swig sources" FORCE)
+
+set (PACKAGE_NAME swig)
+set (PACKAGE_VERSION ${SWIG_VERSION})
+
+# Configure
+# ---------
+
+list (APPEND CMAKE_MODULE_PATH ${SWIG_ROOT}/Tools/cmake)
+
+include (CheckIncludeFiles)
+include (CheckIncludeFile)
+include (CheckIncludeFileCXX)
+include (CheckTypeSize)
+include (CheckSymbolExists)
+include (CheckFunctionExists)
+include (CheckLibraryExists)
+include (CheckCSourceCompiles)
+
+# HACK: didn't get the bool check working for Visual Studio 2008
+if (MSVC)
+  set(HAVE_BOOL 1)
+else()
+  set (CMAKE_EXTRA_INCLUDE_FILES stdbool.h)
+  check_type_size ("bool" HAVE_BOOL)
+  set (CMAKE_EXTRA_INCLUDE_FILES)
+endif()
+
+check_include_file ("inttypes.h" HAVE_INTTYPES_H)
+check_include_file ("stddef.h" HAVE_STDDEF_H)
+check_include_file ("stdint.h" HAVE_STDINT_H)
+check_include_file ("stdio.h" HAVE_STDIO_H)
+check_include_file ("stdlib.h" HAVE_STDLIB_H)
+check_include_file ("string.h" HAVE_STRING_H)
+check_include_file ("strings.h" HAVE_STRINGS_H)
+check_include_file ("sys/stat.h" HAVE_SYS_STAT_H)
+check_include_file ("sys/types.h" HAVE_SYS_TYPES_H)
+check_include_file ("unistd.h" HAVE_UNISTD_H)
+check_include_files ("stdlib.h;stdarg.h;string.h;float.h" STDC_HEADERS)
+
+check_include_file_cxx ("boost/shared_ptr.hpp" HAVE_BOOST)
+check_library_exists (dl dlopen "" HAVE_LIBDL)
+check_function_exists (popen HAVE_POPEN)
+
+if (MSVC)
+  set (CMAKE_CXX_FLAGS "/EHsc ${CMAKE_CXX_FLAGS}")
+endif ()
+
+option (WITH_PCRE "Enable PCRE" ON)
+if (WITH_PCRE)
+  find_package (PCRE2 REQUIRED)
+  set (HAVE_PCRE 1)
+  include_directories (${PCRE2_INCLUDE_DIRS})
+endif()
+
+#if (WIN32)
+#  file (TO_NATIVE_PATH ${CMAKE_INSTALL_PREFIX}/${SWIG_LIB} SWIG_LIB_WIN_UNIX)
+#  string (REGEX REPLACE "\\\\" "\\\\\\\\" SWIG_LIB_WIN_UNIX "${SWIG_LIB_WIN_UNIX}")
+#endif ()
+configure_file (${SWIG_ROOT}/Tools/cmake/swigconfig.h.in
+                ${CMAKE_CURRENT_BINARY_DIR}/Source/Include/swigconfig.h)
+
+find_package (BISON 3.5 REQUIRED)
+
+
+# Compiler flags
+# --------------
+
+include_directories (
+    ${SWIG_SOURCE_DIR}/CParse
+    ${SWIG_SOURCE_DIR}/Include
+    ${SWIG_SOURCE_DIR}/DOH
+    ${SWIG_SOURCE_DIR}/Swig
+    ${SWIG_SOURCE_DIR}/Preprocessor
+    ${SWIG_SOURCE_DIR}/Modules
+    ${PROJECT_BINARY_DIR}/Source/Include
+    ${PROJECT_BINARY_DIR}/Source/CParse
+    ${PROJECT_SOURCE_DIR}/Source/Doxygen
+)
+
+# generate the parser source code (depends on bison)
+file (MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/Source/CParse)
+
+BISON_TARGET (swig_parser
+    ${SWIG_SOURCE_DIR}/CParse/parser.y
+    ${PROJECT_BINARY_DIR}/Source/CParse/parser.c
+)
+
+# generate swigwarn.swg
+file (READ ${SWIG_SOURCE_DIR}/Include/swigwarn.h SWIG_WARN_H)
+string (REGEX REPLACE "#define WARN([^ \\t]*)[ \\t]*([0-9]+)" "%define SWIGWARN\\1 \\2 %enddef" SWIG_WARN_SWG ${SWIG_WARN_H})
+file (WRITE ${CMAKE_CURRENT_BINARY_DIR}/swigwarn.swg ${SWIG_WARN_SWG})
+set_property (SOURCE ${CMAKE_CURRENT_BINARY_DIR}/swigwarn.swg PROPERTY GENERATED 1)
+
+# install lib
+install (DIRECTORY ${SWIG_ROOT}/Lib/ DESTINATION ${SWIG_LIB})
+install (FILES ${CMAKE_CURRENT_BINARY_DIR}/swigwarn.swg DESTINATION ${SWIG_LIB})
+
+# sources
+# ---------
+file (GLOB DOH_SOURCES ${SWIG_SOURCE_DIR}/DOH/*.c)
+file (GLOB CPARSE_SOURCES ${SWIG_SOURCE_DIR}/CParse/*.c)
+list (REMOVE_ITEM CPARSE_SOURCES ${SWIG_SOURCE_DIR}/CParse/parser.c)
+list (APPEND CPARSE_SOURCES)
+file (GLOB PREPROCESSOR_SOURCES ${SWIG_SOURCE_DIR}/Preprocessor/*.c)
+file (GLOB CORE_SOURCES ${SWIG_SOURCE_DIR}/Swig/*.c)
+file (GLOB DOXYGEN_SOURCES ${SWIG_SOURCE_DIR}/Doxygen/*.cxx)
+file (GLOB MODULES_SOURCES ${SWIG_SOURCE_DIR}/Modules/*.cxx)
+
+add_executable (swig
+  ${CPARSE_SOURCES}
+  ${DOH_SOURCES}
+  ${DOXYGEN_SOURCES}
+  ${MODULES_SOURCES}
+  ${CORE_SOURCES}
+  ${PREPROCESSOR_SOURCES}
+  ${PROJECT_BINARY_DIR}/Source/Include/swigconfig.h
+  ${SWIG_SOURCE_DIR}/Include/swigwarn.h
+  ${PROJECT_BINARY_DIR}/Source/CParse/parser.c
+  ${PROJECT_BINARY_DIR}/Source/CParse/parser.h
+)
+if (PCRE2_FOUND)
+  target_link_libraries (swig ${PCRE2_LIBRARIES})
+endif ()
+install (TARGETS swig DESTINATION bin)
+
+# 'make package-source' creates tarballs
+set (CPACK_PACKAGE_NAME ${PACKAGE_NAME})
+set (CPACK_SOURCE_GENERATOR "TGZ;TBZ2")
+set (CPACK_SOURCE_IGNORE_FILES "/.git;/build;.*~;${CPACK_SOURCE_IGNORE_FILES}")
+set (CPACK_SOURCE_PACKAGE_FILE_NAME ${PACKAGE_NAME}-${PACKAGE_VERSION})
+include (CPack)
+
+# few tests
+enable_testing ()
+add_test (NAME cmd_version COMMAND swig -version)
+add_test (NAME cmd_pcreversion COMMAND swig -pcreversion)
+add_test (NAME cmd_swiglib COMMAND swig -swiglib)
+add_test (NAME cmd_external_runtime COMMAND swig -external-runtime ext_rt.h)
+set_tests_properties(cmd_external_runtime PROPERTIES ENVIRONMENT "SWIG_LIB=${PROJECT_SOURCE_DIR}/Lib")
+
diff --git a/COPYRIGHT b/COPYRIGHT
index e6df73f..c5931c6 100644
--- a/COPYRIGHT
+++ b/COPYRIGHT
@@ -1,7 +1,7 @@
 SWIG Copyright and Authors
 --------------------------
 
-Copyright (c) 1995-2011 The SWIG Developers
+Copyright (c) 1995-2023 The SWIG Developers
 Copyright (c) 2005-2006 Arizona Board of Regents (University of Arizona).
 Copyright (c) 1998-2005 University of Chicago.
 Copyright (c) 1995-1998 The University of Utah and the Regents of the University of California
@@ -14,10 +14,7 @@
  William Fulton (wsf@fultondesigns.co.uk)                 (SWIG core, Java, C#, Windows, Cygwin)
  Olly Betts (olly@survex.com)                             (PHP)
  Joseph Wang (joequant@gmail.com)                         (R)
- Xavier Delacour (xavier.delacour@gmail.com)              (Octave)
- David Nadlinger (code@klickverbot.at)                    (D)
- Oliver Buchtala (oliver.buchtala@gmail.com)              (Javascript)
- Neha Narang (narangneha03@gmail.com)                     (Javascript)
+ Momtchil Momtchev (momtchil@momtchev.com)                (Javascript Node-API)
  Simon Marchetto (simon.marchetto@scilab-enterprises.com) (Scilab)
  Zackery Spytz (zspytz@gmail.com)                         (OCaml, SWIG core)
 
@@ -69,6 +66,10 @@
  Vincent Couvert                                          (Scilab)
  Sylvestre Ledru                                          (Scilab)
  Wolfgang Frisch                                          (Scilab)
+ Oliver Buchtala (oliver.buchtala@gmail.com)              (Javascript)
+ Neha Narang (narangneha03@gmail.com)                     (Javascript)
+ Xavier Delacour (xavier.delacour@gmail.com)              (Octave)
+ David Nadlinger (code@klickverbot.at)                    (D)
 
 Past contributors include:
  James Michael DuPont, Clark McGrew, Dustin Mitchell, Ian Cooke, Catalin Dumitrescu, Baran
diff --git a/Doc/Devel/cmdopt.html b/Doc/Devel/cmdopt.html
index 5e90d2a..10dc731 100644
--- a/Doc/Devel/cmdopt.html
+++ b/Doc/Devel/cmdopt.html
@@ -60,7 +60,7 @@
 <b><tt>void Swig_check_options()</tt></b>
 <blockquote>
 Checks all command line options to see if they have all been processed.  If not, an error message is generated and
-execution terminates with a call to <tt>exit()</tt>.   This function is currently invoked in <tt>Source/Modules/main.cxx</tt> just before SWIG starts any processing of input files.
+SWIG exits.   This function is currently invoked in <tt>Source/Modules/main.cxx</tt> just before SWIG starts any processing of input files.
 </blockquote>
 
 <h2>Utility Function</h2>
@@ -68,7 +68,7 @@
 <b><tt>void Swig_arg_error())</tt></b>
 
 <blockquote>
-A generic function that issues an error message about being unable to parse command line options.  SWIG is terminated by a call to <tt>exit()</tt>.
+A generic function that issues an error message about being unable to parse command line options and SWIG exits.
 
 </body>
 </html>
diff --git a/Doc/Devel/engineering.html b/Doc/Devel/engineering.html
index c12eb13..c2cad48 100644
--- a/Doc/Devel/engineering.html
+++ b/Doc/Devel/engineering.html
@@ -130,7 +130,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * xxx.c
  *
diff --git a/Doc/Devel/internals.html b/Doc/Devel/internals.html
index c9082d3..51fc7da 100644
--- a/Doc/Devel/internals.html
+++ b/Doc/Devel/internals.html
@@ -108,7 +108,7 @@
   </tr>
 
   <tr><td>CParse</td>
-  <td>Parser (lex / yacc) files and support</td>
+  <td>Parser (bison) files and support</td>
   </tr>
 
   <tr><td>Modules</td>
@@ -441,12 +441,12 @@
 
 <blockquote>
 <pre>
-hash len: 5
-get: hashval2
-hash item: hashval5 [h5]
-hash item: hashval1 [h1]
-hash item: hashval2 [h2]
-hash item: hashval3 [h3]
+list len: 5
+get: listval2
+list item: newlistval1
+list item: listval2
+list item: listval3
+list item: listval5
 </pre>
 </blockquote>
 
@@ -494,12 +494,12 @@
 
 <blockquote>
 <pre>
-list len: 5
-get: listval2
-list item: newlistval1
-list item: listval2
-list item: listval3
-list item: listval5
+hash len: 5
+get: hashval2
+hash item: hashval5 [h5]
+hash item: hashval1 [h1]
+hash item: hashval2 [h2]
+hash item: hashval3 [h3]
 </pre>
 </blockquote>
 
@@ -519,7 +519,27 @@
 <h3>2.10 Utility functions </h3>
 </a>
 
-[ TODO ]
+<p>
+DOH wraps some standard C library functions - these wrapped versions should
+always be used in code in the SWIG tool itself (but not in generated code).
+When compiling with GCC or clang, the original library function names are
+marked as "poisoned" symbols so you should get an error if you accidentally
+use one of the unwrapped functions.  These functions are:
+
+<ul>
+    <li><tt>Calloc(m,n)</tt> : wrapper for <tt>calloc(m,n)</tt> which exits on memory failure so never returns <tt>NULL</tt>.
+    <li><tt>Malloc(n)</tt> : wrapper for <tt>malloc(n)</tt> which exits on memory failure so never returns <tt>NULL</tt>.
+    <li><tt>Realloc(p,n)</tt> : wrapper for <tt>realloc(p,n)</tt> which exits on memory failure so never returns <tt>NULL</tt>.
+    <li><tt>Free(p)</tt> : wrapper for <tt>free(p)</tt> (doesn't currently do anything special, really done for consistency with <tt>Malloc()</tt> etc).
+    <li><tt>Exit(r)</tt> : wrapper for <tt>exit(r)</tt> which for SWIG removes generated files if <tt>r&gt;0</tt>.
+</ul>
+
+<tt>abort()</tt> is also poisoned - please use <tt>Exit(EXIT_FAILURE)</tt> instead so that generated files are removed.
+</p>
+
+<p>
+[ TODO document others ]
+</p>
 
 <a name="3" href="#i3">
 <h2>3. Types and Typemaps</h2>
@@ -535,7 +555,7 @@
 <li><tt>SwigType_str(SwigType *t, char *name)</tt>.<br>
  This function produces the exact string 
 representation of the datatype <tt>t</tt>.  <tt>name</tt> is an optional parameter that 
-specifies a declaration name.   This is used when dealing with more complicated datatypes
+specifies a declaration name and can be <tt>NULL</tt>.  This is used when dealing with more complicated datatypes
 such as arrays and pointers to functions where the output might look something like
 "<tt>int (*name)(int, double)</tt>".
 
@@ -1194,12 +1214,12 @@
 grabs a chunk of memory from the C memory allocator and manages the usage internally.
 Stale DOH object usage can be checked for by defining <tt>DOH_DEBUG_MEMORY_POOLS</tt> in 
 <tt>memory.c</tt>. If an attempt to use an object is made after the reference count is
-zero, an assertion is triggered instead of quietly re-using the stale object...
+zero, a fatal error is triggered instead of quietly re-using the stale object:
 </p>
 
 <blockquote>
 <pre>
-swig: DOH/memory.c:91: DohCheck: Assertion `!DOH_object_already_deleted' failed.
+Fatal internal error: Attempt to delete a non-DOH object.
 </pre>
 </blockquote>
 
@@ -1209,7 +1229,7 @@
 </p>
 
 <hr>
-Copyright (C) 1999-2010 SWIG Development Team.
+Copyright (C) 1999-2022 SWIG Development Team.
 
 </body>
 </html>
diff --git a/Doc/Devel/migrate.txt b/Doc/Devel/migrate.txt
index b40fa36..3973eb9 100644
--- a/Doc/Devel/migrate.txt
+++ b/Doc/Devel/migrate.txt
@@ -101,10 +101,10 @@
   ParmList *l;
   Parm *p;
 
-  for (p = l; p; p = Getnext(p)) {
-      SwigType *pt = Gettype(p);        /* Get parameter type */
-      String   *pn = Getname(p);        /* Get parameter name */
-      String   *value = Getvalue(p);    /* Get parameter value */
+  for (p = l; p; p = nextSibling(p)) {
+      SwigType *pt = Getattr(p, "type");      /* Get parameter type */
+      String   *pn = Getattr(p, "name");      /* Get parameter name */
+      String   *value = Getattr(p, "value");  /* Get parameter value */
       ...
       do whatever
       ...
@@ -119,7 +119,7 @@
 
 the function is
 
-     Swig_typemap_lookup("in",type,pname,"$source","$target",wrapper);
+     Swig_typemap_lookup("in", node, pname, wrapper);
 
 There are a variety of other changes to typemaps (see CHANGES).
 
diff --git a/Doc/Devel/plan-gsoc-2012.txt b/Doc/Devel/plan-gsoc-2012.txt
index ac764fb..c217dad 100644
--- a/Doc/Devel/plan-gsoc-2012.txt
+++ b/Doc/Devel/plan-gsoc-2012.txt
@@ -45,7 +45,7 @@
   -----------------
   
   Note:
-     See 'http://www.stack.nl/~dimitri/doxygen/docblocks.html' for
+     See 'https://www.doxygen.nl/manual/docblocks.html' for
      the detailed description of Doxygen syntax and terms used in this
      section.
 
@@ -72,10 +72,10 @@
   ----
 
   This section contains all doxygen tags taken from 
-  http://www.stack.nl/~dimitri/doxygen/commands.html. If a tag is
+  https://www.doxygen.nl/manual/commands.html. If a tag is
   marked as 'ignored', then the tag is ignored, but the text is copied
   to the destination documentation. 'Not implemented' means that the
-  tag with it's contents is stripped out of the output.
+  tag with its contents is stripped out of the output.
 
     Doxygen tags:
     
diff --git a/Doc/Devel/scanner.html b/Doc/Devel/scanner.html
index 65ef1d8..efa553e 100644
--- a/Doc/Devel/scanner.html
+++ b/Doc/Devel/scanner.html
@@ -19,7 +19,7 @@
 
 This document describes functions that can be used to tokenize C/C++
 input text.  These functions are relatively low-level and are meant to
-be used in the implementation of scanners that can be plugged into yacc or used for
+be used in the implementation of scanners that can be plugged into bison or used for
 other purposes.  For instance, the preprocessor uses these functions to evaluate and test 
 constant expressions.  
 
@@ -103,7 +103,7 @@
 </blockquote>
 
 <p>
-<b><tt>void Scanner_skip_balanced(Scanner *s, int startchar, int endchar)</tt></b>
+<b><tt>int Scanner_skip_balanced(Scanner *s, int startchar, int endchar)</tt></b>
 <blockquote>
 Skips to the end of a block of text denoted by starting and ending characters.  For example, <tt>{</tt> and <tt>}</tt>.  The
 function is smart about how it skips text.  String literals and comments are ignored.   The function also is aware of nesting.  The
@@ -112,7 +112,7 @@
 
 
 <p>
-<b><tt>void Scanner_set_location(Scanner *s, int startchar, int endchar)</tt></b>
+<b><tt>void Scanner_set_location(Scanner *s, String *file, int line)</tt></b>
 <blockquote>
 Changes the current filename and line number of the scanner.
 </blockquote>
@@ -136,7 +136,7 @@
 </blockquote>
 
 <p>
-<b><tt>void Scanner_idstart(Scanner *s, char *idchar)</tt></b>
+<b><tt>void Scanner_idstart(Scanner *s, const char *idchar)</tt></b>
 <blockquote>
 Sets additional characters (other than the C default) that may be used to start C identifiers.  <tt>idchar</tt> is a string
 containing the characters (e.g., "%@").  The purpose of this function is to up special keywords such as "%module" or "@directive" as
@@ -187,7 +187,6 @@
 SWIG_TOKEN_SEMI              ; 
 SWIG_TOKEN_COMMA             , 
 SWIG_TOKEN_STAR              * 
-SWIG_TOKEN_TIMES             *
 SWIG_TOKEN_LBRACE            { 
 SWIG_TOKEN_RBRACE            } 
 SWIG_TOKEN_EQUAL             = 
@@ -204,16 +203,15 @@
 SWIG_TOKEN_GREATERTHAN       &gt; 
 SWIG_TOKEN_LTEQUAL           &lt;= 
 SWIG_TOKEN_GTEQUAL           &gt;= 
+SWIG_TOKEN_LTEQUALGT         &lt;=&gt;
 SWIG_TOKEN_NOT               ~ 
 SWIG_TOKEN_LNOT              ! 
 SWIG_TOKEN_LBRACKET          [ 
 SWIG_TOKEN_RBRACKET          ] 
 SWIG_TOKEN_SLASH             / 
-SWIG_TOKEN_DIVIDE            /
 SWIG_TOKEN_BACKSLASH         \ 
 SWIG_TOKEN_POUND             # 
 SWIG_TOKEN_PERCENT           % 
-SWIG_TOKEN_MODULO            %
 SWIG_TOKEN_COLON             : 
 SWIG_TOKEN_DCOLON            :: 
 SWIG_TOKEN_DCOLONSTAR        ::*
@@ -237,21 +235,28 @@
 SWIG_TOKEN_PERIOD            . 
 SWIG_TOKEN_AT                @ 
 SWIG_TOKEN_DOLLAR            $ 
+SWIG_TOKEN_ELLIPSIS          ...
+SWIG_TOKEN_LLBRACKET         [[
+SWIG_TOKEN_RRBRACKET         ]]
 SWIG_TOKEN_ENDLINE           Literal newline
 SWIG_TOKEN_ID                identifier 
 SWIG_TOKEN_FLOAT             Floating point with F suffix (e.g., 3.1415F)
 SWIG_TOKEN_DOUBLE            Floating point (e.g., 3.1415 )
+SWIG_TOKEN_LONGDOUBLE        Floating point with L suffix (e.g., 3.1415L)
 SWIG_TOKEN_INT               Integer (e.g., 314)
 SWIG_TOKEN_UINT              Unsigned integer (e.g., 314U)
 SWIG_TOKEN_LONG              Long integer (e.g., 314L) 
 SWIG_TOKEN_ULONG             Unsigned long integer (e.g., 314UL)
 SWIG_TOKEN_LONGLONG          Long long integer (e.g., 314LL )
 SWIG_TOKEN_ULONGLONG         Unsigned long long integer (e.g., 314ULL) 
+SWIG_TOKEN_BOOL              Boolean literal (true or false)
 SWIG_TOKEN_CHAR              Character literal in single quotes ('c')
+SWIG_TOKEN_WCHAR             Wide character literal (L'c')
 SWIG_TOKEN_STRING            String literal in double quotes ("str")
 SWIG_TOKEN_RSTRING           Reverse quote string (`str`)
 SWIG_TOKEN_CODEBLOCK         SWIG code literal block %{ ... %}
 SWIG_TOKEN_COMMENT           C or C++ comment  (// or /* ... */)
+SWIG_TOKEN_WSTRING           Wide string literal (L"str")
 SWIG_TOKEN_ILLEGAL           Illegal character
 </pre>
 </blockquote>
@@ -259,9 +264,6 @@
 <b>Notes</b>
 
 <ul>
-<li>When more than one token code exist for the same token text, those codes are identical (e.g., <tt>SWIG_TOKEN_STAR</tt> and <tt>SWIG_TOKEN_TIMES</tt>).
-
-<p>
 <li>
 String literals are returned in their exact representation in which escape codes (if any) have been interpreted.
 
@@ -276,7 +278,7 @@
 <p>
 <li>The maximum token integer value is found in the constant <tt>SWIG_MAXTOKENS</tt>.   This can be used if you wanted to create 
 an array or table for the purposes of remapping tokens to a different set of codes. For instance, if you are
-using these functions to write a yacc-compatible lexer.
+using these functions to write a bison-compatible lexer.
 </ul>
 
 </body>
diff --git a/Doc/Devel/tree.html b/Doc/Devel/tree.html
index 5bb4b6a..6ccfd63 100644
--- a/Doc/Devel/tree.html
+++ b/Doc/Devel/tree.html
@@ -183,8 +183,8 @@
 <b><tt>void Swig_require(const char *namespace, Node *n, ...)</tt></b>
 
 <blockquote>
-This function is similar to <tt>Swig_save()</tt> except that adds additional attribute checking. There are different interpretations
-of the attribute names.  A name of "attr" merely requests that the function check for the presence of an attribute.  If the attribute is missing, SWIG will exit with a failed assertion.   An attribute name of "?attr" specifies that the attribute "attr" is optional and
+This function is similar to <tt>Swig_save()</tt> except that it performs additional attribute checking. There are different interpretations
+of the attribute names.  A name of "attr" merely requests that the function check for the presence of an attribute.  If the attribute is missing, SWIG will exit with a fatal error.   An attribute name of "?attr" specifies that the attribute "attr" is optional and
 that its old value must be saved (if any).   An attribute name of "*attr" specifies that the attribute is required and that
 its value must be saved.   The saving of attributes is performed in the same manner as with <tt>Swig_save()</tt>. Here is an example:
 
@@ -241,17 +241,17 @@
 
 <pre>
 % swig -debug-tags -python example.i
- . top (:1)
- . top . include (/Users/beazley/Projects/share/swig/1.3.31/swig.swg:0)
- . top . include . include (/Users/beazley/Projects/share/swig/1.3.31/swigwarnings.swg:0)
- . top . include . include . include (/Users/beazley/Projects/share/swig/1.3.31/swigwarn.swg:0)
+:1:  . top
+:1:  . top . include
+/usr/share/swig/swig.swg:320:  . top . include . include
+/usr/share/swig/swigwarnings.swg:39:  . top . include . include . include
 ...
 ...
- . top . include (example.i:0)
- . top . include . module (example.i:2)
- . top . include . insert (example.i:7)
- . top . include . cdecl (example.i:5)
- . top . include . cdecl (example.i:6)
+:4:  . top . include
+example.i:2:  . top . include . module
+example.i:7:  . top . include . insert
+example.i:5:  . top . include . cdecl
+example.i:6:  . top . include . cdecl
 </pre>
 
 Since many language modules include hundreds of typemaps and other information, the output of this can be significantly more complicated than you might expect.
diff --git a/Doc/Manual/Allegrocl.html b/Doc/Manual/Allegrocl.html
deleted file mode 100644
index 4069ecd..0000000
--- a/Doc/Manual/Allegrocl.html
+++ /dev/null
@@ -1,2150 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-<title>SWIG and Allegro Common Lisp</title>
-<link rel="stylesheet" type="text/css" href="style.css">
-<meta http-equiv="content-type" content="text/html; charset=UTF-8">
-</head>
-
-<body bgcolor="#ffffff">
-
-<H1><a name="Allegrocl">20 SWIG and Allegro Common Lisp</a></H1>
-<!-- INDEX -->
-<div class="sectiontoc">
-<ul>
-<li><a href="#Allegrocl_nn2">Basics</a>
-<ul>
-<li><a href="#Allegrocl_nn3">Running SWIG</a>
-<li><a href="#Allegrocl_nn4">Command Line Options</a>
-<li><a href="#Allegrocl_nn5">Inserting user code into generated files</a>
-</ul>
-<li><a href="#Allegrocl_nn6">Wrapping Overview</a>
-<ul>
-<li><a href="#Allegrocl_nn7">Function Wrapping</a>
-<li><a href="#Allegrocl_nn8">Foreign Wrappers</a>
-<li><a href="#Allegrocl_nn9">FFI Wrappers</a>
-<li><a href="#Allegrocl_nn10">Non-overloaded Defuns</a>
-<li><a href="#Allegrocl_nn11">Overloaded Defuns</a>
-<li><a href="#Allegrocl_nn12">What about constant and variable access?</a>
-<li><a href="#Allegrocl_nn13">Object Wrapping</a>
-</ul>
-<li><a href="#Allegrocl_nn14">Wrapping Details</a>
-<ul>
-<li><a href="#Allegrocl_nn15">Namespaces</a>
-<li><a href="#Allegrocl_nn16">Constants</a>
-<li><a href="#Allegrocl_nn17">Variables</a>
-<li><a href="#Allegrocl_nn18">Enumerations</a>
-<li><a href="#Allegrocl_nn19">Arrays</a>
-<li><a href="#Allegrocl_nn20">Classes and Structs and Unions (oh my!)</a>
-<ul>
-<li><a href="#Allegrocl_nn21">CLOS wrapping of</a>
-<li><a href="#Allegrocl_nn22">CLOS Inheritance</a>
-<li><a href="#Allegrocl_nn23">Member fields and functions</a>
-<li><a href="#Allegrocl_nn24">Why not directly access C++ classes using foreign types?</a>
-</ul>
-<li><a href="#Allegrocl_nn25">Templates</a>
-<ul>
-<li><a href="#Allegrocl_nn26">Generating wrapper code for templates</a>
-<li><a href="#Allegrocl_nn27">Implicit Template instantiation</a>
-</ul>
-<li><a href="#Allegrocl_nn28">Typedef, Templates, and Synonym Types</a>
-<ul>
-<li><a href="#Allegrocl_nn29">Choosing a primary type</a>
-</ul>
-<li><a href="#Allegrocl_nn30">Function overloading/Parameter defaulting</a>
-<li><a href="#Allegrocl_nn31">Operator wrapping and Operator overloading</a>
-<li><a href="#Allegrocl_nn32">Varargs</a>
-<li><a href="#Allegrocl_nn33">C++ Exceptions</a>
-<li><a href="#Allegrocl_nn34">Pass by value, pass by reference</a>
-</ul>
-<li><a href="#Allegrocl_nn35">Typemaps</a>
-<ul>
-<li><a href="#Allegrocl_nn36">Code Generation in the C++ Wrapper</a>
-<ul>
-<li><a href="#Allegrocl_nn37">IN Typemap</a>
-<li><a href="#Allegrocl_nn38">OUT Typemap</a>
-<li><a href="#Allegrocl_nn39">CTYPE Typemap</a>
-</ul>
-<li><a href="#Allegrocl_nn40">Code generation in Lisp wrappers</a>
-<ul>
-<li><a href="#Allegrocl_nn41">LIN Typemap</a>
-<li><a href="#Allegrocl_nn42">LOUT Typemap</a>
-<li><a href="#Allegrocl_nn43">FFITYPE Typemap</a>
-<li><a href="#Allegrocl_nn44">LISPTYPE Typemap</a>
-<li><a href="#Allegrocl_nn45">LISPCLASS Typemap</a>
-</ul>
-<li><a href="#Allegrocl_nn46">Modifying SWIG behavior using typemaps</a>
-</ul>
-<li><a href="#Allegrocl_nn47">Identifier Converter functions</a>
-<ul>
-<li><a href="#Allegrocl_nn48">Creating symbols in the lisp environment</a>
-<li><a href="#Allegrocl_nn49">Existing identifier-converter functions</a>
-<ul>
-<li><a href="#Allegrocl_nn50">identifier-convert-null</a>
-<li><a href="#Allegrocl_nn51">identifier-convert-lispify</a>
-<li><a href="#Allegrocl_nn52">Default identifier to symbol conversions</a>
-</ul>
-<li><a href="#Allegrocl_nn53">Defining your own identifier-converter</a>
-<li><a href="#Allegrocl_nn54">Instructing SWIG to use a particular identifier-converter</a>
-</ul>
-</ul>
-</div>
-<!-- INDEX -->
-
-
-
-<p>
-This chapter describes SWIG's support of Allegro Common Lisp. Allegro
-CL is a full-featured implementation of the Common Lisp language
-standard that includes many vendor-specific enhancements and add-on
-modules for increased usability.
-</p>
-
-<p>
-One such module included in Allegro CL is the Foreign Functions
-Interface (FFI). This module, tailored primarily toward interfacing
-with C/C++ and, historically, Fortran, provides a means by which
-compiled foreign code can be loaded into a running lisp
-environment and executed. The interface supports the calling of
-foreign functions and methods, allows for executing lisp routines
-from foreign code (callbacks), and the passing of data between foreign
-and lisp code.
-</p>
-
-<p>
-The goal of this module is to make it possible to quickly generate the
-necessary foreign function definitions so one can make use of C/C++
-foreign libraries directly from lisp without the tedium of having to
-code them by hand. When necessary, it will also generate further C/C++
-code that will need to be linked with the intended library for proper
-interfacing from lisp. It has been designed with an eye toward
-flexibility. Some foreign function calls may release the heap, while
-other should not. Some foreign functions should automatically convert
-lisp strings into native strings, while others should not. These
-adjustments and many more are possible with the current module.
-</p>
-
-<p>
-It is significant to note that, while this is a vendor-specific
-module, we would like to acknowledge the current and ongoing
-work by developers in the open source lisp community that are
-working on similar interfaces to implementation-independent
-foreign function interfaces (CFFI, for example). Such
-work can only benefit the lisp community, and we would not
-be unhappy to see some enterprising folk use this work to add
-to it.
-</p>
-
-<H2><a name="Allegrocl_nn2">20.1 Basics</a></H2>
-
-
-<H3><a name="Allegrocl_nn3">20.1.1 Running SWIG</a></H3>
-
-
-<p>
-If you're reading this, you must have some library you need to
-generate an interface for. In order for SWIG to do this work, however,
-it needs a bit of information about how it should go about creating
-your interface, and what you are interfacing to.
-</p>
-
-<p>
-SWIG expects a description of what in the foreign interface you wish
-to connect to. It must consisting of C/C++ declarations and special
-SWIG directives. SWIG can be furnished with a header file, but an
-interface can also be generated without library headers by supplying a
-simple text file--called the interface file, which is typically named
-with a <tt>.i</tt> extension--containing any foreign declarations of
-identifiers you wish to use. The most common approach is to use an
-interface file with directives to parse the needed headers. A straight
-parse of library headers will result in usable code, but SWIG
-directives provides much freedom in how a user might tailor the
-generated code to their needs or style of coding.
-</p>
-
-<p>
-Note that SWIG does not require any function definitions; the
-declarations of those functions is all that is necessary. Be careful
-when tuning the interface as it is quite possible to generate code
-that will not load or compile.
-</p>
-
-<p>
-An example interface file is shown below. It makes use of two SWIG
-directives, one of which requests that the declarations in a header
-file be used to generate part of the interface, and also includes an
-additional declaration to be added.</p>
-
-<div class="code">example.i
-<pre>
-%module example
-
-%include "header.h"
-
-int fact(int n);
-</pre>
-</div>
-
-<p>The contents of header.h are very simple:</p>
-<div class="code">header.h
-<pre>
-int fact(char *statement);   // pass it a fact, and it will rate it.
-</pre>
-</div>
-
-<p>The contents of example.cl will look like this:</p>
-
-<div class="targetlang">example.cl
-<pre>
-(defpackage :example
-  (:use :common-lisp :swig :ff :excl))
-
-  ... helper routines for defining the interface ...
-
-(swig-in-package ())
-
-(swig-defun ("fact")
-  ((PARM0_statement cl:string (* :char) ))
-  (:returning (:int )
-   :strings-convert t)
-  (let ((SWIG_arg0 PARM0_statement))
-  (swig-ff-call SWIG_arg0)))
-
-(swig-defun ("fact")
-  ((PARM0_n cl:integer :int ))
-  (:returning (:int )
-   :strings-convert t)
-  (let ((SWIG_arg0 PARM0_n))
-  (swig-ff-call SWIG_arg0)))
-
-(swig-dispatcher ("fact" :type :function :arities (1)))
-</pre>
-</div>
-
-<p>
-The generated file contains calls to internal swig helper
-functions. In this case there are two calls to swig-defun.
-These calls will expand into code that will make the appropriate
-definitions using the Allegro FFI. Note also, that this code is
-<b>erroneous</b>. Function overloading is not supported in C, and this
-code will not compile even though SWIG did not complain.
-</p>
-
-<p>
-In order to generate a C interface to Allegro CL using this code run
-swig using the <tt>-allegrocl</tt> option, as below:
-</p>
-
-<div class="shell">
-<pre>
-% swig -allegrocl example.i
-</pre>
-</div>
-
-<p>
-When building an interface to C++ code, include the <tt>-c++</tt> option:
-</p>
-
-<div class="shell">
-<pre>
-% swig -allegrocl -c++ example.i
-</pre>
-</div>
-
-<p>
-As a result of running one of the above commands, a file named <tt>example.cl</tt> 
-will be generated containing the lisp side of the interface. As well, a file 
-<tt>example_wrap.cxx</tt> is also generated, containing C/C++ wrapper code to
-facilitate access to C++ methods, enumeration values, and constant values.
-Wrapper functions are necessary in C++ due to the lack of a standard for mangling 
-the names of symbols across all C++ compilers. These wrapper functions are
-exported from the shared library as appropriate, using the C name mangling
-convention. The lisp code that is generated will interface to your foreign
-library through these wrappers.
-</p>
-
-<p>
-It is possible to disable the creation of the .cxx file when generating a C
-interface by using the -nocwrap command-line argument. For interfaces that
-don't contain complex enum or constant expressions, contain nested struct/union
-declarations, or doesn't need to use many of the SWIG customization featuers, 
-this will result in a more streamlined, direct interface to the
-intended module.
-</p>
-
-<p>
-The generated wrapper file is below. It contains very simple
-wrappers by default, that simply pass the arguments to the
-actual function.
-</p>
-
-<div class="code">example_wrap.i
-<pre>
-  ... lots of SWIG internals ...
-
-EXPORT int ACL___fact__SWIG_0 (char *larg1) {
-  int lresult = (int)0 ;
-  char *arg1 = (char *) 0 ;
-  int result;
-
-  arg1 = larg1;
-  try {
-    result = (int)fact(arg1);
-
-    lresult = result;
-    return lresult;
-  } catch (...) {
-    return (int)0;
-  }
-}
-
-
-EXPORT int ACL___fact__SWIG_1 (int larg1) {
-  int lresult = (int)0 ;
-  int arg1 ;
-  int result;
-
-  arg1 = larg1;
-  try {
-    result = (int)fact(arg1);
-
-    lresult = result;
-    return lresult;
-  } catch (...) {
-    return (int)0;
-  }
-}
-</pre>
-</div>
-
-<p>
-And again, the generated lisp code. Note that it differs from
-what is generated when parsing C code:
-</p>
-
-<div class="targetlang">
-<pre>
-  ...
-
-(swig-in-package ())
-
-(swig-defmethod ("fact" "ACL___fact__SWIG_0" :type :function :arity 1)
-  ((PARM0_statement cl:string (* :char) ))
-  (:returning (:int )
-   :strings-convert t)
-  (let ((SWIG_arg0 PARM0_statement))
-  (swig-ff-call SWIG_arg0)))
-
-(swig-defmethod ("fact" "ACL___fact__SWIG_1" :type :function :arity 1)
-  ((PARM0_n cl:integer :int ))
-  (:returning (:int )
-   :strings-convert t)
-  (let ((SWIG_arg0 PARM0_n))
-  (swig-ff-call SWIG_arg0)))
-
-(swig-dispatcher ("fact" :type :function :arities (1)))
-</pre>
-</div>
-
-<p>In this case, the interface generates two swig-defmethod forms and
-a swig-dispatcher form. This provides a single functional interface for
-all overloaded routines. A more detailed description of this features 
-is to be found in the section titled <b>Function overloading/Parameter defaulting</b>.
-
-<p>
-In order to load a C++ interface, you will need to build a shared library
-from example_wrap.cxx. Be sure to link in the actual library you created
-the interface for, as well as any other dependent shared libraries. For
-example, if you intend to be able to call back into lisp, you will also
-need to link in the Allegro shared library. The library you create from
-the C++ wrapper will be what you then load into Allegro CL.
-</p>
-
-<H3><a name="Allegrocl_nn4">20.1.2 Command Line Options</a></H3>
-
-
-<p>
-There are three Allegro CL specific command-line option:
-</p>
-
-<div class="shell">
-<pre>
-swig -allegrocl [ options ] filename
-
-   -identifier-converter [name] - Binds the variable swig:*swig-identifier-convert* 
-                                  in the generated .cl file to <tt>name</tt>.
-                                  This function is used to generate symbols
-                                  for the lisp side of the interface.
-
-   -cwrap - [default] Generate a .cxx file containing C wrapper function when
-            wrapping C code. The interface generated is similar to what is
-            done for C++ code.
-   -nocwrap - Explicitly turn off generation of .cxx wrappers for C code. Reasonable
-              for modules with simple interfaces. Can not handle all legal enum
-              and constant constructs, or take advantage of SWIG customization features.
-
-   -isolate - With this command-line argument, all lisp helper functions are defined
-              in a unique package named <tt>swig.&lt;module-name&gt;</tt> rather than
-              <tt>swig</tt>. This prevents conflicts when the module is
-              intended to be used with other swig generated interfaces that may,
-              for instance, make use of different identifier converters.
-</pre>
-</div>
-
-<p>
-See <a href="#Allegrocl_nn47">Section 17.5 Identifier converter
-functions</a> for more details.
-</p>
-
-<H3><a name="Allegrocl_nn5">20.1.3 Inserting user code into generated files</a></H3>
-
-
-<p>
-It is often necessary to include user-defined code into the
-automatically generated interface files. For example, when building
-a C++ interface, example_wrap.cxx will likely not compile unless
-you add a <tt>#include "header.h"</tt> directive. This can be done
-using the SWIG <tt>%insert(section) %{ ...code... %}</tt> directive:
-</p>
-
-<div class="code">
-<pre>
-%module example
-
-%{
-#include "header.h"
-%}
-
-%include "header.h"
-
-int fact(int n);
-</pre>
-</div>
-
-<p>
-Additional sections have been added for inserting into the
-generated lisp interface file
-</p>
-<ul>
-  <li><tt>lisphead</tt> - inserts before type declarations</li>
-  <li><tt>lisp</tt> - inserts after type declarations according to
-    where it appears in the .i file</li>
-</ul>
-<p>
-Note that the block <tt>%{ ... %}</tt> is effectively a shortcut for
-<tt>%insert("header") %{ ... %}</tt>.
-</p>
-
-
-<H2><a name="Allegrocl_nn6">20.2 Wrapping Overview</a></H2>
-
-
-<p>
-New users to SWIG are encouraged to read
-<a href="SWIG.html#SWIG">SWIG Basics</a>, and
-<a href="SWIGPlus.html#SWIGPlus">SWIG and C++</a>, for those
-interested in generating an interface to C++.
-</p>
-
-<H3><a name="Allegrocl_nn7">20.2.1 Function Wrapping</a></H3>
-
-
-  <p>
-  Writing lisp code that directly invokes functions at the foreign
-  function interface level can be cumbersome. Data must often be
-  translated between lisp and foreign types, data extracted from
-  objects, foreign objects allocated and freed upon completion of
-  the foreign call. Dealing with pointers can be unwieldy when it
-  comes to keeping them distinct from other valid integer values.
-  </p>
-
-  <p>
-  We make an attempt to ease some of these burdens by making the
-  interface to foreign code much more lisp-like, rather than C
-  like. How this is done is described in later chapters. The
-  layers themselves, appear as follows:
-  </p>
-
-  <div class="diagram">
-  <pre>
-        ______________
-       |              |  (foreign side)
-       | Foreign Code |  What we're generating an interface to.
-       |______________|
-               |
-               |
-        _______v______
-       |              |  (foreign side)
-       | Wrapper code |  extern "C" wrappers calling C++ 
-       |______________|  functions and methods.
-               |
-    .  . . - - + - - . .  .
-        _______v______
-       |              |  (lisp side)
-       |  FFI Layer   |  Low level lisp interface. ff:def-foreign-call,
-       |______________|  ff:def-foreign-variable
-               |
-               +----------------------------
-        _______v______              _______v______
-       |              |            |              | (lisp side)    
-       |    Defuns    |            |  Defmethods  | wrapper for overloaded
-       |______________|            |______________| functions or those with
-        (lisp side)                        |        defaulted arguments
-        Wrapper for non-overloaded         |
-        functions and methods       _______v______
-                                   |              | (lisp side)
-                                   |    Defuns    | dispatch function
-                                   |______________| to overloads based
-                                                    on arity
-  </pre>
-  </div>
-
-<H3><a name="Allegrocl_nn8">20.2.2 Foreign Wrappers</a></H3>
-
-
-  <p>
-    These wrappers are as generated by SWIG default. The types of
-    function parameters can be transformed in place using the CTYPE
-    typemap. This is use for converting pass-by-value parameters to
-    pass-by-reference where necessary. All wrapper parameters are then
-    bound to local variables for possible transformation of values
-    (see LIN typemap). Return values can be transformed via the OUT
-    typemap. 
-  </p>
-
-<H3><a name="Allegrocl_nn9">20.2.3 FFI Wrappers</a></H3>
-
-
-  <p>
-    These are the generated ff:def-foreign-call forms. No typemaps are
-    applicable to this layer, but the <tt>%ffargs</tt> directive is
-    available for use in .i files, to specify which keyword arguments
-    should be specified for a given function.
-  </p>
-  
-  <div class="code">ffargs.i:
-  <pre>
-%module ffargs
-
-%ffargs(strings_convert="nil", call_direct="t") foo;
-%ffargs(strings_convert="nil", release_heap=":never", optimize_for_space="t") bar;
-
-int foo(float f1, float f2);
-int foo(float f1, char c2);
-
-void bar(void *lisp_fn);
-
-char *xxx();
-  </pre>
-  </div>
-
-  <p>Generates:
-  </p>
-  <div class="targetlang">ffargs.cl:
-  <pre>
-(swig-in-package ())
-
-(swig-defmethod ("foo" "ACL___foo__SWIG_0" :type :function :arity 2)
-  ((PARM0_f1 cl:single-float :float )
-   (PARM1_f2 cl:single-float :float ))
-  (:returning (:int )
-   :call-direct t
-   :strings-convert nil)
-  (let ((SWIG_arg0 PARM0_f1))
-  (let ((SWIG_arg1 PARM1_f2))
-  (swig-ff-call SWIG_arg0 SWIG_arg1))))
-
-(swig-defmethod ("foo" "ACL___foo__SWIG_1" :type :function :arity 2)
-  ((PARM0_f1 cl:single-float :float )
-   (PARM1_c2 cl:character :char character))
-  (:returning (:int )
-   :call-direct t
-   :strings-convert nil)
-  (let ((SWIG_arg0 PARM0_f1))
-  (let ((SWIG_arg1 PARM1_c2))
-  (swig-ff-call SWIG_arg0 SWIG_arg1))))
-
-(swig-dispatcher ("foo" :type :function :arities (2)))
-(swig-defun ("bar" "ACL___bar__SWIG_0" :type :function)
-  ((PARM0_lisp_fn  (* :void) ))
-  (:returning (:void )
-   :release-heap :never
-   :optimize-for-space t
-   :strings-convert nil)
-  (let ((SWIG_arg0 PARM0_lisp_fn))
-  (swig-ff-call SWIG_arg0)))
-
-
-(swig-defun ("xxx" "ACL___xxx__SWIG_0" :type :function)
-  (:void)
-  (:returning ((* :char) )
-   :strings-convert t)
-  (swig-ff-call))
-  </pre>
-  </div>
-
-  <div class="code">
-    <pre>%ffargs(strings_convert="t");</pre>
-  </div>
-
-  <p>
-    Is the only default value specified in <tt>allegrocl.swg</tt> to force
-    the muffling of warnings about automatic string conversion when defining
-    ff:def-foreign-call's.
-  </p>
-
-<H3><a name="Allegrocl_nn10">20.2.4 Non-overloaded Defuns</a></H3>
-
-
-  <p>
-    These are simple defuns. There is no typechecking of arguments.
-    Parameters are bound to local variables for possible
-    transformation of values, such as pulling values out of instance
-    slots or allocating temporary stack allocated structures, via the
-    <tt>lin</tt> typemap. These arguments are then passed to the
-    foreign-call (where typechecking may occur). The return value from
-    this function can be manipulated via the <tt>lout</tt> typemap.
-  </p>
-
-<H3><a name="Allegrocl_nn11">20.2.5 Overloaded Defuns</a></H3>
-
-
-  <p>
-    In the case of overloaded functions, multiple layers are
-    generated. First, all the overloads for a given name are separated
-    out into groups based on arity, and are wrapped in
-    defmethods. Each method calls a distinct wrapper function, but are
-    themselves distinguished by the types of their arguments
-    (see <tt>lispclass</tt> typemap). These are further wrapped in a
-    dispatching function (defun) which will invoke the appropriate
-    generic-function based on arity. This provides a single functional
-    interface to all overloads. The return value from this function
-    can be manipulated via the <tt>lout</tt> typemap.
-  </p>
-
-<H3><a name="Allegrocl_nn12">20.2.6 What about constant and variable access?</a></H3>
-
-
-  <p>
-    Along with the described functional layering, when creating a .cxx wrapper, 
-    this module will generate getter and--if not immutable--setter,
-    functions for variables and constants. If the -nocwrap option is used,
-    <tt>defconstant</tt> and <tt>ff:def-foreign-variable</tt> forms will be
-    generated for accessing constants and global variables. These, along with
-    the <tt>defuns</tt> listed above are the intended API for calling
-    into the foreign module.
-  </p>
-
-<H3><a name="Allegrocl_nn13">20.2.7 Object Wrapping</a></H3>
-
-
-  <p>
-  All non-primitive types (Classes, structs, unions, and typedefs
-  involving same) have a corresponding foreign-type defined on the
-  lisp side via ff:def-foreign-type.
-  </p>
-
-  <p>
-  All non-primitive types are further represented by a CLOS class,
-  created via defclass. An attempt is made to create the same class
-  hierarchy, with all classes inheriting directly or indirectly from
-  ff:foreign-pointer. Further, wherever it is apparent, all pointers
-  returned from foreign code are wrapped in a CLOS instance of the
-  appropriate class. For ff:def-foreign-calls that have been defined
-  to expect a :foreign-address type as argument, these CLOS instances
-  can legally be passed and the pointer to the C++ object
-  automatically extracted. This is a natural feature of Allegro's
-  foreign function interface.
-  </p>
-
-<H2><a name="Allegrocl_nn14">20.3 Wrapping Details</a></H2>
-
-
-  <p>
-    In this section is described how particular C/C++ constructs are
-    translated into lisp.
-  </p>
-
-<H3><a name="Allegrocl_nn15">20.3.1 Namespaces</a></H3>
-
-
-  <p>
-    C++ namespaces are translated into Lisp packages by SWIG. The
-    Global namespace is mapped to a package named by the <tt>%module</tt>
-    directive or the <tt>-module</tt> command-line argument. Further
-    namespaces are generated by the <tt>swig-defpackage</tt> utility
-    function and given names based on Allegro CLs nested namespace
-    convention. For example:
-  </p>
-
-    <div class="code">foo.i:
-    <pre>
-%module foo
-
-%{
-#include "foo.h"
-%}
-
-%include "foo.h"
-
-namespace car {
-  ...
-  namespace tires {
-    int do_something(int n);
-  }
-}
-    </pre>
-    </div>
-  <p>Generates the following code.
-  </p>
-    <div class="targetlang">foo.cl
-    <pre>
-(defpackage :foo
-  (:use :common-lisp :swig :ff :excl))
-
-...
-
-(swig-defpackage ("car"))
-(swig-defpackage ("car" "tires"))
-
-...
-
-(swig-in-package ("car" "tires"))
-(swig-defun ("do_something" "ACL_car_tires__do_something__SWIG_0" :type :function)
-  ((PARM0_n  :int ))
-  (:returning (:int )
-   :strings-convert t)
-  (let ((SWIG_arg0 PARM0_n))
-  (swig-ff-call SWIG_arg0)))
-    </pre>
-    </div>
-
-    <p>
-      The above interface file would cause packages foo, foo.car, and
-      foo.car.tires to be created. One would find the function wrapper
-      for do_something defined in the foo.car.tires package(*).
-    </p>
-
-    <p>(<b>*</b>) Except for the package named by the module, all
-      namespace names are passed to the identifier-converter-function
-      as strings with a <tt>:type</tt> of <tt>:namespace</tt>. It is the
-      job of this function to generate the desired symbol, accounting for
-      case preferences, additional naming cues, etc.
-    </p>
-
-    <p>
-      Note that packages created by <tt>swig-defpackage</tt> do not
-      use the COMMON-LISP or EXCL package. This reduces possible
-      conflicts when defining foreign types via the SWIG interface
-      in <b>all but the toplevel modules package</b>. This may
-      lead to confusion if, for example, the current package is
-      <tt>foo.car.tires</tt> and you attempt to use a common-lisp
-      function such as <tt>(car '(1 2 3)</tt>.
-    </p>
-
-<H3><a name="Allegrocl_nn16">20.3.2 Constants</a></H3>
-
-
-    
-    <p>
-      Constants, as declared by the preprocessor #define macro or SWIG
-      <tt>%constant</tt> directive, are included in SWIG's parse tree
-      when it can be determined that they are, or could be reduced to,
-      a literal value. Such values are translated into defconstant
-      forms in the generated lisp wrapper when the -nocwrap command-line
-      options is used. Else, wrapper functions are generated as in the
-      case of variable access (see section below).
-    </p>
-    <p>
-      Here are examples of simple preprocessor constants when using -nocwrap.
-    </p>
-      <div class="code">
-      <pre>
-#define A 1                    =&gt; (swig-defconstant "A" 1)  
-#define B 'c'                  =&gt; (swig-defconstant "B" #\c)
-#define C B                    =&gt; (swig-defconstant "C" #\c)
-#define D 1.0e2                =&gt; (swig-defconstant "D" 1.0d2)
-#define E 2222                 =&gt; (swig-defconstant "E" 2222)
-#define F (unsigned int)2222   =&gt; no code generated
-#define G 1.02e2f              =&gt; (swig-defconstant "G" 1.02f2)
-#define H foo                  =&gt; no code generated
-      </pre>
-      </div>
-
-      <p>
-      Note that where SWIG is unable to determine if a constant is
-      a literal, no node is added to the SWIG parse tree, and so
-      no values can be generated.
-      </p>
-
-    <p>
-      For preprocessor constants containing expressions which can be
-      reduced to literal values, nodes are created, but with no simplification
-      of the constant value. A very very simple infix to prefix converter
-      has been implemented that tries to do the right thing for simple cases, but
-      does not for more complex expressions. If the literal parser determines
-      that something is wrong, a warning will be generated and the literal 
-      expression will be included in the generated code, but commented out.
-    </p>
-      
-      <div class="code">
-      <pre>
-#define I A + E                =&gt; (swig-defconstant "I" (+ 1 2222))
-#define J 1|2                  =&gt; (swig-defconstant "J" (logior 1 2))
-#define Y 1 + 2 * 3 + 4        =&gt; (swig-defconstant "Y" (* (+ 1 2) (+ 3 4)))
-#define Y1 (1 + 2) * (3 + 4)   =&gt; (swig-defconstant "Y1" (* (+ 1 2) (+ 3 4)))
-#define Y2 1 * 2 + 3 * 4       =&gt; (swig-defconstant "Y2" (* 1 (+ 2 3) 4))  ;; WRONG
-#define Y3 (1 * 2) + (3 * 4)   =&gt; (swig-defconstant "Y3" (* 1 (+ 2 3) 4))  ;; WRONG
-#define Z 1 + 2 - 3 + 4 * 5    =&gt; (swig-defconstant "Z" (* (+ 1 (- 2 3) 4) 5)) ;; WRONG
-      </pre>
-      </div>
-      <p>
-      Users are cautioned to get to know their constants before use, or
-      not use the <tt>-nocwrap</tt> command-line option.
-      </p>
-
-<H3><a name="Allegrocl_nn17">20.3.3 Variables</a></H3>
-
-
-    <p>
-      For C wrapping, a def-foreign-variable call is generated for access
-      to global variables.
-    </p>
-    <p>
-      When wrapping C++ code, both global and member variables, getter
-      wrappers are generated for accessing their value, and if not immutable,
-      setter wrappers as well. In the example below, note the lack of a 
-      setter wrapper for global_var, defined as const.
-    </p>
-
-    <div class="code">vars.h
-    <pre>
-namespace nnn {
-  int const global_var = 2;
-  float glob_float = 2.0;
-}
-    </pre>
-    </div>
-
-    <p>
-    Generated code:
-    </p>
-    <div class="targetlang">vars.cl
-    <pre>
-(swig-in-package ("nnn"))
-(swig-defun ("global_var" "ACL_nnn__global_var_get__SWIG_0" :type :getter)
-  (:void)
-  (:returning (:int )
-   :strings-convert t)
-  (swig-ff-call))
-
-
-(swig-defun ("glob_float" "ACL_nnn__glob_float_set__SWIG_0" :type :setter)
-  ((PARM0_glob_float  :float ))
-  (:returning (:void )
-   :strings-convert t)
-  (let ((SWIG_arg0 PARM0_glob_float))
-  (swig-ff-call SWIG_arg0)))
-
-
-(swig-defun ("glob_float" "ACL_nnn__glob_float_get__SWIG_0" :type :getter)
-  (:void)
-  (:returning (:float )
-   :strings-convert t)
-  (swig-ff-call))
-    </pre>
-    </div>
-
-    <p>
-      Note also, that where applicable, setter wrappers are implemented
-      as setf methods on the getter function, providing a lispy interface
-      to the foreign code.
-    </p>
-
-    <div class="targetlang">
-    <pre>
-user&gt; (load "globalvar.dll")
-; Foreign loading globalvar.dll.
-t
-user&gt; (load "globalvar.cl")
-; Loading c:\mikel\src\swig\test\globalvar.cl
-t
-user&gt; 
-globalvar&gt; (globalvar.nnn::global_var)
-2
-globalvar&gt; (globalvar.nnn::glob_float)
-2.0
-globalvar&gt; (setf (globalvar.nnn::glob_float) 3.0)
-3.0
-globalvar&gt; (globalvar.nnn::glob_float)
-3.0
-    </pre>
-    </div>
-
-<H3><a name="Allegrocl_nn18">20.3.4 Enumerations</a></H3>
-
-
-    <p>
-      In C, an enumeration value is an integer value, while in C++ an
-      enumeration value is implicitly convertible to an integer value,
-      but can also be distinguished by its enum type. For each enum
-      declaration a def-foreign-type is generated, assigning the enum
-      a default type of :int. Users may adjust the foreign type of
-      enums via SWIG <tt>typemaps</tt>.
-    </p>
-
-    <p>
-      Enum values are a bit trickier as they can be initialized using
-      any valid C/C++ expression. In C with the -nocwrap command-line option,
-      we handle the typical cases (simple integer initialization) and
-      generate a defconstant form for each enum value. This has the advantage
-      of it not being necessary to probe into foreign space to retrieve enum
-      values. When generating a .cxx wrapper file, a more general solution is
-      employed. A wrapper variable is created in the module_wrap.cxx file, and
-      a ff:def-foreign-variable call is generated to retrieve its value into lisp.
-    </p>
-
-    <p>For example, the following header file
-      <div class="code">enum.h:
-      <pre>
-enum COL { RED, GREEN, BLUE };
-enum FOO { FOO1 = 10, FOO2, FOO3 };
-      </pre>
-      </div>
-      <p>
-      In -nocwrap mode, generates
-      </p>
-      <div class="targetlang">enum.cl:
-      <pre>
-(swig-def-foreign-type "COL" :int)
-(swig-defconstant "RED" 0)
-(swig-defconstant "GREEN" (+ #.(swig-insert-id "RED" () :type :constant) 1))
-(swig-defconstant "BLUE" (+ #.(swig-insert-id "GREEN" () :type :constant) 1))
-
-(swig-def-foreign-type "FOO" :int)
-(swig-defconstant "FOO1" 10)
-(swig-defconstant "FOO2" (+ #.(swig-insert-id "FOO1" () :type :constant) 1))
-(swig-defconstant "FOO3" (+ #.(swig-insert-id "FOO2" () :type :constant) 1))
-      </pre>
-      </div>
-
-    <p>And when generating a .cxx wrapper
-      <div class="code">enum_wrap.cxx:
-      <pre>
-EXPORT const int ACL_ENUM___RED__SWIG_0 = RED;
-EXPORT const int ACL_ENUM___GREEN__SWIG_0 = GREEN;
-EXPORT const int ACL_ENUM___BLUE__SWIG_0 = BLUE;
-EXPORT const int ACL_ENUM___FOO1__SWIG_0 = FOO1;
-EXPORT const int ACL_ENUM___FOO2__SWIG_0 = FOO2;
-EXPORT const int ACL_ENUM___FOO3__SWIG_0 = FOO3;
-      </pre>
-      </div>
-    <p>
-    and
-    </p>
-      <div class="targetlang">enum.cl:
-      <pre>
-(swig-def-foreign-type "COL" :int)
-(swig-defvar "RED" "ACL_ENUM___RED__SWIG_0" :type :constant)
-(swig-defvar "GREEN" "ACL_ENUM___GREEN__SWIG_0" :type :constant)
-(swig-defvar "BLUE" "ACL_ENUM___BLUE__SWIG_0" :type :constant)
-
-(swig-def-foreign-type "FOO" :int)
-(swig-defvar "FOO1" "ACL_ENUM___FOO1__SWIG_0" :type :constant)
-(swig-defvar "FOO2" "ACL_ENUM___FOO2__SWIG_0" :type :constant)
-(swig-defvar "FOO3" "ACL_ENUM___FOO3__SWIG_0" :type :constant)
-
-      </pre>
-      </div>
-
-<H3><a name="Allegrocl_nn19">20.3.5 Arrays</a></H3>
-
-
-    <p>
-    One limitation in the Allegro CL foreign-types module, is that,
-    without macrology, expressions may not be used to specify the
-    dimensions of an array declaration. This is not a horrible
-    drawback unless it is necessary to allocate foreign structures
-    based on the array declaration using ff:allocate-fobject. When it
-    can be determined that an array bound is a valid numeric value,
-    SWIG will include this in the generated array declaration on the
-    lisp side, otherwise the value will be included, but commented out.
-    </p>
-
-    <p>
-      Below is a comprehensive example, showing a number of legal
-      C/C++ array declarations and how they are translated
-      into foreign-type specifications in the generated lisp code.
-    </p>
-    <div class="code">array.h
-    <pre>
-#define MAX_BUF_SIZE 1024
-
-namespace FOO {
-  int global_var1[13];
-  float global_var2[MAX_BUF_SIZE];
-
-}
-
-enum COLOR { RED = 10, GREEN = 20, BLUE, PURPLE = 50, CYAN };
-
-namespace BAR {
-  char global_var3[MAX_BUF_SIZE + 1];
-  float global_var4[MAX_BUF_SIZE][13];
-  signed short global_var5[MAX_BUF_SIZE + MAX_BUF_SIZE];
-
-  int enum_var5[GREEN];
-  int enum_var6[CYAN];
-
-  COLOR enum_var7[CYAN][MAX_BUF_SIZE];
-}
-    </pre>
-    </div>
-
-    <p>
-    Generates:
-    </p>
-
-    <div class="targetlang">array.cl
-    <pre>
-(in-package #.*swig-module-name*)
-
-(swig-defpackage ("FOO"))
-(swig-defpackage ("BAR"))
-
-(swig-in-package ())
-(swig-def-foreign-type "COLOR" :int)
-(swig-defvar "RED" "ACL_ENUM___RED__SWIG_0" :type :constant)
-(swig-defvar "GREEN" "ACL_ENUM___GREEN__SWIG_0" :type :constant)
-(swig-defvar "BLUE" "ACL_ENUM___BLUE__SWIG_0" :type :constant)
-(swig-defvar "PURPLE" "ACL_ENUM___PURPLE__SWIG_0" :type :constant)
-(swig-defvar "CYAN" "ACL_ENUM___CYAN__SWIG_0" :type :constant)
-
-(swig-in-package ())
-
-(swig-defconstant "MAX_BUF_SIZE" 1024)
-(swig-in-package ("FOO"))
-
-(swig-defun ("global_var1" "ACL_FOO__global_var1_get__SWIG_0" :type :getter)
-  (:void)
-  (:returning ((* :int) )
-   :strings-convert t)
-  (make-instance 'ff:foreign-pointer :foreign-address (swig-ff-call)))
-
-
-(swig-defun ("global_var2" "ACL_FOO__global_var2_set__SWIG_0" :type :setter)
-  ((global_var2  (:array :float 1024) ))
-  (:returning (:void )
-   :strings-convert t)
-  (let ((SWIG_arg0 global_var2))
-  (swig-ff-call SWIG_arg0)))
-
-
-(swig-in-package ())
-(swig-in-package ("BAR"))
-(swig-defun ("global_var3" "ACL_BAR__global_var3_set__SWIG_0" :type :setter)
-  ((global_var3  (:array :char #|1024+1|#) ))
-  (:returning (:void )
-   :strings-convert t)
-  (let ((SWIG_arg0 global_var3))
-  (swig-ff-call SWIG_arg0)))
-
-
-(swig-defun ("global_var4" "ACL_BAR__global_var4_set__SWIG_0" :type :setter)
-  ((global_var4  (:array (:array :float 13) 1024) ))
-  (:returning (:void )
-   :strings-convert t)
-  (let ((SWIG_arg0 global_var4))
-  (swig-ff-call SWIG_arg0)))
-
-
-(swig-defun ("global_var4" "ACL_BAR__global_var4_get__SWIG_0" :type :getter)
-  (:void)
-  (:returning ((* (:array :float 13)) )
-   :strings-convert t)
-  (make-instance 'ff:foreign-pointer :foreign-address (swig-ff-call)))
-
-
-(swig-defun ("global_var5" "ACL_BAR__global_var5_set__SWIG_0" :type :setter)
-  ((global_var5  (:array :short #|1024+1024|#) ))
-  (:returning (:void )
-   :strings-convert t)
-  (let ((SWIG_arg0 global_var5))
-  (swig-ff-call SWIG_arg0)))
-
-
-(swig-defun ("enum_var5" "ACL_BAR__enum_var5_set__SWIG_0" :type :setter)
-  ((enum_var5  (:array :int #|GREEN|#) ))
-  (:returning (:void )
-   :strings-convert t)
-  (let ((SWIG_arg0 enum_var5))
-  (swig-ff-call SWIG_arg0)))
-
-
-(swig-defun ("enum_var6" "ACL_BAR__enum_var6_set__SWIG_0" :type :setter)
-  ((enum_var6  (:array :int #|CYAN|#) ))
-  (:returning (:void )
-   :strings-convert t)
-  (let ((SWIG_arg0 enum_var6))
-  (swig-ff-call SWIG_arg0)))
-
-
-(swig-defun ("enum_var7" "ACL_BAR__enum_var7_set__SWIG_0" :type :setter)
-  ((enum_var7  (:array (:array #.(swig-insert-id "COLOR" ()) 1024) #|CYAN|#) ))
-  (:returning (:void )
-   :strings-convert t)
-  (let ((SWIG_arg0 enum_var7))
-  (swig-ff-call SWIG_arg0)))
-
-
-(swig-defun ("enum_var7" "ACL_BAR__enum_var7_get__SWIG_0" :type :getter)
-  (:void)
-  (:returning ((* (:array #.(swig-insert-id "COLOR" ()) 1024)) )
-   :strings-convert t)
-  (make-instance 'ff:foreign-pointer :foreign-address (swig-ff-call)))
-    </pre>
-    </div>
-
-<H3><a name="Allegrocl_nn20">20.3.6 Classes and Structs and Unions (oh my!)</a></H3>
-
-
-<H4><a name="Allegrocl_nn21">20.3.6.1 CLOS wrapping of</a></H4>
-
-
-    <p>
-      Classes, unions, and structs are all treated the same way by the
-      interface generator. For any of these objects, a
-      def-foreign-type and a defclass form are generated.  For every
-      function that returns an object (or pointer/reference) of C/C++
-      type <tt>X</tt>, the wrapping defun (or defmethod) on the Lisp
-      side will automatically wrap the pointer returned in an instance
-      of the appropriate class. This makes it much easier to write and
-      debug code than if pointers were passed around as a jumble of
-      integer values.
-    </p>
-
-<H4><a name="Allegrocl_nn22">20.3.6.2 CLOS Inheritance</a></H4>
-
-
-    <p>
-      The CLOS class schema generated by the interface mirrors the
-      inheritance of the classes in foreign code, with the
-      ff:foreign-pointer class at its root. ff:foreign-pointer is a thin
-      wrapper for pointers that is made available by the foreign function
-      interface. Its key benefit is that it may be passed as an argument
-      to any ff:def-foreign-call that is expecting a pointer as the
-      parameter.
-    </p>
-
-<H4><a name="Allegrocl_nn23">20.3.6.3 Member fields and functions</a></H4>
-
-
-    <p>
-      All public fields will have accessor getter/setter functions
-      generated for them, as appropriate. All public member functions
-      will have wrapper functions generated.
-    </p>
-
-    <p>
-      We currently ignore anything that isn't <tt>public</tt> (i.e.
-      <tt>private</tt> or <tt>protected</tt>), because the C++ compiler
-      won't allow the wrapper functions to access such fields. Likewise,
-      the interface does nothing for <tt>friend</tt> directives, 
-    </p>
-
-<H4><a name="Allegrocl_nn24">20.3.6.4 Why not directly access C++ classes using foreign types?</a></H4>
-
-
-    <p>
-      The def-foreign-type generated by the SWIG interface is
-      currently incomplete. We can reliably generate the object layout
-      of simple structs and unions; they can be allocated via
-      ff:allocate-fobject, and their member variables accessed
-      directly using the various ff:fslot-value-* functions. However,
-      the layout of C++ classes is more complicated. Different
-      compilers adjust class layout based on inheritance patterns, and
-      the presence of virtual member functions. The size of member
-      function pointers vary across compilers as well. As a result, it
-      is recommended that users of any generated interface not attempt
-      to access C++ instances via the foreign type system, but instead
-      use the more robust wrapper functions. 
-    </p>
-
-<H3><a name="Allegrocl_nn25">20.3.7 Templates</a></H3>
-
-
-    
-<H4><a name="Allegrocl_nn26">20.3.7.1 Generating wrapper code for templates</a></H4>
-
-
-<p>
-SWIG provides support for dealing with templates, but by
-default, it will not generate any member variable or function
-wrappers for templated classes. In order to create these
-wrappers, you need to explicitly tell SWIG to instantiate
-them. This is done via the
-<a href="SWIGPlus.html#SWIGPlus_nn30"><tt>%template</tt></a>
-directive.
-</p>
-
-<H4><a name="Allegrocl_nn27">20.3.7.2 Implicit Template instantiation</a></H4>
-
-
-<p>
-While no wrapper code is generated for accessing member
-variables, or calling member functions, type code is generated
-to include these templated classes in the foreign-type and CLOS
-class schema.
-</p>
-
-<H3><a name="Allegrocl_nn28">20.3.8 Typedef, Templates, and Synonym Types</a></H3>
-
-
-    <p>
-      In C/C++ it is possible, via typedef, to have many names refer to
-      the same <tt>type</tt>. In general, this is not a problem, though
-      it can lead to confusion.  Assume the below C++ header file:
-    </p>
-
-    <div class="code">synonyms.h
-    <pre>
-class A { 
-  int x;
-  int y;
-};
-
-typedef A Foo;
-
-A *xxx(int i);         /* sets A-&gt;x = A-&gt;y = i */
-Foo *yyy(int i);       /* sets Foo-&gt;x = Foo-&gt;y = i */
-
-int zzz(A *inst = 0);  /* return inst-&gt;x + inst-&gt;y */
-    </pre>
-    </div>
-
-    <p>
-      The function <tt>zzz</tt> is an overloaded functions; the
-      foreign function call to it will be wrapped in a
-      generic-function whose argument will be checked against a type
-      of <tt>A</tt>. Assuming a simple implementation, a call
-      to <tt>xxx(1)</tt> will return a pointer to an A object, which
-      will be wrapped in a CLOS instance of class <tt>A</tt>, and a
-      call to <tt>yyy(1)</tt> will result in a CLOS instance of
-      type <tt>Foo</tt> being returned.  Without establishing a clear
-      type relationship between <tt>Foo</tt> and <tt>A</tt>, an
-      attempt to call <tt>zzz(yyy(1))</tt> will result in an error.
-    </p>
-
-    <p>
-      We resolve this issue, by noting synonym relationships between
-      types while generating the interface. A Primary type is selected
-      (more on this below) from the candidate list of synonyms. For
-      all other synonyms, instead of generating a distinct CLOS class
-      definition, we generate a form that expands to:
-    </p>
-      <div class="targetlang">
-        <tt>(setf (find-class &lt;synonym&gt;) &lt;primary&gt;)</tt>
-      </div>
-    <p>
-      The result is that all references to synonym types in foreign
-      code, are wrapped in the same CLOS wrapper, and, in particular,
-      method specialization in wrapping generic functions works as 
-      expected.
-    </p>
-
-    <p>
-      Given the above header file, synonym.h, a Lisp session would
-      appear as follows:
-    </p>
-    <div class="targetlang">
-    <pre>
-CL-USER&gt; (load "synonym.dll")
-; Foreign loading synonym.dll.
-t
-CL-USER&gt; (load "synonym.cl")
-; Loading c:\mikel\src\swig\test\synonym.cl
-t
-CL-USER&gt; 
-synonym&gt; (setf a (xxx 3))
-#&lt;A nil #x3261a0 @ #x207299da&gt;
-synonym&gt; (setf foo (yyy 10))
-#&lt;A nil #x3291d0 @ #x2072e982&gt;
-synonym&gt; (zzz a)
-6
-synonym&gt; (zzz foo)
-20
-synonym&gt; 
-    </pre>
-    </div>
-
-<H4><a name="Allegrocl_nn29">20.3.8.1 Choosing a primary type</a></H4>
-
-
-    <p>
-      The choice of a primary type is selected by the following
-      criteria from a set of synonym types.
-    </p>
-      <ul>
-        <li>
-        If a synonym type has a class definition, it is the primary type.
-        </li>
-        <li>
-        If a synonym type is a class template and has been explicitly
-        instantiated via <tt>%template</tt>, it is the primary type.
-        </li>
-        <li>
-        For all other sets of synonymous types, the synonym which is
-        parsed first becomes the primary type.
-        </li>
-      </ul>
-
-<H3><a name="Allegrocl_nn30">20.3.9 Function overloading/Parameter defaulting</a></H3>
-
-
-    <p>
-      For each possible argument combination, a distinct wrapper
-      function is created in the .cxx file. On the Lisp side, a
-      generic functions is defined for each possible arity the
-      overloaded/defaulted call may have. Each distinct wrapper is
-      then called from within a defmethod on the appropriate generic
-      function. These are further wrapped inside a dispatch function
-      that checks the number of arguments it is called with and passes
-      them via apply to the appropriate generic-function. This allows
-      for a single entry point to overloaded functions on the lisp
-      side.
-    </p>
-
-    <p>Example:
-    </p>
-    <div class="code">overload.h:
-    <pre>
-
-class A {
- public:
-  int x;
-  int y;
-};
-
-float xxx(int i, int x = 0);   /* return i * x */
-float xxx(A *inst, int x);     /* return x + A-&gt;x + A-&gt;y */
-    </pre>
-    </div>
-
-    <p>Creates the following three wrappers, for each of the possible argument
-      combinations
-    </p>
-    <div class="code">overload_wrap.cxx
-    <pre>
-EXPORT void ACL___delete_A__SWIG_0 (A *larg1) {
-  A *arg1 = (A *) 0 ;
-
-  arg1 = larg1;
-  try {
-    delete arg1;
-
-  } catch (...) {
-
-  }
-}
-
-
-EXPORT float ACL___xxx__SWIG_0 (int larg1, int larg2) {
-  float lresult = (float)0 ;
-  int arg1 ;
-  int arg2 ;
-  float result;
-
-  arg1 = larg1;
-  arg2 = larg2;
-  try {
-    result = (float)xxx(arg1, arg2);
-
-    lresult = result;
-    return lresult;
-  } catch (...) {
-    return (float)0;
-  }
-}
-
-
-EXPORT float ACL___xxx__SWIG_1 (int larg1) {
-  float lresult = (float)0 ;
-  int arg1 ;
-  float result;
-
-  arg1 = larg1;
-  try {
-    result = (float)xxx(arg1);
-
-    lresult = result;
-    return lresult;
-  } catch (...) {
-    return (float)0;
-  }
-}
-
-
-EXPORT float ACL___xxx__SWIG_2 (A *larg1, int larg2) {
-  float lresult = (float)0 ;
-  A *arg1 = (A *) 0 ;
-  int arg2 ;
-  float result;
-
-  arg1 = larg1;
-  arg2 = larg2;
-  try {
-    result = (float)xxx(arg1, arg2);
-
-    lresult = result;
-    return lresult;
-  } catch (...) {
-    return (float)0;
-  }
-}
-    </pre>
-    </div>
-
-    <p>
-      And the following foreign-function-call and method definitions on the
-      lisp side:
-    </p>
-    <div class="targetlang">overload.cl
-    <pre>
-(swig-defmethod ("xxx" "ACL___xxx__SWIG_0" :type :function :arity 2)
-  ((PARM0_i cl:integer :int )
-   (PARM1_x cl:integer :int ))
-  (:returning (:float )
-   :strings-convert t)
-  (let ((SWIG_arg0 PARM0_i))
-  (let ((SWIG_arg1 PARM1_x))
-  (swig-ff-call SWIG_arg0 SWIG_arg1))))
-
-(swig-defmethod ("xxx" "ACL___xxx__SWIG_1" :type :function :arity 1)
-  ((PARM0_i cl:integer :int ))
-  (:returning (:float )
-   :strings-convert t)
-  (let ((SWIG_arg0 PARM0_i))
-  (swig-ff-call SWIG_arg0)))
-
-(swig-defmethod ("xxx" "ACL___xxx__SWIG_2" :type :function :arity 2)
-  ((PARM0_inst #.(swig-insert-id "A" () :type :class) (* #.(swig-insert-id "A" ())) )
-   (PARM1_x cl:integer :int ))
-  (:returning (:float )
-   :strings-convert t)
-  (let ((SWIG_arg0 PARM0_inst))
-  (let ((SWIG_arg1 PARM1_x))
-  (swig-ff-call SWIG_arg0 SWIG_arg1))))
-
-(swig-dispatcher ("xxx" :type :function :arities (1 2)))
-    </pre>
-    </div>
-
-    <p>And their usage in a sample lisp session:
-    </p>
-    <div class="targetlang">
-    <pre>
-overload&gt; (setf a (new_A))
-#&lt;A nil #x329268 @ #x206cf612&gt;
-overload&gt; (setf (A_x a) 10)
-10
-overload&gt; (setf (A_y a) 20)
-20
-overload&gt; (xxx 1)
-0.0
-overload&gt; (xxx 3 10)
-30.0
-overload&gt; (xxx a 1)
-31.0
-overload&gt; (xxx a 2)
-32.0
-overload&gt; 
-    </pre>
-    </div>
-
-<H3><a name="Allegrocl_nn31">20.3.10 Operator wrapping and Operator overloading</a></H3>
-
-
-    <p>
-      Wrappers to defined C++ Operators are automatically renamed, using
-      <tt>%rename</tt>, to the following defaults:
-    </p>
-    <div class="code">
-    <pre>
-/* name conversion for overloaded operators. */
-#ifdef __cplusplus
-%rename(__add__)             *::operator+;
-%rename(__pos__)             *::operator+();
-%rename(__pos__)             *::operator+() const;
-
-%rename(__sub__)             *::operator-;
-%rename(__neg__)             *::operator-() const;
-%rename(__neg__)             *::operator-();
-
-%rename(__mul__)             *::operator*;
-%rename(__deref__)           *::operator*();
-%rename(__deref__)           *::operator*() const;
-
-%rename(__div__)             *::operator/;
-%rename(__mod__)             *::operator%;
-%rename(__logxor__)          *::operator^;
-%rename(__logand__)          *::operator&amp;;
-%rename(__logior__)          *::operator|;
-%rename(__lognot__)          *::operator~();
-%rename(__lognot__)          *::operator~() const;
-
-%rename(__not__)             *::operator!();
-%rename(__not__)             *::operator!() const;
-
-%rename(__assign__)          *::operator=;
-
-%rename(__add_assign__)      *::operator+=;
-%rename(__sub_assign__)      *::operator-=;
-%rename(__mul_assign__)      *::operator*=;
-%rename(__div_assign__)      *::operator/=;
-%rename(__mod_assign__)      *::operator%=;
-%rename(__logxor_assign__)   *::operator^=;
-%rename(__logand_assign__)   *::operator&amp;=;
-%rename(__logior_assign__)   *::operator|=;
-
-%rename(__lshift__)          *::operator&lt;&lt;;
-%rename(__lshift_assign__)   *::operator&lt;&lt;=;
-%rename(__rshift__)          *::operator&gt;&gt;;
-%rename(__rshift_assign__)   *::operator&gt;&gt;=;
-
-%rename(__eq__)              *::operator==;
-%rename(__ne__)              *::operator!=;
-%rename(__lt__)              *::operator&lt;;
-%rename(__gt__)              *::operator&gt;;
-%rename(__lte__)             *::operator&lt;=;
-%rename(__gte__)             *::operator&gt;=;
-
-%rename(__and__)             *::operator&amp;&amp;;
-%rename(__or__)              *::operator||;
-
-%rename(__preincr__)         *::operator++();
-%rename(__postincr__)        *::operator++(int);
-%rename(__predecr__)         *::operator--();
-%rename(__postdecr__)        *::operator--(int);
-
-%rename(__comma__)           *::operator,();
-%rename(__comma__)           *::operator,() const;
-
-%rename(__member_ref__)      *::operator-&gt;;
-%rename(__member_func_ref__) *::operator-&gt;*;
-
-%rename(__funcall__)         *::operator();
-%rename(__aref__)            *::operator[];
-    </pre>
-    </div>
-
-    <p>
-      Name mangling occurs on all such renamed identifiers, so that wrapper name
-      generated by <tt>B::operator=</tt> will be <tt>B___eq__</tt>, i.e.
-      <tt>&lt;class-or-namespace&gt;_</tt> has been added. Users may modify
-      these default names by adding <tt>%rename</tt> directives in their own .i files.
-    </p>
-
-    <p>
-      Operator overloading can be achieved by adding functions based
-      on the mangled names of the function. In the following example,
-      a class B is defined with a Operator== method defined. The
-      swig <tt>%extend</tt> directive is used to add an overload method
-      on Operator==.
-    </p>
-
-    <div class="code">opoverload.h
-    <pre>
-class B {
- public:
-  int x;
-  int y;
-  bool operator==(B const&amp; other) const;
-};
-    </pre>
-    </div>
-
-    <p>
-    and
-    </p>
-    <div class="code">opoverload.i
-    <pre>
-%module opoverload
-
-%{
-#include &lt;fstream&gt;
-#include "opoverload.h"
-%}
-
-%{
-bool B___eq__(B const *inst, int const x)
-{
-  // insert the function definition into the wrapper code before
-  // the wrapper for it.
-  // ... do stuff ...
-}
-%}
-
-%include "opoverload.h"
-
-%extend B {
- public:
-  bool __eq__(int const x) const;
-};
-    </pre>
-    </div>
-
-    <p>
-      Either operator can be called via a single call
-      to the dispatch function:
-    </p>
-    <div class="targetlang">
-    <pre>
-opoverload&gt; (B___eq__ x1 x2)
-nil
-opoverload&gt; (B___eq__ x1 3)
-nil
-opoverload&gt; 
-    </pre>
-    </div>
-
-<H3><a name="Allegrocl_nn32">20.3.11 Varargs</a></H3>
-
-
-    <p>
-      Variable length argument lists are not supported, by default. If
-      such a function is encountered, a warning will generated to
-      stderr. Varargs are supported via the SWIG <tt>%varargs</tt>
-      directive. This directive allows you to specify a (finite)
-      argument list which will be inserted into the wrapper in place
-      of the variable length argument indicator.  As an example,
-      consider the function <tt>printf()</tt>. Its declaration would
-      appear as follows:
-    </p>
-
-    <p>
-      See the following section
-      on <a href="Varargs.html#Varargs">Variable Length arguments</a>
-      provides examples on how <tt>%varargs</tt> can be used, along
-      with other ways such functions can be wrapped.
-    </p>
-
-<H3><a name="Allegrocl_nn33">20.3.12 C++ Exceptions</a></H3>
-
-
-    <p>
-      Each C++ wrapper includes a handler to catch any exceptions that may
-      be thrown while in foreign code. This helps prevent simple C++ errors
-      from killing the entire lisp process. There is currently no mechanism
-      to have these exceptions forwarded to the lisp condition system, nor
-      has any explicit support of the exception related SWIG typemaps been
-      implemented.
-    </p>
-
-<H3><a name="Allegrocl_nn34">20.3.13 Pass by value, pass by reference</a></H3>
-
-
-    <p>
-      Allegro CL does not support the passing of non-primitive foreign
-      structures by value. As a result, SWIG must automatically detect
-      and convert function parameters and return values to pointers
-      whenever necessary. This is done via the use of <tt>typemaps</tt>,
-      and should not require any fine tuning by the user, even for
-      newly defined types.
-    </p>
-
-<H2><a name="Allegrocl_nn35">20.4 Typemaps</a></H2>
-
-
-<p>
-  SWIG Typemaps provide a powerful tool for automatically generating
-  code to handle various menial tasks required of writing an interface
-  to foreign code. The purpose of this section is to describe each of
-  the typemaps used by the Allegro CL module. Please read the chapter
-  on <a href="Typemaps.html#Typemaps">Typemaps</a> for more information.
-</p>
-
-<H3><a name="Allegrocl_nn36">20.4.1 Code Generation in the C++ Wrapper</a></H3>
-
-
-    
-    <p>
-      Every C++ wrapper generated by SWIG takes the following form:
-    </p>
-
-    <div class="diagram">
-    <pre>
-return-val wrapper-name(parm0, parm1, ..., parmN)
-{
-  return-val lresult;   /* return value from wrapper */
-  &lt;local-declaration&gt;
-  ... results;          /* return value from function call */
-
-  &lt;binding locals to parameters&gt;
-
-  try {
-    result = function-name(local0, local1, ..., localN);
-
-    &lt;convert and bind result to lresult&gt;
-
-    return lresult;
-  catch (...) {
-    return (int)0;
-  }
-    </pre>
-    </div>
-
-<H4><a name="Allegrocl_nn37">20.4.1.1 IN Typemap</a></H4>
-
-
-    <p>
-      the <tt>in</tt> typemap is used to generate code to convert parameters
-      passed to C++ wrapper functions into the arguments desired for the
-      call being wrapped. That is, it fills in the code for the 
-      <tt>&lt;binding locals to parameters&gt;</tt> section above. We
-      use this map to automatically convert parameters passed by
-      reference to the wrapper function into by-value arguments for
-      the wrapped call, and also to convert boolean values, which are
-      passed as integers from lisp (by default), into the appropriate
-      type for the language of code being wrapped.
-    </p>
-
-    <p>These are the default specifications for the IN typemap. Here,
-      <tt>$input</tt> refers to the parameter code is being generated
-      for, and <tt>$1</tt> is the local variable to which it is
-      being assigned. The default settings of this typemap are as follows:
-    </p>
-      
-    <div class="code">
-    <pre>
-%typemap(in) bool                          "$1 = (bool)$input;";
-%typemap(in) char, unsigned char, signed char,
-             short, signed short, unsigned short,
-             int, signed int, unsigned int,
-             long, signed long, unsigned long,
-             float, double, long double, char *, void *, void,
-             enum SWIGTYPE, SWIGTYPE *,
-             SWIGTYPE[ANY], SWIGTYPE &amp;     "$1 = $input;";
-%typemap(in) SWIGTYPE                      "$1 = *$input;";
-    </pre>
-    </div>
-
-<H4><a name="Allegrocl_nn38">20.4.1.2 OUT Typemap</a></H4>
-
-
-    <p>
-      The <tt>out</tt> typemap is used to generate code to form the
-      return value of the wrapper from the return value of the wrapped
-      function. This code is placed in the &lt;convert and bind result to lresult&gt;
-      section of the above code diagram. Its default mapping is as follows:
-    </p>
-
-    <div class="code">
-    <pre>
-%typemap(out) bool                          "$result = (int)$1;";
-%typemap(out) char, unsigned char, signed char,
-              short, signed short, unsigned short,
-              int, signed int, unsigned int,
-              long, signed long, unsigned long,
-              float, double, long double, char *, void *, void,
-              enum SWIGTYPE, SWIGTYPE *,
-              SWIGTYPE[ANY], SWIGTYPE &amp;    "$result = $1;";
-%typemap(out) SWIGTYPE                     "$result = new $1_type($1);";
-    </pre>
-    </div>
-
-<H4><a name="Allegrocl_nn39">20.4.1.3 CTYPE Typemap</a></H4>
-
-
-    <p>
-      This typemap is not used for code generation, but purely for the
-      transformation of types in the parameter list of the wrapper function.
-      Its primary use is to handle by-value to by-reference conversion in the
-      wrappers parameter list. Its default settings are:
-    </p>
-
-    <div class="code">
-    <pre>
-%typemap(ctype) bool                       "int";
-%typemap(ctype) char, unsigned char, signed char,
-                short, signed short, unsigned short,
-                int, signed int, unsigned int,
-                long, signed long, unsigned long,
-                float, double, long double, char *, void *, void,
-                enum SWIGTYPE, SWIGTYPE *,
-                SWIGTYPE[ANY], SWIGTYPE &amp;  "$1_ltype";
-%typemap(ctype) SWIGTYPE                   "$&amp;1_type";
-    </pre>
-    </div>
-
-    <p>
-      These three typemaps are specifically employed by the
-      Allegro CL interface generator. SWIG also implements a number of
-      other typemaps that can be used for generating code in the C/C++
-      wrappers. You can read about
-      these <a href="Typemaps.html#Typemaps_nn25">common typemaps</a> here.
-    </p>
-
-<H3><a name="Allegrocl_nn40">20.4.2 Code generation in Lisp wrappers</a></H3>
-
-
-    <p>
-      A number of custom typemaps have also been added to facilitate
-      the generation of code in the lisp side of the interface. These
-      are described below. The basic code generation structure is
-      applied as a series of nested expressions, one for each
-      parameter, then one for manipulating the return value, and last,
-      the foreign function call itself.
-    </p>
-
-    <p>
-      Note that the typemaps below use fully qualified symbols where
-      necessary. Users writing their own typemaps should do likewise. 
-      See the explanation in the last paragraph of 
-      <a href="#Allegrocl_nn15">16.3.1 Namespaces</a> for details.
-    </p>
-
-<H4><a name="Allegrocl_nn41">20.4.2.1 LIN Typemap</a></H4>
-
-
-    <p>
-      The LIN typemap allows for the manipulating the lisp objects
-      passed as arguments to the wrapping defun before passing them to
-      the foreign function call. For example, when passing lisp
-      strings to foreign code, it is often necessary to copy the
-      string into a foreign structure of type (:char *) of appropriate
-      size, and pass this copy to the foreign call. Using the LIN
-      typemap, one could arrange for the stack-allocation of a foreign
-      char array, copy your string into it, and not have to worry
-      about freeing the copy after the function returns. 
-    </p>
-
-    <p>The LIN typemap accepts the following <tt>$variable</tt> references.
-    </p>
-      <ul>
-        <li><tt>$in</tt> - expands to the name of the parameter being
-        applied to this typemap
-        </li>
-        <li><tt>$out</tt> - expands to the name of the local variable
-        assigned to this typemap
-        </li>
-        <li><tt>$in_fftype</tt> - the foreign function type of the C type.</li>
-        <li><tt>$*in_fftype</tt> - the foreign function type of the C type
-        with one pointer removed. If there is no pointer, then $*in_fftype
-        is the same as $in_fftype.
-        </li>
-        <li><tt>$body</tt> - very important. Instructs SWIG where
-        subsequent code generation steps should be inserted into the
-        current typemap.  Leaving out a <tt>$body</tt> reference
-        will result in lisp wrappers that do very little by way of
-        calling into foreign code. Not recommended.
-        </li>
-      </ul>
-      
-    <div class="code">
-    <pre>
-%typemap(lin) SWIGTYPE "(cl:let (($out $in))\n  $body)";
-    </pre>
-    </div>
-
-<H4><a name="Allegrocl_nn42">20.4.2.2 LOUT Typemap</a></H4>
-
-
-    <p>
-      The LOUT typemap is the means by which we effect the wrapping of
-      foreign pointers in CLOS instances. It is applied after all LIN
-      typemaps, and immediately before the actual foreign-call.
-    </p>
-
-    <p>The LOUT typemap uses the following $variable
-    </p>
-      <ul>
-        <li><tt>$lclass</tt> - Expands to the CLOS class that
-        represents foreign-objects of the return type matching this
-        typemap.
-        </li>
-        <li><tt>$body</tt> - Same as for the LIN map. Place this
-        variable where you want the foreign-function call to occur.
-        </li>
-        <li><tt>$ldestructor</tt> - Expands to the symbol naming the destructor for this
-        class ($lclass) of object. Allows you to insert finalization or automatic garbage
-        collection into the wrapper code (see default mappings below).
-        </li>
-      </ul>
-
-    <div class="code">
-    <pre>
-%typemap(lout) bool, char, unsigned char, signed char,
-               short, signed short, unsigned short,
-               int, signed int, unsigned int,
-               long, signed long, unsigned long,
-               float, double, long double, char *, void *, void,
-               enum SWIGTYPE    "$body";
-%typemap(lout) SWIGTYPE[ANY], SWIGTYPE *,
-               SWIGTYPE &amp;       "(cl:make-instance '$lclass :foreign-address $body)";
-%typemap(lout) SWIGTYPE    "(cl:let* ((address $body)\n
-                            (ACL_result (cl:make-instance '$lclass :foreign-address address)))\n
-                            (cl:unless (cl::zerop address)\n
-                            (excl:schedule-finalization ACL_result #'$ldestructor))\n
-                             ACL_result)";
-    </pre>
-    </div>
-
-<H4><a name="Allegrocl_nn43">20.4.2.3 FFITYPE Typemap</a></H4>
-
-
-    
-    <p>
-      The FFITYPE typemap works as a helper for a body of code that
-      converts C/C++ type specifications into Allegro CL foreign-type
-      specifications. These foreign-type specifications appear in
-      ff:def-foreing-type declarations, and in the argument list and
-      return values of ff:def-foreign-calls. You would modify this
-      typemap if you want to change how the FFI passes through
-      arguments of a given type. For example, if you know that a
-      particular compiler represents booleans as a single byte, you
-      might add an entry for:
-    </p>
-
-    <div class="code">
-    <pre>
-%typemap(ffitype) bool ":unsigned-char";
-    </pre>
-    </div>
-
-    <p>
-      Note that this typemap is pure type transformation, and is not
-      used in any code generations step the way the LIN and LOUT
-      typemaps are. The default mappings for this typemap are:
-    </p>
-
-    <div class="code">
-    <pre>
-%typemap(ffitype) bool ":int";
-%typemap(ffitype) char ":char";
-%typemap(ffitype) unsigned char ":unsigned-char";
-%typemap(ffitype) signed char ":char";
-%typemap(ffitype) short, signed short ":short";
-%typemap(ffitype) unsigned short ":unsigned-short";
-%typemap(ffitype) int, signed int ":int";
-%typemap(ffitype) unsigned int ":unsigned-int";
-%typemap(ffitype) long, signed long ":long";
-%typemap(ffitype) unsigned long ":unsigned-long";
-%typemap(ffitype) float ":float";
-%typemap(ffitype) double ":double";
-%typemap(ffitype) char * "(* :char)";
-%typemap(ffitype) void * "(* :void)";
-%typemap(ffitype) void ":void";
-%typemap(ffitype) enum SWIGTYPE ":int";
-%typemap(ffitype) SWIGTYPE &amp; "(* :void)";
-    </pre>
-    </div>
-
-<H4><a name="Allegrocl_nn44">20.4.2.4 LISPTYPE Typemap</a></H4>
-
-
-    <p>
-      This is another type only transformation map, and is used to
-      provide the lisp-type, which is the optional third argument in
-      argument specifier in a ff:def-foreign-call form. Specifying a
-      lisp-type allows the foreign call to perform type checking on
-      the arguments passed in. The default entries in this typemap are:
-    </p>
-
-    <div class="code">
-    <pre>
-%typemap(lisptype) bool "cl:boolean";
-%typemap(lisptype) char "cl:character";
-%typemap(lisptype) unsigned char "cl:integer";
-%typemap(lisptype) signed char "cl:integer";
-    </pre>
-    </div>
-
-<H4><a name="Allegrocl_nn45">20.4.2.5 LISPCLASS Typemap</a></H4>
-
-
-    <p>
-      The LISPCLASS typemap is used to generate the method signatures
-      for the generic-functions which wrap overloaded functions and
-      functions with defaulted arguments. The default entries are:
-    </p>
-
-    <div class="code">
-    <pre>
-%typemap(lispclass) bool "t";
-%typemap(lispclass) char "cl:character";
-%typemap(lispclass) unsigned char, signed char,
-                    short, signed short, unsigned short,
-                    int, signed int, unsigned int,
-                    long, signed long, unsigned long,
-                    enum SWIGTYPE       "cl:integer";
-%typemap(lispclass) float "cl:single-float";
-%typemap(lispclass) double "cl:double-float";
-%typemap(lispclass) char * "cl:string";
-    </pre>
-    </div>
-
-<H3><a name="Allegrocl_nn46">20.4.3 Modifying SWIG behavior using typemaps</a></H3>
-
-
-    <p>
-      The following example shows how we made use of the above
-      typemaps to add support for the wchar_t type. 
-    </p>
-
-    <div class="code">
-    <pre>
-%typecheck(SWIG_TYPECHECK_UNICHAR) wchar_t { $1 = 1; };
-
-%typemap(in)        wchar_t "$1 = $input;";
-%typemap(lin)       wchar_t "(cl:let (($out (cl:char-code $in)))\n  $body)";
-%typemap(lin)       wchar_t* "(excl:with-native-string
-                                         ($out $in
-                                          :external-format #+little-endian :fat-le 
-                                                           #-little-endian :fat)\n
-                                 $body)"
-
-%typemap(out)       wchar_t "$result = $1;";
-%typemap(lout)      wchar_t "(cl:code-char $body)";
-%typemap(lout)      wchar_t* "(excl:native-to-string $body
-                                          :external-format #+little-endian :fat-le
-                                                           #-little-endian :fat)";
-
-%typemap(ffitype)   wchar_t ":unsigned-short";
-%typemap(lisptype)  wchar_t "";
-%typemap(ctype)     wchar_t "wchar_t";
-%typemap(lispclass) wchar_t "cl:character";
-%typemap(lispclass) wchar_t* "cl:string";
-    </pre>
-    </div>
-
-<H2><a name="Allegrocl_nn47">20.5 Identifier Converter functions</a></H2>
-
-
-<H3><a name="Allegrocl_nn48">20.5.1 Creating symbols in the lisp environment</a></H3>
-
-
-<p>
-  Various symbols must be generated in the lisp environment to which
-  class definitions, functions, constants, variables, etc. must be
-  bound. Rather than force a particular convention for naming these
-  symbols, an identifier (to symbol) conversion function is used. A
-  user-defined identifier-converter can then implement any symbol
-  naming, case-modifying, scheme desired.
-</p>
-
-<p>
-  In generated SWIG code, whenever some interface object must be
-  referenced by its lisp symbol, a macro is inserted that calls the
-  identifier-converter function to generate the appropriate symbol
-  reference. It is therefore expected that the identifier-converter
-  function reliably return the same (eq) symbol given the same set
-  of arguments.
-</p>
-
-<H3><a name="Allegrocl_nn49">20.5.2 Existing identifier-converter functions</a></H3>
-
-
-  <p>Two basic identifier routines have been defined.
-<H4><a name="Allegrocl_nn50">20.5.2.1 identifier-convert-null</a></H4>
-
-
-    <p>
-      No modification of the identifier string is performed. Based on
-      other arguments, the identifier may be concatenated with other
-      strings, from which a symbol will be created.
-    </p>
-
-<H4><a name="Allegrocl_nn51">20.5.2.2 identifier-convert-lispify</a></H4>
-
-
-    <p>
-      All underscores in the identifier string are converted to
-      hyphens. Otherwise, identifier-convert-lispify performs the
-      same symbol transformations.
-    </p>
-
-<H4><a name="Allegrocl_nn52">20.5.2.3 Default identifier to symbol conversions</a></H4>
-
-
-    <p>
-      Check the definitions of the above two default
-      identifier-converters in <tt>Lib/allegrocl/allegrocl.swg</tt> for
-      default naming conventions.
-    </p>
-
-<H3><a name="Allegrocl_nn53">20.5.3 Defining your own identifier-converter</a></H3>
-
-
-<p>
-  A user-defined identifier-converter function should conform to the following
-  specification:
-</p>
-
-<div class="targetlang">
-<pre>
-(defun identifier-convert-fn (id &amp;key type class arity) ...body...)
-result ==&gt; symbol or (setf symbol)
-</pre>
-</div>
-
-<p>The <tt>ID</tt> argument is a string representing an identifier in the
-foreign environment.
-</p>
-
-<p>
-The :type keyword argument provides more information on the type of
-identifier. Its value is a symbol. This allows the
-identifier-converter to apply different heuristics when mapping
-different types of identifiers to symbols. SWIG will generate calls
-to your identifier-converter using the following types.
-</p>
-
-<ul>
-  <li>:class - names a CLOS class.</li>
-  <li>:constant - names a defconstant</li>
-  <li>:constructor - names a function for creating a foreign object</li>
-  <li>:destructor - names a function for freeing a foreign object</li>
-  <li>:function - names a CLOS wrapping defmethod or defun.</li>
-  <li>:ff-operator - names a foreign call defined via ff:def-foreign-call</li>
-  <li>:getter - getter function</li>
-  <li>:namespace - names a C++ namespace</li>
-  <li>:setter - names a setter function. May return a (setf symbol) reference</li>
-  <li>:operator - names a C++ operator, such as Operator=, Operator*.</li>
-  <li>:slot - names a slot in a struct/class/union declaration.</li>
-  <li>:type - names a foreign-type defined via ff:def-foreign-type.</li>
-  <li>:variable - names a variable defined via ff:def-foreign-variable.</li>
-</ul>
-
-<p>
-The :class keyword argument is a string naming a foreign
-class. When non-nil, it indicates that the current identifier has
-scope in the specified class.
-</p>
-
-<p>
-The :arity keyword argument only appears in swig:swig-defmethod forms
-generated for overloaded functions. Its value is an integer
-indicating the number of arguments passed to the routine indicated by
-this identifier.
-</p>
-
-<H3><a name="Allegrocl_nn54">20.5.4 Instructing SWIG to use a particular identifier-converter</a></H3>
-
-
-<p>
-  By default, SWIG will use identifier-converter-null. To specify
-  another convert function, use the <tt>-identifier-converter</tt>
-  command-line argument. The value should be a string naming the
-  function you wish the interface to use instead, when generating
-  symbols. ex:
-</p>
-
-<div class="code">
-<pre>
-% swig -allegrocl -c++ -module mymodule -identifier-converter my-identifier-converter
-</pre>
-</div>
-
-
-</body>
-</html>
diff --git a/Doc/Manual/Android.html b/Doc/Manual/Android.html
index 944a88d..da475e9 100644
--- a/Doc/Manual/Android.html
+++ b/Doc/Manual/Android.html
@@ -6,7 +6,7 @@
 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 </head>
 <body bgcolor="#FFFFFF">
-<H1><a name="Android">21 SWIG and Android</a></H1>
+<H1><a name="Android">22 SWIG and Android</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -31,7 +31,7 @@
 
 
 
-<H2><a name="Android_overview">21.1 Overview</a></H2>
+<H2><a name="Android_overview">22.1 Overview</a></H2>
 
 
 <p>
@@ -41,10 +41,10 @@
 This chapter contains a few Android specific notes and examples.
 </p>
 
-<H2><a name="Android_examples">21.2 Android examples</a></H2>
+<H2><a name="Android_examples">22.2 Android examples</a></H2>
 
 
-<H3><a name="Android_examples_intro">21.2.1 Examples introduction</a></H3>
+<H3><a name="Android_examples_intro">22.2.1 Examples introduction</a></H3>
 
 
 <p>
@@ -77,7 +77,7 @@
 The following examples are shipped with SWIG under the Examples/android directory and include a Makefile to build and install each example.
 </p>
 
-<H3><a name="Android_example_simple">21.2.2 Simple C example</a></H3>
+<H3><a name="Android_example_simple">22.2.2 Simple C example</a></H3>
 
 
 <p>
@@ -399,7 +399,7 @@
 <center><img src="android-simple.png" alt="Android screenshot of SwigSimple example"></center>
 
 
-<H3><a name="Android_example_class">21.2.3 C++ class example</a></H3>
+<H3><a name="Android_example_class">22.2.3 C++ class example</a></H3>
 
 
 <p>
@@ -747,7 +747,7 @@
 
 <center><img src="android-class.png" alt="Android screenshot of SwigClass example"></center>
 
-<H3><a name="Android_examples_other">21.2.4 Other examples</a></H3>
+<H3><a name="Android_examples_other">22.2.4 Other examples</a></H3>
 
 
 <p>
@@ -759,7 +759,7 @@
 Normally C++ exception handling and the STL is not available by default in the version of g++ shipped with Android, but this example turns these features on as described in the next section.
 </p>
 
-<H2><a name="Android_stl">21.3 C++ STL</a></H2>
+<H2><a name="Android_stl">22.3 C++ STL</a></H2>
 
 
 <p>
diff --git a/Doc/Manual/Arguments.html b/Doc/Manual/Arguments.html
index 2828bf4..e1644f8 100644
--- a/Doc/Manual/Arguments.html
+++ b/Doc/Manual/Arguments.html
@@ -7,7 +7,7 @@
 </head>
 
 <body bgcolor="#ffffff">
-<H1><a name="Arguments">12 Argument Handling</a></H1>
+<H1><a name="Arguments">13 Argument Handling</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -43,7 +43,7 @@
 describes some of the techniques for doing this.
 </p>
 
-<H2><a name="Arguments_nn2">12.1 The typemaps.i library</a></H2>
+<H2><a name="Arguments_nn2">13.1 The typemaps.i library</a></H2>
 
 
 <p>
@@ -51,7 +51,7 @@
 change certain properties of argument conversion.
 </p>
 
-<H3><a name="Arguments_nn3">12.1.1 Introduction</a></H3>
+<H3><a name="Arguments_nn3">13.1.1 Introduction</a></H3>
 
 
 <p>
@@ -195,7 +195,7 @@
 </pre>
 </div>
 
-<H3><a name="Arguments_nn4">12.1.2 Input parameters</a></H3>
+<H3><a name="Arguments_nn4">13.1.2 Input parameters</a></H3>
 
 
 <p>
@@ -248,7 +248,7 @@
 result = add(3, 4)
 </pre></div>
 
-<H3><a name="Arguments_nn5">12.1.3 Output parameters</a></H3>
+<H3><a name="Arguments_nn5">13.1.3 Output parameters</a></H3>
 
 
 <p>
@@ -315,7 +315,7 @@
 </pre>
 </div>
 
-<H3><a name="Arguments_nn6">12.1.4 Input/Output parameters</a></H3>
+<H3><a name="Arguments_nn6">13.1.4 Input/Output parameters</a></H3>
 
 
 <p>
@@ -375,12 +375,7 @@
 rather than directly overwriting the value of the original input object.
 </p>
 
-<p>
-<b>Compatibility note :</b> The <tt>INOUT</tt> rule used to be known as <tt>BOTH</tt> in earlier versions of
-SWIG.  Backwards compatibility is preserved, but deprecated.
-</p>
-
-<H3><a name="Arguments_nn7">12.1.5 Using different names</a></H3>
+<H3><a name="Arguments_nn7">13.1.5 Using different names</a></H3>
 
 
 <p>
@@ -414,7 +409,7 @@
 file or a matching <tt>%clear</tt> declaration.
 </p>
 
-<H2><a name="Arguments_nn8">12.2 Applying constraints to input values</a></H2>
+<H2><a name="Arguments_nn8">13.2 Applying constraints to input values</a></H2>
 
 
 <p>
@@ -424,7 +419,7 @@
 can be accomplished including the <tt>constraints.i</tt> library file.
 </p>
 
-<H3><a name="Arguments_nn9">12.2.1 Simple constraint example</a></H3>
+<H3><a name="Arguments_nn9">13.2.1 Simple constraint example</a></H3>
 
 
 <p>
@@ -440,7 +435,7 @@
 double log(double POSITIVE);         // Allow only positive values
 double sqrt(double NONNEGATIVE);     // Non-negative values only
 double inv(double NONZERO);          // Non-zero values
-void   free(void *NONNULL);          // Non-NULL pointers only
+int    fclose(FILE *NONNULL);        // Non-NULL pointers only
 
 </pre></div>
 
@@ -450,7 +445,7 @@
 exception will be raised. As a result, it is possible to catch bad
 values, prevent mysterious program crashes and so on.</p>
 
-<H3><a name="Arguments_nn10">12.2.2 Constraint methods</a></H3>
+<H3><a name="Arguments_nn10">13.2.2 Constraint methods</a></H3>
 
 
 <p>
@@ -466,7 +461,7 @@
 
 </pre></div>
 
-<H3><a name="Arguments_nn11">12.2.3 Applying constraints to new datatypes</a></H3>
+<H3><a name="Arguments_nn11">13.2.3 Applying constraints to new datatypes</a></H3>
 
 
 <p>
diff --git a/Doc/Manual/CCache.html b/Doc/Manual/CCache.html
index edd435f..e6935b8 100644
--- a/Doc/Manual/CCache.html
+++ b/Doc/Manual/CCache.html
@@ -7,7 +7,7 @@
 </head>
 
 <body bgcolor="#ffffff">
-<H1><a name="CCache">20 Using SWIG with ccache - ccache-swig(1) manpage</a></H1>
+<H1><a name="CCache">21 Using SWIG with ccache - ccache-swig(1) manpage</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -35,7 +35,7 @@
 
 
 <p>
-<H2><a name="CCache_nn2">20.1 NAME</a></H2>
+<H2><a name="CCache_nn2">21.1 NAME</a></H2>
 
 
 <p>
@@ -43,7 +43,7 @@
 ccache-swig - a fast compiler cache
 
 <p>
-<H2><a name="CCache_nn3">20.2 SYNOPSIS</a></H2>
+<H2><a name="CCache_nn3">21.2 SYNOPSIS</a></H2>
 
 
 <p>
@@ -53,7 +53,7 @@
 <p>
 &lt;compiler&gt; [COMPILER OPTIONS]
 <p>
-<H2><a name="CCache_nn4">20.3 DESCRIPTION</a></H2>
+<H2><a name="CCache_nn4">21.3 DESCRIPTION</a></H2>
 
 
 <p>
@@ -62,7 +62,7 @@
 being done again. ccache-swig is ccache plus support for SWIG. ccache
 and ccache-swig are used interchangeably in this document.
 <p>
-<H2><a name="CCache_nn5">20.4 OPTIONS SUMMARY</a></H2>
+<H2><a name="CCache_nn5">21.4 OPTIONS SUMMARY</a></H2>
 
 
 <p>
@@ -82,7 +82,7 @@
 </pre>
 
 <p>
-<H2><a name="CCache_nn6">20.5 OPTIONS</a></H2>
+<H2><a name="CCache_nn6">21.5 OPTIONS</a></H2>
 
 
 <p>
@@ -124,7 +124,7 @@
 <p>
 </dl>
 <p>
-<H2><a name="CCache_nn7">20.6 INSTALLATION</a></H2>
+<H2><a name="CCache_nn7">21.6 INSTALLATION</a></H2>
 
 
 <p>
@@ -156,7 +156,7 @@
 Note! Do not use a hard link, use a symbolic link. A hardlink will
 cause "interesting" problems.
 <p>
-<H2><a name="CCache_nn8">20.7 EXTRA OPTIONS</a></H2>
+<H2><a name="CCache_nn8">21.7 EXTRA OPTIONS</a></H2>
 
 
 <p>
@@ -176,7 +176,7 @@
 treated as an input file name and instead be passed along to the
 compiler as a command line option.
 <p>
-<H2><a name="CCache_nn9">20.8 ENVIRONMENT VARIABLES</a></H2>
+<H2><a name="CCache_nn9">21.8 ENVIRONMENT VARIABLES</a></H2>
 
 
 <p>
@@ -315,7 +315,7 @@
 <p>
 </dl>
 <p>
-<H2><a name="CCache_nn10">20.9 CACHE SIZE MANAGEMENT</a></H2>
+<H2><a name="CCache_nn10">21.9 CACHE SIZE MANAGEMENT</a></H2>
 
 
 <p>
@@ -328,7 +328,7 @@
 below the numbers you specified in order to avoid doing the cache
 clean operation too often.
 <p>
-<H2><a name="CCache_nn11">20.10 CACHE COMPRESSION</a></H2>
+<H2><a name="CCache_nn11">21.10 CACHE COMPRESSION</a></H2>
 
 
 <p>
@@ -339,7 +339,7 @@
 that fit in the cache. You can turn off compression setting the
 CCACHE_NOCOMPRESS environment variable.
 <p>
-<H2><a name="CCache_nn12">20.11 HOW IT WORKS</a></H2>
+<H2><a name="CCache_nn12">21.11 HOW IT WORKS</a></H2>
 
 
 <p>
@@ -364,7 +364,7 @@
 discover a case where ccache changes the output of your compiler then
 please let me know.
 <p>
-<H2><a name="CCache_nn13">20.12 USING CCACHE WITH DISTCC</a></H2>
+<H2><a name="CCache_nn13">21.12 USING CCACHE WITH DISTCC</a></H2>
 
 
 <p>
@@ -378,7 +378,7 @@
 'distcc' and ccache will prefix the command line used with the
 compiler with the command 'distcc'.
 <p>
-<H2><a name="CCache_nn14">20.13 SHARING A CACHE</a></H2>
+<H2><a name="CCache_nn14">21.13 SHARING A CACHE</a></H2>
 
 
 <p>
@@ -407,7 +407,7 @@
   versions of ccache that do not support compression.
 </ul>
 <p>
-<H2><a name="CCache_nn15">20.14 HISTORY</a></H2>
+<H2><a name="CCache_nn15">21.14 HISTORY</a></H2>
 
 
 <p>
@@ -423,7 +423,7 @@
 compiler cache and I wanted to remove some of the limitations of the
 shell-script version.
 <p>
-<H2><a name="CCache_nn16">20.15 DIFFERENCES FROM COMPILERCACHE</a></H2>
+<H2><a name="CCache_nn16">21.15 DIFFERENCES FROM COMPILERCACHE</a></H2>
 
 
 <p>
@@ -441,7 +441,7 @@
 <li> ccache avoids a double call to cpp on a cache miss
 </ul>
 <p>
-<H2><a name="CCache_nn17">20.16 CREDITS</a></H2>
+<H2><a name="CCache_nn17">21.16 CREDITS</a></H2>
 
 
 <p>
@@ -453,7 +453,7 @@
  <li> Paul Russell for many suggestions and the debian packaging
 </ul>
 <p>
-<H2><a name="CCache_nn18">20.17 AUTHOR</a></H2>
+<H2><a name="CCache_nn18">21.17 AUTHOR</a></H2>
 
 
 <p>
@@ -463,7 +463,7 @@
 <p>
 If you wish to report a problem or make a suggestion then please email
 the SWIG developers on the swig-devel mailing list, see
-<a href="http://www.swig.org/mail.html">http://www.swig.org/mail.html</a>
+<a href="https://www.swig.org/mail.html">https://www.swig.org/mail.html</a>
 <p>
 ccache is released under the GNU General Public License version 2 or
 later. Please see the file COPYING for license details.
diff --git a/Doc/Manual/CPlusPlus11.html b/Doc/Manual/CPlusPlus11.html
index 11335a2..fe0ae7c 100644
--- a/Doc/Manual/CPlusPlus11.html
+++ b/Doc/Manual/CPlusPlus11.html
@@ -15,6 +15,11 @@
 <li><a href="#CPlusPlus11_core_language_changes">Core language changes</a>
 <ul>
 <li><a href="#CPlusPlus11_rvalue_reference_and_move_semantics">Rvalue reference and move semantics</a>
+<ul>
+<li><a href="#CPlusPlus11_rvalue_reference_inputs">Rvalue reference inputs</a>
+<li><a href="#CPlusPlus11_rvalue_reference_outputs">Rvalue reference outputs</a>
+<li><a href="#CPlusPlus11_move_only">Movable and move-only types by value</a>
+</ul>
 <li><a href="#CPlusPlus11_generalized_constant_expressions">Generalized constant expressions</a>
 <li><a href="#CPlusPlus11_extern_template">Extern template</a>
 <li><a href="#CPlusPlus11_initializer_lists">Initializer lists</a>
@@ -68,8 +73,7 @@
 
 
 <p>This chapter gives you a brief overview about the SWIG
-implementation of the C++11 standard. This part of SWIG is still a work in
-progress. 
+implementation of the C++11 standard.
 </p>
 <p>SWIG supports the new C++ syntax changes with some minor limitations
 in some areas such as decltype expressions and variadic templates. Wrappers for the
@@ -95,6 +99,7 @@
 ...
   std::vector&lt;int&gt; numbers;
 public:
+  MyClass() : numbers() {}
   MyClass(MyClass &amp;&amp;other) : numbers(std::move(other.numbers)) {}
   MyClass &amp; operator=(MyClass &amp;&amp;other) {
     numbers = std::move(other.numbers);
@@ -104,8 +109,8 @@
 </pre></div>
 
 <p>
-Rvalue references are designed for C++ temporaries and so are not very useful when used from non-C++ target languages.
-Generally you would just ignore them via <tt>%ignore</tt> before parsing the class.
+Rvalue references are designed for C++ temporaries and are not particularly useful when used from non-C++ target languages.
+One option is to just ignore them via <tt>%ignore</tt>.
 For example, ignore the move constructor:
 </p>
 
@@ -113,8 +118,49 @@
 %ignore MyClass::MyClass(MyClass &amp;&amp;);
 </pre></div>
 
+<H4><a name="CPlusPlus11_rvalue_reference_inputs">7.2.1.1 Rvalue reference inputs</a></H4>
+
+
 <p>
-The plan is to ignore move constructors by default in a future version of SWIG. Note that both normal assignment operators as well as move assignment operators are ignored by default in most target languages with the following warning:
+Rvalue reference parameters are useful as input parameters in C++ for implementing move semantics, such as,
+in the move constructor and move assignment operator.
+This type of usage can be useful from target languages too to avoid copying large objects.
+</p>
+
+<p>
+If you do wrap a function/contructor with an rvalue reference parameter and pass a proxy class to it, SWIG will assume that after the call, the rvalue reference parameter object will have been 'moved'.
+The proxy class passed as the rvalue reference, will own the underlying C++ object up until it is used as an rvalue reference parameter.
+Afterwards, the proxy class will have the underlying C++ pointer set to the nullptr so that the proxy class instance cannot be used again and the underlying (moved from) C++ object will be deleted after the function/constructor call has returned.
+</p>
+
+<p>
+In this way, the SWIG proxy class works much like an exclusively owned smart pointer (think of <tt>std::unique_ptr</tt>), passing ownership to the called C++ function/constructor.
+Let's consider an example in Java using the wrapped proxy class from above:
+</p>
+
+<div class="targetlang"><pre>
+MyClass mc = new MyClass();
+MyClass mc1 = new MyClass(mc); // move constructor
+MyClass mc2 = new MyClass(mc); // move constructor fails
+</pre></div>
+
+<p>
+The second call to the move constructor will fail as the <tt>mc</tt> proxy instance has been moved.
+Each target language handles the moved proxy class slightly differently when attempting to move it again, but typically you'll get an exception such as in Java:
+</p>
+
+<div class="shell">
+<pre>
+Exception in thread "main" java.lang.RuntimeException: Cannot release ownership as memory is not owned
+        at MyClass.swigRelease(MyClass.java:27)
+        at MyClass.&lt;init&gt;(MyClass.java:55)
+        at runme.main(runme.java:18)
+</pre>
+</div>
+
+
+<p>
+Note that both normal copy assignment operators as well as move assignment operators are ignored by default in the target languages with the following warning:
 </p>
 
 <div class="shell">
@@ -123,6 +169,332 @@
 </pre>
 </div>
 
+<p>
+Using a <tt>%rename</tt> will remove the warning and also makes the move assignment operator available from the target language:
+</p>
+<div class="code"><pre>
+%rename(MoveAssign) MyClass::operator=(MyClass &amp;&amp;);
+</pre></div>
+
+<p>
+You can then use it, but like the move constructor example above, you cannot use
+a proxy class once it has already been moved:
+</p>
+
+<div class="targetlang"><pre>
+MyClass mc = new MyClass();
+MyClass mc2 = mc.MoveAssign(mc);
+MyClass mc3 = mc.MoveAssign(mc); // Use of mc again will fail
+</pre></div>
+
+<p>
+It is of course perfectly possible in C++ for a function/constructor to not move an object passed to it in an rvalue reference parameter. The assumption that SWIG makes would then not hold and customisation of the appropriate input typemaps would be required.
+For scripting languages, this would be for the 'in' typemap and for the non-scripting languages additional typemaps such as the 'javain' typemap, which is used to set the memory ownership of the underlying C++ object for Java, would also need copying and modifying appropriately.
+</p>
+
+<p>
+<b>Compatibility note:</b>
+SWIG-4.1.0 changed the way that rvalue reference parameters were handled and implemented typemaps assuming that the
+proxy class owns the underlying C++ object and transfers ownership of the object when a function/constructor with an rvalue reference parameter is called.
+</p>
+
+<H4><a name="CPlusPlus11_rvalue_reference_outputs">7.2.1.2 Rvalue reference outputs</a></H4>
+
+
+<p>
+While rvalue reference parameter inputs are not uncommon in C++ and can be usefully utilised from target languages, this cannot be said for rvalue reference outputs.
+Firstly, it is quite unusual in C++ to have functions that return an rvalue reference.
+Secondly, these cases are nigh on impossible to use from a target language.
+The main problem is these references are for C++ compiler temporaries used on the stack and the target languages use objects on the heap
+and the concept of compiler temporary objects doesn't make sense from another language.
+</p>
+
+<p>
+Using <tt>MyClass</tt> from earlier and this C++ code:
+</p>
+
+<div class="code"><pre>
+void use(MyClass &amp;&amp;mc);
+MyClass &amp;&amp; get1();
+MyClass &amp; get2();
+</pre></div>
+
+<p>
+SWIG wraps the <tt>get1</tt> and <tt>get2</tt> functions more or less identically.
+The returned references are converted into pointers that are not owned by the target language.
+It means that the following perfectly valid C++ has no equivalent in any of the target languages:
+</p>
+
+<div class="code"><pre>
+use(get1());
+use(std::move(get2()));
+</pre></div>
+
+<p>
+An attempt to call the equivalent <tt>use(get1())</tt> from one of the target languages will result in the ownership failure mentioned in the previous section as the object being passed to the <tt>use</tt> function is not owned by the proxy class.
+In order to own the object, it would need to be cloned for the object to move from the stack to the heap, for which an appropriate clone function would be required, but may not even be available.
+Note that a move constructor or copy constructor may slice the object when inheritance is involved.
+Alternatively, customising the input rvalue reference typemap, as mentioned in the previous section, could remove the ownership requirement.
+Another alternative would be to modify the output rvalue reference typemap to always clone the rvalue reference object.
+Fortunately you're highly unlikely to have to solve any of these issues!
+</p>
+
+<H4><a name="CPlusPlus11_move_only">7.2.1.3 Movable and move-only types by value</a></H4>
+
+
+<p>
+SWIG has traditionally relied on wrapped C++ types to be copy constructible or copy assignable, either via an explicit or implicit copy constructor and copy assignment operator.
+Prior to C++11, a function could not return nor take a type by value that was not copyable.
+In C++11 this is no longer the case. A type can also be movable if it has has a move constructor and a move assignment operator.
+A move-only type is movable but not copyable; it has both the copy constructor and copy assignment operator deleted.
+Movable types can appear in function signatures for passing 'by value' and in C++11 the object can then be moved rather than copied.
+</p>
+
+<p>
+SWIG has support for both copyable and/or movable types.
+Support for move semantics is quite seamless when returning by value from a function.
+Support for move semantics is less so and may require some customisation when passing by value to a function.
+First let's consider returning by value from a function.
+</p>
+
+<p>
+The support for function return values is generically implemented in the "out" <tt>SWIGTYPE</tt> typemap which supports any type, including copyable, movable and move-only types.
+The typemap code is very simple and written so that the compiler will call the move constructor if possible,
+otherwise the copy constructor:
+</p>
+
+<div class="code"><pre>
+%typemap(out) SWIGTYPE %{
+  $result = new $1_ltype($1);
+%}
+</pre></div>
+
+<p>
+The above typemap is for C# and when used to wrap a move-only type such as:
+</p>
+
+<div class="code"><pre>
+struct MoveOnly {
+  int  val;
+  MoveOnly(): val(0)  {}
+
+  MoveOnly(const MoveOnly &amp;) = delete;
+  MoveOnly(MoveOnly &amp;&amp;) = default;
+
+  MoveOnly &amp; operator=(const MoveOnly &amp;) = delete;
+  MoveOnly &amp; operator=(MoveOnly &amp;&amp;) = default;
+
+  static MoveOnly create() { return MoveOnly(); }
+  static void take(MoveOnly mo);
+};
+</pre></div>
+
+<p>
+will generate wrapper code for the <tt>create</tt> factory method:
+</p>
+
+<div class="code"><pre>
+SWIGEXPORT void * SWIGSTDCALL CSharp_MoveOnly_create() {
+  void * jresult ;
+  SwigValueWrapper&lt; MoveOnly &gt; result;
+
+  result = MoveOnly::create();
+  jresult = new MoveOnly(result);
+  return jresult;
+}
+</pre></div>
+
+<p>
+<tt>SwigValueWrapper</tt> is covered in <a href="SWIGPlus.html#SWIGPlus_nn19">Pass and return by value</a>.
+Note that the generated code could be optimised further using the <a href="Typemaps.html#Typemaps_optimal">"optimal" attribute</a>
+in the "out" typemap, so if the above typemap is customised as follows (note that this is C# specific):
+</p>
+
+<div class="code"><pre>
+%typemap(out, optimal="1") MoveOnly %{
+  $result = new $1_ltype($1);
+%}
+</pre></div>
+
+<p>
+then the generated code will result in the object being optimally moved:
+</p>
+
+<div class="code"><pre>
+SWIGEXPORT void * SWIGSTDCALL CSharp_MoveOnly_create() {
+  void * jresult ;
+  jresult = new MoveOnly(MoveOnly::create());
+  return jresult;
+}
+</pre></div>
+
+<p>
+Now let's consider passing by value.
+We'll consider three cases; namely types that are:
+</p>
+
+<ol>
+  <li> Copyable and not movable - <tt>CopyOnly</tt>.</li>
+  <li> Copyable and movable - <tt>MovableCopyable</tt>.</li>
+  <li> Movable and not copyable - <tt>MoveOnly</tt>.</li>
+</ol>
+
+<p>
+and for clarification, define these two additional types as follows:
+</p>
+
+<div class="code"><pre>
+struct CopyOnly {
+  int  val;
+  CopyOnly(): val(0)  {}
+
+  CopyOnly(const CopyOnly &amp;) = default;
+  CopyOnly &amp; operator=(const CopyOnly &amp;) = default;
+
+  static CopyOnly create() { return CopyOnly(); }
+  static void take(CopyOnly co);
+};
+
+struct MovableCopyable {
+  int  val;
+  MovableCopyable(): val(0)  {}
+
+  MovableCopyable(const MovableCopyable &amp;) = default;
+  MovableCopyable(MovableCopyable &amp;&amp;) = default;
+  MovableCopyable &amp; operator=(const MovableCopyable &amp;) = default;
+  MovableCopyable &amp; operator=(MovableCopyable &amp;&amp;) = default;
+
+  static MovableCopyable create() { return MovableCopyable(); }
+  static void take(MovableCopyable mc);
+};
+</pre></div>
+
+<p>
+The generated code is shown below for <tt>CopyOnly::take</tt> (with additional comments for when constructors and assignment operators are called).
+While the code shown is C# specific, the generated constructor and/or assignment operator calls are ultimately the same for all target languages.
+</p>
+
+<div class="code"><pre>
+SWIGEXPORT void SWIGSTDCALL CSharp_CopyOnly_take(void * jarg1) {
+  CopyOnly arg1 ; // (a) Default constructor
+  CopyOnly *argp1 ;
+  
+  argp1 = (CopyOnly *)jarg1; 
+  if (!argp1) {
+    SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null CopyOnly", 0);
+    return ;
+  }
+  arg1 = *argp1; // (b) Copy assignment
+  CopyOnly::take(SWIG_STD_MOVE(arg1)); // (c) Copy constructor
+}
+</pre></div>
+
+<p>
+Note that <tt>SWIG_STD_MOVE</tt> is a macro defined as shown below to use <tt>std::move</tt> which is only available from C++11 onwards:
+</p>
+
+<div class="code"><pre>
+#if __cplusplus &gt;=201103L
+# define SWIG_STD_MOVE(OBJ) std::move(OBJ)
+#else
+# define SWIG_STD_MOVE(OBJ) OBJ
+#endif
+</pre></div>
+
+<p>
+Also note: <i>(c) Copy constructor</i>.
+Yes, when passing by value the copy constructor is called for all versions of C++, even C++11 and later even though std::move is specified.
+It's a C++ language feature for types that don't have move semantics!
+</p>
+
+<p>
+The generated code for <tt>MovableCopyable::take</tt> is the same as for <tt>CopyOnly::take</tt>, however, the C++ compiler will choose the move constructor this time where commented <i>(c) Move constructor</i>:
+</p>
+
+<div class="code"><pre>
+SWIGEXPORT void SWIGSTDCALL CSharp_MovableCopyable_take(void * jarg1) {
+  MovableCopyable arg1 ; // (a) Default constructor
+  MovableCopyable *argp1 ;
+  
+  argp1 = (MovableCopyable *)jarg1; 
+  if (!argp1) {
+    SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null MovableCopyable", 0);
+    return ;
+  }
+  arg1 = *argp1; // (b) Copy assignment
+  MovableCopyable::take(SWIG_STD_MOVE(arg1)); // (c) Move constructor
+}
+</pre></div>
+
+<p>
+There are two optimisation opportunities available.
+</p>
+<ol>
+  <li> Remove the default constructor call with the <tt>%feature("valuewrapper")</tt> covered in <a href="SWIGPlus.html#SWIGPlus_nn19">Pass and return by value</a> and replace it with <tt>SwigValueWrapper</tt>.
+  </li>
+  <li> Apply the SWIGTYPE MOVE typemaps which are designed specifically to implement full move semantics when passing parameters by value.
+    They replace the copy assignment with a call to <tt>SwigValueWrapper::reset</tt>, which works much like <tt>std::unique_ptr::reset</tt>.
+    These typemaps could alternatively have replaced the copy assignment with a move assignment, but this is not maximally optimal.
+  </li>
+</ol>
+<p>
+Simply add the following before the <tt>MovableCopyable::take</tt> method is parsed:
+</p>
+
+<div class="code"><pre>
+%valuewrapper MovableCopyable;
+%include &lt;swigmove.i&gt;
+%apply SWIGTYPE MOVE { MovableCopyable }
+</pre></div>
+
+<p>
+will result in this optimal code where just one move constructor is invoked:
+</p>
+
+<div class="code"><pre>
+SWIGEXPORT void SWIGSTDCALL CSharp_MovableCopyable_take(void * jarg1) {
+  SwigValueWrapper&lt; MovableCopyable &gt; arg1 ; // (a) No constructors invoked
+  MovableCopyable *argp1 ;
+  
+  argp1 = (MovableCopyable *)jarg1;
+  if (!argp1) {
+    SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null MovableCopyable", 0);
+    return ;
+  }
+  SwigValueWrapper&lt; MovableCopyable &gt;::reset(arg1, argp1);  // (b) No constructor or assignment operator invoked
+  MovableCopyable::take(SWIG_STD_MOVE(arg1)); // (c) Move constructor
+}
+</pre></div>
+
+<p>
+Note that <tt>SwigValueWrapper</tt> will call the destructor for the pointer passed to it in the <tt>reset</tt> function.
+This pointer is the underlying C++ object that the proxy class owns.
+The details aren't shown, but the 'csin' typemap also generates C# code to ensure that the proxy class releases ownership of the object.
+Please see the 'SWIGTYPE MOVE' typemaps in the swigmove.i file provided for each target language.
+Therefore full move semantics are implemented; ownership is moved from the proxy class into the C++ layer and the net effect
+is the same as using an <a href="#CPlusPlus11_rvalue_reference_inputs">rvalue reference parameter</a> discussed earlier.
+</p>
+
+<p>
+Lastly, let's consider the <tt>MoveOnly::take</tt> function defined earlier.
+By default the generated code fails to compile as <tt>MoveOnly</tt> does not have a copy assignment operator.
+SWIG is not designed to select a different typemap automatically for move-only types and the user
+must apply the SWIGTYPE MOVE typemaps to ensure that only move-only semantics are used.
+However, SWIG is able to automatically use <tt>%feature("valuewrapper")</tt> for move-only
+types so it is not necessary to explicitly use this feature.
+So in this move-only case, simply add the following before <tt>MoveOnly::take</tt> is parsed, which results in the same optimal code shown above for <tt>MovableCopyable</tt>:
+</p>
+
+<div class="code"><pre>
+%include &lt;swigmove.i&gt;
+%apply SWIGTYPE MOVE { MoveOnly }
+</pre></div>
+
+<p>
+<b>Compatibility note:</b>
+SWIG-4.1.0 introduced support for taking advantage of types with move semantics and making it possible to easily use move only types.
+</p>
+
 
 <H3><a name="CPlusPlus11_generalized_constant_expressions">7.2.2 Generalized constant expressions</a></H3>
 
@@ -144,14 +516,39 @@
 <H3><a name="CPlusPlus11_extern_template">7.2.3 Extern template</a></H3>
 
 
-<p>SWIG correctly parses the keywords <tt>extern template</tt>.
+<p>SWIG correctly parses <tt>extern template</tt> explicit instantiation declarations.
 However, this template instantiation suppression in a translation unit has no relevance outside of the C++ compiler and so is not used by SWIG.
-SWIG only uses <tt>%template</tt> for instantiating and wrapping templates.</p>
+SWIG only uses <tt>%template</tt> for instantiating and wrapping templates.
+Consider the class template below:
+</p>
 
 <div class="code"><pre>
-template class std::vector&lt;int&gt;;        // C++03 explicit instantiation in C++
-extern template class std::vector&lt;int&gt;; // C++11 explicit instantiation suppression in C++
-%template(VectorInt) std::vector&lt;int&gt;;  // SWIG instantiation
+// Class template
+template class std::vector&lt;int&gt;;        // C++03 template explicit instantiation definition in C++
+extern template class std::vector&lt;int&gt;; // C++11 template explicit instantiation declaration (extern template)
+%template(VectorInt) std::vector&lt;int&gt;;  // SWIG template instantiation
+</pre></div>
+
+<p>
+The above result in warnings:
+</p>
+
+<div class="shell">
+<pre>
+example.i:2: Warning 320: Explicit template instantiation ignored.
+example.i:3: Warning 327: Extern template ignored.
+</pre>
+</div>
+
+<p>
+Similarly for the function template below:
+</p>
+
+<div class="code"><pre>
+// Function template
+template void Func&lt;int&gt;();              // C++03 template explicit instantiation definition in C++
+extern template void Func&lt;int&gt;();       // C++11 template explicit instantiation declaration (extern template)
+%template(FuncInt) Func&lt;int&gt;;           // SWIG template instantiation
 </pre></div>
 
 <H3><a name="CPlusPlus11_initializer_lists">7.2.4 Initializer lists</a></H3>
@@ -322,20 +719,57 @@
 <H3><a name="CPlusPlus11_type_inference">7.2.6 Type inference</a></H3>
 
 
-<p>SWIG supports <tt>decltype()</tt> with some limitations. Single
-variables are allowed, however, expressions are not supported yet. For
-example, the following code will work:</p>
+<p><tt>decltype()</tt> is supported with a few limitations.  SWIG can parse
+all uses, but can't deduce the type in every situation where a C++ compiler
+can.  The cases SWIG can deduce have expanded with time and hopefully will
+continue to.  For example, for the code</p>
 <div class="code"><pre>
 int i;
 decltype(i) j;
+decltype(i+j) k;
 </pre></div>
 
-<p>However, using an expression inside the decltype results in syntax error:</p>
+<p>SWIG is able to deduce that the variable <tt>i</tt> and the expression
+<tt>i+j</tt> both have type <tt>int</tt>.
+</p>
+
+<p>
+Using an expression for the decltype which SWIG can't handle results in a warning:</p>
 <div class="code"><pre>
-int i; int j;
-decltype(i+j) k;  // syntax error
+int foo(int);
+decltype(foo(0)) k;  // Warning 344: Unable to deduce decltype for 'foo(0)'.
 </pre></div>
 
+<p>
+This warning should be viewed as a prompt to add in a manual ignore of the variable/function as
+in most cases the generated code will not compile.
+For the example above, ignore the symbol that is declared using <tt>decltype</tt> and perhaps additionally
+suppress the warning as follows:
+</p>
+
+<div class="code"><pre>
+#pragma SWIG nowarn=SWIGWARN_CPP11_DECLTYPE
+%ignore k;
+</pre></div>
+
+<p>
+If an ignore is not acceptable, a workaround is to redefine the symbol with the actual type, for example:
+</p>
+
+<div class="code"><pre>
+int k; // define k with the actual type
+%ignore k; // ignore the real definition of k
+</pre></div>
+
+<p>You would typically put one of these workarounds in your interface file before
+using <tt>%include</tt> to get SWIG to parse the header which defines <tt>k</tt>.
+</p>
+
+<p>SWIG supports <tt>auto</tt> as a type specifier for variables (with the same limitations
+for actually deducing the type as for <tt>decltype()</tt>), and for specifying
+the return type of <a href="#CPlusPlus11_lambda_functions_and_expressions">lambdas</a>
+and <a href="#CPlusPlus11_alternate_function_syntax">functions</a>.</p>
+
 <H3><a name="CPlusPlus11_range_based_for_loop">7.2.7 Range-based for-loop</a></H3>
 
 
@@ -431,12 +865,9 @@
 
 <p>
 The second improvement is constructor inheritance via a <tt>using</tt> declaration.
-This is parsed correctly, but the additional constructors are not currently added to the derived proxy class in the target language.
-An example is shown below:
-<!--
-The extra constructors provided by the <tt>using</tt> syntax will add the appropriate constructors into the target language proxy derived classes.
-In the example below a wrapper for the <tt>DerivedClass(int)</tt> is added to <tt>DerivedClass</tt>:
--->
+The extra constructors provided by the <tt>using</tt> declaration will add the appropriate constructors into the target language proxy derived classes.
+In the example below a wrapper for the <tt>DerivedClass(int)</tt> constructor is added to <tt>DerivedClass</tt>:
+
 </p>
 
 <div class="code"><pre>
@@ -452,6 +883,10 @@
 </pre></div>
 
 <p>
+<b>Compatibility note:</b> SWIG-4.2.0 was the first version to generate wrappers for constructors inherited via <tt>using</tt> declarations.
+</p>
+
+<p>
 The final part is member initialization at the site of the declaration.
 This kind of initialization is handled by SWIG.
 </p>
@@ -489,6 +924,19 @@
 };
 </pre></div>
 
+<p>
+Classes can also be marked as final, such as
+</p>
+
+<div class="code"><pre>
+struct FinalDerivedStruct final : BaseStruct {
+  virtual void ab() const override;
+};
+</pre></div>
+
+<p>
+<b>Compatibility note:</b> Final methods were supported much earlier than final classes. SWIG-4.1.0 was the first version to support classes marked as final.
+</p>
 
 <H3><a name="CPlusPlus11_null_pointer_constant">7.2.12 Null pointer constant</a></H3>
 
@@ -551,6 +999,22 @@
 System.out.println(Color.RainbowColors.Red.swigValue() + " " + Color.WarmColors.Red.swigValue() + " " + Color.PrimeColors.Red.swigValue());
 </pre></div>
 
+<p>
+The C++11 enum base type, such as <tt>unsigned int</tt>, in the example above, is used by some language modules and is missing support in others. For example, in C#, the enum base type in the example above is used and converted into a C# <tt>uint</tt> to specify the underlying C# enumeration type as follows:
+</p>
+
+<div class="targetlang"><pre>
+  public enum RainbowColors : uint {
+    Red,
+    Orange,
+    Yellow,
+    Green,
+    Blue,
+    Indigo,
+    Violet
+  }
+</pre></div>
+
 <H3><a name="CPlusPlus11_double_angle_brackets">7.2.14 Double angle brackets</a></H3>
 
 
@@ -683,38 +1147,71 @@
 <H3><a name="CPlusPlus11_variadic_templates">7.2.18 Variadic templates</a></H3>
 
 
-<p>SWIG supports the variadic templates syntax (inside the &lt;&gt;
-block, variadic class inheritance and variadic constructor and
-initializers) with some limitations. The following code is correctly parsed:</p>
+<p>SWIG supports the variadic templates including the &lt;&gt;
+variadic class inheritance, variadic methods, variadic constructors and
+initializers. Example:</p>
 
 <div class="code"><pre>
 template &lt;typename... BaseClasses&gt; class ClassName : public BaseClasses... {
 public:
-  ClassName (BaseClasses &amp;&amp;... baseClasses) : BaseClasses(baseClasses)... {}
-}
+  ClassName(BaseClasses &amp;&amp;... baseClasses) : BaseClasses(baseClasses)... {}
+  void InstanceMethod(const BaseClasses&amp;... baseClasses) {}
+};
 </pre></div>
 
 <p>
-For now however, the <tt>%template</tt> directive only accepts one parameter substitution
-for the variable template parameters.
+The <tt>%template</tt> directive works as expected for variable template parameters.
 </p>
 
 <div class="code"><pre>
-%template(MyVariant1) ClassName&lt;&gt;         // zero argument not supported yet
-%template(MyVariant2) ClassName&lt;int&gt;      // ok
-%template(MyVariant3) ClassName&lt;int, int&gt; // too many arguments not supported yet
+struct A {
+  virtual void amethod();
+  virtual ~A();
+};
+struct B {
+  virtual void bmethod();
+  virtual ~B();
+};
+%template(ClassName0) ClassName&lt;&gt;
+%template(ClassName1) ClassName&lt;A&gt;
+%template(ClassName2) ClassName&lt;A, B&gt;
 </pre></div>
 
-<p>Support for the variadic <tt>sizeof()</tt> function is correctly parsed:</p>
+<p>
+Example usage from say Python:
+</p>
+
+<div class="targetlang"><pre>
+cn0 = ClassName0()
+cn0.InstanceMethod()
+
+a = A()
+cn1 = ClassName1(a)
+cn1.amethod()
+cn1.InstanceMethod(a)
+
+b = B()
+cn2 = ClassName2(a, b)
+cn2.InstanceMethod(a, b)
+cn2.amethod()
+cn2.bmethod()
+</pre></div>
+
+<p>Support for the variadic <tt>sizeof()</tt> function also works:</p>
 
 <div class="code"><pre>
-const int SIZE = sizeof...(ClassName&lt;int, int&gt;);
+const int SIZE = sizeof...(ClassName&lt;A, B&gt;);
 </pre></div>
 
 <p>
 In the above example <tt>SIZE</tt> is of course wrapped as a constant.
 </p>
 
+<p>
+<b>Compatibility note:</b> SWIG-4.2.0 was the first version to fully support variadic templates.
+SWIG-3.0.0 provided initial support and was limited to only one variadic parameter.
+</p>
+
 <H3><a name="CPlusPlus11_new_char_literals">7.2.19 New character literals</a></H3>
 
 
@@ -981,7 +1478,9 @@
 
 
 <p>
-Attributes such as those shown below, are not yet supported and will give a syntax error.
+Attributes such as those shown below, are supported since SWIG 4.1.0 but are
+currently crudely ignored by the parser's tokeniser so they have no effect on
+SWIG's code generation.
 </p>
 
 <div class="code"><pre>
@@ -1128,14 +1627,16 @@
 
 <p>
 SWIG provides special smart pointer handling for <tt>std::shared_ptr</tt> in the same way it has support for <tt>boost::shared_ptr</tt>.
-Please see the <a href="Library.html#Library_std_shared_ptr">shared_ptr smart pointer</a> library section.
-There is no special smart pointer handling available for <tt>std::weak_ptr</tt> and <tt>std::unique_ptr</tt> yet.
+Please see the <a href="Library.html#Library_std_shared_ptr">shared_ptr smart pointer</a>
+and <a href="Library.html#Library_std_unique_ptr">unique_ptr smart pointer</a> library sections.
+There is no special smart pointer handling available for <tt>std::weak_ptr</tt>.
+
 </p>
 
 <H3><a name="CPlusPlus11_extensible_random_number_facility">7.3.6 Extensible random number facility</a></H3>
 
 
-<p>This feature extends and standardizes the standard library only and does not effect the C++ language nor SWIG.</p>
+<p>This feature extends and standardizes the standard library only and does not affect the C++ language nor SWIG.</p>
 
 <H3><a name="CPlusPlus11_wrapper_reference">7.3.7 Wrapper reference</a></H3>
 
diff --git a/Doc/Manual/CPlusPlus14.html b/Doc/Manual/CPlusPlus14.html
index b162c78..adca9b3 100644
--- a/Doc/Manual/CPlusPlus14.html
+++ b/Doc/Manual/CPlusPlus14.html
@@ -15,6 +15,7 @@
 <li><a href="#CPlusPlus14_core_language_changes">Core language changes</a>
 <ul>
 <li><a href="#CPlusPlus14_binary_literals">Binary integer literals</a>
+<li><a href="#CPlusPlus14_return_type_deduction">Return type deduction</a>
 </ul>
 <li><a href="#CPlusPlus14_standard_library_changes">Standard library changes</a>
 </ul>
@@ -53,6 +54,67 @@
 </pre>
 </div>
 
+<H3><a name="CPlusPlus14_return_type_deduction">8.2.2 Return type deduction</a></H3>
+
+
+<p>
+C++14 added the ability to specify <tt>auto</tt> for the return type of a function
+and have the compiler deduce it from the body of the function (in C++11 you had
+to explicitly specify a trailing return type if you used <tt>auto</tt> for the
+return type).
+</p>
+
+<p>
+SWIG parses these types of functions, but with one significant limitation: SWIG
+can't actually deduce the return type!  If you want to wrap such a function
+you will need to tell SWIG the return type explicitly.
+</p>
+
+<p>
+The trick for specifying the return type is to use <tt>%ignore</tt> to tell
+SWIG to ignore the function with the deduced return type, but first provide
+SWIG with an alternative declaration of the function with an explicit return
+type.  The generated wrapper will wrap this alternative declaration, and the
+call in the wrapper to the function will call the actual declaration.  Here is
+an actual example:
+</p>
+
+<div class="code"><pre>
+std::tuple&lt;int, int&gt; va_static_cast();
+%ignore va_static_cast();
+#pragma SWIG nowarn=SWIGWARN_CPP14_AUTO
+
+%inline %{
+#include &lt;tuple&gt;
+
+auto va_static_cast() {
+    return std::make_tuple(0, 0);
+}
+%}
+</pre></div>
+
+<p>
+For member methods the trick is to use <tt>%extend</tt> to redeclare the method and call it as follows:
+</p>
+
+<div class="code"><pre>
+%extend X {
+  const char * a() const { return $self-&gt;a(); }
+}
+%inline %{
+struct X {
+  auto a() const {
+    return "a string";
+  }
+};
+%}
+</pre></div>
+
+<p>
+<b>Compatibility note:</b> SWIG-4.2.0 first introduced support for functions declared with an auto return without a trailing return type.
+</p>
+
+
 <H2><a name="CPlusPlus14_standard_library_changes">8.3 Standard library changes</a></H2>
 
 
diff --git a/Doc/Manual/CPlusPlus20.html b/Doc/Manual/CPlusPlus20.html
new file mode 100644
index 0000000..98cb286
--- /dev/null
+++ b/Doc/Manual/CPlusPlus20.html
@@ -0,0 +1,91 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
+<html>
+<head>
+<title>SWIG and C++20</title>
+<link rel="stylesheet" type="text/css" href="style.css">
+<meta http-equiv="content-type" content="text/html; charset=UTF-8">
+</head>
+
+<body bgcolor="#ffffff">
+<H1><a name="CPlusPlus20">10 SWIG and C++20</a></H1>
+<!-- INDEX -->
+<div class="sectiontoc">
+<ul>
+<li><a href="#CPlusPlus20_introduction">Introduction</a>
+<li><a href="#CPlusPlus20_core_language_changes">Core language changes</a>
+<ul>
+<li><a href="#CPlusPlus20_spaceship_operator">Spaceship operator</a>
+<li><a href="#CPlusPlus20_lambda_templates">Lambda templates</a>
+<li><a href="#CPlusPlus20_constexpr_destructors">Constexpr destructors</a>
+</ul>
+<li><a href="#CPlusPlus20_standard_library_changes">Standard library changes</a>
+</ul>
+</div>
+<!-- INDEX -->
+
+
+
+<H2><a name="CPlusPlus20_introduction">10.1 Introduction</a></H2>
+
+
+<p>This chapter gives you a brief overview about the SWIG
+implementation of the C++20 standard.
+Work has only just begun on adding C++20 support.
+</p>
+
+<p>
+<b>Compatibility note:</b> SWIG-4.1.0 is the first version to support any C++20 features.
+</p>
+
+<H2><a name="CPlusPlus20_core_language_changes">10.2 Core language changes</a></H2>
+
+
+<H3><a name="CPlusPlus20_spaceship_operator">10.2.1 Spaceship operator</a></H3>
+
+
+<p>
+SWIG supports the spaceship operator <tt>&lt;=&gt;</tt> in constant
+expressions.  To simplify handling of the return value type, it is currently
+treated as an integer rather than <tt>std::strong_ordering</tt>, etc.
+In practice we think that should do the right thing in most cases.
+</p>
+
+<p>
+SWIG also recognises <tt>operator&lt;=&gt;</tt> which can be wrapped
+if renamed.  There is not currently any default renaming for the operator
+or any attempt to automatically map it to a three-way comparison operator
+in any of the target languages.
+</p>
+
+<H3><a name="CPlusPlus20_lambda_templates">10.2.2 Lambda templates</a></H3>
+
+
+<p>
+SWIG should parse lambda templates, but like
+<a href="CPlusPlus11.html#CPlusPlus11_lambda_functions_and_expressions">
+non-templated lambdas</a> they aren't currently wrapped.
+</p>
+
+
+<H3><a name="CPlusPlus20_constexpr_destructors">10.2.3 Constexpr destructors</a></H3>
+
+
+<p>
+Destructors that are declared <tt>constexpr</tt> are parsed and handled like any other constructor.
+For example:
+</p>
+
+<div class="code">
+<pre>
+class DtorA {
+public:
+  constexpr ~DtorA() {}
+};
+</pre>
+</div>
+
+<H2><a name="CPlusPlus20_standard_library_changes">10.3 Standard library changes</a></H2>
+
+
+</body>
+</html>
diff --git a/Doc/Manual/CSharp.html b/Doc/Manual/CSharp.html
index 1fc2d21..1c0994c 100644
--- a/Doc/Manual/CSharp.html
+++ b/Doc/Manual/CSharp.html
@@ -6,7 +6,7 @@
 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 </head>
 <body bgcolor="#FFFFFF">
-<H1><a name="CSharp">22 SWIG and C#</a></H1>
+<H1><a name="CSharp">23 SWIG and C#</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -16,7 +16,12 @@
 <li><a href="#CSharp_commandline">Additional command line options</a>
 </ul>
 <li><a href="#CSharp_differences_java">Differences to the Java module</a>
+<li><a href="#CSharp_type_mapping">Type mapping</a>
+<ul>
+<li><a href="#CSharp_primitive_types">Primitive types</a>
+<li><a href="#CSharp_other_type_mappings">Other types</a>
 <li><a href="#CSharp_void_pointers">Void pointers</a>
+</ul>
 <li><a href="#CSharp_arrays">C# Arrays</a>
 <ul>
 <li><a href="#CSharp_arrays_swig_library">The SWIG C arrays library</a>
@@ -37,6 +42,7 @@
 <li><a href="#CSharp_director_caveats">Director caveats</a>
 </ul>
 <li><a href="#CSharp_multiple_modules">Multiple modules</a>
+<li><a href="#CSharp_named_arguments">C# named and optional arguments</a>
 <li><a href="#CSharp_typemap_examples">C# Typemap examples</a>
 <ul>
 <li><a href="#CSharp_memory_management_member_variables">Memory management when returning references to member variables</a>
@@ -55,7 +61,7 @@
 
 
 
-<H2><a name="CSharp_introduction">22.1 Introduction</a></H2>
+<H2><a name="CSharp_introduction">23.1 Introduction</a></H2>
 
 
 <p>
@@ -66,7 +72,13 @@
 It is also better suited for robust production environments due to the Managed C++ flaw called the
 <a href="https://msdn.microsoft.com/en-us/ie/aa290048(v=vs.94)">Mixed DLL Loading Problem</a>.
 SWIG C# works equally well on non-Microsoft operating systems such as Linux, Solaris and Apple Mac using
-<a href="https://www.mono-project.com/Main_Page/">Mono</a> and <a href="http://www.dotgnu.org/pnet.html">Portable.NET</a>.
+<a href="https://www.mono-project.com/Main_Page/">Mono</a>.
+</p>
+
+<p>
+SWIG 3 and later requires .NET 2.0 at a minimum.
+There are some minor exceptions, where the minimum required is .NET 4.0.
+This is when using the <tt>std::complex</tt> and <tt>std::list</tt> STL containers.
 </p>
 
 <p>
@@ -75,7 +87,7 @@
 Monodoc, available from the Mono project, has a very useful section titled <a href="https://www.mono-project.com/docs/advanced/pinvoke/">Interop with native libraries</a>.
 </p>
 
-<H3><a name="CSharp_introduction_swig2_compatibility">22.1.1 SWIG 2 Compatibility</a></H3>
+<H3><a name="CSharp_introduction_swig2_compatibility">23.1.1 SWIG 2 Compatibility</a></H3>
 
 
 <p>
@@ -83,7 +95,7 @@
 </p>
 
 
-<H3><a name="CSharp_commandline">22.1.2 Additional command line options</a></H3>
+<H3><a name="CSharp_commandline">23.1.2 Additional command line options</a></H3>
 
 
 <p>
@@ -135,7 +147,7 @@
 Due to possible compiler limits it is not advisable to use <tt>-outfile</tt> for large projects.
 </p>
 
-<H2><a name="CSharp_differences_java">22.2 Differences to the Java module</a></H2>
+<H2><a name="CSharp_differences_java">23.2 Differences to the Java module</a></H2>
 
 
 <p>
@@ -234,6 +246,7 @@
 javafinalize                -&gt; csfinalize
 javadestruct                -&gt; csdisposing and csdispose
 javadestruct_derived        -&gt; csdisposing_derived and csdispose_derived
+javainterfacemodifiers      -&gt; csinterfacemodifiers
 javainterfacecode           -&gt; csinterfacecode
 </pre></div>
 
@@ -513,7 +526,7 @@
 
 <div class="code">
 <pre>
-%module (imclassname="name") modulename
+%module(imclassname="name") modulename
 </pre>
 </div>
 
@@ -524,6 +537,38 @@
 </li>
 
 <li>
+<a name="CSharp_begin"></a>
+<p>
+The <tt>%module</tt> directive supports the <tt>csbegin</tt> option for adding code to the start of every generated C# file.
+This is useful for adding common comments, using statements and/or preprocessor statements into all generated .cs files. For example,
+C# 8 nullable reference types can be enabled via a C# preprocessor directive by adding <tt>#nullable enable</tt> into C# files as follows:
+</p>
+
+<div class="code">
+<pre>
+%module(csbegin="#nullable enable\n") mymodule
+</pre>
+</div>
+
+<p>
+It might be easier to use a macro for multiple lines of code, for example:
+</p>
+
+<div class="code">
+<pre>
+%define CSBEGIN_CODE
+"
+/* Copyright statement */
+using System.Text;
+#nullable enable
+"
+%enddef
+
+%module(csbegin=CSBEGIN_CODE) mymodule
+</pre>
+</div>
+
+<li>
 There is no additional 'premature garbage collection prevention parameter' as the marshalling of the <tt>HandleRef</tt> object
 takes care of ensuring a reference to the proxy class is held until the unmanaged call completed.
 </li>
@@ -544,6 +589,12 @@
 </p>
 
 <p>
+<b><tt>$imfuncname</tt></b><br>
+This special variable expands to the name of the function in the intermediary class that will be used in $imcall.
+Like, $imcall, this special variable is only expanded in the "csout", "csvarin" and "csvarout" typemaps.
+</p>
+
+<p>
 The directory <tt>Examples/csharp</tt> has a number of simple examples. 
 Visual Studio .NET 2003 solution and project files are available for compiling with the Microsoft .NET C#
 compiler on Windows. This also works with newer versions of Visual Studio if you allow
@@ -553,17 +604,313 @@
 the examples will be run, by either running <tt>runme.exe</tt> or by running
 <tt>mono runme.exe</tt> (Mono C# compiler).
 Windows users can also get the examples working using a
-<a href="http://www.cygwin.com">Cygwin</a> or <a href="http://www.mingw.org">MinGW</a> environment for automatic configuration of the example makefiles.
+<a href="http://www.cygwin.com">Cygwin</a> or <a href="https://osdn.net/projects/mingw/">MinGW</a> environment for automatic configuration of the example makefiles.
 Any one of the C# compilers (Mono or Microsoft) can be detected from within a Cygwin or Mingw environment if installed in your path. 
 
-<H2><a name="CSharp_void_pointers">22.3 Void pointers</a></H2>
+<H2><a name="CSharp_type_mapping">23.3 Type mapping</a></H2>
 
 
 <p>
-By default SWIG treats <tt>void *</tt> as any other pointer and hence marshalls it as a type wrapper class called <tt>SWIGTYPE_p_void</tt>.
+The marshalling of the types and typemaps used for marshalling across the managed/unmanaged layers are discussed in this section.
+The interested reader will find the implementation in the csharp.swg file.
+</p>
+
+<H3><a name="CSharp_primitive_types">23.3.1 Primitive types</a></H3>
+
+
+<p>
+Primitive types are marshalled between the unmanaged and managed layers as blittable types.
+</p>
+
+<ul>
+<li> The first column in the table below shows various C/C++ types that might be parsed by SWIG.
+<li> The second column contains the default type provided by the 'ctype' typemap, that is, the type used for marshalling on the C side.
+<li> The third column shows the default type provided by both the 'imtype' and the 'cstype' typemaps, that is, the equivalent type on the C# side.
+<li> The fourth column shows the size or number of bytes of the 'imtype'/'cstype', which may or may not match the size of the C/C++ type and is discussed next.
+</ul>
+
+<table BORDER summary="Default primitive type mappings">
+<tr>
+<td><b>C/C++ type</b></td>
+<td><b>ctype</b></td>
+<td><b>imtype/cstype</b></td>
+<td><b>Size</b></td>
+</tr>
+
+<tr>
+<td>bool<br> const bool &amp; </td>
+<td>unsigned int</td>
+<td>bool</td>
+<td>1</td>
+</tr>
+
+<tr>
+<td>char<br>const char &amp;</td>
+<td>char</td>
+<td>char</td>
+<td>1</td>
+</tr>
+
+<tr>
+<td>signed char<br>const signed char &amp;</td>
+<td>signed char</td>
+<td>sbyte</td>
+<td>1</td>
+</tr>
+
+<tr>
+<td>unsigned char<br>const unsigned char &amp;</td>
+<td>unsigned char</td>
+<td>byte</td>
+<td>1</td>
+</tr>
+
+<tr>
+<td>short<br>const short &amp;</td>
+<td>short</td>
+<td>short</td>
+<td>2</td>
+</tr>
+
+<tr>
+<td>unsigned short<br> const unsigned short &amp;</td>
+<td>unsigned short</td>
+<td>ushort</td>
+<td>2</td>
+</tr>
+
+<tr>
+<td>int<br> const int &amp;</td>
+<td>int</td>
+<td>int</td>
+<td>4</td>
+</tr>
+
+<tr>
+<td>unsigned int<br> const unsigned int &amp;</td>
+<td>unsigned int</td>
+<td>uint</td>
+<td>4</td>
+</tr>
+
+<tr>
+<td>long<br>const long &amp;</td>
+<td>int</td>
+<td>int</td>
+<td>4</td>
+</tr>
+
+<tr>
+<td>unsigned long<br>const unsigned long &amp;</td>
+<td>unsigned int</td>
+<td>uint</td>
+<td>4</td>
+</tr>
+
+<tr>
+<td>long long<br> const long long &amp;</td>
+<td>long long</td>
+<td>long</td>
+<td>8</td>
+</tr>
+
+<tr>
+<td>unsigned long long<br>const unsigned long long &amp;</td>
+<td>unsigned long long</td>
+<td>ulong</td>
+<td>8</td>
+</tr>
+
+<tr>
+<td>float<br>const float &amp;</td>
+<td>float</td>
+<td>float</td>
+<td>4</td>
+</tr>
+
+<tr>
+<td>double<br> const double &amp;</td>
+<td>double</td>
+<td>double</td>
+<td>8</td>
+</tr>
+
+<tr>
+<td>size_t<br> const size_t &amp;</td>
+<td>unsigned int</td>
+<td>uint</td>
+<td>4</td>
+</tr>
+
+
+</table>
+
+<p>
+The size in bytes of the C type, 'ctype', should match the C# type, 'imtype' for blitting across the managed/unmanaged layers.
+They do match across the common 32-bit and 64-bit operating systems, Unix, Windows and MacOS, except for the C long/unsigned long and size_t types.
+From the table above the default is to handle C long and size_t as a 32-bit (4 byte) type, so large numbers could be truncated on some 64-bit operating systems.
+If <tt>SWIGWORDSIZE64</tt> is defined the C long type is instead handled as a 64-bit (8 byte) type, as per the table below.
+</p>
+
+<table BORDER summary="SWIGWORDSIZE64 primitive type mappings">
+
+<tr>
+<td><b>C/C++ type</b></td>
+<td><b>ctype</b></td>
+<td><b>imtype/cstype</b></td>
+<td><b>Size</b></td>
+</tr>
+
+<tr>
+<td>long<br>const long &amp;</td>
+<td>long long</td>
+<td>long</td>
+<td>8</td>
+</tr>
+
+<tr>
+<td>unsigned long<br>const unsigned long &amp;</td>
+<td>unsigned long long</td>
+<td>ulong</td>
+<td>8</td>
+</tr>
+
+</table>
+
+<p>
+However, truncation may then occur when the C long type is actually 32-bits (4 bytes).
+It's best to avoid using C long for portability across different operating systems!
+</p>
+
+<p>
+If you need to support long on a range of systems where the size of long varies, then steps must be taken before invoking SWIG to determine whether or not to define <tt>SWIGWORDSIZE64</tt> when invoking SWIG.
+</p>
+
+<p>
+In order to treat the C size_t type as a 64-bit (8 byte) type, apply the 64-bit typemaps as follows:
+</p>
+
+<div class="code">
+<pre>
+%apply unsigned long long { size_t };
+%apply const unsigned long long &amp; { const size_t &amp; };
+</pre>
+</div>
+
+<p>
+The net effect then changes from the default shown earlier to:
+</p>
+
+<table BORDER summary="size_t long long mappings">
+
+<tr>
+<td><b>C/C++ type</b></td>
+<td><b>ctype</b></td>
+<td><b>imtype/cstype</b></td>
+<td><b>Size</b></td>
+</tr>
+
+<tr>
+<td>size_t<br>const size_t &amp;</td>
+<td>unsigned long long</td>
+<td>ulong</td>
+<td>8</td>
+</tr>
+
+</table>
+
+<p>
+If you need to support size_t on a range of systems where the size of size_t varies, then steps must be taken before invoking SWIG to determine whether or not to apply the typemaps.
+Conditionally applying the typemaps using a macro is easily done. For example define <tt>MY_SIZET_WORDSIZE64</tt> to generate 64-bit (8 byte) handling using the following:
+</p>
+
+<div class="code">
+<pre>
+#if defined(MY_SIZET_WORDSIZE64)
+%apply unsigned long long { size_t };
+%apply const unsigned long long &amp; { const size_t &amp; };
+#endif
+</pre>
+</div>
+
+<H3><a name="CSharp_other_type_mappings">23.3.2 Other types</a></H3>
+
+
+<p>
+The table below shows the equivalent mappings for pointers and strings.
+Classes and structs are marshalled using a pointer to the instance of the object.
+Note the types in the 'imtype' and 'cstype' typemaps can be different.
+</p>
+
+<ul>
+<li> The 'imtype' type is used for marshalling across the managed and unmanaged boundary.
+<li> The 'cstype' is the final C# proxy or intermediary class type.
+<li> In the table below, the 'imtype' type is used for marshalling from the managed to the unmanaged layer.
+<li> The 'imtype out' type is used for marshalling from the unmanaged to the managed layer.
+</ul>
+
+<table BORDER summary="Other type mappings">
+
+<tr>
+<td><b>C/C++ type</b></td>
+<td><b>ctype</b></td>
+<td><b>imtype</b></td>
+<td><b>imtype out</b></td>
+<td><b>cstype</b></td>
+</tr>
+
+<tr>
+<td>char *<br>char []</td>
+<td>char *</td>
+<td>string</td>
+<td>string</td>
+<td>string</td>
+</tr>
+
+<tr>
+<td>void *</td>
+<td>void *</td>
+<td>System.Runtime.InteropServices.HandleRef</td>
+<td>System.IntPtr</td>
+<td>SWIGTYPE_p_void</td>
+</tr>
+
+</table>
+
+
+<H3><a name="CSharp_void_pointers">23.3.3 Void pointers</a></H3>
+
+
+<p>
+By default SWIG treats <tt>void *</tt> as any other pointer and hence marshalls it as a type wrapper class called <tt>SWIGTYPE_p_void</tt>,
+as shown in the table in the previous section.
 If you want to marshall with the .NET <tt>System.IntPtr</tt> type instead, there is a simple set of named typemaps called
 <tt>void *VOID_INT_PTR</tt> that can be used.
-They can be applied like any other named typemaps:
+The net effect is then:
+</p>
+
+<table BORDER summary="VOID_INT_PTR type mappings">
+
+<tr>
+<td><b>C/C++ type</b></td>
+<td><b>ctype</b></td>
+<td><b>imtype</b></td>
+<td><b>imtype out</b></td>
+<td><b>cstype</b></td>
+</tr>
+
+<tr>
+<td>void *VOID_INT_PTR</td>
+<td>void *</td>
+<td>System.IntPtr</td>
+<td>System.IntPtr</td>
+<td>System.IntPtr</td>
+</tr>
+
+</table>
+
+<p>
+This is achieved by applying them like any other named typemaps:
 </p>
 
 
@@ -574,7 +921,7 @@
 </pre>
 </div>
 
-<H2><a name="CSharp_arrays">22.4 C# Arrays</a></H2>
+<H2><a name="CSharp_arrays">23.4 C# Arrays</a></H2>
 
 
 <p>
@@ -586,7 +933,7 @@
 pinned arrays.
 </p>
 
-<H3><a name="CSharp_arrays_swig_library">22.4.1 The SWIG C arrays library</a></H3>
+<H3><a name="CSharp_arrays_swig_library">23.4.1 The SWIG C arrays library</a></H3>
 
 
 <p>
@@ -623,7 +970,7 @@
 </div>
 
 
-<H3><a name="CSharp_arrays_pinvoke_default_array_marshalling">22.4.2 Managed arrays using P/Invoke default array marshalling</a></H3>
+<H3><a name="CSharp_arrays_pinvoke_default_array_marshalling">23.4.2 Managed arrays using P/Invoke default array marshalling</a></H3>
 
 
 <p>
@@ -750,7 +1097,7 @@
 </div>
 
 
-<H3><a name="CSharp_arrays_pinning">22.4.3 Managed arrays using pinning</a></H3>
+<H3><a name="CSharp_arrays_pinning">23.4.3 Managed arrays using pinning</a></H3>
 
 
 <p>
@@ -845,7 +1192,7 @@
 
 
 
-<H2><a name="CSharp_exceptions">22.5 C# Exceptions</a></H2>
+<H2><a name="CSharp_exceptions">23.5 C# Exceptions</a></H2>
 
 
 <p>
@@ -942,7 +1289,7 @@
 </p>
 
 
-<H3><a name="CSharp_exception_example_check_typemap">22.5.1 C# exception example using "check" typemap</a></H3>
+<H3><a name="CSharp_exception_example_check_typemap">23.5.1 C# exception example using "check" typemap</a></H3>
 
 
 <p>
@@ -1124,7 +1471,7 @@
 Actually it will issue this warning for any function beginning with <tt>SWIG_CSharpSetPendingException</tt>.
 </P>
 
-<H3><a name="CSharp_exception_example_percent_exception">22.5.2 C# exception example using %exception</a></H3>
+<H3><a name="CSharp_exception_example_percent_exception">23.5.2 C# exception example using %exception</a></H3>
 
 
 <p>
@@ -1189,7 +1536,7 @@
 </pre>
 </div>
 
-<H3><a name="CSharp_exception_example_exception_specifications">22.5.3 C# exception example using exception specifications</a></H3>
+<H3><a name="CSharp_exception_example_exception_specifications">23.5.3 C# exception example using exception specifications</a></H3>
 
 
 <p>
@@ -1245,7 +1592,7 @@
 Multiple catch handlers are generated should there be more than one exception specifications declared.
 </p>
 
-<H3><a name="CSharp_custom_application_exception">22.5.4 Custom C# ApplicationException example</a></H3>
+<H3><a name="CSharp_custom_application_exception">23.5.4 Custom C# ApplicationException example</a></H3>
 
 
 <p>
@@ -1379,7 +1726,7 @@
 </pre>
 </div>
 
-<H2><a name="CSharp_directors">22.6 C# Directors</a></H2>
+<H2><a name="CSharp_directors">23.6 C# Directors</a></H2>
 
 
 <p>
@@ -1392,7 +1739,7 @@
 However, the <a href="Java.html#Java_directors">Java directors</a> section should also be read in order to gain more insight into directors.
 </p>
 
-<H3><a name="CSharp_directors_example">22.6.1 Directors example</a></H3>
+<H3><a name="CSharp_directors_example">23.6.1 Directors example</a></H3>
 
 
 <p>
@@ -1460,7 +1807,7 @@
 {
   public override uint UIntMethod(uint x)
   {
-    Console.WriteLine("CSharpDerived - UIntMethod({0})", x);
+    global::System.Console.WriteLine("CSharpDerived - UIntMethod({0})", x);
     return x;
   }
 }
@@ -1513,7 +1860,7 @@
 </pre>
 </div>
 
-<H3><a name="CSharp_directors_implementation">22.6.2 Directors implementation</a></H3>
+<H3><a name="CSharp_directors_implementation">23.6.2 Directors implementation</a></H3>
 
 
 <p>
@@ -1721,7 +2068,7 @@
 </pre>
 </div>
 
-<H3><a name="CSharp_director_caveats">22.6.3 Director caveats</a></H3>
+<H3><a name="CSharp_director_caveats">23.6.3 Director caveats</a></H3>
 
 
 <p>
@@ -1769,7 +2116,7 @@
 should pass the call on to <tt>CSharpDefaults.DefaultMethod(int)</tt>using the C++ default value, as shown above.
 </p>
 
-<H2><a name="CSharp_multiple_modules">22.7 Multiple modules</a></H2>
+<H2><a name="CSharp_multiple_modules">23.7 Multiple modules</a></H2>
 
 
 <p>
@@ -1804,7 +2151,96 @@
 if you don't want users to easily stumble upon these so called 'internal workings' of the wrappers.
 </p>
 
-<H2><a name="CSharp_typemap_examples">22.8 C# Typemap examples</a></H2>
+
+<H2><a name="CSharp_named_arguments">23.8 C# named and optional arguments</a></H2>
+
+
+<p>
+  In C++ you can specify default arguments for functions, methods, and constructors.  C# offers named arguments.  This feature, specific to C#, lets you bind default argument functions with default arguments in C#.  SWIG also allows you to add default arguments to C# functions which don't have default arguments in C++.
+</p>
+
+<p>
+The <tt>cs:defaultargs</tt> feature enables C# named arguments with C# default values.
+Using this feature will turn off SWIG's default handling for default arguments, which would create an override for each defaulted argument.
+</p>
+
+<p>For this feature, you first specify the function/method/constructor you want it to impact.  Inside the feature
+  call you specify each argument you want to override.  If you specify none, it will take the literal text from c++
+  for each argument and apply that in C#.  That often works fine, but when it doesn't you can supply a string literal
+  with a C# expression to be used as an override.  Or you can supply an int literal, or a float literal.  If you want to give a literal
+  string you need to include an escaped quote at the start and end of the literal such as  <tt>"\"a string\""</tt>.
+</p>
+
+<p>
+Let's consider an example:
+</p>
+
+<div class="code">
+  <pre>
+    %feature("cs:defaultargs") Foo::Foo;
+    %feature("cs:defaultargs", x=0, z=4) Foo::bar;
+    %feature("cs:defaultargs", x="\"five\"") Foo::zoo;
+
+    %inline %{
+    class Foo {
+    public:
+        Foo(int a, int b=1, int c=2)
+        {
+        }
+        int bar(int x, int y=2, int z=3)
+        {
+            return x+y+z;
+        }
+        int bat(int x=1, int y=2, int z=3)
+        {
+            return x+y+z;
+        }
+        int zoo(std::string x="four")
+        {
+            return (int)x.size();
+        }
+    };
+    %}
+  </pre>
+</div>
+
+<p>
+The generated C# proxy class contains:
+</p>
+
+<div class="code">
+<pre>
+public class Foo : global::System.IDisposable {
+  ...
+  public Foo(int a, int b=1, int c=2) ...
+
+  public int bar(int x=0, int y=2, int z=4) ...
+
+  public int bat(int x, int y, int z) ...
+  public int bat(int x, int y) ...
+  public int bat(int x) ...
+  public int bat() ...
+
+  public int zoo(string x="five") ...
+}
+</pre>
+</div>
+
+<p>
+Note that:
+</p>
+<ol>
+<li> The constructor uses the default arguments exactly as taken from C++.  </li>
+<li> The <tt>bar</tt> method uses the default arguments exactly as taken from C++ apart from <tt>z</tt> whose default value is changed to 4, and <tt>x</tt> did not have a default value in C++, but does in the generated C#.</li>
+<li> The <tt>bat</tt> method does not use the <tt>cs:defaultargs</tt> feature and so the default handling of one overloaded C# method per defaulted C++ argument is generated.</li>
+<li> The <tt>zoo</tt> method's string value is overridden by the new string value from the feature. </li>
+</ol>
+
+<p>
+<b>Compatibility Note:</b> SWIG-4.2.0 added support for the <tt>cs:defaultargs</tt> feature.
+</p>
+
+<H2><a name="CSharp_typemap_examples">23.9 C# Typemap examples</a></H2>
 
 
 This section includes a few examples of typemaps.  For more examples, you
@@ -1812,7 +2248,7 @@
 the SWIG library.
 
 
-<H3><a name="CSharp_memory_management_member_variables">22.8.1 Memory management when returning references to member variables</a></H3>
+<H3><a name="CSharp_memory_management_member_variables">23.9.1 Memory management when returning references to member variables</a></H3>
 
 
 <p>
@@ -1848,7 +2284,7 @@
 <div class="code">
 <pre>
   Wheel wheel = new Bike(10).getWheel();
-  Console.WriteLine("wheel size: " + wheel.size);
+  global::System.Console.WriteLine("wheel size: " + wheel.size);
   // Simulate a garbage collection
   global::System.GC.Collect();
   global::System.GC.WaitForPendingFinalizers();
@@ -1936,7 +2372,7 @@
 Note the <tt>addReference</tt> call.
 </p>
 
-<H3><a name="CSharp_memory_management_objects">22.8.2 Memory management for objects passed to the C++ layer</a></H3>
+<H3><a name="CSharp_memory_management_objects">23.9.2 Memory management for objects passed to the C++ layer</a></H3>
 
 
 <p>
@@ -1997,7 +2433,7 @@
   Container container = new Container();
   Element element = new Element(20);
   container.setElement(element);
-  Console.WriteLine("element.value: " + container.getElement().value);
+  global::System.Console.WriteLine("element.value: " + container.getElement().value);
   // Simulate a garbage collection
   global::System.GC.Collect();
   global::System.GC.WaitForPendingFinalizers();
@@ -2068,7 +2504,7 @@
 </div>
 
 
-<H3><a name="CSharp_date_marshalling">22.8.3 Date marshalling using the csin typemap and associated attributes</a></H3>
+<H3><a name="CSharp_date_marshalling">23.9.3 Date marshalling using the csin typemap and associated attributes</a></H3>
 
 
 <p>
@@ -2354,7 +2790,7 @@
 </pre>
 </div>
 
-<H3><a name="CSharp_date_properties">22.8.4 A date example demonstrating marshalling of C# properties</a></H3>
+<H3><a name="CSharp_date_properties">23.9.4 A date example demonstrating marshalling of C# properties</a></H3>
 
 
 <p>
@@ -2454,7 +2890,7 @@
   <li>The 'csin' typemap has 'pre', 'post' and 'cshin' attributes, and these are all ignored in the property set. The code in these attributes must instead be replicated within the 'csvarin' typemap. The line creating the <tt>temp$csinput</tt> variable is such an example; it is identical to what is in the 'pre' attribute.
 </ul>
 
-<H3><a name="CSharp_date_pre_post_directors">22.8.5 Date example demonstrating the 'pre' and 'post' typemap attributes for directors</a></H3>
+<H3><a name="CSharp_date_pre_post_directors">23.9.5 Date example demonstrating the 'pre' and 'post' typemap attributes for directors</a></H3>
 
 
 <p>
@@ -2516,7 +2952,7 @@
 </p>
 
 
-<H3><a name="CSharp_partial_classes">22.8.6 Turning proxy classes into partial classes</a></H3>
+<H3><a name="CSharp_partial_classes">23.9.6 Turning proxy classes into partial classes</a></H3>
 
 
 <p>
@@ -2616,7 +3052,7 @@
 The following example is an alternative approach to adding managed code to the generated proxy class.
 </p>
 
-<H3><a name="CSharp_sealed_proxy_class">22.8.7 Turning proxy classes into sealed classes</a></H3>
+<H3><a name="CSharp_sealed_proxy_class">23.9.7 Turning proxy classes into sealed classes</a></H3>
 
 
 <p>
@@ -2706,7 +3142,7 @@
 'csbody' typemap code in csharp.swg by modifying swigCMemOwn to not be protected.
 </p>
 
-<H3><a name="CSharp_extending_proxy_class">22.8.8 Extending proxy classes with additional C# code</a></H3>
+<H3><a name="CSharp_extending_proxy_class">23.9.8 Extending proxy classes with additional C# code</a></H3>
 
 
 <p>
@@ -2745,11 +3181,12 @@
 </pre>
 </div>
 
-<H3><a name="CSharp_enum_underlying_type">22.8.9 Underlying type for enums</a></H3>
+<H3><a name="CSharp_enum_underlying_type">23.9.9 Underlying type for enums</a></H3>
 
 
 <P>
-C# enums use int as the underlying type for each enum item.
+C# enums use int as the underlying type for each enum item, unless there is a C++11 enum base specifying the underlying C++ enum type.
+If there is a C++ base enum then this is automatically converted to the equivalent C# integral type.
 If you wish to change the underlying type to something else, then use the <tt>csbase</tt> typemap.
 For example when your C++ code uses a value larger than int, this is necessary as the C# compiler will not compile values which are too large to fit into an int.
 Here is an example:
@@ -2768,7 +3205,7 @@
 The generated enum will then use the given underlying type and compile correctly:
 </p>
 
-<div class="code">
+<div class="targetlang">
 <pre>
 public enum BigNumbers : uint {
   big = 0x80000000,
@@ -2777,6 +3214,58 @@
 </pre>
 </div>
 
+<p>
+If a C++11 enum base is specified, such as <tt>unsigned short</tt> in the following:
+</p>
+
+<div class="code">
+<pre>
+%inline %{
+  enum SmallNumbers : unsigned short { tiny, small=1  };
+%}
+</pre>
+</div>
+
+<p>
+The underlying type is automatically converted to the C# equivalent, <tt>ushort</tt>:
+</p>
+
+<div class="targetlang">
+<pre>
+public enum SmallNumbers : ushort {
+  tiny,
+  small = 1
+}
+</pre>
+</div>
+
+<p>
+The underlying C# type can still be changed to something else using the csbase typemap but the <tt>replace</tt> attribute must be set to avoid an ignored warnings as there are effectively two specified bases, which of course is not possible. For example:
+</p>
+
+<div class="code">
+<pre>
+%typemap(csbase, replace="1") SmallNumbers "byte"
+%inline %{
+  enum SmallNumbers : unsigned short { tiny, small=1  };
+%}
+</pre>
+</div>
+
+<p>
+which generates the desired underlying enum type:
+</p>
+
+<div class="targetlang">
+<pre>
+public enum SmallNumbers : byte {
+  tiny,
+  small = 1
+}
+</pre>
+</div>
+
+
 </body>
 </html>
 
diff --git a/Doc/Manual/Chicken.html b/Doc/Manual/Chicken.html
deleted file mode 100644
index 3a80811..0000000
--- a/Doc/Manual/Chicken.html
+++ /dev/null
@@ -1,597 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-<title>SWIG and Chicken</title>
-<link rel="stylesheet" type="text/css" href="style.css">
-<meta http-equiv="content-type" content="text/html; charset=UTF-8">
-</head>
-
-<body bgcolor="#ffffff">
-
-<H1><a name="Chicken">23 SWIG and Chicken</a></H1>
-<!-- INDEX -->
-<div class="sectiontoc">
-<ul>
-<li><a href="#Chicken_nn2">Preliminaries</a>
-<ul>
-<li><a href="#Chicken_nn3">Running SWIG in C mode</a>
-<li><a href="#Chicken_nn4">Running SWIG in C++ mode</a>
-</ul>
-<li><a href="#Chicken_nn5">Code Generation</a>
-<ul>
-<li><a href="#Chicken_nn6">Naming Conventions</a>
-<li><a href="#Chicken_nn7">Modules</a>
-<li><a href="#Chicken_nn8">Constants and Variables</a>
-<li><a href="#Chicken_nn9">Functions</a>
-<li><a href="#Chicken_nn10">Exceptions</a>
-</ul>
-<li><a href="#Chicken_nn11">TinyCLOS</a>
-<li><a href="#Chicken_nn12">Linkage</a>
-<ul>
-<li><a href="#Chicken_nn13">Static binary or shared library linked at compile time</a>
-<li><a href="#Chicken_nn14">Building chicken extension libraries</a>
-<li><a href="#Chicken_nn15">Linking multiple SWIG modules with TinyCLOS</a>
-</ul>
-<li><a href="#Chicken_nn16">Typemaps</a>
-<li><a href="#Chicken_nn17">Pointers</a>
-<ul>
-<li><a href="#Chicken_collection">Garbage collection</a>
-</ul>
-<li><a href="#Chicken_nn18">Unsupported features and known problems</a>
-<ul>
-<li><a href="#Chicken_nn19">TinyCLOS problems with Chicken version &lt;= 1.92</a>
-</ul>
-</ul>
-</div>
-<!-- INDEX -->
-
-
-
-    <p>
-      This chapter describes SWIG's support of CHICKEN.  CHICKEN is a
-      Scheme-to-C compiler supporting most of the language features as
-      defined in the <i>Revised^5 Report on Scheme</i>.  Its main
-      attributes are that it
-    </p>
-
-      <ol>
-        <li>generates portable C code</li>
-        <li>includes a customizable interpreter</li>
-        <li>links to C libraries with a simple Foreign Function Interface</li>
-        <li>supports full tail-recursion and first-class continuations</li>
-      </ol>
-
-    <p>
-      When confronted with a large C library, CHICKEN users can use
-      SWIG to generate CHICKEN wrappers for the C library.  However,
-      the real advantages of using SWIG with CHICKEN are its
-      <strong>support for C++</strong> -- object-oriented code is
-      difficult to wrap by hand in CHICKEN -- and its <strong>typed
-      pointer representation</strong>, essential for C and C++
-      libraries involving structures or classes.
-
-    </p>
-
-<H2><a name="Chicken_nn2">23.1 Preliminaries</a></H2>
-
-
-    <p>
-      CHICKEN support was introduced to SWIG in version 1.3.18.  SWIG
-      relies on some recent additions to CHICKEN, which are only
-      present in releases of CHICKEN with version number
-      <strong>greater than or equal to 1.89</strong>.  
-      To use a chicken version between 1.40 and 1.89, see the <a href="#Chicken_collection">Garbage collection</a>
-      section below.
-    </p>
-
-      <p>
-      You may want to look at any of the examples in Examples/chicken/
-      directory for the basic steps to run SWIG CHICKEN.
-      </p>
-
-<H3><a name="Chicken_nn3">23.1.1 Running SWIG in C mode</a></H3>
-
-
-      <p>
-      To run SWIG CHICKEN in C mode, use
-      the -chicken option.
-      </p>
-
-      <div class="shell">
-        <pre>% swig -chicken example.i</pre>
-      </div>
-
-      <p>
-      To allow the wrapper to take advantage of future CHICKEN code
-      generation improvements, part of the wrapper is direct CHICKEN
-      function calls (<tt>example_wrap.c</tt>) and part is CHICKEN
-      Scheme (<tt>example.scm</tt>).  The basic Scheme code must
-      be compiled to C using your system's CHICKEN compiler or
-      both files can be compiled directly using the much simpler <tt>csc</tt>.
-      </p>
-
-      <div class="shell">
-<pre>
-% chicken example.scm -output-file oexample.c
-</pre>
-      </div>
-
-      <p>
-      So for the C mode of SWIG CHICKEN, <tt>example_wrap.c</tt> and
-      <tt>oexample.c</tt> are the files that must be compiled to
-      object files and linked into your project.
-      </p>
-
-<H3><a name="Chicken_nn4">23.1.2 Running SWIG in C++ mode</a></H3>
-
-
-      <p>
-      To run SWIG CHICKEN in C++ mode, use
-      the -chicken -c++ option.
-      </p>
-
-      <div class="shell">
-        <pre>% swig -chicken -c++ example.i</pre>
-      </div>
-
-      <p>
-      This will generate <tt>example_wrap.cxx</tt> and
-      <tt>example.scm</tt>.  The basic Scheme code must be
-      compiled to C using your system's CHICKEN compiler or
-      both files can be compiled directly using the much simpler <tt>csc</tt>.
-      </p>
-
-      <div class="shell">
-        <pre>% chicken example.scm -output-file oexample.c</pre>
-      </div>
-
-      <p>
-      So for the C++ mode of SWIG CHICKEN, <tt>example_wrap.cxx</tt>
-      and <tt>oexample.c</tt> are the files that must be compiled to
-      object files and linked into your project.
-      </p>
-
-<H2><a name="Chicken_nn5">23.2 Code Generation</a></H2>
-
-
-<H3><a name="Chicken_nn6">23.2.1 Naming Conventions</a></H3>
-
-
-    <p>
-      Given a C variable, function or constant declaration named
-      <tt>Foo_Bar</tt>, the declaration will be available
-      in CHICKEN as an identifier ending with
-      <tt>Foo-Bar</tt>.  That is, an underscore is converted
-      to a dash.
-    </p>
-
-    <p>
-      You may control what the CHICKEN identifier will be by using the
-      <tt>%rename</tt> SWIG directive in the SWIG interface file.
-    </p>
-
-<H3><a name="Chicken_nn7">23.2.2 Modules</a></H3>
-
-
-      <p>
-      The name of the module must be declared one of two ways:
-      <ul>
-        <li>Placing <tt>%module example</tt> in the SWIG interface
-        file.</li>
-        <li>Using <tt>-module example</tt> on the SWIG command
-        line.</li>
-      </ul>
-
-      <p>
-      The generated example.scm file then exports <code>(declare (unit modulename))</code>.
-      If you do not want SWIG to export the <code>(declare (unit modulename))</code>, pass
-      the -nounit option to SWIG.
-
-    <p>
-      CHICKEN will be able to access the module using the <code>(declare
-        (uses <i>modulename</i>))</code> CHICKEN Scheme form.
-    </p>
-
-<H3><a name="Chicken_nn8">23.2.3 Constants and Variables</a></H3>
-
-
-    <p>
-      Constants may be created using any of the four constructs in
-      the interface file:
-    </p>
-      <ol>
-        <li><code>#define MYCONSTANT1 ...</code></li>
-        <li><code>%constant int MYCONSTANT2 = ...</code></li>
-        <li><code>const int MYCONSTANT3 = ...</code></li>
-        <li><code>enum { MYCONSTANT4  = ... };</code></li>
-      </ol>
-
-    <p>
-      In all cases, the constants may be accessed from within CHICKEN
-      using the form <tt>(MYCONSTANT1)</tt>; that is, the constants
-      may be accessed using the read-only parameter form.
-    </p>
-
-    <p>
-      Variables are accessed using the full parameter form.
-      For example, to set the C variable "int my_variable;", use the
-      Scheme form <tt>(my-variable 2345)</tt>.  To get the C variable,
-      use <tt>(my-variable)</tt>.
-    </p>
-
-    <p>
-      The <tt>%feature("constasvar")</tt> can be applied to any constant
-      or immutable variable.  Instead of exporting the constant as
-      a function that must be called, the constant will appear as a
-      scheme variable.  This causes the generated .scm file to just contain the code
-      <tt>(set! MYCONSTANT1 (MYCONSTANT1))</tt>. See 
-      <a href="Customization.html#Customization_features">Features and the %feature directive</a>
-      for info on how to apply the %feature.
-    </p>
-
-<H3><a name="Chicken_nn9">23.2.4 Functions</a></H3>
-
-
-    <p>
-      C functions declared in the SWIG interface file will have
-      corresponding CHICKEN Scheme procedures.  For example, the C
-      function "int sqrt(double x);" will be available using the
-      Scheme form <tt>(sqrt 2345.0)</tt>.  A <code>void</code> return
-      value will give C_SCHEME_UNDEFINED as a result.
-    </p>
-    <p>
-      A function may return more than one value by using the
-      <code>OUTPUT</code> specifier (see Lib/chicken/typemaps.i).
-      They will be returned as multiple values using <code>(values)</code> if there is more than one
-      result (that is, a non-void return value and at least one argout
-      parameter, or a void return value and at least two argout
-      parameters).  The return values can then be accessed with <code>(call-with-values)</code>.
-    </p>
-
-<H3><a name="Chicken_nn10">23.2.5 Exceptions</a></H3>
-
-
-     <p>The SWIG chicken module has support for exceptions thrown from
-     C or C++ code to be caught in scheme.  
-     See <a href="Customization.html#Customization_exception">Exception handling with %exception</a>
-     for more information about declaring exceptions in the interface file.
-     </p>
-
-     <p>Chicken supports both the <code>SWIG_exception(int code, const char *msg)</code> interface
-     as well as a <code>SWIG_ThrowException(C_word val)</code> function for throwing exceptions from
-     inside the %exception blocks.  <code>SWIG_exception</code> will throw a list consisting of the code
-     (as an integer) and the message.  Both of these will throw an exception using <code>(abort)</code>,
-     which can be handled by <code>(handle-exceptions)</code>.  See
-     the Chicken manual on Exceptions
-     and <a href="http://srfi.schemers.org/srfi-12/srfi-12.html">SFRI-12</a>.  Since the exception values are thrown
-     directly, if <code>(condition-case)</code> is used to catch an exception the exception will come through in the <code>val ()</code> case.
-     </p>
-
-     <p>The following simple module</p>
-     
-<div class="code"><pre>
-%module exception_test
-
-%inline %{
-  void test_throw(int i) throws (int) { 
-    if (i == 1) throw 15; 
-  }
-%}
-</pre></div>
-
-     <p>could be run with</p>
-
-<div class="targetlang"><pre>
-(handle-exceptions exvar 
-  (if (= exvar 15)
-    (print "Correct!") 
-    (print "Threw something else " exvar))
-  (test-throw 1))
-</pre></div>
-
-
-<H2><a name="Chicken_nn11">23.3 TinyCLOS</a></H2>
-
-
-      <p>
-      The author of TinyCLOS, Gregor Kiczales, describes TinyCLOS as:
-      "Tiny CLOS is a Scheme implementation of a 'kernelized' CLOS, with a
-      metaobject protocol. The implementation is even simpler than
-      the simple CLOS found in 'The Art of the Metaobject Protocol',
-      weighing in at around 850 lines of code, including (some)
-      comments and documentation."
-      </p>
-
-      <p>
-      Almost all good Scheme books describe how to use metaobjects and
-      generic procedures to implement an object-oriented Scheme
-      system.  Please consult a Scheme book if you are unfamiliar
-      with the concept.
-      </p>
-
-      <p>
-
-      CHICKEN has a modified version of TinyCLOS, which SWIG CHICKEN
-      uses if the -proxy argument is given.  If -proxy is passed, then
-      the generated example.scm file will contain TinyCLOS class definitions.
-      A class named Foo is declared as &lt;Foo&gt;, and each member variable
-      is allocated a slot.  Member functions are exported as generic functions.
-
-      <p>
-      
-      Primitive symbols and functions (the interface that would be presented if
-      -proxy was not passed) are hidden and no longer accessible.  If the -unhideprimitive
-      command line argument is passed to SWIG, then the primitive symbols will be
-      available, but each will be prefixed by the string "primitive:"
-
-      <p>
-
-      The exported symbol names can be controlled with the -closprefix and -useclassprefix arguments.
-      If -useclassprefix is passed to SWIG, every member function will be generated with the class name
-      as a prefix.  If the -closprefix mymod: argument is passed to SWIG, then the exported functions will
-      be prefixed by the string "mymod:".  If -useclassprefix is passed, -closprefix is ignored.
-      
-      </p>
-
-<H2><a name="Chicken_nn12">23.4 Linkage</a></H2>
-
-
-    <p>
-      Please refer to <em>CHICKEN - A practical and portable Scheme
-      system - User's manual</em> for detailed help on how to link
-      object files to create a CHICKEN Scheme program.  Briefly, to
-      link object files, be sure to add <tt>`chicken-config
-      -extra-libs -libs`</tt> or <tt>`chicken-config -shared
-      -extra-libs -libs`</tt>to your linker options.  Use the
-      <tt>-shared</tt> option if you want to create a dynamically
-      loadable module.  You might also want to use the much simpler
-      <tt>csc</tt> or <tt>csc.bat</tt>.
-    </p>
-
-    <p>Each scheme file that is generated
-   by SWIG contains <code>(declare (uses <i>modname</i>))</code>.  This means that to load the
-   module from scheme code, the code must include <code>(declare (uses <i>modname</i>))</code>.
-   </p>
-
-
-<H3><a name="Chicken_nn13">23.4.1 Static binary or shared library linked at compile time</a></H3>
-
-
-   <p>We can easily use csc to build a static binary.</p>
-
-<div class="shell">
-<pre>
-$ swig -chicken example.i
-$ csc -v example.scm example_impl.c example_wrap.c test_script.scm -o example
-$ ./example
-</pre>
-</div>
-
-<p>Similar to the above, any number of <tt>module.scm</tt> files could be compiled
-into a shared library, and then that shared library linked when compiling the
-main application.</p>
-
-<div class="shell">
-<pre>
-$ swig -chicken example.i
-$ csc -sv example.scm example_wrap.c example_impl.c -o example.so
-</pre>
-</div>
-
-<p>The <tt>example.so</tt> file can then linked with <tt>test_script.scm</tt> when it
-is compiled, in which case <tt>test_script.scm</tt> must have <code>(declare (uses example))</code>.
-Multiple SWIG modules could have been linked into <tt>example.so</tt> and each
-one accessed with a <code>(declare (uses ... ))</code>.
-</p>
-
-<div class="shell">
-<pre>
-$ csc -v test_script.scm -lexample
-</pre>
-</div>
-
-<p>An alternative is that the test_script.scm can have the code <code>(load-library 'example "example.so")</code>,
-in which case the test script does not need to be linked with example.so.  The test_script.scm file can then
-be run with <tt>csi</tt>.
-</p>
-
-<H3><a name="Chicken_nn14">23.4.2 Building chicken extension libraries</a></H3>
-
-
-<p>Building a shared library like in the above section only works if the library
-is linked at compile time with a script containing <code>(declare (uses ...))</code> or is
-loaded explicitly with <code>(load-library 'example "example.so")</code>. It is
-not the format that CHICKEN expects for extension libraries and eggs.  The problem is the
-<code>(declare (unit <i>modname</i>))</code> inside the <tt>modname.scm</tt> file.  There are
-two possible solutions to this.</p>
-
-<p>First, SWIG accepts a <tt>-nounit</tt> argument, in which case the <code>(declare (unit <i>modname</i>))</code>
-is not generated.  Then, the <tt>modname.scm</tt> and <tt>modname_wrap.c</tt> files <b>must</b> be compiled into
-their own shared library.</p>
-
-<div class="shell">
-<pre>
-$ csc -sv modname.scm modname_wrap.c modname_impl.c -o modname.so
-</pre>
-</div>
-
-<p>This library can then be loaded by scheme code with the <code>(require 'modname)</code> function.
-See the
-Loading-extension-libraries in the eval unit inside the CHICKEN manual for more information.</p>
-
-<p>Another alternative is to run SWIG normally and create a scheme file that contains <code>(declare (uses <i>modname</i>))</code>
-and then compile that file into the shared library as well.  For example, inside the <tt>mod_load.scm</tt> file,</p>
-
-<div class="targetlang">
-<pre>
-(declare (uses mod1))
-(declare (uses mod2))
-</pre>
-</div>
-
-<p>Which would then be compiled with</p>
-
-<div class="shell">
-<pre>
-$ swig -chicken mod1.i
-$ swig -chicken mod2.i
-$ csc -sv mod_load.scm mod1.scm mod2.scm mod1_wrap.c mod2_wrap.c mod1_impl.c mod2_impl.c -o mod.so
-</pre>
-</div>
-
-<p>Then the extension library can be loaded with <code>(require 'mod)</code>.  As we can see here,
-<tt>mod_load.scm</tt> contains the code that gets executed when the module is loaded.  All this code
-does is load both mod1 and mod2.  As we can see, this technique is more useful when you want to
-combine a few SWIG modules into one chicken extension library, especially if modules are related by
-<code>%import</code></p>
-
-<p>In either method, the files that are compiled into the shared library could also be
-packaged into an egg.  The <tt>mod1_wrap.c</tt> and <tt>mod2_wrap.c</tt> files that are created by SWIG
-are stand alone and do not need SWIG to be installed to be compiled.  Thus the egg could be
-distributed and used by anyone, even if SWIG is not installed.</p>
-
-<p>See the <tt>Examples/chicken/egg</tt> directory in the SWIG source for an example that builds
-two eggs, one using the first method and one using the second method.</p>
-
-<H3><a name="Chicken_nn15">23.4.3 Linking multiple SWIG modules with TinyCLOS</a></H3>
-
-
-<p>Linking together multiple modules that share type information using the <code>%import</code>
-directive while also using <tt>-proxy</tt> is more complicated.  For example, if <tt>mod2.i</tt> imports <tt>mod1.i</tt>, then the
-<tt>mod2.scm</tt> file contains references to symbols declared in <tt>mod1.scm</tt>,
-and thus a <code>(declare (uses <i>mod1</i>))</code> or <code>(require '<i>mod1</i>)</code> must be exported
-to the top of <tt>mod2.scm</tt>.  By default, when SWIG encounters an <code>%import "modname.i"</code> directive,
-it exports <code>(declare (uses <i>modname</i>))</code> into the scm file.  This works fine unless mod1 was compiled with
-the <tt>-nounit</tt> argument or was compiled into an extension library with other modules under a different name.</p>
-
-<p>One option is to override the automatic generation of <code>(declare (uses mod1))</code>
-by passing the <tt>-noclosuses</tt> option to SWIG when compiling <tt>mod2.i</tt>.
-SWIG then provides the <code>%insert(closprefix) %{ %}</code> directive.  Any scheme code inside that directive is inserted into the
-generated .scm file, and if <tt>mod1</tt> was compiled with <tt>-nounit</tt>, the directive should contain <code>(require 'mod1)</code>.
-This option allows for mixed loading as well, where some modules are imported with <code>(declare (uses <i>modname</i>))</code>
-(which means they were compiled without -nounit) and some are imported with <code>(require 'modname)</code>.</p>
-
-<p>The other option is to use the second idea in the above section.  Compile all the modules normally, without any
-<code>%insert(closprefix)</code>, <tt>-nounit</tt>, or <tt>-noclosuses</tt>.  Then the modules will import each other correctly
-with <code>(declare (uses ...))</code>.
-To create an extension library or an egg, just create a <tt>module_load.scm</tt> file that <code>(declare (uses ...))</code>
-all the modules.</p>
-
-<H2><a name="Chicken_nn16">23.5 Typemaps</a></H2>
-
-
-    <p>
-      The Chicken module handles all types via typemaps. This information is
-      read from <code>Lib/chicken/typemaps.i</code> and
-      <code>Lib/chicken/chicken.swg</code>.
-    </p>
-
-<H2><a name="Chicken_nn17">23.6 Pointers</a></H2>
-
-
-    <p>
-      For pointer types, SWIG uses CHICKEN tagged pointers.
-
-      A tagged pointer is an ordinary CHICKEN pointer with an
-      extra slot for a void *.  With SWIG
-      CHICKEN, this void * is a pointer to a type-info
-      structure.  So each pointer used as input or output from
-      the SWIG-generated CHICKEN wrappers will have type
-      information attached to it.  This will let the wrappers
-      correctly determine which method should be called
-      according to the object type hierarchy exposed in the SWIG
-      interface files.
-    </p>
-    <p>
-      To construct a Scheme object from a C pointer, the wrapper code
-      calls the function 
-      <code>SWIG_NewPointerObj(void *ptr, swig_type_info *type, int owner)</code>,
-      The function that calls <code>SWIG_NewPointerObj</code> must have a variable declared
-      <code>C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);</code>
-      It is ok to call <code>SWIG_NewPointerObj</code> more than once, 
-      just make sure known_space has enough space for all the created pointers.
-    </p>
-    <p>
-      To get the pointer represented by a CHICKEN tagged pointer, the
-      wrapper code calls the function 
-      <code>SWIG_ConvertPtr(C_word s, void **result, swig_type_info *type, int flags)</code>,
-      passing a pointer to a struct representing the expected pointer
-      type. flags is either zero or SWIG_POINTER_DISOWN (see below).
-    </p>
-
-<H3><a name="Chicken_collection">23.6.1 Garbage collection</a></H3>
-
-
-  <p>If the owner flag passed to <code>SWIG_NewPointerObj</code> is 1, <code>NewPointerObj</code> will add a
-     finalizer to the type which will call the destructor or delete method of
-     that type.  The destructor and delete functions are no longer exported for
-     use in scheme code, instead SWIG and chicken manage pointers.
-  In situations where SWIG knows that a function is returning a type that should
-  be garbage collected, SWIG will automatically set the owner flag to 1.  For other functions,
-  the <code>%newobject</code> directive must be specified for functions whose return values
-  should be garbage collected.  See 
-  <a href="Customization.html#Customization_ownership">Object ownership and %newobject</a> for more information.
-  </p>
-
-  <p>In situations where a C or C++ function will assume ownership of a pointer, and thus
-  chicken should no longer garbage collect it, SWIG provides the <code>DISOWN</code> input typemap.
-  After applying this typemap (see the <a href="Typemaps.html#Typemaps">Typemaps chapter</a> for more information on how to apply typemaps),
-  any pointer that gets passed in will no longer be garbage collected.  
-  An object is disowned by passing the <code>SWIG_POINTER_DISOWN</code> flag to <code>SWIG_ConvertPtr</code>.
-  <b>Warning:</b> Since the lifetime of the object is now controlled by the underlying code, the object might
-  get deleted while the scheme code still holds a pointer to it.  Further use of this pointer
-  can lead to a crash.
-  </p>
-
-  <p>Adding a finalizer function from C code was added to chicken in the 1.89 release, so garbage collection
-  does not work for chicken versions below 1.89.  If you would like the SWIG generated code to work with
-  chicken 1.40 to 1.89, pass the <code>-nocollection</code> argument to SWIG.  This will not export code
-  inside the _wrap.c file to register finalizers, and will then export destructor functions which
-  must be called manually.
-  </p>
-
-<H2><a name="Chicken_nn18">23.7 Unsupported features and known problems</a></H2>
-
-
-    <ul>
-      <li>No director support.</li>
-      <li>No support for c++ standard types like std::vector.</li>
-      <li>The TinyCLOS wrappers for overloaded functions will not work correctly when using 
-          <a href="SWIGPlus.html#SWIGPlus_default_args">%feature(compactdefaultargs)</a>.</li>
-    </ul>
-
-<H3><a name="Chicken_nn19">23.7.1 TinyCLOS problems with Chicken version &lt;= 1.92</a></H3>
-
-
-    <p>In Chicken versions equal to or below 1.92, TinyCLOS has a limitation such that generic methods do not properly work on methods
-    with different number of specializers: TinyCLOS assumes that every method added to a generic function
-    will have the same number of specializers. SWIG generates functions with different lengths of specializers
-    when C/C++ functions are overloaded.  For example, the code</p>
-
-<div class="code">
-<pre>
-class Foo {};
-int foo(int a, Foo *b);
-int foo(int a);
-</pre></div>
-
-<p>will produce scheme code</p>
-
-<div class="targetlang">
-<pre>
-(define-method (foo (arg0 &lt;top&gt;) (arg1 &lt;Foo&gt;)) (<i>call primitive function</i>))
-(define-method (foo (arg0 &lt;top&gt;)) (<i>call primitive function</i>))
-</pre></div>
-
-<p>Using unpatched TinyCLOS, the second <code>(define-method)</code> will replace the first one,
-so calling <code>(foo 3 f)</code> will produce an error.</p>
-
-<p>There are three solutions to this.  The easist is to upgrade to the latest Chicken version.  Otherwise, the
-file <tt>Lib/chicken/tinyclos-multi-generic.patch</tt> in the SWIG source contains a patch against
-tinyclos.scm inside the 1.92 chicken source to add support into TinyCLOS for multi-argument generics.  (This patch was accepted into Chicken)
-This requires chicken to be rebuilt and custom install of chicken.  An alternative is the <tt>Lib/chicken/multi-generic.scm</tt>
-file in the SWIG source.  This file can be loaded after TinyCLOS is loaded, and it will override some functions
-inside TinyCLOS to correctly support multi-argument generics.  Please see the comments at the top of both files for more information.</p>
-
-  </body>
-</html>
diff --git a/Doc/Manual/Contents.html b/Doc/Manual/Contents.html
index 57aef5b..4aef597 100644
--- a/Doc/Manual/Contents.html
+++ b/Doc/Manual/Contents.html
@@ -91,16 +91,16 @@
 </ul>
 <li><a href="Windows.html#Windows_other_compilers">Instructions for using the Examples with other compilers</a>
 </ul>
-<li><a href="Windows.html#Windows_cygwin_mingw">SWIG on Cygwin and MinGW</a>
-<ul>
 <li><a href="Windows.html#Windows_swig_exe">Building swig.exe on Windows</a>
 <ul>
+<li><a href="Windows.html#Windows_cmake">Building swig.exe using CMake</a>
+<li><a href="Windows.html#Windows_msys2">Building swig.exe using MSYS2</a>
 <li><a href="Windows.html#Windows_mingw_msys">Building swig.exe using MinGW and MSYS</a>
 <li><a href="Windows.html#Windows_cygwin">Building swig.exe using Cygwin</a>
-<li><a href="Windows.html#Windows_building_alternatives">Building swig.exe alternatives</a>
-</ul>
+<ul>
 <li><a href="Windows.html#Windows_examples_cygwin">Running the examples on Windows using Cygwin</a>
 </ul>
+</ul>
 <li><a href="Windows.html#Windows_interface_file">Microsoft extensions and other Windows quirks</a>
 </ul>
 </div>
@@ -171,6 +171,7 @@
 <li><a href="SWIG.html#SWIG_rename_ignore">Renaming and ignoring declarations</a>
 <ul>
 <li><a href="SWIG.html#SWIG_nn29">Simple renaming of specific identifiers</a>
+<li><a href="SWIG.html#SWIG_ignore">Ignoring identifiers</a>
 <li><a href="SWIG.html#SWIG_advanced_renaming">Advanced renaming support</a>
 <li><a href="SWIG.html#SWIG_limiting_renaming">Limiting global renaming rules</a>
 <li><a href="SWIG.html#SWIG_chosen_unignore">Ignoring everything then wrapping a few selected symbols</a>
@@ -236,6 +237,12 @@
 <li><a href="SWIGPlus.html#SWIGPlus_nn15">Protection</a>
 <li><a href="SWIGPlus.html#SWIGPlus_nn16">Enums and constants</a>
 <li><a href="SWIGPlus.html#SWIGPlus_nn17">Friends</a>
+<ul>
+<li><a href="SWIGPlus.html#SWIGPlus_friend_classes">Friend classes</a>
+<li><a href="SWIGPlus.html#SWIGPlus_friend_function_definitions">Friend function definitions</a>
+<li><a href="SWIGPlus.html#SWIGPlus_friend_function_declarations">Friend function declarations</a>
+<li><a href="SWIGPlus.html#SWIGPlus_friends_unqualified">Unqualified friend functions</a>
+</ul>
 <li><a href="SWIGPlus.html#SWIGPlus_nn18">References and pointers</a>
 <li><a href="SWIGPlus.html#SWIGPlus_nn19">Pass and return by value</a>
 <li><a href="SWIGPlus.html#SWIGPlus_nn20">Inheritance</a>
@@ -250,12 +257,16 @@
 </ul>
 <li><a href="SWIGPlus.html#SWIGPlus_nn28">Overloaded operators</a>
 <li><a href="SWIGPlus.html#SWIGPlus_class_extension">Class extension</a>
+<ul>
+<li><a href="SWIGPlus.html#SWIGPlus_replacing_methods">Replacing class methods</a>
+</ul>
 <li><a href="SWIGPlus.html#SWIGPlus_nn30">Templates</a>
 <ul>
 <li><a href="SWIGPlus.html#SWIGPlus_template_directive">The %template directive</a>
 <li><a href="SWIGPlus.html#SWIGPlus_template_functions">Function templates</a>
 <li><a href="SWIGPlus.html#SWIGPlus_template_classes">Default template arguments</a>
 <li><a href="SWIGPlus.html#SWIGPlus_template_class_inheritance">Template base classes</a>
+<li><a href="SWIGPlus.html#SWIGPlus_template_empty">Empty template instantiation</a>
 <li><a href="SWIGPlus.html#SWIGPlus_template_specialization">Template specialization</a>
 <li><a href="SWIGPlus.html#SWIGPlus_template_member">Member templates</a>
 <li><a href="SWIGPlus.html#SWIGPlus_template_scoping">Scoping and templates</a>
@@ -293,6 +304,11 @@
 <li><a href="CPlusPlus11.html#CPlusPlus11_core_language_changes">Core language changes</a>
 <ul>
 <li><a href="CPlusPlus11.html#CPlusPlus11_rvalue_reference_and_move_semantics">Rvalue reference and move semantics</a>
+<ul>
+<li><a href="CPlusPlus11.html#CPlusPlus11_rvalue_reference_inputs">Rvalue reference inputs</a>
+<li><a href="CPlusPlus11.html#CPlusPlus11_rvalue_reference_outputs">Rvalue reference outputs</a>
+<li><a href="CPlusPlus11.html#CPlusPlus11_move_only">Movable and move-only types by value</a>
+</ul>
 <li><a href="CPlusPlus11.html#CPlusPlus11_generalized_constant_expressions">Generalized constant expressions</a>
 <li><a href="CPlusPlus11.html#CPlusPlus11_extern_template">Extern template</a>
 <li><a href="CPlusPlus11.html#CPlusPlus11_initializer_lists">Initializer lists</a>
@@ -349,6 +365,7 @@
 <li><a href="CPlusPlus14.html#CPlusPlus14_core_language_changes">Core language changes</a>
 <ul>
 <li><a href="CPlusPlus14.html#CPlusPlus14_binary_literals">Binary integer literals</a>
+<li><a href="CPlusPlus14.html#CPlusPlus14_return_type_deduction">Return type deduction</a>
 </ul>
 <li><a href="CPlusPlus14.html#CPlusPlus14_standard_library_changes">Standard library changes</a>
 </ul>
@@ -372,7 +389,24 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Preprocessor.html#Preprocessor">10 Preprocessing</a></h3>
+<h3><a href="CPlusPlus20.html#CPlusPlus20">10 SWIG and C++20</a></h3>
+
+<!-- INDEX -->
+<div class="sectiontoc">
+<ul>
+<li><a href="CPlusPlus20.html#CPlusPlus20_introduction">Introduction</a>
+<li><a href="CPlusPlus20.html#CPlusPlus20_core_language_changes">Core language changes</a>
+<ul>
+<li><a href="CPlusPlus20.html#CPlusPlus20_spaceship_operator">Spaceship operator</a>
+<li><a href="CPlusPlus20.html#CPlusPlus20_lambda_templates">Lambda templates</a>
+<li><a href="CPlusPlus20.html#CPlusPlus20_constexpr_destructors">Constexpr destructors</a>
+</ul>
+<li><a href="CPlusPlus20.html#CPlusPlus20_standard_library_changes">Standard library changes</a>
+</ul>
+</div>
+<!-- INDEX -->
+
+<h3><a href="Preprocessor.html#Preprocessor">11 Preprocessing</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -395,7 +429,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Library.html#Library">11 SWIG library</a></h3>
+<h3><a href="Library.html#Library">12 SWIG library</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -403,6 +437,7 @@
 <li><a href="Library.html#Library_nn2">The %include directive and library search path</a>
 <li><a href="Library.html#Library_nn3">C arrays and pointers</a>
 <ul>
+<li><a href="Library.html#Library_argcargv">argcargv.i</a>
 <li><a href="Library.html#Library_nn4">cpointer.i</a>
 <li><a href="Library.html#Library_carrays">carrays.i</a>
 <li><a href="Library.html#Library_nn6">cmalloc.i</a>
@@ -418,6 +453,7 @@
 <li><a href="Library.html#Library_stl_cpp_library">STL/C++ library</a>
 <ul>
 <li><a href="Library.html#Library_std_string">std::string</a>
+<li><a href="Library.html#Library_std_string_view">std::string_view</a>
 <li><a href="Library.html#Library_std_vector">std::vector</a>
 <li><a href="Library.html#Library_stl_exceptions">STL exceptions</a>
 <li><a href="Library.html#Library_std_shared_ptr">shared_ptr smart pointer</a>
@@ -428,17 +464,22 @@
 <li><a href="Library.html#Library_shared_ptr_templates">shared_ptr and templates</a>
 <li><a href="Library.html#Library_shared_ptr_directors">shared_ptr and directors</a>
 </ul>
+<li><a href="Library.html#Library_std_unique_ptr">unique_ptr smart pointer</a>
 <li><a href="Library.html#Library_std_auto_ptr">auto_ptr smart pointer</a>
 </ul>
 <li><a href="Library.html#Library_nn16">Utility Libraries</a>
 <ul>
 <li><a href="Library.html#Library_nn17">exception.i</a>
+<li><a href="Library.html#Library_attributes">attribute.i</a>
+<ul>
+<li><a href="Library.html#Library_attribute_templates">%attribute and C++ templates</a>
+</ul>
 </ul>
 </ul>
 </div>
 <!-- INDEX -->
 
-<h3><a href="Arguments.html#Arguments">12 Argument Handling</a></h3>
+<h3><a href="Arguments.html#Arguments">13 Argument Handling</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -461,7 +502,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Typemaps.html#Typemaps">13 Typemaps</a></h3>
+<h3><a href="Typemaps.html#Typemaps">14 Typemaps</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -503,6 +544,7 @@
 <ul>
 <li><a href="Typemaps.html#Typemaps_special_macro_descriptor">$descriptor(type)</a>
 <li><a href="Typemaps.html#Typemaps_special_macro_typemap">$typemap(method, typepattern)</a>
+<li><a href="Typemaps.html#Typemaps_special_macro_typemap_attribute">$typemap(method:attribute, typepattern)</a>
 </ul>
 <li><a href="Typemaps.html#Typemaps_special_variable_attributes">Special variables and typemap attributes</a>
 <li><a href="Typemaps.html#Typemaps_special_variables_and_macros">Special variables combined with special variable macros</a>
@@ -555,7 +597,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Customization.html#Customization">14 Customization Features</a></h3>
+<h3><a href="Customization.html#Customization">15 Customization Features</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -583,7 +625,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Contract.html#Contract">15 Contracts</a></h3>
+<h3><a href="Contract.html#Contract">16 Contracts</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -596,7 +638,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Varargs.html#Varargs">16 Variable Length Arguments</a></h3>
+<h3><a href="Varargs.html#Varargs">17 Variable Length Arguments</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -614,7 +656,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Doxygen.html#Doxygen">17 SWIG and Doxygen Translation</a></h3>
+<h3><a href="Doxygen.html#Doxygen">18 SWIG and Doxygen Translation</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -662,7 +704,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Warnings.html#Warnings">18 Warning Messages</a></h3>
+<h3><a href="Warnings.html#Warnings">19 Warning Messages</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -691,7 +733,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Modules.html#Modules">19 Working with Modules</a></h3>
+<h3><a href="Modules.html#Modules">20 Working with Modules</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -707,7 +749,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="CCache.html#CCache">20 Using SWIG with ccache - ccache-swig(1) manpage</a></h3>
+<h3><a href="CCache.html#CCache">21 Using SWIG with ccache - ccache-swig(1) manpage</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -733,7 +775,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Android.html#Android">21 SWIG and Android</a></h3>
+<h3><a href="Android.html#Android">22 SWIG and Android</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -751,7 +793,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="CSharp.html#CSharp">22 SWIG and C#</a></h3>
+<h3><a href="CSharp.html#CSharp">23 SWIG and C#</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -762,7 +804,12 @@
 <li><a href="CSharp.html#CSharp_commandline">Additional command line options</a>
 </ul>
 <li><a href="CSharp.html#CSharp_differences_java">Differences to the Java module</a>
+<li><a href="CSharp.html#CSharp_type_mapping">Type mapping</a>
+<ul>
+<li><a href="CSharp.html#CSharp_primitive_types">Primitive types</a>
+<li><a href="CSharp.html#CSharp_other_type_mappings">Other types</a>
 <li><a href="CSharp.html#CSharp_void_pointers">Void pointers</a>
+</ul>
 <li><a href="CSharp.html#CSharp_arrays">C# Arrays</a>
 <ul>
 <li><a href="CSharp.html#CSharp_arrays_swig_library">The SWIG C arrays library</a>
@@ -783,6 +830,7 @@
 <li><a href="CSharp.html#CSharp_director_caveats">Director caveats</a>
 </ul>
 <li><a href="CSharp.html#CSharp_multiple_modules">Multiple modules</a>
+<li><a href="CSharp.html#CSharp_named_arguments">C# named and optional arguments</a>
 <li><a href="CSharp.html#CSharp_typemap_examples">C# Typemap examples</a>
 <ul>
 <li><a href="CSharp.html#CSharp_memory_management_member_variables">Memory management when returning references to member variables</a>
@@ -799,7 +847,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="D.html#D">23 SWIG and D</a></h3>
+<h3><a href="D.html#D">24 SWIG and D</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -816,7 +864,11 @@
 <li><a href="D.html#D_code_injection_typemaps">Code injection typemaps</a>
 <li><a href="D.html#D_special_variables">Special variable macros</a>
 </ul>
+<li><a href="D.html#D_other_code_control">Other D code control features</a>
+<ul>
+<li><a href="D.html#D_module">D begin</a>
 <li><a href="D.html#D_features">D and %feature</a>
+</ul>
 <li><a href="D.html#D_pragmas">Pragmas</a>
 <li><a href="D.html#D_exceptions">D Exceptions</a>
 <li><a href="D.html#D_directors">D Directors</a>
@@ -833,7 +885,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Go.html#Go">24 SWIG and Go</a></h3>
+<h3><a href="Go.html#Go">25 SWIG and Go</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -857,6 +909,8 @@
 <li><a href="Go.html#Go_class_inheritance">Go Class Inheritance</a>
 </ul>
 <li><a href="Go.html#Go_templates">Go Templates</a>
+<li><a href="Go.html#Go_threads">Go and C/C++ Threads</a>
+<li><a href="Go.html#Go_exceptions">Go and C++ Exceptions</a>
 <li><a href="Go.html#Go_director_classes">Go Director Classes</a>
 <ul>
 <li><a href="Go.html#Go_director_example_cpp_code">Example C++ code</a>
@@ -877,7 +931,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Guile.html#Guile">25 SWIG and Guile</a></h3>
+<h3><a href="Guile.html#Guile">26 SWIG and Guile</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -913,7 +967,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Java.html#Java">26 SWIG and Java</a></h3>
+<h3><a href="Java.html#Java">27 SWIG and Java</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -1014,6 +1068,7 @@
 <li><a href="Java.html#Java_proxycode">Class extension with %proxycode</a>
 <li><a href="Java.html#Java_exception_handling">Exception handling with %exception and %javaexception</a>
 <li><a href="Java.html#Java_method_access">Method access with %javamethodmodifiers</a>
+<li><a href="Java.html#Java_begin">Java begin</a>
 </ul>
 <li><a href="Java.html#Java_tips_techniques">Tips and techniques</a>
 <ul>
@@ -1067,7 +1122,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Javascript.html#Javascript">27 SWIG and Javascript</a></h3>
+<h3><a href="Javascript.html#Javascript">28 SWIG and Javascript</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -1083,6 +1138,7 @@
 <ul>
 <li><a href="Javascript.html#Javascript_node_extensions">Creating node.js Extensions</a>
 <ul>
+<li><a href="Javascript.html#Javascript_using_yeoman">Using <code>yeoman</code> to generate a Node-API skeleton</a>
 <li><a href="Javascript.html#Javascript_troubleshooting">Troubleshooting</a>
 </ul>
 <li><a href="Javascript.html#Javascript_embedded_webkit">Embedded Webkit</a>
@@ -1104,12 +1160,13 @@
 <li><a href="Javascript.html#Javascript_emitter">Emitter</a>
 <li><a href="Javascript.html#Javascript_emitter_states">Emitter states</a>
 <li><a href="Javascript.html#Javascript_jsc_exceptions">Handling Exceptions in JavascriptCore</a>
+<li><a href="Javascript.html#Javascript_napi_exceptions">Handling Exceptions in Node-API</a>
 </ul>
 </ul>
 </div>
 <!-- INDEX -->
 
-<h3><a href="Lua.html#Lua">28 SWIG and Lua</a></h3>
+<h3><a href="Lua.html#Lua">29 SWIG and Lua</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -1177,7 +1234,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Octave.html#Octave">29 SWIG and Octave</a></h3>
+<h3><a href="Octave.html#Octave">30 SWIG and Octave</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -1217,7 +1274,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Perl5.html#Perl5">30 SWIG and Perl5</a></h3>
+<h3><a href="Perl5.html#Perl5">31 SWIG and Perl5</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -1293,7 +1350,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Php.html#Php">31 SWIG and PHP</a></h3>
+<h3><a href="Php.html#Php">32 SWIG and PHP</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -1317,6 +1374,7 @@
 <li><a href="Php.html#Php_nn2_6_3">Static Member Variables</a>
 <li><a href="Php.html#Php_nn2_6_4">Static Member Functions</a>
 <li><a href="Php.html#Php_nn2_6_5">Specifying Implemented Interfaces</a>
+<li><a href="Php.html#Php_nn2_6_6">Dynamic Properties</a>
 </ul>
 <li><a href="Php.html#Php_nn2_7">PHP Pragmas, Startup and Shutdown code</a>
 </ul>
@@ -1334,7 +1392,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Python.html#Python">32 SWIG and Python</a></h3>
+<h3><a href="Python.html#Python">33 SWIG and Python</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -1393,6 +1451,7 @@
 <li><a href="Python.html#Python_nn37">Overhead and code bloat</a>
 <li><a href="Python.html#Python_nn38">Typemaps</a>
 <li><a href="Python.html#Python_nn39">Miscellaneous</a>
+<li><a href="Python.html#Python_stable_abi">Stable ABI</a>
 </ul>
 <li><a href="Python.html#Python_nn40">Common customization features</a>
 <ul>
@@ -1422,7 +1481,7 @@
 </ul>
 <li><a href="Python.html#Python_nn58">Typemap Examples</a>
 <ul>
-<li><a href="Python.html#Python_nn59">Converting  Python list to a char ** </a>
+<li><a href="Python.html#Python_nn59">Converting a Python list to a char ** </a>
 <li><a href="Python.html#Python_nn60">Expanding a Python object into multiple arguments</a>
 <li><a href="Python.html#Python_nn61">Using typemaps to return arguments</a>
 <li><a href="Python.html#Python_nn62">Mapping Python tuples into small arrays</a>
@@ -1442,6 +1501,7 @@
 <li><a href="Python.html#Python_nn70">%feature("autodoc", "docstring")</a>
 </ul>
 <li><a href="Python.html#Python_nn71">%feature("docstring")</a>
+<li><a href="Python.html#Python_doxygen_docstrings">Doxygen comments</a>
 </ul>
 <li><a href="Python.html#Python_nn72">Python Packages</a>
 <ul>
@@ -1461,7 +1521,10 @@
 </ul>
 <li><a href="Python.html#Python_python3support">Python 3 Support</a>
 <ul>
-<li><a href="Python.html#Python_nn74">Function annotation</a>
+<li><a href="Python.html#Python_annotations">Python function annotations and variable annotations</a>
+<ul>
+<li><a href="Python.html#Python_annotations_c">C/C++ annotation types</a>
+</ul>
 <li><a href="Python.html#Python_nn75">Buffer interface</a>
 <li><a href="Python.html#Python_nn76">Abstract base classes</a>
 <li><a href="Python.html#Python_nn77">Byte string output conversion</a>
@@ -1476,7 +1539,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="R.html#R">33 SWIG and R</a></h3>
+<h3><a href="R.html#R">34 SWIG and R</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -1487,12 +1550,15 @@
 <li><a href="R.html#R_nn5">General policy</a>
 <li><a href="R.html#R_language_conventions">Language conventions</a>
 <li><a href="R.html#R_nn6">C++ classes</a>
+<ul>
+<li><a href="R.html#R_class_examples">Examples</a>
+</ul>
 <li><a href="R.html#R_nn7">Enumerations</a>
 </ul>
 </div>
 <!-- INDEX -->
 
-<h3><a href="Ruby.html#Ruby">34 SWIG and Ruby</a></h3>
+<h3><a href="Ruby.html#Ruby">35 SWIG and Ruby</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -1630,7 +1696,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Scilab.html#Scilab">35 SWIG and Scilab</a></h3>
+<h3><a href="Scilab.html#Scilab">36 SWIG and Scilab</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -1693,13 +1759,14 @@
 <ul>
 <li><a href="Scilab.html#Scilab_generated_scripts_builder_script">Builder script</a>
 <li><a href="Scilab.html#Scilab_generated_scripts_loader_script">Loader script</a>
+<li><a href="Scilab.html#Scilab_generated_scripts_gateway">Gateway XML files</a>
 </ul>
 <li><a href="Scilab.html#Scilab_other_resources">Other resources</a>
 </ul>
 </div>
 <!-- INDEX -->
 
-<h3><a href="Tcl.html#Tcl">36 SWIG and Tcl</a></h3>
+<h3><a href="Tcl.html#Tcl">37 SWIG and Tcl</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -1765,7 +1832,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Mzscheme.html#Mzscheme">37 SWIG and MzScheme/Racket</a></h3>
+<h3><a href="Mzscheme.html#Mzscheme">38 SWIG and MzScheme/Racket</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -1777,7 +1844,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Ocaml.html#Ocaml">38 SWIG and OCaml</a></h3>
+<h3><a href="Ocaml.html#Ocaml">39 SWIG and OCaml</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
@@ -1832,7 +1899,7 @@
 </div>
 <!-- INDEX -->
 
-<h3><a href="Extending.html#Extending">39 Extending SWIG to support new languages</a></h3>
+<h3><a href="Extending.html#Extending">40 Extending SWIG to support new languages</a></h3>
 
 <!-- INDEX -->
 <div class="sectiontoc">
diff --git a/Doc/Manual/Contract.html b/Doc/Manual/Contract.html
index 93fb8c0..f7acbba 100644
--- a/Doc/Manual/Contract.html
+++ b/Doc/Manual/Contract.html
@@ -7,7 +7,7 @@
 </head>
 
 <body bgcolor="#ffffff">
-<H1><a name="Contract">15 Contracts</a></H1>
+<H1><a name="Contract">16 Contracts</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -39,7 +39,7 @@
 generated rather than having the program continue to execute.
 </p>
 
-<H2><a name="Contract_nn2">15.1 The %contract directive</a></H2>
+<H2><a name="Contract_nn2">16.1 The %contract directive</a></H2>
 
 
 <p>
@@ -95,7 +95,7 @@
 </pre>
 </div>
 
-<H2><a name="Contract_nn3">15.2 %contract and classes</a></H2>
+<H2><a name="Contract_nn3">16.2 %contract and classes</a></H2>
 
 
 <p>
@@ -174,7 +174,7 @@
 this means that both the arguments to <tt>Spam::bar</tt> must be positive.
 </p>
 
-<H2><a name="Contract_nn4">15.3 Constant aggregation and %aggregate_check</a></H2>
+<H2><a name="Contract_nn4">16.3 Constant aggregation and %aggregate_check</a></H2>
 
 
 <p>
@@ -263,7 +263,7 @@
 release.
 </p>
 
-<H2><a name="Contract_nn5">15.4 Notes</a></H2>
+<H2><a name="Contract_nn5">16.4 Notes</a></H2>
 
 
 <p>
diff --git a/Doc/Manual/Customization.html b/Doc/Manual/Customization.html
index 328bc23..ac0969f 100644
--- a/Doc/Manual/Customization.html
+++ b/Doc/Manual/Customization.html
@@ -7,7 +7,7 @@
 </head>
 
 <body bgcolor="#ffffff">
-<H1><a name="Customization">14 Customization Features</a></H1>
+<H1><a name="Customization">15 Customization Features</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -46,7 +46,7 @@
 customization mechanism known as "features" is described.
 </p>
 
-<H2><a name="Customization_exception">14.1 Exception handling with %exception</a></H2>
+<H2><a name="Customization_exception">15.1 Exception handling with %exception</a></H2>
 
 
 <p>
@@ -95,13 +95,7 @@
 %exception;   // Deletes any previously defined handler
 </pre></div>
 
-<p>
-<b>Compatibility note:</b>  Previous versions of SWIG used a special directive <tt>%except</tt>
-for exception handling.   That directive is deprecated--<tt>%exception</tt>
-provides the same functionality, but is substantially more flexible.
-</p>
-
-<H3><a name="Customization_nn3">14.1.1 Handling exceptions in C code</a></H3>
+<H3><a name="Customization_nn3">15.1.1 Handling exceptions in C code</a></H3>
 
 
 <p>
@@ -169,7 +163,7 @@
 and for Perl it is the <tt>croak</tt> method shown above.
 </p>
 
-<H3><a name="Customization_nn4">14.1.2 Exception handling with longjmp()</a></H3>
+<H3><a name="Customization_nn4">15.1.2 Exception handling with longjmp()</a></H3>
 
 
 <p>
@@ -245,7 +239,7 @@
 modify it to handle nested <tt>try</tt> declarations.
 </p>
 
-<H3><a name="Customization_nn5">14.1.3 Handling C++ exceptions</a></H3>
+<H3><a name="Customization_nn5">15.1.3 Handling C++ exceptions</a></H3>
 
 
 <p>
@@ -280,7 +274,7 @@
 </pre>
 </div>
 
-<H3><a name="Customization_allowexcept">14.1.4 Exception handlers for variables</a></H3>
+<H3><a name="Customization_allowexcept">15.1.4 Exception handlers for variables</a></H3>
 
 
 <p>
@@ -305,7 +299,7 @@
 </pre>
 </div>
 
-<H3><a name="Customization_nn6">14.1.5 Defining different exception handlers</a></H3>
+<H3><a name="Customization_nn6">15.1.5 Defining different exception handlers</a></H3>
 
 
 <p>
@@ -432,17 +426,7 @@
 </pre>
 </div>
 
-<p>
-<b>Compatibility note:</b> The <tt>%exception</tt> directive replaces
-the functionality provided by the deprecated "except" typemap.
-The typemap would allow exceptions to be thrown in the target 
-language based on the return type of a function and 
-was intended to be a mechanism for pinpointing specific
-declarations.  However, it never really worked that well and the new
-%exception directive is much better.
-</p>
-
-<H3><a name="Customization_exception_special_variables">14.1.6 Special variables for %exception</a></H3>
+<H3><a name="Customization_exception_special_variables">15.1.6 Special variables for %exception</a></H3>
 
 
 <p>
@@ -545,7 +529,7 @@
 </pre></div>
 
 
-<H3><a name="Customization_nn7">14.1.7 Using The SWIG exception library</a></H3>
+<H3><a name="Customization_nn7">15.1.7 Using The SWIG exception library</a></H3>
 
 
 <p>
@@ -600,7 +584,7 @@
 The <tt>SWIG_exception()</tt> function can also be used in typemaps.
 </p>
 
-<H2><a name="Customization_ownership">14.2 Object ownership and %newobject</a></H2>
+<H2><a name="Customization_ownership">15.2 Object ownership and %newobject</a></H2>
 
 
 <p>
@@ -668,7 +652,7 @@
 
 <div class="code">
 <pre>
-%typemap(newfree) char * "free($1);";
+%typemap(newfree) char * "free($1);"
 ...
 %newobject strdup;
 ...
@@ -727,37 +711,7 @@
 <a href="SWIGPlus.html#SWIGPlus_ref_unref">C++ reference counted objects</a> section.
 </p>
 
-<p>
-<b>Compatibility note:</b>  Previous versions of SWIG had a special <tt>%new</tt> directive.  However, unlike <tt>%newobject</tt>,
-it only applied to the next declaration.  For example:
-</p>
-
-<div class="code">
-<pre>
-%new char *strdup(const char *s);
-</pre>
-</div>
-
-<p>
-For now this is still supported but is deprecated.  
-</p>
-
-<p>
-<b>How to shoot yourself in the foot:</b>  The <tt>%newobject</tt> directive is not a declaration modifier like the old
-<tt>%new</tt> directive.   Don't write code like this:
-</p>
-
-<div class="code">
-<pre>
-%newobject
-char *strdup(const char *s);
-</pre>
-</div>
-<p>
-The results might not be what you expect.
-</p>
-
-<H2><a name="Customization_features">14.3 Features and the %feature directive</a></H2>
+<H2><a name="Customization_features">15.3 Features and the %feature directive</a></H2>
 
 
 <p>
@@ -839,7 +793,7 @@
 The syntax in the first variation will generate the <tt>{ }</tt> delimiters used whereas the other variations will not.
 </p>
 
-<H3><a name="Customization_feature_attributes">14.3.1 Feature attributes</a></H3>
+<H3><a name="Customization_feature_attributes">15.3.1 Feature attributes</a></H3>
 
 
 <p>
@@ -880,7 +834,7 @@
 Further details can be obtained from the <a href="Java.html#Java_exception_handling">Java exception handling</a> section.
 </p>
 
-<H3><a name="Customization_feature_flags">14.3.2 Feature flags</a></H3>
+<H3><a name="Customization_feature_flags">15.3.2 Feature flags</a></H3>
 
 
 <p>
@@ -978,7 +932,7 @@
 The concept of clearing features is discussed next.
 </p>
 
-<H3><a name="Customization_clearing_features">14.3.3 Clearing features</a></H3>
+<H3><a name="Customization_clearing_features">15.3.3 Clearing features</a></H3>
 
 
 <p>
@@ -1071,7 +1025,7 @@
 </pre>
 </div>
 
-<H3><a name="Customization_features_default_args">14.3.4 Features and default arguments</a></H3>
+<H3><a name="Customization_features_default_args">15.3.4 Features and default arguments</a></H3>
 
 
 <p>
@@ -1146,7 +1100,7 @@
 in SWIG-1.3.23 when the approach to wrapping methods with default arguments was changed.
 </p>
 
-<H3><a name="Customization_features_example">14.3.5 Feature example</a></H3>
+<H3><a name="Customization_features_example">15.3.5 Feature example</a></H3>
 
 
 <p>
diff --git a/Doc/Manual/D.html b/Doc/Manual/D.html
index d97267a..17757e3 100644
--- a/Doc/Manual/D.html
+++ b/Doc/Manual/D.html
@@ -6,7 +6,7 @@
 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 </head>
 <body bgcolor="#FFFFFF">
-<H1><a name="D">23 SWIG and D</a></H1>
+<H1><a name="D">24 SWIG and D</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -22,7 +22,11 @@
 <li><a href="#D_code_injection_typemaps">Code injection typemaps</a>
 <li><a href="#D_special_variables">Special variable macros</a>
 </ul>
+<li><a href="#D_other_code_control">Other D code control features</a>
+<ul>
+<li><a href="#D_module">D begin</a>
 <li><a href="#D_features">D and %feature</a>
+</ul>
 <li><a href="#D_pragmas">Pragmas</a>
 <li><a href="#D_exceptions">D Exceptions</a>
 <li><a href="#D_directors">D Directors</a>
@@ -41,19 +45,19 @@
 
 
 
-<H2><a name="D_introduction">23.1 Introduction</a></H2>
+<H2><a name="D_introduction">24.1 Introduction</a></H2>
 
 
-<p>From the <a href="http://www.digitalmars.com/d/">D Programming Language</a> web site: <em>D is a systems programming language. Its focus is on combining the power and high performance of C and C++ with the programmer productivity of modern languages like Ruby and Python. [...] The D language is statically typed and compiles directly to machine code.</em> As such, it is not very surprising that D is able to directly <a href="http://www.digitalmars.com/d/1.0/interfaceToC.html">interface with C libraries</a>. Why would a SWIG module for D be needed then in the first place?</p>
+<p>From the <a href="https://www.digitalmars.com/d/">D Programming Language</a> web site: <em>D is a systems programming language. Its focus is on combining the power and high performance of C and C++ with the programmer productivity of modern languages like Ruby and Python. [...] The D language is statically typed and compiles directly to machine code.</em> As such, it is not very surprising that D is able to directly <a href="https://www.digitalmars.com/d/1.0/interfaceToC.html">interface with C libraries</a>. Why would a SWIG module for D be needed then in the first place?</p>
 
 <p>Well, besides the obvious downside that the C header files have to be manually converted to D modules for this to work, there is one major inconvenience with this approach: D code usually is on a higher abstraction level than C, and many of the features that make D interesting are simply not available when dealing with C libraries, requiring you e.g. to manually convert strings between pointers to <tt>\0</tt>-terminated char arrays and D char arrays, making the algorithms from the D2 standard library unusable with C arrays and data structures, and so on.</p>
 
-<p>While these issues can be worked around relatively easy by hand-coding a thin wrapper layer around the C library in question, there is another issue where writing wrapper code per hand is not feasible: C++ libraries. D did not support interfacing to C++ in version 1 at all, and even if <tt>extern(C++)</tt> has been added to D2, the support is still very limited, and a custom wrapper layer is still required in many cases. </p>
+<p>While these issues can be worked around relatively easy by hand-coding a thin wrapper layer around the C library in question, there is another issue where writing wrapper code per hand is not feasible: C++ libraries. Support for C++ was added in D2 via <tt>extern(C++)</tt> but this support is still very limited, and a custom wrapper layer is still required in many cases. </p>
 
 <p>To help addressing these issues, the SWIG C# module has been forked to support D. Is has evolved quite a lot since then, but there are still many similarities, so if you do not find what you are looking for on this page, it might be worth having a look at the chapter on <a href="CSharp.html#CSharp">C#</a> (and also on <a href="Java.html#Java">Java</a>, since the C# module was in turn forked from it).</p>
 
 
-<H2><a name="D_command_line_invocation">23.2 Command line invocation</a></H2>
+<H2><a name="D_command_line_invocation">24.2 Command line invocation</a></H2>
 
 
 <p>To activate the D module, pass the <tt>-d</tt> option to SWIG at the command line. The same standard command line options as with any other language module are available, plus the following D specific ones:</p>
@@ -61,7 +65,7 @@
 <dl>
   <dt><tt>-d2</tt></dt>
   <dd>
-    <p>By default, SWIG generates code for D1/Tango. Use the <tt>-d2</tt> flag to target D2/Phobos instead.</p>
+    <p>Prior to SWIG 4.2.0, SWIG generated wrappers for D1/Tango by default and <tt>-d2</tt> could be used to generate D2/Phobos wrappers instead.  SWIG 4.2.0 dropped support for D1, and D2 wrappers are now produced by default.  This option is still recognised to allow existing build systems calling SWIG to work, but is now a no-op.</p>
   </dd>
 
   <dt><a name="D_splitproxy"></a><tt>-splitproxy</tt></dt>
@@ -83,10 +87,10 @@
 </dl>
 
 
-<H2><a name="D_typemaps">23.3 Typemaps</a></H2>
+<H2><a name="D_typemaps">24.3 Typemaps</a></H2>
 
 
-<H3><a name="D_typemap_name_comparison">23.3.1 C# &lt;-&gt; D name comparison</a></H3>
+<H3><a name="D_typemap_name_comparison">24.3.1 C# &lt;-&gt; D name comparison</a></H3>
 
 
 <p>If you already know the SWIG C# module, you might find the following name comparison table useful:</p>
@@ -112,7 +116,7 @@
 </pre></div>
 
 
-<H3><a name="D_ctype_imtype_dtype">23.3.2 ctype, imtype, dtype</a></H3>
+<H3><a name="D_ctype_imtype_dtype">24.3.2 ctype, imtype, dtype</a></H3>
 
 
 <p>Mapping of types between the C/C++ library, the C/C++ library wrapper exposing the C functions, the D wrapper module importing these functions and the D proxy code.</p>
@@ -120,7 +124,7 @@
 <p>The <tt>ctype</tt> typemap is used to determine the types to use in the C wrapper functions. The types from the <tt>imtype</tt> typemap are used in the extern(C) declarations of these functions in the intermediary D module. The <tt>dtype</tt> typemap contains the D types used in the D proxy module/class.</p>
 
 
-<H3><a name="D_in_out_directorin_direcetorout">23.3.3 in, out, directorin, directorout</a></H3>
+<H3><a name="D_in_out_directorin_direcetorout">24.3.3 in, out, directorin, directorout</a></H3>
 
 
 <p>Used for converting between the types for C/C++ and D when generating the code for the wrapper functions (on the C++ side).</p>
@@ -130,7 +134,7 @@
 <p>The <tt>directorin</tt> typemap is used to convert parameters to the type used in the D director callback function, its return value is processed by <tt>directorout</tt> (see below).</p>
 
 
-<H3><a name="D_din_dout_ddirectorin_ddirectorout">23.3.4 din, dout, ddirectorin, ddirectorout</a></H3>
+<H3><a name="D_din_dout_ddirectorin_ddirectorout">24.3.4 din, dout, ddirectorin, ddirectorout</a></H3>
 
 
 <p>Typemaps for code generation in D proxy and type wrapper classes.</p>
@@ -157,13 +161,13 @@
       dtype             DClass.method(dtype a)</pre></div>
 
 
-<H3><a name="D_typecheck_typemaps">23.3.5 typecheck typemaps</a></H3>
+<H3><a name="D_typecheck_typemaps">24.3.5 typecheck typemaps</a></H3>
 
 
 <p>Because, unlike many scripting languages supported by SWIG, D does not need any dynamic dispatch helper to access an overloaded function, the purpose of these is merely to issue a warning for overloaded C++ functions that cannot be overloaded in D (as more than one C++ type maps to a single D type).</p>
 
 
-<H3><a name="D_code_injection_typemaps">23.3.6 Code injection typemaps</a></H3>
+<H3><a name="D_code_injection_typemaps">24.3.6 Code injection typemaps</a></H3>
 
 
 <p>These typemaps are used for generating the skeleton of proxy classes for C++ types.</p>
@@ -178,7 +182,7 @@
 Code can also be injected into the D proxy class using <tt>%proxycode</tt>.
 </p>
 
-<H3><a name="D_special_variables">23.3.7 Special variable macros</a></H3>
+<H3><a name="D_special_variables">24.3.7 Special variable macros</a></H3>
 
 
 <p>The standard SWIG special variables are available for use within typemaps as described in the <a href="Typemaps.html#Typemaps">Typemaps documentation</a>, for example <tt>$1</tt>, <tt>$input</tt>, <tt>$result</tt> etc.</p>
@@ -267,12 +271,18 @@
 </pre></div>
   </dd>
 
+  <dt><tt>$imfuncname</tt></dt>
+  <dd><p>
+This special variable expands to the name of the function in the intermediary class that will be used in $imcall.
+Like, $imcall, this special variable is only expanded in the "dout" typemap.
+  </p></dd>
+
   <dt><a name="D_importtype"></a><tt>$importtype(SomeDType)</tt></dt>
   <dd>
     <p>This macro is used in the <tt>dimports</tt> typemap if a dependency on another D type generated by SWIG is added by a custom typemap.</p>
     <p>Consider the following code snippet:</p>
 <div class="code"><pre>
-%typemap(dinterfaces) SomeClass "AnInterface, AnotherInterface";
+%typemap(dinterfaces) SomeClass "AnInterface, AnotherInterface"
 </pre></div>
     <p>This causes SWIG to add <tt>AnInterface</tt> and <tt>AnotherInterface</tt> to the base class list of <tt>SomeClass</tt>:</p>
 <div class="targetlang"><pre>
@@ -299,7 +309,29 @@
 </dl>
 
 
-<H2><a name="D_features">23.4 D and %feature</a></H2>
+<H2><a name="D_other_code_control">24.4 Other D code control features</a></H2>
+
+
+<H3><a name="D_module">24.4.1 D begin</a></H3>
+
+
+<p>
+It is possible to add a common comment at the start of every generated D file.
+The <tt>%module</tt> directive supports the <tt>dbegin</tt> option for this.
+The provided text is generated at the very beginning of each generated D file.
+As it is generated before the D module statement, is only really useful for adding in
+a common comment into all generated D files. For example, copyright text for each file:
+</p>
+
+
+<div class="code">
+<pre>
+%module(dbegin="/* Common comment. Copyright (C) 2000 Mr Nobody. */\n") nobodymodule
+</pre>
+</div>
+
+
+<H3><a name="D_features">24.4.2 D and %feature</a></H3>
 
 
 <p>The D module defines a number of directives which modify the <a href="Customization.html#Customization_features">SWIG features</a> set globally or for a specific declaration:</p>
@@ -308,7 +340,7 @@
 <dl>
   <dt><tt>%dmanifestconst</tt> and <tt>%dconstvalue(value)</tt></dt>
   <dd>
-    <p>Out of the box, SWIG generates accessor methods for C <tt>#defines</tt> and C++ constants. The <tt>%dmanifestconst</tt> directive enables wrapping these constants as D manifest constants (<tt>const</tt> in D1, <tt>enum</tt> in D2).</p>
+    <p>Out of the box, SWIG generates accessor methods for C <tt>#defines</tt> and C++ constants. The <tt>%dmanifestconst</tt> directive enables wrapping these constants as D manifest constants (<tt>enum</tt> in D2).</p>
     <p>For this to work, the C/C++ code for the constant value must directly compile as D code, though. If this is not the case, you can manually override the expression written to the D proxy module using the <tt>%dconstvalue</tt> directive, passing the new value as parameter.</p>
     <p>For <tt>enum</tt>s, again <tt>%dconstvalue</tt> can be used to override the value of an enum item if the initializer should not compile in D.</p>
   </dd>
@@ -329,7 +361,7 @@
 </dl>
 
 
-<H2><a name="D_pragmas">23.5 Pragmas</a></H2>
+<H2><a name="D_pragmas">24.5 Pragmas</a></H2>
 
 
 <p>There are a few SWIG pragmas specific to the D module, which you can use to influence the D code SWIG generates:</p>
@@ -368,7 +400,7 @@
 </dl>
 
 
-<H2><a name="D_exceptions">23.6 D Exceptions</a></H2>
+<H2><a name="D_exceptions">24.6 D Exceptions</a></H2>
 
 
 <p>Out of the box, C++ exceptions are fundamentally incompatible to their equivalent in the D world and cannot simply be propagated to a calling D method. There is, however, an easy way to solve this problem: Just catch the exception in the C/C++ wrapper layer, pass the contents to D, and make the wrapper code rethrow the exception in the D world.</p>
@@ -378,7 +410,7 @@
 <p>As this feature is implemented in exactly the same way it is for C#, please see the <a href="CSharp.html#CSharp_exceptions">C# documentation</a> for a more detailed explanation.</p>
 
 
-<H2><a name="D_directors">23.7 D Directors</a></H2>
+<H2><a name="D_directors">24.7 D Directors</a></H2>
 
 
 <p>When the directors feature is activated, SWIG generates extra code on both the C++ and the D side to enable cross-language polymorphism. Essentially, this means that if you subclass a proxy class in D, C++ code can access any overridden virtual methods just as if you created a derived class in C++.</p>
@@ -387,16 +419,16 @@
 </p>
 
 
-<H2><a name="D_other_features">23.8 Other features</a></H2>
+<H2><a name="D_other_features">24.8 Other features</a></H2>
 
 
-<H3><a name="D_nspace">23.8.1 Extended namespace support (nspace)</a></H3>
+<H3><a name="D_nspace">24.8.1 Extended namespace support (nspace)</a></H3>
 
 
 <p>By default, SWIG flattens all C++ namespaces into a single target language namespace, but as for Java and C#, the <a href="SWIGPlus.html#SWIGPlus_nspace"><tt>nspace</tt></a> feature is supported for D. If it is active, C++ namespaces are mapped to D packages/modules. Note, however, that like for the other languages, <em>free</em> variables and functions are not supported yet; currently, they are all allows written to the main proxy D module.</p>
 
 
-<H3><a name="D_native_pointer_support">23.8.2 Native pointer support</a></H3>
+<H3><a name="D_native_pointer_support">24.8.2 Native pointer support</a></H3>
 
 
 <p>Contrary to many of the scripting languages supported by SWIG, D fully supports C-style pointers. The D module thus includes a custom mechanism to wrap C pointers directly as D pointers where applicable, that is, if the type that is pointed to is represented the same in C and D (on the bit-level), dubbed a <em>primitive type</em> below.</p>
@@ -408,34 +440,34 @@
 <p>To determine if a type should be considered primitive, the <tt>cprimitive</tt> attribute on its <tt>dtype</tt> attribute is used. For example, the <tt>dtype</tt> typemap for <tt>float</tt> has <tt>cprimitive="1"</tt>, so the code from the <tt>nativepointer</tt> attribute is taken into account e.g. for <tt>float **</tt> or the function pointer <tt>float (*)(float *)</tt>.</p>
 
 
-<H3><a name="D_operator_overloading">23.8.3 Operator overloading</a></H3>
+<H3><a name="D_operator_overloading">24.8.3 Operator overloading</a></H3>
 
 
-<p>The D module comes with basic operator overloading support for both D1 and D2. There are, however, a few limitations arising from conceptual differences between C++ and D:</p>
+<p>The D module comes with basic operator overloading support. There are, however, a few limitations arising from conceptual differences between C++ and D:</p>
 
 <p>The first key difference is that C++ supports free functions as operators (along with argument-dependent lookup), while D requires operators to be member functions of the class they are operating on. SWIG can only automatically generate wrapping code for member function operators; if you want to use operators defined as free functions in D, you need to handle them manually.</p>
 
-<p>Another set of differences between C++ and D concerns individual operators. For example, there are quite a few operators which are overloadable in C++, but not in D, for example <tt>&amp;&amp;</tt> and <tt>||</tt>, but also <tt>!</tt>, and prefix increment/decrement operators in <a href="http://www.digitalmars.com/d/1.0/operatoroverloading.html">D1</a> resp. their postfix pendants in <a href="http://www.digitalmars.com/d/2.0/operatoroverloading.html">D2</a>.</p>
+<p>Another set of differences between C++ and D concerns individual operators. For example, there are quite a few operators which are overloadable in C++, but not in D, for example <tt>&amp;&amp;</tt> and <tt>||</tt>, but also <tt>!</tt>, and postfix increment/decrement operators (see the <a href="https://www.digitalmars.com/d/2.0/operatoroverloading.html">D documentation</a> for details).</p>
 
 <p>There are also some cases where the operators can be translated to D, but the differences in the implementation details are big enough that a rather involved scheme would be required for automatic wrapping them, which has not been implemented yet. This affects, for example, the array subscript operator, <tt>[]</tt>, in combination with assignments - while <tt>operator []</tt> in C++ simply returns a reference which is then written to, D resorts to a separate <tt>opIndexAssign</tt> method -, or implicit casting (which was introduced in D2 via <tt>alias this</tt>). Despite the lack of automatic support, manually handling these cases should be perfectly possible.</p>
 
 
-<H3><a name="D_test_suite">23.8.4 Running the test-suite</a></H3>
+<H3><a name="D_test_suite">24.8.4 Running the test-suite</a></H3>
 
 
-<p>As with any other language, the SWIG test-suite can be built for D using the <tt>*-d-test-suite</tt> targets of the top-level Makefile. By default, D1 is targeted, to build it with D2, use the optional <tt>D_VERSION</tt> variable, e.g. <tt>make check-d-test-suite D_VERSION=2</tt>.</p>
+<p>As with any other language, the SWIG test-suite can be built for D using the <tt>*-d-test-suite</tt> targets of the top-level Makefile.</p>
 
 <p>Note: If you want to use GDC on Linux or another platform which requires you to link <tt>libdl</tt> for dynamically loading the shared library, you might have to add <tt>-ldl</tt> manually to the <tt>d_compile</tt> target in <tt>Examples/Makefile</tt>, because GDC does not currently honor the <tt>pragma(lib, ...)</tt> statement.</p>
 
 
-<H2><a name="D_typemap_examples">23.9 D Typemap examples</a></H2>
+<H2><a name="D_typemap_examples">24.9 D Typemap examples</a></H2>
 
 
 <p>There are no D-specific typemap examples yet. However, with the above <a href="D.html#D_typemap_name_comparison">name comparison table</a>, you should be able to get an idea what can be done by looking at the <a href="CSharp.html#CSharp_typemap_examples">corresponding C# section</a>.</p>
 
 
 
-<H2><a name="D_planned_features">23.10 Work in progress and planned features</a></H2>
+<H2><a name="D_planned_features">24.10 Work in progress and planned features</a></H2>
 
 
 <p>There are a couple of features which are not implemented yet, but would be very useful and might be added in the near future:</p>
diff --git a/Doc/Manual/Doxygen.html b/Doc/Manual/Doxygen.html
index ff025c0..9f92db9 100644
--- a/Doc/Manual/Doxygen.html
+++ b/Doc/Manual/Doxygen.html
@@ -5,7 +5,7 @@
 <link rel="stylesheet" type="text/css" href="style.css">
 </head>
 <body bgcolor="#FFFFFF">
-<H1><a name="Doxygen">17 SWIG and Doxygen Translation</a></H1>
+<H1><a name="Doxygen">18 SWIG and Doxygen Translation</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -61,13 +61,13 @@
 supported.
 </p>
 
-<H2><a name="Doxygen_translation_overview">17.1 Doxygen translation overview</a></H2>
+<H2><a name="Doxygen_translation_overview">18.1 Doxygen translation overview</a></H2>
 
 
 <p>
 The Doxygen Translation module of SWIG adds an extra layer of
 functionality to SWIG, allowing automated translation of <a href=
-"http://www.doxygen.nl/manual/">Doxygen</a> formatted comments
+"https://www.doxygen.nl/manual/">Doxygen</a> formatted comments
 from input files into a documentation language more suited for the
 target language.  Currently this module only translates into Javadoc
 and Pydoc for the SWIG Java and Python modules.
@@ -77,20 +77,20 @@
 Code</a> proposal from Summer 2008.  
 </p>
 
-<H2><a name="Doxygen_file_preparation">17.2 Preparations</a></H2>
+<H2><a name="Doxygen_file_preparation">18.2 Preparations</a></H2>
 
 
 <p>
 To make use of the comment translation system, your documentation
 comments must be in properly formatted <a href=
-"http://www.doxygen.nl/manual/">Doxygen.</a> Doxygen comments can be
+"https://www.doxygen.nl/manual/">Doxygen.</a> Doxygen comments can be
 present in your main SWIG interface file or any header file that it
 imports.  You are advised to be validate that your comments compile
 properly with Doxygen before you try to translate them.  Doxygen
 itself is a more comprehensive tool and can provide you better feedback for
 correcting any syntax errors that may be present.  Please look at
 Doxygen's <a href=
-"http://www.doxygen.nl/manual/docblocks.html"> Documenting the
+"https://www.doxygen.nl/manual/docblocks.html"> Documenting the
 code</a> for the full comment format specifications.  However, SWIG's
 Doxygen parser will still report many errors and warnings found
 in comments (like unterminated strings or missing ending tags).
@@ -98,7 +98,7 @@
 
 <p>
 Currently, the whole subset of Doxygen comment styles is supported
-(See <a href="http://www.doxygen.nl/manual/docblocks.html">
+(See <a href="https://www.doxygen.nl/manual/docblocks.html">
 Documenting the code</a>). Here they are:
 </p>
 
@@ -117,14 +117,15 @@
 </pre></div>
 
 <p>
-Also any of the above with '&lt;' added after comment-starting symbol,
-like <i>/**&lt;, /*!&lt;, ///&lt;, </i> or <i> //!&lt;</i> will be
+Also any of the above with '<tt>&lt;</tt>' added after comment-starting symbol,
+like <tt>/**&lt;, /*!&lt;, ///&lt;, </tt> or <tt> //!&lt;</tt> will be
 treated as a post-comment and will be assigned to the code before the
 comment.
 
-Any number of '*' or '/' within a Doxygen comment is considered to be a
-separator and is not included in the final comment, so you may safely use
-comments like <i>/*********/</i> or <i>//////////</i>.
+Any number of '<tt>*</tt>' or '<tt>/</tt>' within a Doxygen comment is
+considered to be a separator and is not included in the final comment,
+so you may safely use comments like <tt>/*********/</tt>
+or <tt>//////////</tt>.
 </p>
 
 <p>
@@ -180,7 +181,7 @@
 <div class="code"><pre>
 enum E_NUMBERS
 {
-    EN_ZERO, ///&lt; The first enum item, gets zero as it's value
+    EN_ZERO, ///&lt; The first enum item, gets zero as its value
     EN_ONE, ///&lt; The second, EN_ONE=1
     EN_THREE
 };
@@ -193,7 +194,7 @@
 These structural commands are stripped out by SWIG and are not assigned to anything.
 </p>
 
-<H3><a name="Doxygen_running_swig">17.2.1 Enabling Doxygen translation</a></H3>
+<H3><a name="Doxygen_running_swig">18.2.1 Enabling Doxygen translation</a></H3>
 
 
 <p>
@@ -202,7 +203,7 @@
 do support it (currently Java and Python).
 </p>
 
-<H3><a name="Doxygen_features">17.2.2 Doxygen-specific %feature directives</a></H3>
+<H3><a name="Doxygen_features">18.2.2 Doxygen-specific %feature directives</a></H3>
 
 
 <p>
@@ -210,7 +211,7 @@
 href="Customization.html#Customization_features">%feature directives</a>:
 </p>
 
-<H4><a name="Doxygen_notranslate">17.2.2.1 doxygen:notranslate</a></H4>
+<H4><a name="Doxygen_notranslate">18.2.2.1 doxygen:notranslate</a></H4>
 
 
 <p>
@@ -222,7 +223,7 @@
 </p>
 
 
-<H4><a name="Doxygen_alias">17.2.2.2 doxygen:alias:&lt;command-name&gt;</a></H4>
+<H4><a name="Doxygen_alias">18.2.2.2 doxygen:alias:&lt;command-name&gt;</a></H4>
 
 
 <p>
@@ -269,7 +270,7 @@
 </p>
 
 
-<H4><a name="Doxygen_ignore">17.2.2.3 doxygen:ignore:&lt;command-name&gt;</a></H4>
+<H4><a name="Doxygen_ignore">18.2.2.3 doxygen:ignore:&lt;command-name&gt;</a></H4>
 
 
 <p>
@@ -297,7 +298,7 @@
 <p>
 Doxygen syntax is rather rich and, in addition to simple commands such as
 <tt>@transferfull</tt>, it is also possible to define commands with arguments.
-As explained in <a href="http://www.doxygen.nl/manual/commands.html">Doxygen documentation</a>,
+As explained in <a href="https://www.doxygen.nl/manual/commands.html">Doxygen documentation</a>,
 the arguments can have a range of a single word, everything until the end of
 line or everything until the end of the next paragraph. Currently, only the "end
 of line" case is supported using the <tt>range="line"</tt> argument of the
@@ -420,7 +421,7 @@
 </pre></div>
 
 
-<H4><a name="Doxygen_nolinktranslate">17.2.2.4 doxygen:nolinktranslate</a></H4>
+<H4><a name="Doxygen_nolinktranslate">18.2.2.4 doxygen:nolinktranslate</a></H4>
 
 
 <p>
@@ -429,7 +430,7 @@
 </p>
 
 
-<H4><a name="Doxygen_nostripparams">17.2.2.5 doxygen:nostripparams</a></H4>
+<H4><a name="Doxygen_nostripparams">18.2.2.5 doxygen:nostripparams</a></H4>
 
 
 <p>
@@ -439,14 +440,14 @@
 </p>
 
 
-<H3><a name="Doxygen_additional_options">17.2.3 Additional command line options</a></H3>
+<H3><a name="Doxygen_additional_options">18.2.3 Additional command line options</a></H3>
 
 
 <p>
 ALSO TO BE ADDED (Javadoc auto brief?)
 </p>
 
-<H2><a name="Doxygen_to_javadoc">17.3 Doxygen to Javadoc</a></H2>
+<H2><a name="Doxygen_to_javadoc">18.3 Doxygen to Javadoc</a></H2>
 
 
 <p>
@@ -455,7 +456,7 @@
 and proxy files.
 </p>
 
-<H3><a name="Doxygen_basic_example">17.3.1 Basic example</a></H3>
+<H3><a name="Doxygen_basic_example">18.3.1 Basic example</a></H3>
 
 
 <p>
@@ -562,7 +563,7 @@
 directives</a>):
 </p>
 
-<H3><a name="Doxygen_javadoc_tags">17.3.2 Javadoc tags</a></H3>
+<H3><a name="Doxygen_javadoc_tags">18.3.2 Javadoc tags</a></H3>
 
 
 <p>
@@ -606,6 +607,10 @@
 <td>translated to {@code ...}</td>
 </tr>
 <tr>
+<td>\code{&lt;ext&gt;}</td>
+<td>translated to {@code ...}; code language extension is ignored</td>
+</tr>
+<tr>
 <td>\cond</td>
 <td>translated to 'Conditional comment: &lt;condition&gt;'</td>
 </tr>
@@ -683,7 +688,7 @@
 </tr>
 <tr>
 <td>\n</td>
-<td>replaced with new line char</td>
+<td>replaced with newline char</td>
 </tr>
 <tr>
 <td>\note</td>
@@ -706,6 +711,10 @@
 <td>translated to @param</td>
 </tr>
 <tr>
+<td>\param[&lt;dir&gt;]</td>
+<td>translated to @param; parameter direction ('in'; 'out'; or 'in,out') is ignored</td>
+</tr>
+<tr>
 <td>\remark</td>
 <td>replaced with 'Remarks:'</td>
 </tr>
@@ -816,7 +825,7 @@
 </table>
 </div>
 
-<H3><a name="Doxygen_unsupported_tags">17.3.3 Unsupported tags</a></H3>
+<H3><a name="Doxygen_unsupported_tags">18.3.3 Unsupported tags</a></H3>
 
 
 <p>
@@ -829,155 +838,107 @@
 sense, typically text content).
 Here is the list of these tags:
 </p>
+
 <div class="diagram">
-<table border="0" summary="Unsupported Java Doxygen Tags">
-<tr>
-  <th align="left">Unsupported Doxygen tags</th>
-</tr>
-<tr>
-<td>\addindex</td>
-<td>\addtogroup</td>
-<td>\anchor</td>
-<td>\attention</td>
-</tr>
-<tr>
-<td>\brief</td>
-<td>\bug</td>
-<td>\callgraph</td>
-<td>\callergraph</td>
-</tr>
-<tr>
-<td>\class</td>
-<td>\copybrief</td>
-<td>\copydetails</td>
-<td>\copydoc</td>
-</tr>
-<tr>
-<td>\date</td>
-<td>\def</td>
-<td>\defgroup</td>
-<td>\details</td>
-</tr>
-<tr>
-<td>\dir</td>
-<td>\dontinclude</td>
-<td>\dot</td>
-<td>\dotfile</td>
-</tr>
-<tr>
-<td>\enddot</td>
-<td>\endhtmlonly</td>
-<td>\endinternal</td>
-<td>\endlatexonly</td>
-</tr>
-<tr>
-<td>\endmanonly</td>
-<td>\endmsc</td>
-<td>\endrtfonly</td>
-<td>\endxmlonly</td>
-</tr>
-<tr>
-<td>\enum</td>
-<td>\example</td>
-<td>\extends</td>
-</tr>
-<tr>
-<td>\file</td>
-<td>\fn</td>
-<td>\headerfile</td>
-<td>\hideinitializer</td>
-</tr>
-<tr>
-<td>\htmlinclude</td>
-<td>\htmlonly</td>
-<td>\implements</td>
-<td>\include</td>
-</tr>
-<tr>
-<td>\includelineno</td>
-<td>\ingroup</td>
-<td>\internal</td>
-<td>\invariant</td>
-</tr>
-<tr>
-<td>\interface</td>
-<td>\latexonly</td>
-<td>\line</td>
-<td>\mainpage</td>
-</tr>
-<tr>
-<td>\manonly</td>
-<td>\memberof</td>
-<td>\msc</td>
-<td>\mscfile</td>
-</tr>
-<tr>
-<td>\name</td>
-<td>\namespace</td>
-<td>\nosubgrouping</td>
-<td>\package</td>
-</tr>
-<tr>
-<td>\page</td>
-<td>\paragraph</td>
-<td>\post</td>
-<td>\pre</td>
-</tr>
-<tr>
-<td>\private</td>
-<td>\privatesection</td>
-<td>\property</td>
-<td>\protected</td>
-</tr>
-<tr>
-<td>\protectedsection</td>
-<td>\protocol</td>
-<td>\public</td>
-<td>\publicsection</td>
-</tr>
-<tr>
-<td>\ref</td>
-<td>\related</td>
-<td>\relates</td>
-<td>\relatedalso</td>
-</tr>
-<tr>
-<td>\relatesalso</td>
-<td>\retval</td>
-<td>\rtfonly</td>
-<td>\section</td>
-</tr>
-<tr>
-<td>\short</td>
-<td>\showinitializer</td>
-<td>\skip</td>
-<td>\skipline</td>
-</tr>
-<tr>
-<td>\snippet</td>
-<td>\struct</td>
-<td>\subpage</td>
-<td>\subsection</td>
-</tr>
-<tr>
-<td>\subsubsection</td>
-<td>\tableofcontents</td>
-<td>\test</td>
-<td>\typedef</td>
-</tr>
-<tr>
-<td>\union</td>
-<td>\until</td>
-<td>\var</td>
-<td>\verbinclude</td>
-</tr>
-<tr>
-<td>\weakgroup</td>
-<td>\xmlonly</td>
-<td>\xrefitem</td>
-<td>\category</td>
-</tr>
-</table>
+  <b>Unsupported Doxygen tags</b>
+
+  <ul style="list-style-type:none;column-count:4;">
+    <li>\addindex</li>
+    <li>\addtogroup</li>
+    <li>\anchor</li>
+    <li>\attention</li>
+    <li>\brief</li>
+    <li>\bug</li>
+    <li>\callergraph</li>
+    <li>\callgraph</li>
+    <li>\category</li>
+    <li>\class</li>
+    <li>\copybrief</li>
+    <li>\copydetails</li>
+    <li>\copydoc</li>
+    <li>\date</li>
+    <li>\def</li>
+    <li>\defgroup</li>
+    <li>\details</li>
+    <li>\dir</li>
+    <li>\dontinclude</li>
+    <li>\dot</li>
+    <li>\dotfile</li>
+    <li>\enddot</li>
+    <li>\endhtmlonly</li>
+    <li>\endinternal</li>
+    <li>\endlatexonly</li>
+    <li>\endmanonly</li>
+    <li>\endmsc</li>
+    <li>\endrtfonly</li>
+    <li>\endxmlonly</li>
+    <li>\enum</li>
+    <li>\example</li>
+    <li>\extends</li>
+    <li>\file</li>
+    <li>\fn</li>
+    <li>\headerfile</li>
+    <li>\hideinitializer</li>
+    <li>\htmlinclude</li>
+    <li>\htmlonly</li>
+    <li>\implements</li>
+    <li>\include</li>
+    <li>\includelineno</li>
+    <li>\ingroup</li>
+    <li>\interface</li>
+    <li>\internal</li>
+    <li>\invariant</li>
+    <li>\latexonly</li>
+    <li>\line</li>
+    <li>\mainpage</li>
+    <li>\manonly</li>
+    <li>\memberof</li>
+    <li>\msc</li>
+    <li>\mscfile</li>
+    <li>\name</li>
+    <li>\namespace</li>
+    <li>\nosubgrouping</li>
+    <li>\package</li>
+    <li>\page</li>
+    <li>\paragraph</li>
+    <li>\post</li>
+    <li>\pre</li>
+    <li>\private</li>
+    <li>\privatesection</li>
+    <li>\property</li>
+    <li>\protected</li>
+    <li>\protectedsection</li>
+    <li>\protocol</li>
+    <li>\public</li>
+    <li>\publicsection</li>
+    <li>\ref</li>
+    <li>\related</li>
+    <li>\relatedalso</li>
+    <li>\relates</li>
+    <li>\relatesalso</li>
+    <li>\retval</li>
+    <li>\rtfonly</li>
+    <li>\section</li>
+    <li>\short</li>
+    <li>\showinitializer</li>
+    <li>\skip</li>
+    <li>\skipline</li>
+    <li>\snippet</li>
+    <li>\struct</li>
+    <li>\subpage</li>
+    <li>\subsection</li>
+    <li>\subsubsection</li>
+    <li>\tableofcontents</li>
+    <li>\test</li>
+    <li>\typedef</li>
+    <li>\union</li>
+    <li>\until</li>
+    <li>\var</li>
+    <li>\verbinclude</li>
+    <li>\weakgroup</li>
+    <li>\xmlonly</li>
+    <li>\xrefitem</li>
+  </ul>
 </div>
 
 <p>
@@ -987,79 +948,58 @@
 <!-- see parser.y, function isStructuralDoxygen() -->
 
 </p>
+
 <div class="diagram">
-<table border="0" summary="Ignored Java Doxygen Tags">
-<tr>
-  <th align="left">Ignored Doxygen tags</th>
-</tr>
-<tr>
-<td>\addtogroup</td>
-<td>\callgraph</td>
-<td>\callergraph</td>
-<td>\category</td>
-</tr>
-<tr>
-<td>\class</td>
-<td>\def</td>
-<td>\defgroup</td>
-<td>\dir</td>
-</tr>
-<tr>
-<td>\enum</td>
-<td>\example</td>
-<td>\file</td>
-<td>\fn</td>
-</tr>
-<tr>
-<td>\headerfile</td>
-<td>\hideinitializer</td>
-<td>\interface</td>
-<td>\internal</td>
-</tr>
-<tr>
-<td>\mainpage</td>
-<td>\name</td>
-<td>\namespace</td>
-<td>\nosubgrouping</td>
-</tr>
-<tr>
-<td>\overload</td>
-<td>\package</td>
-<td>\page</td>
-<td>\property</td>
-</tr>
-<tr>
-<td>\protocol</td>
-<td>\relates</td>
-<td>\relatesalso</td>
-<td>\showinitializer</td>
-</tr>
-<tr>
-<td>\struct</td>
-<td>\name</td>
-<td>\namespace</td>
-<td>\nosubgrouping</td>
-</tr>
-<tr>
-<td>\typedef</td>
-<td>\union</td>
-<td>\var</td>
-<td>\weakgroup</td>
-</tr>
+  <b>Ignored Doxygen tags</b>
 
-</table>
+  <ul style="list-style-type:none;column-count:4;">
+    <li>\addtogroup</li>
+    <li>\callergraph</li>
+    <li>\callgraph</li>
+    <li>\category</li>
+    <li>\class</li>
+    <li>\def</li>
+    <li>\defgroup</li>
+    <li>\dir</li>
+    <li>\enum</li>
+    <li>\example</li>
+    <li>\file</li>
+    <li>\fn</li>
+    <li>\headerfile</li>
+    <li>\hideinitializer</li>
+    <li>\interface</li>
+    <li>\internal</li>
+    <li>\mainpage</li>
+    <li>\name</li>
+    <li>\namespace</li>
+    <li>\nosubgrouping</li>
+    <li>\overload</li>
+    <li>\package</li>
+    <li>\page</li>
+    <li>\property</li>
+    <li>\protocol</li>
+    <li>\relates</li>
+    <li>\relatesalso</li>
+    <li>\showinitializer</li>
+    <li>\struct</li>
+    <li>\typedef</li>
+    <li>\union</li>
+    <li>\var</li>
+    <li>\weakgroup</li>
+  </ul>
 </div>
+  
 
 
 
-<H3><a name="Doxygen_further_details">17.3.4 Further details</a></H3>
+<H3><a name="Doxygen_further_details">18.3.4 Further details</a></H3>
 
 
 <p>
 TO BE ADDED.
 </p>
 
-<H2><a name="Doxygen_to_pydoc">17.4 Doxygen to Pydoc</a></H2>
+<H2><a name="Doxygen_to_pydoc">18.4 Doxygen to Pydoc</a></H2>
 
 
 <p>
@@ -1070,7 +1010,7 @@
 copying the appropriate command text.
 </p>
 
-<H3><a name="Doxygen_python_basic_example">17.4.1 Basic example</a></H3>
+<H3><a name="Doxygen_python_basic_example">18.4.1 Basic example</a></H3>
 
 
 <p>
@@ -1139,7 +1079,7 @@
 <p>
 If any parameters of a function or a method are documented in the Doxygen comment,
 their description is copied into the generated output using
-<a href="http://sphinx-doc.org/">Sphinx </a> documentation conventions. For example
+<a href="https://www.sphinx-doc.org/">Sphinx </a> documentation conventions. For example
 </p>
 <div class="code"><pre>
 /**
@@ -1174,7 +1114,7 @@
 change this, you can define your own typemaps for the custom types, e.g:
 </p>
 <div class="code"><pre>
-%typemap(doctype) MyDate "datetime.date";
+%typemap(doctype) MyDate "datetime.date"
 </pre></div>
 
 <p>
@@ -1227,13 +1167,13 @@
 the comments to the proxy file and reformat them if needed, but all
 the comment content will be left as is. As Doxygen doesn't support
 special commands in Python comments
-(see <a href="http://www.doxygen.nl/manual/docblocks.html#pythonblocks">Doxygen
+(see <a href="https://www.doxygen.nl/manual/docblocks.html#pythonblocks">Doxygen
 docs</a>), you may want to use some tool like doxypy
 (<a href="https://pypi.org/project/doxypy/">doxypy</a>)
 to do the work.
 </p>
 
-<H3><a name="Doxygen_pydoc_tags">17.4.2 Pydoc translator</a></H3>
+<H3><a name="Doxygen_pydoc_tags">18.4.2 Pydoc translator</a></H3>
 
 
 <p>
@@ -1246,11 +1186,11 @@
 </tr>
 <tr>
 <td>\a</td>
-<td>wrapped with '_'</td>
+<td>wrapped with '*'</td>
 </tr>
 <tr>
 <td>\arg</td>
-<td>prepended with ' --'</td>
+<td>prepended with '* '</td>
 </tr>
 <tr>
 <td>\author</td>
@@ -1258,17 +1198,29 @@
 </tr>
 <tr>
 <td>\authors</td>
-<td>prints 'Author:'</td>
+<td>prints 'Authors:'</td>
 </tr>
 <tr>
 <td>\b</td>
-<td>wrapped with '__'</td>
+<td>wrapped with '**'</td>
+</tr>
+<tr>
+<td>\c</td>
+<td>wrapped with '``'</td>
 </tr>
 <tr>
 <td>\cite</td>
 <td>wrapped with single quotes</td>
 </tr>
 <tr>
+<td>\code</td>
+<td>replaced with '.. code-block:: c++'</td>
+</tr>
+<tr>
+<td>\code{&lt;ext&gt;}</td>
+<td>replaced with '.. code-block:: &lt;lang&gt;', where the following doxygen code languages are recognized: .c -&gt; C, .py -&gt; python, .java &gt; java</td>
+</tr>
+<tr>
 <td>\cond</td>
 <td>translated to 'Conditional comment: &lt;condition&gt;'</td>
 </tr>
@@ -1282,7 +1234,7 @@
 </tr>
 <tr>
 <td>\e</td>
-<td>wrapped with '_'</td>
+<td>wrapped with '*'</td>
 </tr>
 <tr>
 <td>\else</td>
@@ -1294,7 +1246,7 @@
 </tr>
 <tr>
 <td>\em</td>
-<td>wrapped with '_'</td>
+<td>wrapped with '*'</td>
 </tr>
 <tr>
 <td>\endcond</td>
@@ -1305,8 +1257,24 @@
 <td>replaced with '}'</td>
 </tr>
 <tr>
+<td>\example</td>
+<td>replaced with 'Example:'</td>
+</tr>
+<tr>
 <td>\exception</td>
-<td>replaced with 'Throws:'</td>
+<td>replaced with ':raises:'</td>
+</tr>
+<tr>
+<td>\f$</td>
+<td>rendered using ':math:``'</td>
+</tr>
+<tr>
+<td>\f[</td>
+<td>rendered using '.. math::'</td>
+</tr>
+<tr>
+<td>\f{</td>
+<td>rendered using '.. math::'</td>
 </tr>
 <tr>
 <td>\if</td>
@@ -1318,11 +1286,11 @@
 </tr>
 <tr>
 <td>\li</td>
-<td>prepended with ' --'</td>
+<td>prepended with '* '</td>
 </tr>
 <tr>
 <td>\n</td>
-<td>replaced with new line char</td>
+<td>replaced with newline char</td>
 </tr>
 <tr>
 <td>\note</td>
@@ -1333,12 +1301,20 @@
 <td>prints 'This is an overloaded ...' according to Doxygen docs</td>
 </tr>
 <tr>
+<td>\p</td>
+<td>wrapped with '``'</td>
+</tr>
+<tr>
 <td>\par</td>
 <td>replaced with 'Title: ...'</td>
 </tr>
 <tr>
 <td>\param</td>
-<td>translated to 'Arguments:\n param(type) --description'</td>
+<td>add ':type:' and ':param:' directives</td>
+</tr>
+<tr>
+<td>\param[&lt;dir&gt;]</td>
+<td>same as \param, but direction ('in'; 'out'; 'in,out') is included in ':type:' directive</td>
 </tr>
 <tr>
 <td>\remark</td>
@@ -1350,15 +1326,15 @@
 </tr>
 <tr>
 <td>\result</td>
-<td>replaced with 'Result:'</td>
+<td>add ':rtype:' and ':return:' directives</td>
 </tr>
 <tr>
 <td>\return</td>
-<td>replaced with 'Result:'</td>
+<td>add ':rtype:' and ':return:' directives</td>
 </tr>
 <tr>
 <td>\returns</td>
-<td>replaced with 'Result:'</td>
+<td>add ':rtype:' and ':return:' directives</td>
 </tr>
 <tr>
 <td>\sa</td>
@@ -1374,11 +1350,11 @@
 </tr>
 <tr>
 <td>\throw</td>
-<td>replaced with 'Throws:'</td>
+<td>replaced with ':raises:'</td>
 </tr>
 <tr>
 <td>\throws</td>
-<td>replaced wih 'Throws:'</td>
+<td>replaced with ':raises:'</td>
 </tr>
 <tr>
 <td>\todo</td>
@@ -1386,7 +1362,11 @@
 </tr>
 <tr>
 <td>\tparam</td>
-<td>translated to 'Arguments:\n param(type) --description'</td>
+<td>add ':type:' and ':param:' directives</td>
+</tr>
+<tr>
+<td>\verbatim</td>
+<td>content copied verbatim</td>
 </tr>
 <tr>
 <td>\version</td>
@@ -1447,7 +1427,7 @@
 </table>
 </div>
 
-<H3><a name="Doxygen_python_unsupported_tags">17.4.3 Unsupported tags</a></H3>
+<H3><a name="Doxygen_python_unsupported_tags">18.4.3 Unsupported tags</a></H3>
 
 
 <p>
@@ -1458,187 +1438,119 @@
 sense, typically text content).
 Here is the list of these tags:
 </p>
+
 <div class="diagram">
-<table border="0" summary="Unsupported Python Doxygen Tags">
-<tr>
-  <th align="left">Unsupported Doxygen tags</th>
-</tr>
-<tr>
-<td>\addindex</td>
-<td>\addtogroup</td>
-<td>\anchor</td>
-<td>\attention</td>
-</tr>
-<tr>
-<td>\brief</td>
-<td>\bug</td>
-<td>\callgraph</td>
-<td>\callergraph</td>
-</tr>
-<tr>
-<td>\class</td>
-<td>\copybrief</td>
-<td>\copydetails</td>
-<td>\copydoc</td>
-</tr>
-<tr>
-<td>\date</td>
-<td>\def</td>
-<td>\defgroup</td>
-<td>\details</td>
-</tr>
-<tr>
-<td>\dir</td>
-<td>\dontinclude</td>
-<td>\dot</td>
-<td>\dotfile</td>
-</tr>
-<tr>
-<td>\code</td>
-<td>\endcode</td>
-<td>\endverbatim</td>
-<td>\endlink</td>
-</tr>
-<tr>
-<td>\enddot</td>
-<td>\endhtmlonly</td>
-<td>\endinternal</td>
-<td>\endlatexonly</td>
-</tr>
-<tr>
-<td>\endmanonly</td>
-<td>\endmsc</td>
-<td>\endrtfonly</td>
-<td>\endxmlonly</td>
-</tr>
-<tr>
-<td>\enum</td>
-<td>\example</td>
-<td>\extends</td>
-<td>\f$</td>
-</tr>
-<tr>
-<td>\f[</td>
-<td>\f]</td>
-<td>\f{</td>
-<td>\f}</td>
-</tr>
-<tr>
-<td>\file</td>
-<td>\fn</td>
-<td>\headerfile</td>
-<td>\hideinitializer</td>
-</tr>
-<tr>
-<td>\htmlinclude</td>
-<td>\htmlonly</td>
-<td>\implements</td>
-<td>\include</td>
-</tr>
-<tr>
-<td>\image</td>
-<td>\link</td>
-<td>\verbatim</td>
-<td>\p</td>
-</tr>
-<tr>
-<td>\includelineno</td>
-<td>\ingroup</td>
-<td>\internal</td>
-<td>\invariant</td>
-</tr>
-<tr>
-<td>\interface</td>
-<td>\latexonly</td>
-<td>\line</td>
-<td>\mainpage</td>
-</tr>
-<tr>
-<td>\manonly</td>
-<td>\memberof</td>
-<td>\msc</td>
-<td>\mscfile</td>
-</tr>
-<tr>
-<td>\name</td>
-<td>\namespace</td>
-<td>\nosubgrouping</td>
-<td>\package</td>
-</tr>
-<tr>
-<td>\page</td>
-<td>\paragraph</td>
-<td>\post</td>
-<td>\pre</td>
-</tr>
-<tr>
-<td>\private</td>
-<td>\privatesection</td>
-<td>\property</td>
-<td>\protected</td>
-</tr>
-<tr>
-<td>\protectedsection</td>
-<td>\protocol</td>
-<td>\public</td>
-<td>\publicsection</td>
-</tr>
-<tr>
-<td>\ref</td>
-<td>\related</td>
-<td>\relates</td>
-<td>\relatedalso</td>
-</tr>
-<tr>
-<td>\relatesalso</td>
-<td>\retval</td>
-<td>\rtfonly</td>
-<td>\section</td>
-</tr>
-<tr>
-<td>\short</td>
-<td>\showinitializer</td>
-<td>\skip</td>
-<td>\skipline</td>
-</tr>
-<tr>
-<td>\snippet</td>
-<td>\struct</td>
-<td>\subpage</td>
-<td>\subsection</td>
-</tr>
-<tr>
-<td>\subsubsection</td>
-<td>\tableofcontents</td>
-<td>\test</td>
-<td>\typedef</td>
-</tr>
-<tr>
-<td>\union</td>
-<td>\until</td>
-<td>\var</td>
-<td>\verbinclude</td>
-</tr>
-<tr>
-<td>\weakgroup</td>
-<td>\xmlonly</td>
-<td>\xrefitem</td>
-<td>\category</td>
-</tr>
-<tr>
-<td>\c</td>
-</tr>
-</table>
+  <b>Unsupported Python Doxygen tags</b>
+
+  <ul style="list-style-type:none;column-count:4;">
+    <li>\addindex</li>
+    <li>\addtogroup</li>
+    <li>\anchor</li>
+    <li>\attention</li>
+    <li>\brief</li>
+    <li>\bug</li>
+    <li>\callergraph</li>
+    <li>\callgraph</li>
+    <li>\category</li>
+    <li>\class</li>
+    <li>\copybrief</li>
+    <li>\copydetails</li>
+    <li>\copydoc</li>
+    <li>\date</li>
+    <li>\def</li>
+    <li>\defgroup</li>
+    <li>\details</li>
+    <li>\dir</li>
+    <li>\dontinclude</li>
+    <li>\dot</li>
+    <li>\dotfile</li>
+    <li>\enddot</li>
+    <li>\endhtmlonly</li>
+    <li>\endinternal</li>
+    <li>\endlatexonly</li>
+    <li>\endlink</li>
+    <li>\endmanonly</li>
+    <li>\endmsc</li>
+    <li>\endrtfonly</li>
+    <li>\endxmlonly</li>
+    <li>\enum</li>
+    <li>\extends</li>
+    <li>\file</li>
+    <li>\fn</li>
+    <li>\headerfile</li>
+    <li>\hideinitializer</li>
+    <li>\htmlinclude</li>
+    <li>\htmlonly</li>
+    <li>\image</li>
+    <li>\implements</li>
+    <li>\include</li>
+    <li>\includelineno</li>
+    <li>\ingroup</li>
+    <li>\interface</li>
+    <li>\internal</li>
+    <li>\invariant</li>
+    <li>\latexonly</li>
+    <li>\line</li>
+    <li>\link</li>
+    <li>\mainpage</li>
+    <li>\manonly</li>
+    <li>\memberof</li>
+    <li>\msc</li>
+    <li>\mscfile</li>
+    <li>\name</li>
+    <li>\namespace</li>
+    <li>\nosubgrouping</li>
+    <li>\package</li>
+    <li>\page</li>
+    <li>\paragraph</li>
+    <li>\post</li>
+    <li>\pre</li>
+    <li>\private</li>
+    <li>\privatesection</li>
+    <li>\property</li>
+    <li>\protected</li>
+    <li>\protectedsection</li>
+    <li>\protocol</li>
+    <li>\public</li>
+    <li>\publicsection</li>
+    <li>\ref</li>
+    <li>\related</li>
+    <li>\relatedalso</li>
+    <li>\relates</li>
+    <li>\relatesalso</li>
+    <li>\retval</li>
+    <li>\rtfonly</li>
+    <li>\section</li>
+    <li>\short</li>
+    <li>\showinitializer</li>
+    <li>\skip</li>
+    <li>\skipline</li>
+    <li>\snippet</li>
+    <li>\struct</li>
+    <li>\subpage</li>
+    <li>\subsection</li>
+    <li>\subsubsection</li>
+    <li>\tableofcontents</li>
+    <li>\test</li>
+    <li>\typedef</li>
+    <li>\union</li>
+    <li>\until</li>
+    <li>\var</li>
+    <li>\verbinclude</li>
+    <li>\weakgroup</li>
+    <li>\xmlonly</li>
+    <li>\xrefitem</li>
+  </ul>
 </div>
 
-<H3><a name="Doxygen_python_further_details">17.4.4 Further details</a></H3>
+<H3><a name="Doxygen_python_further_details">18.4.4 Further details</a></H3>
 
 
 <p>
 TO BE ADDED.
 </p>
 
-<H2><a name="Doxygen_troubleshooting">17.5 Troubleshooting</a></H2>
+<H2><a name="Doxygen_troubleshooting">18.5 Troubleshooting</a></H2>
 
 
 <p>
@@ -1660,7 +1572,7 @@
 </p>
 
 
-<H3><a name="troubleshooting_ifndef">17.5.1 Problem with conditional compilation</a></H3>
+<H3><a name="troubleshooting_ifndef">18.5.1 Problem with conditional compilation</a></H3>
 
 
 <p>
@@ -1700,14 +1612,14 @@
 </pre></div>
 
 
-<H2><a name="Doxygen_developer_details">17.6 Developer information</a></H2>
+<H2><a name="Doxygen_developer_details">18.6 Developer information</a></H2>
 
 
 <p>
 This section contains information for developers enhancing the Doxygen translator.
 </p>
 
-<H3><a name="Doxygen_translator_design">17.6.1 Doxygen translator design</a></H3>
+<H3><a name="Doxygen_translator_design">18.6.1 Doxygen translator design</a></H3>
 
 
 <p>
@@ -1733,7 +1645,7 @@
 example, <tt>JavaDocConverter</tt> is the Javadoc module class.
 </p>
 
-<H3><a name="Doxygen_debugging_commands">17.6.2 Debugging the Doxygen parser and translator</a></H3>
+<H3><a name="Doxygen_debugging_commands">18.6.2 Debugging the Doxygen parser and translator</a></H3>
 
 
 <p>
@@ -1746,7 +1658,7 @@
   -debug-doxygen-translator - Display Doxygen translator module debugging information
 </pre></div>
 
-<H3><a name="Doxygen_tests">17.6.3 Tests</a></H3>
+<H3><a name="Doxygen_tests">18.6.3 Tests</a></H3>
 
 
 <p>
@@ -1798,7 +1710,7 @@
 properties.
 </p>
 
-<H2><a name="Doxygen_language_extension">17.7 Extending to other languages</a></H2>
+<H2><a name="Doxygen_language_extension">18.7 Extending to other languages</a></H2>
 
 
 <p>
diff --git a/Doc/Manual/Extending.html b/Doc/Manual/Extending.html
index 5a640fb..bc4f948 100644
--- a/Doc/Manual/Extending.html
+++ b/Doc/Manual/Extending.html
@@ -7,7 +7,7 @@
 </head>
 
 <body bgcolor="#ffffff">
-<H1><a name="Extending">39 Extending SWIG to support new languages</a></H1>
+<H1><a name="Extending">40 Extending SWIG to support new languages</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -81,7 +81,7 @@
 
 
 
-<H2><a name="Extending_nn2">39.1 Introduction</a></H2>
+<H2><a name="Extending_nn2">40.1 Introduction</a></H2>
 
 
 <p>
@@ -97,7 +97,7 @@
 you should probably look at one of SWIG's existing modules.
 </p>
 
-<H2><a name="Extending_nn3">39.2 Prerequisites</a></H2>
+<H2><a name="Extending_nn3">40.2 Prerequisites</a></H2>
 
 
 <p>
@@ -127,7 +127,7 @@
 wrapper code are driven by C++ datatypes.
 </p>
 
-<H2><a name="Extending_nn4">39.3 The Big Picture</a></H2>
+<H2><a name="Extending_nn4">40.3 The Big Picture</a></H2>
 
 
 <p>
@@ -164,7 +164,7 @@
 based on pattern matching and interact heavily with the underlying type system.
 </p>
 
-<H2><a name="Extending_nn5">39.4 Execution Model</a></H2>
+<H2><a name="Extending_nn5">40.4 Execution Model</a></H2>
 
 
 <p>
@@ -209,7 +209,7 @@
 The next few sections briefly describe some of these stages.
 </p>
 
-<H3><a name="Extending_nn6">39.4.1 Preprocessing</a></H3>
+<H3><a name="Extending_nn6">40.4.1 Preprocessing</a></H3>
 
 
 <p>
@@ -290,7 +290,7 @@
 construction of the wrapper code.
 </p>
 
-<H3><a name="Extending_nn7">39.4.2 Parsing</a></H3>
+<H3><a name="Extending_nn7">40.4.2 Parsing</a></H3>
 
 
 <p>
@@ -391,7 +391,7 @@
 arguments).
 </p>
 
-<H3><a name="Extending_nn8">39.4.3 Parse Trees</a></H3>
+<H3><a name="Extending_nn8">40.4.3 Parse Trees</a></H3>
 
 
 <p>
@@ -462,191 +462,224 @@
 There are a number of other parse tree display options, for example, <tt>swig -debug-module &lt;n&gt;</tt> will
 avoid displaying system parse information and only display the parse tree pertaining to the user's module at
 stage <tt>n</tt> of processing.
+Adding the <tt>-debug-quiet</tt> option is recommended as it removes some noise which is not usually needed,
+that is, the display of many linked list pointers and symbol table pointers.
 </p>
 
 <div class="shell">
 <pre>
-$ swig -c++ -python -debug-module 4 example.i
-      +++ include ----------------------------------------
-      | name         - "example.i"
+$ swig -c++ -python -debug-module 1 -debug-quiet example.i
+debug-module stage 1
++++ module ----------------------------------------
+| name         - "example"
+| 
++++ insert ----------------------------------------
+| code         - "\n#include \"example.h\"\n"
+| 
++++ include ----------------------------------------
+| name         - "example.h"
 
-            +++ module ----------------------------------------
-            | name         - "example"
-            |
-            +++ insert ----------------------------------------
-            | code         - "\n#include \"example.h\"\n"
-            |
-            +++ include ----------------------------------------
-            | name         - "example.h"
+      +++ class ----------------------------------------
+      | abstracts    - 0x7f4f15182930
+      | allows_typedef - "1"
+      | kind         - "class"
+      | name         - "Shape"
+      | sym:name     - "Shape"
 
-                  +++ class ----------------------------------------
-                  | abstract     - "1"
-                  | sym:name     - "Shape"
-                  | name         - "Shape"
-                  | kind         - "class"
-                  | symtab       - 0x40194140
-                  | sym:symtab   - 0x40191078
+            +++ access ----------------------------------------
+            | kind         - "public"
+            | 
+            +++ constructor ----------------------------------------
+            | access       - "public"
+            | code         - "{\n    nshapes++;\n  }"
+            | decl         - "f()."
+            | feature:new  - "1"
+            | ismember     - "1"
+            | name         - "Shape"
+            | sym:name     - "Shape"
+            | 
+            +++ destructor ----------------------------------------
+            | access       - "public"
+            | code         - "{\n    nshapes--;\n  }"
+            | decl         - "f()."
+            | ismember     - "1"
+            | name         - "~Shape"
+            | storage      - "virtual"
+            | sym:name     - "~Shape"
+            | 
+            +++ cdecl ----------------------------------------
+            | access       - "public"
+            | decl         - ""
+            | ismember     - "1"
+            | kind         - "variable"
+            | name         - "x"
+            | sym:name     - "x"
+            | type         - "double"
+            | 
+            +++ cdecl ----------------------------------------
+            | access       - "public"
+            | decl         - ""
+            | ismember     - "1"
+            | kind         - "variable"
+            | name         - "y"
+            | sym:name     - "y"
+            | type         - "double"
+            | 
+            +++ cdecl ----------------------------------------
+            | access       - "public"
+            | decl         - "f(double,double)."
+            | ismember     - "1"
+            | kind         - "function"
+            | name         - "move"
+            | parms        - 'double dx,double dy'
+            | sym:name     - "move"
+            | type         - "void"
+            | 
+            +++ cdecl ----------------------------------------
+            | abstract     - "1"
+            | access       - "public"
+            | decl         - "f()."
+            | ismember     - "1"
+            | kind         - "function"
+            | name         - "area"
+            | storage      - "virtual"
+            | sym:name     - "area"
+            | type         - "double"
+            | value        - "0"
+            | valuetype    - "int"
+            | 
+            +++ cdecl ----------------------------------------
+            | abstract     - "1"
+            | access       - "public"
+            | decl         - "f()."
+            | ismember     - "1"
+            | kind         - "function"
+            | name         - "perimeter"
+            | storage      - "virtual"
+            | sym:name     - "perimeter"
+            | type         - "double"
+            | value        - "0"
+            | valuetype    - "int"
+            | 
+            +++ cdecl ----------------------------------------
+            | access       - "public"
+            | decl         - ""
+            | ismember     - "1"
+            | kind         - "variable"
+            | name         - "nshapes"
+            | storage      - "static"
+            | sym:name     - "nshapes"
+            | type         - "int"
+            | 
+      +++ class ----------------------------------------
+      | allows_typedef - "1"
+      | baselist     - 0x7f4f15182ad0
+      | kind         - "class"
+      | name         - "Circle"
+      | privatebaselist - 0x7f4f15182b10
+      | protectedbaselist - 0x7f4f15182af0
+      | sym:name     - "Circle"
 
-                        +++ access ----------------------------------------
-                        | kind         - "public"
-                        |
-                        +++ constructor ----------------------------------------
-                        | sym:name     - "Shape"
-                        | name         - "Shape"
-                        | decl         - "f()."
-                        | code         - "{\n    nshapes++;\n  }"
-                        | sym:symtab   - 0x40194140
-                        |
-                        +++ destructor ----------------------------------------
-                        | sym:name     - "~Shape"
-                        | name         - "~Shape"
-                        | storage      - "virtual"
-                        | code         - "{\n    nshapes--;\n  }"
-                        | sym:symtab   - 0x40194140
-                        |
-                        +++ cdecl ----------------------------------------
-                        | sym:name     - "x"
-                        | name         - "x"
-                        | decl         - ""
-                        | type         - "double"
-                        | sym:symtab   - 0x40194140
-                        |
-                        +++ cdecl ----------------------------------------
-                        | sym:name     - "y"
-                        | name         - "y"
-                        | decl         - ""
-                        | type         - "double"
-                        | sym:symtab   - 0x40194140
-                        |
-                        +++ cdecl ----------------------------------------
-                        | sym:name     - "move"
-                        | name         - "move"
-                        | decl         - "f(double, double)."
-                        | parms        - double, double
-                        | type         - "void"
-                        | sym:symtab   - 0x40194140
-                        |
-                        +++ cdecl ----------------------------------------
-                        | sym:name     - "area"
-                        | name         - "area"
-                        | decl         - "f(void)."
-                        | parms        - void
-                        | storage      - "virtual"
-                        | value        - "0"
-                        | type         - "double"
-                        | sym:symtab   - 0x40194140
-                        |
-                        +++ cdecl ----------------------------------------
-                        | sym:name     - "perimeter"
-                        | name         - "perimeter"
-                        | decl         - "f(void)."
-                        | parms        - void
-                        | storage      - "virtual"
-                        | value        - "0"
-                        | type         - "double"
-                        | sym:symtab   - 0x40194140
-                        |
-                        +++ cdecl ----------------------------------------
-                        | sym:name     - "nshapes"
-                        | name         - "nshapes"
-                        | decl         - ""
-                        | storage      - "static"
-                        | type         - "int"
-                        | sym:symtab   - 0x40194140
-                        |
-                  +++ class ----------------------------------------
-                  | sym:name     - "Circle"
-                  | name         - "Circle"
-                  | kind         - "class"
-                  | bases        - 0x40194510
-                  | symtab       - 0x40194538
-                  | sym:symtab   - 0x40191078
+            +++ access ----------------------------------------
+            | kind         - "private"
+            | 
+            +++ cdecl ----------------------------------------
+            | access       - "private"
+            | decl         - ""
+            | ismember     - "1"
+            | kind         - "variable"
+            | name         - "radius"
+            | type         - "double"
+            | 
+            +++ access ----------------------------------------
+            | kind         - "public"
+            | 
+            +++ constructor ----------------------------------------
+            | access       - "public"
+            | code         - "{ }"
+            | decl         - "f(double)."
+            | feature:new  - "1"
+            | ismember     - "1"
+            | name         - "Circle"
+            | parms        - 'double r'
+            | sym:name     - "Circle"
+            | 
+            +++ cdecl ----------------------------------------
+            | access       - "public"
+            | decl         - "f()."
+            | ismember     - "1"
+            | kind         - "function"
+            | name         - "area"
+            | storage      - "virtual"
+            | sym:name     - "area"
+            | type         - "double"
+            | 
+            +++ cdecl ----------------------------------------
+            | access       - "public"
+            | decl         - "f()."
+            | ismember     - "1"
+            | kind         - "function"
+            | name         - "perimeter"
+            | storage      - "virtual"
+            | sym:name     - "perimeter"
+            | type         - "double"
+            | 
+      +++ class ----------------------------------------
+      | allows_typedef - "1"
+      | baselist     - 0x7f4f15183830
+      | kind         - "class"
+      | name         - "Square"
+      | privatebaselist - 0x7f4f15183870
+      | protectedbaselist - 0x7f4f15183850
+      | sym:name     - "Square"
 
-                        +++ access ----------------------------------------
-                        | kind         - "private"
-                        |
-                        +++ cdecl ----------------------------------------
-                        | name         - "radius"
-                        | decl         - ""
-                        | type         - "double"
-                        |
-                        +++ access ----------------------------------------
-                        | kind         - "public"
-                        |
-                        +++ constructor ----------------------------------------
-                        | sym:name     - "Circle"
-                        | name         - "Circle"
-                        | parms        - double
-                        | decl         - "f(double)."
-                        | code         - "{ }"
-                        | sym:symtab   - 0x40194538
-                        |
-                        +++ cdecl ----------------------------------------
-                        | sym:name     - "area"
-                        | name         - "area"
-                        | decl         - "f(void)."
-                        | parms        - void
-                        | storage      - "virtual"
-                        | type         - "double"
-                        | sym:symtab   - 0x40194538
-                        |
-                        +++ cdecl ----------------------------------------
-                        | sym:name     - "perimeter"
-                        | name         - "perimeter"
-                        | decl         - "f(void)."
-                        | parms        - void
-                        | storage      - "virtual"
-                        | type         - "double"
-                        | sym:symtab   - 0x40194538
-                        |
-                  +++ class ----------------------------------------
-                  | sym:name     - "Square"
-                  | name         - "Square"
-                  | kind         - "class"
-                  | bases        - 0x40194760
-                  | symtab       - 0x40194788
-                  | sym:symtab   - 0x40191078
-
-                        +++ access ----------------------------------------
-                        | kind         - "private"
-                        |
-                        +++ cdecl ----------------------------------------
-                        | name         - "width"
-                        | decl         - ""
-                        | type         - "double"
-                        |
-                        +++ access ----------------------------------------
-                        | kind         - "public"
-                        |
-                        +++ constructor ----------------------------------------
-                        | sym:name     - "Square"
-                        | name         - "Square"
-                        | parms        - double
-                        | decl         - "f(double)."
-                        | code         - "{ }"
-                        | sym:symtab   - 0x40194788
-                        |
-                        +++ cdecl ----------------------------------------
-                        | sym:name     - "area"
-                        | name         - "area"
-                        | decl         - "f(void)."
-                        | parms        - void
-                        | storage      - "virtual"
-                        | type         - "double"
-                        | sym:symtab   - 0x40194788
-                        |
-                        +++ cdecl ----------------------------------------
-                        | sym:name     - "perimeter"
-                        | name         - "perimeter"
-                        | decl         - "f(void)."
-                        | parms        - void
-                        | storage      - "virtual"
-                        | type         - "double"
-                        | sym:symtab   - 0x40194788
+            +++ access ----------------------------------------
+            | kind         - "private"
+            | 
+            +++ cdecl ----------------------------------------
+            | access       - "private"
+            | decl         - ""
+            | ismember     - "1"
+            | kind         - "variable"
+            | name         - "width"
+            | type         - "double"
+            | 
+            +++ access ----------------------------------------
+            | kind         - "public"
+            | 
+            +++ constructor ----------------------------------------
+            | access       - "public"
+            | code         - "{ }"
+            | decl         - "f(double)."
+            | feature:new  - "1"
+            | ismember     - "1"
+            | name         - "Square"
+            | parms        - 'double w'
+            | sym:name     - "Square"
+            | 
+            +++ cdecl ----------------------------------------
+            | access       - "public"
+            | decl         - "f()."
+            | ismember     - "1"
+            | kind         - "function"
+            | name         - "area"
+            | storage      - "virtual"
+            | sym:name     - "area"
+            | type         - "double"
+            | 
+            +++ cdecl ----------------------------------------
+            | access       - "public"
+            | decl         - "f()."
+            | ismember     - "1"
+            | kind         - "function"
+            | name         - "perimeter"
+            | storage      - "virtual"
+            | sym:name     - "perimeter"
+            | type         - "double"
 </pre>
 </div>
 
-<H3><a name="Extending_nn9">39.4.4 Attribute namespaces</a></H3>
+<H3><a name="Extending_nn9">40.4.4 Attribute namespaces</a></H3>
 
 
 <p>
@@ -665,7 +698,7 @@
 <tt>perl:foo</tt>.
 </p>
 
-<H3><a name="Extending_nn10">39.4.5 Symbol Tables</a></H3>
+<H3><a name="Extending_nn10">40.4.5 Symbol Tables</a></H3>
 
 
 <p>
@@ -698,31 +731,28 @@
 
 <div class="shell">
 <pre>
-$ swig -debug-top 4 example.i
+$ swig -debug-top 1 -debug-quiet example.i
 ...
             +++ cdecl ----------------------------------------
-            | sym:name     - "foo_i"
-            | name         - "foo"
             | decl         - "f(int)."
+            | name         - "foo"
             | parms        - int
+            | sym:name     - "foo_i"
             | type         - "void"
-            | sym:symtab   - 0x40165078
             |
             +++ cdecl ----------------------------------------
-            | sym:name     - "foo_d"
-            | name         - "foo"
             | decl         - "f(double)."
+            | name         - "foo"
             | parms        - double
+            | sym:name     - "foo_d"
             | type         - "void"
-            | sym:symtab   - 0x40165078
             |
             +++ cdecl ----------------------------------------
-            | sym:name     - "foo"
-            | name         - "foo"
             | decl         - "f(p.Bar)."
+            | name         - "foo"
             | parms        - Bar *
+            | sym:name     - "foo"
             | type         - "void"
-            | sym:symtab   - 0x40165078
 </pre>
 </div>
 
@@ -756,7 +786,7 @@
 </pre>
 </div>
 
-<H3><a name="Extending_nn11">39.4.6 The %feature directive</a></H3>
+<H3><a name="Extending_nn11">40.4.6 The %feature directive</a></H3>
 
 
 <p>
@@ -787,19 +817,18 @@
 The behavior of <tt>%feature</tt> is very easy to describe--it simply
 attaches a new attribute to any parse tree node that matches the
 given prototype.   When a feature is added, it shows up as an attribute in the <tt>feature:</tt> namespace.
-You can see this when running with the <tt>-debug-top 4</tt> option.   For example:
+You can see this when running with the <tt>-debug-top 4 -debug-quiet</tt> option.   For example:
 </p>
 
 <div class="shell">
 <pre>
  +++ cdecl ----------------------------------------
- | sym:name     - "getitem"
- | name         - "getitem"
  | decl         - "f(int).p."
- | parms        - int
- | type         - "Object"
  | feature:except - "{\n    try {\n       $action\n    } catc..."
- | sym:symtab   - 0x40168ac8
+ | name         - "getitem"
+ | parms        - int
+ | sym:name     - "getitem"
+ | type         - "Object"
  |
 </pre>
 </div>
@@ -812,7 +841,7 @@
 stored without any modifications.
 </p>
 
-<H3><a name="Extending_nn12">39.4.7 Code Generation</a></H3>
+<H3><a name="Extending_nn12">40.4.7 Code Generation</a></H3>
 
 
 <p>
@@ -934,7 +963,7 @@
 The role of these functions is described shortly.
 </p>
 
-<H3><a name="Extending_nn13">39.4.8 SWIG and XML</a></H3>
+<H3><a name="Extending_nn13">40.4.8 SWIG and XML</a></H3>
 
 
 <p>
@@ -947,7 +976,7 @@
 your mind as a model.
 </p>
 
-<H2><a name="Extending_nn14">39.5 Primitive Data Structures</a></H2>
+<H2><a name="Extending_nn14">40.5 Primitive Data Structures</a></H2>
 
 
 <p>
@@ -993,7 +1022,7 @@
 </pre>
 </div>
 
-<H3><a name="Extending_nn15">39.5.1 Strings</a></H3>
+<H3><a name="Extending_nn15">40.5.1 Strings</a></H3>
 
 
 <p>
@@ -1132,9 +1161,14 @@
 Returns the number of replacements made (if any).
 </p>
 
+<p>
+At most one of <tt>DOH_REPLACE_ANY</tt> and <tt>DOH_REPLACE_FIRST</tt> should be specified.
+<tt>DOH_REPLACE_ANY</tt> is the default if neither is specified.
+</p>
+
 </div>
 
-<H3><a name="Extending_nn16">39.5.2 Hashes</a></H3>
+<H3><a name="Extending_nn16">40.5.2 Hashes</a></H3>
 
 
 <p>
@@ -1210,8 +1244,16 @@
 Returns the list of hash table keys.
 </div>
 
+<p>
+<b><tt>List *SortedKeys(Hash *h, int (*cmp) (const DOH *, const DOH *))</tt></b>
+</p>
 
-<H3><a name="Extending_nn17">39.5.3 Lists</a></H3>
+<div class="indent">
+Returns the list of sorted hash table keys.
+</div>
+
+
+<H3><a name="Extending_nn17">40.5.3 Lists</a></H3>
 
 
 <p>
@@ -1300,7 +1342,7 @@
 and is used to create a String object.
 </div>
 
-<H3><a name="Extending_nn18">39.5.4 Common operations</a></H3>
+<H3><a name="Extending_nn18">40.5.4 Common operations</a></H3>
 
 
 The following operations are applicable to all datatypes.
@@ -1355,7 +1397,7 @@
 Gets the line number associated with <tt>x</tt>.
 </div>
 
-<H3><a name="Extending_nn19">39.5.5 Iterating over Lists and Hashes</a></H3>
+<H3><a name="Extending_nn19">40.5.5 Iterating over Lists and Hashes</a></H3>
 
 
 To iterate over the elements of a list or a hash table, the following functions are used:
@@ -1400,7 +1442,7 @@
 
 </div>
 
-<H3><a name="Extending_nn20">39.5.6 I/O</a></H3>
+<H3><a name="Extending_nn20">40.5.6 I/O</a></H3>
 
 
 Special I/O functions are used for all internal I/O.  These operations
@@ -1534,7 +1576,7 @@
 Similarly, the preprocessor and parser all operate on string-files.
 </p>
 
-<H2><a name="Extending_nn21">39.6 Navigating and manipulating parse trees</a></H2>
+<H2><a name="Extending_nn21">40.6 Navigating and manipulating parse trees</a></H2>
 
 
 Parse trees are built as collections of hash tables.   Each node is a hash table in which
@@ -1668,7 +1710,7 @@
 the parent so that sibling nodes are unaffected.
 </div>
 
-<H2><a name="Extending_nn22">39.7 Working with attributes</a></H2>
+<H2><a name="Extending_nn22">40.7 Working with attributes</a></H2>
 
 
 <p>
@@ -1785,7 +1827,7 @@
 function.
 </div>
 
-<H2><a name="Extending_nn23">39.8 Type system</a></H2>
+<H2><a name="Extending_nn23">40.8 Type system</a></H2>
 
 
 <p>
@@ -1794,7 +1836,7 @@
 type theory is impossible here.   However, let's cover the highlights.
 </p>
 
-<H3><a name="Extending_nn24">39.8.1 String encoding of types</a></H3>
+<H3><a name="Extending_nn24">40.8.1 String encoding of types</a></H3>
 
 
 <p>
@@ -1895,7 +1937,7 @@
 string concatenation.
 </p>
 
-<H3><a name="Extending_nn25">39.8.2 Type construction</a></H3>
+<H3><a name="Extending_nn25">40.8.2 Type construction</a></H3>
 
 
 <p>
@@ -2064,7 +2106,7 @@
 <tt>ty</tt> is unmodified.
 </div>
 
-<H3><a name="Extending_nn26">39.8.3 Type tests</a></H3>
+<H3><a name="Extending_nn26">40.8.3 Type tests</a></H3>
 
 
 <p>
@@ -2151,7 +2193,7 @@
 Checks if <tt>ty</tt> is a templatized type.
 </div>
 
-<H3><a name="Extending_nn27">39.8.4 Typedef and inheritance</a></H3>
+<H3><a name="Extending_nn27">40.8.4 Typedef and inheritance</a></H3>
 
 
 <p>
@@ -2253,7 +2295,7 @@
 will consist only of primitive typenames.
 </div>
 
-<H3><a name="Extending_nn28">39.8.5 Lvalues</a></H3>
+<H3><a name="Extending_nn28">40.8.5 Lvalues</a></H3>
 
 
 <p>
@@ -2290,7 +2332,7 @@
 </pre>
 </div>
 
-<H3><a name="Extending_nn29">39.8.6 Output functions</a></H3>
+<H3><a name="Extending_nn29">40.8.6 Output functions</a></H3>
 
 
 <p>
@@ -2352,7 +2394,7 @@
 that appear in wrappers (e.g., <tt>SWIGTYPE_p_double</tt>).
 </div>
 
-<H2><a name="Extending_nn30">39.9 Parameters</a></H2>
+<H2><a name="Extending_nn30">40.9 Parameters</a></H2>
 
 
 <p>
@@ -2451,7 +2493,7 @@
 Returns the number of required (non-optional) arguments in <tt>p</tt>.
 </div>
 
-<H2><a name="Extending_nn31">39.10 Writing a Language Module</a></H2>
+<H2><a name="Extending_nn31">40.10 Writing a Language Module</a></H2>
 
 
 <p>
@@ -2466,7 +2508,7 @@
 this to other languages.
 </p>
 
-<H3><a name="Extending_nn32">39.10.1 Execution model</a></H3>
+<H3><a name="Extending_nn32">40.10.1 Execution model</a></H3>
 
 
 <p>
@@ -2476,7 +2518,7 @@
 different methods of the <tt>Language</tt> that must be defined by your module.
 </p>
 
-<H3><a name="Extending_starting_out">39.10.2 Starting out</a></H3>
+<H3><a name="Extending_starting_out">40.10.2 Starting out</a></H3>
 
 
 <p>
@@ -2584,7 +2626,7 @@
 messages from your new module should appear.
 </p>
 
-<H3><a name="Extending_nn34">39.10.3 Command line options</a></H3>
+<H3><a name="Extending_nn34">40.10.3 Command line options</a></H3>
 
 
 <p>
@@ -2643,7 +2685,7 @@
 unrecognized command line option error.
 </p>
 
-<H3><a name="Extending_nn35">39.10.4 Configuration and preprocessing</a></H3>
+<H3><a name="Extending_nn35">40.10.4 Configuration and preprocessing</a></H3>
 
 
 <p>
@@ -2692,7 +2734,7 @@
 <tt>python.swg</tt>.
 </p>
 
-<H3><a name="Extending_nn36">39.10.5 Entry point to code generation</a></H3>
+<H3><a name="Extending_nn36">40.10.5 Entry point to code generation</a></H3>
 
 
 <p>
@@ -2750,7 +2792,7 @@
 </pre>
 </div>
 
-<H3><a name="Extending_nn37">39.10.6 Module I/O and wrapper skeleton</a></H3>
+<H3><a name="Extending_nn37">40.10.6 Module I/O and wrapper skeleton</a></H3>
 
 
 <!-- please report bugs in this section to mgossage -->
@@ -2802,7 +2844,7 @@
   f_begin = NewFile(outfile, "w", SWIG_output_files());
   if (!f_begin) {
     FileErrorDisplay(outfile);
-    SWIG_exit(EXIT_FAILURE);
+    Exit(EXIT_FAILURE);
   }
   f_runtime = NewString("");
   f_init = NewString("");
@@ -2898,7 +2940,7 @@
 </pre>
 </div>
 
-<H3><a name="Extending_nn38">39.10.7 Low-level code generators</a></H3>
+<H3><a name="Extending_nn38">40.10.7 Low-level code generators</a></H3>
 
 
 <!-- please report bugs in this section to mgossage -->
@@ -2986,7 +3028,7 @@
   /* create the wrapper object */
   Wrapper *wrapper = NewWrapper();
 
-  /* create the functions wrappered name */
+  /* create the wrapper function's name */
   String *wname = Swig_name_wrapper(iname);
 
   /* deal with overloading */
@@ -2995,7 +3037,7 @@
   /* write the wrapper function definition */
   Printv(wrapper-&gt;def, "RETURN_TYPE ", wname, "(ARGS) {", NIL);
 
-  /* if any additional local variable needed, add them now */
+  /* if any additional local variables are needed, add them now */
   ...
 
   /* write the list of locals/arguments required */
@@ -3052,7 +3094,7 @@
 </p>
 
 
-<H3><a name="Extending_configuration_files">39.10.8 Configuration files</a></H3>
+<H3><a name="Extending_configuration_files">40.10.8 Configuration files</a></H3>
 
 
 <!-- please report bugs in this section to ttn -->
@@ -3107,7 +3149,7 @@
 <dd> This file is processed by
 
 <p>
-<A HREF="http://www.gnu.org/software/autoconf/">autoconf</A>
+<A HREF="https://www.gnu.org/software/autoconf/">autoconf</A>
 to generate the <TT>configure</TT> script.  This is where you
 need to add shell script fragments and autoconf macros to detect the
 presence of whatever development support your language module requires,
@@ -3196,7 +3238,7 @@
 </dl>
 
 
-<H3><a name="Extending_nn40">39.10.9 Runtime support</a></H3>
+<H3><a name="Extending_nn40">40.10.9 Runtime support</a></H3>
 
 
 <p>
@@ -3205,7 +3247,7 @@
 the SWIG files that implement those functions.
 </p>
 
-<H3><a name="Extending_nn41">39.10.10 Standard library files</a></H3>
+<H3><a name="Extending_nn41">40.10.10 Standard library files</a></H3>
 
 
 <p>
@@ -3224,7 +3266,7 @@
 Please copy these and modify for any new language.
 </p>
 
-<H3><a name="Extending_nn42">39.10.11 User examples</a></H3>
+<H3><a name="Extending_nn42">40.10.11 User examples</a></H3>
 
 
 <p>
@@ -3253,7 +3295,7 @@
 files</a>.
 </p>
 
-<H3><a name="Extending_test_suite">39.10.12 Test driven development and the test-suite</a></H3>
+<H3><a name="Extending_test_suite">40.10.12 Test driven development and the test-suite</a></H3>
 
 
 <p>
@@ -3312,7 +3354,7 @@
 but error/exception out with an error message on stderr on failure.
 </p>
 
-<H4><a name="Extending_running_test_suite">39.10.12.1 Running the test-suite</a></H4>
+<H4><a name="Extending_running_test_suite">40.10.12.1 Running the test-suite</a></H4>
 
 
 <p>
@@ -3455,7 +3497,7 @@
 The make variables <tt>SWIGTOOL</tt> and <tt>RUNTOOL</tt> are used to specify a tool to respectively, invoke SWIG 
 and the execution of the runtime test.
 You are advised to view the <tt>Examples/test-suite/common.mk</tt> file for details but for a short summary,
-the classic usage is to use <a href="http://valgrind.org/">Valgrind</a> for memory checking.
+the classic usage is to use <a href="https://valgrind.org/">Valgrind</a> for memory checking.
 For example, checking for memory leaks when running the runtime test in the target language interpreter:
 </p>
 
@@ -3504,7 +3546,7 @@
 The test cases used and the way it works is described in <tt>Examples/test-suite/errors/Makefile.in</tt>.
 </p>
 
-<H3><a name="Extending_nn43">39.10.13 Documentation</a></H3>
+<H3><a name="Extending_nn43">40.10.13 Documentation</a></H3>
 
 
 <p>
@@ -3536,7 +3578,7 @@
      if available.
 </ul>
 
-<H3><a name="Extending_coding_style_guidelines">39.10.14 Coding style guidelines</a></H3>
+<H3><a name="Extending_coding_style_guidelines">40.10.14 Coding style guidelines</a></H3>
 
 
 <p>
@@ -3561,7 +3603,7 @@
 </p>
 
 
-<H3><a name="Extending_language_status">39.10.15 Target language status</a></H3>
+<H3><a name="Extending_language_status">40.10.15 Target language status</a></H3>
 
 
 <p>
@@ -3570,7 +3612,7 @@
 This section provides more details on how this status is given.
 </p>
 
-<H4><a name="Extending_supported_status">39.10.15.1 Supported status</a></H4>
+<H4><a name="Extending_supported_status">40.10.15.1 Supported status</a></H4>
 
 
 <p>
@@ -3588,7 +3630,7 @@
 <li>
   It passes all of the main SWIG test-suite.
   The main test-suite is defined by the tests in the C_TEST_CASES, CPP_TEST_CASES and MULTI_CPP_TEST_CASES lists in Examples/test-suite/common.mk.
-  The tests in CPP11_TEST_CASES will also be required in the near future.
+  All the newer C++ standard tests need to work and are grouped together, such as CPP11_TEST_CASES for C++11. These more 'modern' C++ standards are only tested though if the compiler is detected as supporting the given standard.
 </li>
 <li>
   The test-suite must also include at least twenty wide-ranging runtime tests.
@@ -3607,17 +3649,17 @@
   A major or minor version is the first or second digit in the three digit version.
 </li>
 <li>
-  Fixing unintended regressions in the Supported languages will be given higher priority over experimental languages by the core SWIG developers.
+  Fixing unintended regressions in the Supported languages will be given higher priority over the Experimental languages by the core SWIG developers.
 </li>
 <li>
   Examples must be available and run successfully.
 </li>
 <li>
-  The examples and test-suite must be fully functioning on the Travis Continuous Integration platform.
+  The examples and test-suite must be fully functioning on the Github Actions Continuous Integration platform.
 </li>
 </ul>
 
-<H4><a name="Extending_experimental_status">39.10.15.2 Experimental status</a></H4>
+<H4><a name="Extending_experimental_status">40.10.15.2 Experimental status</a></H4>
 
 
 <p>
@@ -3660,9 +3702,9 @@
   The number of tests in these lists should be no greater than half of the number of tests in the full test-suite.
 </li>
 <li>
-  The examples and test-suite must also be fully functioning on the Travis Continuous Integration platform.
-  However, experimental languages will be set as 'allow_failures'.
-  This means that pull requests and normal development commits will not break the entire Travis build should an experimental language fail.
+  The examples and test-suite must also be fully functioning on the Github Actions Continuous Integration platform.
+  However, experimental languages will be flagged as 'continue-on-error'.
+  This means that pull requests and normal development commits will not break the entire Github Actions build should an experimental language fail.
 </li>
 <li>
   Any new failed tests will be fixed on a 'best effort' basis by core developers with no promises made.
@@ -3682,7 +3724,7 @@
 </li>
 </ul>
 
-<H3><a name="Extending_prerequisites">39.10.16 Prerequisites for adding a new language module to the SWIG distribution</a></H3>
+<H3><a name="Extending_prerequisites">40.10.16 Prerequisites for adding a new language module to the SWIG distribution</a></H3>
 
 
 <p>
@@ -3746,7 +3788,7 @@
 </p>
 
 
-<H2><a name="Extending_debugging_options">39.11 Debugging Options</a></H2>
+<H2><a name="Extending_debugging_options">40.11 Debugging Options</a></H2>
 
 
 <p>
@@ -3760,6 +3802,7 @@
 -debug-symbols    - Display target language symbols in the symbol tables
 -debug-csymbols   - Display C symbols in the symbol tables
 -debug-lsymbols   - Display target language layer symbols
+-debug-quiet      - Display less parse tree node debug info when using other -debug options
 -debug-tags       - Display information about the tags found in the interface
 -debug-template   - Display information for debugging templates
 -debug-top &lt;n&gt;    - Display entire parse tree at stages 1-4, &lt;n&gt; is a csv list of stages
@@ -3773,7 +3816,7 @@
 The complete list of command line options for SWIG are available by running <tt>swig -help</tt>.
 </p>
 
-<H2><a name="Extending_nn46">39.12 Guide to parse tree nodes</a></H2>
+<H2><a name="Extending_nn46">40.12 Guide to parse tree nodes</a></H2>
 
 
 <p>
@@ -4181,7 +4224,7 @@
 </pre>
 </div>
 
-<H2><a name="Extending_further_info">39.13 Further Development Information</a></H2>
+<H2><a name="Extending_further_info">40.13 Further Development Information</a></H2>
 
 
 <p>
diff --git a/Doc/Manual/Go.html b/Doc/Manual/Go.html
index c28cc03..5b774bc 100644
--- a/Doc/Manual/Go.html
+++ b/Doc/Manual/Go.html
@@ -6,7 +6,7 @@
 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 </head>
 <body bgcolor="#FFFFFF">
-<H1><a name="Go">24 SWIG and Go</a></H1>
+<H1><a name="Go">25 SWIG and Go</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -29,6 +29,8 @@
 <li><a href="#Go_class_inheritance">Go Class Inheritance</a>
 </ul>
 <li><a href="#Go_templates">Go Templates</a>
+<li><a href="#Go_threads">Go and C/C++ Threads</a>
+<li><a href="#Go_exceptions">Go and C++ Exceptions</a>
 <li><a href="#Go_director_classes">Go Director Classes</a>
 <ul>
 <li><a href="#Go_director_example_cpp_code">Example C++ code</a>
@@ -54,10 +56,10 @@
 <p>
 This chapter describes SWIG's support of Go.  For more information on
 the Go programming language
-see <a href="http://golang.org/">golang.org</a>.
+see <a href="https://golang.org/">golang.org</a>.
 </p>
 
-<H2><a name="Go_overview">24.1 Overview</a></H2>
+<H2><a name="Go_overview">25.1 Overview</a></H2>
 
 
 <p>
@@ -71,6 +73,7 @@
 There are (at least) two different Go compilers.  The first is the gc compiler
 of the <a href="https://golang.org/doc/install">Go distribution</a>, normally
 invoked via the <a href="https://golang.org/cmd/go/">go tool</a>.
+SWIG supports the gc compiler version 1.2 or later.
 The second Go compiler is the <a href="https://golang.org/doc/install/gccgo">
 gccgo compiler</a>, which is a frontend to the GCC compiler suite.
 The interface to C/C++ code is completely different for the two Go compilers.
@@ -86,7 +89,7 @@
 are not used.
 </p>
 
-<H2><a name="Go_examples">24.2 Examples</a></H2>
+<H2><a name="Go_examples">25.2 Examples</a></H2>
 
 
 <p>
@@ -101,7 +104,7 @@
 </p>
 
 
-<H2><a name="Go_running_swig">24.3 Running SWIG with Go</a></H2>
+<H2><a name="Go_running_swig">25.3 Running SWIG with Go</a></H2>
 
 
 <p>
@@ -142,46 +145,8 @@
 usual.
 </p>
 
-<p>
-SWIG can be used without cgo, via the <tt>-no-cgo</tt> option, but
-more steps are required.  This only works with Go versions before 1.5.
-When using Go version 1.2 or later, or when using gccgo, the code
-generated by SWIG can be linked directly into the Go program.  A
-typical command sequence when using the Go compiler of the Go
-distribution would look like this:
-</p>
 
-<div class="code"><pre>
-% swig -go -no-cgo example.i
-% gcc -c code.c    # The C library being wrapped.
-% gcc -c example_wrap.c
-% go tool 6g example.go
-% go tool 6c example_gc.c
-% go tool pack grc example.a example.6 example_gc.6 code.o example_wrap.o
-% go tool 6g main.go
-% go tool 6l main.6
-</pre></div>
-
-<p>
-You can also put the wrapped code into a shared library, and when using the Go
-versions before 1.2 this is the only supported option.  A typical command
-sequence for this approach would look like this:
-</p>
-
-<div class="code"><pre>
-% swig -go -no-cgo -use-shlib example.i
-% gcc -c -fpic example.c
-% gcc -c -fpic example_wrap.c
-% gcc -shared example.o example_wrap.o -o example.so
-% go tool 6g example.go
-% go tool 6c example_gc.c
-% go tool pack grc example.a example.6 example_gc.6
-% go tool 6g main.go  # your code, not generated by SWIG
-% go tool 6l main.6
-</pre></div>
-
-
-<H3><a name="Go_commandline">24.3.1 Go-specific Commandline Options</a></H3>
+<H3><a name="Go_commandline">25.3.1 Go-specific Commandline Options</a></H3>
 
 
 <p>
@@ -206,19 +171,17 @@
 
 <tr>
 <td>-no-cgo</td>
-<td>Generate files that can be used directly, rather than via the Go
-  cgo tool.  This option does not work with Go 1.5 or later.  It is
-  required for versions of Go before 1.2.</td>
+<td>This option is no longer supported.</td>
 </tr>
 
 <tr>
 <td>-intgosize &lt;s&gt;</td>
 <td>Set the size for the Go type <tt>int</tt>.  This controls the size
   that the C/C++ code expects to see.  The &lt;s&gt; argument should
-  be 32 or 64.  This option is currently required during the
+  be 32 or 64.  This option was required during the
   transition from Go 1.0 to Go 1.1, as the size of <tt>int</tt> on
-  64-bit x86 systems changes between those releases (from 32 bits to
-  64 bits).  In the future the option may become optional, and SWIG
+  64-bit x86 systems changed between those releases (from 32 bits to
+  64 bits).  It was made optional in SWIG 4.1.0 and if not specified SWIG
   will assume that the size of <tt>int</tt> is the size of a C
   pointer.</td>
 </tr>
@@ -276,16 +239,13 @@
 </table>
 
 
-<H3><a name="Go_outputs">24.3.2 Generated Wrapper Files</a></H3>
+<H3><a name="Go_outputs">25.3.2 Generated Wrapper Files</a></H3>
 
 
-<p>There are two different approaches to generating wrapper files,
-  controlled by SWIG's <tt>-no-cgo</tt> option.  The <tt>-no-cgo</tt>
-  option only works with version of Go before 1.5.  It is required
-  when using versions of Go before 1.2.</p>
-
-<p>With or without the <tt>-no-cgo</tt> option, SWIG will generate the
-  following files when generating wrapper code:</p>
+<p>
+SWIG will generate the following files when generating wrapper
+code:
+</p>
 
 <ul>
 <li>
@@ -308,19 +268,8 @@
 </li>
 </ul>
 
-<p>When the <tt>-no-cgo</tt> option is used, and the <tt>-gccgo</tt>
-  option is not used, SWIG will also generate an additional file:</p>
 
-<ul>
-<li>
-MODULE_gc.c will contain C code which should be compiled with the C
-compiler distributed as part of the gc compiler.  It should then be
-combined with the compiled MODULE.go using go tool pack.
-</li>
-</ul>
-
-
-<H2><a name="Go_basic_tour">24.4 A tour of basic C/C++ wrapping</a></H2>
+<H2><a name="Go_basic_tour">25.4 A tour of basic C/C++ wrapping</a></H2>
 
 
 <p>
@@ -330,7 +279,7 @@
 essential aspects of this wrapping.
 </p>
 
-<H3><a name="Go_package">24.4.1 Go Package Name</a></H3>
+<H3><a name="Go_package">25.4.1 Go Package Name</a></H3>
 
 
 <p>
@@ -340,7 +289,7 @@
 command line option.
 </p>
 
-<H3><a name="Go_names">24.4.2 Go Names</a></H3>
+<H3><a name="Go_names">25.4.2 Go Names</a></H3>
 
 
 <p>
@@ -372,7 +321,7 @@
 named <tt>Delete</tt> followed by that name.
 </p>
 
-<H3><a name="Go_constants">24.4.3 Go Constants</a></H3>
+<H3><a name="Go_constants">25.4.3 Go Constants</a></H3>
 
 
 <p>
@@ -380,7 +329,7 @@
 directive become Go constants, declared with a <tt>const</tt>
 declaration.
 
-<H3><a name="Go_enumerations">24.4.4 Go Enumerations</a></H3>
+<H3><a name="Go_enumerations">25.4.4 Go Enumerations</a></H3>
 
 
 <p>
@@ -390,7 +339,7 @@
 code should avoid modifying those variables.
 </p>
 
-<H3><a name="Go_classes">24.4.5 Go Classes</a></H3>
+<H3><a name="Go_classes">25.4.5 Go Classes</a></H3>
 
 
 <p>
@@ -468,7 +417,7 @@
 for this by calling the Swigcptr() method.
 </p>
 
-<H4><a name="Go_class_memory">24.4.5.1 Go Class Memory Management</a></H4>
+<H4><a name="Go_class_memory">25.4.5.1 Go Class Memory Management</a></H4>
 
 
 <p>
@@ -547,10 +496,6 @@
 predictable when the finalizer will run and this might require a Close or Delete
 method to be added the Go object that stores a C++ object to mitigate.
 </li>
-<li>
-The Go finalizer function typically runs in a different OS thread which can be
-problematic with C++ code that uses thread-local storage.
-</li>
 </ul>
 
 <p>
@@ -590,7 +535,7 @@
 </pre>
 </div>
 
-<H4><a name="Go_class_inheritance">24.4.5.2 Go Class Inheritance</a></H4>
+<H4><a name="Go_class_inheritance">25.4.5.2 Go Class Inheritance</a></H4>
 
 
 <p>
@@ -602,7 +547,7 @@
 be checked dynamically.
 </p>
 
-<H3><a name="Go_templates">24.4.6 Go Templates</a></H3>
+<H3><a name="Go_templates">25.4.6 Go Templates</a></H3>
 
 
 <p>
@@ -610,8 +555,37 @@
 wrappers for a particular template instantiation.  To do this, use
 the <tt>%template</tt> directive.
 
+<H3><a name="Go_threads">25.4.7 Go and C/C++ Threads</a></H3>
 
-<H3><a name="Go_director_classes">24.4.7 Go Director Classes</a></H3>
+
+<p>
+C and C++ code can use operating system threads and thread local
+storage.  Go code uses goroutines, which are multiplexed onto
+operating system threads.  This multiplexing means that Go code can
+change to run on a different thread at any time.  C/C++ code, on the
+other hand, may assume that it runs on a single thread; this is true
+in particular if the C/C++ code uses thread local storage.
+</p>
+
+<p>
+In order to use Go code with C/C++ code that expects to run on a
+single thread, the Go code must call
+the <a href="https://pkg.go.dev/runtime#LockOSThread"><code>runtime.LockOSThread</code></a>
+function to lock the goroutine onto a single thread.
+</p>
+
+<H3><a name="Go_exceptions">25.4.8 Go and C++ Exceptions</a></H3>
+
+
+<p>
+C++ exceptions do not interoperate with Go code.  Attempts to throw
+C++ exceptions through a Go caller are unreliable: in many cases the
+C++ exception handler will be unable to unwind the stack, and the
+program will crash.  The only safe way to handle C++ exceptions is to
+catch them in C++ before returning to Go.
+</p>
+
+<H3><a name="Go_director_classes">25.4.9 Go Director Classes</a></H3>
 
 
 <p>
@@ -629,7 +603,7 @@
 </p>
 
 
-<H4><a name="Go_director_example_cpp_code">24.4.7.1 Example C++ code</a></H4>
+<H4><a name="Go_director_example_cpp_code">25.4.9.1 Example C++ code</a></H4>
 
 
 <p>
@@ -701,7 +675,7 @@
 </p>
 
 
-<H4><a name="Go_director_enable">24.4.7.2 Enable director feature</a></H4>
+<H4><a name="Go_director_enable">25.4.9.2 Enable director feature</a></H4>
 
 
 <p>
@@ -736,7 +710,7 @@
 </p>
 
 
-<H4><a name="Go_director_ctor_dtor">24.4.7.3 Constructor and destructor</a></H4>
+<H4><a name="Go_director_ctor_dtor">25.4.9.3 Constructor and destructor</a></H4>
 
 
 <p>
@@ -789,7 +763,7 @@
 </p>
 
 
-<H4><a name="Go_director_overriding">24.4.7.4 Override virtual methods</a></H4>
+<H4><a name="Go_director_overriding">25.4.9.4 Override virtual methods</a></H4>
 
 
 <p>
@@ -857,7 +831,7 @@
 </p>
 
 
-<H4><a name="Go_director_base_methods">24.4.7.5 Call base methods</a></H4>
+<H4><a name="Go_director_base_methods">25.4.9.5 Call base methods</a></H4>
 
 
 <p>
@@ -894,7 +868,7 @@
 </p>
 
 
-<H4><a name="Go_director_subclass">24.4.7.6 Subclass via embedding</a></H4>
+<H4><a name="Go_director_subclass">25.4.9.6 Subclass via embedding</a></H4>
 
 
 <p>
@@ -962,7 +936,7 @@
 </p>
 
 
-<H4><a name="Go_director_finalizer">24.4.7.7 Memory management with runtime.SetFinalizer</a></H4>
+<H4><a name="Go_director_finalizer">25.4.9.7 Memory management with runtime.SetFinalizer</a></H4>
 
 
 <p>
@@ -1027,7 +1001,7 @@
 </p>
 
 
-<H4><a name="Go_director_foobargo_class">24.4.7.8 Complete FooBarGo example class</a></H4>
+<H4><a name="Go_director_foobargo_class">25.4.9.8 Complete FooBarGo example class</a></H4>
 
 
 <p>
@@ -1156,7 +1130,7 @@
 </p>
 
 
-<H3><a name="Go_primitive_type_mappings">24.4.8 Default Go primitive type mappings</a></H3>
+<H3><a name="Go_primitive_type_mappings">25.4.10 Default Go primitive type mappings</a></H3>
 
 
 <p>
@@ -1263,7 +1237,7 @@
 into Go types.
 </p>
 
-<H3><a name="Go_output_arguments">24.4.9 Output arguments</a></H3>
+<H3><a name="Go_output_arguments">25.4.11 Output arguments</a></H3>
 
 
 <p>Because of limitations in the way output arguments are processed in swig,
@@ -1316,7 +1290,7 @@
 </pre>
 </div>
 
-<H3><a name="Go_adding_additional_code">24.4.10 Adding additional go code</a></H3>
+<H3><a name="Go_adding_additional_code">25.4.12 Adding additional go code</a></H3>
 
 
 <p>Often the APIs generated by swig are not very natural in go, especially if
@@ -1411,7 +1385,7 @@
 </pre>
 </div>
 
-<H3><a name="Go_typemaps">24.4.11 Go typemaps</a></H3>
+<H3><a name="Go_typemaps">25.4.13 Go typemaps</a></H3>
 
 
 <p>
@@ -1450,7 +1424,7 @@
 <td>
 An intermediate Go type used by the "goin", "goout", "godirectorin",
 and "godirectorout" typemaps.  If this typemap is not defined for a
-C/C++ type, the gotype typemape will be used.  This is useful when
+C/C++ type, the gotype typemap will be used.  This is useful when
 gotype is best converted to C/C++ using Go code.
 </td>
 </tr>
diff --git a/Doc/Manual/Guile.html b/Doc/Manual/Guile.html
index 31d8225..b39b393 100644
--- a/Doc/Manual/Guile.html
+++ b/Doc/Manual/Guile.html
@@ -8,7 +8,7 @@
 
 <body bgcolor="#ffffff">
 
-<H1><a name="Guile">25 SWIG and Guile</a></H1>
+<H1><a name="Guile">26 SWIG and Guile</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -48,21 +48,22 @@
 <p>
 This section details guile-specific support in SWIG.
 
-<H2><a name="Guile_nn1">25.1 Supported Guile Versions</a></H2>
+<H2><a name="Guile_nn1">26.1 Supported Guile Versions</a></H2>
 
 
 <p>
-SWIG works with Guile versions 1.8.x and 2.0.x. Support for version
-1.6.x has been dropped. The last version of SWIG that still works with
-Guile version 1.6.x is SWIG 2.0.9.
+SWIG is known to work with Guile versions 2.0.x, 2.2.x and 3.0.x (these are
+all tested via CI). SWIG probably still works with Guile 1.8.x but we're no
+longer able to regularly test this either in CI or by hand. Support for Guile
+1.6.x has been dropped (SWIG 2.0.9 was the last version of SWIG to support it).
 
 <p>
 Note that starting with guile 2.0, the guile sources can be compiled for
 improved performance. This is currently not tested with swig
 so your mileage may vary. To be safe set environment variable
-GUILE_AUTO_COMPILE to 0 when using swig generated guile code.
+<tt>GUILE_AUTO_COMPILE</tt> to 0 when using swig generated guile code.
 
-<H2><a name="Guile_nn2">25.2 Meaning of "Module"</a></H2>
+<H2><a name="Guile_nn2">26.2 Meaning of "Module"</a></H2>
 
 
 <p>
@@ -70,18 +71,18 @@
 separately for SWIG, Guile, and Libtool.  To avoid horrible confusion,
 we explicitly prefix the context, e.g., "guile-module".
 
-<H2><a name="Guile_nn3">25.3 Old GH Guile API</a></H2>
+<H2><a name="Guile_nn3">26.3 Old GH Guile API</a></H2>
 
 
 <p>Guile 1.8 and older could be interfaced using two different api's, the SCM
 or the GH API. The GH interface to guile is deprecated.  Read more about why in the 
-<a href="http://www.gnu.org/software/guile/docs/docs-1.6/guile-ref/GH.html#GH">Guile manual</a>.
+<a href="https://www.gnu.org/software/guile/docs/docs-1.6/guile-ref/GH.html#GH">Guile manual</a>.
 
 <p>Support for the guile GH wrapper code generation has been dropped from SWIG. The last
 version of SWIG that can still generate guile GH wrapper code is 2.0.9. Please
 use that version if you really need the GH wrapper code.
 
-<H2><a name="Guile_nn4">25.4 Linkage</a></H2>
+<H2><a name="Guile_nn4">26.4 Linkage</a></H2>
 
 
 <p>
@@ -89,7 +90,7 @@
 which manifests in multiple shared-library usage conventions.  A set of
 policies implementing a usage convention is called a <b>linkage</b>.
 
-<H3><a name="Guile_nn5">25.4.1 Simple Linkage</a></H3>
+<H3><a name="Guile_nn5">26.4.1 Simple Linkage</a></H3>
 
 
 <p>
@@ -183,7 +184,7 @@
 </div>
 
 <p>
-(The <code>%scheme</code> directive allows to insert arbitrary Scheme
+(The <code>%scheme</code> directive allows inserting arbitrary Scheme
 code into the generated file <code><var>module.scm</var></code>; it is
 placed between the <code>define-module</code> form and the
 <code>export</code> form.)
@@ -194,7 +195,7 @@
 <code>SWIG_init</code> via a preprocessor define to avoid symbol
 clashes. For this case, however, passive linkage is available.
 
-<H3><a name="Guile_nn6">25.4.2 Passive Linkage</a></H3>
+<H3><a name="Guile_nn6">26.4.2 Passive Linkage</a></H3>
 
 
 <p>Passive linkage is just like simple linkage, but it generates an
@@ -204,7 +205,7 @@
 <p>You should use passive linkage rather than simple linkage when you
 are using multiple modules.
 
-<H3><a name="Guile_nn7">25.4.3 Native Guile Module Linkage</a></H3>
+<H3><a name="Guile_nn7">26.4.3 Native Guile Module Linkage</a></H3>
 
 
 <p>SWIG can also generate wrapper code that does all the Guile module
@@ -245,33 +246,16 @@
 </div>
 </ul>
 
-<H3><a name="Guile_nn8">25.4.4 Old Auto-Loading Guile Module Linkage</a></H3>
+<H3><a name="Guile_nn8">26.4.4 Old Auto-Loading Guile Module Linkage</a></H3>
 
 
 <p>Guile used to support an autoloading facility for object-code
-modules. This support has been marked deprecated in version 1.4.1 and
-is going to disappear sooner or later. SWIG still supports building
-auto-loading modules if you pass it the <code>-Linkage ltdlmod</code>
-command-line option.
-
-<p>Auto-loading worked like this: Suppose a module with name <code>(my
-lib foo)</code> is required and not loaded yet.  Guile will then search
-all directories in its search path
-for a Scheme file <code>my/modules/foo.scm</code> or a shared library
-<code><var>my</var>/<var>modules</var>/lib<var>foo</var>.so</code> (or
-<code><var>my</var>/<var>modules</var>/lib<var>foo</var>.la</code>; 
-see the GNU libtool documentation). If a
-shared library is found that contains the symbol
-<code>scm_init_<var>my</var>_<var>modules</var>_<var>foo</var>_module</code>, 
-the library is loaded, and the function at that symbol is called with
-no arguments in order to initialize the module.
-
-<p>When invoked with the <code>-Linkage ltdlmod</code> command-line
-option, SWIG generates an exported module initialization function with
-an appropriate name. 
+modules, but this support was deprecated and removed in Guile version 1.4.1.
+SWIG supported this via option <code>-Linkage ltdlmod</code>, but this
+support is no longer useful and was removed in SWIG 4.2.0.
 
 
-<H3><a name="Guile_nn9">25.4.5 Hobbit4D Linkage</a></H3>
+<H3><a name="Guile_nn9">26.4.5 Hobbit4D Linkage</a></H3>
 
 
 <p>
@@ -296,19 +280,21 @@
 experimental; the (hobbit4d link) conventions are not well understood.
 </p>
 
-<H2><a name="Guile_nn10">25.5 Underscore Folding</a></H2>
+<H2><a name="Guile_nn10">26.5 Underscore Folding</a></H2>
 
 
 <p>
 Underscores are converted to dashes in identifiers.  Guile support may
 grow an option to inhibit this folding in the future, but no one has
 complained so far.
+</p>
 
-<p>You can use the SWIG directives <code>%name</code> and
-<code>%rename</code> to specify the Guile name of the wrapped
-functions and variables (see CHANGES).
+<p>You can use the <a href="SWIG.html#SWIG_rename_ignore">SWIG
+directive <code>%rename</code></a> to specify the Guile
+names of the wrapped functions and variables.
+</p>
 
-<H2><a name="Guile_nn11">25.6 Typemaps</a></H2>
+<H2><a name="Guile_nn11">26.6 Typemaps</a></H2>
 
 
 <p>
@@ -400,7 +386,7 @@
 <a href="Customization.html#Customization_features">Features and the %feature directive</a>
 for info on how to apply the %feature.</p>
 
-<H2><a name="Guile_nn12">25.7 Representation of pointers as smobs</a></H2>
+<H2><a name="Guile_nn12">26.7 Representation of pointers as smobs</a></H2>
 
 
 <p>
@@ -421,7 +407,7 @@
 If the Scheme object passed was not a SWIG smob representing a compatible
 pointer, a <code>wrong-type-arg</code> exception is raised.
 
-<H3><a name="Guile_nn14">25.7.1 Smobs</a></H3>
+<H3><a name="Guile_nn14">26.7.1 Smobs</a></H3>
 
 
 <p>
@@ -440,7 +426,7 @@
 the corresponding GOOPS class.</p>
 
 
-<H3><a name="Guile_nn15">25.7.2 Garbage Collection</a></H3>
+<H3><a name="Guile_nn15">26.7.2 Garbage Collection</a></H3>
 
 
 <p>Garbage collection is a feature of Guile since version 1.6. As SWIG now requires Guile &gt; 1.8,
@@ -454,14 +440,14 @@
 Object ownership and %newobject</a> in the SWIG manual.  All typemaps use an $owner var, and
 the guile module replaces $owner with 0 or 1 depending on feature:new.</p>
 
-<H2><a name="Guile_nn16">25.8 Native Guile pointers</a></H2>
+<H2><a name="Guile_nn16">26.8 Native Guile pointers</a></H2>
 
 
 <p>
 In addition to SWIG smob pointers, <a href="https://www.gnu.org/software/guile/manual/html_node/Foreign-Pointers.html">Guile's native pointer type</a> are accepted as arguments to wrapped SWIG functions. This can be useful for passing <a href="https://www.gnu.org/software/guile/manual/html_node/Void-Pointers-and-Byte-Access.html#">pointers to bytevector data</a> to wrapped functions.
 </p>
 
-<H2><a name="Guile_nn17">25.9 Exception Handling</a></H2>
+<H2><a name="Guile_nn17">26.9 Exception Handling</a></H2>
 
 
 <p>
@@ -487,7 +473,7 @@
 The default when not specified here is to use "swig-error".
 See Lib/exception.i for details.
 
-<H2><a name="Guile_nn18">25.10 Procedure documentation</a></H2>
+<H2><a name="Guile_nn18">26.10 Procedure documentation</a></H2>
 
 
 <p>If invoked with the command-line option <code>-procdoc
@@ -522,7 +508,7 @@
 typemap argument <code>doc</code>. See <code>Lib/guile/typemaps.i</code> for
 details.
 
-<H2><a name="Guile_nn19">25.11 Procedures with setters</a></H2>
+<H2><a name="Guile_nn19">26.11 Procedures with setters</a></H2>
 
 
 <p>For global variables, SWIG creates a single wrapper procedure
@@ -550,7 +536,7 @@
 pointer)</code> and <code>(<var>struct-member</var>-set pointer
 value)</code> are <em>not</em> generated.
 
-<H2><a name="Guile_nn20">25.12 GOOPS Proxy Classes</a></H2>
+<H2><a name="Guile_nn20">26.12 GOOPS Proxy Classes</a></H2>
 
 
 <p>SWIG can also generate classes and generic functions for use with
@@ -696,7 +682,7 @@
 <code>%import "foo.h"</code> before the <code>%inline</code> block.
 </p>
 
-<H3><a name="Guile_nn21">25.12.1 Naming Issues</a></H3>
+<H3><a name="Guile_nn21">26.12.1 Naming Issues</a></H3>
 
 
 <p>As you can see in the example above, there are potential naming conflicts.  The default exported
@@ -733,7 +719,7 @@
 (use-modules ((Test) #:renamer (symbol-prefix-proc 'goops:)))
 </pre></div>
 
-<H3><a name="Guile_nn22">25.12.2 Linking</a></H3>
+<H3><a name="Guile_nn22">26.12.2 Linking</a></H3>
 
 
 <p>The guile-modules generated above all need to be linked together.  GOOPS support requires
diff --git a/Doc/Manual/Introduction.html b/Doc/Manual/Introduction.html
index 8d161b7..fa5be4f 100644
--- a/Doc/Manual/Introduction.html
+++ b/Doc/Manual/Introduction.html
@@ -172,7 +172,7 @@
 
 <p>
 The second part of the SWIG documentation contains a chapter for each target level language.
-Each chapter will state the status (Supported or Experimental) for that language.
+The target language chapters are under one of two sections indicating the status (Supported or Experimental) for that language.
 </p>
 
 <H3><a name="Introduction_supported_status">2.3.1 Supported status</a></H3>
@@ -416,6 +416,7 @@
 Most of C++11 is also supported. Details are in the <a href="CPlusPlus11.html#CPlusPlus11">C++11</a> chapter.
 C++14 support is covered in the <a href="CPlusPlus14.html#CPlusPlus14">C++14</a> chapter.
 C++17 support is covered in the <a href="CPlusPlus17.html#CPlusPlus17">C++17</a> chapter.
+C++20 support is covered in the <a href="CPlusPlus20.html#CPlusPlus20">C++20</a> chapter.
 </p>
 
 <p>
@@ -452,14 +453,14 @@
 
 <p>
 If you are using the GNU Autotools 
-(<a href="http://www.gnu.org/software/autoconf/">Autoconf</a>/
-<a href="http://www.gnu.org/software/automake/">Automake</a>/
-<a href="http://www.gnu.org/software/libtool/">Libtool</a>)
+(<a href="https://www.gnu.org/software/autoconf/">Autoconf</a>/
+<a href="https://www.gnu.org/software/automake/">Automake</a>/
+<a href="https://www.gnu.org/software/libtool/">Libtool</a>)
 to configure SWIG use in your project, the SWIG Autoconf macros can be used.
 The primary macro is <tt>ax_pkg_swig</tt>, see
-<a href="http://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html#ax_pkg_swig">http://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html#ax_pkg_swig</a>.
+<a href="https://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html#ax_pkg_swig">http://www.gnu.org/software/autoconf-archive/ax_pkg_swig.html#ax_pkg_swig</a>.
 The <tt>ax_python_devel</tt> macro is also helpful for generating Python extensions. See the 
-<a href="http://www.gnu.org/software/autoconf-archive/">Autoconf Archive</a>
+<a href="https://www.gnu.org/software/autoconf-archive/">Autoconf Archive</a>
 for further information on this and other Autoconf macros.
 </p>
 
diff --git a/Doc/Manual/Java.html b/Doc/Manual/Java.html
index db5f041..570c600 100644
--- a/Doc/Manual/Java.html
+++ b/Doc/Manual/Java.html
@@ -6,7 +6,7 @@
 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 </head>
 <body bgcolor="#FFFFFF">
-<H1><a name="Java">26 SWIG and Java</a></H1>
+<H1><a name="Java">27 SWIG and Java</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -106,6 +106,7 @@
 <li><a href="#Java_proxycode">Class extension with %proxycode</a>
 <li><a href="#Java_exception_handling">Exception handling with %exception and %javaexception</a>
 <li><a href="#Java_method_access">Method access with %javamethodmodifiers</a>
+<li><a href="#Java_begin">Java begin</a>
 </ul>
 <li><a href="#Java_tips_techniques">Tips and techniques</a>
 <ul>
@@ -167,7 +168,7 @@
 </p>
 
 
-<H2><a name="Java_overview">26.1 Overview</a></H2>
+<H2><a name="Java_overview">27.1 Overview</a></H2>
 
 
 <p>
@@ -202,7 +203,7 @@
 The latter sections cover the advanced techniques of using typemaps for complete control of the wrapping process.
 </p>
 
-<H2><a name="Java_preliminaries">26.2 Preliminaries</a></H2>
+<H2><a name="Java_preliminaries">27.2 Preliminaries</a></H2>
 
 
 <p>
@@ -222,7 +223,7 @@
 Android uses Java JNI and also works with SWIG. Please read the <a href="Android.html#Android">Android chapter</a> in conjunction with this one if you are targeting Android.
 </p>
 
-<H3><a name="Java_running_swig">26.2.1 Running SWIG</a></H3>
+<H3><a name="Java_running_swig">27.2.1 Running SWIG</a></H3>
 
 
 <p>
@@ -281,7 +282,7 @@
 compiling and using the generated files.
 </p>
 
-<H3><a name="Java_commandline">26.2.2 Additional Commandline Options</a></H3>
+<H3><a name="Java_commandline">27.2.2 Additional Commandline Options</a></H3>
 
 
 <p>
@@ -318,7 +319,7 @@
 Their use will become clearer by the time you have finished reading this section on SWIG and Java.
 </p>
 
-<H3><a name="Java_getting_right_headers">26.2.3 Getting the right header files</a></H3>
+<H3><a name="Java_getting_right_headers">27.2.3 Getting the right header files</a></H3>
 
 
 <p>
@@ -333,7 +334,7 @@
 <p>
 The exact location may vary on your machine, but the above locations are typical. </p>
 
-<H3><a name="Java_compiling_dynamic">26.2.4 Compiling a dynamic module</a></H3>
+<H3><a name="Java_compiling_dynamic">27.2.4 Compiling a dynamic module</a></H3>
 
 
 <p>
@@ -368,7 +369,7 @@
 If the name of your SWIG module is "<tt>example</tt>", the name of the corresponding shared library file should be "<tt>libexample.so</tt>" (or equivalent depending on your machine, see <a href="#Java_dynamic_linking_problems">Dynamic linking problems</a> for more information). 
 The name of the module is specified using the <tt>%module</tt> directive or <tt>-module</tt> command line option.</p>
 
-<H3><a name="Java_using_module">26.2.5 Using your module</a></H3>
+<H3><a name="Java_using_module">27.2.5 Using your module</a></H3>
 
 
 <p>
@@ -403,7 +404,7 @@
 If it doesn't work have a look at the following section which discusses problems loading the shared library.
 </p>
 
-<H3><a name="Java_dynamic_linking_problems">26.2.6 Dynamic linking problems</a></H3>
+<H3><a name="Java_dynamic_linking_problems">27.2.6 Dynamic linking problems</a></H3>
 
 
 <p>
@@ -490,7 +491,7 @@
 </p>
 
 
-<H3><a name="Java_compilation_problems_cpp">26.2.7 Compilation problems and compiling with C++</a></H3>
+<H3><a name="Java_compilation_problems_cpp">27.2.7 Compilation problems and compiling with C++</a></H3>
 
 
 <p>
@@ -542,7 +543,7 @@
 </p>
 
 
-<H3><a name="Java_building_windows">26.2.8 Building on Windows</a></H3>
+<H3><a name="Java_building_windows">27.2.8 Building on Windows</a></H3>
 
 
 <p>
@@ -551,7 +552,7 @@
 This section covers the process of using SWIG with Microsoft Visual C++ 6 although the procedure may be similar with other compilers.  
 In order for everything to work, you will need to have a JDK installed on your machine in order to read the JNI header files.</p>
 
-<H4><a name="Java_visual_studio">26.2.8.1 Running SWIG from Visual Studio</a></H4>
+<H4><a name="Java_visual_studio">27.2.8.1 Running SWIG from Visual Studio</a></H4>
 
 
 <p>
@@ -590,7 +591,7 @@
 If the library fails to load have a look at <a href="#Java_dynamic_linking_problems">Dynamic linking problems</a>.
 </p>
 
-<H4><a name="Java_nmake">26.2.8.2 Using NMAKE</a></H4>
+<H4><a name="Java_nmake">27.2.8.2 Using NMAKE</a></H4>
 
 
 <p>
@@ -644,12 +645,12 @@
 
 <p>
 To build the DLL and compile the java code, run NMAKE (you may need to run <tt>vcvars32</tt> first). 
-This is a pretty simplistic Makefile, but hopefully its enough to get you started.
+This is a pretty simplistic Makefile, but hopefully it's enough to get you started.
 Of course you may want to make changes for it to work for C++ by adding in the -c++ command line option for swig and replacing .c with .cxx.
 </p>
 
 
-<H2><a name="Java_basic_tour">26.3 A tour of basic C/C++ wrapping</a></H2>
+<H2><a name="Java_basic_tour">27.3 A tour of basic C/C++ wrapping</a></H2>
 
 
 <p>
@@ -659,7 +660,7 @@
 This section briefly covers the essential aspects of this wrapping.
 </p>
 
-<H3><a name="Java_module_packages_classes">26.3.1 Modules, packages and generated Java classes</a></H3>
+<H3><a name="Java_module_packages_classes">27.3.1 Modules, packages and generated Java classes</a></H3>
 
 
 <p>
@@ -695,7 +696,7 @@
 SWIG won't create the directory, so make sure it exists beforehand.
 </p>
 
-<H3><a name="Java_functions">26.3.2 Functions</a></H3>
+<H3><a name="Java_functions">27.3.2 Functions</a></H3>
 
 
 <p>
@@ -729,7 +730,7 @@
 </pre></div>
 
 
-<H3><a name="Java_global_variables">26.3.3 Global variables</a></H3>
+<H3><a name="Java_global_variables">27.3.3 Global variables</a></H3>
 
 
 <p>
@@ -816,7 +817,7 @@
 </div>
 
 
-<H3><a name="Java_constants">26.3.4 Constants</a></H3>
+<H3><a name="Java_constants">27.3.4 Constants</a></H3>
 
 
 <p>
@@ -956,7 +957,7 @@
 </p>
 
 
-<H3><a name="Java_enumerations">26.3.5 Enumerations</a></H3>
+<H3><a name="Java_enumerations">27.3.5 Enumerations</a></H3>
 
 
 <p>
@@ -970,7 +971,7 @@
 Before looking at the various approaches for wrapping named C/C++ enums, anonymous enums are considered.
 </p>
 
-<H4><a name="Java_anonymous_enums">26.3.5.1 Anonymous enums</a></H4>
+<H4><a name="Java_anonymous_enums">27.3.5.1 Anonymous enums</a></H4>
 
 
 <p>
@@ -1033,7 +1034,7 @@
 </p>
 
 
-<H4><a name="Java_typesafe_enums">26.3.5.2 Typesafe enums</a></H4>
+<H4><a name="Java_typesafe_enums">27.3.5.2 Typesafe enums</a></H4>
 
 
 <p>
@@ -1126,7 +1127,7 @@
 The following section details proper Java enum generation.
 </p>
 
-<H4><a name="Java_proper_enums">26.3.5.3 Proper Java enums</a></H4>
+<H4><a name="Java_proper_enums">27.3.5.3 Proper Java enums</a></H4>
 
 
 <p>
@@ -1179,7 +1180,7 @@
 <a href="#Java_simpler_enum_classes">Simpler Java enums for enums without initializers</a> section.
 </p>
 
-<H4><a name="Java_typeunsafe_enums">26.3.5.4 Type unsafe enums</a></H4>
+<H4><a name="Java_typeunsafe_enums">27.3.5.4 Type unsafe enums</a></H4>
 
 
 <p>
@@ -1227,7 +1228,7 @@
 Thus the upgrade path to proper enums provided in JDK 1.5 is more painful.
 </p>
 
-<H4><a name="Java_simple_enums">26.3.5.5 Simple enums</a></H4>
+<H4><a name="Java_simple_enums">27.3.5.5 Simple enums</a></H4>
 
 
 <p>
@@ -1246,7 +1247,7 @@
 The type unsafe approach is preferable to this one and this simple approach is only included for backwards compatibility with these earlier versions of SWIG.
 </p>
 
-<H3><a name="Java_pointers">26.3.6 Pointers</a></H3>
+<H3><a name="Java_pointers">27.3.6 Pointers</a></H3>
 
 
 <p>
@@ -1334,7 +1335,7 @@
 a NULL pointer if the conversion can't be performed.
 </p>
 
-<H3><a name="Java_structures">26.3.7 Structures</a></H3>
+<H3><a name="Java_structures">27.3.7 Structures</a></H3>
 
 
 <p>
@@ -1502,7 +1503,7 @@
 </div>
 
 
-<H3><a name="Java_classes">26.3.8 C++ classes</a></H3>
+<H3><a name="Java_classes">27.3.8 C++ classes</a></H3>
 
 
 <p>
@@ -1565,7 +1566,7 @@
 </div>
 
 
-<H3><a name="Java_inheritance">26.3.9 C++ inheritance</a></H3>
+<H3><a name="Java_inheritance">27.3.9 C++ inheritance</a></H3>
 
 
 <p>
@@ -1626,7 +1627,7 @@
 A warning is given when multiple inheritance is detected and only the first base class is used. 
 </p>
 
-<H3><a name="Java_pointers_refs_arrays">26.3.10 Pointers, references, arrays and pass by value</a></H3>
+<H3><a name="Java_pointers_refs_arrays">27.3.10 Pointers, references, arrays and pass by value</a></H3>
 
 
 <p>
@@ -1681,7 +1682,7 @@
 when the returned object's finalizer is run by the garbage collector).
 </p>
 
-<H4><a name="Java_null_pointers">26.3.10.1 Null pointers</a></H4>
+<H4><a name="Java_null_pointers">27.3.10.1 Null pointers</a></H4>
 
 
 <p>
@@ -1705,7 +1706,7 @@
 The converse also occurs, that is, NULL pointers are translated into <tt>null</tt> Java objects when returned from a C/C++ function.
 </p>
 
-<H3><a name="Java_overloaded_functions">26.3.11 C++ overloaded functions</a></H3>
+<H3><a name="Java_overloaded_functions">27.3.11 C++ overloaded functions</a></H3>
 
 
 <p>
@@ -1820,7 +1821,7 @@
 </pre>
 </div>
 
-<H3><a name="Java_default_arguments">26.3.12 C++ default arguments</a></H3>
+<H3><a name="Java_default_arguments">27.3.12 C++ default arguments</a></H3>
 
 
 <p>
@@ -1863,7 +1864,7 @@
 </p>
 
 
-<H3><a name="Java_namespaces">26.3.13 C++ namespaces</a></H3>
+<H3><a name="Java_namespaces">27.3.13 C++ namespaces</a></H3>
 
 
 <p>
@@ -1953,7 +1954,7 @@
 you will need to open up the visibility for the pointer constructor and <tt>getCPtr</tt> method from the default 'protected' to 'public' with the <tt>SWIG_JAVABODY_PROXY</tt> macro. See <a href="#Java_code_typemaps">Java code typemaps</a>.
 </p>
 
-<H3><a name="Java_templates">26.3.14 C++ templates</a></H3>
+<H3><a name="Java_templates">27.3.14 C++ templates</a></H3>
 
 
 <p>
@@ -2002,10 +2003,10 @@
 More details can be found in the <a href="SWIGPlus.html#SWIGPlus">SWIG and C++</a> chapter.   
 </p>
 
-<H3><a name="Java_smart_pointers">26.3.15 C++ Smart Pointers</a></H3>
+<H3><a name="Java_smart_pointers">27.3.15 C++ Smart Pointers</a></H3>
 
 
-<H4><a name="Java_smart_pointers_shared_ptr">26.3.15.1 The shared_ptr Smart Pointer</a></H4>
+<H4><a name="Java_smart_pointers_shared_ptr">27.3.15.1 The shared_ptr Smart Pointer</a></H4>
 
 
 <p>
@@ -2016,7 +2017,7 @@
 </p>
 
 
-<H4><a name="Java_smart_pointers_generic">26.3.15.2 Generic Smart Pointers</a></H4>
+<H4><a name="Java_smart_pointers_generic">27.3.15.2 Generic Smart Pointers</a></H4>
 
 
 <p>
@@ -2100,7 +2101,7 @@
 </pre>
 </div>
 
-<H2><a name="Java_further_details">26.4 Further details on the generated Java classes</a></H2>
+<H2><a name="Java_further_details">27.4 Further details on the generated Java classes</a></H2>
 
 
 <p>
@@ -2115,7 +2116,7 @@
 First, the crucial intermediary JNI class is considered.
 </p>
 
-<H3><a name="Java_imclass">26.4.1 The intermediary JNI class</a></H3>
+<H3><a name="Java_imclass">27.4.1 The intermediary JNI class</a></H3>
 
 
 <p>
@@ -2226,7 +2227,7 @@
 
 <div class="code">
 <pre>
-%module (jniclassname="name") modulename
+%module(jniclassname="name") modulename
 </pre>
 </div>
 
@@ -2235,7 +2236,7 @@
 from <tt>modulename</tt> to <tt>modulenameModule</tt>.
 </p>
 
-<H4><a name="Java_imclass_pragmas">26.4.1.1 The intermediary JNI class pragmas</a></H4>
+<H4><a name="Java_imclass_pragmas">27.4.1.1 The intermediary JNI class pragmas</a></H4>
 
 
 <p>
@@ -2317,7 +2318,7 @@
 All the methods in the intermediary JNI class will then not be callable outside of the package as the method modifiers have been changed from public access to default access. This is useful if you want to prevent users calling these low level functions.
 </p>
 
-<H3><a name="Java_module_class">26.4.2 The Java module class</a></H3>
+<H3><a name="Java_module_class">27.4.2 The Java module class</a></H3>
 
 
 <p>
@@ -2348,7 +2349,7 @@
 The primary reason for having the module class wrapping the calls in the intermediary JNI class is to implement static type checking. In this case only a <tt>Foo</tt> can be passed to the <tt>egg</tt> function, whereas any <tt>long</tt> can be passed to the <tt>egg</tt> function in the intermediary JNI class.
 </p>
 
-<H4><a name="Java_module_class_pragmas">26.4.2.1 The Java module class pragmas</a></H4>
+<H4><a name="Java_module_class_pragmas">27.4.2.1 The Java module class pragmas</a></H4>
 
 
 <p>
@@ -2399,7 +2400,7 @@
 </p>
 
 
-<H3><a name="Java_proxy_classes">26.4.3 Java proxy classes</a></H3>
+<H3><a name="Java_proxy_classes">27.4.3 Java proxy classes</a></H3>
 
 
 <p>
@@ -2475,7 +2476,7 @@
 </pre>
 </div>
 
-<H4><a name="Java_memory_management">26.4.3.1 Memory management</a></H4>
+<H4><a name="Java_memory_management">27.4.3.1 Memory management</a></H4>
 
 
 <p>
@@ -2637,7 +2638,7 @@
 </p>
 
 
-<H4><a name="Java_inheritance_mirroring">26.4.3.2 Inheritance</a></H4>
+<H4><a name="Java_inheritance_mirroring">27.4.3.2 Inheritance</a></H4>
 
 
 <p>
@@ -2753,7 +2754,7 @@
 </p>
 
 
-<H4><a name="Java_proxy_classes_gc">26.4.3.3 Proxy classes and garbage collection</a></H4>
+<H4><a name="Java_proxy_classes_gc">27.4.3.3 Proxy classes and garbage collection</a></H4>
 
 
 <p>
@@ -2836,7 +2837,7 @@
 See the <a href="http://www.devx.com/Java/Article/30192">How to Handle Java Finalization's Memory-Retention Issues</a> article for alternative approaches to managing memory by avoiding finalizers altogether.
 </p>
 
-<H4><a name="Java_pgcpp">26.4.3.4 The premature garbage collection prevention parameter for proxy class marshalling</a></H4>
+<H4><a name="Java_pgcpp">27.4.3.4 The premature garbage collection prevention parameter for proxy class marshalling</a></H4>
 
 
 <p>
@@ -2958,7 +2959,7 @@
 <b>Compatibility note:</b> The generation of this additional parameter did not occur in versions prior to SWIG-1.3.30.
 </p>
 
-<H4><a name="Java_multithread_libraries">26.4.3.5 Single threaded applications and thread safety</a></H4>
+<H4><a name="Java_multithread_libraries">27.4.3.5 Single threaded applications and thread safety</a></H4>
 
 
 <p>
@@ -3046,7 +3047,7 @@
 </pre></div>
  
 
-<H3><a name="Java_type_wrapper_classes">26.4.4 Type wrapper classes</a></H3>
+<H3><a name="Java_type_wrapper_classes">27.4.4 Type wrapper classes</a></H3>
 
 
 <p>
@@ -3133,7 +3134,7 @@
 </div>
 
 
-<H3><a name="Java_enum_classes">26.4.5 Enum classes</a></H3>
+<H3><a name="Java_enum_classes">27.4.5 Enum classes</a></H3>
 
 
 <p>
@@ -3142,7 +3143,7 @@
 The following sub-sections detail the various types of enum classes that can be generated.
 </p>
 
-<H4><a name="Java_typesafe_enums_classes">26.4.5.1 Typesafe enum classes</a></H4>
+<H4><a name="Java_typesafe_enums_classes">27.4.5.1 Typesafe enum classes</a></H4>
 
 
 <p>
@@ -3226,7 +3227,7 @@
 The <tt>toString</tt> method is overridden so that the enum name is available.
 </p>
 
-<H4><a name="Java_proper_enums_classes">26.4.5.2 Proper Java enum classes</a></H4>
+<H4><a name="Java_proper_enums_classes">27.4.5.2 Proper Java enum classes</a></H4>
 
 
 <p>
@@ -3304,7 +3305,7 @@
 <a href="#Java_simpler_enum_classes">Simpler Java enums for enums without initializers</a> section describes how typemaps can be used to achieve this.
 </p>
 
-<H4><a name="Java_typeunsafe_enums_classes">26.4.5.3 Type unsafe enum classes</a></H4>
+<H4><a name="Java_typeunsafe_enums_classes">27.4.5.3 Type unsafe enum classes</a></H4>
 
 
 <p>
@@ -3335,7 +3336,7 @@
 </pre>
 </div>
 
-<H3><a name="Java_interfaces">26.4.6 Interfaces</a></H3>
+<H3><a name="Java_interfaces">27.4.6 Interfaces</a></H3>
 
 
 <p>
@@ -3434,9 +3435,11 @@
 namespace Space {
   struct Base1 {
     virtual void Method1();
+    virtual Base1();
   };
   struct Base2 {
     virtual void Method2();
+    virtual Base2();
   };
   struct Derived : Base1, Base2 {
   };
@@ -3453,7 +3456,7 @@
 
 <div class="shell">
 <pre>
-example.i:10: Warning 813: Warning for Derived, base Base2 ignored. 
+example.i:12: Warning 813: Warning for Derived, base Base2 ignored.
 Multiple inheritance is not supported in Java.
 </pre>
 </div>
@@ -3506,7 +3509,7 @@
 </div>
 
 <p>
-In fact any class deriving from <tt>Base</tt> will now implement the interface instead of
+In fact any class using <tt>Base</tt> as an immediate base class will now implement the interface instead of
 deriving from it (or ignoring the base in the case of multiple base classes).
 Hence the <tt>Derived</tt> proxy class will now implement both bases:
 </p>
@@ -3536,6 +3539,21 @@
 </div>
 
 <p>
+The proxy class has methods added to it, from the implemented bases, so that
+the underlying C++ implementation can be called.
+In the example above, <tt>Method1</tt> and <tt>Method2</tt> have been added from the implemented bases.
+If a method is ignored in the base, such as via <tt>%ignore</tt>, then that method
+will be excluded from the interface and there will not be an additional method
+added to the proxy class implementing that interface.
+</p>
+
+<p>
+The Java interface only ever contains virtual and non-virtual instance methods from the wrapped C++ class.
+Any static methods, enums or variables in the wrapped C++ class are not supported and are not added to the interface.
+They are of course still available in the Java proxy class.
+</p>
+
+<p>
 Wherever a class marked as an interface is used, such as the <tt>UseBases</tt> method in the example,
 the interface name is used as the type in the Java layer:
 </p>
@@ -3580,7 +3598,7 @@
 See <a href="Java.html#Java_code_typemaps">Java code typemaps</a> for details.
 </p>
 
-<H2><a name="Java_directors">26.5 Cross language polymorphism using directors</a></H2>
+<H2><a name="Java_directors">27.5 Cross language polymorphism using directors</a></H2>
 
 
 <p>
@@ -3602,7 +3620,7 @@
 Neither C++ code nor Java code needs to know where a particular method is implemented: the combination of proxy classes, director classes, and C wrapper functions transparently takes care of all the cross-language method routing.
 </p>
 
-<H3><a name="Java_enabling_directors">26.5.1 Enabling directors</a></H3>
+<H3><a name="Java_enabling_directors">27.5.1 Enabling directors</a></H3>
 
 
 <p>
@@ -3670,7 +3688,7 @@
 </pre>
 </div>
 
-<H3><a name="Java_directors_classes">26.5.2 Director classes</a></H3>
+<H3><a name="Java_directors_classes">27.5.2 Director classes</a></H3>
 
 
 <p>
@@ -3698,7 +3716,7 @@
 </p>
 
 
-<H3><a name="Java_directors_overhead">26.5.3 Overhead and code bloat</a></H3>
+<H3><a name="Java_directors_overhead">27.5.3 Overhead and code bloat</a></H3>
 
 
 <p>
@@ -3716,7 +3734,7 @@
 </p>
 
 
-<H3><a name="Java_directors_example">26.5.4 Simple directors example</a></H3>
+<H3><a name="Java_directors_example">27.5.4 Simple directors example</a></H3>
 
 
 <p>
@@ -3779,7 +3797,7 @@
 </pre>
 </div>
 
-<H3><a name="Java_directors_threading">26.5.5 Director threading issues</a></H3>
+<H3><a name="Java_directors_threading">27.5.5 Director threading issues</a></H3>
 
 
 <p>
@@ -3799,7 +3817,7 @@
 </pre>
 </div>
 
-<H3><a name="Java_directors_performance">26.5.6 Director performance tuning</a></H3>
+<H3><a name="Java_directors_performance">27.5.6 Director performance tuning</a></H3>
 
 
 <p>
@@ -3820,7 +3838,7 @@
 The disadvantage is that invocation of director methods from C++ when Java doesn't actually override the method will require an additional call up into Java and back to C++.  As such, this option is only useful when overrides are extremely common and instantiation is frequent enough that its performance is critical.
 </p>
 
-<H3><a name="Java_exceptions_from_directors">26.5.7 Java exceptions from directors</a></H3>
+<H3><a name="Java_exceptions_from_directors">27.5.7 Java exceptions from directors</a></H3>
 
 
 <p>
@@ -3896,7 +3914,7 @@
 More on the <tt>Swig::DirectorException</tt> class can be found in the next section which details how to customize the handling of director exceptions.
 </p>
 
-<H4><a name="Java_customizing_director_exceptions">26.5.7.1 Customizing director exceptions</a></H4>
+<H4><a name="Java_customizing_director_exceptions">27.5.7.1 Customizing director exceptions</a></H4>
 
 
 <p>
@@ -4030,7 +4048,7 @@
 for each director method.
 To mitigate this, a second approach is provided via typemaps in a
 fashion analogous to
-the <a href="Typemaps.html#throws_typemap">"throws" typemap</a>.
+the <a href="Typemaps.html#Typemaps_throws_typemap">"throws" typemap</a>.
 The "throws" typemap provides a way to map all the C++
 exceptions listed in a method's defined exceptions (either from
 a C++ <em>exception specification</em> or a <code>%catches</code>
@@ -4081,7 +4099,7 @@
 the relevant "directorthrows" typemaps, for each and every exception defined for the method. 
 The relevant exceptions can be defined either with a C++ exception
 specification or <code>%catches</code> as described for the
-<a href="Typemaps.html#throws_typemap">"throws" typemap</a>.
+<a href="Typemaps.html#Typemaps_throws_typemap">"throws" typemap</a>.
 </p>
 
 <p>
@@ -4201,7 +4219,7 @@
 %}
 
 // Expose C++ exception as a Java Exception by changing the Java base class and providing a getMessage()
-%typemap(javabase) MyNS::MyException "java.lang.RuntimeException";
+%typemap(javabase) MyNS::MyException "java.lang.RuntimeException"
 %rename(getMessage) MyNS::MyException::whatsup;
 
 %inline %{
@@ -4454,7 +4472,7 @@
 </pre>
 </div>
 
-<H2><a name="Java_allprotected">26.6 Accessing protected members</a></H2>
+<H2><a name="Java_allprotected">27.6 Accessing protected members</a></H2>
 
 
 <p>
@@ -4550,7 +4568,7 @@
 
 
 
-<H2><a name="Java_common_customization">26.7 Common customization features</a></H2>
+<H2><a name="Java_common_customization">27.7 Common customization features</a></H2>
 
 
 <p>
@@ -4562,7 +4580,7 @@
 to improve the interface to existing C/C++ code.
 </p>
 
-<H3><a name="Java_helper_functions">26.7.1 C/C++ helper functions</a></H3>
+<H3><a name="Java_helper_functions">27.7.1 C/C++ helper functions</a></H3>
 
 
 <p>
@@ -4628,7 +4646,7 @@
 customization features as covered in later sections, but sometimes helper functions are a quick and easy solution to difficult cases.  
 </p>
 
-<H3><a name="Java_class_extension">26.7.2 Class extension with %extend</a></H3>
+<H3><a name="Java_class_extension">27.7.2 Class extension with %extend</a></H3>
 
 
 <p>
@@ -4691,7 +4709,7 @@
 in any way---the extensions only show up in the Java interface.
 </p>
 
-<H3><a name="Java_proxycode">26.7.3 Class extension with %proxycode</a></H3>
+<H3><a name="Java_proxycode">27.7.3 Class extension with %proxycode</a></H3>
 
 
 <p>
@@ -4828,7 +4846,7 @@
 </pre>
 </div>
 
-<H3><a name="Java_exception_handling">26.7.4 Exception handling with %exception and %javaexception</a></H3>
+<H3><a name="Java_exception_handling">27.7.4 Exception handling with %exception and %javaexception</a></H3>
 
 
 <p>
@@ -4987,7 +5005,7 @@
 The typemap example <a href="#Java_exception_typemap">Handling C++ exception specifications as Java exceptions</a> provides further exception handling capabilities.
 </p>
 
-<H3><a name="Java_method_access">26.7.5 Method access with %javamethodmodifiers</a></H3>
+<H3><a name="Java_method_access">27.7.5 Method access with %javamethodmodifiers</a></H3>
 
 
 <p>
@@ -5013,7 +5031,26 @@
 </pre>
 </div>
 
-<H2><a name="Java_tips_techniques">26.8 Tips and techniques</a></H2>
+<H3><a name="Java_begin">27.7.6 Java begin</a></H3>
+
+
+<p>
+It is possible to add a common comment at the start of every generated Java file.
+The <tt>%module</tt> directive supports the <tt>javabegin</tt> option for this.
+The provided text is generated at the very beginning of each generated .java file.
+As it is generated before the package statement, is only really useful for adding in
+a common comment into all generated .java files. For example, copyright text for each file:
+</p>
+
+
+<div class="code">
+<pre>
+%module(javabegin="/* Common comment. Copyright (C) 2000 Mr Nobody. */\n") nobodymodule
+</pre>
+</div>
+
+
+<H2><a name="Java_tips_techniques">27.8 Tips and techniques</a></H2>
 
 
 <p>
@@ -5023,7 +5060,7 @@
 solving these problems.
 </p>
 
-<H3><a name="Java_input_output_parameters">26.8.1 Input and output parameters using primitive pointers and references</a></H3>
+<H3><a name="Java_input_output_parameters">27.8.1 Input and output parameters using primitive pointers and references</a></H3>
 
 
 <p>
@@ -5197,7 +5234,7 @@
 will not have the intended effect since <tt>typemaps.i</tt> does not define an OUTPUT rule for <tt>Bar</tt>.
 </p>
 
-<H3><a name="Java_simple_pointers">26.8.2 Simple pointers</a></H3>
+<H3><a name="Java_simple_pointers">27.8.2 Simple pointers</a></H3>
 
 
 <p>
@@ -5263,7 +5300,7 @@
 See the <a href="Library.html#Library">SWIG Library</a> chapter for further details.
 </p>
 
-<H3><a name="Java_c_arrays">26.8.3 Wrapping C arrays with Java arrays</a></H3>
+<H3><a name="Java_c_arrays">27.8.3 Wrapping C arrays with Java arrays</a></H3>
 
 
 <p>
@@ -5330,7 +5367,7 @@
 There is an alternative approach using the SWIG array library and this is covered in the next section.
 </p>
 
-<H3><a name="Java_unbounded_c_arrays">26.8.4 Unbounded C Arrays</a></H3>
+<H3><a name="Java_unbounded_c_arrays">27.8.4 Unbounded C Arrays</a></H3>
 
 
 <p>
@@ -5410,10 +5447,10 @@
 
 <div class="code">
 <pre>
-int *new_intArray(int nelements);
+int *new_intArray(size_t nelements);
 void delete_intArray(int *x);
-int intArray_getitem(int *x, int index);
-void intArray_setitem(int *x, int index, int value);
+int intArray_getitem(int *x, size_t index);
+void intArray_setitem(int *x, size_t index, int value);
 </pre>
 </div>
 
@@ -5475,7 +5512,7 @@
 package binary data, etc.
 </p>
 
-<H3><a name="Java_binary_char">26.8.5 Binary data vs Strings</a></H3>
+<H3><a name="Java_binary_char">27.8.5 Binary data vs Strings</a></H3>
 
 
 <p>
@@ -5519,7 +5556,7 @@
 </pre></div>
 
 
-<H3><a name="Java_heap_allocations">26.8.6 Overriding new and delete to allocate from Java heap</a></H3>
+<H3><a name="Java_heap_allocations">27.8.6 Overriding new and delete to allocate from Java heap</a></H3>
 
 
 <p>
@@ -5636,7 +5673,7 @@
 code.
 </p>
 
-<H2><a name="Java_typemaps">26.9 Java typemaps</a></H2>
+<H2><a name="Java_typemaps">27.9 Java typemaps</a></H2>
 
 
 <p>
@@ -5657,7 +5694,7 @@
 part of using SWIG---the default wrapping behavior is enough in most cases.
 Typemaps are only used if you want to change some aspect of the generated code.
 
-<H3><a name="Java_default_primitive_type_mappings">26.9.1 Default primitive type mappings</a></H3>
+<H3><a name="Java_default_primitive_type_mappings">27.9.1 Default primitive type mappings</a></H3>
 
 
 <p>
@@ -5755,6 +5792,12 @@
 </tr>
 
 <tr>
+<td>size_t<br> const size_t &amp;</td>
+<td>long</td>
+<td>jlong</td>
+</tr>
+
+<tr>
 <td>char *<br>char []</td>
 <td>String</td>
 <td>jstring</td>
@@ -5763,6 +5806,62 @@
 </table>
 
 <p>
+Note that default mappings for the C long type is more suitable for 32-bit systems.
+If long is 64-bit, the full range can be obtained by defining <tt>SWIGWORDSIZE64</tt> when invoking SWIG.
+The long type will instead be mapped as follows:
+</p>
+
+<table BORDER summary="SWIGWORDSIZE64 primitive type mappings">
+<tr>
+<td><b>C/C++ type</b></td>
+<td><b>Java type</b></td>
+<td><b>JNI type</b></td>
+</tr>
+
+<tr>
+<td>long<br> const long &amp;</td>
+<td>long</td>
+<td>jlong</td>
+</tr>
+
+<tr>
+<td>unsigned long<br>const unsigned long &amp;</td>
+<td>java.math.BigInteger</td>
+<td>jobject</td>
+</tr>
+
+</table>
+
+<p>
+Note that when size_t is 64-bit in C, the full unsigned range is not available.
+This can be fixed by applying the 64-bit unsigned long long typemaps as follows:
+</p>
+
+<div class="code"> <pre>
+%apply unsigned long long { size_t };
+%apply const unsigned long long &amp; { const size_t &amp; };
+</pre> </div>
+
+<p>
+The net effect then changes from the default shown earlier to:
+</p>
+
+<table BORDER summary="64-bit size_t primitive type mappings">
+<tr>
+<td><b>C/C++ type</b></td>
+<td><b>Java type</b></td>
+<td><b>JNI type</b></td>
+</tr>
+
+<tr>
+<td>size_t<br> const size_t &amp;</td>
+<td>java.math.BigInteger</td>
+<td>jobject</td>
+</tr>
+
+</table>
+
+<p>
 Note that SWIG wraps the C <tt>char</tt> type as a character. Pointers and arrays of this type are wrapped as strings. 
 The <tt>signed char</tt> type can be used if you want to treat <tt>char</tt> as a signed number rather than a character.
 Also note that all const references to primitive types are treated as if they are passed by value.
@@ -5809,7 +5908,7 @@
 </p>
 
 
-<H3><a name="Java_default_non_primitive_typemaps">26.9.2 Default typemaps for non-primitive types</a></H3>
+<H3><a name="Java_default_non_primitive_typemaps">27.9.2 Default typemaps for non-primitive types</a></H3>
 
 
 <p>
@@ -5824,7 +5923,7 @@
 The Java type is either the proxy class or type wrapper class.
 </p>
 
-<H3><a name="Java_jvm64">26.9.3 Sixty four bit JVMs</a></H3>
+<H3><a name="Java_jvm64">27.9.3 Sixty four bit JVMs</a></H3>
 
 
 <p>
@@ -5837,7 +5936,7 @@
 </p>
 
 
-<H3><a name="Java_what_is_typemap">26.9.4 What is a typemap?</a></H3>
+<H3><a name="Java_what_is_typemap">27.9.4 What is a typemap?</a></H3>
 
 
 <p>
@@ -5960,7 +6059,7 @@
 </pre>
 </div>
 
-<H3><a name="Java_typemaps_c_to_java_types">26.9.5 Typemaps for mapping C/C++ types to Java types</a></H3>
+<H3><a name="Java_typemaps_c_to_java_types">27.9.5 Typemaps for mapping C/C++ types to Java types</a></H3>
 
 
 <p>
@@ -6240,7 +6339,7 @@
 
 </table>
 
-<H3><a name="Java_typemap_attributes">26.9.6 Java typemap attributes</a></H3>
+<H3><a name="Java_typemap_attributes">27.9.6 Java typemap attributes</a></H3>
 
 
 <p>
@@ -6286,7 +6385,7 @@
 Note that when the 'pre' or 'post' attributes are specified and the associated type is used in a constructor, a constructor helper function is generated. This is necessary as the Java proxy constructor wrapper makes a call to a support constructor using a <i>this</i> call. In Java the <i>this</i> call must be the first statement in the constructor body. The constructor body thus calls the helper function and the helper function instead makes the JNI call, ensuring the 'pre' code is called before the JNI call is made. There is a <a href="#Java_date_marshalling">Date marshalling</a> example showing 'pre', 'post' and 'pgcppname' attributes in action.
 </p>
 
-<H3><a name="Java_special_variables">26.9.7 Java special variables</a></H3>
+<H3><a name="Java_special_variables">27.9.7 Java special variables</a></H3>
 
 
 <p>
@@ -6440,6 +6539,12 @@
 </p>
 
 <p>
+<b><tt>$imfuncname</tt></b><br>
+This special variable expands to the name of the function in the intermediary class that will be used in $jnicall.
+Like, $jnicall, this special variable is only expanded in the "javaout" typemap.
+</p>
+
+<p>
 <b><tt>$javainterfacename</tt></b><br>
 This special variable is only expanded when the <tt>interface</tt> feature is applied to a class.
 It works much like <tt>$javaclassname</tt>, but instead of expanding to the proxy classname,
@@ -6468,7 +6573,7 @@
 <a href="SWIGPlus.html#SWIGPlus_nspace">nspace feature</a>.
 </p>
 
-<H3><a name="Java_typemaps_for_c_and_cpp">26.9.8 Typemaps for both C and C++ compilation</a></H3>
+<H3><a name="Java_typemaps_for_c_and_cpp">27.9.8 Typemaps for both C and C++ compilation</a></H3>
 
 
 <p>
@@ -6505,7 +6610,7 @@
 </p>
 
 
-<H3><a name="Java_code_typemaps">26.9.9 Java code typemaps</a></H3>
+<H3><a name="Java_code_typemaps">27.9.9 Java code typemaps</a></H3>
 
 
 <p>
@@ -6610,6 +6715,15 @@
 
 </div>
 
+<p><tt>%typemap(javainterfacemodifiers)</tt></p>
+<div class="indent">
+Interface modifiers for the Java interface generated when using the <tt>interface</tt> feature, see <a href="Java.html#Java_interfaces">Java interfaces</a> section. The default is "public interface".
+<p>
+<b>Compatibility note:</b> This typemap was added in SWIG-4.1.0.
+</p>
+
+</div>
+
 <p><tt>%typemap(javainterfacecode, declaration="...", cptrmethod="...")</tt></p>
 <div class="indent">
 <p>
@@ -6709,7 +6823,7 @@
 <div class="code">
 <pre>
 [ javaimports typemap ]
-public interface [ javainterfacename ] {
+[ javainterfacemodifiers typemap ] [ javainterfacename ] {
 [ javainterfacecode:cptrmethod typemap attribute ]
 ... interface declarations ...
 }
@@ -6803,7 +6917,7 @@
 </pre>
 </div>
 
-<H3><a name="Java_directors_typemaps">26.9.10 Director specific typemaps</a></H3>
+<H3><a name="Java_directors_typemaps">27.9.10 Director specific typemaps</a></H3>
 
 
 <p>
@@ -7033,7 +7147,7 @@
 <pre>
 // class Foo is handled in a different interface file:
 %import "Foo.i"
-%typemap("javapackage") Foo, Foo *, Foo &amp; "com.wombat.foo";
+%typemap("javapackage") Foo, Foo *, Foo &amp; "com.wombat.foo"
 %feature("director") Example;
 
 %inline {
@@ -7061,11 +7175,11 @@
                                             "package.for.most.classes";
 
 %define OTHER_PACKAGE_SPEC(TYPE...)
-%typemap("javapackage") TYPE, TYPE *, TYPE &amp; "package.for.other.classes";
+%typemap("javapackage") TYPE, TYPE *, TYPE &amp; "package.for.other.classes"
 %enddef
 
 %define ANOTHER_PACKAGE_SPEC(TYPE...)
-%typemap("javapackage") TYPE, TYPE *, TYPE &amp; "package.for.another.set";
+%typemap("javapackage") TYPE, TYPE *, TYPE &amp; "package.for.another.set"
 %enddef
 
 OTHER_PACKAGE_SPEC(Package_2_class_one)
@@ -7080,7 +7194,7 @@
 
 </div>
 
-<H2><a name="Java_typemap_examples">26.10 Typemap Examples</a></H2>
+<H2><a name="Java_typemap_examples">27.10 Typemap Examples</a></H2>
 
 
 <p>
@@ -7090,7 +7204,7 @@
 </p>
 
 
-<H3><a name="Java_simpler_enum_classes">26.10.1 Simpler Java enums for enums without initializers</a></H3>
+<H3><a name="Java_simpler_enum_classes">27.10.1 Simpler Java enums for enums without initializers</a></H3>
 
 
 <p>
@@ -7169,7 +7283,7 @@
 </p>
 
 
-<H3><a name="Java_exception_typemap">26.10.2 Handling C++ exception specifications as Java exceptions</a></H3>
+<H3><a name="Java_exception_typemap">27.10.2 Handling C++ exception specifications as Java exceptions</a></H3>
 
 
 <p>
@@ -7259,7 +7373,7 @@
 
 <div class="code">
 <pre>
-%typemap(javabase) FileException "java.lang.Exception";
+%typemap(javabase) FileException "java.lang.Exception"
 %typemap(javacode) FileException %{
   public String getMessage() {
     return what();
@@ -7294,7 +7408,7 @@
 </p>
 
 
-<H3><a name="Java_nan_exception_typemap">26.10.3 NaN Exception - exception handling for a particular type</a></H3>
+<H3><a name="Java_nan_exception_typemap">27.10.3 NaN Exception - exception handling for a particular type</a></H3>
 
 
 <p>
@@ -7449,7 +7563,7 @@
 If we had, we would have put it in the "in" typemap which, like all JNI and Java typemaps, also supports the 'throws' attribute.
 </p>
 
-<H3><a name="Java_converting_java_string_arrays">26.10.4 Converting Java String arrays to char ** </a></H3>
+<H3><a name="Java_converting_java_string_arrays">27.10.4 Converting Java String arrays to char ** </a></H3>
 
 
 <p>
@@ -7593,7 +7707,7 @@
 what Java types to use.
 </p>
 
-<H3><a name="Java_expanding_java_object">26.10.5 Expanding a Java object to multiple arguments</a></H3>
+<H3><a name="Java_expanding_java_object">27.10.5 Expanding a Java object to multiple arguments</a></H3>
 
 
 <p>
@@ -7675,7 +7789,7 @@
 </div>
 
 
-<H3><a name="Java_using_typemaps_return_arguments">26.10.6 Using typemaps to return arguments</a></H3>
+<H3><a name="Java_using_typemaps_return_arguments">27.10.6 Using typemaps to return arguments</a></H3>
 
 
 <p>
@@ -7793,7 +7907,7 @@
 1 12.0  340.0
 </pre></div>
 
-<H3><a name="Java_adding_downcasts">26.10.7 Adding Java downcasts to polymorphic return types</a></H3>
+<H3><a name="Java_adding_downcasts">27.10.7 Adding Java downcasts to polymorphic return types</a></H3>
 
 
 <p>
@@ -7999,7 +8113,7 @@
 Note that the JNI code above uses a number of string lookups to call a constructor, whereas this would not occur using byte compiled Java code.
 </p>
 
-<H3><a name="Java_adding_equals_method">26.10.8 Adding an equals method to the Java classes</a></H3>
+<H3><a name="Java_adding_equals_method">27.10.8 Adding an equals method to the Java classes</a></H3>
 
 
 <p>
@@ -8043,7 +8157,7 @@
 </div>
 
 
-<H3><a name="Java_void_pointers">26.10.9 Void pointers and a common Java base class</a></H3>
+<H3><a name="Java_void_pointers">27.10.9 Void pointers and a common Java base class</a></H3>
 
 
 <p>
@@ -8102,7 +8216,7 @@
     <li> It also has a function which effectively implements a cast from the type of the proxy/type wrapper class to a void pointer. This is necessary for passing a proxy class or a type wrapper class to a function that takes a void pointer.
 </ul>
 
-<H3><a name="Java_struct_pointer_pointer">26.10.10 Struct pointer to pointer</a></H3>
+<H3><a name="Java_struct_pointer_pointer">27.10.10 Struct pointer to pointer</a></H3>
 
 
 <p>
@@ -8282,7 +8396,7 @@
 the Butler class would behave much like any pure Java class and feel more natural to Java users.
 </p>
 
-<H3><a name="Java_memory_management_member_variables">26.10.11 Memory management when returning references to member variables</a></H3>
+<H3><a name="Java_memory_management_member_variables">27.10.11 Memory management when returning references to member variables</a></H3>
 
 
 <p>
@@ -8405,7 +8519,7 @@
 Note the <tt>addReference</tt> call.
 </p>
 
-<H3><a name="Java_memory_management_objects">26.10.12 Memory management for objects passed to the C++ layer</a></H3>
+<H3><a name="Java_memory_management_objects">27.10.12 Memory management for objects passed to the C++ layer</a></H3>
 
 
 <p>
@@ -8533,7 +8647,7 @@
 </pre>
 </div>
 
-<H3><a name="Java_date_marshalling">26.10.13 Date marshalling using the javain typemap and associated attributes</a></H3>
+<H3><a name="Java_date_marshalling">27.10.13 Date marshalling using the javain typemap and associated attributes</a></H3>
 
 
 <p>
@@ -8710,7 +8824,7 @@
 
 
 
-<H2><a name="Java_directors_faq">26.11 Living with Java Directors</a></H2>
+<H2><a name="Java_directors_faq">27.11 Living with Java Directors</a></H2>
 
 
 <p>
@@ -8889,16 +9003,21 @@
   </li>
 </ol>
 
-<H2><a name="Java_odds_ends">26.12 Odds and ends</a></H2>
+<H2><a name="Java_odds_ends">27.12 Odds and ends</a></H2>
 
 
-<H3><a name="Java_javadoc_comments">26.12.1 JavaDoc comments</a></H3>
+<H3><a name="Java_javadoc_comments">27.12.1 JavaDoc comments</a></H3>
 
 
 <p>
-The SWIG documentation system is currently deprecated. 
-When it is resurrected JavaDoc comments will be fully supported. 
-If you can't wait for the full documentation system a couple of workarounds are available. 
+SWIG can translate <a href="https://doxygen.org/">Doxygen</a> comments in the
+C/C++ headers being wrapped to JavaDoc.  For details of this, see the
+<a href="Doxygen.html#Doxygen_to_javadoc">Doxygen to Javadoc</a> section.
+</p>
+
+<p>
+If you don't have Doxygen comments to translate then it's possible to add
+JavaDoc comments from your interface file.
 The <tt>%javamethodmodifiers</tt> feature can be used for adding proxy class method comments and module class method comments. 
 The "javaimports" typemap can be hijacked for adding in proxy class JavaDoc comments. 
 The <tt>jniclassimports</tt> or <tt>jniclassclassmodifiers</tt> pragmas can also be used for adding intermediary JNI class comments and likewise the <tt>moduleimports</tt> or <tt>moduleclassmodifiers</tt> pragmas for the module class. 
@@ -8948,7 +9067,7 @@
 
 
 
-<H3><a name="Java_functional_interface">26.12.2 Functional interface without proxy classes</a></H3>
+<H3><a name="Java_functional_interface">27.12.2 Functional interface without proxy classes</a></H3>
 
 
 <p>
@@ -9009,7 +9128,7 @@
 </p>
 
 
-<H3><a name="Java_using_own_jni_functions">26.12.3 Using your own JNI functions</a></H3>
+<H3><a name="Java_using_own_jni_functions">27.12.3 Using your own JNI functions</a></H3>
 
 
 <p>
@@ -9054,12 +9173,17 @@
 </p>
 
 <p>
+Note that if you're wanting to effectively <b>replace</b> the JNI code generated for a C/C++ function then you'll need to use <tt>%ignore</tt> as well
+to tell SWIG not to automatically generate a JNI wrapper for it.
+</p>
+
+<p>
 In summary the <tt>%native</tt> directive is telling SWIG to generate the Java code to access the JNI C code, but not the JNI C function itself.
 This directive is only really useful if you want to mix your own hand crafted JNI code and the SWIG generated code into one Java class or package.
 </p>
 
 
-<H3><a name="Java_performance">26.12.4 Performance concerns and hints</a></H3>
+<H3><a name="Java_performance">27.12.4 Performance concerns and hints</a></H3>
 
 
 <p>
@@ -9080,13 +9204,13 @@
 This method normally calls the C++ destructor or <tt>free()</tt> for C code.
 </p>
 
-<H3><a name="Java_debugging">26.12.5 Debugging</a></H3>
+<H3><a name="Java_debugging">27.12.5 Debugging</a></H3>
 
 
 <p>
 The generated code can be debugged using both a Java debugger and a C++ debugger using the usual debugging techniques.
 Breakpoints can be set in either Java or C++ code and so both can be debugged simultaneously.
-Most debuggers do not understand both Java and C++, with one noteable exception of Sun Studio, 
+Most debuggers do not understand both Java and C++, with one notable exception of Sun Studio, 
 where it is possible to step from Java code into a JNI method within one environment.
 </p>
 
@@ -9102,7 +9226,7 @@
 </p>
 
 
-<H2><a name="Java_examples">26.13 Java Examples</a></H2>
+<H2><a name="Java_examples">27.13 Java Examples</a></H2>
 
 
 <p>
diff --git a/Doc/Manual/Javascript.html b/Doc/Manual/Javascript.html
index 0b30137..573b091 100644
--- a/Doc/Manual/Javascript.html
+++ b/Doc/Manual/Javascript.html
@@ -7,7 +7,7 @@
 </head>
 <body>
 
-<H1><a name="Javascript">27 SWIG and Javascript</a></H1>
+<H1><a name="Javascript">28 SWIG and Javascript</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -22,6 +22,7 @@
 <ul>
 <li><a href="#Javascript_node_extensions">Creating node.js Extensions</a>
 <ul>
+<li><a href="#Javascript_using_yeoman">Using <code>yeoman</code> to generate a Node-API skeleton</a>
 <li><a href="#Javascript_troubleshooting">Troubleshooting</a>
 </ul>
 <li><a href="#Javascript_embedded_webkit">Embedded Webkit</a>
@@ -43,6 +44,7 @@
 <li><a href="#Javascript_emitter">Emitter</a>
 <li><a href="#Javascript_emitter_states">Emitter states</a>
 <li><a href="#Javascript_jsc_exceptions">Handling Exceptions in JavascriptCore</a>
+<li><a href="#Javascript_napi_exceptions">Handling Exceptions in Node-API</a>
 </ul>
 </ul>
 </div>
@@ -52,7 +54,7 @@
 
 <p>This chapter describes SWIG's support of Javascript. It does not cover SWIG basics, but only information that is specific to this module.</p>
 
-<H2><a name="Javascript_overview">27.1 Overview</a></H2>
+<H2><a name="Javascript_overview">28.1 Overview</a></H2>
 
 
 <p>Javascript is a prototype-based scripting language that is dynamic, weakly typed and has first-class functions. Its arguably the most popular language for web development.
@@ -63,10 +65,10 @@
 With <a href="https://github.com/rogerwang/node-webkit">node-webkit</a> there is a platform which uses Google's <code>Chromium</code> as Web-Browser widget and <code>node.js</code> for javascript extensions.
 </p>
 
-<H2><a name="Javascript_preliminaries">27.2 Preliminaries</a></H2>
+<H2><a name="Javascript_preliminaries">28.2 Preliminaries</a></H2>
 
 
-<H3><a name="Javascript_running_swig">27.2.1 Running SWIG</a></H3>
+<H3><a name="Javascript_running_swig">28.2.1 Running SWIG</a></H3>
 
 
 <p>Suppose that you defined a SWIG module such as the following:</p>
@@ -79,7 +81,7 @@
 int gcd(int x, int y);
 extern double Foo;</pre>
 </div>
-<p>To build a Javascript module, run SWIG using the <code>-javascript</code> option and a desired target engine <code>-jsc</code>, <code>-v8</code>, or <code>-node</code>. The generator for <code>node</code> is essentially delegating to the <code>v8</code> generator and adds some necessary preprocessor definitions.</p>
+<p>To build a Javascript module, run SWIG using the <code>-javascript</code> option and a desired target engine <code>-jsc</code>, <code>-v8</code>, <code>-node</code> or <code>-napi</code>. <code>-v8</code> allows for interfacing with a raw embedded version of V8. In this case, it is up to the user to implement a binary module loading protocol. There are two generators supporting Node.js. The older generator for <code>node</code> is essentially delegating to the <code>v8</code> generator and adds some necessary preprocessor definitions. The more recent <code>-napi</code> generator produces <code>node-addon-api</code> that interfaces to Node.js through Node-API. The V8 generator is more mature, while the Node-API generator offers a number of advantages such as binary stable ABI allowing for publishing of universal binary modules on npm, Electron support and automatic multi-threading.</p>
 <div class="shell">
 <pre>
 $ swig -javascript -jsc example.i</pre>
@@ -89,19 +91,14 @@
 <pre>
 $ swig -c++ -javascript -jsc example.i</pre>
 </div>
-<p>The V8 code that SWIG generates should work with most versions from 3.11.10 up to 3.29.14 and later.</p>
-<p>The API headers for V8 &gt;= 4.3.0 define constants which SWIG can use to
-determine the V8 version it is compiling for.  For versions &lt; 4.3.0, you
-need to specify the V8 version when running SWIG.  This is specified as a hex
-constant, but the constant is read as pairs of decimal digits, so for V8
-3.25.30 use constant 0x032530.  This scheme can't represent components &gt; 99,
-but this constant is only useful for V8 &lt; 4.3.0, and no V8 versions from
-that era had a component &gt; 99.  For example:</p>
-<div class="shell">
-<pre>
-$ swig -c++ -javascript -v8 -DV8_VERSION=0x032530 example.i</pre>
-</div>
-<p>If you're targeting V8 &gt;= 4.3.0, you would just run swig like so:</p>
+<p>The V8 code that SWIG generates requires at least V8 5.0. Keep in mind
+that this is the V8 version, not Node.js. To give some perspective, Node.js v6.0
+uses V8 5.0, v12.0 - 7.4, v14.0 - 8.1...</p>
+<p>The Node-API code that SWIG generates requires Node-API version 6.
+This Node-API is available starting from Node.js v10.20 on the v10.x branch,
+Node.js v12.17 on the v12.x branch and all versions starting from v14.0.
+</p>
+<p>To generate code for V8, you would run swig like so:</p>
 <div class="shell">
 <pre>
 $ swig -c++ -javascript -v8 example.i</pre>
@@ -121,7 +118,7 @@
 <b>Note</b>: be aware that <code>v8</code> has a C++ API, and thus, the generated modules must be compiled as C++.
 </p>
 
-<H3><a name="Javascript_running_tests_examples">27.2.2 Running Tests and Examples</a></H3>
+<H3><a name="Javascript_running_tests_examples">28.2.2 Running Tests and Examples</a></H3>
 
 
 <p>The configuration for tests and examples currently supports Linux and Mac only and not MinGW (Windows) yet.</p>
@@ -134,14 +131,19 @@
 <p>Running with <code>V8</code> requires <code>libv8</code>:</p>
 <div class="shell">
 <pre>
-$ sudo apt-get install libv8-dev</pre>
+$ sudo apt-get install libnode-dev</pre>
+</div>
+<p>Running with Node-API requires <code>node-addon-api</code>:</p>
+<div class="shell">
+  <pre>
+$ sudo npm install -g node-addon-api</pre>
 </div>
 <p>Examples can be run using</p>
 <div class="shell">
 <pre>
 $ make check-javascript-examples ENGINE=jsc</pre>
 </div>
-<p><code>ENGINE</code> can be <code>node</code>, <code>jsc</code>, or <code>v8</code>.</p>
+<p><code>ENGINE</code> can be <code>node</code>, <code>jsc</code>, <code>v8</code>, or <code>napi</code>.</p>
 <p>The test-suite can be run using</p>
 <div class="shell">
 <pre>
@@ -153,28 +155,28 @@
 $ make check-javascript-examples V8_VERSION=0x032530 ENGINE=v8</pre>
 </div>
 
-<H3><a name="Javascript_known_issues">27.2.3 Known Issues</a></H3>
+<H3><a name="Javascript_known_issues">28.2.3 Known Issues</a></H3>
 
 
 <p>At the moment, the Javascript generators pass all tests syntactically, i.e., the generated source code compiles. However, there are still remaining runtime issues.</p>
 
 <ul>
-    <li><p>Default optional arguments do not work for all targeted interpreters</p></li>
+    <li><p>Default optional arguments do not work for all targeted interpreters except Node-API</p></li>
     <li><p>Multiple output arguments do not work for JSC</p></li>
     <li><p>C89 incompatibility: the JSC generator might still generate C89 violating code</p></li>
-    <li><p><code>long long</code> is not supported</p></li>
+    <li><p><code>long long</code> is not supported except with Node-API</p></li>
     <li><p>Javascript callbacks are not supported</p></li>
     <li><p><code>instanceOf</code> does not work under JSC</p></li>
 </ul>
 
-<p>The primary development environment has been Linux (Ubuntu 12.04). Windows and Mac OS X have been tested sporadically. Therefore, the generators might have more issues on those platforms. Please report back any problem you observe to help us improving this module quickly.</p>
+<p>The primary development environment has been Linux (Ubuntu 22.04). Windows and Mac OS X have been tested sporadically. Therefore, the generators might have more issues on those platforms. Please report back any problem you observe to help us improving this module quickly.</p>
 
-<H2><a name="Javascript_integration">27.3 Integration</a></H2>
+<H2><a name="Javascript_integration">28.3 Integration</a></H2>
 
 
 <p>This chapter gives a short introduction how to use a native Javascript extension: as a <code>node.js</code> module, and as an extension for an embedded Webkit.</p>
 
-<H3><a name="Javascript_node_extensions">27.3.1 Creating node.js Extensions</a></H3>
+<H3><a name="Javascript_node_extensions">28.3.1 Creating node.js Extensions</a></H3>
 
 
 <p>To install <code>node.js</code> you can download an installer from their <a href="https://launchpad.net/~chris-lea/+archive/node.js">web-site</a> for Mac OS X and Windows. For Linux you can either build the source yourself and run <code>sudo checkinstall</code> or keep to the (probably stone-age) packaged version. For Ubuntu there is a <a href="https://launchpad.net/~chris-lea/+archive/ubuntu/node.js/">PPA</a> available.</p>
@@ -220,7 +222,27 @@
 </div>
 <p>A more detailed explanation is given in the <a href="#Javascript_examples">Examples</a> section.</p>
 
-<H4><a name="Javascript_troubleshooting">27.3.1.1 Troubleshooting</a></H4>
+<H4><a name="Javascript_using_yeoman">28.3.1.1 Using <code>yeoman</code> to generate a Node-API skeleton</a></H4>
+
+
+<p>If targeting Node-API, the easiest way to bootstrap a project is by using the <code>yeoman</code> generator: </p>
+<div class="shell">
+<pre>
+$ sudo npm install -g yo
+$ sudo npm install -g generator-napi-module
+$ mkdir example
+$ cd example
+$ yo napi-module                     # the choice of template is irrelevant, SWIG will replace the C++ code
+$ npm install node-addon-api@latest  # the yeoman version is outdated
+$ swig -javascript -napi -c++ -o src/example.cc example.i
+$ node-gyp configure
+$ node-gyp build
+</pre>
+</div>
+<p>There is also the <a href="https://github.com/mmomtchev/node-magickwand"><code>node-magickwand</code></a> project that can be used as a tutorial for building and publishing a complex C++ library to
+  npm as a ready-to-use real-world binary module.</p>
+
+<H4><a name="Javascript_troubleshooting">28.3.1.2 Troubleshooting</a></H4>
 
 
 <ul>
@@ -232,12 +254,12 @@
 $ sudo apt-get remove gyp</pre>
 </div>
 
-<H3><a name="Javascript_embedded_webkit">27.3.2 Embedded Webkit</a></H3>
+<H3><a name="Javascript_embedded_webkit">28.3.2 Embedded Webkit</a></H3>
 
 
 <p>Webkit is pre-installed on Mac OS X and available as a library for GTK.</p>
 
-<H4><a name="Javascript_osx">27.3.2.1 Mac OS X</a></H4>
+<H4><a name="Javascript_osx">28.3.2.1 Mac OS X</a></H4>
 
 
 <p>There is general information about programming with WebKit on <a href="https://developer.apple.com/library/mac/documentation/cocoa/conceptual/DisplayWebContent/DisplayWebContent.html">Apple Developer Documentation</a>. Details about <code>Cocoa</code> programming are not covered here.</p>
@@ -285,10 +307,10 @@
 @end</pre>
 </div>
 
-<H4><a name="Javascript_gtk">27.3.2.2 GTK</a></H4>
+<H4><a name="Javascript_gtk">28.3.2.2 GTK</a></H4>
 
 
-<p>There is general information about programming GTK at <a href="https://developer.gnome.org/gtk2/">GTK documentation</a> and in the <a href="https://developer.gnome.org/gtk-tutorial/">GTK tutorial</a>, and for Webkit there is a <a href="http://webkitgtk.org/reference/webkitgtk/stable/index.html">Webkit GTK+ API Reference</a>.</p>
+<p>There is general information about programming GTK at <a href="https://developer.gnome.org/gtk2/">GTK documentation</a> and in the <a href="https://developer.gnome.org/gtk-tutorial/">GTK tutorial</a>, and for Webkit there is a <a href="https://webkitgtk.org/reference/webkitgtk/stable/index.html">Webkit GTK+ API Reference</a>.</p>
 <p>An integration of a native extension 'example' would look like this:</p>
 <div class="code">
 <pre>
@@ -319,7 +341,7 @@
   ...
 
   // Load a web page into the browser instance
-  webkit_web_view_load_uri(webView, "http://www.webkitgtk.org/");
+  webkit_web_view_load_uri(webView, "https://www.webkitgtk.org/");
 
   ...
 
@@ -330,7 +352,7 @@
 }</pre>
 </div>
 
-<H3><a name="Javascript_applications_webkit">27.3.3 Creating Applications with node-webkit</a></H3>
+<H3><a name="Javascript_applications_webkit">28.3.3 Creating Applications with node-webkit</a></H3>
 
 
 <p>To get started with <code>node-webkit</code> there is a very informative set of <a href="https://github.com/rogerwang/node-webkit/wiki">wiki pages</a>.</p>
@@ -401,7 +423,7 @@
 
 <p>
 As known from <code>node.js</code> one can use <code>require</code> to load javascript modules.
-Additionally, <code>node-webkit</code> provides an API that allows to manipulate the window's menu,
+Additionally, <code>node-webkit</code> provides an API that allows manipulating the window's menu,
 open new windows, and many more things.
 </p>
 
@@ -421,12 +443,12 @@
 };</pre>
 </div>
 
-<H2><a name="Javascript_examples">27.4 Examples</a></H2>
+<H2><a name="Javascript_examples">28.4 Examples</a></H2>
 
 
 <p>Some basic examples are shown here in more detail.</p>
 
-<H3><a name="Javascript_simple_example">27.4.1 Simple</a></H3>
+<H3><a name="Javascript_simple_example">28.4.1 Simple</a></H3>
 
 
 <p>The common example <code>simple</code> looks like this:</p>
@@ -474,9 +496,9 @@
 </div>
 <p>First the module <code>example</code> is loaded from the previously built extension. Global methods and variables are available in the scope of the module.</p>
 
-<p><b>Note</b>: ECMAScript 5, the currently implemented Javascript standard, does not have modules. <code>node.js</code> and other implementations provide this mechanism defined by the <a href="http://wiki.commonjs.org/wiki/CommonJS">CommonJS</a> group. For browsers this is provided by <a href="http://browserify.org">Browserify</a>, for instance.</p>
+<p><b>Note</b>: ECMAScript 5, the currently implemented Javascript standard, does not have modules. <code>node.js</code> and other implementations provide this mechanism defined by the <a href="https://wiki.commonjs.org/wiki/CommonJS">CommonJS</a> group. For browsers this is provided by <a href="https://browserify.org">Browserify</a>, for instance.</p>
 
-<H3><a name="Javascript_class_example">27.4.2 Class</a></H3>
+<H3><a name="Javascript_class_example">28.4.2 Class</a></H3>
 
 
 <p>The common example <code>class</code> defines three classes, <code>Shape</code>, <code>Circle</code>, and <code>Square</code>:</p>
@@ -606,15 +628,15 @@
 <b>Note</b>: In ECMAScript 5 there is no concept for classes. Instead each function can be used as a constructor function which is executed by the 'new' operator. Furthermore, during construction the key property <code>prototype</code> of the constructor function is used to attach a prototype instance to the created object. A prototype is essentially an object itself that is the first-class delegate of a class used whenever the access to a property of an object fails. The very same prototype instance is shared among all instances of one type. Prototypal inheritance is explained in more detail on in <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain">Inheritance and the prototype chain</a>, for instance.
 </p>
 
-<H2><a name="Javascript_implementation">27.5 Implementation</a></H2>
+<H2><a name="Javascript_implementation">28.5 Implementation</a></H2>
 
 
 <p>The Javascript Module implementation has taken a very different approach compared to other language modules in order to support different Javascript interpreters.</p>
 
-<H3><a name="Javascript_source_code">27.5.1 Source Code</a></H3>
+<H3><a name="Javascript_source_code">28.5.1 Source Code</a></H3>
 
 
-<p>The Javascript module is implemented in <code>Source/Modules/javascript.cxx</code>. It dispatches the code generation to a <code>JSEmitter</code> instance, <code>V8Emitter</code> or <code>JSCEmitter</code>. Additionally there are some helpers: <code>Template</code>, for templated code generation, and <code>JSEmitterState</code>, which is used to manage state information during AST traversal. This rough map shall make it easier to find a way through this huge source file:</p>
+<p>The Javascript module is implemented in <code>Source/Modules/javascript.cxx</code>. It dispatches the code generation to a <code>JSEmitter</code> instance, <code>V8Emitter</code>, <code>JSCEmitter</code> or <code>NAPIEmitter</code>. Additionally there are some helpers: <code>Template</code>, for templated code generation, and <code>JSEmitterState</code>, which is used to manage state information during AST traversal. This rough map shall make it easier to find a way through this huge source file:</p>
 <div class="code">
 <pre>
 // module wide defines
@@ -638,6 +660,7 @@
 
 JSEmitter *swig_javascript_create_JSCEmitter();
 JSEmitter *swig_javascript_create_V8Emitter();
+JSEmitter *swig_javascript_create_NAPIEmitter();
 
 // ###############################
 // # Javascript module
@@ -712,10 +735,10 @@
 ...</pre>
 </div>
 
-<H3><a name="Javascript_code_templates">27.5.2 Code Templates</a></H3>
+<H3><a name="Javascript_code_templates">28.5.2 Code Templates</a></H3>
 
 
-<p>All generated code is created on the basis of code templates. The templates for <em>JavascriptCore</em> can be found in <code>Lib/javascript/jsc/javascriptcode.swg</code>, for <em>v8</em> in <code>Lib/javascript/v8/javascriptcode.swg</code>.</p>
+<p>All generated code is created on the basis of code templates. The templates for <em>JavascriptCore</em> can be found in <code>Lib/javascript/jsc/javascriptcode.swg</code>, for <em>v8</em> in <code>Lib/javascript/v8/javascriptcode.swg</code> and for <em>Node-API</em> in <code>Lib/javascript/napi/javascriptcode.swg</code>.</p>
 <p>To track the originating code template for generated code you can run</p>
 <div class="shell">
 <pre>
@@ -751,7 +774,7 @@
 </div>
 <p><code>Template</code> creates a copy of that string and <code>Template::replace</code> uses Swig's <code>Replaceall</code> to replace variables in the template. <code>Template::trim</code> can be used to eliminate leading and trailing whitespaces. <code>Template::print</code> is used to write the final template string to a Swig <code>DOH</code> (based on <code>Printv</code>). All methods allow chaining.</p>
 
-<H3><a name="Javascript_emitter">27.5.3 Emitter</a></H3>
+<H3><a name="Javascript_emitter">28.5.3 Emitter</a></H3>
 
 
 <p>The Javascript module delegates code generation to a <code>JSEmitter</code> instance. The following extract shows the essential interface:</p>
@@ -870,7 +893,7 @@
 </div>
 <p>In <code>enterClass</code> the emitter stores state information that is necessary when processing class members. In <code>exitClass</code> the wrapper code for the whole class is generated.</p>
 
-<H3><a name="Javascript_emitter_states">27.5.4 Emitter states</a></H3>
+<H3><a name="Javascript_emitter_states">28.5.4 Emitter states</a></H3>
 
 
 <p>For storing information during the AST traversal the emitter provides a <code>JSEmitterState</code> with different slots to store data representing the scopes global, class, function, and variable.</p>
@@ -914,7 +937,7 @@
 <p>State information can be retrieved using <code>state.clazz(NAME)</code> or with <code>Getattr</code> on <code>state.clazz()</code> which actually returns a <code>Hash</code> instance.</p>
 
 
-<H3><a name="Javascript_jsc_exceptions">27.5.5 Handling Exceptions in JavascriptCore</a></H3>
+<H3><a name="Javascript_jsc_exceptions">28.5.5 Handling Exceptions in JavascriptCore</a></H3>
 
 
 <p>Applications with an embedded JavascriptCore should be able to present detailed exception messages that occur in the Javascript engine. Below is an example derived from code provided by Brian Barnes on how these exception details can be extracted.</p>
@@ -994,5 +1017,30 @@
 }</pre>
 </div>
 
+<H3><a name="Javascript_napi_exceptions">28.5.6 Handling Exceptions in Node-API</a></H3>
+
+
+<p>Node-API is the only generator that provides fully automatic conversion of C++ exceptions to JavaScript exceptions when building with C++ exceptions enabled in `binding.gyp`:</p>
+<div class="code">
+<pre>
+'conditions': [
+  ['OS=="mac"',
+    {
+      'xcode_settings': {
+        'GCC_ENABLE_CPP_RTTI': 'YES',
+        'GCC_ENABLE_CPP_EXCEPTIONS' : 'YES'
+      }
+    }
+  ],
+  ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"',
+    {
+      'cflags!': [ '-fno-exceptions' ],
+      'cflags_cc!': [ '-fno-exceptions', '-fno-rtti' ]
+    }
+  ]
+]
+</pre>
+</div>
+<p>In this case, nothing else is needed for the C++ exceptions to be passed to JavaScript.</p>
 </body>
 </html>
diff --git a/Doc/Manual/Library.html b/Doc/Manual/Library.html
index 5608592..c405c6f 100644
--- a/Doc/Manual/Library.html
+++ b/Doc/Manual/Library.html
@@ -7,13 +7,14 @@
 </head>
 
 <body bgcolor="#ffffff">
-<H1><a name="Library">11 SWIG library</a></H1>
+<H1><a name="Library">12 SWIG library</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
 <li><a href="#Library_nn2">The %include directive and library search path</a>
 <li><a href="#Library_nn3">C arrays and pointers</a>
 <ul>
+<li><a href="#Library_argcargv">argcargv.i</a>
 <li><a href="#Library_nn4">cpointer.i</a>
 <li><a href="#Library_carrays">carrays.i</a>
 <li><a href="#Library_nn6">cmalloc.i</a>
@@ -29,6 +30,7 @@
 <li><a href="#Library_stl_cpp_library">STL/C++ library</a>
 <ul>
 <li><a href="#Library_std_string">std::string</a>
+<li><a href="#Library_std_string_view">std::string_view</a>
 <li><a href="#Library_std_vector">std::vector</a>
 <li><a href="#Library_stl_exceptions">STL exceptions</a>
 <li><a href="#Library_std_shared_ptr">shared_ptr smart pointer</a>
@@ -39,11 +41,16 @@
 <li><a href="#Library_shared_ptr_templates">shared_ptr and templates</a>
 <li><a href="#Library_shared_ptr_directors">shared_ptr and directors</a>
 </ul>
+<li><a href="#Library_std_unique_ptr">unique_ptr smart pointer</a>
 <li><a href="#Library_std_auto_ptr">auto_ptr smart pointer</a>
 </ul>
 <li><a href="#Library_nn16">Utility Libraries</a>
 <ul>
 <li><a href="#Library_nn17">exception.i</a>
+<li><a href="#Library_attributes">attribute.i</a>
+<ul>
+<li><a href="#Library_attribute_templates">%attribute and C++ templates</a>
+</ul>
 </ul>
 </ul>
 </div>
@@ -67,7 +74,7 @@
 carefully if you used the old libraries.
 </p>
 
-<H2><a name="Library_nn2">11.1 The %include directive and library search path</a></H2>
+<H2><a name="Library_nn2">12.1 The %include directive and library search path</a></H2>
 
 
 <p>
@@ -99,7 +106,7 @@
 The directories that are searched are displayed when using <tt>-verbose</tt> commandline option.
 </p>
 
-<H2><a name="Library_nn3">11.2 C arrays and pointers</a></H2>
+<H2><a name="Library_nn3">12.2 C arrays and pointers</a></H2>
 
 
 <p>
@@ -111,7 +118,48 @@
 memory, their use is potentially unsafe and you should exercise caution.
 </p>
 
-<H3><a name="Library_nn4">11.2.1 cpointer.i</a></H3>
+<H3><a name="Library_argcargv">12.2.1 argcargv.i</a></H3>
+
+
+<p>
+The argcargv.i library is a simple library providing multi-argument typemaps for handling C
+argc argv command line argument C string arrays.
+The <tt>argc</tt> parameter contains the argument count and <tt>argv</tt> contains the argument vector array.
+</p>
+
+<p>
+This library provides the following multi-argument typemap:
+</p>
+
+<p>
+<b><tt>(int ARGC, char **ARGV)</tt></b>
+</p>
+
+<p>
+Apply this multi-argument typemap to your use case, for example:
+</p>
+
+<div class="code">
+<pre>
+%apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
+
+int mainApp(size_t argc, const char **argv);
+</pre>
+</div>
+
+<p>
+then from Ruby:
+</p>
+
+<div class="targetlang">
+<pre>
+$args = ["myarg1", "myarg2"]
+mainApp(args);
+</pre>
+</div>
+
+
+<H3><a name="Library_nn4">12.2.2 cpointer.i</a></H3>
 
 
 <p>
@@ -327,7 +375,7 @@
 <b>Note:</b> When working with simple pointers, typemaps can often be used to provide more seamless operation.
 </p>
 
-<H3><a name="Library_carrays">11.2.2 carrays.i</a></H3>
+<H3><a name="Library_carrays">12.2.3 carrays.i</a></H3>
 
 
 <p>
@@ -345,7 +393,7 @@
 <p>Creates four functions.</p>
 
 <p>
-<tt>type *new_name(int nelements)</tt>
+<tt>type *new_name(size_t nelements)</tt>
 </p>
 
 <div class="indent"><p>
@@ -362,7 +410,7 @@
 </p></div>
 
 <p>
-<tt>type name_getitem(type *ary, int index)</tt>
+<tt>type name_getitem(type *ary, size_t index)</tt>
 </p>
 
 <div class="indent"><p>
@@ -370,7 +418,7 @@
 </p></div>
 
 <p>
-<tt>void name_setitem(type *ary, int index, type value)</tt>
+<tt>void name_setitem(type *ary, size_t index, type value)</tt>
 </p>
 
 <div class="indent"><p>
@@ -443,10 +491,10 @@
 <div class="code">
 <pre>
 struct name {
-  name(int nelements);                  // Create an array
+  name(size_t nelements);               // Create an array
   ~name();                              // Delete array
-  type getitem(int index);              // Return item
-  void setitem(int index, type value);  // Set item
+  type getitem(size_t index);           // Return item
+  void setitem(size_t index, type value);  // Set item
   type *cast();                         // Cast to original type
   static name *frompointer(type *);     // Create class wrapper from
                                         // existing pointer
@@ -506,7 +554,7 @@
 SWIG's default handling of these types is to handle them as character strings and the two macros do not do enough to change this.
 </p>
 
-<H3><a name="Library_nn6">11.2.3 cmalloc.i</a></H3>
+<H3><a name="Library_nn6">12.2.4 cmalloc.i</a></H3>
 
 
 <p>
@@ -667,7 +715,7 @@
 </pre>
 </div>
 
-<H3><a name="Library_nn7">11.2.4 cdata.i</a></H3>
+<H3><a name="Library_nn7">12.2.5 cdata.i</a></H3>
 
 
 <p>
@@ -769,7 +817,7 @@
 Clearly they are unsafe.
 </p>
 
-<H2><a name="Library_nn8">11.3 C string handling</a></H2>
+<H2><a name="Library_nn8">12.3 C string handling</a></H2>
 
 
 <p>
@@ -789,7 +837,7 @@
 for manipulating raw C strings.
 </p>
 
-<H3><a name="Library_nn9">11.3.1 Default string handling</a></H3>
+<H3><a name="Library_nn9">12.3.1 Default string handling</a></H3>
 
 
 <p>
@@ -830,7 +878,7 @@
 not work well with binary data. Instead, strings are assumed to be NULL-terminated.
 </p>
 
-<H3><a name="Library_nn10">11.3.2 Passing binary data</a></H3>
+<H3><a name="Library_nn10">12.3.2 Passing binary data</a></H3>
 
 
 <p>
@@ -872,7 +920,7 @@
 The <tt>(char *STRING, int LENGTH)</tt> multi-argument typemap is also available in addition to <tt>(char *STRING, size_t LENGTH)</tt>.
 </p>
 
-<H3><a name="Library_nn11">11.3.3 Using %newobject to release memory</a></H3>
+<H3><a name="Library_nn11">12.3.3 Using %newobject to release memory</a></H3>
 
 
 <p>
@@ -913,7 +961,7 @@
 See <a href="Customization.html#Customization_ownership">Object ownership and %newobject</a> for more details.
 </p>
 
-<H3><a name="Library_nn12">11.3.4 cstring.i</a></H3>
+<H3><a name="Library_nn12">12.3.4 cstring.i</a></H3>
 
 
 <p>
@@ -1373,7 +1421,7 @@
 </li>
 </ul>
 
-<H2><a name="Library_stl_cpp_library">11.4 STL/C++ library</a></H2>
+<H2><a name="Library_stl_cpp_library">12.4 STL/C++ library</a></H2>
 
 
 <p>
@@ -1403,14 +1451,15 @@
 <tr> <td>std::multiset (C++11)</td>           <td>multiset</td>             <td>std_multiset.i</td> </tr>
 <tr> <td>std::pair</td>           <td>utility</td>             <td>std_pair.i</td> </tr>
 <tr> <td>std::set</td>           <td>set</td>             <td>std_set.i</td> </tr>
+<tr> <td>std::shared_ptr (C++11)</td>           <td>shared_ptr</td>             <td>std_shared_ptr.i</td> </tr>
 <tr> <td>std::string</td>           <td>string</td>             <td>std_string.i</td> </tr>
+<tr> <td>std::string_view (C++17)</td>           <td>string_view</td>             <td>std_string_view.i</td> </tr>
 <tr> <td>std::unordered_map (C++11)</td>           <td>unordered_map</td>             <td>std_unordered_map.i</td> </tr>
 <tr> <td>std::unordered_multimap (C++11)</td>           <td>unordered_multimap</td>             <td>std_unordered_multimap.i</td> </tr>
 <tr> <td>std::unordered_multiset (C++11)</td>           <td>unordered_multiset</td>             <td>std_unordered_multiset.i</td> </tr>
 <tr> <td>std::unordered_set (C++11)</td>           <td>unordered_set</td>             <td>std_unordered_set.i</td> </tr>
 <tr> <td>std::vector</td>           <td>vector</td>             <td>std_vector.i</td> </tr>
 <tr> <td>std::wstring</td>           <td>wstring</td>             <td>std_wstring.i</td> </tr>
-<tr> <td>std::shared_ptr (C++11)</td>           <td>shared_ptr</td>             <td>std_shared_ptr.i</td> </tr>
 
 </table>
 
@@ -1420,7 +1469,7 @@
 </p>
 
 
-<H3><a name="Library_std_string">11.4.1 std::string</a></H3>
+<H3><a name="Library_std_string">12.4.1 std::string</a></H3>
 
 
 <p>
@@ -1504,7 +1553,51 @@
 </pre>
 </div>
 
-<H3><a name="Library_std_vector">11.4.2 std::vector</a></H3>
+<H3><a name="Library_std_string_view">12.4.2 std::string_view</a></H3>
+
+
+<p>
+The <tt>std_string_view.i</tt> library provides typemaps for converting C++17 <tt>std::string_view</tt>
+objects to and from strings in the target scripting language.  For example:
+</p>
+
+<div class="code">
+<pre>
+%module example
+%include "std_string_view.i"
+
+std::string_view foo();
+void        bar(std::string_view x);
+</pre>
+</div>
+
+<p>
+In the target language:
+</p>
+
+<div class="targetlang">
+<pre>
+x = foo();                # Returns a string object
+bar("Hello World");       # Pass string as std::string_view
+</pre>
+</div>
+
+<p>
+For target languages for which SWIG supports directors, <tt>directorout</tt>
+typemaps are provided for <tt>std::string_view</tt>, but these require extra
+care to use safely.  The issue is that returning <tt>std::string_view</tt>
+effectively returns a pointer to string data but doesn't own the pointed to
+data.  For target languages where there isn't a native narrow string
+representation (e.g. C#, Java) a <tt>static std::string</tt> is used to cache
+the data, which works but isn't thread/reentrant safe.  For target languages
+where there is a native narrow string representation SWIG will return a
+<tt>std::string_view</tt> pointing to that data, so you need to store the
+string to return somewhere which will persist for the lifetime the caller
+needs (e.g. put it in a member variable) - you can't return a temporary target
+language string.  In both cases SWIG will issue a warning by default.
+</p>
+
+<H3><a name="Library_std_vector">12.4.3 std::vector</a></H3>
 
 
 <p>
@@ -1683,7 +1776,7 @@
 details and the public API exposed to the interpreter vary.
 </p>
 
-<H3><a name="Library_stl_exceptions">11.4.3 STL exceptions</a></H3>
+<H3><a name="Library_stl_exceptions">12.4.4 STL exceptions</a></H3>
 
 
 <p>
@@ -1733,10 +1826,10 @@
 Any thrown STL exceptions will then be gracefully handled instead of causing a crash.
 </p>
 
-<H3><a name="Library_std_shared_ptr">11.4.4 shared_ptr smart pointer</a></H3>
+<H3><a name="Library_std_shared_ptr">12.4.5 shared_ptr smart pointer</a></H3>
 
 
-<H4><a name="Library_shared_ptr_basics">11.4.4.1 shared_ptr basics</a></H4>
+<H4><a name="Library_shared_ptr_basics">12.4.5.1 shared_ptr basics</a></H4>
 
 
 <p>
@@ -1779,7 +1872,7 @@
 
 <p>
 You can only use one of these variants of shared_ptr in your interface file at a time.
-and all three variants must be used in conjunction with the <tt>%shared_ptr(T)</tt> macro,
+All three variants must be used in conjunction with the <tt>%shared_ptr(T)</tt> macro,
 where <tt>T</tt> is the underlying pointer type equating to usage <tt>shared_ptr&lt;T&gt;</tt>.
 The type <tt>T</tt> must be non-primitive.
 A simple example demonstrates usage:
@@ -1832,7 +1925,7 @@
 </pre>
 </div>
 
-<H4><a name="Library_shared_ptr_inheritance">11.4.4.2 shared_ptr and inheritance</a></H4>
+<H4><a name="Library_shared_ptr_inheritance">12.4.5.2 shared_ptr and inheritance</a></H4>
 
 
 <p>
@@ -1923,7 +2016,7 @@
 </pre>
 </div>
 
-<H4><a name="Library_shared_ptr_overloading">11.4.4.3 shared_ptr and method overloading</a></H4>
+<H4><a name="Library_shared_ptr_overloading">12.4.5.3 shared_ptr and method overloading</a></H4>
 
 
 <p>
@@ -1945,7 +2038,7 @@
 For the interested reader, SWIG detects that they are equivalent types via the <a href=Typemaps.html#Typemaps_typecheck_pointer>typecheck typemaps</a> in the shared_ptr library.
 </p>
 
-<H4><a name="Library_shared_ptr_templates">11.4.4.4 shared_ptr and templates</a></H4>
+<H4><a name="Library_shared_ptr_templates">12.4.5.4 shared_ptr and templates</a></H4>
 
 
 <p>
@@ -1987,45 +2080,48 @@
 </pre>
 </div>
 
-<H4><a name="Library_shared_ptr_directors">11.4.4.5 shared_ptr and directors</a></H4>
+<H4><a name="Library_shared_ptr_directors">12.4.5.5 shared_ptr and directors</a></H4>
 
 
 <p>
 The languages that support shared_ptr also have support for using shared_ptr with directors.
 </p>
 
-
-<H3><a name="Library_std_auto_ptr">11.4.5 auto_ptr smart pointer</a></H3>
+<H3><a name="Library_std_unique_ptr">12.4.6 unique_ptr smart pointer</a></H3>
 
 
 <p>
-While <tt>std::auto_ptr</tt> is deprecated in C++11, some existing code may
-still be using it, so SWIG provides limited support for this class:
-<tt>std_auto_ptr.i</tt> defines the typemaps which apply to the functions
-returning objects of this type. Any other use of <tt>std_auto_ptr.i</tt> is not
-directly supported.
+The <tt>std_unique_ptr.i</tt> library file provides SWIG's unique_ptr support.
+It defines typemaps and a macro, <tt>%unique_ptr(T)</tt>, to use for handling
+<tt>std::unique_ptr&lt;T&gt;</tt> for a type <tt>T</tt>.
+The type <tt>T</tt> must be non-primitive.
+This macro should be used before any code declaring or using type <tt>T</tt>.
+Ordering requirements for using this smart pointer macro are the same as the
+equivalent <tt>%shared_ptr(T)</tt> macro covered in the previous section.
 </p>
 
 <p>
-A typical example of use would be
+Example usage of a <tt>std::unique_ptr</tt> being returned from a function is shown below.
 </p>
+
 <div class="code">
 <pre>
-%include &lt;std_auto_ptr.i&gt;
+%include &lt;std_unique_ptr.i&gt;
 
-%auto_ptr(Klass)
+%unique_ptr(Klass)
 %inline %{
+#include &lt;memory&gt;
 class Klass {
 public:
   // Factory function creating objects of this class:
-  static std::auto_ptr&lt;Klass&gt; Create(int value) {
-    return std::auto_ptr&lt;Klass&gt;(new Klass(value));
+  static std::unique_ptr&lt;Klass&gt; Create(int value) {
+    return std::unique_ptr&lt;Klass&gt;(new Klass(value));
   }
 
   int getValue() const { return m_value; }
 
 private:
-  DerivedIntValue(int value) : m_value(value) {}
+  Klass(int value) : m_value(value) {}
   int m_value;
 };
 %}
@@ -2044,10 +2140,148 @@
 </pre>
 </div>
 
-<H2><a name="Library_nn16">11.5 Utility Libraries</a></H2>
+<p>
+The implementation simply calls <tt>std::unique_ptr::release()</tt> to obtain
+the underlying raw pointer. The pointer is then used to create a target language
+proxy class in the same way that SWIG handles a C++ function returning a class by value.
+The target language proxy class then owns the memory pointed to by the raw pointer
+and memory handling is identical to normal SWIG proxy class handling of the underlying C++ memory.
+Note that an object returned by value is first copied/moved from the stack onto the heap in order to obtain
+a raw pointer on the heap, whereas the underlying raw pointer in <tt>std::unique_ptr</tt> already points to an object the heap.
+</p>
+
+<p>
+Note that the implementation is quite different to the <tt>std::shared_ptr</tt> smart pointer,
+where the proxy class manages the underlying C++ memory as a pointer to a shared_ptr instead of a plain raw pointer.
+</p>
+
+<p>
+A possibly less common usage of this smart pointer is as a parameter to a function.
+When used like this it indicates that memory usage of the object pointed to by the underlying pointer
+is transferred to the function being called.
+The code that SWIG generates assumes this happens.
+First, it is assumed that a proxy class already owns the underlying C++ object and is used to pass the object to the C++ function being called.
+Second, the ownership is transferred from the proxy class to the C++ function being called and
+lifetime is then controlled by the function.
+Finally, it is assumed the lifetime of the object may not last beyond returning from the C++ function
+and hence the proxy class can no longer be used.
+</p>
+
+<p>
+Consider expanding the example above with a function that takes a <tt>std::unique_ptr</tt> as follows:
+</p>
+
+<div class="code">
+<pre>
+void take(std::unique_ptr&lt;Klass&gt;);
+</pre>
+</div>
+
+<p>
+and use from C#:
+</p>
+
+<div class="targetlang">
+<pre>
+Klass k = Klass.Create(17); // create an instance of Klass any way you like
+int value = k.getValue();   // ok
+example.take(k);            // memory ownership passes from C# layer to C++ layer
+int v = k.getValue();       // don't do this - invalid use of k
+</pre>
+</div>
+
+<p>
+Attempts to use <tt>k</tt> after the ownership has been passed into the <tt>take</tt> function
+should not be attempted.
+The implementation sets the proxy class to an invalid state by setting the class's underlying
+C++ pointer to null after the return from the <tt>take</tt> function.
+Subsequent use of an invalid proxy class instance is very much dependent on the implementation
+in the target language and ranges from a segfault to giving a nice error.
+Consider implementing additional checks via the 'check' typemap.
+</p>
+
+<p>
+Attempts to pass ownership from a proxy class to a <tt>std::unique</tt> parameter more than once will result
+in a "Cannot release ownership as memory is not owned" exception. For example, if <tt>example.take(k)</tt> in the example above is called twice.
+</p>
+
+<p>
+<b>Compatibility note:</b> Support for <tt>std::unique_ptr</tt> was added in SWIG-4.1.0.
+</p>
+
+<H3><a name="Library_std_auto_ptr">12.4.7 auto_ptr smart pointer</a></H3>
 
 
-<H3><a name="Library_nn17">11.5.1 exception.i</a></H3>
+<p>
+While <tt>std::auto_ptr</tt> is deprecated in C++11, some existing code may
+still be using it. SWIG provides support for this class which is nearly identical
+to <tt>std::unique_ptr</tt>.
+</p>
+
+<p>
+The <tt>std_auto_ptr.i</tt> library file provides SWIG's auto_ptr support.
+It defines typemaps and a macro, <tt>%auto_ptr(T)</tt>, to use for handling
+<tt>std::auto_ptr&lt;T&gt;</tt> for a type <tt>T</tt>.
+The type <tt>T</tt> must be non-primitive.
+This macro should be used before any code declaring or using type <tt>T</tt>.
+Ordering requirements for using this smart pointer macro are the same as the
+equivalent <tt>%shared_ptr(T)</tt> and <tt>%unique_ptr</tt> macros covered in
+the previous two sections.
+</p>
+
+<p>
+Example usage of a <tt>std::auto_ptr</tt> being returned from a function is shown below.
+</p>
+
+<div class="code">
+<pre>
+%include &lt;std_auto_ptr.i&gt;
+
+%auto_ptr(Klass)
+%inline %{
+#include &lt;memory&gt;
+class Klass {
+public:
+  // Factory function creating objects of this class:
+  static std::auto_ptr&lt;Klass&gt; Create(int value) {
+    return std::auto_ptr&lt;Klass&gt;(new Klass(value));
+  }
+
+  int getValue() const { return m_value; }
+
+private:
+  Klass(int value) : m_value(value) {}
+  int m_value;
+};
+%}
+</pre>
+</div>
+
+<p>
+The returned objects can be used naturally from the target language, e.g. from
+C#:
+</p>
+
+<div class="targetlang">
+<pre>
+Klass k = Klass.Create(17);
+int value = k.getValue();
+</pre>
+</div>
+
+<p>
+The implementation simply calls <tt>std::auto_ptr::release()</tt> to obtain the underlying raw pointer.
+That is, it works the same way covered in the previous section for <tt>std::unique_ptr</tt>.
+</p>
+
+<p>
+Input parameters also work the same way as <tt>std::unique_ptr</tt> covered in the previous section.
+</p>
+
+<H2><a name="Library_nn16">12.5 Utility Libraries</a></H2>
+
+
+<H3><a name="Library_nn17">12.5.1 exception.i</a></H3>
 
 
 <p>
@@ -2108,5 +2342,244 @@
 </div>
 
 
+<H3><a name="Library_attributes">12.5.2 attribute.i</a></H3>
+
+
+<p>
+The attribute library contains a set of macros to convert a pair of set/get methods
+into a "native" attribute/property.
+</p>
+
+<p>
+Use <tt>%attribute</tt> when you have a pair of get/set methods to a
+primitive type like:
+</p>
+
+<div class="code">
+<pre>
+%include "attribute.i"
+%attribute(A, int, a, get_a, set_a);
+
+struct A {
+  int get_a() const;
+  void set_a(int aa);
+};
+</pre>
+</div>
+
+<p>
+and you want to provide that variable as an attribute in the target
+language. This example only works for primitive types, not derived
+types.
+Now you can use the attributes like so (in Python):
+</p>
+
+<div class="targetlang">
+<pre>
+x = A()
+x.a = 3        # calls A::set_a(3)
+print(x.a)     # calls A::get_a() const
+</pre>
+</div>
+
+<p>
+If you don't provide a 'set' method, a 'read-only' attribute
+is generated, ie, like:
+</p>
+
+<div class="code">
+<pre>
+%attribute(A, int, c, get_c);
+</pre>
+</div>
+
+<p>
+Use <tt>%attributeref</tt> when you have const/non-const reference
+access methods for primitive types or class/structs, like:
+</p>
+
+<div class="code">
+<pre>
+%attributeref(A, int, b);
+
+struct A {
+  const int &amp; b() const;
+  int &amp; b();
+};
+
+%attributeref(B, int, c);
+
+struct B {
+  int &amp; c();
+};
+</pre>
+</div>
+
+<p>
+Use the attributes like so (in Python):
+</p>
+
+<div class="targetlang">
+<pre>
+x = A()
+x.b = 3        # calls A::b()
+print(x.b)     # calls A::b() const
+</pre>
+</div>
+
+<p>
+You can also use
+</p>
+
+<div class="code">
+<pre>
+%attributeref(Class, AttributeType, AttributeName, AccessorMethod)
+</pre>
+</div>
+
+<p>
+if the internal C++ reference methods have a different name from the
+attribute you want, so
+</p>
+
+<div class="code">
+<pre>
+%attributeref(B, int, d, c);
+</pre>
+</div>
+
+<p>
+is the same as the last example, but instead of the attribute 'c' being
+called 'c', it is called 'd'.
+</p>
+
+<p>
+Use <tt>%attribute2</tt> instead of <tt>%attribute</tt> to indicate
+that reference-pointer translation is required.
+Use <tt>%attribute2</tt> instead of <tt>%attribute</tt> in cases like
+this:
+</p>
+
+<div class="code">
+<pre>
+%attribute2(MyClass, MyFoo, Foo, GetFoo, SetFoo);
+%inline %{
+  struct MyFoo {
+    int x;
+  };
+  class MyClass {
+    MyFoo foo;
+  public:
+    MyFoo &amp; GetFoo() { return foo; }
+    void SetFoo(const MyFoo &amp;other) { foo = other; }
+  };
+%}
+</pre>
+</div>
+
+<p>
+Here, the data type of the property is a wrapped type <tt>MyFoo</tt> and on
+the C++ side it is passed by reference. The problem is that the SWIG
+wrapper will pass around a pointer (MyFoo *) which is not compatible
+with the reference type of the accessors (MyFoo &amp;). Therefore, if you
+use <tt>%attribute</tt>, you'll get an error from your C/C++
+compiler. <tt>%attribute2</tt> translates between a pointer and a
+reference to eliminate the error. In case you're confused, let's make
+it simple: just use <tt>%attribute</tt> at first, but if the C/C++
+compiler gives an error while compiling the wrapper,
+try <tt>%attribute2</tt> instead.
+</p>
+
+<p>
+NOTE: remember that if the type contains commas, such as
+<tt>std::pair&lt;int, int&gt;</tt>, you need to use the macro like:
+</p>
+
+<div class="code">
+<pre>
+%attributeref(A, %arg(std::pair&lt;int, int&gt;), pval);
+</pre>
+</div>
+
+<p>
+where <tt>%arg()</tt> 'normalizes' the type to be understood as a single
+argument, otherwise the macro will get confused by the comma.
+</p>
+
+<p>
+The <tt>%attributeval</tt> is the same as <tt>%attribute</tt>, but
+should be used when the type is a class/struct (ie a non-primitive
+type) and when the get and set methods return/pass by value. The
+following is very similar to the above example, but note that the
+access is by value rather than reference.
+</p>
+
+<div class="code">
+<pre>
+%attributeval(MyClassVal, MyFoo, ReadWriteFoo, GetFoo, SetFoo);
+%attributeval(MyClassVal, MyFoo, ReadOnlyFoo, GetFoo);
+%inline %{
+  class MyClassVal {
+    MyFoo foo;
+  public:
+    MyFoo GetFoo() { return foo; }
+    void SetFoo(MyFoo other) { foo = other; }
+  };
+%}
+</pre>
+</div>
+
+<p>
+The <tt>%attributestring</tt> is the same as <tt>%attributeval</tt>,
+but should be used for string class types, which are unusual as they
+are a class on the C++ side, but normally an immutable/primitive type
+in the target language. Example usage for <tt>std::string</tt>:
+</p>
+
+<div class="code">
+<pre>
+%include &lt;std_string.i&gt;
+%attributestring(MyStringyClass, std::string, ReadWriteString, GetString, SetString);
+%attributestring(MyStringyClass, std::string, ReadOnlyString, GetString);
+%inline %{
+  class MyStringyClass {
+    std::string str;
+  public:
+    MyStringyClass(const std::string &amp;val) : str(val) {}
+    std::string GetString() { return str; }
+    void SetString(std::string other) { str = other; }
+  };
+%}
+</pre>
+</div>
+
+<p>
+The <tt>%attributestring</tt> also works for class types that
+have <tt>%naturalvar</tt> turned on and so is also useful for
+shared_ptr which has <tt>%naturalvar</tt> turned on in
+<tt>%shared_ptr</tt>.
+</p>
+
+<H4><a name="Library_attribute_templates">12.5.2.1 %attribute and C++ templates</a></H4>
+
+
+<p>
+  <tt>%attribute</tt> and friends have to be used on fully specified classes. For example
+</p>
+<div class="code">
+<pre>
+%attributeref(A&lt;int&gt;, int, a);
+%inline %{
+  template &lt;class T&gt; struct A {
+    T a() const;
+    void a(T &amp;);
+  };
+%}
+</pre>
+</div>
+<p>
+Note the use of a template-id (i.e., <tt>A&lt;int&gt;</tt> not <tt>A&lt;T&gt;</tt> or just <tt>A</tt>).
+This means that <tt>%attribute</tt> statements have to be repeated for any template-id that you want to use with <tt>%template</tt>.
+</p>
 </body>
 </html>
diff --git a/Doc/Manual/Lisp.html b/Doc/Manual/Lisp.html
deleted file mode 100644
index 6eb448a..0000000
--- a/Doc/Manual/Lisp.html
+++ /dev/null
@@ -1,604 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-<title>SWIG and Common Lisp</title>
-<link rel="stylesheet" type="text/css" href="style.css">
-<meta http-equiv="content-type" content="text/html; charset=UTF-8">
-</head>
-
-<body bgcolor="#ffffff">
-<H1><a name="Lisp">29 SWIG and Common Lisp</a></H1>
-<!-- INDEX -->
-<div class="sectiontoc">
-<ul>
-<li><a href="#Lisp_nn3">Common Foreign Function Interface(CFFI)</a>
-<ul>
-<li><a href="#Lisp_nn4">Additional Commandline Options </a>
-<li><a href="#Lisp_nn5">Generating CFFI bindings</a>
-<li><a href="#Lisp_nn6">Generating CFFI bindings for C++ code</a>
-<li><a href="#Lisp_nn7">Inserting user code into generated files</a>
-</ul>
-<ul>
-<li><a href="#Lisp_nn9">Additional Commandline Options </a>
-</ul>
-</ul>
-</div>
-<!-- INDEX -->
-
-
-
-<p>
-      Common Lisp is a high-level, all-purpose, object-oriented,
-      dynamic, functional programming language with long history. 
-      Common Lisp is used in many fields, ranging from web development to
-      finance, and also common in computer science education.
-      There are more than 9 different implementations of common lisp which
-      are available, all have different foreign function
-      interfaces. SWIG currently supports the
-      Common Foreign Function Interface(CFFI).
-</p>
-
-<H2><a name="Lisp_nn3">29.2 Common Foreign Function Interface(CFFI)</a></H2>
-
-
-<p>
-      CFFI, the Common Foreign Function Interface, is a portable foreign
-      function interface for ANSI Common Lisp systems.
-      CFFI requires only a small set of
-      low-level functionality from the Lisp implementation, such as
-      calling a foreign function by name, allocating foreign memory,
-      and dereferencing pointers.  
-</p>
-
-<p>
-      To run the cffi module of SWIG requires very little effort, you
-      just need to run:
-</p>
-<div class="code"><pre>
-swig -cffi -module <i>module-name</i>   <i>file-name</i> 
-
-</pre></div>
-
-<p>
-      But a better was of using all the power of SWIG is to write SWIG
-      interface files. Below we will explain how to write interface
-      files and the various things which you can do with them.
-</p>
-
-<H3><a name="Lisp_nn4">29.2.1 Additional Commandline Options </a></H3>
-
-
-<table summary="CFFI specific options">
-<tr>
- <th> CFFI specific options</th>
-</tr>
-
-<tr>
-<td>-generate-typedef</td>
-<td>If this option is given then defctype will be used to generate<br/>
-      shortcuts according to the typedefs in the input.
-</td>
-</tr>
-
-<tr>
-<td>-[no]cwrap</td>
-<td>Turn on or turn off generation of an intermediate C file when<br/>
-    creating a C interface. By default this is only done for C++ code.
-</td>
-</tr>
-
-<tr>
-<td>-[no]swig-lisp</td>
-<td>Turns on or off generation of code for helper lisp macro, functions,
-      etc. which SWIG uses while generating wrappers. These macros, functions
-      may still be used by generated wrapper code.
-</td>
-</tr>
-
-</table>
-
-<H3><a name="Lisp_nn5">29.2.2 Generating CFFI bindings</a></H3>
-
-
-<p>
-
-As we mentioned earlier the ideal way to use SWIG is to use interface
-    files. To illustrate the use of it, let's assume that we have a
-    file named <i>test.h</i> with the following C code:
-</p>
-
-<div class="code"><pre>
-#define y 5
-#define x (y &gt;&gt;  1)
-
-typedef int days;
-
-struct bar {
-  short p, q;
-  char a, b;
-  int *z[1000];
-  struct bar * n;
-};
-  
-struct   bar * my_struct;
-
-struct foo {
-  int a;
-  struct foo * b[100];
-};
-
-int pointer_func(void (*ClosureFun)( void* _fun, void* _data, void* _evt ), int p);
-
-int func123(div_t * p, int **q[100], int r[][1000][10]);
-
-void lispsort_double (int n, double * array);
-
-enum color { RED, BLUE, GREEN};
-</pre></div>
-
-<p>
-Corresponding to this we will write a simple interface file:
-</p>
-
-<div class="code"><pre>
-%module test
-
-%include "test.h"
-
-</pre></div>
-
-<p>
-The generated SWIG Code will be:
-</p>
-
-<div class="targetlang"><pre>
-;;;SWIG wrapper code starts here
-
-(cl:defmacro defanonenum (&amp;body enums)
-   "Converts anonymous enums to defconstants."
-  `(cl:progn , @(cl:loop for value in enums
-                        for index = 0 then (cl:1+ index)
-                        when (cl:listp value) do (cl:setf index (cl:second value)
-                                                          value (cl:first value))
-                        collect `(cl:defconstant , value , index))))
-
-(cl:eval-when (:compile-toplevel :load-toplevel)
-  (cl:unless (cl:fboundp 'swig-lispify)
-    (cl:defun swig-lispify (name flag cl:&amp;optional (package cl:*package*))
-      (cl:labels ((helper (lst last rest cl:&amp;aux (c (cl:car lst)))
-                    (cl:cond
-                      ((cl:null lst)
-                       rest)
-                      ((cl:upper-case-p c)
-                       (helper (cl:cdr lst) 'upper
-                               (cl:case last
-                                 ((lower digit) (cl:list* c #\- rest))
-                                 (cl:t (cl:cons c rest)))))
-                      ((cl:lower-case-p c)
-                       (helper (cl:cdr lst) 'lower (cl:cons (cl:char-upcase c) rest)))
-                      ((cl:digit-char-p c)
-                       (helper (cl:cdr lst) 'digit 
-                               (cl:case last
-                                 ((upper lower) (cl:list* c #\- rest))
-                                 (cl:t (cl:cons c rest)))))
-                      ((cl:char-equal c #\_)
-                       (helper (cl:cdr lst) '_ (cl:cons #\- rest)))
-                      (cl:t
-                       (cl:error "Invalid character: ~A" c)))))
-        (cl:let ((fix (cl:case flag
-                        ((constant enumvalue) "+")
-                        (variable "*")
-                        (cl:t ""))))
-          (cl:intern
-           (cl:concatenate
-            'cl:string
-            fix
-            (cl:nreverse (helper (cl:concatenate 'cl:list name) cl:nil cl:nil))
-            fix)
-           package))))))
-
-;;;SWIG wrapper code ends here
-
-
-(cl:defconstant y 5)
-
-(cl:defconstant x (cl:ash 5 -1))
-
-(cffi:defcstruct bar
-        (p :short)
-        (q :short)
-        (a :char)
-        (b :char)
-        (z :pointer)
-        (n :pointer))
-
-(cffi:defcvar ("my_struct" my_struct)
- :pointer)
-
-(cffi:defcstruct foo
-        (a :int)
-        (b :pointer))
-
-(cffi:defcfun ("pointer_func" pointer_func) :int
-  (ClosureFun :pointer)
-  (p :int))
-
-(cffi:defcfun ("func123" func123) :int
-  (p :pointer)
-  (q :pointer)
-  (r :pointer))
-
-(cffi:defcfun ("lispsort_double" lispsort_double) :void
-  (n :int)
-  (array :pointer))
-
-(cffi:defcenum color
-        :RED
-        :BLUE
-        :GREEN)
-</pre></div>
-
-<p>
-   The <i>SWIG wrapper</i> code refers to the special code which SWIG
-    may need to use while wrapping C code. You can turn on/off the
-    generation of this code by using the <i>-[no]swig-lisp</i>
-    option. You must have noticed that SWIG goes one extra step to
-    ensure that CFFI does not do automatic lispification of the C
-    function names. The reason SWIG does this is because quite often
-    developers want to build a nice CLOS based lispy API, and this one
-    to one correspondence between C function names and lisp function
-    name helps.
-</p>
-   
-<p> Maybe you want to have your own convention for generating lisp
-      function names for corresponding C function names, or you just
-      want to lispify the names, also, before we forget you want to
-      export the generated lisp names. To do this, we will use the
-      SWIG <a
-        href="Customization.html#Customization_features">feature directive</a>. 
-Let's edit the interface file such that the C type "div_t*" is changed
-      to Lisp type ":my-pointer", we lispify all names, 
-      export everything, and do some more stuff.
-
-</p>
-<div class="code"><pre>
-%module test
-
-%typemap(cin) div_t* ":my-pointer";
-
-%feature("intern_function", "1");
-%feature("export");
-
-%feature("inline") lispsort_double;
-%feature("intern_function", "my-lispify") lispsort_double;
-%feature("export", package="'some-other-package") lispsort_double;
-
-%rename func123 renamed_cool_func;
-
-%ignore "pointer_func";
-
-%include "test.h"
-
-</pre></div>
-
-<p>
-The <i>typemap(cin)</i> ensures that for all arguments which are input
-    to C with the type "div_t*", the ":my-pointer" type be
-    used. Similarly  <i>typemap(cout)</i> are used for all types which
-    are returned from C.
-</p>
-<p>
-The feature <i>intern_function</i> ensures that all C names are
-      interned using the <b>swig-lispify</b> function. The "1" given
-      to the feature is optional. The use of feature like
-      <i>%feature("intern_function", "1");</i> globally enables
-      interning for everything. If you want to target a single
-      function, or declaration then use the targeted version of
-      feature, <i>%feature("intern_function", "my-lispify")
-        lispsort_double;</i>, here we are using an additional feature
-      which allows us to use our lispify function.
-</p>
-<p>The <i>export</i> feature allows us to export the symbols. If
-      the <i>package</i> argument is given, then the symbol will be exported to
-      the specified Lisp package. The <i>inline</i> feature declaims the
-      declared function as inline. The <i>rename</i> directive allows us to
-      change the name(it is useful when generating C wrapper code for handling
-      overloaded functions). The <i>ignore</i> directive ignores a certain
-      declaration.
-</p>
-<p>There are several other things which are possible, to see some
-      example of usage of SWIG look at the Lispbuilder and wxCL
-      projects. The generated code with 'noswig-lisp' option is:
-</p>
-
-<div class="targetlang"><pre>
-(cl:defconstant #.(swig-lispify "y" 'constant) 5)
-
-(cl:export '#.(swig-lispify "y" 'constant))
-
-(cl:defconstant #.(swig-lispify "x" 'constant) (cl:ash 5 -1))
-
-(cl:export '#.(swig-lispify "x" 'constant))
-
-(cffi:defcstruct #.(swig-lispify "bar" 'classname)
-        (#.(swig-lispify "p" 'slotname) :short)
-        (#.(swig-lispify "q" 'slotname) :short)
-        (#.(swig-lispify "a" 'slotname) :char)
-        (#.(swig-lispify "b" 'slotname) :char)
-        (#.(swig-lispify "z" 'slotname) :pointer)
-        (#.(swig-lispify "n" 'slotname) :pointer))
-
-(cl:export '#.(swig-lispify "bar" 'classname))
-
-(cl:export '#.(swig-lispify "p" 'slotname))
-
-(cl:export '#.(swig-lispify "q" 'slotname))
-
-(cl:export '#.(swig-lispify "a" 'slotname))
-
-(cl:export '#.(swig-lispify "b" 'slotname))
-
-(cl:export '#.(swig-lispify "z" 'slotname))
-
-(cl:export '#.(swig-lispify "n" 'slotname))
-
-(cffi:defcvar ("my_struct" #.(swig-lispify "my_struct" 'variable))
- :pointer)
-
-(cl:export '#.(swig-lispify "my_struct" 'variable))
-
-(cffi:defcstruct #.(swig-lispify "foo" 'classname)
-        (#.(swig-lispify "a" 'slotname) :int)
-        (#.(swig-lispify "b" 'slotname) :pointer))
-
-(cl:export '#.(swig-lispify "foo" 'classname))
-
-(cl:export '#.(swig-lispify "a" 'slotname))
-
-(cl:export '#.(swig-lispify "b" 'slotname))
-
-(cffi:defcfun ("renamed_cool_func" #.(swig-lispify "renamed_cool_func" 'function)) :int
-  (p :my-pointer)
-  (q :pointer)
-  (r :pointer))
-
-(cl:export '#.(swig-lispify "renamed_cool_func" 'function))
-
-(cl:declaim (cl:inline #.(my-lispify "lispsort_double" 'function)))
-
-(cffi:defcfun ("lispsort_double" #.(my-lispify "lispsort_double" 'function)) :void
-  (n :int)
-  (array :pointer))
-
-(cl:export '#.(my-lispify "lispsort_double" 'function) 'some-other-package)
-
-(cffi:defcenum #.(swig-lispify "color" 'enumname)
-        #.(swig-lispify "RED" 'enumvalue :keyword)
-        #.(swig-lispify "BLUE" 'enumvalue :keyword)
-        #.(swig-lispify "GREEN" 'enumvalue :keyword))
-
-(cl:export '#.(swig-lispify "color" 'enumname))
-
-</pre></div>
-
-<H3><a name="Lisp_nn6">29.2.3 Generating CFFI bindings for C++ code</a></H3>
-
-
-<p>This feature to SWIG (for CFFI) is very new and still far from
-    complete. Pitch in with your patches, bug reports and feature
-    requests to improve it.
-</p>
-<p> Generating bindings for C++ code, requires <i>-c++</i> option to be
-      present and it first generates C binding which will wrap the C++
-      code, and then generates the 
-      corresponding CFFI wrapper code. In the generated C wrapper
-      code, you will often want to put your own C code, such as the
-      code to include various files. This can be done by making use of
-      "%{" and "%}" as shown below.
-</p> 
-<div class="code"><pre>
-%{
- #include "Test/test.h"
-%}
-</pre></div>
-<p>
-Also, while parsing the C++ file and generating C wrapper code SWIG
-    may need to be able to understand various symbols used in other
-    header files. To help SWIG in doing this while ensuring that
-    wrapper code is generated for the target file, use the "import"
-    directive. The "include" directive specifies the target file for
-    which wrapper code will be generated.
-</p>
-<div class="code"><pre>
-
-%import "ancillary/header.h"
-
-%include "target/header.h"
-
-</pre></div>
-<p>
-Various features which were available for C headers can also be used
-    here. The target header which we are going to use here is:
-</p>
-<div class="code"><pre>
-namespace OpenDemo {
-  class Test
-  {
-    public:
-      float x;
-      // constructors
-      Test (void) {x = 0;}
-      Test (float X) {x = X;}
-
-      // vector addition
-      Test operator+ (const Test&amp; v) const {return Test (x+v.x);}
-
-      // length squared
-      float lengthSquared (void) const {return this-&gt;dot (*this);}
-
-      static float distance (const Test&amp; a, const Test&amp; b){return(a-b).length();}
-
-      inline Test parallelComponent (const Test&amp; unitBasis) const {
-        return unitBasis * projection;
-      }
-
-      Test setYtoZero (void) const {return Test (this-&gt;x);}
-
-      static const Test zero;
-  };
-
-  inline Test operator* (float s, const Test&amp; v) {return v*s;}
-
-  inline std::ostream&amp; operator&lt;&lt; (std::ostream&amp; o, const Test&amp; v)
-  {
-    return o &lt;&lt; "(" &lt;&lt; v.x &lt;&lt; ")";
-  }
-
-  inline Test RandomUnitVectorOnXZPlane (void)
-  {
-    return RandomVectorInUnitRadiusSphere().setYtoZero().normalize();
-  }
-}
-</pre></div>
-<p>The interface used is: </p>
-<div class="code"><pre>
-%module test
-%include "test.cpp"
-</pre></div>
-
-<p>
-SWIG generates 3 files, the first one is a C wrap which we don't show,
-    the second is the plain CFFI wrapper which is as shown below:
-</p>
-<div class="targetlang"><pre>
-(cffi:defcfun ("_wrap_Test_x_set" Test_x_set) :void
-  (self :pointer)
-  (x :float))
-
-(cffi:defcfun ("_wrap_Test_x_get" Test_x_get) :float
-  (self :pointer))
-
-(cffi:defcfun ("_wrap_new_Test__SWIG_0" new_Test) :pointer)
-
-(cffi:defcfun ("_wrap_new_Test__SWIG_1" new_Test) :pointer
-  (X :float))
-
-(cffi:defcfun ("_wrap_Test___add__" Test___add__) :pointer
-  (self :pointer)
-  (v :pointer))
-
-(cffi:defcfun ("_wrap_Test_lengthSquared" Test_lengthSquared) :float
-  (self :pointer))
-
-(cffi:defcfun ("_wrap_Test_distance" Test_distance) :float
-  (a :pointer)
-  (b :pointer))
-
-(cffi:defcfun ("_wrap_Test_parallelComponent" Test_parallelComponent) :pointer
-  (self :pointer)
-  (unitBasis :pointer))
-
-(cffi:defcfun ("_wrap_Test_setYtoZero" Test_setYtoZero) :pointer
-  (self :pointer))
-
-(cffi:defcvar ("Test_zero" Test_zero)
- :pointer)
-
-(cffi:defcfun ("_wrap_delete_Test" delete_Test) :void
-  (self :pointer))
-
-(cffi:defcfun ("_wrap___mul__" __mul__) :pointer
-  (s :float)
-  (v :pointer))
-
-(cffi:defcfun ("_wrap___lshift__" __lshift__) :pointer
-  (o :pointer)
-  (v :pointer))
-
-(cffi:defcfun ("_wrap_RandomUnitVectorOnXZPlane" RandomUnitVectorOnXZPlane) :pointer)
-</pre></div>
-
-<p>
-The output is pretty good but it fails in disambiguating overloaded
-    functions such as the constructor, in this case. One way of
-    resolving this problem is to make the interface use the rename
-    directiv, but hopefully there are better solutions.
- In addition SWIG also generates, a CLOS file
-</p>
-
-
-<div class="targetlang"><pre>
-(clos:defclass test()
-  ((ff :reader ff-pointer)))
-
-(clos:defmethod (cl:setf x) (arg0 (obj test))
-  (Test_x_set (ff-pointer obj) arg0))
-
-(clos:defmethod x ((obj test))
-  (Test_x_get (ff-pointer obj)))
-
-(cl:shadow "+")
-(clos:defmethod + ((obj test) (self test) (v test))
-  (Test___add__ (ff-pointer obj) (ff-pointer self) (ff-pointer v)))
-
-(clos:defmethod length-squared ((obj test) (self test))
-  (Test_lengthSquared (ff-pointer obj) (ff-pointer self)))
-
-(clos:defmethod parallel-component ((obj test) (self test) (unitBasis test))
-  (Test_parallelComponent (ff-pointer obj) (ff-pointer self) (ff-pointer unitBasis)))
-
-(clos:defmethod set-yto-zero ((obj test) (self test))
-  (Test_setYtoZero (ff-pointer obj) (ff-pointer self)))
-</pre></div>
-
-<p>I agree that the CFFI C++ module needs lot more work. But I hope it
-    provides a starting point, on which you can base your work of
-    importing C++ libraries to Lisp. 
-</p>
-<p>
-If you have any questions, suggestions, patches, etc., related to CFFI
-      module feel free to contact us on the SWIG mailing list, and
-      also please add a "[CFFI]" tag in the subject line.
-
-<H3><a name="Lisp_nn7">29.2.4 Inserting user code into generated files</a></H3>
-
-
-<p>
-It is often necessary to <a href="SWIG.html#SWIG_nn40">include user-defined code</a> 
-into the automatically generated interface files. For example, when building
-a C++ interface, example_wrap.cxx will likely not compile unless
-you add a <tt>#include "header.h"</tt> directive. This can be done
-using the SWIG <tt>%insert(section) %{ ...code... %}</tt> directive:
-</p>
-
-<div class="code">
-<pre>
-%module example
-
-%{
-#include "header.h"
-%}
-
-%include "header.h"
-
-int fact(int n);
-</pre>
-</div>
-
-<p>
-Additional sections have been added for inserting into the
-generated lisp interface file:
-</p>
-<ul>
-  <li><tt>lisphead</tt> - inserts before type declarations</li>
-  <li><tt>swiglisp</tt> - inserts after type declarations according to
-    where it appears in the .i file</li>
-</ul>
-<p>
-Note that the block <tt>%{ ... %}</tt> is effectively a shortcut for
-<tt>%insert("header") %{ ... %}</tt>.
-</p>
-
-
-</body>
-</html>
diff --git a/Doc/Manual/Lua.html b/Doc/Manual/Lua.html
index 6633eaa..54b81cc 100644
--- a/Doc/Manual/Lua.html
+++ b/Doc/Manual/Lua.html
@@ -7,7 +7,7 @@
 </head>
 
 <body bgcolor="#ffffff">
-<H1><a name="Lua">28 SWIG and Lua</a></H1>
+<H1><a name="Lua">29 SWIG and Lua</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -77,20 +77,20 @@
 
 
 <p>
-Lua is an extension programming language designed to support general procedural programming with data description facilities. It also offers good support for object-oriented programming, functional programming, and data-driven programming. Lua is intended to be used as a powerful, light-weight configuration language for any program that needs one. Lua is implemented as a library, written in clean C (that is, in the common subset of ISO C and C++). It's also a <em>really</em> tiny language, less than 6000 lines of code, which compiles to &lt;100 kilobytes of binary code. It can be found at <a href="http://www.lua.org">http://www.lua.org</a>
+Lua is an extension programming language designed to support general procedural programming with data description facilities. It also offers good support for object-oriented programming, functional programming, and data-driven programming. Lua is intended to be used as a powerful, light-weight configuration language for any program that needs one. Lua is implemented as a library, written in clean C (that is, in the common subset of ISO C and C++). It's also a <em>really</em> tiny language, less than 6000 lines of code, which compiles to &lt;100 kilobytes of binary code. It can be found at <a href="https://www.lua.org">https://www.lua.org</a>
 </p>
 <p>
 eLua stands for Embedded Lua (can be thought of as a flavor of Lua) and offers the full implementation of the Lua programming language to the embedded world, extending it with specific features for efficient and portable software embedded development. eLua runs on smaller devices like microcontrollers and provides the full features of the regular Lua desktop version. More information on eLua can be found here: <a href="http://www.eluaproject.net">http://www.eluaproject.net</a>
 </p>
 
-<H2><a name="Lua_nn2">28.1 Preliminaries</a></H2>
+<H2><a name="Lua_nn2">29.1 Preliminaries</a></H2>
 
 
 <p>
 The current SWIG implementation is designed to work with Lua 5.0.x, 5.1.x and 5.2.x. It should work with later versions of Lua, but certainly not with Lua 4.0 due to substantial API changes. It is possible to either static link or dynamic link a Lua module into the interpreter (normally Lua static links its libraries, as dynamic linking is not available on all platforms). SWIG also has support for eLua starting from eLua 0.8. Due to substantial changes between SWIG 2.x and SWIG 3.0 and unavailability of testing platform, eLua status was downgraded to 'experimental'.
 </p>
 
-<H2><a name="Lua_nn3">28.2 Running SWIG</a></H2>
+<H2><a name="Lua_nn3">29.2 Running SWIG</a></H2>
 
 
 <p>
@@ -138,14 +138,14 @@
 The <tt>-elua</tt> option puts all the C function wrappers and variable get/set wrappers in rotables. It also generates a metatable which will control the access to these variables from eLua. It also offers a significant amount of module size compression. On the other hand, the <tt>-eluac</tt> option puts all the wrappers in a single rotable. With this option, no matter how huge the module, it will consume no additional microcontroller SRAM (crass compression). There is a catch though: Metatables are not generated with <tt>-eluac</tt>. To access any value from eLua, one must directly call the wrapper function associated with that value.
 </p>
 
-<H3><a name="Lua_commandline">28.2.1 Additional command line options</a></H3>
+<H3><a name="Lua_commandline">29.2.1 Additional command line options</a></H3>
 
 
 <p>
 The following table list the additional commandline options available for the Lua module. They can also be seen by using: 
 </p>
 
-<div class="code"><pre>
+<div class="shell"><pre>
 swig -lua -help 
 </pre></div>
 
@@ -171,7 +171,8 @@
 
 <tr>
   <td>-no-old-metatable-bindings</td>
-  <td>Disable backward compatibility: old-style binding names generations and a few other things. Explanations are included in appropriate later sections.</td>
+  <td>Disable backward compatibility: old-style binding names generations and a few other things. Explanations are included in appropriate later sections.
+      This option is considered deprecated and will be removed in the near future.</td>
 </tr>
 <tr>
   <td>-squash-bases</td>
@@ -179,7 +180,7 @@
 </tr>
 </table>
 
-<H3><a name="Lua_nn4">28.2.2 Compiling and Linking and Interpreter</a></H3>
+<H3><a name="Lua_nn4">29.2.2 Compiling and Linking and Interpreter</a></H3>
 
 
 <p>
@@ -250,7 +251,7 @@
 More information on building and configuring eLua can be found here: <a href="http://www.eluaproject.net/doc/v0.8/en_building.html">http://www.eluaproject.net/doc/v0.8/en_building.html</a>
 </p>
 
-<H3><a name="Lua_nn5">28.2.3 Compiling a dynamic module</a></H3>
+<H3><a name="Lua_nn5">29.2.3 Compiling a dynamic module</a></H3>
 
 
 <p>
@@ -318,7 +319,7 @@
 
 
 
-<H3><a name="Lua_nn6">28.2.4 Using your module</a></H3>
+<H3><a name="Lua_nn6">29.2.4 Using your module</a></H3>
 
 
 <p>
@@ -336,19 +337,19 @@
 &gt;
 </pre></div>
 
-<H2><a name="Lua_nn7">28.3 A tour of basic C/C++ wrapping</a></H2>
+<H2><a name="Lua_nn7">29.3 A tour of basic C/C++ wrapping</a></H2>
 
 
 <p>
 By default, SWIG tries to build a very natural Lua interface to your C/C++ code. This section briefly covers the essential aspects of this wrapping.
 </p>
-<H3><a name="Lua_nn8">28.3.1 Modules</a></H3>
+<H3><a name="Lua_nn8">29.3.1 Modules</a></H3>
 
 
 <p>
 The SWIG module directive specifies the name of the Lua module. If you specify `module example', then everything is wrapped into a Lua table 'example' containing all the functions and variables. When choosing a module name, make sure you don't use the same name as a built-in Lua command or standard module name.
 </p>
-<H3><a name="Lua_nn9">28.3.2 Functions</a></H3>
+<H3><a name="Lua_nn9">29.3.2 Functions</a></H3>
 
 
 <p>
@@ -370,7 +371,6 @@
 To avoid name collisions, SWIG create a Lua table which keeps all the functions, constants, classes and global variables in.
 It is possible to copy the functions, constants and classes (but not variables) out of this and into the global environment with the following code.
 This can easily overwrite existing functions, so this must be used with care.
-This option is considered deprecated and will be removed in the near future.
 </p>
 <div class="targetlang"><pre>
 &gt; for k, v in pairs(example) do _G[k]=v end
@@ -389,7 +389,7 @@
 24
 </pre></div>
 
-<H3><a name="Lua_nn10">28.3.3 Global variables</a></H3>
+<H3><a name="Lua_nn10">29.3.3 Global variables</a></H3>
 
 
 <p>
@@ -410,7 +410,7 @@
 &gt; example.Foo=4
 &gt; print(c)
 3
-&gt; c=5 -- this will not effect the original example.Foo
+&gt; c=5 -- this will not affect the original example.Foo
 &gt; print(example.Foo, c)
 4    5
 </pre></div>
@@ -477,7 +477,7 @@
 In general, functions of the form <tt>"variable_get()"</tt> and <tt>"variable_set()"</tt> are automatically generated by SWIG for use with <tt>-eluac</tt>.
 </p>
 
-<H3><a name="Lua_nn11">28.3.4 Constants and enums</a></H3>
+<H3><a name="Lua_nn11">29.3.4 Constants and enums</a></H3>
 
 
 <p>
@@ -512,7 +512,7 @@
 Hello World
 </pre></div>
 
-<H4><a name="Lua_nn13">28.3.4.1 Constants/enums and classes/structures</a></H4>
+<H4><a name="Lua_nn13">29.3.4.1 Constants/enums and classes/structures</a></H4>
 
 
 <p>
@@ -566,9 +566,9 @@
 </p>
 <p>
 It is worth mentioning, that <tt>example.Test.TEST1</tt> and <tt>example.Test_TEST1</tt> are different entities and changing one does not change the other. 
-Given the fact that these are constantes and they are not supposed to be changed, it is up to you to avoid such issues.
+Given the fact that these are constants and they are not supposed to be changed, it is up to you to avoid such issues.
 </p>
-<H3><a name="Lua_nn12">28.3.5 Pointers</a></H3>
+<H3><a name="Lua_nn12">29.3.5 Pointers</a></H3>
 
 
 <p>
@@ -606,7 +606,7 @@
 nil
 </pre></div>
 
-<H3><a name="Lua_structures">28.3.6 Structures</a></H3>
+<H3><a name="Lua_structures">29.3.6 Structures</a></H3>
 
 
 <p>
@@ -710,7 +710,7 @@
 In general, functions of the form <tt>"new_struct()"</tt>, <tt>"struct_member_get()"</tt>, <tt>"struct_member_set()"</tt> and <tt>"free_struct()"</tt> are automatically generated by SWIG for each structure defined in C. (Please note: This doesn't apply for modules generated with the <tt>-elua</tt> option)
 </p>
 
-<H3><a name="Lua_nn14">28.3.7 C++ classes</a></H3>
+<H3><a name="Lua_nn14">29.3.7 C++ classes</a></H3>
 
 
 <p>
@@ -747,7 +747,8 @@
 <p>
 Class data members are accessed in the same manner as C structures. Static class members present a special problem for Lua, as Lua doesn't have support for such features. Therefore, SWIG generates wrappers that try to work around some of these issues. To illustrate, suppose you have a class like this:
 </p>
-<div class="targetlang"><pre>class Spam {
+<div class="code"><pre>
+class Spam {
 public:
   static void foo();
   static int bar;
@@ -756,7 +757,7 @@
 <p>
 In Lua, C++ static members can be accessed as follows:
 </p>
-<div class="code"><pre>
+<div class="targetlang"><pre>
 &gt; example.Spam.foo()            -- calling Spam::foo()
 &gt; a=example.Spam.bar            -- reading Spam::bar 
 &gt; example.Spam.bar=b            -- writing to Spam::bar
@@ -774,7 +775,7 @@
 <b>Compatibility Note:</b> In versions prior to SWIG-3.0.0 only the following names would work:
 </p>
 
-<div class="code"><pre>
+<div class="targetlang"><pre>
 &gt; example.Spam_foo()            -- calling Spam::foo()
 &gt; a=example.Spam_bar            -- reading Spam::bar 
 &gt; example.Spam_bar=b            -- writing to Spam::bar
@@ -785,7 +786,7 @@
 However, if the <tt>-no-old-metatable-bindings</tt> option is used, then the backward compatible names are not generated in addition to ordinary ones.
 </p>
 
-<H3><a name="Lua_nn15">28.3.8 C++ inheritance</a></H3>
+<H3><a name="Lua_nn15">29.3.8 C++ inheritance</a></H3>
 
 
 <p>
@@ -810,7 +811,7 @@
 <p>
 It is safe to use multiple inheritance with SWIG.
 </p>
-<H3><a name="Lua_nn16">28.3.9 Pointers, references, values, and arrays</a></H3>
+<H3><a name="Lua_nn16">29.3.9 Pointers, references, values, and arrays</a></H3>
 
 
 <p>
@@ -841,7 +842,7 @@
 <p>
 then all three functions will return a pointer to some Foo object. Since the third function (spam7) returns a value, newly allocated memory is used to hold the result and a pointer is returned (Lua will release this memory when the return value is garbage collected). The other two are pointers which are assumed to be managed by the C code and so will not be garbage collected.
 </p>
-<H3><a name="Lua_nn17">28.3.10 C++ overloaded functions</a></H3>
+<H3><a name="Lua_nn17">29.3.10 C++ overloaded functions</a></H3>
 
 
 <p>
@@ -927,7 +928,7 @@
 <p>
 Dealing with the Lua coercion mechanism, the priority is roughly (integers, floats, strings, userdata). But it is better to rename the functions rather than rely upon the ordering.
 </p>
-<H3><a name="Lua_nn18">28.3.11 C++ operators</a></H3>
+<H3><a name="Lua_nn18">29.3.11 C++ operators</a></H3>
 
 
 <p>
@@ -964,7 +965,8 @@
 <p>
 One restriction with operator overloading support is that SWIG is not able to fully handle operators that aren't defined as part of the class. For example, if you had code like this
 </p>
-<div class="targetlang"><pre>class Complex {
+<div class="code"><pre>
+class Complex {
 ...
 friend Complex operator+(double, const Complex &amp;c);
 ...
@@ -973,7 +975,8 @@
 <p>
 then SWIG doesn't know what to do with the friend function--in fact, it simply ignores it and issues a warning. You can still wrap the operator, but you may have to encapsulate it in a special function. For example:
 </p>
-<div class="targetlang"><pre>%rename(Complex_add_dc) operator+(double, const Complex &amp;);
+<div class="code"><pre>
+%rename(Complex_add_dc) operator+(double, const Complex &amp;);
 ...
 Complex operator+(double, const Complex &amp;c);
 </pre></div>
@@ -1059,7 +1062,7 @@
 </ul>
 <p>No other lua metafunction is inherited. For example, __gc is not inherited and must be redefined in every class. <tt>__tostring</tt> is subject to a special handling. If absent in class and in class bases, a default one will be provided by SWIG.
 </p>
-<H3><a name="Lua_nn19">28.3.12 Class extension with %extend</a></H3>
+<H3><a name="Lua_nn19">29.3.12 Class extension with %extend</a></H3>
 
 
 <p>
@@ -1116,7 +1119,7 @@
 Extend works with both C and C++ code, on classes and structs. It does not modify the underlying object in any way---the extensions only show up in the Lua interface. The only item to take note of is the code has to use the '$self' instead of 'this', and that you cannot access protected/private members of the code (as you are not officially part of the class).
 </p>
 
-<H3><a name="Lua_nn20">28.3.13 Using %newobject to release memory</a></H3>
+<H3><a name="Lua_nn20">29.3.13 Using %newobject to release memory</a></H3>
 
 
 <p> If you have a function that allocates memory like this,</p>
@@ -1140,7 +1143,7 @@
 </div>
 <p> This will release the allocated memory.</p>
 
-<H3><a name="Lua_nn21">28.3.14 C++ templates</a></H3>
+<H3><a name="Lua_nn21">29.3.14 C++ templates</a></H3>
 
 
 <p>
@@ -1175,7 +1178,7 @@
 <p>
 Obviously, there is more to template wrapping than shown in this example. More details can be found in the SWIG and C++ chapter. Some more complicated examples will appear later.
 </p>
-<H3><a name="Lua_nn22">28.3.15 C++ Smart Pointers</a></H3>
+<H3><a name="Lua_nn22">29.3.15 C++ Smart Pointers</a></H3>
 
 
 <p>
@@ -1227,7 +1230,7 @@
 &gt; f = p:__deref__()     -- Returns underlying Foo *
 </pre></div>
 
-<H3><a name="Lua_nn23">28.3.16 C++ Exceptions</a></H3>
+<H3><a name="Lua_nn23">29.3.16 C++ Exceptions</a></H3>
 
 
 <p>
@@ -1370,7 +1373,7 @@
 add exception specification to functions or globally (respectively).
 </p>
 
-<H3><a name="Lua_namespaces">28.3.17 Namespaces </a></H3>
+<H3><a name="Lua_namespaces">29.3.17 Namespaces </a></H3>
 
 
 <p>
@@ -1421,7 +1424,7 @@
 19
 &gt;
 </pre></div>
-<H4><a name="Lua_nn27">28.3.17.1 Compatibility Note </a></H4>
+<H4><a name="Lua_nn27">29.3.17.1 Compatibility Note </a></H4>
 
 
 <p>
@@ -1437,7 +1440,7 @@
 </pre></div>
 
 
-<H4><a name="Lua_nn29">28.3.17.2 Names </a></H4>
+<H4><a name="Lua_nn29">29.3.17.2 Names </a></H4>
 
 
 <p> If SWIG is launched without <tt>-no-old-metatable-bindings</tt> option, then it enters backward-compatible mode. While in this mode, it tries
@@ -1446,6 +1449,7 @@
 If %nspace is enabled, then class namespace is taken as scope. If there is no namespace, or %nspace is disabled,
 then module is considered a class namespace.</p>
 <p> Consider the following C++ code </p>
+
 <div class="code"><pre>%module example
 %nspace MyWorld::Test;
 namespace MyWorld {
@@ -1481,11 +1485,12 @@
 &gt;
 </pre></div>
 
-<H4><a name="Lua_nn30">28.3.17.3 Inheritance </a></H4>
+<H4><a name="Lua_nn30">29.3.17.3 Inheritance </a></H4>
 
 
 <p> The internal organization of inheritance has changed. 
 Consider the following C++ code:</p>
+
 <div class="code"><pre>%module example
 class Base {
   public:
@@ -1502,6 +1507,7 @@
 was copied to <tt>.fn</tt> table of class Derived and so on. This was a recursive procedure, so in the end the whole
 inheritance tree of derived class was squashed into derived class. </p>
 <p> That means that any changes done to class Base after module initialization wouldn't affect class Derived:</p>
+
 <div class="targetlang"><pre>
 base = example.Base()
 der = example.Derived()
@@ -1514,20 +1520,22 @@
 nil
 &gt;
 </pre></div>
-<p> This behaviour was changed. Now unless -squash-bases option is provided, Derived store a list of it's bases and if some symbol is not found in it's own service tables
+<p> This behaviour was changed. Now unless -squash-bases option is provided, Derived stores a list of its bases and if some symbol is not found in its own service tables
 then its bases are searched for it. Option -squash-bases will effectively return old behaviour.
+</p>
+
 <div class="targetlang"><pre>
 &gt; print(der.new_func) -- Now it works
 function
 &gt;
 </pre></div>
 
-<H2><a name="Lua_nn24">28.4 Typemaps</a></H2>
+<H2><a name="Lua_nn24">29.4 Typemaps</a></H2>
 
 
 <p>This section explains what typemaps are and how to use them. The default wrapping behaviour of SWIG is enough in most cases. However sometimes SWIG may need a little additional assistance to know which typemap to apply to provide the best wrapping. This section will be explaining how to use typemaps to best effect</p>
 
-<H3><a name="Lua_nn25">28.4.1 What is a typemap?</a></H3>
+<H3><a name="Lua_nn25">29.4.1 What is a typemap?</a></H3>
 
 
 <p>A typemap is nothing more than a code generation rule that is attached to a specific C datatype. For example, to convert integers from Lua to C, you might define a typemap like this:</p>
@@ -1555,7 +1563,7 @@
 720
 </pre></div>
 
-<H3><a name="Lua_nn26">28.4.2 Using typemaps</a></H3>
+<H3><a name="Lua_nn26">29.4.2 Using typemaps</a></H3>
 
 
 <p>There are many ready written typemaps built into SWIG for all common types (int, float, short, long, char*, enum and more), which SWIG uses automatically, with no effort required on your part.</p>
@@ -1608,7 +1616,7 @@
 
 <p>Note: C++ references must be handled exactly the same way. However SWIG will automatically wrap a <tt>const int&amp;</tt>  as an input parameter (since that it obviously input).</p>
 
-<H3><a name="Lua_typemap_arrays">28.4.3 Typemaps and arrays</a></H3>
+<H3><a name="Lua_typemap_arrays">29.4.3 Typemaps and arrays</a></H3>
 
 
 <p>Arrays present a challenge for SWIG, because like pointers SWIG does not know whether these are input or output values, nor
@@ -1616,8 +1624,8 @@
 arrays for convenient usage.</p>
 
 <p>Given the functions:</p>
-<div class="code"><pre>extern void sort_int(int* arr, int len);
-extern void sort_double(double* arr, int len);
+<div class="code"><pre>extern void sort_int(int* arr, size_t len);
+extern void sort_double(double* arr, size_t len);
 </pre></div>
 
 <p>There are basically two ways that SWIG can deal with this. The first way, uses the <tt>&lt;carrays.i&gt;</tt> library
@@ -1630,16 +1638,16 @@
 
 <div class="code"><pre>// using the C-array
 %include &lt;carrays.i&gt;
-// this declares a batch of function for manipulating C integer arrays
+// this declares a batch of functions for manipulating C integer arrays
 %array_functions(int, int)
 
-extern void sort_int(int* arr, int len); // the function to wrap
+extern void sort_int(int* arr, size_t len); // the function to wrap
 
 // using typemaps
 %include &lt;typemaps.i&gt;
-%apply (double *INOUT, int) {(double* arr, int len)};
+%apply (double *INOUT, int) {(double* arr, size_t len)};
 
-extern void sort_double(double* arr, int len); // the function to wrap
+extern void sort_double(double* arr, size_t len); // the function to wrap
 </pre></div>
 
 <p>Once wrapped, the functions can both be called, though with different ease of use:</p>
@@ -1672,7 +1680,7 @@
 
 <p>Note: SWIG also can support arrays of pointers in a similar manner.</p>
 
-<H3><a name="Lua_typemaps_ptr_ptr_functions">28.4.4 Typemaps and pointer-pointer functions</a></H3>
+<H3><a name="Lua_typemaps_ptr_ptr_functions">29.4.4 Typemaps and pointer-pointer functions</a></H3>
 
 
 <p>Several C++ libraries use a pointer-pointer functions to create its objects. These functions require a pointer to a pointer which is then filled with the pointer to the new object. Microsoft's COM and DirectX as well as many other libraries have this kind of function. An example is given below:</p>
@@ -1706,7 +1714,7 @@
 ptr=nil -- the iMath* will be GC'ed as normal
 </pre></div>
 
-<H2><a name="Lua_writing_typemaps">28.5 Writing typemaps</a></H2>
+<H2><a name="Lua_writing_typemaps">29.5 Writing typemaps</a></H2>
 
 
 <p>This section describes how you can modify SWIG's default wrapping behavior for various C/C++ datatypes using the <tt>%typemap</tt> directive. This is an advanced topic that assumes familiarity with the Lua C API as well as the material in the "<a href="Typemaps.html#Typemaps">Typemaps</a>" chapter.</p>
@@ -1715,7 +1723,7 @@
 
 <p>Before proceeding, you should read the previous section on using typemaps, and look at the existing typemaps found in luatypemaps.swg and typemaps.i. These are both well documented and fairly easy to read. You should not attempt to write your own typemaps until you have read and can understand both of these files (they may well also give you an idea to base your work on).</p>
 
-<H3><a name="Lua_typemaps_write">28.5.1 Typemaps you can write</a></H3>
+<H3><a name="Lua_typemaps_write">29.5.1 Typemaps you can write</a></H3>
 
 
 <p>There are many different types of typemap that can be written, the full list can be found in the "<a href="Typemaps.html#Typemaps">Typemaps</a>" chapter. However the following are the most commonly used ones.</p>
@@ -1728,7 +1736,7 @@
 (the syntax for the typecheck is different from the typemap, see typemaps for details).</li>
 </ul>
 
-<H3><a name="Lua_nn31">28.5.2 SWIG's Lua-C API</a></H3>
+<H3><a name="Lua_nn31">29.5.2 SWIG's Lua-C API</a></H3>
 
 
 <p>This section explains the SWIG specific Lua-C API. It does not cover the main Lua-C api, as this is well documented and not worth covering.</p>
@@ -1777,7 +1785,7 @@
 <div class="indent">
 Similar to SWIG_fail_arg, except that it will display the swig_type_info information instead.</div>
 
-<H2><a name="Lua_nn32">28.6 Customization of your Bindings</a></H2>
+<H2><a name="Lua_nn32">29.6 Customization of your Bindings</a></H2>
 
 
 <p>
@@ -1786,7 +1794,7 @@
 
 
 
-<H3><a name="Lua_nn33">28.6.1 Writing your own custom wrappers</a></H3>
+<H3><a name="Lua_nn33">29.6.1 Writing your own custom wrappers</a></H3>
 
 
 <p>
@@ -1805,7 +1813,7 @@
 The <tt>%native</tt> directive in the above example, tells SWIG that there is a function <tt>int native_function(lua_State*L);</tt> which is to be added into the module under the name '<tt>my_func</tt>'. SWIG will not add any wrapper for this function, beyond adding it into the function table. How you write your code is entirely up to you.
 </p>
 
-<H3><a name="Lua_nn34">28.6.2 Adding additional Lua code</a></H3>
+<H3><a name="Lua_nn34">29.6.2 Adding additional Lua code</a></H3>
 
 
 <p>
@@ -1843,7 +1851,7 @@
 See Examples/lua/arrays for an example of this code.
 </p>
 
-<H2><a name="Lua_nn35">28.7 Details on the Lua binding</a></H2>
+<H2><a name="Lua_nn35">29.7 Details on the Lua binding</a></H2>
 
 
 <p>
@@ -1854,7 +1862,7 @@
  </i>
 </p>
 
-<H3><a name="Lua_nn36">28.7.1 Binding global data into the module.</a></H3>
+<H3><a name="Lua_nn36">29.7.1 Binding global data into the module.</a></H3>
 
 
 <p>
@@ -1914,7 +1922,7 @@
 <p>
 That way when you call '<tt>a=example.Foo</tt>', the interpreter looks at the table 'example' sees that there is no field 'Foo' and calls __index. This will in turn check in '.get' table and find the existence of 'Foo' and then return the value of the C function call 'Foo_get()'. Similarly for the code '<tt>example.Foo=10</tt>', the interpreter will check the table, then call the __newindex which will then check the '.set' table and call the C function 'Foo_set(10)'.
 </p>
-<H3><a name="Lua_nn37">28.7.2 Userdata and Metatables</a></H3>
+<H3><a name="Lua_nn37">29.7.2 Userdata and Metatables</a></H3>
 
 
 <p>
@@ -1989,12 +1997,12 @@
 In theory, you can play with this usertable &amp; add new features, but remember that it is a shared table between all instances of one class, and you could very easily corrupt the functions in all the instances.
 </p>
 <p>
-Note: Both the opaque structures (like the FILE*) and normal wrapped classes/structs use the same 'swig_lua_userdata' structure. Though the opaque structures has do not have a metatable attached, or any information on how to dispose of them when the interpreter has finished with them.
+Note: Both the opaque structures (like the FILE*) and normal wrapped classes/structs use the same 'swig_lua_userdata' structure. Though the opaque structures do not have a metatable attached, or any information on how to dispose of them when the interpreter has finished with them.
 </p>
 <p>
-Note: Operator overloads are basically done in the same way, by adding functions such as '__add' &amp; '__call' to the class' metatable. The current implementation is a bit rough as it will add any member function beginning with '__' into the metatable too, assuming its an operator overload.
+Note: Operator overloads are basically done in the same way, by adding functions such as '__add' &amp; '__call' to the class' metatable. The current implementation is a bit rough as it will add any member function beginning with '__' into the metatable too, assuming it's an operator overload.
 </p>
-<H3><a name="Lua_nn38">28.7.3 Memory management</a></H3>
+<H3><a name="Lua_nn38">29.7.3 Memory management</a></H3>
 
 
 <p>
diff --git a/Doc/Manual/Makefile b/Doc/Manual/Makefile
index 9505adb..0f9fe0e 100644
--- a/Doc/Manual/Makefile
+++ b/Doc/Manual/Makefile
@@ -1,7 +1,7 @@
 # Makefile for generating the SWIG documentation
 #
 # Note that the htmldoc package needs to be installed. wkhtmltopdf patched with qt is also required
-# and can be installed from http://wkhtmltopdf.org/downloads.html.
+# and the prebuilt binaries can be installed from https://wkhtmltopdf.org/downloads.html.
 #
 # The .html files are first processed and updated with chapter numbering and anchor names
 # are added to the HTML headings using the python scripts. The htmldoc program is then
@@ -43,8 +43,8 @@
 #  3) <pre> <tt> <code> elements do not always select a fixed-width font - try installing the
 #     Courier font to fix - these have been added to style.css.
 generate: SWIGDocumentation.html
-	wkhtmltopdf --version | grep "with patched qt" || (echo "wkhtmltopdf is not the patched qt version and so cannot be used - download it from http://wkhtmltopdf.org/downloads.html" && false)
-	wkhtmltopdf --margin-top 20mm --margin-bottom 20mm --margin-left 10mm --margin-right 10mm --header-font-size 6 --footer-font-size 6 --header-spacing 6 --footer-spacing 6 --header-center '[doctitle]' --footer-left '[subsection]' --footer-right '[page]' SWIGDocumentation.html SWIGDocumentation.pdf
+	wkhtmltopdf --version | grep "with patched qt" || (echo "wkhtmltopdf is not the patched qt version and so cannot be used - download it from https://wkhtmltopdf.org/downloads.html" && false)
+	wkhtmltopdf --margin-top 20mm --margin-bottom 20mm --margin-left 10mm --margin-right 10mm --header-font-size 6 --footer-font-size 6 --header-spacing 6 --footer-spacing 6 --header-center '[doctitle]' --footer-left '[subsection]' --footer-right '[page]' --allow . SWIGDocumentation.html SWIGDocumentation.pdf
 
 SWIGDocumentation.html: swightml.book
 	htmldoc --batch swightml.book || true
diff --git a/Doc/Manual/Modula3.html b/Doc/Manual/Modula3.html
deleted file mode 100644
index fc4ffa0..0000000
--- a/Doc/Manual/Modula3.html
+++ /dev/null
@@ -1,942 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-<title>SWIG and Modula-3</title>
-<link rel="stylesheet" type="text/css" href="style.css">
-<meta http-equiv="content-type" content="text/html; charset=UTF-8">
-</head>
-<body bgcolor="#FFFFFF">
-<H1><a name="Modula3">31 SWIG and Modula-3</a></H1>
-<!-- INDEX -->
-<div class="sectiontoc">
-<ul>
-<li><a href="#Modula3_modula3_overview">Overview</a>
-<ul>
-<li><a href="#Modula3_motivation">Motivation</a>
-</ul>
-<li><a href="#Modula3_conception">Conception</a>
-<ul>
-<li><a href="#Modula3_cinterface">Interfaces to C libraries</a>
-<li><a href="#Modula3_cppinterface">Interfaces to C++ libraries</a>
-</ul>
-<li><a href="#Modula3_preliminaries">Preliminaries</a>
-<ul>
-<li><a href="#Modula3_compilers">Compilers</a>
-<li><a href="#Modula3_commandline">Additional Commandline Options</a>
-</ul>
-<li><a href="#Modula3_typemaps">Modula-3 typemaps</a>
-<ul>
-<li><a href="#Modula3_inoutparam">Inputs and outputs</a>
-<li><a href="#Modula3_ordinals">Subranges, Enumerations, Sets</a>
-<li><a href="#Modula3_class">Objects</a>
-<li><a href="#Modula3_imports">Imports</a>
-<li><a href="#Modula3_exceptions">Exceptions</a>
-<li><a href="#Modula3_typemap_example">Example</a>
-</ul>
-<li><a href="#Modula3_hints">More hints to the generator</a>
-<ul>
-<li><a href="#Modula3_features">Features</a>
-<li><a href="#Modula3_pragmas">Pragmas</a>
-</ul>
-<li><a href="#Modula3_remarks">Remarks</a>
-</ul>
-</div>
-<!-- INDEX -->
-
-
-
-<p>
-This chapter describes SWIG's support for
-<a href="http://modula3.org/">Modula-3</a>.
-You should be familiar with the
-<a href="SWIG.html#SWIG">basics</a>
-of SWIG,
-especially
-<a href="Typemaps.html#Typemaps">typemaps</a>.
-</p>
-
-<H2><a name="Modula3_modula3_overview">31.1 Overview</a></H2>
-
-
-<p>
-Modula-3 is a compiled language in the tradition of Niklaus Wirth's Modula 2,
-which is in turn a successor to Pascal.
-</p>
-
-<p>
-SWIG's Modula-3 support is currently very basic and highly experimental!
-Many features are still not designed satisfyingly
-and I need more discussion about the odds and ends.
-Don't rely on any feature, incompatible changes are likely in the future!
-However, the Modula-3 generator was already useful for interfacing
-to the libraries:
-</p>
-
-<ol>
-<li>
-<a href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/plplot/">
-PLPlot
-</a>
-</li>
-<li>
-<a href="http://www.elegosoft.com/cgi-bin/cvsweb.cgi/cm3/m3-libs/fftw/">
-FFTW
-</a>
-</li>
-</ol>
-
-<H3><a name="Modula3_motivation">31.1.1 Motivation</a></H3>
-
-
-<p>
-Although it is possible to write Modula-3 code that performs as well as C/C++
-most existing libraries are not written in Modula-3 but in C or C++, and
-even libraries in other languages may provide C header files.
-</p>
-
-<p>
-Fortunately Modula-3 can call C functions, but you have to write Modula-3
-interfaces to them, and to make things comfortable you will also need
-wrappers that convert between high-level features of Modula-3 (garbage
-collecting, exceptions) and the explicit tracking of allocated memory and
-exception codes used by C APIs.
-</p>
-
-<p>
-SWIG converts C headers to Modula-3 interfaces for you, and using typemaps
-you can pass <tt>TEXT</tt>s or open arrays, and convert error return codes
-into exceptions.
-</p>
-
-<p>
-If the library API is ill designed
-writing appropriate typemaps can still be time-consuming.
-E.g. C programmers are very creative to work-around
-missing data types like (real) enumerations and sets.
-You should turn such work-arounds back to the Modula-3 way
-otherwise you lose static safety and consistency.
-</p>
-
-<p>
-Without SWIG you would probably never consider trying to call C++ libraries
-from Modula-3, but with SWIG this is becomes feasible.
-SWIG can generate C wrappers to C++ functions and object methods
-that may throw exceptions, and then wrap these C wrappers for Modula-3.
-To make it complete you can then hide the C interface with Modula-3 classes and
-exceptions.
-</p>
-
-<p>
-SWIG allows you to call C and C++ libraries from Modula-3 (even with call back
-functions), but it doesn't allow you to easily integrate a Modula-3 module into
-a C/C++ project.
-</p>
-
-<H2><a name="Modula3_conception">31.2 Conception</a></H2>
-
-
-<H3><a name="Modula3_cinterface">31.2.1 Interfaces to C libraries</a></H3>
-
-
-<p>
-Modula-3 has integrated support for calling C functions.
-This is also extensively used by the standard Modula-3 libraries
-to call OS functions.
-The Modula-3 part of SWIG and the corresponding SWIG library
-modula3.swg
-contain code that uses these features.
-Because of the built-in support there is no need
-for calling the SWIG kernel to generate wrappers written in C.
-All conversion and argument checking can be done in Modula-3
-and the interfacing is quite efficient.
-All you have to do is to write pieces of Modula-3 code
-that SWIG puts together.
-</p>
-
-<table border summary="Modula-3 C library support">
-<tr><th colspan=2>C library support integrated in Modula-3<th></tr>
-<tr>
-<td>Pragma <tt>&lt;* EXTERNAL *&gt;</tt></td>
-<td>Precedes a declaration of a PROCEDURE that is implemented
-in an external library instead of a Modula-3 module.</td>
-</tr>
-<tr>
-<td>Pragma <tt>&lt;* CALLBACK *&gt;</tt></td>
-<td>Precedes a declaration of a PROCEDURE that should be called
-by external library code.</td>
-</tr>
-<tr>
-<td>Module <tt>Ctypes</tt></td>
-<td>Contains Modula-3 types that match some basic C types.</td>
-</tr>
-<tr>
-<td>Module <tt>M3toC</tt></td>
-<td>Contains routines that convert between Modula-3's <tt>TEXT</tt> type
-and C's <tt>char *</tt> type.</td>
-</tr>
-</table>
-
-<p>
-In each run of SWIG the Modula-3 part
-generates several files:
-</p>
-<table border summary="Modula-3 generated files">
-<tr>
-  <th>Module name scheme</th>
-  <th>Identifier for <tt>%insert</tt></th>
-  <th>Description</th>
-</tr>
-<tr>
-  <td>Module<tt>Raw.i3</tt></td>
-  <td><tt>m3rawintf</tt></td>
-  <td>Declaration of types that are equivalent to those of the C library,
-      <tt>EXTERNAL</tt> procedures as interface to the C library functions</td>
-</tr>
-<tr>
-  <td>Module<tt>Raw.m3</tt></td>
-  <td><tt>m3rawimpl</tt></td>
-  <td>Almost empty.</td>
-</tr>
-<tr>
-  <td>Module<tt>.i3</tt></td>
-  <td><tt>m3wrapintf</tt></td>
-  <td>Declaration of comfortable wrappers to the C library functions.</td>
-</tr>
-<tr>
-  <td>Module<tt>.m3</tt></td>
-  <td><tt>m3wrapimpl</tt></td>
-  <td>Implementation of the wrappers that
-      convert between Modula-3 and C types,
-      check for validity of values,
-      hand-over resource management to the garbage collector using <tt>WeakRef</tt>s
-      and raises exceptions.</td>
-</tr>
-<tr>
-  <td><tt>m3makefile</tt></td>
-  <td><tt>m3makefile</tt></td>
-  <td>Add the modules above to the Modula-3 project and
-      specify the name of the Modula-3 wrapper library
-      to be generated.
-
-    Today I'm not sure if it is a good idea
-    to create a <tt>m3makefile</tt> in each run,
-    because SWIG must be started for each Modula-3 module it creates.
-    Thus the m3makefile is overwritten each time. :-(
-  </td>
-</tr>
-</table>
-
-<p>
-Here's a scheme of how the function calls to Modula-3 wrappers
-are redirected to C library functions:
-</p>
-
-<table summary="Modula-3 C library">
-<tr>
-  <td align=center>
-    Modula-3 wrapper<br>
-    Module<tt>.i3</tt><br>
-    generated by Modula-3 part of SWIG
-  </td>
-  <td></td>
-  <td align=center></td>
-</tr>
-<tr>
-  <td align=center>
-    <!-- pre tag overrides centering -->
-    |<br>
-    v
-  </td>
-  <td></td>
-  <td align=center></td>
-</tr>
-<tr>
-  <td align=center>
-    Modula-3 interface to C<br>
-    Module<tt>Raw.i3</tt><br>
-    generated by Modula-3 part of SWIG
-  </td>
-  <td>--&gt;</td>
-  <td align=center>
-    C library
-  </td>
-</tr>
-</table>
-
-
-<p>
-I have still no good conception how one can split C library interfaces
-into type oriented interfaces.
-A Module in Modula-3 represents an Abstract DataType
-(or call it a static classes, i.e. a class without virtual methods).
-E.g. if you have a principal type, say <tt>Database</tt>,
-it is good Modula-3 style to set up one Module with the name <tt>Database</tt>
-where the database type is declared with the name <tt>T</tt>
-and where all functions are declared that operates on it.
-</p>
-
-<p>
-The normal operation of SWIG is to generate a fixed set of files per call.
-To generate multiple modules one has to write one SWIG interface
-(different SWIG interfaces can share common data) per module.
-Identifiers belonging to a different module may ignored (<tt>%ignore</tt>)
-and the principal type must be renamed (<tt>%typemap</tt>).
-</p>
-
-
-<H3><a name="Modula3_cppinterface">31.2.2 Interfaces to C++ libraries</a></H3>
-
-
-<p>
-Interfaces to C++ files are much more complicated and
-there are some more design decisions that are not made, yet.
-Modula-3 has no support for C++ functions
-but C++ compilers should support generating C++ functions
-with a C interface.
-</p>
-
-<p>
-Here's a scheme of how the function calls to Modula-3 wrappers
-are redirected to C library functions:
-</p>
-
-<table summary="Modula-3 C++ library">
-<tr>
-  <td align=center>
-    Modula-3 wrapper<br>
-    Module<tt>.i3</tt><br>
-    generated by Modula-3 part of SWIG
-  </td>
-  <td></td>
-  <td align=center>C++ library</td>
-</tr>
-<tr>
-  <td align=center>
-    <!-- pre tag overrides centering -->
-    |<br>
-    v
-  </td>
-  <td></td>
-  <td align=center>
-    ^<br>
-    |
-  </td>
-</tr>
-<tr>
-  <td align=center>
-    Modula-3 interface to C<br>
-    Module<tt>Raw.i3</tt><br>
-    generated by Modula-3 part of SWIG
-  </td>
-  <td>--&gt;</td>
-  <td align=center>
-    C interface to C++<br>
-    module<tt>_wrap.cxx</tt><br>
-    generated by the SWIG core
-  </td>
-</tr>
-</table>
-
-<p>
-Wrapping C++ libraries arises additional problems:
-</p>
-<ul>
-<li>
-Is it sensible to wrap C++ classes with Modula-3 classes?
-</li>
-<li>
-How to find the wrapping Modula-3 class
-for a class pointer that is returned by a C++ routine?
-</li>
-<li>
-How to deal with multiple inheritance
-which was neglected for Modula-3 for good reasons?
-</li>
-<li>
-Is it possible to sub-class C++ classes with Modula-3 code?
-This issue is addressed by directors,
-a feature that was experimentally added to some Language modules
-like
-<a href="Java.html#Java_directors">Java</a> and
-<a href="Python.html#Python_directors">Python</a>.
-</li>
-<li>
-How to manage storage with the garbage collector of Modula-3?
-Support for
-<a href="Customization.html#Customization_ownership">
-<tt>%newobject</tt> and <tt>%typemap(newfree)</tt></a>
-isn't implemented, yet.
-What's about resources that are managed by the garbage collector
-but shall be passed back to the storage management of the C++ library?
-This is a general issue which is not solved in a satisfying fashion
-as far as I know.
-</li>
-<li>
-How to turn C++ exceptions into Modula-3 exceptions?
-There's also no support for
-<a href="Customization.html#Customization_exception">
-<tt>%exception</tt></a>, yet.
-</li>
-</ul>
-
-<p>
-Be warned:
-There is no C++ library I wrote a SWIG interface for,
-so I'm not sure if this is possible or sensible, yet.
-</p>
-
-<H2><a name="Modula3_preliminaries">31.3 Preliminaries</a></H2>
-
-
-<H3><a name="Modula3_compilers">31.3.1 Compilers</a></H3>
-
-
-<p>
-There are different Modula-3 compilers around:
-cm3, pm3, ezm3, Klagenfurth Modula-3, Cambridge Modula-3.
-SWIG itself does not contain compiler specific code
-but the modula3.swg library file
-may do so.
-For testing examples I use Critical Mass cm3.
-</p>
-
-
-<H3><a name="Modula3_commandline">31.3.2 Additional Commandline Options</a></H3>
-
-
-<p>
-There are some experimental command line options
-that prevent SWIG from generating interface files.
-Instead files are emitted that may assist you
-when writing SWIG interface files.
-</p>
-
-<table border summary="Modula-3 specific options">
-<tr>
-<th>Modula-3 specific options</th>
-<th>Description</th>
-</tr>
-
-<tr>
-<td valign=top>-generateconst &lt;file&gt;</td>
-<td>
-Disable generation of interfaces and wrappers.
-Instead write code for computing numeric values of constants
-to the specified file.
-<br>
-C code may contain several constant definitions
-written as preprocessor macros.
-Other language modules of SWIG use
-compute-once-use-readonly variables or
-functions to wrap such definitions.
-All of them can invoke C code dynamically
-for computing the macro values.
-But if one wants to turn them into Modula-3
-integer constants, enumerations or set types,
-the values of these expressions has to be known statically.
-Although definitions like <tt>(1 &lt;&lt; FLAG_MAXIMIZEWINDOW)</tt>
-must be considered as good C style
-they are hard to convert to Modula-3
-since the value computation can use every feature of C.
-<br>
-Thus I implemented these switch
-to extract all constant definitions
-and write a C program that output the values of them.
-It works for numeric constants only
-and treats all of them as <tt>double</tt>.
-Future versions may generate a C++ program
-that can detect the type of the macros
-by overloaded output functions.
-Then strings can also be processed.
-</td>
-</tr>
-
-<tr>
-<td valign=top>-generaterename &lt;file&gt;</td>
-<td>
-Disable generation of interfaces and wrappers.
-Instead generate suggestions for <tt>%rename</tt>.
-<br>
-C libraries use a naming style
-that is neither homogeneous nor similar to that of Modula-3.
-C function names often contain a prefix denoting the library
-and some name components separated by underscores
-or capitalization changes.
-To get library interfaces that are really Modula-3 like
-you should rename the function names with the <tt>%rename</tt> directive.
-This switch outputs a list of such directives
-with a name suggestion generated by a simple heuristic.
-</td>
-</tr>
-
-<tr>
-<td valign=top>-generatetypemap &lt;file&gt;</td>
-<td>
-Disable generation of interfaces and wrappers.
-Instead generate templates for some basic typemaps.
-</td>
-</tr>
-</table>
-
-<H2><a name="Modula3_typemaps">31.4 Modula-3 typemaps</a></H2>
-
-
-<H3><a name="Modula3_inoutparam">31.4.1 Inputs and outputs</a></H3>
-
-
-<p>
-Each C procedure has a bunch of inputs and outputs.
-Inputs are passed as function arguments,
-outputs are updated referential arguments and
-the function value.
-</p>
-
-<p>
-Each C type can have several typemaps
-that apply only in case if a type is used
-for an input argument, for an output argument,
-or for a return value.
-A further typemap may specify
-the direction that is used for certain parameters.
-I have chosen this separation
-in order to be able to write general typemaps for the modula3.swg typemap library.
-In the library code the final usage of the type is not known.
-Using separate typemaps for each possible use
-allows appropriate definitions for each case.
-If these pre-definitions are fine
-then the direction of the function parameter
-is the only hint the user must give.
-</p>
-
-<p>
-The typemaps specific to Modula-3 have a common name scheme:
-A typemap name starts with "m3",
-followed by "raw" or "wrap"
-depending on whether it controls the generation
-of the Module<tt>Raw.i3</tt> or the Module<tt>.i3</tt>, respectively.
-It follows an "in" for typemaps applied to input argument,
-"out" for output arguments, "arg" for all kind of arguments,
-"ret" for returned values.
-</p>
-
-<p>
-The main task of SWIG is to build wrapper function,
-i.e. functions that convert values between C and Modula-3
-and call the corresponding C function.
-Modula-3 wrapper functions generated by SWIG
-consist of the following parts:
-</p>
-<ul>
-<li>Generate <tt>PROCEDURE</tt> signature.</li>
-<li>Declare local variables.</li>
-<li>Convert input values from Modula-3 to C.</li>
-<li>Check for input value integrity.</li>
-<li>Call the C function.</li>
-<li>Check returned values, e.g. error codes.</li>
-<li>Convert and write back values into Modula-3 records.</li>
-<li>Free temporary storage.</li>
-<li>Return values.</li>
-</ul>
-
-<table border summary="Modula-3 typemaps">
-<tr>
-  <th>Typemap</th>
-  <th>Example</th>
-  <th>Description</th>
-</tr>
-<tr>
-  <td>m3wrapargvar</td>
-  <td><tt>$1: INTEGER := $1_name;</tt></td>
-  <td>
-    Declaration of some variables needed for temporary results.
-  </td>
-</tr>
-<tr>
-  <td>m3wrapargconst</td>
-  <td><tt>$1 = "$1_name";</tt></td>
-  <td>
-    Declaration of some constant, maybe for debug purposes.
-  </td>
-</tr>
-<tr>
-  <td>m3wrapargraw</td>
-  <td><tt>ORD($1_name)</tt></td>
-  <td>
-    The expression that should be passed as argument to the raw Modula-3 interface function.
-  </td>
-</tr>
-<tr>
-  <td>m3wrapargdir</td>
-  <td><tt>out</tt></td>
-  <td>
-    Referential arguments can be used for input, output, update.
-    ???
-  </td>
-</tr>
-<tr>
-  <td>m3wrapinmode</td>
-  <td><tt>READONLY</tt></td>
-  <td>
-    One of Modula-3 parameter modes
-    <tt>VALUE</tt> (or empty),
-    <tt>VAR</tt>,
-    <tt>READONLY</tt>
-  </td>
-</tr>
-<tr>
-  <td>m3wrapinname</td>
-  <td></td>
-  <td>
-    New name of the input argument.
-  </td>
-</tr>
-<tr>
-  <td>m3wrapintype</td>
-  <td></td>
-  <td>
-    Modula-3 type of the input argument.
-  </td>
-</tr>
-<tr>
-  <td>m3wrapindefault</td>
-  <td></td>
-  <td>
-    Default value of the input argument
-  </td>
-</tr>
-<tr>
-  <td>m3wrapinconv</td>
-  <td><tt>$1 := M3toC.SharedTtoS($1_name);</tt></td>
-  <td>
-    Statement for converting the Modula-3 input value to C compliant value.
-  </td>
-</tr>
-<tr>
-  <td>m3wrapincheck</td>
-  <td><tt>IF Text.Length($1_name) &gt; 10 THEN RAISE E("str too long"); END;</tt></td>
-  <td>
-    Check the integrity of the input value.
-  </td>
-</tr>
-<tr>
-  <td>m3wrapoutname</td>
-  <td></td>
-  <td>
-    Name of the <tt>RECORD</tt> field to be used for returning multiple values.
-    This applies to referential output arguments that shall be turned
-    into return values.
-  </td>
-</tr>
-<tr>
-  <td>m3wrapouttype</td>
-  <td></td>
-  <td>
-    Type of the value that is returned instead of a referential output argument.
-  </td>
-</tr>
-<tr>
-  <td>m3wrapoutconv</td>
-  <td></td>
-  <td>
-  </td>
-</tr>
-<tr>
-  <td>m3wrapoutcheck</td>
-  <td></td>
-  <td>
-  </td>
-</tr>
-<tr>
-  <td>m3wrapretraw</td>
-  <td></td>
-  <td>
-  </td>
-</tr>
-<tr>
-  <td>m3wrapretname</td>
-  <td></td>
-  <td>
-  </td>
-</tr>
-<tr>
-  <td>m3wraprettype</td>
-  <td></td>
-  <td>
-  </td>
-</tr>
-<tr>
-  <td>m3wrapretvar</td>
-  <td></td>
-  <td>
-  </td>
-</tr>
-<tr>
-  <td>m3wrapretconv</td>
-  <td></td>
-  <td>
-  </td>
-</tr>
-<tr>
-  <td>m3wrapretcheck</td>
-  <td></td>
-  <td>
-  </td>
-</tr>
-<tr>
-  <td>m3wrapfreearg</td>
-  <td><tt>M3toC.FreeSharedS(str, arg1);</tt></td>
-  <td>
-    Free resources that were temporarily used in the wrapper.
-    Since this step should never be skipped,
-    SWIG will put it in the <tt>FINALLY</tt> branch
-    of a <tt>TRY .. FINALLY</tt> structure.
-  </td>
-</tr>
-</table>
-
-
-<H3><a name="Modula3_ordinals">31.4.2 Subranges, Enumerations, Sets</a></H3>
-
-
-<p>
-Subranges, enumerations, and sets are machine oriented types
-that make Modula very strong and expressive compared
-with the type systems of many other languages.
-</p>
-
-<ul>
-<li>
-Subranges are used for statically restricted choices of integers.
-</li>
-<li>
-Enumerations are used for named choices.
-</li>
-<li>
-Sets are commonly used for flag (option) sets.
-</li>
-</ul>
-
-<p>
-Using them extensively makes Modula code very safe and readable.
-</p>
-
-<p>
-C supports enumerations, too, but they are not as safe as the ones of Modula.
-Thus they are abused for many things:
-For named choices, for integer constant definitions, for sets.
-To make it complete every way of defining a value in C
-(<tt>#define</tt>, <tt>const int</tt>, <tt>enum</tt>)
-is somewhere used for defining something
-that must be handled completely different in Modula-3
-(<tt>INTEGER</tt>, enumeration, <tt>SET</tt>).
-</p>
-
-<p>
-I played around with several <tt>%feature</tt>s and <tt>%pragma</tt>s
-that split the task up into converting
-the C bit patterns (integer or bit set)
-into Modula-3 bit patterns (integer or bit set)
-and change the type as requested.
-See the corresponding example in the 
-Examples/modula3/enum/example.i file.
-This is quite messy and not satisfying.
-So the best what you can currently do is
-to rewrite constant definitions manually.
-Though this is a tedious work
-that I'd like to automate.
-</p>
-
-
-<H3><a name="Modula3_class">31.4.3 Objects</a></H3>
-
-
-<p>
-Declarations of C++ classes are mapped to <tt>OBJECT</tt> types
-while it is tried to retain the access hierarchy
-"public - protected - private" using partial revelation.
-Though the example in 
-Examples/modula3/class/example.i
-is not really useful, yet.
-</p>
-
-
-<H3><a name="Modula3_imports">31.4.4 Imports</a></H3>
-
-
-<p>
-Pieces of Modula-3 code provided by typemaps
-may contain identifiers from foreign modules.
-If the typemap <tt>m3wrapinconv</tt> for <tt>blah *</tt>
-contains code using the function <tt>M3toC.SharedTtoS</tt>
-you may declare <tt>%typemap("m3wrapinconv:import") blah * %{M3toC%}</tt>.
-Then the module <tt>M3toC</tt> is imported
-if the <tt>m3wrapinconv</tt> typemap for <tt>blah *</tt>
-is used at least once.
-Use <tt>%typemap("m3wrapinconv:import") blah * %{MyConversions AS M3toC%}</tt>
-if you need module renaming.
-Unqualified import is not supported.
-</p>
-
-<p>
-It is cumbersome to add this typemap to each piece of Modula-3 code.
-It is especially useful when writing general typemaps
-for the modula3.swg typemap library.
-For a monolithic module you might be better off
-if you add the imports directly:
-</p>
-
-<div class="code">
-<pre>
-%insert(m3rawintf) %{
-IMPORT M3toC;
-%}
-</pre></div>
-
-
-<H3><a name="Modula3_exceptions">31.4.5 Exceptions</a></H3>
-
-
-<p>
-Modula-3 provides another possibility
-of an output of a function: exceptions.
-</p>
-
-<p>
-Any piece of Modula-3 code that SWIG inserts
-due to a typemap can raise an exception.
-This way you can also convert an error code
-from a C function into a Modula-3 exception.
-</p>
-
-<p>
-The <tt>RAISES</tt> clause is controlled
-by typemaps with the <tt>throws</tt> extension.
-If the typemap <tt>m3wrapinconv</tt> for <tt>blah *</tt>
-contains code that may raise the exceptions <tt>OSError.E</tt>
-you should declare
-<tt>%typemap("m3wrapinconv:throws") blah * %{OSError.E%}</tt>.
-</p>
-
-<H3><a name="Modula3_typemap_example">31.4.6 Example</a></H3>
-
-
-<p>
-The generation of wrappers in Modula-3 needs very fine control
-to take advantage of the language features.
-Here is an example of a generated wrapper
-where almost everything is generated by a typemap:
-</p>
-
-<div class="code"><pre>
-<I>         (* %relabel  m3wrapinmode m3wrapinname m3wrapintype  m3wrapindefault *)</I>
-  PROCEDURE Name     (READONLY       str       :    TEXT    :=      ""       )
-<I>              (* m3wrapoutcheck:throws *)</I>
-     : NameResult RAISES {E} =
-    CONST
-      arg1name = "str";                  <I>(* m3wrapargconst *)</I>
-    VAR
-      arg0   : C.char_star;              <I>(* m3wrapretvar *)</I>
-      arg1   : C.char_star;              <I>(* m3wrapargvar *)</I>
-      arg2   : C.int;
-      result : RECORD
-<I>           (*m3wrapretname  m3wraprettype*)</I>
-                 unixPath : TEXT;
-<I>           (*m3wrapoutname  m3wrapouttype*)</I>
-                 checksum : CARDINAL;
-               END;
-    BEGIN
-      TRY
-        arg1 := M3toC.SharedTtoS(str);   <I>(* m3wrapinconv *)</I>
-        IF Text.Length(arg1) &gt; 10 THEN   <I>(* m3wrapincheck *)</I>
-          RAISE E("str too long");
-        END;
-<I> (* m3wrapretraw           m3wrapargraw *)</I>
-        arg0 := MessyToUnix  (arg1,   arg2);
-        result.unixPath := M3toC.CopyStoT(arg0);  <I>(* m3wrapretconv *)</I>
-        result.checksum := arg2;         <I>(* m3wrapoutconv *)</I>
-        IF result.checksum = 0 THEN      <I>(* m3wrapoutcheck *)</I>
-          RAISE E("invalid checksum");
-        END;
-      FINALLY
-        M3toC.FreeSharedS(str, arg1);     <I>(* m3wrapfreearg *)</I>
-      END;
-    END Name;
-</pre></div>
-
-
-<H2><a name="Modula3_hints">31.5 More hints to the generator</a></H2>
-
-
-<H3><a name="Modula3_features">31.5.1 Features</a></H3>
-
-
-<table border summary="Modula-3 features">
-<tr>
-  <th>Feature</th>
-  <th>Example</th>
-  <th>Description</th>
-</tr>
-<tr>
-  <td>multiretval</td>
-  <td><tt>%m3multiretval get_box;</tt> or
-      <tt>%feature("modula3:multiretval") get_box;</tt></td>
-  <td>Let the denoted function return a <tt>RECORD</tt>
-      rather than a plain value.
-      This <tt>RECORD</tt> contains all arguments with "out" direction
-      including the return value of the C function (if there is one).
-      If more than one argument is "out"
-      then the function <b>must</b> have the <tt>multiretval</tt> feature activated,
-      but it is explicitly requested from the user to prevent mistakes.</td>
-</tr>
-<tr>
-  <td>constnumeric</td>
-  <td><tt>%constnumeric(12) twelve;</tt> or
-      <tt>%feature("constnumeric", "12") twelve;</tt></td>
-  <td>This feature can be used to tell Modula-3's back-end of SWIG
-      the value of an identifier.
-      This is necessary in the cases
-      where it was defined by a non-trivial C expression.
-      This feature is used by the
-      <tt>-generateconst</tt> <a href="#Modula3_commandline">option</a>.
-      In future it may be generalized to other kind of values
-      such as strings.
-      </td>
-</tr>
-</table>
-
-<H3><a name="Modula3_pragmas">31.5.2 Pragmas</a></H3>
-
-
-<table border summary="Modula-3 pragmas">
-<tr>
-  <th>Pragma</th>
-  <th>Example</th>
-  <th>Description</th>
-</tr>
-<tr>
-  <td>unsafe</td>
-  <td><tt>%pragma(modula3) unsafe="true";</tt></td>
-  <td>Mark the raw interface modules as <tt>UNSAFE</tt>.
-      This will be necessary in many cases.</td>
-</tr>
-<tr>
-  <td>library</td>
-  <td><tt>%pragma(modula3) library="m3fftw";</tt></td>
-  <td>Specifies the library name for the wrapper library to be created.
-      It should be distinct from the name of the library to be wrapped.</td>
-</tr>
-</table>
-
-<H2><a name="Modula3_remarks">31.6 Remarks</a></H2>
-
-
-<ul>
-<li>
-The Modula-3 part of SWIG doesn't try to generate nicely formatted code.
-If you need to read the generated code, use <tt>m3pp</tt> to postprocess the
-Modula files.
-</li>
-</ul>
-
-</body>
-</html>
diff --git a/Doc/Manual/Modules.html b/Doc/Manual/Modules.html
index 7efd74e..1e3a8e7 100644
--- a/Doc/Manual/Modules.html
+++ b/Doc/Manual/Modules.html
@@ -7,7 +7,7 @@
 </head>
 
 <body bgcolor="#ffffff">
-<H1><a name="Modules">19 Working with Modules</a></H1>
+<H1><a name="Modules">20 Working with Modules</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -24,7 +24,7 @@
 
 
 
-<H2><a name="Modules_introduction">19.1 Modules Introduction</a></H2>
+<H2><a name="Modules_introduction">20.1 Modules Introduction</a></H2>
 
 
 <p>
@@ -78,7 +78,7 @@
 Each module in the collection is created via separate invocations of SWIG.
 </p>
 
-<H2><a name="Modules_nn1">19.2 Basics</a></H2>
+<H2><a name="Modules_nn1">20.2 Basics</a></H2>
 
 
 <p>
@@ -119,6 +119,10 @@
 // File: derived_module.i
 %module derived_module
 
+%{
+#include "base.h"
+%}
+
 %import "base_module.i"
 
 %inline %{
@@ -156,6 +160,10 @@
 // File: derived_module.i
 %module derived_module
 
+%{
+#include "base.h"
+%}
+
 %import(module="base_module") "base.h"
 
 %inline %{
@@ -177,7 +185,7 @@
 issue, read on.
 </p>
 
-<H2><a name="Modules_nn2">19.3 The SWIG runtime code</a></H2>
+<H2><a name="Modules_nn2">20.3 The SWIG runtime code</a></H2>
 
 
 <p>
@@ -243,7 +251,7 @@
 is empty. Only modules compiled with the same pair will share type information.
 </p>
 
-<H2><a name="Modules_external_run_time">19.4 External access to the runtime</a></H2>
+<H2><a name="Modules_external_run_time">20.4 External access to the runtime</a></H2>
 
 
 <p>As described in <a href="Typemaps.html#Typemaps_runtime_type_checker">The run-time type checker</a>,
@@ -282,7 +290,7 @@
 access.
 </p>
 
-<H2><a name="Modules_nn4">19.5 A word of caution about static libraries</a></H2>
+<H2><a name="Modules_nn4">20.5 A word of caution about static libraries</a></H2>
 
 
 <p>
@@ -293,7 +301,7 @@
 behavior. When working with dynamically loadable modules, you should try to work exclusively with shared libraries.
 </p>
 
-<H2><a name="Modules_nn5">19.6 References</a></H2>
+<H2><a name="Modules_nn5">20.6 References</a></H2>
 
 
 <p>
@@ -301,7 +309,7 @@
 an outside reference.  John Levine's "Linkers and Loaders" is highly recommended.
 </p>
 
-<H2><a name="Modules_nn6">19.7 Reducing the wrapper file size</a></H2>
+<H2><a name="Modules_nn6">20.7 Reducing the wrapper file size</a></H2>
 
 
 <p>
diff --git a/Doc/Manual/Mzscheme.html b/Doc/Manual/Mzscheme.html
index aae181e..070f914 100644
--- a/Doc/Manual/Mzscheme.html
+++ b/Doc/Manual/Mzscheme.html
@@ -8,7 +8,7 @@
 
 <body bgcolor="#ffffff">
 
-<H1><a name="Mzscheme">37 SWIG and MzScheme/Racket</a></H1>
+<H1><a name="Mzscheme">38 SWIG and MzScheme/Racket</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -22,9 +22,10 @@
 
 
 <p>
-This section contains information on SWIG's support of Racket, formally known as MzScheme.
+This section contains information on SWIG's support of Racket, formally known as MzScheme.  SWIG works with Racket versions &lt; 8 (Racket 8 switched to be based on a different scheme interpreter and SWIG hasn't been updated for this change).
+</p>
 
-<H2><a name="MzScheme_nn2">37.1 Creating native structures</a></H2>
+<H2><a name="MzScheme_nn2">38.1 Creating native structures</a></H2>
 
 
 <p>
@@ -65,7 +66,7 @@
 </pre>
 </div>
 
-<H2><a name="MzScheme_simple">37.2 Simple example</a></H2>
+<H2><a name="MzScheme_simple">38.2 Simple example</a></H2>
 
 
 <p>
@@ -166,7 +167,7 @@
   <li> The above requests mzc to create an extension using the CGC garbage-collector. The alternative -- the 3m collector -- has generally better performance, but work is still required for SWIG to emit code which is compatible with it.
 </ul>
 
-<H2><a name="MzScheme_external_docs">37.3 External documentation</a></H2>
+<H2><a name="MzScheme_external_docs">38.3 External documentation</a></H2>
 
 
 <p>
diff --git a/Doc/Manual/Ocaml.html b/Doc/Manual/Ocaml.html
index 92b5260..ba18a7b 100644
--- a/Doc/Manual/Ocaml.html
+++ b/Doc/Manual/Ocaml.html
@@ -7,7 +7,7 @@
 </head>
 
 <body bgcolor="#ffffff">
-<H1><a name="Ocaml">38 SWIG and OCaml</a></H1>
+<H1><a name="Ocaml">39 SWIG and OCaml</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -85,14 +85,15 @@
 
 <p>
 If you're not familiar with the Objective Caml language, you can visit
-<a href="http://ocaml.org/">The Ocaml Website</a>.
+<a href="https://ocaml.org/">The Ocaml Website</a>.
 </p>
 
-<H2><a name="Ocaml_nn2">38.1 Preliminaries</a></H2>
+<H2><a name="Ocaml_nn2">39.1 Preliminaries</a></H2>
 
 
 <p>
-SWIG is compatible with OCaml 3.12.0 and above.  Given the choice,
+SWIG is known to be compatible with OCaml 4.13.1 and above - older versions
+are not regularly tested.  Given the choice,
 you should use the latest stable release.  The SWIG Ocaml module has
 been tested on Linux (x86, PPC, Sparc) and Cygwin on Windows.  The
 best way to determine whether your system will work is to compile the
@@ -106,7 +107,7 @@
 will be loaded dynamically.  This has only been tested on Linux so far.
 </p>
 
-<H3><a name="Ocaml_nn3">38.1.1 Running SWIG</a></H3>
+<H3><a name="Ocaml_nn3">39.1.1 Running SWIG</a></H3>
 
 
 <p>
@@ -129,7 +130,7 @@
 the resulting .ml and .mli files as well, and do the final link with -custom
 (not needed for native link).</p>
 
-<H3><a name="Ocaml_nn4">38.1.2 Compiling the code</a></H3>
+<H3><a name="Ocaml_nn4">39.1.2 Compiling the code</a></H3>
 
 
 <p>
@@ -166,7 +167,7 @@
 </pre>
 </div>
 
-<H3><a name="Ocaml_nn5">38.1.3 The camlp4 module</a></H3>
+<H3><a name="Ocaml_nn5">39.1.3 The camlp4 module</a></H3>
 
 
 <p>
@@ -242,7 +243,7 @@
 </td></tr>
 </table>
 
-<H3><a name="Ocaml_nn6">38.1.4 Using your module</a></H3>
+<H3><a name="Ocaml_nn6">39.1.4 Using your module</a></H3>
 
 
 <p>
@@ -256,7 +257,7 @@
 option is not needed when you build native code.
 </p>
 
-<H3><a name="Ocaml_nn7">38.1.5 Compilation problems and compiling with C++</a></H3>
+<H3><a name="Ocaml_nn7">39.1.5 Compilation problems and compiling with C++</a></H3>
 
 
 <p>
@@ -267,7 +268,7 @@
 Most code meant to be compiled as C++ will not have problems.
 </p>
 
-<H2><a name="Ocaml_nn8">38.2 The low-level Ocaml/C interface</a></H2>
+<H2><a name="Ocaml_nn8">39.2 The low-level Ocaml/C interface</a></H2>
 
 
 <p>
@@ -367,7 +368,7 @@
 signature for a function that uses value in this way.
 </p>
 
-<H3><a name="Ocaml_nn9">38.2.1 The generated module</a></H3>
+<H3><a name="Ocaml_nn9">39.2.1 The generated module</a></H3>
 
 
 <p>
@@ -401,7 +402,7 @@
 </td></tr>
 </table>
 
-<H3><a name="Ocaml_nn10">38.2.2 Enums</a></H3>
+<H3><a name="Ocaml_nn10">39.2.2 Enums</a></H3>
 
 
 <p>
@@ -464,7 +465,7 @@
 </pre>
 </div>
 
-<H4><a name="Ocaml_nn11">38.2.2.1 Enum typing in Ocaml</a></H4>
+<H4><a name="Ocaml_nn11">39.2.2.1 Enum typing in Ocaml</a></H4>
 
 
 <p>
@@ -477,10 +478,10 @@
 values using the swig_val function before sharing them with another module.
 </p>
 
-<H3><a name="Ocaml_nn12">38.2.3 Arrays</a></H3>
+<H3><a name="Ocaml_nn12">39.2.3 Arrays</a></H3>
 
 
-<H4><a name="Ocaml_nn13">38.2.3.1 Simple types of bounded arrays</a></H4>
+<H4><a name="Ocaml_nn13">39.2.3.1 Simple types of bounded arrays</a></H4>
 
 
 <p>
@@ -501,7 +502,7 @@
 for arrays whose bounds are completely specified.
 </p>
 
-<H4><a name="Ocaml_nn14">38.2.3.2 Complex and unbounded arrays</a></H4>
+<H4><a name="Ocaml_nn14">39.2.3.2 Complex and unbounded arrays</a></H4>
 
 
 <p>
@@ -514,7 +515,7 @@
 so you have to specify it for yourself in the form of a typemap.
 </p>
 
-<H4><a name="Ocaml_nn15">38.2.3.3 Using an object</a></H4>
+<H4><a name="Ocaml_nn15">39.2.3.3 Using an object</a></H4>
 
 
 <p>
@@ -528,7 +529,7 @@
 such as using a required sentinel, etc.
 </p>
 
-<H4><a name="Ocaml_nn16">38.2.3.4 Example typemap for a function taking float * and int</a></H4>
+<H4><a name="Ocaml_nn16">39.2.3.4 Example typemap for a function taking float * and int</a></H4>
 
 
 <p>
@@ -579,7 +580,7 @@
 </pre></td></tr></table>
 
 
-<H3><a name="Ocaml_nn17">38.2.4 C++ Classes</a></H3>
+<H3><a name="Ocaml_nn17">39.2.4 C++ Classes</a></H3>
 
 
 <p>
@@ -622,7 +623,7 @@
 returned value for the same object.
 </p>
 
-<H4><a name="Ocaml_nn18">38.2.4.1 STL vector and string Example</a></H4>
+<H4><a name="Ocaml_nn18">39.2.4.1 STL vector and string Example</a></H4>
 
 
 <p>
@@ -702,7 +703,7 @@
 #
 </pre></div>
 
-<H4><a name="Ocaml_nn19">38.2.4.2 C++ Class Example</a></H4>
+<H4><a name="Ocaml_nn19">39.2.4.2 C++ Class Example</a></H4>
 
 
 <p>
@@ -720,7 +721,6 @@
 class QApplication {
 public:
   QApplication( int argc, char **argv );
-  void setMainWidget( QWidget *widget );
   void exec();
 };
 
@@ -732,25 +732,24 @@
 };
 </pre></td></tr></table>
 
-<H4><a name="Ocaml_nn20">38.2.4.3 Compiling the example</a></H4>
+<H4><a name="Ocaml_nn20">39.2.4.3 Compiling the example</a></H4>
 
 
 <div class="code"><pre>
-bash-2.05a$ QTPATH=/your/qt/path
-bash-2.05a$ for file in swig.mli swig.ml swigp4.ml ; do swig -ocaml -co $file ; done
-bash-2.05a$ ocamlc -c swig.mli ; ocamlc -c swig.ml
-bash-2.05a$ ocamlc -I `camlp4 -where` -pp "camlp4o pa_extend.cmo q_MLast.cmo" -c swigp4.ml
-bash-2.05a$ swig -ocaml -c++ -I$QTPATH/include qt.i
-bash-2.05a$ mv qt_wrap.cxx qt_wrap.c
-bash-2.05a$ ocamlc -c -ccopt -xc++ -ccopt -g -g -ccopt -I$QTPATH/include qt_wrap.c
-bash-2.05a$ ocamlc -c qt.mli
-bash-2.05a$ ocamlc -c qt.ml
-bash-2.05a$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
+$ QTPATH=/your/qt/path
+$ for file in swig.mli swig.ml swigp4.ml ; do swig -ocaml -co $file ; done
+$ ocamlc -c swig.mli ; ocamlc -c swig.ml
+$ ocamlc -I `camlp4 -where` -pp "camlp4o pa_extend.cmo q_MLast.cmo" -c swigp4.ml
+$ swig -ocaml -c++ -o qt_wrap.c qt.i
+$ ocamlc -c -ccopt -xc++ -ccopt -g -g -ccopt -I$QTPATH/include qt_wrap.c
+$ ocamlc -c qt.mli
+$ ocamlc -c qt.ml
+$ ocamlmktop -custom swig.cmo -I `camlp4 -where` \
   camlp4o.cma swigp4.cmo qt_wrap.o qt.cmo -o qt_top -cclib \
   -L$QTPATH/lib -cclib -lqt
 </pre></div>
 
-<H4><a name="Ocaml_nn21">38.2.4.4 Sample Session</a></H4>
+<H4><a name="Ocaml_nn21">39.2.4.4 Sample Session</a></H4>
 
 
 <div class="code"><pre>
@@ -777,10 +776,10 @@
 containing the string "hi" in a button.
 </p>
 
-<H3><a name="Ocaml_nn22">38.2.5 Director Classes</a></H3>
+<H3><a name="Ocaml_nn22">39.2.5 Director Classes</a></H3>
 
 
-<H4><a name="Ocaml_nn23">38.2.5.1 Director Introduction</a></H4>
+<H4><a name="Ocaml_nn23">39.2.5.1 Director Introduction</a></H4>
 
 
 <p>
@@ -807,7 +806,7 @@
 };
 </pre></div>
 
-<H4><a name="Ocaml_nn24">38.2.5.2 Overriding Methods in Ocaml</a></H4>
+<H4><a name="Ocaml_nn24">39.2.5.2 Overriding Methods in Ocaml</a></H4>
 
 
 <p>
@@ -835,7 +834,7 @@
 an overloaded class.  This example is contained in Examples/ocaml/shapes.
 </p>
 
-<H4><a name="Ocaml_nn25">38.2.5.3 Director Usage Example</a></H4>
+<H4><a name="Ocaml_nn25">39.2.5.3 Director Usage Example</a></H4>
 
 
 <table border="1" bgcolor="#dddddd" summary="Director usage example">
@@ -896,7 +895,7 @@
 program in C++.
 </p>
 
-<H4><a name="Ocaml_nn26">38.2.5.4 Creating director objects</a></H4>
+<H4><a name="Ocaml_nn26">39.2.5.4 Creating director objects</a></H4>
 
 
 <p>
@@ -937,7 +936,7 @@
 properly.
 </p>
 
-<H4><a name="Ocaml_nn27">38.2.5.5 Typemaps for directors, directorin, directorout, directorargout</a></H4>
+<H4><a name="Ocaml_nn27">39.2.5.5 Typemaps for directors, directorin, directorout, directorargout</a></H4>
 
 
 <p>
@@ -948,7 +947,7 @@
 and to receive arguments the same way you normally receive function returns.
 </p>
 
-<H4><a name="Ocaml_nn28">38.2.5.6 directorin typemap</a></H4>
+<H4><a name="Ocaml_nn28">39.2.5.6 directorin typemap</a></H4>
 
 
 <p>
@@ -959,7 +958,7 @@
 can use the same body as a simple <tt>out</tt> typemap.
 </p>
 
-<H4><a name="Ocaml_nn29">38.2.5.7 directorout typemap</a></H4>
+<H4><a name="Ocaml_nn29">39.2.5.7 directorout typemap</a></H4>
 
 
 <p>
@@ -970,7 +969,7 @@
 ownership, etc.
 </p>
 
-<H4><a name="Ocaml_nn30">38.2.5.8 directorargout typemap</a></H4>
+<H4><a name="Ocaml_nn30">39.2.5.8 directorargout typemap</a></H4>
 
 
 <p>
@@ -987,7 +986,7 @@
 values will read zero, and struct or object returns have undefined results.
 </p>
 
-<H3><a name="Ocaml_nn31">38.2.6 Exceptions</a></H3>
+<H3><a name="Ocaml_nn31">39.2.6 Exceptions</a></H3>
 
 
 <p>
@@ -1075,7 +1074,7 @@
 to raise exceptions.  See the <a href="Library.html#Library">SWIG Library</a> chapter.
 </p>
 
-<H2><a name="Ocaml_nn32">38.3 Documentation Features</a></H2>
+<H2><a name="Ocaml_nn32">39.3 Documentation Features</a></H2>
 
 
 <p>
@@ -1084,7 +1083,7 @@
 <a href="https://caml.inria.fr/pub/docs/manual-ocaml/ocamldoc.html">OCamldoc</a>.
 </p>
 
-<H3><a name="Ocaml_nn33">38.3.1 Module docstring</a></H3>
+<H3><a name="Ocaml_nn33">39.3.1 Module docstring</a></H3>
 
 
 <p>
diff --git a/Doc/Manual/Octave.html b/Doc/Manual/Octave.html
index bd6b08f..724fc51 100644
--- a/Doc/Manual/Octave.html
+++ b/Doc/Manual/Octave.html
@@ -9,7 +9,7 @@
 
 <body bgcolor="#ffffff">
 
-<H1><a name="Octave">29 SWIG and Octave</a></H1>
+<H1><a name="Octave">30 SWIG and Octave</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -51,8 +51,8 @@
 
 
 <p>
-         Octave is a high-level language intended for numerical programming that is mostly compatible with MATLAB.
-More information can be found at <a href="http://www.gnu.org/software/octave/">Octave web site</a>. 
+Octave is a high-level language intended for numerical programming that is mostly compatible with MATLAB.
+More information can be found at <a href="https://octave.org/">Octave web site</a>.
 </p>
 
 <p>
@@ -60,11 +60,12 @@
 Also, there are a dozen or so examples in the Examples/octave directory, and hundreds in the test suite (Examples/test-suite and Examples/test-suite/octave).
 </p>
 
-<H2><a name="Octave_nn2">29.1 Preliminaries</a></H2>
+<H2><a name="Octave_nn2">30.1 Preliminaries</a></H2>
 
 
 <p>
-SWIG is regularly tested against the following versions of Octave: 3.8, 4.0, 4.2.
+SWIG is regularly tested against the following versions of Octave: 5.2, 6.4.
+SWIG 4.2.1 has also been manually tested with 7.3, 8.4 and 9.0.
 </p>
 
 <p>
@@ -76,7 +77,7 @@
 The SWIG runtime exports the function <tt>swig_octave_prereq()</tt> for checking the version of Octave.
 </p>
 
-<H2><a name="Octave_nn3">29.2 Running SWIG</a></H2>
+<H2><a name="Octave_nn3">30.2 Running SWIG</a></H2>
 
 
 <p>
@@ -104,11 +105,8 @@
 
 <div class="shell"><pre>$ swig -octave -c++ -o example_wrap.cpp example.i </pre></div>
 
-<p>
-This creates a C++ source file "example_wrap.cpp". A C++ file is generated even when wrapping C code as Octave is itself written in C++ and requires wrapper code to be in the same language. The generated C++ source file contains the low-level wrappers that need to be compiled and linked with the rest of your C/C++ application (in this case, the gcd implementation) to create an extension module.
-</p>
 
-<H3><a name="Octave_nn4">29.2.1 Command-line options</a></H3>
+<H3><a name="Octave_nn4">30.2.1 Command-line options</a></H3>
 
 
 <p>
@@ -131,7 +129,7 @@
 The <em>-opprefix</em> options sets the prefix of the names of global/friend <a href="#Octave_nn18">operator</a> functions.
 </p>
 
-<H3><a name="Octave_nn5">29.2.2 Compiling a dynamic module</a></H3>
+<H3><a name="Octave_nn5">30.2.2 Compiling a dynamic module</a></H3>
 
 
 <p>
@@ -158,7 +156,7 @@
 
           <div class="targetlang"><pre>octave:1&gt; swigexample</pre></div>
 
-<H3><a name="Octave_nn6">29.2.3 Using your module</a></H3>
+<H3><a name="Octave_nn6">30.2.3 Using your module</a></H3>
 
 
 <p>
@@ -176,10 +174,10 @@
 octave:5&gt; swigexample.cvar.Foo
 ans =  4 </pre></div>
 
-<H2><a name="Octave_nn7">29.3 A tour of basic C/C++ wrapping</a></H2>
+<H2><a name="Octave_nn7">30.3 A tour of basic C/C++ wrapping</a></H2>
 
 
-<H3><a name="Octave_nn8">29.3.1 Modules</a></H3>
+<H3><a name="Octave_nn8">30.3.1 Modules</a></H3>
 
 
 <p>
@@ -224,7 +222,7 @@
 ans =  2
 </pre></div>
 
-<H3><a name="Octave_nn9">29.3.2 Functions</a></H3>
+<H3><a name="Octave_nn9">30.3.2 Functions</a></H3>
 
 
 <p>
@@ -241,7 +239,7 @@
     <div class="targetlang"><pre>octave:1&gt; swigexample.fact(4)
 24 </pre></div>
 
-<H3><a name="Octave_nn10">29.3.3 Global variables</a></H3>
+<H3><a name="Octave_nn10">30.3.3 Global variables</a></H3>
 
 
 <p>
@@ -294,7 +292,7 @@
 octave:3&gt; swigexample.PI
 ans =  3.1420 </pre></div>
 
-<H3><a name="Octave_nn11">29.3.4 Constants and enums</a></H3>
+<H3><a name="Octave_nn11">30.3.4 Constants and enums</a></H3>
 
 
 <p>
@@ -316,7 +314,7 @@
 swigexample.SUNDAY=0
 .... </pre></div>
 
-<H3><a name="Octave_nn12">29.3.5 Pointers</a></H3>
+<H3><a name="Octave_nn12">30.3.5 Pointers</a></H3>
 
 
 <p>
@@ -363,7 +361,11 @@
 error: value on right hand side of assignment is undefined
 error: evaluating assignment expression near line 2, column 2 </pre></div>
 
-<H3><a name="Octave_nn13">29.3.6 Structures and C++ classes</a></H3>
+<p>
+NULL C/C++ pointers are represented by the Octave null matrix, <tt>[]</tt>.
+</p>
+
+<H3><a name="Octave_nn13">30.3.6 Structures and C++ classes</a></H3>
 
 
 <p>
@@ -498,7 +500,7 @@
 Depending on the ownership setting of a <tt>swig_ref</tt>, it may call C++ destructors when its reference count goes to zero. See the section on memory management below for details.
 </p>
 
-<H3><a name="Octave_nn15">29.3.7 C++ inheritance</a></H3>
+<H3><a name="Octave_nn15">30.3.7 C++ inheritance</a></H3>
 
 
 <p>
@@ -507,7 +509,7 @@
 the tree is walked to find a match in the current class as well as any of its bases. The lookup is then cached in the <tt>swig_ref</tt>.
 </p>
 
-<H3><a name="Octave_nn17">29.3.8 C++ overloaded functions</a></H3>
+<H3><a name="Octave_nn17">30.3.8 C++ overloaded functions</a></H3>
 
 
 <p>
@@ -517,7 +519,7 @@
 <tt>typecheck</tt> typemaps are used to analyze each argument, as well as assign precedence. See the chapter on typemaps for details.
 </p>
 
-<H3><a name="Octave_nn18">29.3.9 C++ operators</a></H3>
+<H3><a name="Octave_nn18">30.3.9 C++ operators</a></H3>
 
 
 <p>
@@ -570,13 +572,13 @@
 __div__        a / b
 __pow__        a ^ b
 __ldiv__       a \ b
-__lshift__     a << b
-__rshift__     a >> b
-__lt__         a < b
-__le__         a <= b
+__lshift__     a &lt;&lt; b
+__rshift__     a &gt;&gt; b
+__lt__         a &lt; b
+__le__         a &lt;= b
 __eq__         a == b
-__ge__         a >= b
-__gt__         a > b
+__ge__         a &gt;= b
+__gt__         a &gt; b
 __ne__         a != b
 __el_mul__     a .* b
 __el_div__     a ./ b
@@ -598,16 +600,16 @@
 %rename(__mul__)       *::operator*;
 %rename(__div__)       *::operator/;
 %rename(__mod__)       *::operator%;
-%rename(__lshift__)    *::operator<<;
-%rename(__rshift__)    *::operator>>;
+%rename(__lshift__)    *::operator&lt;&lt;;
+%rename(__rshift__)    *::operator&gt;&gt;;
 %rename(__el_and__)    *::operator&amp;&amp;;
 %rename(__el_or__)     *::operator||;
 %rename(__xor__)       *::operator^;
 %rename(__invert__)    *::operator~;
-%rename(__lt__)        *::operator<;
-%rename(__le__)        *::operator<=;
-%rename(__gt__)        *::operator>;
-%rename(__ge__)        *::operator>=;
+%rename(__lt__)        *::operator&lt;;
+%rename(__le__)        *::operator&lt;=;
+%rename(__gt__)        *::operator&gt;;
+%rename(__ge__)        *::operator&gt;=;
 %rename(__eq__)        *::operator==;
 %rename(__ne__)        *::operator!=;
 %rename(__not__)       *::operator!;
@@ -621,7 +623,17 @@
 Octave can also utilise friend (i.e. non-member) operators with a simple %rename: see the example in the Examples/octave/operator directory.
 </p>
 
-<H3><a name="Octave_nn19">29.3.10 Class extension with %extend</a></H3>
+<p>
+Octave has several operators for which no corresponding C++ operators exist. For example, the Octave code
+</p>
+<div class="targetlang"><pre>
+x=[a,b,c];
+</pre></div>
+<p>
+calls the Octave operator <tt>horzcat</tt> of the class of <tt>a</tt>. Hence, if <tt>a</tt> is of type <tt>swig_ref</tt> you can write an overload for this operator for your wrapped C++ class by placing a file <tt>@swig_ref/horzcat.m</tt> in the Octave load path (like for every Octave class, see <a href="https://docs.octave.org/latest/Creating-a-Class.html">Creating a Class</a>). This Octave function file is then called whenever the above Octave code is executed for a variable of type <tt>swig_ref</tt>.
+</p>
+
+<H3><a name="Octave_nn19">30.3.10 Class extension with %extend</a></H3>
 
 
 <p>
@@ -634,7 +646,7 @@
 %extend A {
 string __str__() {
   stringstream sout;
-  sout&lt;&lt;$self->value;
+  sout&lt;&lt;$self-&gt;value;
   return sout.str();
 }
 }
@@ -660,7 +672,7 @@
 Octave 3.8.0 and later versions will also map unary functions X() to the corresponding <tt>__X__</tt> method, where X includes: abs(), acos(), acosh(), angle(), arg(), asin(), asinh(), atan(), atanh(), cbrt(), ceil(), conj(), cos(), cosh(), dawson(), erf(), erfc(), erfcinv(), erfcx(), erfi(), erfinv(), exp(), expm1(), finite(), fix(), floor(), gamma(), imag(), isalnum(), isalpha(), isascii(), iscntrl(), isdigit(), isgraph(), isinf(), islower(), isna(), isnan(), isprint(), ispunct(), isspace(), isupper(), isxdigit(), lgamma(), log(), log10(), log1p(), log2(), real(), round(), roundb(), signbit(), signum(), sin(), sinh(), sqrt(), tan(), tanh(), toascii(), tolower(), toupper()
 </p>
 
-<H3><a name="Octave_nn20">29.3.11 C++ templates</a></H3>
+<H3><a name="Octave_nn20">30.3.11 C++ templates</a></H3>
 
 
 <p>
@@ -737,10 +749,10 @@
 </pre></div>
 
 
-<H3><a name="Octave_nn21">29.3.12 C++ Smart Pointers</a></H3>
+<H3><a name="Octave_nn21">30.3.12 C++ Smart Pointers</a></H3>
 
 
-<H4><a name="Octave_smart_pointers_shared_ptr">29.3.12.1 The shared_ptr Smart Pointer</a></H4>
+<H4><a name="Octave_smart_pointers_shared_ptr">30.3.12.1 The shared_ptr Smart Pointer</a></H4>
 
 
 <p>
@@ -751,14 +763,14 @@
 </p>
 
 
-<H4><a name="Octave_smart_pointers_generic">29.3.12.2 Generic Smart Pointers</a></H4>
+<H4><a name="Octave_smart_pointers_generic">30.3.12.2 Generic Smart Pointers</a></H4>
 
 
 <p>
 C++ smart pointers are fully supported as in other modules.
 </p>
 
-<H3><a name="Octave_nn22">29.3.13 Directors (calling Octave from C++ code)</a></H3>
+<H3><a name="Octave_nn22">30.3.13 Directors (calling Octave from C++ code)</a></H3>
 
 
 <p>
@@ -839,18 +851,19 @@
 octave-side routine called
 </pre></div>
 
-<H3><a name="Octave_nn23">29.3.14 Threads</a></H3>
+<H3><a name="Octave_nn23">30.3.14 Threads</a></H3>
 
 
 <p>
 The use of threads in wrapped Director code is not supported; i.e., an Octave-side implementation of a C++ class must be called from the Octave interpreter's thread. Anything fancier (apartment/queue model, whatever) is left to the user. Without anything fancier, this amounts to the limitation that Octave must drive the module... like, for example, an optimization package that calls Octave to evaluate an objective function.
 </p>
 
-<H3><a name="Octave_nn24">29.3.15 Memory management</a></H3>
+<H3><a name="Octave_nn24">30.3.15 Memory management</a></H3>
 
 
 <p>
 As noted above, <tt>swig_ref</tt> represents a reference counted pointer to a C/C++-side object. It also contains a flag indicating whether Octave or the C/C++ code owns the object. If Octave owns it, any destructors will be called when the reference count reaches zero. If the C/C++ side owns the object, then destructors will not be called when the reference count goes to zero.
+As noted above, <tt>swig_ref</tt> represents a reference counted pointer to a C/C++-side object. It also contains a flag indicating whether Octave or the C/C++ code owns the object. If Octave owns it, any destructors will be called when the reference count reaches zero. If the C/C++ side owns the object, then destructors will not be called when the reference count goes to zero.
 </p>
 <p>
 For example,
@@ -880,14 +893,14 @@
 In the case where one wishes for the C++ side to own an object that was created in Octave (especially a Director object), one can use the __disown() method to invert this logic. Then letting the Octave reference count go to zero will not destroy the object, but destroying the object will invalidate the Octave-side object if it still exists (and call destructors of other C++ bases in the case of multiple inheritance/<tt>subclass()</tt>'ing).
 </p>
 
-<H3><a name="Octave_nn25">29.3.16 STL support</a></H3>
+<H3><a name="Octave_nn25">30.3.16 STL support</a></H3>
 
 
 <p>
 Various STL library files are provided for wrapping STL containers.
 </p>
 
-<H3><a name="Octave_nn26">29.3.17 Matrix typemaps</a></H3>
+<H3><a name="Octave_nn26">30.3.17 Matrix typemaps</a></H3>
 
 
 <p>
diff --git a/Doc/Manual/Perl5.html b/Doc/Manual/Perl5.html
index 766ccae..b97614c 100644
--- a/Doc/Manual/Perl5.html
+++ b/Doc/Manual/Perl5.html
@@ -7,7 +7,7 @@
 </head>
 
 <body bgcolor="#ffffff">
-<H1><a name="Perl5">30 SWIG and Perl5</a></H1>
+<H1><a name="Perl5">31 SWIG and Perl5</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -91,13 +91,13 @@
 <p>
 This chapter describes SWIG's support of Perl5. Although the Perl5
 module is one of the earliest SWIG modules, it has continued to evolve
-and has been improved greatly with the help of SWIG users. For the
-best results, it is recommended that SWIG be used with Perl 5.8 or
-later. We're no longer testing regularly with older versions, but
-Perl 5.6 seems to mostly work, while older versions don't.
+and has been improved greatly with the help of SWIG users. As of SWIG
+4.1.0, the minimum version of Perl we aim to support is Perl 5.8.0.
+We can no longer easily test with older versions, and they no longer
+seem to be in active use.
 </p>
 
-<H2><a name="Perl5_nn2">30.1 Overview</a></H2>
+<H2><a name="Perl5_nn2">31.1 Overview</a></H2>
 
 
 <p>
@@ -118,7 +118,7 @@
 options are found near the end of the chapter.
 </p>
 
-<H2><a name="Perl5_nn3">30.2 Preliminaries</a></H2>
+<H2><a name="Perl5_nn3">31.2 Preliminaries</a></H2>
 
 
 <p>
@@ -143,7 +143,7 @@
 <tt>example_wrap.c</tt> and link it with the rest of your program.
 </p>
 
-<H3><a name="Perl5_nn4">30.2.1 Getting the right header files</a></H3>
+<H3><a name="Perl5_nn4">31.2.1 Getting the right header files</a></H3>
 
 
 <p>
@@ -175,7 +175,7 @@
 </pre>
 </div>
 
-<H3><a name="Perl5_nn5">30.2.2 Compiling a dynamic module</a></H3>
+<H3><a name="Perl5_nn5">31.2.2 Compiling a dynamic module</a></H3>
 
 
 <p>
@@ -208,7 +208,7 @@
 `<tt>example.sl</tt>', or the appropriate dynamic module name on your system.
 </p>
 
-<H3><a name="Perl5_nn6">30.2.3 Building a dynamic module with MakeMaker</a></H3>
+<H3><a name="Perl5_nn6">31.2.3 Building a dynamic module with MakeMaker</a></H3>
 
 
 <p>
@@ -242,7 +242,7 @@
 found in "Programming Perl, 2nd ed." by Larry Wall, Tom Christiansen,
 and Randal Schwartz.</p>
 
-<H3><a name="Perl5_nn7">30.2.4 Building a static version of Perl</a></H3>
+<H3><a name="Perl5_nn7">31.2.4 Building a static version of Perl</a></H3>
 
 
 <p>
@@ -311,7 +311,7 @@
 additional libraries such as <tt>-lsocket, -lnsl, -ldl</tt>, etc.
 </p>
 
-<H3><a name="Perl5_nn8">30.2.5 Using the module</a></H3>
+<H3><a name="Perl5_nn8">31.2.5 Using the module</a></H3>
 
 
 <p>
@@ -464,7 +464,7 @@
 read the man pages).
 </p>
 
-<H3><a name="Perl5_nn9">30.2.6 Compilation problems and compiling with C++</a></H3>
+<H3><a name="Perl5_nn9">31.2.6 Compilation problems and compiling with C++</a></H3>
 
 
 <p>
@@ -604,10 +604,10 @@
 other headers.  But if you get macro type conflicts from other macros not included
 in Lib/perl5/noembed.h while compiling the wrapper, you will
 have to find the macro that conflicts and add an #undef into the .i file.  Please report
-any conflicting macros you find to <a href="http://www.swig.org/mail.html">swig-user mailing list</a>.
+any conflicting macros you find to <a href="https://www.swig.org/mail.html">swig-user mailing list</a>.
 </p>
 
-<H3><a name="Perl5_nn10">30.2.7 Compiling for 64-bit platforms</a></H3>
+<H3><a name="Perl5_nn10">31.2.7 Compiling for 64-bit platforms</a></H3>
 
 
 <p>
@@ -634,7 +634,7 @@
 linking standard (e.g., -o32 and -n32 on Irix).
 </p>
 
-<H2><a name="Perl5_nn11">30.3 Building Perl Extensions under Windows</a></H2>
+<H2><a name="Perl5_nn11">31.3 Building Perl Extensions under Windows</a></H2>
 
 
 <p>
@@ -645,7 +645,7 @@
 although the procedure may be similar with other compilers.  
 </p>
 
-<H3><a name="Perl5_nn12">30.3.1 Running SWIG from Developer Studio</a></H3>
+<H3><a name="Perl5_nn12">31.3.1 Running SWIG from Developer Studio</a></H3>
 
 
 <p>
@@ -680,7 +680,6 @@
 installation under "Additional include directories".
 
 <li>Define the symbols WIN32 and MSWIN32 under preprocessor options.
-If using the ActiveWare port, also define the symbol PERL_OBJECT.
 Note that all extensions to the ActiveWare port must be compiled with
 the C++ compiler since Perl has been encapsulated in a C++ class.
 
@@ -708,7 +707,7 @@
 
 </pre></div>
 
-<H3><a name="Perl5_nn13">30.3.2 Using other compilers</a></H3>
+<H3><a name="Perl5_nn13">31.3.2 Using other compilers</a></H3>
 
 
 <p>
@@ -716,7 +715,7 @@
 For general hints and suggestions refer to the <a href="Windows.html#Windows">Windows</a> chapter.
 </p>
 
-<H2><a name="Perl5_nn14">30.4 The low-level interface</a></H2>
+<H2><a name="Perl5_nn14">31.4 The low-level interface</a></H2>
 
 
 <p>
@@ -726,7 +725,7 @@
 construct more user-friendly proxy classes as described in the next section.
 </p>
 
-<H3><a name="Perl5_nn15">30.4.1 Functions</a></H3>
+<H3><a name="Perl5_nn15">31.4.1 Functions</a></H3>
 
 
 <p>
@@ -749,7 +748,7 @@
 $a = &amp;example::fact(2);
 </pre></div>
 
-<H3><a name="Perl5_nn16">30.4.2 Global variables</a></H3>
+<H3><a name="Perl5_nn16">31.4.2 Global variables</a></H3>
 
 
 <p>
@@ -819,7 +818,7 @@
 </pre>
 </div>
 
-<H3><a name="Perl5_nn17">30.4.3 Constants</a></H3>
+<H3><a name="Perl5_nn17">31.4.3 Constants</a></H3>
 
 
 <p>
@@ -859,7 +858,7 @@
 </pre>
 </div>
 
-<H3><a name="Perl5_nn18">30.4.4 Pointers</a></H3>
+<H3><a name="Perl5_nn18">31.4.4 Pointers</a></H3>
 
 
 <p>
@@ -968,7 +967,7 @@
 SWIG and XS, this is no longer supported.
 </p>
 
-<H3><a name="Perl5_nn19">30.4.5 Structures</a></H3>
+<H3><a name="Perl5_nn19">31.4.5 Structures</a></H3>
 
 
 <p>
@@ -1065,7 +1064,7 @@
 <p>
 If you want to set an array member, you will need to supply a "memberin" typemap
 described later in this chapter.  As a special case, SWIG does generate
-code to set array members of type <tt>char</tt> (allowing you to store a Python
+code to set array members of type <tt>char</tt> (allowing you to store a Perl
 string in the structure).
 </p>
 
@@ -1102,7 +1101,7 @@
 </div>
 
 
-<H3><a name="Perl5_nn20">30.4.6 C++ classes</a></H3>
+<H3><a name="Perl5_nn20">31.4.6 C++ classes</a></H3>
 
 
 <p>
@@ -1167,7 +1166,7 @@
 can be built using these low-level accessors.  This is described shortly.
 </p>
 
-<H3><a name="Perl5_nn21">30.4.7 C++ classes and type-checking</a></H3>
+<H3><a name="Perl5_nn21">31.4.7 C++ classes and type-checking</a></H3>
 
 
 <p>
@@ -1203,7 +1202,7 @@
 multiple inheritance is used).
 </p>
 
-<H3><a name="Perl5_nn22">30.4.8 C++ overloaded functions</a></H3>
+<H3><a name="Perl5_nn22">31.4.8 C++ overloaded functions</a></H3>
 
 
 <p>
@@ -1247,7 +1246,7 @@
 Please refer to the "SWIG Basics" chapter for more information. 
 </p>
 
-<H3><a name="Perl5_nn23">30.4.9 Operators</a></H3>
+<H3><a name="Perl5_nn23">31.4.9 Operators</a></H3>
 
 
     <p>
@@ -1274,7 +1273,7 @@
 <li>operator or  </li>
     </ul>
 
-<H3><a name="Perl5_nn24">30.4.10 Modules and packages</a></H3>
+<H3><a name="Perl5_nn24">31.4.10 Modules and packages</a></H3>
 
 
 <p>
@@ -1369,7 +1368,7 @@
 </pre></div>
 -->
 
-<H2><a name="Perl5_nn25">30.5 Input and output parameters</a></H2>
+<H2><a name="Perl5_nn25">31.5 Input and output parameters</a></H2>
 
 
 <p>
@@ -1494,7 +1493,7 @@
 <div class="code">
 <pre>
 /* send message, return number of bytes sent, along with success code */
-int send_message(char *text, int len, int *success);
+int send_message(char *text, int *success);
 </pre>
 </div>
 
@@ -1588,7 +1587,7 @@
 <b>Note:</b> The <tt>REFERENCE</tt> feature is only currently supported for numeric types (integers and floating point).
 </p>
 
-<H2><a name="Perl5_nn26">30.6 Exception handling</a></H2>
+<H2><a name="Perl5_nn26">31.6 Exception handling</a></H2>
 
 
 <p>
@@ -1730,29 +1729,7 @@
 See the chapter on "<a href="Customization.html#Customization">Customization features</a>" for more examples.
 </p>
 
-<p>
-<b>Compatibility note:</b> In SWIG1.1, exceptions were defined using the older <tt>%except</tt> directive:
-</p>
-
-<div class="code">
-<pre>
-%except(python) {
-  try {
-    $function
-  }
-  catch (RangeError) {
-    croak("Array index out-of-bounds");
-  }
-}
-</pre>
-</div>
-
-<p>
-This is still supported, but it is deprecated.  The newer <tt>%exception</tt> directive provides the same
-functionality, but it has additional capabilities that make it more powerful.
-</p>
-
-<H2><a name="Perl5_nn27">30.7 Remapping datatypes with typemaps</a></H2>
+<H2><a name="Perl5_nn27">31.7 Remapping datatypes with typemaps</a></H2>
 
 
 <p>
@@ -1769,7 +1746,7 @@
 C-Perl interface.
 </p>
 
-<H3><a name="Perl5_nn28">30.7.1 A simple typemap example</a></H3>
+<H3><a name="Perl5_nn28">31.7.1 A simple typemap example</a></H3>
 
 
 <p>
@@ -1873,7 +1850,7 @@
 </div>
 
 
-<H3><a name="Perl5_nn29">30.7.2 Perl5 typemaps</a></H3>
+<H3><a name="Perl5_nn29">31.7.2 Perl5 typemaps</a></H3>
 
 
 <p>
@@ -1963,14 +1940,6 @@
 </div>
 
 <p>
-<tt>%typemap(memberout)</tt>
-</p>
-
-<div class="indent">
-Return of C++ member data (all languages).
-</div>
-
-<p>
 <tt>%typemap(check)</tt>
 </p>
 
@@ -1978,7 +1947,7 @@
 Check value of input parameter.
 </div>
 
-<H3><a name="Perl5_nn30">30.7.3 Typemap variables</a></H3>
+<H3><a name="Perl5_nn30">31.7.3 Typemap variables</a></H3>
 
 
 <p>
@@ -2049,7 +2018,7 @@
 The Perl name of the wrapper function being created.
 </div>
 
-<H3><a name="Perl5_nn31">30.7.4 Useful functions</a></H3>
+<H3><a name="Perl5_nn31">31.7.4 Useful functions</a></H3>
 
 
 <p>
@@ -2118,7 +2087,7 @@
 </div>
 
 
-<H2><a name="Perl5_nn32">30.8 Typemap Examples</a></H2>
+<H2><a name="Perl5_nn32">31.8 Typemap Examples</a></H2>
 
 
 <p>
@@ -2127,7 +2096,7 @@
 the SWIG library.
 </p>
 
-<H3><a name="Perl5_nn33">30.8.1 Converting a Perl5 array to a char **</a></H3>
+<H3><a name="Perl5_nn33">31.8.1 Converting a Perl5 array to a char **</a></H3>
 
 
 <p>
@@ -2219,7 +2188,7 @@
 </pre></div>
 
 
-<H3><a name="Perl5_nn34">30.8.2 Return values</a></H3>
+<H3><a name="Perl5_nn34">31.8.2 Return values</a></H3>
 
 
 <p>
@@ -2243,12 +2212,12 @@
     EXTEND(sp, 1);              /* Extend the stack by 1 object */
   }
   $result = sv_newmortal();
-  sv_setiv($target, (IV) *($1));
+  sv_setiv($result, (IV) *($1));
   argvi++;
 }
 </pre></div>
 
-<H3><a name="Perl5_nn35">30.8.3 Returning values from arguments</a></H3>
+<H3><a name="Perl5_nn35">31.8.3 Returning values from arguments</a></H3>
 
 
 <p>
@@ -2302,7 +2271,7 @@
 ($x, $y) = multout(7, 13);
 </pre></div>
 
-<H3><a name="Perl5_nn36">30.8.4 Accessing array structure members</a></H3>
+<H3><a name="Perl5_nn36">31.8.4 Accessing array structure members</a></H3>
 
 
 <p>
@@ -2320,7 +2289,7 @@
 
 <p>
 By default, SWIG doesn't know how to the handle the values structure
-member it's an array, not a pointer.  In this case, SWIG makes the array member
+member because it's an array, not a pointer.  In this case, SWIG makes the array member
 read-only.   Reading will simply return a pointer to the first item in the array.
 To make the member writable, a "memberin" typemap can be used.
 </p>
@@ -2365,7 +2334,7 @@
 to copy the converted array into a C data structure.
 </p>
 
-<H3><a name="Perl5_nn37">30.8.5 Turning Perl references into C pointers</a></H3>
+<H3><a name="Perl5_nn37">31.8.5 Turning Perl references into C pointers</a></H3>
 
 
 <p>
@@ -2430,7 +2399,7 @@
 
 </pre></div>
 
-<H3><a name="Perl5_nn38">30.8.6 Pointer handling</a></H3>
+<H3><a name="Perl5_nn38">31.8.6 Pointer handling</a></H3>
 
 
 <p>
@@ -2515,7 +2484,7 @@
 </pre>
 </div>
 
-<H2><a name="Perl5_nn39">30.9 Proxy classes</a></H2>
+<H2><a name="Perl5_nn39">31.9 Proxy classes</a></H2>
 
 
 <p>
@@ -2531,7 +2500,7 @@
 details of the proxy interface.
 </p>
 
-<H3><a name="Perl5_nn40">30.9.1 Preliminaries</a></H3>
+<H3><a name="Perl5_nn40">31.9.1 Preliminaries</a></H3>
 
 
 <p>
@@ -2553,7 +2522,7 @@
 high level wrappers.  The wrappers, in turn, interact with the low-level procedural module.
 </p>
 
-<H3><a name="Perl5_nn41">30.9.2 Structure and class wrappers</a></H3>
+<H3><a name="Perl5_nn41">31.9.2 Structure and class wrappers</a></H3>
 
 
 <p>
@@ -2651,8 +2620,8 @@
 "new" and "DESTROY".  The constructor always returns a tied hash
 table.  This hash table is used to access the member variables of a
 structure in addition to being able to invoke member functions.  The
-<tt>%OWNER</tt> and <tt>%BLESSEDMEMBERS</tt> hash tables are used
-internally and described shortly.
+<tt>%OWNER</tt> and <tt>%BLESSEDMEMBERS</tt> hash tables are
+implementation details used internally and described shortly.
 </p>
 
 <p>
@@ -2680,7 +2649,7 @@
 
 </pre></div>
 
-<H3><a name="Perl5_nn42">30.9.3 Object Ownership</a></H3>
+<H3><a name="Perl5_nn42">31.9.3 Object Ownership</a></H3>
 
 
 <p>
@@ -2740,8 +2709,15 @@
 corresponding Perl object (this situation turns out to come up
 frequently when constructing objects like linked lists and trees).
 When C takes possession of an object, you can change Perl's ownership
-by simply deleting the object from the <tt>%OWNER</tt> hash.  This is
-done using the <tt>DISOWN</tt> method.
+by calling the <tt>DISOWN</tt> method (which will delete the object
+from the internal <tt>%OWNER</tt> hash).
+</p>
+
+<p>
+The <tt>%OWNER</tt> hash is an implementation detail, discussed here
+only to help clarify the operation of <tt>ACQUIRE</tt> and <tt>DISOWN</tt>.
+You should not access <tt>%OWNER</tt> directly - the details of how it
+works (and possibly even its existence) may change in future SWIG versions.
 </p>
 
 <div class="targetlang"><pre>
@@ -2767,7 +2743,7 @@
 sophisticated languages.
 </p>
 
-<H3><a name="Perl5_nn43">30.9.4 Nested Objects</a></H3>
+<H3><a name="Perl5_nn43">31.9.4 Nested Objects</a></H3>
 
 
 <p>
@@ -2820,7 +2796,7 @@
 %${$p-&gt;{v}} = ( x=&gt;0, y=&gt;0, z=&gt;0);         
 </pre></div>
 
-<H3><a name="Perl5_nn44">30.9.5 Proxy Functions</a></H3>
+<H3><a name="Perl5_nn44">31.9.5 Proxy Functions</a></H3>
 
 
 <p>
@@ -2854,7 +2830,7 @@
 identical manner.
 </p>
 
-<H3><a name="Perl5_nn45">30.9.6 Inheritance</a></H3>
+<H3><a name="Perl5_nn45">31.9.6 Inheritance</a></H3>
 
 
 <p>
@@ -2930,7 +2906,7 @@
 not even sure if it really works).
 </p>
 
-<H3><a name="Perl5_nn46">30.9.7 Modifying the proxy methods</a></H3>
+<H3><a name="Perl5_nn46">31.9.7 Modifying the proxy methods</a></H3>
 
 
 <p>
@@ -2958,7 +2934,7 @@
 };
 </pre></div>
 
-<H2><a name="Perl5_nn47">30.10 Adding additional Perl code</a></H2>
+<H2><a name="Perl5_nn47">31.10 Adding additional Perl code</a></H2>
 
 
 <p>
@@ -3009,7 +2985,7 @@
 </pre>
 </div>
 
-<H2><a name="Perl5_directors">30.11 Cross language polymorphism</a></H2>
+<H2><a name="Perl5_directors">31.11 Cross language polymorphism</a></H2>
 
 
 <p>
@@ -3043,7 +3019,7 @@
 all the cross-language method routing transparently.
 </p>
 
-<H3><a name="Perl5_nn48">30.11.1 Enabling directors</a></H3>
+<H3><a name="Perl5_nn48">31.11.1 Enabling directors</a></H3>
 
 
 <p>
@@ -3133,7 +3109,7 @@
 </div>
 
 
-<H3><a name="Perl5_nn49">30.11.2 Director classes</a></H3>
+<H3><a name="Perl5_nn49">31.11.2 Director classes</a></H3>
 
 
  
@@ -3214,7 +3190,7 @@
 calls through Perl.
 </p>
 
-<H3><a name="Perl5_nn50">30.11.3 Ownership and object destruction</a></H3>
+<H3><a name="Perl5_nn50">31.11.3 Ownership and object destruction</a></H3>
 
 
 <p>
@@ -3263,7 +3239,7 @@
 </div>
 
 
-<H3><a name="Perl5_nn51">30.11.4 Exception unrolling</a></H3>
+<H3><a name="Perl5_nn51">31.11.4 Exception unrolling</a></H3>
 
 
 <p>
@@ -3319,7 +3295,7 @@
 exception as soon as the C wrapper function returns.
 </p>
 
-<H3><a name="Perl5_nn52">30.11.5 Overhead and code bloat</a></H3>
+<H3><a name="Perl5_nn52">31.11.5 Overhead and code bloat</a></H3>
 
 
 <p>
@@ -3353,7 +3329,7 @@
 Perl.
 </p>
 
-<H3><a name="Perl5_nn53">30.11.6 Typemaps</a></H3>
+<H3><a name="Perl5_nn53">31.11.6 Typemaps</a></H3>
 
 
 <p>
diff --git a/Doc/Manual/Php.html b/Doc/Manual/Php.html
index d0ec0df..ede3519 100644
--- a/Doc/Manual/Php.html
+++ b/Doc/Manual/Php.html
@@ -7,7 +7,7 @@
 </head>
 
 <body bgcolor="#ffffff">
-<H1><a name="Php">31 SWIG and PHP</a></H1>
+<H1><a name="Php">32 SWIG and PHP</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -30,6 +30,7 @@
 <li><a href="#Php_nn2_6_3">Static Member Variables</a>
 <li><a href="#Php_nn2_6_4">Static Member Functions</a>
 <li><a href="#Php_nn2_6_5">Specifying Implemented Interfaces</a>
+<li><a href="#Php_nn2_6_6">Dynamic Properties</a>
 </ul>
 <li><a href="#Php_nn2_7">PHP Pragmas, Startup and Shutdown code</a>
 </ul>
@@ -50,18 +51,20 @@
 
 
 <p>
-In this chapter, we discuss SWIG's support of PHP.  SWIG currently supports
-generating wrappers for PHP7.  Support for PHP5 was removed in SWIG 4.0.0
-and support for PHP4 was removed in SWIG 1.3.37.
+In this chapter, we discuss SWIG's support of PHP.  Currently any PHP8
+release should work.
 </p>
 
 <p>
-Currently any PHP7 release should work.
+Support for PHP8 was added in SWIG 4.1.0.
+Support for PHP7 was added in SWIG 3.0.11 and removed in 4.2.0.
+Support for PHP5 was removed in SWIG 4.0.0 and support for PHP4 was removed in
+SWIG 1.3.37.  There never was a PHP6 release.
 </p>
 
 <p>
 In order to use this module, you will need to have a copy of the PHP
-include files to compile the SWIG generated files.  If you installed
+include files to compile the SWIG generated C/C++ sources.  If you installed
 PHP from a binary package, you may need to install a "php-dev" or "php-devel"
 package for these to be installed.  You can find out where these files are
 by running <tt>php-config --includes</tt>.  To use the built PHP module you
@@ -70,30 +73,36 @@
 available.
 </p>
 
-<H2><a name="Php_nn1">31.1 Generating PHP Extensions</a></H2>
+<H2><a name="Php_nn1">32.1 Generating PHP Extensions</a></H2>
 
 
 <p>
-To build a PHP extension, run swig using the <tt>-php7</tt> option as follows
-(<tt>-php</tt> is also supported and currently is an alias for <tt>-php7</tt>
-but prior to SWIG 4.0.0 it was an alias for <tt>-php5</tt>):
+To build a PHP extension, run swig using the <tt>-php</tt> option
+(you can also use <tt>-php7</tt> - PHP7 and PHP8 have a largely compatible C
+extension API, hence the same option name has been used for both).  For
+example:
 </p>
 
 <div class="code"><pre>
-swig -php7 example.i
+swig -php example.i
 </pre></div>
 
 <p>
-This will produce 3 files example_wrap.c, php_example.h and
-example.php. The first file, <tt>example_wrap.c</tt> contains all of
+This will produce 2 files: example_wrap.c and php_example.h.
+The first file, <tt>example_wrap.c</tt> contains all of
 the C code needed to build a PHP extension. The second file,
 <tt>php_example.h</tt> contains the header information needed if
 you wish to statically link the extension into the php interpreter.
-The third file,
-<tt>example.php</tt> can be included by PHP scripts.  It attempts to
-dynamically load the extension and contains extra php code specified
-in the interface file.  If wrapping C++ code with PHP classes, it will
-also contain PHP class wrappers.
+</p>
+
+<p>
+If the interface file uses <tt>%pragma(php) include=</tt>... or
+<tt>%pragma(php) code=</tt>... then SWIG will also generate a third file,
+<tt>example.php</tt> to contain what these specify.  In SWIG &lt; 4.1.0,
+this third file was always generated as it defined the PHP classes, etc
+(but this is now done via C code in <tt>example_wrap.c</tt>) and also
+contained code to dynamically load the extension (but this used the
+PHP <tt>dl()</tt> function, which isn't recommended nowadays).
 </p>
 
 <p>
@@ -119,7 +128,7 @@
 this approach, or provide explicit support for it.
 </p>
 
-<H3><a name="Php_nn1_1">31.1.1 Building a loadable extension</a></H3>
+<H3><a name="Php_nn1_1">32.1.1 Building a loadable extension</a></H3>
 
 
 <p>
@@ -134,13 +143,24 @@
         gcc -shared example_wrap.o example.o -o example.so
 </pre></div>
 
-<H3><a name="Php_nn1_3">31.1.2 Using PHP Extensions</a></H3>
+<H3><a name="Php_nn1_3">32.1.2 Using PHP Extensions</a></H3>
 
 
 <p>
 To test the extension from a PHP script, you first need to tell PHP to
-load it.  To do this, add a line like this to the <tt>[PHP]</tt> section of
-<tt>php.ini</tt>:
+load it.  The recommended (and simplest!) way to do this is to copy it to
+PHP's default extension directory and add a line like this to the
+<tt>[PHP]</tt> section of <tt>php.ini</tt>:
+</p>
+
+<div class="code"><pre>
+        extension=modulename
+</pre></div>
+
+<p>
+If the module is not in PHP's default extension directory, you also need to
+specify the path, in which case you'll also need to deal with platform-specific
+naming - for example, on Linux:
 </p>
 
 <div class="code"><pre>
@@ -148,41 +168,35 @@
 </pre></div>
 
 <p>
-If the module is in PHP's default extension directory, you can omit the path.
+but on Microsoft Windows you'd need to use:
 </p>
 
+<div class="code"><pre>
+        extension=/path/to/php_modulename.dll
+</pre></div>
+
 <p>
-For some SAPIs (for example, the CLI SAPI) you can instead use the
-<a href="https://www.php.net/manual/en/function.dl.php">dl() function</a> to load
-an extension at run time, by adding a line like this to the start of each
+If you're using the PHP CLI SAPI it's possible (but not recommended) to use the
+<a href="https://www.php.net/manual/en/function.dl.php">dl() function</a> to
+load an extension at run time, by adding a line like this to the start of each
 PHP script which uses your extension:
 </p>
 
 <div class="code"><pre>
-        dl("/path/to/modulename.so"); // Load the module
+        dl("modulename"); // Load the module
 </pre></div>
 
 <p>
-But note that <tt>dl()</tt> isn't supported when running PHP through a
-webserver - you'll need to use <tt>extension</tt> in <tt>php.ini</tt> as
-described above.
+Again, if the module isn't in PHP's default extension directory you'll also
+need to specify the path and deal with that varying by platform.
 </p>
 
 <p>
-The PHP module which SWIG generates will also attempt to do the <tt>dl()</tt>
-call for you if the extension isn't already loaded:
+For security reasons PHP no longer supports <tt>dl()</tt> when running PHP
+through a webserver, so this isn't an option there.
 </p>
 
-<div class="code"><pre>
-        include("example.php");
-</pre></div>
-
-<p>
-This PHP module also defines the PHP classes for the wrapped API, so you'll
-almost certainly want to include it anyway.
-</p>
-
-<H2><a name="Php_nn2">31.2 Basic PHP interface</a></H2>
+<H2><a name="Php_nn2">32.2 Basic PHP interface</a></H2>
 
 
 <p>
@@ -194,7 +208,7 @@
 namespace feature.
 </p>
 
-<H3><a name="Php_nn2_1">31.2.1 Constants</a></H3>
+<H3><a name="Php_nn2_1">32.2.1 Constants</a></H3>
 
 
 <p>
@@ -219,61 +233,13 @@
 </p>
 
 <div class="code"><pre>
-include("example.php");
-
 echo "PI = " . PI . "\n";
-
 echo "E = " . E . "\n";
-
 </pre>
 </div>
 
-<p>
-There's one peculiarity of how constants work in PHP which it is useful
-to note (this is not specific to SWIG though) - if you try to use an undeclared
-constant, PHP will emit a warning (or a notice in PHP 7.1 and earlier) and then
-expand the constant to a string version of the constant's name.  Unfortunately
-it is easy to miss the warning message if you're using PHP in a webserver as
-it will probably end up in error.log or similar.  Apparently this will throw
-an Error in a future version of PHP, but until then it's something to be
-aware of.
-</p>
 
-<p>
-For example,
-</p>
-
-<div class="code"><pre>
-%module example
-
-#define EASY_TO_MISPELL 0
-</pre>
-</div>
-
-<p>
-accessed incorrectly in PHP,
-</p>
-
-<div class="code">
-<pre>
-include("example.php");
-
-if(EASY_TO_MISPEL) {
-  ...
-} else {
-  ...
-}
-
-</pre>
-</div>
-
-<p>
-The mis-spelled constant will become the string 'EASY_TO_MISPEL', which
-is treated as true by the if test, when the value of the intended constant
-would be treated as false!
-</p>
-
-<H3><a name="Php_nn2_2">31.2.2 Global Variables</a></H3>
+<H3><a name="Php_nn2_2">32.2.2 Global Variables</a></H3>
 
 
 <p>
@@ -298,7 +264,6 @@
 </p>
 
 <div class="code"><pre>
-include("example.php");
 print seki_get();
 seki_set( seki_get() * 2); # The C variable is now 4.
 print seki_get();
@@ -306,23 +271,24 @@
 
 <p>
 SWIG supports global variables of all C datatypes including pointers
-and complex objects.  Additional types can be supported by using the
-<tt>varinit</tt> typemap.
+and complex objects.  To support additional types, you just need to
+supply the standard <tt>in</tt> and <tt>out</tt> typemaps, which get
+used because of the wrapping as <tt>_get()</tt> and <tt>_set()</tt>
+functions.
 </p>
 
 <p>
-SWIG honors the <tt>%immutable</tt> modifier by not generating code
-for the <tt>_set</tt> method.  This provides read-only access to the
-variable from the php script.  Attempting to access the <tt>_set</tt>
-method will result in a php fatal error because the function is
-undefined.
+SWIG honors the <tt>%immutable</tt> modifier by not generating a
+<tt>_set</tt> method (so attempting to call it will give a PHP fatal
+error).  A <tt>_get</tt> method is still generated so this provides read-only
+access to the variable from the PHP script.
 </p>
 
 <p>
 At this time SWIG does not support custom accessor methods.
 </p>
 
-<H3><a name="Php_nn2_3">31.2.3 Functions</a></H3>
+<H3><a name="Php_nn2_3">32.2.3 Functions</a></H3>
 
 
 <p>
@@ -342,13 +308,84 @@
 </p>
 
 <div class="code"><pre>
-include("example.php");
 $a = foo(2);
 $b = bar(3.5, -1.5);
 $c = bar(3.5);  # Use default argument for 2nd parameter
 
 </pre></div>
 
+<p>
+SWIG generates PHP type declarations for function parameters and return
+types for PHP 8 and later.
+</p>
+
+<p>
+You can control the generation of PHP type declarations using
+the "php:type" %feature.  This has three settings:
+</p>
+
+<ul>
+    <li> <p>If unset or set to "0" then no type declarations are generated, e.g.: <tt>%feature("php:type", "0");</tt>
+      </p>
+    </li>
+    <li> <p>If set to "1" then type declarations are generated for both parameters and return types, e.g.: <tt>%feature("php:type", "1");</tt>
+      </p></li>
+      <li> <p>The default setting is "compat", which is the same as "1" except no
+      return type declarations are generated for virtual methods for which
+      directors are enabled.  This provides better compatibility for PHP
+      subclasses of wrapped virtual methods in existing SWIG-generated bindings, e.g.: <tt>%feature("php:type", "compat");</tt>
+      </p></li>
+</ul>
+
+<p>
+If you have an existing PHP interface and are upgrading to SWIG &gt;= 4.1.0
+then the default "compat" setting should work well.
+</p>
+
+<p>
+If you're writing a new set of bindings and <b>only targeting PHP8 or newer</b>
+then enabling type declarations everywhere probably makes sense.  It will
+only actually make a difference if you enable directors and are wrapping C++
+classes with virtual methods, but doing it anyway means you won't forget to if
+the code you are wrapping later evolves to have such classes and methods.
+</p>
+
+<p>
+The type declaration information will make the generated source code and
+compiler extension module larger, so you might want to turn off type
+declarations if keeping these small is important to you.  If you find you
+need to turn off type declarations to fix a problem, please let us know
+via our github issue tracker.
+</p>
+
+<p>
+Note that being a SWIG feature this can be specified globally (like above) or
+per class, per method, etc.  See the <a
+href="Customization.html#Customization_features">%feature directives</a>
+section for full details of how to control at a fine-grained level.
+</p>
+
+<p>
+The PHP type information is specified via a "phptype" attribute on "in" and
+"out" typemaps, and these have been added for all the typemaps we supply for
+PHP.  We don't currently support this for "argout" templates, but probably
+will in a future version.
+</p>
+
+<p>
+If you have written custom SWIG typemaps for PHP and want to add PHP type
+declarations, then the syntax is very like how you'd specify the type in
+PHP code, e.g. <tt>%typemap(in, phptype="int|string|Foo")</tt> means the
+typemap accepts a PHP int or string or an object of class Foo,
+<tt>%typemap(in, phptype="?int")</tt> means a PHP int or NULL, etc.
+As well as the standard PHP type declaration types, SWIG also understands the
+special type "SWIGTYPE" as an entry in phptype, which means the PHP type
+corresponding to the type that this typemap matched on - for a object this
+will give you the PHP class for the object, and for a pointer to a non-class
+type it will give you the name of the PHP class SWIG created for that
+pointer type.
+</p>
+
 <!-- This isn't correct for 1.3.30 and needs rewriting to reflect reality
 <p>
 Because PHP is a dynamically typed language, the default typemaps
@@ -375,7 +412,7 @@
 -->
 
 
-<H3><a name="Php_nn2_4">31.2.4 Overloading</a></H3>
+<H3><a name="Php_nn2_4">32.2.4 Overloading</a></H3>
 
 
 <p>
@@ -430,12 +467,15 @@
 </p>
 -->
 
-<H3><a name="Php_nn2_5">31.2.5 Pointers and References</a></H3>
+<H3><a name="Php_nn2_5">32.2.5 Pointers and References</a></H3>
 
 
 <p>
-Pointers to C/C++ objects are represented
-as PHP resources, rather like MySQL connection handles.
+Since SWIG 4.1.0, SWIG wraps C/C++ classes directly with PHP objects.
+Pointers to other types are also wrapped as PHP objects - mostly this is an
+implementation detail, but it's visible from PHP via <tt>is_object()</tt> and
+similar.  In earlier SWIG versions, PHP resources were used to wrap both
+classes and pointers to other types.
 </p>
 
 <p>
@@ -467,8 +507,6 @@
 <div class="code"><pre>
 &lt;?php
 
-include("example.php");
-
 $in1=copy_intp(3);
 $in2=copy_intp(5);
 $result=new_intp();
@@ -476,7 +514,6 @@
 add( $in1, $in2, $result );
 
 echo "The sum " . intp_value($in1) . " + " . intp_value($in2) . " = " . intp_value( $result) . "\n";
-?&gt;
 </pre></div>
 
 <p>
@@ -501,14 +538,11 @@
 <div class="code"><pre>
 &lt;?php
 
-include("example.php");
-
 $in1 = 3;
 $in2 = 5;
 $result= add($in1, $in2);  # Note using variables for the input is unnecessary.
 
 echo "The sum $in1 + $in2 = $result\n";
-?&gt;
 </pre></div>
 
 <p>
@@ -539,15 +573,12 @@
 <div class="code"><pre>
 &lt;?php
 
-include("example.php");
-
 $in1 = 3;
 $in2 = 5;
 $result = 0;
 add($in1, $in2, $result);
 
 echo "The sum $in1 + $in2 = $result\n";
-?&gt;
 </pre></div>
 
 <p>
@@ -568,15 +599,14 @@
 variable, or assigning <tt>NULL</tt> to a variable.
 </p>
 
-<H3><a name="Php_nn2_6">31.2.6 Structures and C++ classes</a></H3>
+<H3><a name="Php_nn2_6">32.2.6 Structures and C++ classes</a></H3>
 
 
 <p>
-SWIG defaults to wrapping C++ structs and classes with PHP classes - this
-is done by generating a PHP wrapper script which defines proxy classes
-which calls a set of flat functions which actually wrap the C++ class.
-You can disable this wrapper layer by passing the command-line option
-"-noproxy" in which case you'll just get the flat functions.
+SWIG wraps C++ structs and classes with PHP classes.
+Since SWIG 4.1.0, this is done entirely via PHP's C API - earlier SWIG
+versions generated a PHP wrapper script which defined proxy classes
+which called a set of flat functions which actually wrapped the C++ class.
 </p>
 
 <p>
@@ -605,7 +635,6 @@
 
 <div class="code"><pre>
 &lt;?php
-  require "vector.php";
 
   $v = new Vector();
   $v-&gt;x = 3;
@@ -622,53 +651,34 @@
   $c-&gt;im = 0;
 
   # $c destructor called when $c goes out of scope.
-?&gt;
 </pre></div>
 
 <p>
 Member variables and methods are accessed using the <tt>-&gt;</tt> operator.
 </p>
 
-<H4><a name="Php_nn2_6_1">31.2.6.1 Using -noproxy</a></H4>
+<H4><a name="Php_nn2_6_1">32.2.6.1 Using -noproxy</a></H4>
 
 
 <p>
-The <tt>-noproxy</tt> option flattens the object structure and
-generates collections of named functions (these are the functions
-which the PHP class wrappers call).  The above example results
-in the following PHP functions:
+SWIG/PHP used to support a <tt>-noproxy</tt> option to flatten the class
+structure and generate collections of named flat functions.  This is no
+longer supported as of SWIG 4.1.0.
 </p>
 
-<div class="code"><pre>
-new_Vector();
-Vector_x_set($obj, $d);
-Vector_x_get($obj);
-Vector_y_set($obj, $d);
-Vector_y_get($obj);
-Vector_z_set($obj, $d);
-Vector_z_get($obj);
-Vector_magnitude($obj);
-new_Complex();
-Complex_re_set($obj, $d);
-Complex_re_get($obj);
-Complex_im_set($obj, $d);
-Complex_im_get($obj);
-</pre></div>
-
-<H4><a name="Php_nn2_6_2">31.2.6.2 Constructors and Destructors</a></H4>
+<H4><a name="Php_nn2_6_2">32.2.6.2 Constructors and Destructors</a></H4>
 
 
 <p>
-The constructor is called when <tt>new Object()</tt> (or
-<tt>new_Object()</tt> if using <tt>-noproxy</tt>) is used to create an
+The constructor is called when <tt>new Object()</tt> is used to create an
 instance of the object. If multiple constructors are defined for an
 object, function overloading will be used to determine which
 constructor to execute.
 </p>
 
 <p>
-Because PHP uses reference counting to manage resources, simple
-assignment of one variable to another such as:
+Because PHP uses reference counting, simple assignment of one variable to
+another such as:
 </p>
 
 <div class="code"><pre>
@@ -696,7 +706,7 @@
 <tt>unset($v)</tt>
 </p>
 
-<H4><a name="Php_nn2_6_3">31.2.6.3 Static Member Variables</a></H4>
+<H4><a name="Php_nn2_6_3">32.2.6.3 Static Member Variables</a></H4>
 
 
 <p>
@@ -721,8 +731,6 @@
 </p>
 
 <div class="code"><pre>
-include("example.php");
-
 echo "There have now been " . Ko::threats() . " threats\n";
 
 </pre></div>
@@ -739,7 +747,7 @@
 echo "There have now been " . Ko::threats() . " threats\n";
 
 </pre></div>
-<H4><a name="Php_nn2_6_4">31.2.6.4 Static Member Functions</a></H4>
+<H4><a name="Php_nn2_6_4">32.2.6.4 Static Member Functions</a></H4>
 
 
 <p>
@@ -754,14 +762,16 @@
 };
 </pre></div>
 
-would be executed in PHP as,
+<p>
+would be executed in PHP as
+</p>
+
 <div class="code"><pre>
-include("example.php");
 Ko::threats();
 </pre></div>
 
 
-<H4><a name="Php_nn2_6_5">31.2.6.5 Specifying Implemented Interfaces</a></H4>
+<H4><a name="Php_nn2_6_5">32.2.6.5 Specifying Implemented Interfaces</a></H4>
 
 
 <p>
@@ -772,20 +782,73 @@
 </p>
 
 <div class="code"><pre>
-%typemap("phpinterfaces") MyIterator "Iterator";
+%typemap("phpinterfaces") MyIterator "Iterator"
 </pre></div>
 
 <p>
 If there are multiple interfaces, just list them separated by commas.
 </p>
 
-<H3><a name="Php_nn2_7">31.2.7 PHP Pragmas, Startup and Shutdown code</a></H3>
+
+<H4><a name="Php_nn2_6_6">32.2.6.6 Dynamic Properties</a></H4>
 
 
 <p>
-To place PHP code in the generated "example.php" file one can use the
-<b>code</b> pragma. The code is inserted after loading the shared
-object.
+Historically PHP has supported dynamic class properties and SWIG
+has implemented them too (because we implement the magic <tt>__get()</tt>,
+<tt>__set()</tt> and <tt>__isset()</tt> methods we need to include explicit
+handling).
+</p>
+
+<p>
+PHP 8.2 <a
+href="https://wiki.php.net/rfc/deprecate_dynamic_properties">deprecates
+dynamic class properties</a> - initially they'll warn, and apparently they'll
+not work by default in PHP 9.0.
+</p>
+
+<p>
+In PHP code dynamic properties can be enabled for a class by
+marking that class with the attribute <tt>#[AllowDynamicProperties]</tt>.
+</p>
+
+<p>
+To follow this PHP change, as of SWIG 4.1.0 you now need enable dynamic
+properties for any classes you want to support them.  To enable for class
+<tt>Foo</tt>:
+</p>
+
+<div class="code"><pre>
+%feature("php:allowdynamicproperties", 1) Foo;
+</pre></div>
+
+<p>
+or to enable them for all wrapped classes:
+</p>
+
+<div class="code"><pre>
+%feature("php:allowdynamicproperties", 1);
+</pre></div>
+
+<p>
+Note that unknown features are ignored, so you can add use these
+unconditionally in your interface file and it'll work with older SWIG too.
+</p>
+
+<p>
+There was a bug in SWIG 4.1.0 where setting this feature to any value enabled
+it - SWIG 4.2.0 fixed this and you can now set it to 0 to turn it off (for
+example, you might want to enabled it for everything and then selectively turn
+it off for specific classes).
+</p>
+
+
+<H3><a name="Php_nn2_7">32.2.7 PHP Pragmas, Startup and Shutdown code</a></H3>
+
+
+<p>
+You can get SWIG to generate an "example.php" file by specifying
+the code to put in it using the <b>code</b> pragma.
 </p>
 
 <div class="code"><pre>
@@ -876,14 +939,14 @@
 into the request init (PHP_RINIT_FUNCTION) and request shutdown (PHP_RSHUTDOWN_FUNCTION) code respectively.
 </p>
 
-<H2><a name="Php_nn3">31.3 Cross language polymorphism</a></H2>
+<H2><a name="Php_nn3">32.3 Cross language polymorphism</a></H2>
 
 
 <p>
 Proxy classes provide a more natural, object-oriented way to access
 extension classes. As described above, each proxy instance has an
 associated C++ instance, and method calls to the proxy are passed to the
-C++ instance transparently via C wrapper functions.
+C++ instance transparently.
 </p>
 
 <p>
@@ -911,7 +974,7 @@
 transparently.
 </p>
 
-<H3><a name="Php_nn3_1">31.3.1 Enabling directors</a></H3>
+<H3><a name="Php_nn3_1">32.3.1 Enabling directors</a></H3>
 
 
 <p>
@@ -989,8 +1052,6 @@
 
 <div class="targetlang">
 <pre>
-require("mymodule.php");
-
 class MyFoo extends Foo {
   function one() {
     print "one from php\n";
@@ -1000,7 +1061,7 @@
 </div>
 
 
-<H3><a name="Php_nn3_2">31.3.2 Director classes</a></H3>
+<H3><a name="Php_nn3_2">32.3.2 Director classes</a></H3>
 
 
  
@@ -1012,8 +1073,8 @@
 <tt>Swig::Director</tt> class. These new classes, referred to as director
 classes, can be loosely thought of as the C++ equivalent of the PHP
 proxy classes. The director classes store a pointer to their underlying
-PHP object.  Indeed, this is quite similar to the "_cPtr" and "thisown"
-members of the PHP proxy classes.
+PHP object.  Indeed, this is quite similar to <tt>struct swig_object_wrapper</tt>
+which is used to implement the PHP proxy classes.
 </p>
 
 <p>
@@ -1068,12 +1129,12 @@
 <p>
 One more point needs to be made about the relationship between director
 classes and proxy classes. When a proxy class instance is created in
-PHP, SWIG creates an instance of the original C++ class and assigns it
-to <tt>-&gt;_cPtr</tt>. This is exactly what happens without directors
-and is true even if directors are enabled for the particular class in
-question. When a class <i>derived</i> from a proxy class is created,
-however, SWIG then creates an instance of the corresponding C++ director
-class. The reason for this difference is that user-defined subclasses
+PHP, SWIG creates an instance of the original C++ class and stores it
+in the <tt>struct swig_object_wrapper</tt>. This is true whether or not
+directors are enabled for the particular class in question. However
+when a class <i>derived</i> from a proxy class is created, SWIG instead
+creates an instance of the corresponding C++ director class.
+The reason for this difference is that user-defined subclasses
 may override or extend methods of the original class, so the director
 class is needed to route calls to these methods correctly. For
 unmodified proxy classes, all methods are ultimately implemented in C++
@@ -1081,7 +1142,7 @@
 calls through PHP.
 </p>
 
-<H3><a name="Php_nn3_3">31.3.3 Ownership and object destruction</a></H3>
+<H3><a name="Php_nn3_3">32.3.3 Ownership and object destruction</a></H3>
 
 
 <p>
@@ -1137,7 +1198,7 @@
 deleting all the Foo pointers it contains at some point.
 </p>
 
-<H3><a name="Php_nn3_4">31.3.4 Exception unrolling</a></H3>
+<H3><a name="Php_nn3_4">32.3.4 Exception unrolling</a></H3>
 
 
 <p>
@@ -1161,7 +1222,12 @@
 <div class="code">
 <pre>
 %feature("director:except") {
-  if ($error == FAILURE) {
+#if SWIG_VERSION &gt;= 0x040100
+  if ($error != NULL)
+#else
+  if ($error == FAILURE)
+#endif
+  {
     throw Swig::DirectorMethodException();
   }
 }
@@ -1169,6 +1235,20 @@
 </div>
 
 <p>
+If you only need to support SWIG &gt;= 4.1.0, you can just use the
+<tt>($error != NULL)</tt> condition.
+</p>
+
+<p>
+In SWIG 4.1.0, <tt>$error</tt> was changed in the SWIG/PHP director
+implementation to make it work more like how it does for other languages.
+Previously, <tt>$error</tt> didn't actually indicate an exception, but instead
+was only set to <tt>FAILURE</tt> if there was a problem calling the PHP method.
+Now <tt>$error</tt> indicates if the PHP method threw a PHP exception, and
+directorout typemaps for PHP no longer need to be gated by <tt>if (EG(exception))</tt>.
+</p>
+
+<p>
 This code will check the PHP error state after each method call from a
 director into PHP, and throw a C++ exception if an error occurred.  This
 exception can be caught in C++ to implement an error handler.
@@ -1204,7 +1284,7 @@
 as soon as the C wrapper function returns.
 </p>
 
-<H3><a name="Php_nn3_5">31.3.5 Overhead and code bloat</a></H3>
+<H3><a name="Php_nn3_5">32.3.5 Overhead and code bloat</a></H3>
 
 
 <p>
@@ -1237,7 +1317,7 @@
 directive) for only those methods that are likely to be extended in PHP.
 </p>
 
-<H3><a name="Php_nn3_6">31.3.6 Typemaps</a></H3>
+<H3><a name="Php_nn3_6">32.3.6 Typemaps</a></H3>
 
 
 <p>
@@ -1251,7 +1331,7 @@
 </p>
 
 
-<H3><a name="Php_nn3_7">31.3.7 Miscellaneous</a></H3>
+<H3><a name="Php_nn3_7">32.3.7 Miscellaneous</a></H3>
 
 
 <p> Director typemaps for STL classes are mostly in place, and hence you
diff --git a/Doc/Manual/Pike.html b/Doc/Manual/Pike.html
deleted file mode 100644
index 2b84323..0000000
--- a/Doc/Manual/Pike.html
+++ /dev/null
@@ -1,246 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
-<html>
-<head>
-<title>SWIG and Pike</title>
-<link rel="stylesheet" type="text/css" href="style.css">
-<meta http-equiv="content-type" content="text/html; charset=UTF-8">
-</head>
-
-<body bgcolor="#ffffff">
-<H1><a name="Pike">37 SWIG and Pike</a></H1>
-<!-- INDEX -->
-<div class="sectiontoc">
-<ul>
-<li><a href="#Pike_nn2">Preliminaries</a>
-<ul>
-<li><a href="#Pike_nn3">Running SWIG</a>
-<li><a href="#Pike_nn4">Getting the right header files</a>
-<li><a href="#Pike_nn5">Using your module</a>
-</ul>
-<li><a href="#Pike_nn6">Basic C/C++ Mapping</a>
-<ul>
-<li><a href="#Pike_nn7">Modules</a>
-<li><a href="#Pike_nn8">Functions</a>
-<li><a href="#Pike_nn9">Global variables</a>
-<li><a href="#Pike_nn10">Constants and enumerated types</a>
-<li><a href="#Pike_nn11">Constructors and Destructors</a>
-<li><a href="#Pike_nn12">Static Members</a>
-</ul>
-</ul>
-</div>
-<!-- INDEX -->
-
-
-
-<p>
-This chapter describes SWIG support for Pike. As of this writing, the
-SWIG  Pike module is still under development and is not considered
-ready for prime  time. The Pike module is being developed against the
-Pike 7.4.10 release  and may not be compatible with previous versions
-of Pike.
-</p>
-
-<p>
-This chapter covers most SWIG features, but certain low-level details
-are  covered in less depth than in earlier chapters.  At the very
-least, make sure you read the "<a href="SWIG.html#SWIG">SWIG Basics</a>"
-chapter.<br>
-</p>
-
-<H2><a name="Pike_nn2">37.1 Preliminaries</a></H2>
-
-
-<H3><a name="Pike_nn3">37.1.1 Running SWIG</a></H3>
-
-
-<p>
-Suppose that you defined a SWIG module such as the following:
-</p>
-
-<div class="code">
-  <pre>%module example<br><br>%{<br>#include "example.h"<br>%}<br><br>int fact(int n);<br></pre>
-</div>
-
-<p>
-To build a C extension module for Pike, run SWIG using the <tt>-pike</tt> option :
-</p>
-
-<div class="code">
-  <pre>$ <b>swig -pike example.i</b><br></pre>
-</div>
-
-<p>
-If you're building a C++ extension, be sure to add the <tt>-c++</tt> option:
-</p>
-
-<div class="code">
-  <pre>$ <b>swig -c++ -pike example.i</b><br></pre>
-</div>
-
-<p>
-This creates a single source file named <tt>example_wrap.c</tt> (or <tt>example_wrap.cxx</tt>, if you
-ran SWIG with the <tt>-c++</tt> option).
-The SWIG-generated source file contains the low-level wrappers that need
-to be compiled and linked with the rest of your C/C++ application to
-create an extension module.
-</p>
-
-<p>
-The name of the wrapper file is derived from the name of the input
-file.  For example, if the input file is <tt>example.i</tt>, the name
-of the wrapper file is <tt>example_wrap.c</tt>. To change this, you
-can use the <tt>-o</tt> option:
-</p>
-
-<div class="code">
-  <pre>$ <b>swig -pike -o pseudonym.c example.i</b><br></pre>
-</div>
-<H3><a name="Pike_nn4">37.1.2 Getting the right header files</a></H3>
-
-
-<p>
-In order to compile the C/C++ wrappers, the compiler needs to know the
-path to the Pike header files. These files are usually contained in a
-directory such as
-</p>
-
-<div class="code">
-  <pre>/usr/local/pike/7.4.10/include/pike<br></pre>
-</div>
-
-<p>
-There doesn't seem to be any way to get Pike itself to reveal the
-location of these files, so you may need to hunt around for them.
-You're looking for files with the names <tt>global.h</tt>, <tt>program.h</tt>
-and so on.
-</p>
-
-<H3><a name="Pike_nn5">37.1.3 Using your module</a></H3>
-
-
-<p>
-To use your module, simply use Pike's <tt>import</tt> statement:
-</p>
-
-<div class="code"><pre>
-$ <b>pike</b>
-Pike v7.4 release 10 running Hilfe v3.5 (Incremental Pike Frontend)
-&gt; <b>import example;</b>
-&gt; <b>fact(4);</b>
-(1) Result: 24
-</pre></div>
-
-<H2><a name="Pike_nn6">37.2 Basic C/C++ Mapping</a></H2>
-
-
-<H3><a name="Pike_nn7">37.2.1 Modules</a></H3>
-
-
-<p>
-All of the code for a given SWIG module is wrapped into a single Pike
-module. Since the name of the shared library that implements your
-module ultimately determines the module's name (as far as Pike is
-concerned), SWIG's <tt>%module</tt> directive doesn't really have any
-significance.
-</p>
-
-<H3><a name="Pike_nn8">37.2.2 Functions</a></H3>
-
-
-<p>
-Global functions are wrapped as new Pike built-in functions. For
-example,
-</p>
-
-<div class="code"><pre>
-%module example
-
-int fact(int n);
-</pre></div>
-
-<p>
-creates a new built-in function <tt>example.fact(n)</tt> that works
-exactly as you'd expect it to:
-</p>
-
-<div class="code"><pre>
-&gt; <b>import example;</b>
-&gt; <b>fact(4);</b>
-(1) Result: 24
-</pre></div>
-
-<H3><a name="Pike_nn9">37.2.3 Global variables</a></H3>
-
-
-<p>
-Global variables are currently wrapped as a pair of functions, one to get
-the current value of the variable and another to set it. For example, the
-declaration
-</p>
-
-<div class="code"><pre>
-%module example
-
-double Foo;
-</pre></div>
-
-<p>
-will result in two functions, <tt>Foo_get()</tt> and <tt>Foo_set()</tt>:
-</p>
-
-<div class="code"><pre>
-&gt; <b>import example;</b>
-&gt; <b>Foo_get();</b>
-(1) Result: 3.000000
-&gt; <b>Foo_set(3.14159);</b>
-(2) Result: 0
-&gt; <b>Foo_get();</b>
-(3) Result: 3.141590
-</pre></div>
-
-<H3><a name="Pike_nn10">37.2.4 Constants and enumerated types</a></H3>
-
-
-<p>
-Enumerated types in C/C++ declarations are wrapped as Pike constants,
-not as Pike enums.
-</p>
-
-<H3><a name="Pike_nn11">37.2.5 Constructors and Destructors</a></H3>
-
-
-<p>
-Constructors are wrapped as <tt>create()</tt> methods, and destructors are
-wrapped as <tt>destroy()</tt> methods, for Pike classes.
-</p>
-
-<H3><a name="Pike_nn12">37.2.6 Static Members</a></H3>
-
-
-<p>
-Since Pike doesn't support static methods or data for Pike classes, static
-member functions in your C++ classes are wrapped as regular functions and
-static member variables are wrapped as pairs of functions (one to get the
-value of the static member variable, and another to set it). The names of
-these functions are prepended with the name of the class.
-For example, given this C++ class declaration:
-</p>
-
-<div class="code"><pre>
-class Shape
-{
-public:
-  static void print();
-  static int nshapes;
-};
-</pre></div>
-
-<p>
-SWIG will generate a <tt>Shape_print()</tt> method that invokes the static
-<tt>Shape::print()</tt> member function, as well as a pair of methods,
-<tt>Shape_nshapes_get()</tt> and <tt>Shape_nshapes_set()</tt>, to get and set
-the value of <tt>Shape::nshapes</tt>.
-</p>
-
-</body>
-</html>
diff --git a/Doc/Manual/Preface.html b/Doc/Manual/Preface.html
index 36a99bd..50a06d6 100644
--- a/Doc/Manual/Preface.html
+++ b/Doc/Manual/Preface.html
@@ -80,7 +80,7 @@
 <p>
 The LICENSE file shipped with SWIG in the top level directory contains the SWIG license.
 For further insight into the license including the license of SWIG's output code, please visit
-the SWIG legal page - <a href="http://www.swig.org/legal.html">http://www.swig.org/legal.html</a>.
+the SWIG legal page - <a href="https://www.swig.org/legal.html">https://www.swig.org/legal.html</a>.
 </p>
 
 <p>
@@ -98,7 +98,7 @@
 </p>
 
 <div class="shell"><pre>
-<a href="http://www.swig.org">http://www.swig.org</a>
+<a href="https://www.swig.org">https://www.swig.org</a>
 </pre></div>
 
 <p>
@@ -111,7 +111,7 @@
 </p>
 
 <div class="shell"><pre>
-<a href="http://www.swig.org/mail.html">http://www.swig.org/mail.html</a>
+<a href="https://www.swig.org/mail.html">https://www.swig.org/mail.html</a>
 </pre></div>
 
 <p>
@@ -125,7 +125,7 @@
 </p>
 
 <div class="shell"><pre>
-<a href="http://www.swig.org/svn.html">SWIG Bleeding Edge</a>
+<a href="https://www.swig.org/svn.html">SWIG Bleeding Edge</a>
 </pre></div>
 
 
@@ -231,7 +231,7 @@
 SWIG is an unfunded project that would not be possible without the
 contributions of many people working in their spare time. 
 If you have benefitted from using SWIG, please consider
-<a href="http://www.swig.org/donate.html">Donating to SWIG</a> to keep development going.
+<a href="https://www.swig.org/donate.html">Donating to SWIG</a> to keep development going.
 There have been a large varied number of people
 who have made contributions at all levels over time. Contributors
 are mentioned either in the COPYRIGHT file or CHANGES files shipped with SWIG or in submitted bugs.
@@ -244,8 +244,8 @@
 Although every attempt has been made to make SWIG bug-free, we are also trying
 to make feature improvements that may introduce bugs.
 To report a bug, either send mail to the SWIG developer
-list at the <a href="http://www.swig.org/mail.html">swig-devel mailing list</a> or report a bug
-at the <a href="http://www.swig.org/bugs.html">SWIG bug tracker</a>. In your report, be as specific as
+list at the <a href="https://www.swig.org/mail.html">swig-devel mailing list</a> or report a bug
+at the <a href="https://www.swig.org/bugs.html">SWIG bug tracker</a>. In your report, be as specific as
 possible, including (if applicable), error messages, tracebacks (if a
 core dump occurred), corresponding portions of the SWIG interface file
 used, and any important pieces of the SWIG generated wrapper code.  We
@@ -273,20 +273,20 @@
 These installation instructions are for using the distributed tarball,
 for example, <tt>swig-3.0.8.tar.gz</tt>.
 If you wish to build and install from source on Github, extra steps are required.
-Please see the <a href="http://swig.org/svn.html">Bleeding Edge</a> page on the SWIG website.
+Please see the <a href="https://swig.org/svn.html">Bleeding Edge</a> page on the SWIG website.
 </p>
 
 <p>
-You must use <a href="http://www.gnu.org/software/make/">GNU make</a> to build and install SWIG.
+You must use <a href="https://www.gnu.org/software/make/">GNU make</a> to build and install SWIG.
 </p>
 
 <p>
-<a href="http://www.pcre.org/">PCRE</a>
+<a href="https://www.pcre.org/">PCRE2</a>
 needs to be installed on your system to build SWIG, in particular
-pcre-config must be available. If you have PCRE headers and libraries but not
-pcre-config itself or, alternatively, wish to override the compiler or linker
-flags returned by pcre-config, you may set PCRE_LIBS and PCRE_CFLAGS variables
-to be used instead. And if you don't have PCRE at all, the configure script
+pcre2-config must be available. If you have PCRE2 headers and libraries but not
+pcre2-config itself or, alternatively, wish to override the compiler or linker
+flags returned by pcre2-config, you may set PCRE2_LIBS and PCRE2_CFLAGS variables
+to be used instead. And if you don't have PCRE2 at all, the configure script
 will provide instructions for obtaining it.
 </p>
 
@@ -357,7 +357,7 @@
 If you checked the code out via Git, you will have to run <tt>./autogen.sh</tt>
 before <tt>./configure</tt>.  In addition, a full build of SWIG requires
 a number of packages to be installed.  Full instructions at
-<a href="http://www.swig.org/svn.html">SWIG bleeding edge</a>.
+<a href="https://www.swig.org/svn.html">SWIG bleeding edge</a>.
 </li>
 </ul>
 
diff --git a/Doc/Manual/Preprocessor.html b/Doc/Manual/Preprocessor.html
index 3d1bb45..e4d4425 100644
--- a/Doc/Manual/Preprocessor.html
+++ b/Doc/Manual/Preprocessor.html
@@ -7,7 +7,7 @@
 </head>
 
 <body bgcolor="#ffffff">
-<H1><a name="Preprocessor">10 Preprocessing</a></H1>
+<H1><a name="Preprocessor">11 Preprocessing</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -38,7 +38,7 @@
 chapter describes some of these modifications.
 </p>
 
-<H2><a name="Preprocessor_nn2">10.1 File inclusion</a></H2>
+<H2><a name="Preprocessor_nn2">11.1 File inclusion</a></H2>
 
 
 <p>
@@ -48,7 +48,7 @@
 
 <div class="code">
 <pre>
-%include "pointer.i"
+%include "cpointer.i"
 </pre>
 </div>
 
@@ -64,7 +64,7 @@
 is that you often don't want SWIG to try and wrap everything included
 in standard header system headers and auxiliary files.
 
-<H2><a name="Preprocessor_nn3">10.2 File imports</a></H2>
+<H2><a name="Preprocessor_nn3">11.2 File imports</a></H2>
 
 
 <p>
@@ -93,14 +93,29 @@
 as imports.    This might be useful if you want to extract type definitions from system 
 header files without generating any wrappers.
 
-<H2><a name="Preprocessor_condition_compilation">10.3 Conditional Compilation</a></H2>
+<H2><a name="Preprocessor_condition_compilation">11.3 Conditional Compilation</a></H2>
 
 
 <p>
 SWIG fully supports the use of <tt>#if</tt>, <tt>#ifdef</tt>,
 <tt>#ifndef</tt>, <tt>#else</tt>, <tt>#endif</tt> to conditionally
-include parts of an interface.  The following symbols are predefined
-by SWIG when it is parsing the interface:
+include parts of an interface.
+</p>
+
+<p>
+SWIG's preprocessor conditionals support the standard C/C++ preprocessor
+integer expressions.  As a SWIG-specific extension, string equality and
+inequality tests are also supported, for example:
+</p>
+
+<div class="code">
+<pre>
+#if defined __cplusplus &amp;&amp; (#__VA_ARGS__ != "" || #TYPE == "void")
+</pre>
+</div>
+
+<p>
+The following symbols are predefined by SWIG when it is parsing the interface:
 </p>
 
 <div class="code"><pre>
@@ -110,18 +125,21 @@
                                 such as 0x010311 (corresponding to SWIG-1.3.11).
 
 SWIGCSHARP                      Defined when using C#
+SWIGD                           Defined when using D
+SWIGGO                          Defined when using Go
 SWIGGUILE                       Defined when using Guile
 SWIGJAVA                        Defined when using Java
 SWIGJAVASCRIPT                  Defined when using Javascript
-SWIG_JAVASCRIPT_JSC             Defined when using Javascript for JavascriptCore
-SWIG_JAVASCRIPT_V8              Defined when using Javascript for v8 or node.js 
+SWIG_JAVASCRIPT_JSC             Defined when using Javascript with -jsc
+SWIG_JAVASCRIPT_V8              Defined when using Javascript with -v8 or -node
+SWIG_JAVASCRIPT_NAPI            Defined when using Javascript with -napi
 SWIGLUA                         Defined when using Lua
 SWIGMZSCHEME                    Defined when using Mzscheme
 SWIGOCAML                       Defined when using OCaml
 SWIGOCTAVE                      Defined when using Octave
 SWIGPERL                        Defined when using Perl
 SWIGPHP                         Defined when using PHP (any version)
-SWIGPHP7                        Defined when using PHP7
+SWIGPHP7                        Defined when using PHP 7 or later (with a compatible C API)
 SWIGPYTHON                      Defined when using Python
 SWIGR                           Defined when using R
 SWIGRUBY                        Defined when using Ruby
@@ -131,6 +149,14 @@
 </pre></div>
 
 <p>
+SWIG also defines <tt>SWIG_VERSION</tt> and a target language macro in
+the generated wrapper file (since SWIG 4.1.0 - in older versions these
+were defined for some target languages but this wasn't consistent).  Best
+practice is to use SWIG-time conditional checks because that results in smaller
+generated wrapper sources.
+</p>
+
+<p>
 In addition, SWIG defines the following set of standard C/C++ macros:
 </p>
 
@@ -138,20 +164,64 @@
 <pre>
 __LINE__                        Current line number
 __FILE__                        Current file name
-__STDC__                        Defined to indicate ISO C
-__cplusplus                     Defined when -c++ option used
+__STDC__                        Defined to indicate ISO C/C++
+__cplusplus                     Defined when -c++ option used, value controlled by <tt>-std=c++NN</tt>
+__STDC_VERSION__                May be defined when -c++ option is not used, value controlled by <tt>-std=cNN</tt>
 </pre>
 </div>
 
 <p>
-Interface files can look at these symbols as necessary to change the
-way in which an interface is generated or to mix SWIG directives with
-C code. These symbols are also defined within the C code generated by
-SWIG (except for the symbol `<tt>SWIG</tt>' which is only defined
-within the SWIG compiler).
+Since SWIG 4.2.0, <tt>__STDC__</tt> is defined to <tt>1</tt> to match
+the behaviour of ISO C/C++ compilers.  Before this SWIG defined it to
+have an empty value.
 </p>
 
-<H2><a name="Preprocessor_nn5">10.4 Macro Expansion</a></H2>
+<p>
+Since SWIG 4.2.0, <tt>__cplusplus</tt> is defined to <tt>199711L</tt>
+(the value for C++98) by default. Before this SWIG always defined it to have
+the <b>value</b> <tt>__cplusplus</tt>.
+</p>
+
+<p>
+Since SWIG 4.2.0, SWIG supports command line options <tt>-std=cNN</tt> and
+<tt>-std=c++NN</tt> to specify the C/C++ standards version.  The only effect of
+these options is to set appropriate values for <tt>__STDC_VERSION__</tt> and
+<tt>__cplusplus</tt> respectively, which is useful if you're wrapping
+headers which have preprocessor checks based on their values.
+</p>
+
+<p>
+If your code requires these macros to be set to a version of the standard
+that is not a final official version, or one that SWIG is not yet aware of,
+you can simply redefine the appropriate macro to an alternative value at the
+top of your interface file, for example:
+</p>
+
+<div class="code"><pre>
+#undef __cplusplus
+#define __cplusplus 202211L
+</pre></div>
+
+<p>
+The following are language specific symbols that might be defined:
+</p>
+
+<div class="code"><pre>
+SWIG_D_VERSION                  Unsigned integer target version when using D
+SWIGGO_CGO                      Defined when using Go for cgo
+SWIGGO_GCCGO                    Defined when using Go for gccgo
+SWIGGO_INTGO_SIZE               Size of the Go type int when using Go (32 or 64)
+SWIGPYTHON_BUILTIN              Defined when using Python with -builtin
+SWIG_RUBY_AUTORENAME            Defined when using Ruby with -autorename
+</pre></div>
+
+<p>
+Interface files can look at these symbols as necessary to change the
+way in which an interface is generated or to mix SWIG directives with
+C code.
+</p>
+
+<H2><a name="Preprocessor_nn5">11.4 Macro Expansion</a></H2>
 
 
 <p>
@@ -161,15 +231,15 @@
 
 <div class="code">
 <pre>
-#ifndef _FOO_H 1
-#define _FOO_H 1
+#ifndef FOO_H 1
+#define FOO_H 1
 ...
 #endif
 </pre>
 </div>
 
 <p>
-you may get some extra constants such as <tt>_FOO_H</tt> showing up in the scripting interface.
+you may get some extra constants such as <tt>FOO_H</tt> showing up in the scripting interface.
 </p>
 
 <p>
@@ -206,7 +276,7 @@
 </li>
 </ul>
 
-<H2><a name="Preprocessor_nn6">10.5 SWIG Macros</a></H2>
+<H2><a name="Preprocessor_nn6">11.5 SWIG Macros</a></H2>
 
 
 <p>
@@ -252,7 +322,7 @@
 support).
 </p>
 
-<H2><a name="Preprocessor_nn7">10.6 C99 and GNU Extensions</a></H2>
+<H2><a name="Preprocessor_nn7">11.6 C99 and GNU Extensions</a></H2>
 
 
 <p>
@@ -308,14 +378,14 @@
 SWIG directives and are provided to make SWIG more compatible with C99 code.
 </p>
 
-<H2><a name="Preprocessor_delimiters">10.7 Preprocessing and delimiters</a></H2>
+<H2><a name="Preprocessor_delimiters">11.7 Preprocessing and delimiters</a></H2>
 
 
 <p>
 The preprocessor handles { }, " " and %{ %} delimiters differently.
 </p>
 
-<H3><a name="Preprocessor_nn8">10.7.1 Preprocessing and %{ ... %} &amp; " ... " delimiters</a></H3>
+<H3><a name="Preprocessor_nn8">11.7.1 Preprocessing and %{ ... %} &amp; " ... " delimiters</a></H3>
 
 
 <p>
@@ -340,7 +410,7 @@
 modification to the output (including all preprocessor directives).
 </p>
 
-<H3><a name="Preprocessor_nn9">10.7.2 Preprocessing and { ... } delimiters</a></H3>
+<H3><a name="Preprocessor_nn9">11.7.2 Preprocessing and { ... } delimiters</a></H3>
 
 
 <p>
@@ -382,7 +452,7 @@
 SWIG will strip the extra <tt>%</tt> and leave the preprocessor directive in the code.
 </p>
 
-<H2><a name="Preprocessor_typemap_delimiters">10.8 Preprocessor and Typemaps</a></H2>
+<H2><a name="Preprocessor_typemap_delimiters">11.8 Preprocessor and Typemaps</a></H2>
 
 
 <p>
@@ -453,7 +523,7 @@
 </div>
 
 
-<H2><a name="Preprocessor_nn10">10.9 Viewing preprocessor output</a></H2>
+<H2><a name="Preprocessor_nn10">11.9 Viewing preprocessor output</a></H2>
 
 
 <p>
@@ -463,7 +533,7 @@
 This might be useful as an aid to debugging and viewing the results of macro expansions.
 </p>
 
-<H2><a name="Preprocessor_warning_error">10.10 The #error and #warning directives</a></H2>
+<H2><a name="Preprocessor_warning_error">11.10 The #error and #warning directives</a></H2>
 
 
 <p>
diff --git a/Doc/Manual/Python.html b/Doc/Manual/Python.html
index ee443be..6246d7b 100644
--- a/Doc/Manual/Python.html
+++ b/Doc/Manual/Python.html
@@ -7,7 +7,7 @@
 </head>
 
 <body bgcolor="#ffffff">
-<H1><a name="Python">32 SWIG and Python</a></H1>
+<H1><a name="Python">33 SWIG and Python</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -65,6 +65,7 @@
 <li><a href="#Python_nn37">Overhead and code bloat</a>
 <li><a href="#Python_nn38">Typemaps</a>
 <li><a href="#Python_nn39">Miscellaneous</a>
+<li><a href="#Python_stable_abi">Stable ABI</a>
 </ul>
 <li><a href="#Python_nn40">Common customization features</a>
 <ul>
@@ -94,7 +95,7 @@
 </ul>
 <li><a href="#Python_nn58">Typemap Examples</a>
 <ul>
-<li><a href="#Python_nn59">Converting  Python list to a char ** </a>
+<li><a href="#Python_nn59">Converting a Python list to a char ** </a>
 <li><a href="#Python_nn60">Expanding a Python object into multiple arguments</a>
 <li><a href="#Python_nn61">Using typemaps to return arguments</a>
 <li><a href="#Python_nn62">Mapping Python tuples into small arrays</a>
@@ -114,6 +115,7 @@
 <li><a href="#Python_nn70">%feature("autodoc", "docstring")</a>
 </ul>
 <li><a href="#Python_nn71">%feature("docstring")</a>
+<li><a href="#Python_doxygen_docstrings">Doxygen comments</a>
 </ul>
 <li><a href="#Python_nn72">Python Packages</a>
 <ul>
@@ -133,7 +135,10 @@
 </ul>
 <li><a href="#Python_python3support">Python 3 Support</a>
 <ul>
-<li><a href="#Python_nn74">Function annotation</a>
+<li><a href="#Python_annotations">Python function annotations and variable annotations</a>
+<ul>
+<li><a href="#Python_annotations_c">C/C++ annotation types</a>
+</ul>
 <li><a href="#Python_nn75">Buffer interface</a>
 <li><a href="#Python_nn76">Abstract base classes</a>
 <li><a href="#Python_nn77">Byte string output conversion</a>
@@ -151,14 +156,9 @@
 
 
 <p>
-<b>Caution: This chapter is under repair!</b>
-</p>
-
-<p>
 This chapter describes SWIG's support of Python.  SWIG is compatible
-with all recent Python versions (Python 2.7 and Python &gt;= 3.2).  If you
-still need to generate bindings which work with older versions of Python,
-you'll have to use SWIG 3.0.x.
+with all recent Python versions (Python 2.7 and Python &gt;= 3.3).  SWIG 4.0.x
+supported Python 3.2.  SWIG 3.0.x supported older Python 2.x and 3.x.
 </p>
 
 <p>
@@ -168,7 +168,7 @@
 Basics</a>" chapter.
 </p>
 
-<H2><a name="Python_nn2">32.1 Overview</a></H2>
+<H2><a name="Python_nn2">33.1 Overview</a></H2>
 
 
 <p>
@@ -195,10 +195,10 @@
 details.
 </p>
 
-<H2><a name="Python_nn3">32.2 Preliminaries</a></H2>
+<H2><a name="Python_nn3">33.2 Preliminaries</a></H2>
 
 
-<H3><a name="Python_nn4">32.2.1 Running SWIG</a></H3>
+<H3><a name="Python_nn4">33.2.1 Running SWIG</a></H3>
 
 
 <p>
@@ -295,7 +295,7 @@
 how you might go about compiling and using the generated files.
 </p>
 
-<H3><a name="Python_nn6">32.2.2 Using distutils</a></H3>
+<H3><a name="Python_nn6">33.2.2 Using distutils</a></H3>
 
 
 <p>
@@ -387,7 +387,7 @@
 can even build extensions to the standard Windows Python using MingGW)
 </p>
 
-<H3><a name="Python_nn7">32.2.3 Hand compiling a dynamic module</a></H3>
+<H3><a name="Python_nn7">33.2.3 Hand compiling a dynamic module</a></H3>
 
 
 <p>
@@ -435,7 +435,7 @@
 </p>
 
 
-<H3><a name="Python_nn8">32.2.4 Static linking</a></H3>
+<H3><a name="Python_nn8">33.2.4 Static linking</a></H3>
 
 
 <p>
@@ -514,7 +514,7 @@
 (perhaps using distutils).
 </p>
 
-<H3><a name="Python_nn9">32.2.5 Using your module</a></H3>
+<H3><a name="Python_nn9">33.2.5 Using your module</a></H3>
 
 
 <p>
@@ -671,7 +671,7 @@
 read the man pages).
 </p>
 
-<H3><a name="Python_nn10">32.2.6 Compilation of C++ extensions</a></H3>
+<H3><a name="Python_nn10">33.2.6 Compilation of C++ extensions</a></H3>
 
 
 <p>
@@ -763,7 +763,7 @@
 might want to investigate using a more formal standard such as COM.
 </p>
 
-<H3><a name="Python_nn11">32.2.7 Compiling for 64-bit platforms</a></H3>
+<H3><a name="Python_nn11">33.2.7 Compiling for 64-bit platforms</a></H3>
 
 
 <p>
@@ -800,7 +800,7 @@
 extension.
 </p>
 
-<H3><a name="Python_nn12">32.2.8 Building Python extensions under Windows</a></H3>
+<H3><a name="Python_nn12">33.2.8 Building Python extensions under Windows</a></H3>
 
 
 <p>
@@ -930,7 +930,7 @@
 </p>
 
 
-<H3><a name="Python_commandline">32.2.9 Additional Python commandline options</a></H3>
+<H3><a name="Python_commandline">33.2.9 Additional Python commandline options</a></H3>
 
 
 <p>
@@ -954,6 +954,7 @@
 <tr><td>-doxygen        </td><td>Convert C++ doxygen comments to pydoc comments in proxy classes</td></tr>
 <tr><td>-extranative    </td><td>Return extra native wrappers for C++ std containers wherever possible</td></tr>
 <tr><td>-fastproxy      </td><td>Use fast proxy mechanism for member methods</td></tr>
+<tr><td>-flatstaticmethod </td><td>Generate additional flattened Python methods for C++ static methods</td></tr>
 <tr><td>-globals &lt;name&gt; </td><td>Set &lt;name&gt; used to access C global variable (default: 'cvar')</td></tr>
 <tr><td>-interface &lt;mod&gt;</td><td>Set low-level C/C++ module name to &lt;mod&gt; (default: module name prefixed by '_')</td></tr>
 <tr><td>-keyword        </td><td>Use keyword arguments</td></tr>
@@ -963,7 +964,6 @@
 <tr><td>-nortti         </td><td>Disable the use of the native C++ RTTI with directors</td></tr>
 <tr><td>-nothreads      </td><td>Disable thread support for the entire interface</td></tr>
 <tr><td>-olddefs        </td><td>Keep the old method definitions when using -fastproxy</td></tr>
-<tr><td>-py3            </td><td>Generate code with Python 3 specific features and syntax</td></tr>
 <tr><td>-relativeimport </td><td>Use relative Python imports</td></tr>
 <tr><td>-threads        </td><td>Add thread support for all the interface</td></tr>
 <tr><td>-O              </td><td>Enable the following optimization options: -fastdispatch -fastproxy -fvirtual</td></tr>
@@ -974,7 +974,7 @@
 Many of these options are covered later on and their use should become clearer by the time you have finished reading this section on SWIG and Python.
 </p>
 
-<H2><a name="Python_nn13">32.3 A tour of basic C/C++ wrapping</a></H2>
+<H2><a name="Python_nn13">33.3 A tour of basic C/C++ wrapping</a></H2>
 
 
 <p>
@@ -983,7 +983,7 @@
 This section briefly covers the essential aspects of this wrapping.
 </p>
 
-<H3><a name="Python_nn14">32.3.1 Modules</a></H3>
+<H3><a name="Python_nn14">33.3.1 Modules</a></H3>
 
 
 <p>
@@ -996,7 +996,7 @@
 Python command or standard module name.
 </p>
 
-<H3><a name="Python_nn15">32.3.2 Functions</a></H3>
+<H3><a name="Python_nn15">33.3.2 Functions</a></H3>
 
 
 <p>
@@ -1020,7 +1020,7 @@
 &gt;&gt;&gt;
 </pre></div>
 
-<H3><a name="Python_nn16">32.3.3 Global variables</a></H3>
+<H3><a name="Python_nn16">33.3.3 Global variables</a></H3>
 
 
 <p>
@@ -1158,7 +1158,7 @@
 if there are no global variables in a module.
 </p>
 
-<H3><a name="Python_nn17">32.3.4 Constants and enums</a></H3>
+<H3><a name="Python_nn17">33.3.4 Constants and enums</a></H3>
 
 
 <p>
@@ -1198,7 +1198,7 @@
 generate code that prevents this.  You will just have to be careful.
 </p>
 
-<H3><a name="Python_nn18">32.3.5 Pointers</a></H3>
+<H3><a name="Python_nn18">33.3.5 Pointers</a></H3>
 
 
 <p>
@@ -1339,7 +1339,7 @@
 <tt>None</tt> if the conversion can't be performed.
 </p>
 
-<H3><a name="Python_nn19">32.3.6 Structures</a></H3>
+<H3><a name="Python_nn19">33.3.6 Structures</a></H3>
 
 
 <p>
@@ -1549,7 +1549,7 @@
 </p>
 
 
-<H3><a name="Python_nn20">32.3.7 C++ classes</a></H3>
+<H3><a name="Python_nn20">33.3.7 C++ classes</a></H3>
 
 
 <p>
@@ -1608,36 +1608,52 @@
 </div>
 
 <p>
-In Python, the static member can be access in three different ways:
+In Python, the static member can be accessed in three different ways:
 </p>
 
 <div class="targetlang">
 <pre>
-&gt;&gt;&gt; example.Spam_foo()    # Spam::foo()
 &gt;&gt;&gt; s = example.Spam()
 &gt;&gt;&gt; s.foo()               # Spam::foo() via an instance
-&gt;&gt;&gt; example.Spam.foo()    # Spam::foo(). Python-2.2 only
+&gt;&gt;&gt; example.Spam.foo()    # Spam::foo() using class method
+&gt;&gt;&gt; example.Spam_foo()    # Spam::foo() "flattened" name
 </pre>
 </div>
 
 <p>
-The first two methods of access are supported in all versions of Python.  The
-last technique is only available in Python-2.2 and later versions.
+The last technique is only available when using the <tt>-flatstaticmethod</tt> option.
+This option is not recommended, it is only available for backwards compatibility
+as ancient versions of Python did not have Python class methods.
 </p>
 
 <p>
 Static member variables are currently accessed as global variables.  This means,
-they are accessed through <tt>cvar</tt> like this:
+they are accessed through <tt>cvar</tt> or via an instance property:
 </p>
 
 <div class="targetlang">
 <pre>
-&gt;&gt;&gt; print example.cvar.Spam_bar
+&gt;&gt;&gt; example.cvar.Spam_bar # Spam::bar
+7
+&gt;&gt;&gt; s = example.Spam()
+&gt;&gt;&gt; s.bar                 # Spam::bar via an instance property
 7
 </pre>
 </div>
 
-<H3><a name="Python_nn21">32.3.8 C++ inheritance</a></H3>
+<p>
+The <tt>-builtin</tt> option uses a metaclass to additionally provide access as follows:
+</p>
+
+<div class="targetlang">
+<pre>
+&gt;&gt;&gt; example.Spam.bar      # Spam::bar using -builtin option only
+7
+</pre>
+</div>
+
+
+<H3><a name="Python_nn21">33.3.8 C++ inheritance</a></H3>
 
 
 <p>
@@ -1692,7 +1708,7 @@
 It is safe to use multiple inheritance with SWIG.
 </p>
 
-<H3><a name="Python_nn22">32.3.9 Pointers, references, values, and arrays</a></H3>
+<H3><a name="Python_nn22">33.3.9 Pointers, references, values, and arrays</a></H3>
 
 
 <p>
@@ -1753,7 +1769,7 @@
 allocation/deallocation process.
 </p>
 
-<H3><a name="Python_nn23">32.3.10 C++ overloaded functions</a></H3>
+<H3><a name="Python_nn23">33.3.10 C++ overloaded functions</a></H3>
 
 
 <p>
@@ -1876,7 +1892,7 @@
 Please refer to the "SWIG and C++" chapter for more information about overloading.
 </p>
 
-<H3><a name="Python_nn24">32.3.11 C++ operators</a></H3>
+<H3><a name="Python_nn24">33.3.11 C++ operators</a></H3>
 
 
 <p>
@@ -1968,12 +1984,12 @@
 <p>
 Operator overloading is implemented in the <tt>pyopers.swg</tt> library file.
 In particular overloaded operators are marked with the <tt>python:maybecall</tt> feature, also known as <tt>%pythonmaybecall</tt>.
-This feature forces SWIG to generate code that return an instance of Python's <tt>NotImplemented</tt>
-instead of raising an exception when the comparison fails, that is, on any kind of error.
+This feature forces SWIG to generate code that returns an instance of Python's <tt>NotImplemented</tt>
+instead of raising the usual <tt>TypeError</tt> exception when an incorrect type is passed to a SWIG wrapped method.
 This follows the guidelines in <a href="https://www.python.org/dev/peps/pep-0207/">PEP 207 - Rich Comparisons</a> and <a href="https://docs.python.org/3/library/constants.html#NotImplemented">NotImplemented Python constant</a>.
 </p>
 
-<H3><a name="Python_nn25">32.3.12 C++ namespaces</a></H3>
+<H3><a name="Python_nn25">33.3.12 C++ namespaces</a></H3>
 
 
 <p>
@@ -2040,7 +2056,7 @@
 identical symbol names, well, then you get what you deserve.
 </p>
 
-<H3><a name="Python_nn26">32.3.13 C++ templates</a></H3>
+<H3><a name="Python_nn26">33.3.13 C++ templates</a></H3>
 
 
 <p>
@@ -2094,10 +2110,10 @@
 examples will appear later.
 </p>
 
-<H3><a name="Python_nn27">32.3.14 C++ Smart Pointers</a></H3>
+<H3><a name="Python_nn27">33.3.14 C++ Smart Pointers</a></H3>
 
 
-<H4><a name="Python_smart_pointers_shared_ptr">32.3.14.1 The shared_ptr Smart Pointer</a></H4>
+<H4><a name="Python_smart_pointers_shared_ptr">33.3.14.1 The shared_ptr Smart Pointer</a></H4>
 
 
 <p>
@@ -2108,7 +2124,7 @@
 </p>
 
 
-<H4><a name="Python_smart_pointers_generic">32.3.14.2 Generic Smart Pointers</a></H4>
+<H4><a name="Python_smart_pointers_generic">33.3.14.2 Generic Smart Pointers</a></H4>
 
 
 <p>
@@ -2192,7 +2208,7 @@
 </pre>
 </div>
 
-<H3><a name="Python_nn27a">32.3.15 C++ reference counted objects</a></H3>
+<H3><a name="Python_nn27a">33.3.15 C++ reference counted objects</a></H3>
 
 
 <p>
@@ -2201,7 +2217,7 @@
 </p>
 
 
-<H2><a name="Python_nn28">32.4 Further details on the Python class interface</a></H2>
+<H2><a name="Python_nn28">33.4 Further details on the Python class interface</a></H2>
 
 
 <p>
@@ -2224,7 +2240,7 @@
 section.
 </p>
 
-<H3><a name="Python_nn29">32.4.1 Proxy classes</a></H3>
+<H3><a name="Python_nn29">33.4.1 Proxy classes</a></H3>
 
 
 <p>
@@ -2313,7 +2329,7 @@
 by Python built-in types until Python 2.2).
 </p>
 
-<H3><a name="Python_builtin_types">32.4.2 Built-in Types</a></H3>
+<H3><a name="Python_builtin_types">33.4.2 Built-in Types</a></H3>
 
 
 <p>
@@ -2357,7 +2373,7 @@
 
 <p><a href="https://docs.python.org/3/extending/newtypes.html">https://docs.python.org/3/extending/newtypes.html</a></p>
 
-<H4><a name="Python_builtin_limitations">32.4.2.1 Limitations</a></H4>
+<H4><a name="Python_builtin_limitations">33.4.2.1 Limitations</a></H4>
 
 
 <p>Use of the <tt>-builtin</tt> option implies a couple of limitations:
@@ -2516,9 +2532,15 @@
 assert(issubclass(B.Derived, A.Base))
 </pre></div>
 </li>
+
+
+<li><p><a href="#Python_annotations">Python annotations</a> are not supported.
+</p>
+</li>
+
 </ul>
 
-<H4><a name="Python_builtin_overloads">32.4.2.2 Operator overloads and slots -- use them!</a></H4>
+<H4><a name="Python_builtin_overloads">33.4.2.2 Operator overloads and slots -- use them!</a></H4>
 
 
 <p>The entire justification for the <tt>-builtin</tt> option is improved
@@ -2568,7 +2590,7 @@
 (<tt>operator==, operator&lt;</tt>, etc.) are also converted to Python
 slot operators.  For a complete list of C++ operators that are
 automatically converted to Python slot operators, refer to the file
-<tt>python/pyopers.swig</tt> in the SWIG library.
+<tt>python/pyopers.swg</tt> in the SWIG library.
 </p>
 
 
@@ -2674,11 +2696,11 @@
 
 <p>
 There is further information on <tt>%feature("python:slot")</tt>
-in the file <tt>python/pyopers.swig</tt> in the SWIG library.
+in the file <tt>python/pyopers.swg</tt> in the SWIG library.
 </p>
 
 
-<H3><a name="Python_nn30">32.4.3 Memory management</a></H3>
+<H3><a name="Python_nn30">33.4.3 Memory management</a></H3>
 
 
 <p>NOTE: Although this section refers to proxy objects, everything here also applies
@@ -2873,7 +2895,7 @@
 typemaps--an advanced topic discussed later.
 </p>
 
-<H2><a name="Python_directors">32.5 Cross language polymorphism</a></H2>
+<H2><a name="Python_directors">33.5 Cross language polymorphism</a></H2>
 
 
 <p>
@@ -2907,7 +2929,7 @@
 all the cross-language method routing transparently.
 </p>
 
-<H3><a name="Python_nn33">32.5.1 Enabling directors</a></H3>
+<H3><a name="Python_nn33">33.5.1 Enabling directors</a></H3>
 
 
 <p>
@@ -2999,7 +3021,7 @@
 </div>
 
 
-<H3><a name="Python_nn34">32.5.2 Director classes</a></H3>
+<H3><a name="Python_nn34">33.5.2 Director classes</a></H3>
 
 
 <p>
@@ -3079,7 +3101,7 @@
 calls through Python.
 </p>
 
-<H3><a name="Python_nn35">32.5.3 Ownership and object destruction</a></H3>
+<H3><a name="Python_nn35">33.5.3 Ownership and object destruction</a></H3>
 
 
 <p>
@@ -3107,9 +3129,7 @@
 <p>
 To help ensure that no references to the Python object remain after
 calling <tt>__disown__()</tt>, this method returns a weak reference to
-the Python object. Weak references are only available in Python versions
-2.1 and higher, so for older versions you must explicitly delete all
-references. Here is an example:
+the Python object. Here is an example:
 </p>
 
 <div class="code">
@@ -3146,7 +3166,7 @@
 references to the Foo objects remain in Python.
 </p>
 
-<H3><a name="Python_nn36">32.5.4 Exception unrolling</a></H3>
+<H3><a name="Python_nn36">33.5.4 Exception unrolling</a></H3>
 
 
 <p>
@@ -3205,7 +3225,7 @@
 exception as soon as the C wrapper function returns.
 </p>
 
-<H3><a name="Python_nn37">32.5.5 Overhead and code bloat</a></H3>
+<H3><a name="Python_nn37">33.5.5 Overhead and code bloat</a></H3>
 
 
 <p>
@@ -3239,7 +3259,7 @@
 Python.
 </p>
 
-<H3><a name="Python_nn38">32.5.6 Typemaps</a></H3>
+<H3><a name="Python_nn38">33.5.6 Typemaps</a></H3>
 
 
 <p>
@@ -3253,7 +3273,7 @@
 </p>
 
 
-<H3><a name="Python_nn39">32.5.7 Miscellaneous</a></H3>
+<H3><a name="Python_nn39">33.5.7 Miscellaneous</a></H3>
 
 
 <p>
@@ -3299,8 +3319,42 @@
 methods that return const references.
 </p>
 
+<H3><a name="Python_stable_abi">33.5.8 Stable ABI</a></H3>
 
-<H2><a name="Python_nn40">32.6 Common customization features</a></H2>
+
+<p>
+By default, the version of Python used to compile the wrappers needs to be the same as that used during runtime.
+Alternatvely, the <a href="https://docs.python.org/3/c-api/stable.html">Python Stable ABI</a> enables a single compiled binary to be used by different versions of Python.
+This is enabled by defining <tt>Py_LIMITED_API</tt> during the compilation of the C/C++ wrapper code and setting this macro to a particular minimum version of Python that one wants to support.
+</p>
+
+<p>
+SWIG supports the stable ABI, but only version 3.4 of Python and later is supported.
+There are two recommended approaches for using SWIG and the stable ABI and both require setting the <tt>Py_LIMITED_API</tt> macro to be set to <tt>0x03040000</tt> as a minimum value (Python 3.4).
+Either set this using <tt>%begin</tt> by adding the following into your interface file so that this macro appears at the beginning of the generated C/C++ code:
+</p>
+
+<div class="code"><pre>
+%begin %{
+#define Py_LIMITED_API 0x03040000
+%}
+</pre></div>
+
+<p>
+or simply define the macro using your C/C++ compiler's <tt>-D</tt> command line option, for example, <tt>-DPy_LIMITED_API=0x03040000</tt>.
+</p>
+
+<p>
+The default SWIG command line options generate code that enable the limited API/stable ABI.
+Some options, such as <tt>-builtin</tt>, <tt>-fast</tt> (used by <tt>-O</tt>) do not use the limited API and hence when <tt>Py_LIMITED_API</tt> is defined there will be missing symbols during compilation.
+Compatibility of user's custom typemaps is of course dependent on the Python APIs used in the typemaps.
+</p>
+
+<p>
+<b>Compatibility Note:</b> Support for the stable ABI was added in SWIG-4.2.0.
+</p>
+
+<H2><a name="Python_nn40">33.6 Common customization features</a></H2>
 
 
 <p>
@@ -3313,7 +3367,7 @@
 improve your the interface to an extension module.
 </p>
 
-<H3><a name="Python_nn41">32.6.1 C/C++ helper functions</a></H3>
+<H3><a name="Python_nn41">33.6.1 C/C++ helper functions</a></H3>
 
 
 <p>
@@ -3394,7 +3448,7 @@
 customization features as covered in later sections.
 </p>
 
-<H3><a name="Python_nn42">32.6.2 Adding additional Python code</a></H3>
+<H3><a name="Python_nn42">33.6.2 Adding additional Python code</a></H3>
 
 
 <p>
@@ -3406,9 +3460,15 @@
 
 <div class="code">
 <pre>
+/* Rename the SWIG-generated wrapper. */
+%rename _set_transform set_transform;
+
+...
+
 void set_transform(Image *im, double x[4][4]);
 
 ...
+
 /* Rewrite the high level interface to set_transform */
 %pythoncode %{
 def set_transform(im, x):
@@ -3416,7 +3476,7 @@
     for i in range(4):
         for j in range(4):
             mat44_set(a, i, j, x[i][j])
-    _example.set_transform(im, a)
+    _example._set_transform(im, a)
     free_mat44(a)
 %}
 </pre>
@@ -3483,7 +3543,7 @@
 
 <div class="code">
 <pre>
-# This file was automatically generated by SWIG (http://www.swig.org).
+# This file was automatically generated by SWIG (https://www.swig.org).
 # Version 4.0.0
 #
 # Do not make changes to this file unless you know what you are doing--modify
@@ -3549,6 +3609,7 @@
 
 <p> where <tt>$action</tt> will be replaced by the call to
 the C/C++ proper method.
+Note that this does not include the arguments to the C/C++ method.
 </p>
 
 <p>
@@ -3650,7 +3711,7 @@
 </p>
 
 
-<H3><a name="Python_nn43">32.6.3 Class extension with %extend</a></H3>
+<H3><a name="Python_nn43">33.6.3 Class extension with %extend</a></H3>
 
 
 <p>
@@ -3739,7 +3800,7 @@
 in any way---the extensions only show up in the Python interface.
 </p>
 
-<H3><a name="Python_nn44">32.6.4 Exception handling with %exception</a></H3>
+<H3><a name="Python_nn44">33.6.4 Exception handling with %exception</a></H3>
 
 
 <p>
@@ -3873,10 +3934,10 @@
 to raise exceptions.  See the <a href="Library.html#Library">SWIG Library</a> chapter.
 </p>
 
-<H3><a name="Python_optimization">32.6.5 Optimization options</a></H3>
+<H3><a name="Python_optimization">33.6.5 Optimization options</a></H3>
 
 
-<H4><a name="Python_fastproxy">32.6.5.1 -fastproxy</a></H4>
+<H4><a name="Python_fastproxy">33.6.5.1 -fastproxy</a></H4>
 
 
 <p>
@@ -3974,7 +4035,7 @@
 
 <p>
 Although the <tt>-fastproxy</tt> option results in faster code over the default, the generated proxy code is not as user-friendly
-as docstring/doxygen comments and functions with default values are not visible in the generated Python proxy class.
+as docstring/doxygen comments, <a href="#Python_annotations">Python annotations</a> and functions with default values are not visible in the generated Python proxy class.
 The <tt>-olddefs</tt> option can rectify this.
 </p>
 
@@ -4009,7 +4070,7 @@
 The command line options mentioned above also apply to wrapped C/C++ global functions, not just class methods.
 </p>
 
-<H2><a name="Python_nn45">32.7 Tips and techniques</a></H2>
+<H2><a name="Python_nn45">33.7 Tips and techniques</a></H2>
 
 
 <p>
@@ -4019,7 +4080,7 @@
 solving these problems.
 </p>
 
-<H3><a name="Python_nn46">32.7.1 Input and output parameters</a></H3>
+<H3><a name="Python_nn46">33.7.1 Input and output parameters</a></H3>
 
 
 <p>
@@ -4151,7 +4212,7 @@
 <div class="code">
 <pre>
 /* send message, return number of bytes sent, along with success code */
-int send_message(char *text, int len, int *success);
+int send_message(char *text, int *success);
 </pre>
 </div>
 
@@ -4232,7 +4293,7 @@
 may not have the intended effect since <tt>typemaps.i</tt> does not define an OUTPUT rule for <tt>Bar</tt>.
 </p>
 
-<H3><a name="Python_nn47">32.7.2 Simple pointers</a></H3>
+<H3><a name="Python_nn47">33.7.2 Simple pointers</a></H3>
 
 
 <p>
@@ -4301,7 +4362,7 @@
 See the <a href="Library.html#Library">SWIG Library</a> chapter for further details.
 </p>
 
-<H3><a name="Python_nn48">32.7.3 Unbounded C Arrays</a></H3>
+<H3><a name="Python_nn48">33.7.3 Unbounded C Arrays</a></H3>
 
 
 <p>
@@ -4363,7 +4424,7 @@
 package binary data, etc.
 </p>
 
-<H3><a name="Python_nn49">32.7.4 String handling</a></H3>
+<H3><a name="Python_nn49">33.7.4 String handling</a></H3>
 
 
 <p>
@@ -4433,7 +4494,7 @@
 </p>
 
 
-<H3><a name="Python_default_args">32.7.5 Default arguments</a></H3>
+<H3><a name="Python_default_args">33.7.5 Default arguments</a></H3>
 
 
 <p>
@@ -4532,7 +4593,7 @@
 equivalent Python default argument values.
 </p>
 
-<H2><a name="Python_nn53">32.8 Typemaps</a></H2>
+<H2><a name="Python_nn53">33.8 Typemaps</a></H2>
 
 
 <p>
@@ -4549,7 +4610,7 @@
 C-Python interface or if you want to elevate your guru status.
 </p>
 
-<H3><a name="Python_nn54">32.8.1 What is a typemap?</a></H3>
+<H3><a name="Python_nn54">33.8.1 What is a typemap?</a></H3>
 
 
 <p>
@@ -4665,7 +4726,7 @@
 </pre>
 </div>
 
-<H3><a name="Python_nn55">32.8.2 Python typemaps</a></H3>
+<H3><a name="Python_nn55">33.8.2 Python typemaps</a></H3>
 
 
 <p>
@@ -4706,7 +4767,7 @@
 </p>
 
 
-<H3><a name="Python_nn56">32.8.3 Typemap variables</a></H3>
+<H3><a name="Python_nn56">33.8.3 Typemap variables</a></H3>
 
 
 <p>
@@ -4777,7 +4838,7 @@
 The Python name of the wrapper function being created.
 </div>
 
-<H3><a name="Python_nn57">32.8.4 Useful Python Functions</a></H3>
+<H3><a name="Python_nn57">33.8.4 Useful Python Functions</a></H3>
 
 
 <p>
@@ -4905,7 +4966,7 @@
 </pre>
 </div>
 
-<H2><a name="Python_nn58">32.9 Typemap Examples</a></H2>
+<H2><a name="Python_nn58">33.9 Typemap Examples</a></H2>
 
 
 <p>
@@ -4914,87 +4975,19 @@
 the SWIG library.
 </p>
 
-<H3><a name="Python_nn59">32.9.1 Converting  Python list to a char ** </a></H3>
+<H3><a name="Python_nn59">33.9.1 Converting a Python list to a char ** </a></H3>
 
 
 <p>
 A common problem in many C programs is the processing of command line
 arguments, which are usually passed in an array of NULL terminated
-strings.  The following SWIG interface file allows a Python list
-object to be used as a <tt>char **</tt> object.
+strings.  SWIG provides typemaps which allow passing a Python list
+or tuple - see
+<a href="Library.html#Library_argcargv">argcargv.i</a>.
 </p>
 
-<div class="code"><pre>
-%module argv
 
-// This tells SWIG to treat char ** as a special case
-%typemap(in) char ** {
-  /* Check if is a list */
-  if (PyList_Check($input)) {
-    int size = PyList_Size($input);
-    int i = 0;
-    $1 = (char **) malloc((size+1)*sizeof(char *));
-    for (i = 0; i &lt; size; i++) {
-      PyObject *o = PyList_GetItem($input, i);
-      if (PyString_Check(o)) {
-        $1[i] = PyString_AsString(PyList_GetItem($input, i));
-      } else {
-        free($1);
-        PyErr_SetString(PyExc_TypeError, "list must contain strings");
-        SWIG_fail;
-      }
-    }
-    $1[i] = 0;
-  } else {
-    PyErr_SetString(PyExc_TypeError, "not a list");
-    SWIG_fail;
-  }
-}
-
-// This cleans up the char ** array we malloc'd before the function call
-%typemap(freearg) char ** {
-  free((char *) $1);
-}
-
-// Now a test function
-%inline %{
-int print_args(char **argv) {
-  int i = 0;
-  while (argv[i]) {
-    printf("argv[%d] = %s\n", i, argv[i]);
-    i++;
-  }
-  return i;
-}
-%}
-
-</pre></div>
-
-<p>
-When this module is compiled, the wrapped C function now operates as
-follows :
-</p>
-
-<div class="targetlang"><pre>
-&gt;&gt;&gt; from argv import *
-&gt;&gt;&gt; print_args(["Dave", "Mike", "Mary", "Jane", "John"])
-argv[0] = Dave
-argv[1] = Mike
-argv[2] = Mary
-argv[3] = Jane
-argv[4] = John
-5
-</pre></div>
-
-<p>
-In the example, two different typemaps are used.  The "in" typemap is
-used to receive an input argument and convert it to a C array.  Since dynamic
-memory allocation is used to allocate memory for the array, the
-"freearg" typemap is used to later release this memory after the execution of
-the C function.
-</p>
-
-<H3><a name="Python_nn60">32.9.2 Expanding a Python object into multiple arguments</a></H3>
+<H3><a name="Python_nn60">33.9.2 Expanding a Python object into multiple arguments</a></H3>
 
 
 <p>
@@ -5038,7 +5031,6 @@
       if (PyString_Check(o)) {
         $2[i] = PyString_AsString(PyList_GetItem($input, i));
       } else {
-        free($2);
         PyErr_SetString(PyExc_TypeError, "list must contain strings");
         SWIG_fail;
       }
@@ -5113,7 +5105,7 @@
 </pre>
 </div>
 
-<H3><a name="Python_nn61">32.9.3 Using typemaps to return arguments</a></H3>
+<H3><a name="Python_nn61">33.9.3 Using typemaps to return arguments</a></H3>
 
 
 <p>
@@ -5201,7 +5193,7 @@
 &gt;&gt;&gt;
 </pre></div>
 
-<H3><a name="Python_nn62">32.9.4 Mapping Python tuples into small arrays</a></H3>
+<H3><a name="Python_nn62">33.9.4 Mapping Python tuples into small arrays</a></H3>
 
 
 <p>
@@ -5250,7 +5242,7 @@
 for small structures, this approach works fine.
 </p>
 
-<H3><a name="Python_nn63">32.9.5 Mapping sequences to C arrays</a></H3>
+<H3><a name="Python_nn63">33.9.5 Mapping sequences to C arrays</a></H3>
 
 
 <p>
@@ -5339,7 +5331,7 @@
 </pre>
 </div>
 
-<H3><a name="Python_nn64">32.9.6 Pointer handling</a></H3>
+<H3><a name="Python_nn64">33.9.6 Pointer handling</a></H3>
 
 
 <p>
@@ -5358,10 +5350,9 @@
 Converts a Python object <tt>obj</tt> to a C pointer.  The result of the conversion is placed
 into the pointer located at <tt>ptr</tt>.  <tt>ty</tt> is a SWIG type descriptor structure.
 <tt>flags</tt> is used to handle error checking and other aspects of conversion.  It is the
-bitwise-or of several flag values including <tt>SWIG_POINTER_EXCEPTION</tt> and
-<tt>SWIG_POINTER_DISOWN</tt>.   The first flag makes the function raise an exception on type
-error.  The second flag additionally
-steals ownership of an object. Returns 0 on success and -1 on error.
+bitwise-or of several flag values including <tt>SWIG_POINTER_DISOWN</tt> (which steals
+ownership of the object) and <tt>SWIG_POINTER_NO_NULL</tt> (which makes the conversion fail
+if the C pointer would be <tt>NULL</tt>). Returns 0 on success and -1 on error.
 </div>
 
 <p>
@@ -5436,7 +5427,7 @@
 class object (if applicable).
 </p>
 
-<H3><a name="Python_memory_management_member_variables">32.9.7 Memory management when returning references to member variables</a></H3>
+<H3><a name="Python_memory_management_member_variables">33.9.7 Memory management when returning references to member variables</a></H3>
 
 
 <p>
@@ -5597,7 +5588,7 @@
 
 
 
-<H2><a name="Python_nn65">32.10 Docstring Features</a></H2>
+<H2><a name="Python_nn65">33.10 Docstring Features</a></H2>
 
 
 <p>
@@ -5625,7 +5616,7 @@
 </p>
 
 
-<H3><a name="Python_nn66">32.10.1 Module docstring</a></H3>
+<H3><a name="Python_nn66">33.10.1 Module docstring</a></H3>
 
 
 <p>
@@ -5659,7 +5650,7 @@
 </div>
 
 
-<H3><a name="Python_nn67">32.10.2 %feature("autodoc")</a></H3>
+<H3><a name="Python_nn67">33.10.2 %feature("autodoc")</a></H3>
 
 
 <p>
@@ -5687,7 +5678,7 @@
 feature, <tt>%feature("autodoc", "<i>level</i>")</tt>.
 The four values for <i>level</i> are covered in the following sub-sections.
 
-<H4><a name="Python_nn68">32.10.2.1 %feature("autodoc", "0")</a></H4>
+<H4><a name="Python_nn68">33.10.2.1 %feature("autodoc", "0")</a></H4>
 
 
 <p>
@@ -5716,7 +5707,7 @@
 </div>
 
 
-<H4><a name="Python_nn69">32.10.2.2 %feature("autodoc", "1")</a></H4>
+<H4><a name="Python_nn69">33.10.2.2 %feature("autodoc", "1")</a></H4>
 
 
 <p>
@@ -5741,7 +5732,7 @@
 </div>
 
 
-<H4><a name="Python_autodoc2">32.10.2.3 %feature("autodoc", "2")</a></H4>
+<H4><a name="Python_autodoc2">33.10.2.3 %feature("autodoc", "2")</a></H4>
 
 
 <p>
@@ -5803,7 +5794,7 @@
 </pre>
 </div>
 
-<H4><a name="Python_autodoc3">32.10.2.4 %feature("autodoc", "3")</a></H4>
+<H4><a name="Python_autodoc3">33.10.2.4 %feature("autodoc", "3")</a></H4>
 
 
 <p>
@@ -5829,7 +5820,7 @@
 </div>
 
 
-<H4><a name="Python_nn70">32.10.2.5 %feature("autodoc", "docstring")</a></H4>
+<H4><a name="Python_nn70">33.10.2.5 %feature("autodoc", "docstring")</a></H4>
 
 
 <p>
@@ -5848,7 +5839,7 @@
 </div>
 
 
-<H3><a name="Python_nn71">32.10.3 %feature("docstring")</a></H3>
+<H3><a name="Python_nn71">33.10.3 %feature("docstring")</a></H3>
 
 
 <p>
@@ -5880,7 +5871,29 @@
 </pre>
 </div>
 
-<H2><a name="Python_nn72">32.11 Python Packages</a></H2>
+<H3><a name="Python_doxygen_docstrings">33.10.4 Doxygen comments</a></H3>
+
+
+<p>
+Please see the separate <a href="Doxygen.html#Doxygen">Doxygen</a> chapter for information
+on making use of C++ Doxygen comments and translating them into Python docstring comments.
+</p>
+
+<p>
+Note that when generating docstrings and Doxygen comments have also been turned on,
+the <a href="#Python_nn71">docstring feature</a> will take precedence over a Doxygen comment.
+If the <a href="#Python_nn67">autodoc feature</a> is also turned on, then it will be
+used in conjunction with the docstring feature.
+However, if there is no docstring feature present and there is a Doxygen comment, then the autodoc docstring will not be generated. The Doxygen comment alone will be used.
+</p>
+
+<p>
+This way, if the autodoc feature is specified globally it will fill in any missing
+Doxygen documentation comments.
+Doxygen comments can be overridden by using the docstring feature.
+</p>
+
+<H2><a name="Python_nn72">33.11 Python Packages</a></H2>
 
 
 <p>Python has concepts of modules and packages. Modules are separate units of
@@ -5954,7 +5967,7 @@
 <tt>%module</tt> directive or import related command line options. These are
 explained in the following sections.</p>
 
-<H3><a name="Python_modulepackage">32.11.1 Setting the Python package</a></H3>
+<H3><a name="Python_modulepackage">33.11.1 Setting the Python package</a></H3>
 
 
 <p>
@@ -6008,7 +6021,7 @@
 </pre>
 </div>
 
-<H3><a name="Python_absrelimports">32.11.2 Absolute and relative imports</a></H3>
+<H3><a name="Python_absrelimports">33.11.2 Absolute and relative imports</a></H3>
 
 
 <p>Suppose, we have the following hierarchy of files:</p>
@@ -6145,7 +6158,7 @@
 <tt>__init__.py</tt> to import symbols from submodules or subpackages and the
 submodule depends on other submodules (discussed later).</p>
 
-<H3><a name="Python_absimport">32.11.3 Enforcing absolute import semantics</a></H3>
+<H3><a name="Python_absimport">33.11.3 Enforcing absolute import semantics</a></H3>
 
 
 <p>As you may know, there is an incompatibility in import semantics (for the
@@ -6182,7 +6195,7 @@
 </pre>
 </div>
 
-<H3><a name="Python_importfrominit">32.11.4 Importing from __init__.py</a></H3>
+<H3><a name="Python_importfrominit">33.11.4 Importing from __init__.py</a></H3>
 
 
 <p>Imports in <tt>__init__.py</tt> are handy when you want to populate a
@@ -6292,7 +6305,7 @@
 effect (note, that the Python 2 case also needs the <tt>-relativeimport</tt>
 workaround).</p>
 
-<H3><a name="Python_implicit_namespace_packages">32.11.5 Implicit namespace packages</a></H3>
+<H3><a name="Python_implicit_namespace_packages">33.11.5 Implicit namespace packages</a></H3>
 
 
 <p> Python 3.3 introduced
@@ -6370,7 +6383,7 @@
 </p>
 
 
-<H3><a name="Python_package_search">32.11.6 Location of modules</a></H3>
+<H3><a name="Python_package_search">33.11.6 Location of modules</a></H3>
 
 
 <p>
@@ -6406,7 +6419,7 @@
 An input interface file, foo.i, results in the two modules foo.py and _foo.so for each of the configurations.
 </p>
 
-<H4><a name="Python_package_search_both_package_modules">32.11.6.1 Both modules in the same package</a></H4>
+<H4><a name="Python_package_search_both_package_modules">33.11.6.1 Both modules in the same package</a></H4>
 
 
 <p>
@@ -6441,7 +6454,7 @@
 </div>
 
 
-<H4><a name="Python_package_search_both_global_modules">32.11.6.2 Both modules are global</a></H4>
+<H4><a name="Python_package_search_both_global_modules">33.11.6.2 Both modules are global</a></H4>
 
 
 <p>
@@ -6473,7 +6486,7 @@
 </pre>
 </div>
 
-<H4><a name="Python_package_search_wrapper_split">32.11.6.3 Split modules custom configuration</a></H4>
+<H4><a name="Python_package_search_wrapper_split">33.11.6.3 Split modules custom configuration</a></H4>
 
 
 <p>In this non-standard 'split module' configuration, the pure Python module is in a package and the low level C/C++ module is global.
@@ -6523,7 +6536,7 @@
 </p>
 
 
-<H4><a name="Python_custom_module_import">32.11.6.4 More on customizing the module import code</a></H4>
+<H4><a name="Python_custom_module_import">33.11.6.4 More on customizing the module import code</a></H4>
 
 
 <p>
@@ -6643,7 +6656,7 @@
 </pre>
 </div>
 
-<H4><a name="Python_package_search_static">32.11.6.5 Statically linked C modules</a></H4>
+<H4><a name="Python_package_search_static">33.11.6.5 Statically linked C modules</a></H4>
 
 
 <p>It is strongly recommended to use dynamically linked modules for the C
@@ -6715,18 +6728,16 @@
 to do this (remember you are now the Python importer) or use dynamic linking.
 </p>
 
-<H2><a name="Python_python3support">32.12 Python 3 Support</a></H2>
+<H2><a name="Python_python3support">33.12 Python 3 Support</a></H2>
 
 
 <p>
 SWIG is able to support Python 3.x. The wrapper code generated by
-SWIG can be compiled with both Python 2.x or 3.x. Further more, by
-passing the <tt>-py3</tt> command line option to SWIG, wrapper code
-with some Python 3 specific features can be generated (see below
-subsections for details of these features).
+SWIG can be compiled with both Python 2.x or 3.x.
+</p>
 
 <p>
-There is a list of known-to-be-broken features in Python 3:
+The list of known-to-be-broken features around Python 3 are:
 </p>
 <ul>
   <li>No more support for FILE* typemaps, because PyFile_AsFile has been dropped
@@ -6740,40 +6751,123 @@
 SWIG.
 </p>
 
-<H3><a name="Python_nn74">32.12.1 Function annotation</a></H3>
+<H3><a name="Python_annotations">33.12.1 Python function annotations and variable annotations</a></H3>
 
 
 <p>
-The <tt>-py3</tt> option will enable function annotation support. When used
-SWIG is able to generate proxy method definitions like this:
-</p>
-
-<div class="code"><pre>
-  def foo(self, bar : "int"=0) -&gt; "void" : ...
-</pre></div>
-
-<p>
-Also, even if without passing SWIG the <tt>-py3</tt> option, the parameter list
-still could be generated:
-</p>
-
-<div class="code"><pre>
-  def foo(self, bar=0): ...
-</pre></div>
-
-<p>
-But for overloaded function or method, the parameter list would fallback to
-<tt>*args</tt> or <tt>self, *args</tt>, and <tt>**kwargs</tt> may be append
-depend on whether you enabled the keyword argument. This fallback is due to
-all overloaded functions share the same function in SWIG generated proxy class.
-</p>
-
-<p>
-For detailed usage of function annotation, see
+Python 3 supports function annotations as defined in
 <a href="https://www.python.org/dev/peps/pep-3107/">PEP 3107</a>.
+Python 3.6 and later additionally support variable annotations as defined in
+<a href="https://www.python.org/dev/peps/pep-526/">PEP 526</a>.
+Note that currently there is no annotations support in SWIG for the <tt>-builtin</tt> nor
+the <tt>-fastproxy</tt> option.
+Annotations are added via the <tt>python:annotations</tt>
+<a href="Customization.html#Customization_features">%feature directives</a>.
+SWIG currently supports one type of function annotation.
 </p>
 
-<H3><a name="Python_nn75">32.12.2 Buffer interface</a></H3>
+<H4><a name="Python_annotations_c">33.12.1.1 C/C++ annotation types</a></H4>
+
+
+<p>
+The <tt>%feature("python:annotations", "c")</tt> directive generates annotations
+containing C/C++ types. For example:
+</p>
+
+<div class="code"><pre>
+%feature("python:annotations", "c") global_ints;
+int *global_ints(int &amp;ri);
+</pre></div>
+
+<p>
+The generated code then contains function annotations containing the C++ types:
+</p>
+
+<div class="targetlang"><pre>
+def global_ints(ri: "int &amp;") -&gt; "int *":
+    return _example.global_ints(ri)
+</pre></div>
+
+<p>
+There are some limitations with function annotations support, for example, overloaded functions use
+<tt>*args</tt> or <tt>**kwargs</tt> when keyword arguments are enabled.
+The parameter names and types are then not shown. For example, with input:
+</p>
+
+<div class="code"><pre>
+int *global_overloaded(int &amp;ri);
+int *global_overloaded();
+</pre></div>
+
+<p>
+The generated Python function including annotations is shown below.
+Only the return type is annotated.
+</p>
+
+<div class="targetlang"><pre>
+def global_overloaded(*args) -&gt; "int *":
+    return _example.global_overloaded(*args)
+</pre></div>
+
+<p>
+Below is an example demonstrating variable annotations.
+</p>
+
+<div class="code"><pre>
+%feature("python:annotations", "c");
+
+struct V {
+  float val;
+};
+</pre></div>
+
+<p>
+The generated code contains a variable annotation containing the C <tt>float</tt> type:
+</p>
+
+<div class="targetlang"><pre>
+class V(object):
+    val: "float" = property(_example.V_val_get, _example.V_val_set)
+    ...
+</pre></div>
+
+<p>
+Variable annotations are only supported from Python 3.6. If you need to support earlier versions of Python, you'll need to turn variable annotations off via the <tt>python:annotations:novar</tt> feature flag.
+It is quite easy to support function annotations but turn off variable annotations. The next example shows how to do this for all variables.
+</p>
+
+<div class="code"><pre>
+%feature("python:annotations", "c");  // Turn on function annotations and variable annotations globally
+%feature("python:annotations:novar"); // Turn off variable annotations globally
+
+struct V {
+  float val;
+  void vv(float *v) const;
+};
+</pre></div>
+
+<p>
+The resulting code will work with versions older than Python 3.6 as the variable annotations are turned off:
+</p>
+
+<div class="targetlang"><pre>
+class V(object):
+    val = property(_example.V_val_get, _example.V_val_set)
+
+    def vv(self, v: "float *") -&gt; "void":
+        return _example.V_vv(self, v)
+    ...
+</pre></div>
+
+
+<p>
+<b>Compatibility Note:</b> SWIG-4.1.0 changed the way that function annotations are generated.
+Prior versions required the (now removed) <tt>-py3</tt> option to generate function annotation support
+containing C/C++ types instead of supporting <tt>%feature("python:annotations", "c")</tt>.
+Variable annotations were also added in SWIG-4.1.0.
+</p>
+
+<H3><a name="Python_nn75">33.12.2 Buffer interface</a></H3>
 
 
 <p>
@@ -6925,14 +7019,15 @@
 </div>
 
 
-<H3><a name="Python_nn76">32.12.3 Abstract base classes</a></H3>
+<H3><a name="Python_nn76">33.12.3 Abstract base classes</a></H3>
 
 
 <p>
-By including <tt>pyabc.i</tt> and using the <tt>-py3</tt> command
-line option when calling SWIG, the proxy classes of the STL containers
+By including <tt>pyabc.i</tt> in your interface file,
+the proxy classes of the STL containers
 will automatically gain an appropriate abstract base class from the
-<tt>collections.abc</tt> module. For
+<tt>collections.abc</tt> module for Python 3.3 and later, otherwise from the
+<tt>collections</tt> module. For
 example, the following SWIG interface:
 </p>
 
@@ -6949,8 +7044,10 @@
 
 <p>
 will generate a Python proxy class <tt>Mapii</tt> inheriting from
-<tt>collections.abc.MutableMap</tt> and a proxy class <tt>IntList</tt>
-inheriting from <tt>collections.abc.MutableSequence</tt>.
+<tt>collections.abc.MutableMap</tt> for Python 3.3 and later, or <tt>collections.MutableMap</tt>
+for earlier versions and a proxy class <tt>IntList</tt>
+inheriting from <tt>collections.abc.MutableSequence</tt> for Python 3.3 or later,
+or <tt>collections.MutableSequence</tt> for earlier versions.
 </p>
 
 <p>
@@ -6959,7 +7056,9 @@
 </p>
 
 <div class="code"><pre>
-%pythonabc(MySet, collections.abc.MutableSet);
+%pythonabc(MySet, collections.abc.MutableSet); # Python 3.3 and later
+%pythonabc(MySet, collections.MutableSet);     # Prior to Python 3.3
+%pythonabc(MySet, "collections.abc.MutableSet if _swig_python_version_info &gt;= (3, 3) else collections.MutableSet"); # All Python versions
 </pre></div>
 
 <p>
@@ -6973,9 +7072,11 @@
 of the classes in the <tt>collections</tt> module in Python 3.7.
 The <tt>collections.abc</tt> module was introduced in Python 3.3 and hence this feature
 requires Python 3.3 or later.
+SWIG-4.1.0 introduced the flexibility of using
+either the <tt>collections.abc</tt> module for Python 3.3 and later or the <tt>collections</tt> module for earlier Python versions.
 </p>
 
-<H3><a name="Python_nn77">32.12.4 Byte string output conversion</a></H3>
+<H3><a name="Python_nn77">33.12.4 Byte string output conversion</a></H3>
 
 
 <p>
@@ -7156,7 +7257,7 @@
 (as Python unicode).
 </p>
 
-<H3><a name="Python_2_unicode">32.12.5 Python 2 Unicode</a></H3>
+<H3><a name="Python_2_unicode">33.12.5 Python 2 Unicode</a></H3>
 
 
 <p>
@@ -7228,7 +7329,7 @@
 prohibiting it.
 </p>
 
-<H2><a name="Python_multithreaded">32.13 Support for Multithreaded Applications</a></H2>
+<H2><a name="Python_multithreaded">33.13 Support for Multithreaded Applications</a></H2>
 
 
 <p>By default, SWIG does not enable support for multithreaded Python applications.  More
@@ -7243,7 +7344,7 @@
     interface for this is described in the next section.
 </p>
 
-<H3><a name="Python_thread_UI">32.13.1 UI for Enabling Multithreading Support</a></H3>
+<H3><a name="Python_thread_UI">33.13.1 UI for Enabling Multithreading Support</a></H3>
 
 
 <p>The user interface is as follows:</p>
@@ -7286,7 +7387,7 @@
   </li>
 </ol>
 
-<H3><a name="Python_thread_performance">32.13.2 Multithread Performance</a></H3>
+<H3><a name="Python_thread_performance">33.13.2 Multithread Performance</a></H3>
 
 
 <p>
diff --git a/Doc/Manual/R.html b/Doc/Manual/R.html
index 373cd7e..0e9e55b 100644
--- a/Doc/Manual/R.html
+++ b/Doc/Manual/R.html
@@ -7,7 +7,7 @@
 </head>
 
 <body bgcolor="#ffffff">
-<H1><a name="R">33 SWIG and R</a></H1>
+<H1><a name="R">34 SWIG and R</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -17,6 +17,9 @@
 <li><a href="#R_nn5">General policy</a>
 <li><a href="#R_language_conventions">Language conventions</a>
 <li><a href="#R_nn6">C++ classes</a>
+<ul>
+<li><a href="#R_class_examples">Examples</a>
+</ul>
 <li><a href="#R_nn7">Enumerations</a>
 </ul>
 </div>
@@ -27,16 +30,20 @@
 <p>
 R is a GPL'ed open source statistical and plotting environment.
 Information about R can be found at <a
-href="http://www.r-project.org/">www.r-project.org</a>.
+href="https://www.r-project.org/">www.r-project.org</a>.
 </p>
 
 <p>
 The R bindings are under active development.  They have been used to
 compile and run an R interface to QuantLib running on Mandriva Linux
-with gcc. The R bindings also work on Microsoft Windows using Visual C++.
+with gcc. They are also used to create the SimpleITK R package, which
+runs on Linux and MacOS. SWIG is used to create all wrapper
+interfaces
+to <a href="https://www.simpleitk.org/">SimpleITK</a>.  The R
+bindings also work on Microsoft Windows using Visual C++.
 </p>
 
-<H2><a name="R_nn2">33.1 Bugs</a></H2>
+<H2><a name="R_nn2">34.1 Bugs</a></H2>
 
 
 <p>
@@ -44,11 +51,13 @@
 </p>
 
 <ul>
-<li>Garbage collection of created objects
+<li>Garbage collection of some created objects. Finalizers are
+  available for wrapped C++ classes and are called by the
+  garbage collection system.
 <li>C Array wrappings
 </ul>
 
-<H2><a name="R_nn3">33.2 Using R and SWIG</a></H2>
+<H2><a name="R_nn3">34.2 Using R and SWIG</a></H2>
 
 
 <p>
@@ -138,7 +147,7 @@
 <li>Make sure the architecture of the shared library(x64 for instance), matches the architecture of the R program you want to load your shared library into
 </ul>
 
-<H2><a name="R_nn4">33.3 Precompiling large R files</a></H2>
+<H2><a name="R_nn4">34.3 Precompiling large R files</a></H2>
 
 
 <p>
@@ -158,9 +167,12 @@
 will save a large amount of loading time.
 </p>
 
+<p>
+There is no need to precompile large R files if the SWIG-generated code is being included
+in an R package. The package infrastructure provides this service during package installation.
+</p>
 
-
-<H2><a name="R_nn5">33.4 General policy</a></H2>
+<H2><a name="R_nn5">34.4 General policy</a></H2>
 
 
 <p>
@@ -169,28 +181,136 @@
 to provide R syntax.
 </p>
 
-<H2><a name="R_language_conventions">33.5 Language conventions</a></H2>
+<H2><a name="R_language_conventions">34.5 Language conventions</a></H2>
 
 
 <p>
-getitem and setitem use C++ conventions (i.e. zero based indices). [<-
+getitem and setitem use C++ conventions (i.e. zero based indices). [&lt;-
 and [ are overloaded to allow for R syntax (one based indices and
 slices)
 </p>
 
-<H2><a name="R_nn6">33.6 C++ classes</a></H2>
+<H2><a name="R_nn6">34.6 C++ classes</a></H2>
 
 
 <p>
-C++ objects are implemented as external pointer objects with the class
-being the mangled name of the class. The C++ classes are encapsulated
-as an SEXP with an external pointer type. The class is the mangled
-name of the class. The nice thing about R is that is allows you to
-keep track of the pointer object which removes the necessity for a lot
-of the proxy class baggage you see in other languages.
+Wrapping of C++ classes for R works quite well. R has a special
+type, known as an external reference, that can be used as a pointer
+to arbitrary things, including C++ classes. The proxy layers generated
+for other classes are not required.
 </p>
 
-<H2><a name="R_nn7">33.7 Enumerations</a></H2>
+<p>
+  SWIG currently creates a custom hierarchy of R classes derived from the
+  external reference type and implements
+type checking and function overloading in the R code it generates. In
+the future we hope to utilise the built in R6 class structures.
+</p>
+
+<p>
+The R interface has the following capabilities:
+</p>
+<ul>
+  <li> Destructor methods are registered and called automatically by the R garbage collector.
+<li> A range of std::vector types are converted automatically to R equivalents via the std_vector.i library.
+<li> The $ operator is used for method access.
+<li> Variable accessors are automatically generated and called via the $, [, [[, $&lt;-,  [&lt;-, [[&lt;- operators.
+</ul>
+
+<H3><a name="R_class_examples">34.6.1 Examples</a></H3>
+
+
+<p>
+Consider the following simple example:
+</p>
+
+<div class="code">
+  <pre>
+class Vehicle {
+private:
+  int m_axles;
+
+public:
+  int Axles() {
+    return(m_axles);
+  }
+
+  bool Available;
+
+  Vehicle() {
+    Available=false;
+    m_axles=2;
+  }
+
+  Vehicle(int ax) {
+    Available=false;
+    m_axles=ax;
+  }
+};
+</pre>
+</div>
+
+<p>
+The following options are available in R:
+</p>
+
+<div class="code">
+<pre>
+v1 &lt;- Vehicle()
+v2 &lt;- Vehicle(4)
+# access members
+v1$Axles()
+[1] 2
+v2$Axles
+[1] 4
+v1$Available
+[1] FALSE
+# Set availability
+v1$Available &lt;- TRUE
+v1$Available
+[1] TRUE
+</pre>
+</div>
+  
+<p>
+A useful trick to determine the methods that are available is to
+query the R method definition as follows:
+</p>
+
+<div class="code">
+  <pre>
+# display the methods for the class
+getMethod("$", class(v1))
+    
+Method Definition:
+
+function (x, name) 
+{
+    accessorFuns = list(Axles = Vehicle_Axles, Available = Vehicle_Available_get)
+    vaccessors = c("Available")
+    idx = pmatch(name, names(accessorFuns))
+    if (is.na(idx)) 
+        return(callNextMethod(x, name))
+    f = accessorFuns[[idx]]
+    if (is.na(match(name, vaccessors))) 
+        function(...) {
+            f(x, ...)
+        }
+    else f(x)
+}
+
+Signatures:
+        x           
+target  "_p_Vehicle"
+defined "_p_Vehicle"
+
+</pre>
+</div>
+<p>
+The names in the <tt>accessorFuns</tt> list correspond to class methods while names in the <tt>vaccessors</tt> section
+correspond to variables that may be modified.
+</p>
+<H2><a name="R_nn7">34.7 Enumerations</a></H2>
 
 
 <p>
@@ -201,7 +321,7 @@
 
 <p>
 The details of enumeration names and contents are stored in hidden R
-environments, which are named according the the enumeration name - for
+environments, which are named according to the enumeration name - for
 example, an enumeration colour:
 </p>
 
diff --git a/Doc/Manual/Ruby.html b/Doc/Manual/Ruby.html
index 3cfd129..852c7ce 100644
--- a/Doc/Manual/Ruby.html
+++ b/Doc/Manual/Ruby.html
@@ -8,7 +8,7 @@
 
 <body bgcolor="#ffffff">
 
-<H1><a name="Ruby">34 SWIG and Ruby</a></H1>
+<H1><a name="Ruby">35 SWIG and Ruby</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -149,10 +149,10 @@
 
 <p>This chapter describes SWIG's support of Ruby.</p>
 
-<H2><a name="Ruby_nn2">34.1 Preliminaries</a></H2>
+<H2><a name="Ruby_nn2">35.1 Preliminaries</a></H2>
 
 
-<p> SWIG 4.0 is known to work with Ruby versions 1.9 and later.
+<p> SWIG 4.2 is known to work with Ruby versions 2.0 and later.
 Given the choice, you should use the latest stable version of Ruby. You
 should also determine if your system supports shared libraries and
 dynamic loading. SWIG will work with or without dynamic loading, but
@@ -164,7 +164,7 @@
 chapter. It is also assumed that the reader has a basic understanding
 of Ruby. </p>
 
-<H3><a name="Ruby_nn3">34.1.1 Running SWIG</a></H3>
+<H3><a name="Ruby_nn3">35.1.1 Running SWIG</a></H3>
 
 
 <p> To build a Ruby module, run SWIG using the <tt>-ruby</tt>
@@ -188,7 +188,7 @@
 build a Ruby extension module. To finish building the module, you need
 to compile this file and link it with the rest of your program. </p>
 
-<H3><a name="Ruby_nn4">34.1.2 Getting the right header files</a></H3>
+<H3><a name="Ruby_nn4">35.1.2 Getting the right header files</a></H3>
 
 
 <p> In order to compile the wrapper code, the compiler needs the <tt>ruby.h</tt>
@@ -202,7 +202,7 @@
 </pre>
 </div>
 
-<H3><a name="Ruby_nn5">34.1.3 Compiling a dynamic module</a></H3>
+<H3><a name="Ruby_nn5">35.1.3 Compiling a dynamic module</a></H3>
 
 
 <p> Ruby extension modules are typically compiled into shared
@@ -275,7 +275,7 @@
 of options. You might also check the <a href="https://github.com/swig/swig/wiki">SWIG Wiki</a>
 for additional information. </p>
 
-<H3><a name="Ruby_nn6">34.1.4 Using your module</a></H3>
+<H3><a name="Ruby_nn6">35.1.4 Using your module</a></H3>
 
 
 <p> Ruby <i>module</i> names must be capitalized,
@@ -305,7 +305,7 @@
 <p> will result in an extension module using the feature name
 "example" and Ruby module name "Example". </p>
 
-<H3><a name="Ruby_nn7">34.1.5 Static linking</a></H3>
+<H3><a name="Ruby_nn7">35.1.5 Static linking</a></H3>
 
 
 <p> An alternative approach to dynamic linking is to rebuild the
@@ -320,7 +320,7 @@
 file, adding your directory to the list of extensions in the file, and
 finally rebuilding Ruby. </p>
 
-<H3><a name="Ruby_nn8">34.1.6 Compilation of C++ extensions</a></H3>
+<H3><a name="Ruby_nn8">35.1.6 Compilation of C++ extensions</a></H3>
 
 
 <p> On most machines, C++ extension modules should be linked
@@ -352,7 +352,7 @@
 create_makefile('example')</pre>
 </div>
 
-<H2><a name="Ruby_nn9">34.2 Building Ruby Extensions under Windows 95/NT</a></H2>
+<H2><a name="Ruby_nn9">35.2 Building Ruby Extensions under Windows 95/NT</a></H2>
 
 
 <p> Building a SWIG extension to Ruby under Windows 95/NT is
@@ -377,7 +377,7 @@
 distribution to the Ruby package, as you will need the Ruby header
 files. </p>
 
-<H3><a name="Ruby_nn10">34.2.1 Running SWIG from Developer Studio</a></H3>
+<H3><a name="Ruby_nn10">35.2.1 Running SWIG from Developer Studio</a></H3>
 
 
 <p> If you are developing your application within Microsoft
@@ -441,13 +441,13 @@
 </pre>
 </div>
 
-<H2><a name="Ruby_nn11">34.3 The Ruby-to-C/C++ Mapping</a></H2>
+<H2><a name="Ruby_nn11">35.3 The Ruby-to-C/C++ Mapping</a></H2>
 
 
 <p> This section describes the basics of how SWIG maps C or C++
 declarations in your SWIG interface files to Ruby constructs. </p>
 
-<H3><a name="Ruby_nn12">34.3.1 Modules</a></H3>
+<H3><a name="Ruby_nn12">35.3.1 Modules</a></H3>
 
 
 <p> The SWIG <tt>%module</tt> directive specifies
@@ -519,7 +519,7 @@
 names of your constants, classes and methods don't conflict with any of
 Ruby's built-in names. </p>
 
-<H3><a name="Ruby_nn13">34.3.2 Functions</a></H3>
+<H3><a name="Ruby_nn13">35.3.2 Functions</a></H3>
 
 
 <p> Global functions are wrapped as Ruby module methods. For
@@ -553,7 +553,7 @@
 24</pre>
 </div>
 
-<H3><a name="Ruby_nn14">34.3.3 Variable Linking</a></H3>
+<H3><a name="Ruby_nn14">35.3.3 Variable Linking</a></H3>
 
 
 <p> C/C++ global variables are wrapped as a pair of singleton
@@ -615,7 +615,25 @@
 effect until it is explicitly disabled using <tt>%mutable</tt>.
 </p>
 
-<H3><a name="Ruby_nn15">34.3.4 Constants</a></H3>
+<p>Note: When SWIG is invoked with the <tt>-globalmodule</tt> option in
+effect, the C/C++ global variables will be translated into Ruby global
+variables. Type-checking and the optional read-only characteristic are
+available in the same way as described above. However the example would
+then have to be modified and executed in the following way:
+
+<div class="code targetlang">
+<pre>$ <b>irb</b>
+irb(main):001:0&gt; <b>require 'Example'</b>
+true
+irb(main):002:0&gt; <b>$variable1 = 2</b>
+2
+irb(main):003:0&gt; <b>$Variable2 = 4 * 10.3</b>
+41.2
+irb(main):004:0&gt; <b>$Variable2</b>
+41.2</pre>
+</div>
+
+<H3><a name="Ruby_nn15">35.3.4 Constants</a></H3>
 
 
 <p> C/C++ constants are wrapped as module constants initialized
@@ -643,7 +661,7 @@
 3.14159</pre>
 </div>
 
-<H3><a name="Ruby_nn16">34.3.5 Pointers</a></H3>
+<H3><a name="Ruby_nn16">35.3.5 Pointers</a></H3>
 
 
 <p> "Opaque" pointers to arbitrary C/C++ types (i.e. types that
@@ -667,7 +685,7 @@
 <p> A <tt>NULL</tt> pointer is always represented by
 the Ruby <tt>nil</tt> object. </p>
 
-<H3><a name="Ruby_nn17">34.3.6 Structures</a></H3>
+<H3><a name="Ruby_nn17">35.3.6 Structures</a></H3>
 
 
 <p> C/C++ structs are wrapped as Ruby classes, with accessor
@@ -772,7 +790,7 @@
 }</pre>
 </div>
 
-<H3><a name="Ruby_nn18">34.3.7 C++ classes</a></H3>
+<H3><a name="Ruby_nn18">35.3.7 C++ classes</a></H3>
 
 
 <p> Like structs, C++ classes are wrapped by creating a new Ruby
@@ -827,7 +845,7 @@
 3</pre>
 </div>
 
-<H3><a name="Ruby_nn19">34.3.8 C++ Inheritance</a></H3>
+<H3><a name="Ruby_nn19">35.3.8 C++ Inheritance</a></H3>
 
 
 <p> The SWIG type-checker is fully aware of C++ inheritance.
@@ -980,7 +998,7 @@
 (i.e. they exhibit <a href="http://c2.com/cgi/wiki?DuckTyping">"Duck
 Typing"</a>). </p>
 
-<H3><a name="Ruby_nn20">34.3.9 C++ Overloaded Functions</a></H3>
+<H3><a name="Ruby_nn20">35.3.9 C++ Overloaded Functions</a></H3>
 
 
 <p> C++ overloaded functions, methods, and constructors are
@@ -1070,7 +1088,7 @@
 <p>Please refer to the <a href="SWIGPlus.html#SWIGPlus">"SWIG
 and C++"</a> chapter for more information about overloading. </p>
 
-<H3><a name="Ruby_nn21">34.3.10 C++ Operators</a></H3>
+<H3><a name="Ruby_nn21">35.3.10 C++ Operators</a></H3>
 
 
 <p> For the most part, overloaded operators are handled
@@ -1112,7 +1130,7 @@
 is discussed in the <a href="#Ruby_operator_overloading">section
 on operator overloading</a>. </p>
 
-<H3><a name="Ruby_nn22">34.3.11 C++ namespaces</a></H3>
+<H3><a name="Ruby_nn22">35.3.11 C++ namespaces</a></H3>
 
 
 <p> SWIG is aware of C++ namespaces, but namespace names do not
@@ -1169,7 +1187,7 @@
 program utilizes thousands of small deeply nested namespaces each with
 identical symbol names, well, then you get what you deserve. </p>
 
-<H3><a name="Ruby_nn23">34.3.12 C++ templates</a></H3>
+<H3><a name="Ruby_nn23">35.3.12 C++ templates</a></H3>
 
 
 <p> C++ templates don't present a huge problem for SWIG. However,
@@ -1211,7 +1229,7 @@
 4</pre>
 </div>
 
-<H3><a name="Ruby_nn23_1">34.3.13 C++ Standard Template Library (STL)</a></H3>
+<H3><a name="Ruby_nn23_1">35.3.13 C++ Standard Template Library (STL)</a></H3>
 
 
 <p> On a related note, the standard SWIG library contains a
@@ -1304,7 +1322,7 @@
 shown in these examples. More details can be found in the <a href="SWIGPlus.html#SWIGPlus">SWIG and C++</a>
 chapter.</p>
 
-<H3><a name="Ruby_C_STL_Functors">34.3.14 C++ STL Functors</a></H3>
+<H3><a name="Ruby_C_STL_Functors">35.3.14 C++ STL Functors</a></H3>
 
 
 <p>Some containers in the STL allow you to modify their default
@@ -1365,7 +1383,7 @@
 </pre>
 </div>
 
-<H3><a name="Ruby_C_Iterators">34.3.15 C++ STL Iterators</a></H3>
+<H3><a name="Ruby_C_Iterators">35.3.15 C++ STL Iterators</a></H3>
 
 
 <p>The STL is well known for the use of iterators. There
@@ -1448,10 +1466,10 @@
 
 <p>If you'd rather have STL classes without any iterators, you should define <tt>-DSWIG_NO_EXPORT_ITERATOR_METHODS</tt> when running swig.</p>
 
-<H3><a name="Ruby_nn24">34.3.16 C++ Smart Pointers</a></H3>
+<H3><a name="Ruby_nn24">35.3.16 C++ Smart Pointers</a></H3>
 
 
-<H4><a name="Ruby_smart_pointers_shared_ptr">34.3.16.1 The shared_ptr Smart Pointer</a></H4>
+<H4><a name="Ruby_smart_pointers_shared_ptr">35.3.16.1 The shared_ptr Smart Pointer</a></H4>
 
 
 <p>
@@ -1462,7 +1480,7 @@
 </p>
 
 
-<H4><a name="Ruby_smart_pointers_generic">34.3.16.2 Generic Smart Pointers</a></H4>
+<H4><a name="Ruby_smart_pointers_generic">35.3.16.2 Generic Smart Pointers</a></H4>
 
 
 <p> In certain C++ programs, it is common to use classes that
@@ -1527,7 +1545,7 @@
 <pre>irb(main):004:0&gt; <b>f = p.__deref__()</b> # Returns underlying Foo *</pre>
 </div>
 
-<H3><a name="Ruby_nn25">34.3.17 Cross-Language Polymorphism</a></H3>
+<H3><a name="Ruby_nn25">35.3.17 Cross-Language Polymorphism</a></H3>
 
 
 <p> SWIG's Ruby module supports cross-language polymorphism
@@ -1536,7 +1554,7 @@
 section just notes the differences that you need to be aware of when
 using this feature with Ruby. </p>
 
-<H4><a name="Ruby_nn26">34.3.17.1 Exception Unrolling</a></H4>
+<H4><a name="Ruby_nn26">35.3.17.1 Exception Unrolling</a></H4>
 
 
 <p> Whenever a C++ director class routes one of its virtual
@@ -1559,7 +1577,7 @@
 function from Ruby's C API. If any Ruby exception is raised, it will be
 caught here and a C++ exception is raised in its place. </p>
 
-<H2><a name="Ruby_nn27">34.4 Naming</a></H2>
+<H2><a name="Ruby_nn27">35.4 Naming</a></H2>
 
 
 <p>Ruby has several common naming conventions. Constants are
@@ -1597,7 +1615,7 @@
 by SWIG, it is turned off by default in SWIG 1.3.28. However, it is
 planned to become the default option in future releases.</p>
 
-<H3><a name="Ruby_nn28">34.4.1 Defining Aliases</a></H3>
+<H3><a name="Ruby_nn28">35.4.1 Defining Aliases</a></H3>
 
 
 <p> It's a fairly common practice in the Ruby built-ins and
@@ -1667,7 +1685,7 @@
 on <a href="Customization.html#Customization">"Customization
 Features"</a>) for more details).</p>
 
-<H3><a name="Ruby_nn29">34.4.2 Predicate Methods</a></H3>
+<H3><a name="Ruby_nn29">35.4.2 Predicate Methods</a></H3>
 
 
 <p> Ruby methods that return a boolean value and end in a
@@ -1689,7 +1707,7 @@
 <div class="code">
 <pre>%rename("is_it_safe?") is_it_safe();
 
-%typemap(out) int is_it_safe "$result = ($1 != 0) ? Qtrue : Qfalse;";
+%typemap(out) int is_it_safe "$result = ($1 != 0) ? Qtrue : Qfalse;"
 
 int is_it_safe();</pre>
 </div>
@@ -1716,7 +1734,7 @@
 used for other kinds of features apply (see the chapter on <a href="Customization.html#Customization">"Customization
 Features"</a>) for more details). </p>
 
-<H3><a name="Ruby_nn30">34.4.3 Bang Methods</a></H3>
+<H3><a name="Ruby_nn30">35.4.3 Bang Methods</a></H3>
 
 
 <p> Ruby methods that modify an object in-place and end in an
@@ -1748,7 +1766,7 @@
 used for other kinds of features apply (see the chapter on <a href="Customization.html#Customization">"Customization
 Features"</a>) for more details). </p>
 
-<H3><a name="Ruby_nn31">34.4.4 Getters and Setters</a></H3>
+<H3><a name="Ruby_nn31">35.4.4 Getters and Setters</a></H3>
 
 
 <p> Often times a C++ library will expose properties through
@@ -1783,7 +1801,7 @@
 %rename("value=") Foo::setValue(int value);</pre>
 </div>
 
-<H2><a name="Ruby_nn32">34.5 Input and output parameters</a></H2>
+<H2><a name="Ruby_nn32">35.5 Input and output parameters</a></H2>
 
 
 <p> A common problem in some C programs is handling parameters
@@ -1922,10 +1940,10 @@
 <pre>r, c = Example.get_dimensions(m)</pre>
 </div>
 
-<H2><a name="Ruby_nn33">34.6 Exception handling </a></H2>
+<H2><a name="Ruby_nn33">35.6 Exception handling </a></H2>
 
 
-<H3><a name="Ruby_nn34">34.6.1 Using the %exception directive </a></H3>
+<H3><a name="Ruby_nn34">35.6.1 Using the %exception directive </a></H3>
 
 
 <p>The SWIG <tt>%exception</tt> directive can be
@@ -2034,7 +2052,7 @@
 limited to C++ exception handling. See the chapter on <a href="Customization.html#Customization">Customization
 Features</a> for more examples.</p>
 
-<H3><a name="Ruby_nn34_2">34.6.2 Handling Ruby Blocks </a></H3>
+<H3><a name="Ruby_nn34_2">35.6.2 Handling Ruby Blocks </a></H3>
 
 
 <p>One of the highlights of Ruby and most of its standard library
@@ -2101,7 +2119,7 @@
 
 <p>For more information on typemaps, see <a href="#Ruby_nn37">Typemaps</a>.</p>
 
-<H3><a name="Ruby_nn35">34.6.3 Raising exceptions </a></H3>
+<H3><a name="Ruby_nn35">35.6.3 Raising exceptions </a></H3>
 
 
 <p>There are three ways to raise exceptions from C++ code to
@@ -2258,7 +2276,7 @@
 is the exception type. You can raise a custom exception type or one of
 the built-in Ruby exception types.</p>
 
-<H3><a name="Ruby_nn36">34.6.4 Exception classes </a></H3>
+<H3><a name="Ruby_nn36">35.6.4 Exception classes </a></H3>
 
 
 <p>Starting with SWIG 1.3.28, the Ruby module supports the <tt>%exceptionclass</tt>
@@ -2295,7 +2313,7 @@
 <p>For another example look at swig/Examples/ruby/exception_class.
 </p>
 
-<H2><a name="Ruby_nn37">34.7 Typemaps</a></H2>
+<H2><a name="Ruby_nn37">35.7 Typemaps</a></H2>
 
 
 <p> This section describes how you can modify SWIG's default
@@ -2310,7 +2328,7 @@
 in most cases. Typemaps are only used if you want to change some aspect
 of the primitive C-Ruby interface.</p>
 
-<H3><a name="Ruby_nn38">34.7.1 What is a typemap?</a></H3>
+<H3><a name="Ruby_nn38">35.7.1 What is a typemap?</a></H3>
 
 
 <p> A typemap is nothing more than a code generation rule that is
@@ -2467,7 +2485,7 @@
 2</pre>
 </div>
 
-<H3><a name="Ruby_Typemap_scope">34.7.2 Typemap scope</a></H3>
+<H3><a name="Ruby_Typemap_scope">35.7.2 Typemap scope</a></H3>
 
 
 <p> Once defined, a typemap remains in effect for all of the
@@ -2513,7 +2531,7 @@
 };</pre>
 </div>
 
-<H3><a name="Ruby_Copying_a_typemap">34.7.3 Copying a typemap</a></H3>
+<H3><a name="Ruby_Copying_a_typemap">35.7.3 Copying a typemap</a></H3>
 
 
 <p> A typemap is copied by using assignment. For example:</p>
@@ -2555,7 +2573,7 @@
 %apply (char *buf, int len) { (char *buffer, int size) }; // Multiple arguments</pre>
 </div>
 
-<H3><a name="Ruby_Deleting_a_typemap">34.7.4 Deleting a typemap</a></H3>
+<H3><a name="Ruby_Deleting_a_typemap">35.7.4 Deleting a typemap</a></H3>
 
 
 <p> A typemap can be deleted by simply defining no code. For
@@ -2580,7 +2598,7 @@
 will make that type unusable unless you also define a new set of
 typemaps immediately after the clear operation.</p>
 
-<H3><a name="Ruby_Placement_of_typemaps">34.7.5 Placement of typemaps</a></H3>
+<H3><a name="Ruby_Placement_of_typemaps">35.7.5 Placement of typemaps</a></H3>
 
 
 <p> Typemap declarations can be declared in the global scope,
@@ -2651,13 +2669,13 @@
 string</tt>
 .</p>
 
-<H3><a name="Ruby_nn39">34.7.6 Ruby typemaps</a></H3>
+<H3><a name="Ruby_nn39">35.7.6 Ruby typemaps</a></H3>
 
 
 <p>The following list details all of the typemap methods that
 can be used by the Ruby module: </p>
 
-<H4><a name="Ruby_in_typemap">34.7.6.1 "in" typemap</a></H4>
+<H4><a name="Ruby_in_typemap">35.7.6.1 "in" typemap</a></H4>
 
 
 <p>Converts Ruby objects to input
@@ -2724,7 +2742,7 @@
 
 <p> At this time, only zero or one arguments may be converted.</p>
 
-<H4><a name="Ruby_typecheck_typemap">34.7.6.2 "typecheck" typemap</a></H4>
+<H4><a name="Ruby_typecheck_typemap">35.7.6.2 "typecheck" typemap</a></H4>
 
 
 <p> The "typecheck" typemap is used to support overloaded
@@ -2746,7 +2764,7 @@
 "typecheck" typemaps. More details about this follow in a later section
 on "Typemaps and Overloading."</p>
 
-<H4><a name="Ruby_out_typemap">34.7.6.3 "out" typemap</a></H4>
+<H4><a name="Ruby_out_typemap">35.7.6.3 "out" typemap</a></H4>
 
 
 <p>Converts return value of a C function
@@ -2797,7 +2815,7 @@
 </table>
 </div>
 
-<H4><a name="Ruby_arginit_typemap">34.7.6.4 "arginit" typemap</a></H4>
+<H4><a name="Ruby_arginit_typemap">35.7.6.4 "arginit" typemap</a></H4>
 
 
 <p> The "arginit" typemap is used to set the initial value of a
@@ -2812,7 +2830,7 @@
 }</pre>
 </div>
 
-<H4><a name="Ruby_default_typemap">34.7.6.5 "default" typemap</a></H4>
+<H4><a name="Ruby_default_typemap">35.7.6.5 "default" typemap</a></H4>
 
 
 <p> The "default" typemap is used to turn an argument into a
@@ -2837,7 +2855,7 @@
 Default/optional arguments</a> section for further information on
 default argument wrapping.</p>
 
-<H4><a name="Ruby_check_typemap">34.7.6.6 "check" typemap</a></H4>
+<H4><a name="Ruby_check_typemap">35.7.6.6 "check" typemap</a></H4>
 
 
 <p> The "check" typemap is used to supply value checking code
@@ -2852,7 +2870,7 @@
 }</pre>
 </div>
 
-<H4><a name="Ruby_argout_typemap_">34.7.6.7 "argout" typemap</a></H4>
+<H4><a name="Ruby_argout_typemap_">35.7.6.7 "argout" typemap</a></H4>
 
 
 <p> The "argout" typemap is used to return values from arguments.
@@ -2906,7 +2924,7 @@
 
 <p> See the <tt>typemaps.i</tt> library for examples.</p>
 
-<H4><a name="Ruby_freearg_typemap_">34.7.6.8 "freearg" typemap</a></H4>
+<H4><a name="Ruby_freearg_typemap_">35.7.6.8 "freearg" typemap</a></H4>
 
 
 <p> The "freearg" typemap is used to cleanup argument data. It is
@@ -2933,7 +2951,7 @@
 that may be used in other typemaps whenever a wrapper function needs to
 abort prematurely.</p>
 
-<H4><a name="Ruby_newfree_typemap">34.7.6.9 "newfree" typemap</a></H4>
+<H4><a name="Ruby_newfree_typemap">35.7.6.9 "newfree" typemap</a></H4>
 
 
 <p> The "newfree" typemap is used in conjunction with the <tt>%newobject</tt>
@@ -2957,7 +2975,7 @@
 <p> See <a href="Customization.html#Customization_ownership">Object
 ownership and %newobject</a> for further details.</p>
 
-<H4><a name="Ruby_memberin_typemap">34.7.6.10 "memberin" typemap</a></H4>
+<H4><a name="Ruby_memberin_typemap">35.7.6.10 "memberin" typemap</a></H4>
 
 
 <p> The "memberin" typemap is used to copy data from<em> an
@@ -2975,21 +2993,21 @@
 already provides a default implementation for arrays, strings, and
 other objects.</p>
 
-<H4><a name="Ruby_varin_typemap">34.7.6.11 "varin" typemap</a></H4>
+<H4><a name="Ruby_varin_typemap">35.7.6.11 "varin" typemap</a></H4>
 
 
 <p> The "varin" typemap is used to convert objects in the target
 language to C for the purposes of assigning to a C/C++ global variable.
 This is implementation specific.</p>
 
-<H4><a name="Ruby_varout_typemap_">34.7.6.12 "varout" typemap</a></H4>
+<H4><a name="Ruby_varout_typemap_">35.7.6.12 "varout" typemap</a></H4>
 
 
 <p> The "varout" typemap is used to convert a C/C++ object to an
 object in the target language when reading a C/C++ global variable.
 This is implementation specific.</p>
 
-<H4><a name="Ruby_throws_typemap">34.7.6.13 "throws" typemap</a></H4>
+<H4><a name="Ruby_throws_typemap">35.7.6.13 "throws" typemap</a></H4>
 
 
 <p> The "throws" typemap is only used when SWIG parses a C++
@@ -3030,7 +3048,7 @@
 deal with them. For a neat way to handle these, see the <a href="Customization.html#Customization_exception">Exception
 handling with %exception</a> section.</p>
 
-<H4><a name="Ruby_directorin_typemap">34.7.6.14 directorin typemap</a></H4>
+<H4><a name="Ruby_directorin_typemap">35.7.6.14 directorin typemap</a></H4>
 
 
 <p>Converts C++ objects in director
@@ -3089,7 +3107,7 @@
 </table>
 </div>
 
-<H4><a name="Ruby_directorout_typemap">34.7.6.15 directorout typemap</a></H4>
+<H4><a name="Ruby_directorout_typemap">35.7.6.15 directorout typemap</a></H4>
 
 
 <p>Converts Ruby objects in director
@@ -3162,7 +3180,7 @@
 
 </p>
 
-<H4><a name="Ruby_directorargout_typemap">34.7.6.16 directorargout typemap</a></H4>
+<H4><a name="Ruby_directorargout_typemap">35.7.6.16 directorargout typemap</a></H4>
 
 
 <p>Output argument processing in director
@@ -3220,19 +3238,19 @@
 </table>
 </div>
 
-<H4><a name="Ruby_ret_typemap">34.7.6.17 ret typemap</a></H4>
+<H4><a name="Ruby_ret_typemap">35.7.6.17 ret typemap</a></H4>
 
 
 <p>Cleanup of function return values
 </p>
 
-<H4><a name="Ruby_globalin_typemap">34.7.6.18 globalin typemap</a></H4>
+<H4><a name="Ruby_globalin_typemap">35.7.6.18 globalin typemap</a></H4>
 
 
 <p>Setting of C global variables
 </p>
 
-<H3><a name="Ruby_nn40">34.7.7 Typemap variables</a></H3>
+<H3><a name="Ruby_nn40">35.7.7 Typemap variables</a></H3>
 
 
 <p>
@@ -3282,7 +3300,7 @@
 <div class="indent">The Ruby name of the wrapper function
 being created. </div>
 
-<H3><a name="Ruby_nn41">34.7.8 Useful Functions</a></H3>
+<H3><a name="Ruby_nn41">35.7.8 Useful Functions</a></H3>
 
 
 <p> When you write a typemap, you usually have to work directly
@@ -3297,7 +3315,7 @@
 That should help you avoid having to rewrite a lot of typemaps
 across multiple languages.</p>
 
-<H4><a name="Ruby_nn42">34.7.8.1 C Datatypes to Ruby Objects</a></H4>
+<H4><a name="Ruby_nn42">35.7.8.1 C Datatypes to Ruby Objects</a></H4>
 
 
 <div class="diagram">
@@ -3339,7 +3357,7 @@
 </table>
 </div>
 
-<H4><a name="Ruby_nn43">34.7.8.2 Ruby Objects to C Datatypes</a></H4>
+<H4><a name="Ruby_nn43">35.7.8.2 Ruby Objects to C Datatypes</a></H4>
 
 
 <p>Here, while the Ruby versions return the value directly, the SWIG
@@ -3393,7 +3411,7 @@
     </tr>
     <tr>
       <td>char * StringValuePtr(String)</td>
-      <td>SWIG_AsCharPtrAndSize(VALUE, char*, size_t, int* alloc)</td>
+      <td>SWIG_AsCharPtrAndSize(VALUE, char**, size_t*, int* alloc)</td>
     </tr>
     <tr>
       <td>char * rb_str2cstr(String, int*length)</td>
@@ -3407,7 +3425,7 @@
 </table>
 </div>
 
-<H4><a name="Ruby_nn44">34.7.8.3 Macros for VALUE</a></H4>
+<H4><a name="Ruby_nn44">35.7.8.3 Macros for VALUE</a></H4>
 
 
 <p> <tt>RSTRING_LEN(str)</tt> </p>
@@ -3430,7 +3448,7 @@
 
 <div class="indent">pointer to array storage</div>
 
-<H4><a name="Ruby_nn45">34.7.8.4 Exceptions</a></H4>
+<H4><a name="Ruby_nn45">35.7.8.4 Exceptions</a></H4>
 
 
 <p> <tt>void rb_raise(VALUE exception, const char *fmt,
@@ -3509,7 +3527,7 @@
 flag. The given format string <i>fmt</i> and remaining
 arguments are interpreted as with <tt>printf()</tt>. </div>
 
-<H4><a name="Ruby_nn46">34.7.8.5 Iterators</a></H4>
+<H4><a name="Ruby_nn46">35.7.8.5 Iterators</a></H4>
 
 
 <p> <tt>void rb_iter_break()</tt> </p>
@@ -3555,14 +3573,14 @@
 <div class="indent"> Equivalent to Ruby's <tt>throw</tt>.
 </div>
 
-<H3><a name="Ruby_nn47">34.7.9 Typemap Examples</a></H3>
+<H3><a name="Ruby_nn47">35.7.9 Typemap Examples</a></H3>
 
 
 <p> This section includes a few examples of typemaps. For more
 examples, you might look at the examples in the <tt>Example/ruby</tt>
 directory. </p>
 
-<H3><a name="Ruby_nn48">34.7.10 Converting a Ruby array to a char **</a></H3>
+<H3><a name="Ruby_nn48">35.7.10 Converting a Ruby array to a char **</a></H3>
 
 
 <p> A common problem in many C programs is the processing of
@@ -3627,7 +3645,7 @@
 the array, the "freearg" typemap is used to later release this memory
 after the execution of the C function. </p>
 
-<H3><a name="Ruby_nn49">34.7.11 Collecting arguments in a hash</a></H3>
+<H3><a name="Ruby_nn49">35.7.11 Collecting arguments in a hash</a></H3>
 
 
 <p> Ruby's solution to the "keyword arguments" capability of some
@@ -3841,7 +3859,7 @@
 program that uses the extension, can be found in the <tt>Examples/ruby/hashargs</tt>
 directory of the SWIG distribution. </p>
 
-<H3><a name="Ruby_nn50">34.7.12 Pointer handling</a></H3>
+<H3><a name="Ruby_nn50">35.7.12 Pointer handling</a></H3>
 
 
 <p> Occasionally, it might be necessary to convert pointer values
@@ -3900,7 +3918,7 @@
 }</pre>
 </div>
 
-<H4><a name="Ruby_nn51">34.7.12.1 Ruby Datatype Wrapping</a></H4>
+<H4><a name="Ruby_nn51">35.7.12.1 Ruby Datatype Wrapping</a></H4>
 
 
 <p> <tt>VALUE Data_Wrap_Struct(VALUE class, void
@@ -3927,7 +3945,7 @@
 type <i>c-type</i> from the data object <i>obj</i>
 and assigns that pointer to <i>ptr</i>. </div>
 
-<H3><a name="Ruby_nn52">34.7.13 Example: STL Vector to Ruby Array</a></H3>
+<H3><a name="Ruby_nn52">35.7.13 Example: STL Vector to Ruby Array</a></H3>
 
 
 <p>Another use for macros and type maps is to create a Ruby array
@@ -4019,7 +4037,7 @@
 which does much more than this. Refer to the section called
 the<a href="#Ruby_nn23_1"> C++ Standard Template Library</a>.
 
-<H2><a name="Ruby_nn65">34.8 Docstring Features</a></H2>
+<H2><a name="Ruby_nn65">35.8 Docstring Features</a></H2>
 
 
 <p>
@@ -4053,7 +4071,7 @@
 $ rdoc -r file_wrap.c
 </pre></div>
 
-<H3><a name="Ruby_nn66">34.8.1 Module docstring</a></H3>
+<H3><a name="Ruby_nn66">35.8.1 Module docstring</a></H3>
 
 
 <p>
@@ -4083,7 +4101,7 @@
 %module(docstring=DOCSTRING) xrc</pre>
 </div>
 
-<H3><a name="Ruby_nn67">34.8.2 %feature("autodoc")</a></H3>
+<H3><a name="Ruby_nn67">35.8.2 %feature("autodoc")</a></H3>
 
 
 <p>Since SWIG does know everything about the function it wraps,
@@ -4104,7 +4122,7 @@
 feature, described below.
 </p>
 
-<H4><a name="Ruby_nn68">34.8.2.1 %feature("autodoc", "0")</a></H4>
+<H4><a name="Ruby_nn68">35.8.2.1 %feature("autodoc", "0")</a></H4>
 
 
 <p>
@@ -4128,7 +4146,7 @@
   ...</pre>
 </div>
 
-<H4><a name="Ruby_autodoc1">34.8.2.2 %feature("autodoc", "1")</a></H4>
+<H4><a name="Ruby_autodoc1">35.8.2.2 %feature("autodoc", "1")</a></H4>
 
 
 <p>
@@ -4148,7 +4166,7 @@
   ...</pre>
 </div>
 
-<H4><a name="Ruby_autodoc2">34.8.2.3 %feature("autodoc", "2")</a></H4>
+<H4><a name="Ruby_autodoc2">35.8.2.3 %feature("autodoc", "2")</a></H4>
 
 
 <p>
@@ -4160,7 +4178,7 @@
 this:
 </p>
 
-<H4><a name="Ruby_feature_autodoc3">34.8.2.4 %feature("autodoc", "3")</a></H4>
+<H4><a name="Ruby_feature_autodoc3">35.8.2.4 %feature("autodoc", "3")</a></H4>
 
 
 <p>
@@ -4181,7 +4199,7 @@
         bar - Bar</pre>
 </div>
 
-<H4><a name="Ruby_nn70">34.8.2.5 %feature("autodoc", "docstring")</a></H4>
+<H4><a name="Ruby_nn70">35.8.2.5 %feature("autodoc", "docstring")</a></H4>
 
 
 <p>
@@ -4197,7 +4215,7 @@
 void GetPosition(int* OUTPUT, int* OUTPUT);</pre>
 </div>
 
-<H3><a name="Ruby_nn71">34.8.3 %feature("docstring")</a></H3>
+<H3><a name="Ruby_nn71">35.8.3 %feature("docstring")</a></H3>
 
 
 <p>
@@ -4208,10 +4226,10 @@
 If an item already has an autodoc string then it is combined with the
 docstring and they are output together. </p>
 
-<H2><a name="Ruby_nn53">34.9 Advanced Topics</a></H2>
+<H2><a name="Ruby_nn53">35.9 Advanced Topics</a></H2>
 
 
-<H3><a name="Ruby_operator_overloading">34.9.1 Operator overloading</a></H3>
+<H3><a name="Ruby_operator_overloading">35.9.1 Operator overloading</a></H3>
 
 
 <p> SWIG allows operator overloading with, by using the <tt>%extend</tt>
@@ -4392,7 +4410,7 @@
 parses the expression <i>a != b</i> as <i>!(a == b)</i>.
 </p>
 
-<H3><a name="Ruby_nn55">34.9.2 Creating Multi-Module Packages</a></H3>
+<H3><a name="Ruby_nn55">35.9.2 Creating Multi-Module Packages</a></H3>
 
 
 <p> The chapter on <a href="Modules.html#Modules">Working
@@ -4518,7 +4536,7 @@
 5.0</pre>
 </div>
 
-<H3><a name="Ruby_nn56">34.9.3 Specifying Mixin Modules</a></H3>
+<H3><a name="Ruby_nn56">35.9.3 Specifying Mixin Modules</a></H3>
 
 
 <p> The Ruby language doesn't support multiple inheritance, but
@@ -4585,7 +4603,7 @@
 on <a href="Customization.html#Customization">"Customization
 Features"</a>) for more details). </p>
 
-<H2><a name="Ruby_nn57">34.10 Memory Management</a></H2>
+<H2><a name="Ruby_nn57">35.10 Memory Management</a></H2>
 
 
 <p>One of the most common issues in generating SWIG bindings for
@@ -4608,7 +4626,7 @@
 invoked. Clearly, developing a SWIG wrapper requires a thorough
 understanding of how the underlying library manages memory.</p>
 
-<H3><a name="Ruby_nn58">34.10.1 Mark and Sweep Garbage Collector </a></H3>
+<H3><a name="Ruby_nn58">35.10.1 Mark and Sweep Garbage Collector </a></H3>
 
 
 <p>Ruby uses a mark and sweep garbage collector. When the garbage
@@ -4639,7 +4657,7 @@
 C++ struct, then a "free" function must be defined that deallocates
 this memory. </p>
 
-<H3><a name="Ruby_nn59">34.10.2 Object Ownership</a></H3>
+<H3><a name="Ruby_nn59">35.10.2 Object Ownership</a></H3>
 
 
 <p>As described above, memory management depends on clearly
@@ -4784,7 +4802,7 @@
 
 <p> This code can be seen in swig/examples/ruby/tracking.</p>
 
-<H3><a name="Ruby_nn60">34.10.3 Object Tracking</a></H3>
+<H3><a name="Ruby_nn60">35.10.3 Object Tracking</a></H3>
 
 
 <p>The remaining parts of this section will use the class library
@@ -5010,7 +5028,7 @@
 also have to call the <tt>SWIG_RubyRemoveTracking</tt> and <tt>RubyUnlinkObjects</tt>
 methods.</p>
 
-<H3><a name="Ruby_nn61">34.10.4 Mark Functions</a></H3>
+<H3><a name="Ruby_nn61">35.10.4 Mark Functions</a></H3>
 
 
 <p>With a bit more testing, we see that our class library still
@@ -5139,7 +5157,7 @@
 
 <p>This code can be seen in swig/examples/ruby/mark_function.</p>
 
-<H3><a name="Ruby_nn62">34.10.5 Free Functions</a></H3>
+<H3><a name="Ruby_nn62">35.10.5 Free Functions</a></H3>
 
 
 <p>By default, SWIG creates a "free" function that is called when
@@ -5307,7 +5325,7 @@
 
 <p>This code can be seen in swig/examples/ruby/free_function.</p>
 
-<H3><a name="Ruby_nn63">34.10.6 Embedded Ruby and the C++ Stack</a></H3>
+<H3><a name="Ruby_nn63">35.10.6 Embedded Ruby and the C++ Stack</a></H3>
 
 
 <p>As has been said, the Ruby GC runs and marks objects before
diff --git a/Doc/Manual/SWIG.html b/Doc/Manual/SWIG.html
index aec48ef..a7a01d6 100644
--- a/Doc/Manual/SWIG.html
+++ b/Doc/Manual/SWIG.html
@@ -47,6 +47,7 @@
 <li><a href="#SWIG_rename_ignore">Renaming and ignoring declarations</a>
 <ul>
 <li><a href="#SWIG_nn29">Simple renaming of specific identifiers</a>
+<li><a href="#SWIG_ignore">Ignoring identifiers</a>
 <li><a href="#SWIG_advanced_renaming">Advanced renaming support</a>
 <li><a href="#SWIG_limiting_renaming">Limiting global renaming rules</a>
 <li><a href="#SWIG_chosen_unignore">Ignoring everything then wrapping a few selected symbols</a>
@@ -127,7 +128,7 @@
      -lua            - Generate Lua wrappers
      -octave         - Generate Octave wrappers
      -perl5          - Generate Perl 5 wrappers
-     -php7           - Generate PHP 7 wrappers
+     -php7           - Generate PHP 8 or later wrappers
      -python         - Generate Python wrappers
      -r              - Generate R (aka GNU S) wrappers
      -ruby           - Generate Ruby wrappers
@@ -154,6 +155,7 @@
      -debug-symbols  - Display target language symbols in the symbol tables
      -debug-csymbols - Display C symbols in the symbol tables
      -debug-lsymbols - Display target language layer symbols
+     -debug-quiet    - Display less parse tree node debug info when using other -debug options
      -debug-tags     - Display information about the tags found in the interface
      -debug-template - Display information for debugging templates
      -debug-top &lt;n&gt;  - Display entire parse tree at stages 1-4, &lt;n&gt; is a csv list of stages
@@ -163,7 +165,7 @@
      -debug-tmused   - Display typemaps used debugging information
      -directors      - Turn on director mode for all the classes, mainly for testing
      -dirprot        - Turn on wrapping of protected members for director classes (default)
-     -D&lt;symbol&gt;      - Define a symbol &lt;symbol&gt; (for conditional compilation)
+     -D&lt;symbol&gt;[=&lt;value&gt;] - Define symbol &lt;symbol&gt; (for conditional compilation)
      -E              - Preprocess only, does not generate wrapper code
      -external-runtime [file] - Export the SWIG runtime stack
      -fakeversion &lt;v&gt;- Make SWIG fake the program version number to &lt;v&gt;
@@ -183,7 +185,6 @@
      -includeall     - Follow all #include statements
      -l&lt;ifile&gt;       - Include SWIG library file &lt;ifile&gt;
      -macroerrors    - Report errors inside macros
-     -makedefault    - Create default constructors/destructors (the default)
      -M              - List all dependencies
      -MD             - Is equivalent to `-M -MF &lt;file&gt;', except `-E' is not implied
      -MF &lt;file&gt;      - Generate dependencies into &lt;file&gt; and continue generating wrappers
@@ -194,7 +195,6 @@
      -MT &lt;target&gt;    - Set the target of the rule emitted by dependency generation
      -nocontract     - Turn off contract checking
      -nocpperraswarn - Do not treat the preprocessor #error statement as #warning
-     -nodefault      - Do not generate default constructors nor default destructors
      -nodefaultctor  - Do not generate implicit default constructors
      -nodefaultdtor  - Do not generate implicit default destructors
      -nodirprot      - Do not wrap director protected members
@@ -208,16 +208,18 @@
      -oh &lt;headfile&gt;  - Set name of C++ output header file for directors to &lt;headfile&gt;
      -outcurrentdir  - Set default output dir to current dir instead of input file's path
      -outdir &lt;dir&gt;   - Set language specific files output directory to &lt;dir&gt;
-     -pcreversion    - Display PCRE version information
+     -pcreversion    - Display PCRE2 version information
      -small          - Compile in virtual elimination and compact mode
+     -std=&lt;standard&gt; - Set the C or C++ language &lt;standard&gt; for inputs
      -swiglib        - Report location of SWIG library and exit
      -templatereduce - Reduce all the typedefs in templates
+     -U&lt;symbol&gt;      - Undefine symbol &lt;symbol&gt;
      -v              - Run in verbose mode
      -version        - Display SWIG version number
      -Wall           - Remove all warning suppression, also implies -Wextra
      -Wallkw         - Enable keyword warnings for all the supported languages
      -Werror         - Treat warnings as errors
-     -Wextra         - Adds the following additional warnings: 202,309,403,405,512,321,322
+     -Wextra         - Adds the following additional warnings: 309,403,405,512,321,322
      -w&lt;list&gt;        - Suppress/add warning messages, eg -w401,+321 - see Warnings.html
      -xmlout &lt;file&gt;  - Write XML version of the parse tree to &lt;file&gt; after normal processing
 </pre></div>
@@ -827,6 +829,32 @@
 </div>
 
 <p>
+This logic can lead to false attempts at converting <tt>#define</tt> into <tt>%constant</tt> though.
+For example the following case does not have any undefined symbols within the macro:
+</p>
+
+<div class="code">
+<pre>
+// For indicating pure virtual functions such as: virtual void f() PURE;
+#define PURE = 0
+</pre>
+</div>
+
+<p>
+A warning is issued:
+</p>
+
+<div class="shell">
+<pre>
+pure.h:1: Warning 305: Bad constant value (ignored).
+</pre>
+</div>
+
+<p>
+In such cases simply ignore the warning or suppress it using the normal warning suppression techniques.
+</p>
+
+<p>
 The use of constant expressions is allowed, but SWIG does not evaluate
 them. Rather, it passes them through to the output file and lets the C
 compiler perform the final evaluation (SWIG does perform a limited
@@ -1443,14 +1471,14 @@
 <pre>
 /* C mode */
 void foo_set(char *value) {
-  if (foo) free(foo);
+  free(foo);
   foo = (char *) malloc(strlen(value)+1);
   strcpy(foo, value);
 }
 
 /* C++ mode.  When -c++ option is used */
 void foo_set(char *value) {
-  if (foo) delete [] foo;
+  delete [] foo;
   foo = new char[strlen(value)+1];
   strcpy(foo, value);
 }
@@ -1752,13 +1780,6 @@
 char * const version="1.0";  /* Read only variable */
 </pre></div>
 
-<p>
-<b>Compatibility note:</b> Read-only access used to be controlled by a pair of directives
-<tt>%readonly</tt> and <tt>%readwrite</tt>.   Although these directives still work, they
-generate a warning message.   Simply change the directives to <tt>%immutable;</tt> and
-<tt>%mutable;</tt> to silence the warning.  Don't forget the extra semicolon!
-</p>
-
 <H3><a name="SWIG_rename_ignore">5.4.7 Renaming and ignoring declarations</a></H3>
 
 
@@ -1816,6 +1837,25 @@
 </pre></div>
 
 <p>
+A new <tt>%rename</tt> for the same name will replace the current
+<tt>%rename</tt> for all uses after it in the file, and setting the
+new name to "" will remove the rename.  So, for instance, if you
+wanted to rename some things in one file and not in another, you could
+do:
+</p>
+
+<div class="code">
+<pre>
+  %rename(print1) print;
+  %include "header1.h" //Anything "print" in here will become "print1"
+  %rename(print2) print;
+  %include "header2.h" //Anything "print" in here will become "print2"
+  %rename("") print;
+  %include "header3.h" //Anything "print" in here will remain "print"
+</pre>
+</div>
+
+<p>
 SWIG does not normally perform any checks to see if the functions it wraps are
 already defined in the target scripting language. However, if you are
 careful about namespaces and your use of modules, you can usually
@@ -1831,6 +1871,9 @@
 for method overloading and default arguments.
 </p>
 
+<H4><a name="SWIG_ignore">5.4.7.2 Ignoring identifiers</a></H4>
+
+
 <p>
 Closely related to <tt>%rename</tt> is the <tt>%ignore</tt> directive.  <tt>%ignore</tt> instructs SWIG
 to ignore declarations that match a given identifier.  For example:
@@ -1854,23 +1897,7 @@
 declarations.  If you need to remove a whole section of problematic code, the SWIG preprocessor should be used instead.
 </p>
 
-<p>
-<b>Compatibility note: </b> Older versions of SWIG provided a special <tt>%name</tt> directive for renaming declarations.
-For example:
-</p>
-
-<div class="code">
-<pre>
-%name(output) extern void print(const char *);
-</pre>
-</div>
-
-<p>
-This directive is still supported, but it is deprecated and should probably be avoided.  The <tt>%rename</tt>
-directive is more powerful and better supports wrapping of raw header file information.
-</p>
-
-<H4><a name="SWIG_advanced_renaming">5.4.7.2 Advanced renaming support</a></H4>
+<H4><a name="SWIG_advanced_renaming">5.4.7.3 Advanced renaming support</a></H4>
 
 
 <p>
@@ -1994,10 +2021,10 @@
 <tr>
     <td><span style="white-space: nowrap;"><tt>regex:/pattern/subst/</tt></span></td>
     <td>String after (Perl-like) regex substitution operation. This function
-    allows to apply arbitrary regular expressions to the identifier names. The
+    allows applying arbitrary regular expressions to the identifier names. The
     <i>pattern</i> part is a regular expression in Perl syntax (as supported
-    by the <a href="http://www.pcre.org/">Perl Compatible Regular Expressions (PCRE)</a>)
-    library and the <i>subst</i> string
+    by the <a href="https://www.pcre.org/">Perl Compatible Regular Expressions</a>)
+    (PCRE2 library) and the <i>subst</i> string
     can contain back-references of the form <tt>\N</tt> where <tt>N</tt> is a digit
     from 0 to 9, or one of the following escape sequences: <tt>\l</tt>, <tt>\L</tt>,
     <tt>\u</tt>, <tt>\U</tt> or <tt>\E</tt>. The back-references are replaced with the
@@ -2015,23 +2042,10 @@
     <tt>%rename("regex:/(\\w+)_(.*)/\\u\\2/")</tt></td>
     <td><tt>prefix_print</tt></td><td><tt>Print</tt></td>
 </tr>
-<tr>
-    <td><tt>command:cmd</tt></td>
-    <td>Output of an external command <tt>cmd</tt> with the string passed to
-    it as input. Notice that this function is extremely slow compared to all
-    the other ones as it involves spawning a separate process and using it for
-    many declarations is not recommended. The <i>cmd</i> is not enclosed in
-    square brackets but must be terminated with a triple <tt>'&lt;'</tt> sign,
-    e.g. <tt>%rename("command:tr&nbsp;-d&nbsp;aeiou &lt;&lt;&lt;")</tt>
-    (nonsensical example removing all vowels)</td>
-    <td><tt>Print</tt></td><td><tt>Prnt</tt></td>
-</tr>
 </table>
 
 <p>
-The most general function of all of the above ones (not counting
-<tt>command</tt> which is even more powerful in principle but which should
-generally be avoided because of performance considerations) is the
+The most general function of all of the above ones is the
 <tt>regex</tt> one. Here are some more examples of its use:
 </p>
 
@@ -2079,7 +2093,7 @@
 multiple declarations using the previously described matching possibilities.
 </p>
 
-<H4><a name="SWIG_limiting_renaming">5.4.7.3 Limiting global renaming rules</a></H4>
+<H4><a name="SWIG_limiting_renaming">5.4.7.4 Limiting global renaming rules</a></H4>
 
 
 <p>
@@ -2111,11 +2125,15 @@
 restricts it to the enum elements. SWIG also provides convenience macros for
 such match expressions, for example
 </p>
+
 <div class="code">
 <pre>
 %rename("%(title)s", %$isenumitem) "";
+// same as:
+%rename("%(title)s", match="enumitem") "";
 </pre>
 </div>
+
 <p>
 will capitalize the names of all the enum elements but not change the case of
 the other declarations. Similarly, <tt>%$isclass</tt>, <tt>%$isfunction</tt>,
@@ -2126,6 +2144,56 @@
 </p>
 
 <p>
+A logical not is also possible by using <tt>notmatch</tt>.
+For example, <tt>notmatch="enumitem"</tt> will restrict the
+match to all items that are not enum elements.
+There is also a <tt>%$not</tt> macro which simply expands to "not".
+Be careful using this as some of the other macros in <tt>swig.swg</tt>
+are complex expressions and so it will only "notmatch" the first part
+of the expression.
+</p>
+
+<div class="code">
+<pre>
+%rename("%(title)s", %$not %$isenumitem) "";
+// same as:
+%rename("%(title)s", notmatch="enumitem") "";
+</pre>
+</div>
+
+<p>
+For a comprehensive understanding of how the matching works, the internal
+<a href="Extending.html#Extending_nn8">parse tree</a> needs to be examined using the
+command line option: <tt>-debug-module 1 -debug-quiet</tt>.
+A snippet of the resulting output might be:
+</p>
+
+<div class="shell">
+<pre>
+            +++ destructor ----------------------------------------
+            | access       - "public"
+            | decl         - "f()."
+            | ismember     - "1"
+            | name         - "~Shape"
+            | storage      - "virtual"
+            | sym:name     - "~Shape"
+</pre>
+</div>
+
+<p>
+Here the node type is a "destructor" and in order to match all destructor nodes, use
+<tt>match="destructor"</tt>. To match one of the listed attributes in the node,
+such as when the storage is virtual, use <tt>match$storage="virtual"</tt>.
+This will match all nodes that have a storage attribute set to "virtual".
+To match only virtual destructors, combine them and use <tt>match="destructor", match$storage="virtual"</tt>.
+</p>
+
+<p>
+While the vast majority of these internal parse tree nodes are unlikely to change from one version of
+SWIG to the next, <b>use these matching rules at your own risk</b> as there are no guarantees that they will not change.
+</p>
+
+<p>
 In addition to literally matching some string with <tt>match</tt> you can
 also use <tt>regexmatch</tt> or <tt>notregexmatch</tt> to match a string
 against a regular expression. For example, to ignore all functions having
@@ -2177,7 +2245,7 @@
 </p>
 
 
-<H4><a name="SWIG_chosen_unignore">5.4.7.4 Ignoring everything then wrapping a few selected symbols</a></H4>
+<H4><a name="SWIG_chosen_unignore">5.4.7.5 Ignoring everything then wrapping a few selected symbols</a></H4>
 
 
 <p>
@@ -2201,6 +2269,23 @@
 %rename("%s") Star::shine; // named method
 
 %include "myheader.h"
+
+%rename("%s") ""; // Undo the %ignore
+</pre>
+</div>
+
+<p>
+If <tt>Star</tt> was in the <tt>Galaxy</tt> namespace, you would need
+to unignore the namespace, too, and add the namespace to all the
+renames:
+</p>
+
+<div class="code">
+<pre>
+%rename("%s") Galaxy;
+%rename("%s") Galaxy::Star;
+%rename("%s") Galaxy::Star::Star;
+...
 </pre>
 </div>
 
@@ -2215,6 +2300,7 @@
 %rename($ignore, %$isclass) ""; // Only ignore all classes
 %rename("%s") Star; // Unignore 'Star'
 %include "myheader.h"
+%rename("%s", %$isclass) ""; // Stop ignoring all classes
 </pre>
 </div>
 
@@ -2420,6 +2506,46 @@
 </p>
 
 <p>
+ISO C has a separate tag name space in which the names of structures,
+unions and enumerated types are put, which is separate from the
+name space for ordinary identifiers (function names, object names,
+typedef names, enumeration constants).  For example, this is valid
+ISO C because <tt>Foo</tt> the struct tag and <tt>Foo</tt> the function
+name are in different name spaces:
+</p>
+
+<div class="code"><pre>
+struct Foo {
+  int bar;
+};
+
+int Foo(void) { return 42; }
+</pre></div>
+
+<p>
+SWIG doesn't currently implement this separate tag name space and
+for the above example you'll get:
+</p>
+
+<div class="code"><pre>
+foo.i:5: Warning 302: Redefinition of identifier 'Foo' as Foo(void) ignored,
+foo.i:1: Warning 302: previous definition of 'Foo'.
+
+</pre></div>
+
+<p>
+In practice this rarely actually causes problems, particular because
+SWIG has special handling for <tt>typedef</tt> so cases such as this
+work:
+</p>
+
+<div class="code"><pre>
+typedef struct Foo {
+  int bar;
+} Foo;
+</pre></div>
+
+<p>
 If SWIG encounters the definition of a structure or union, it
 creates a set of accessor functions. Although SWIG does not need
 structure definitions to build an interface, providing definitions
@@ -2430,8 +2556,7 @@
 <div class="code"><pre>
 struct Vector {
   double x, y, z;
-}
-
+};
 </pre></div>
 
 <p>
@@ -2568,8 +2693,7 @@
 }
 
 char *Foo_name_set(Foo *obj, char *c) {
-  if (obj-&gt;name)
-    free(obj-&gt;name);
+  free(obj-&gt;name);
   obj-&gt;name = (char *) malloc(strlen(c)+1);
   strcpy(obj-&gt;name, c);
   return obj-&gt;name;
@@ -2707,6 +2831,11 @@
 </pre>
 </div>
 
+<p>
+If you have accessor methods that you want to use as attributes in the
+target language, you can make them appear as data members using
+<a href="Library.html#Library_attributes">attributes.i</a>.
+</p>
 
 <p>
 <b>Compatibility Note:</b>  SWIG-1.3.11 and earlier releases transformed all non-primitive member datatypes
@@ -2791,14 +2920,14 @@
 
 <p>
 <b>Compatibility note:</b> Prior to SWIG-1.3.7, SWIG did not generate default constructors
-or destructors unless you explicitly turned them on using <tt>-make_default</tt>. 
+or destructors unless you explicitly turned them on.
 However, it appears that most users want to have constructor and destructor functions so it
 has now been enabled as the default behavior.
 </p>
 
 <p>
-<b>Note:</b> There are also the <tt>-nodefault</tt> option and
-<tt>%nodefault</tt> directive, which disable both the default or
+<b>Note:</b> There is also the
+<tt>%nodefault</tt> directive, which disables both the default or
 implicit destructor generation. This could lead to memory leaks across 
 the target languages, and it is highly recommended you don't use them.
 </p>
@@ -2951,6 +3080,11 @@
 </div>
 
 <p>
+You'll also need to use these names if you want to directly call methods added
+using <tt>%extend</tt> from other C/C++ code.
+</p>
+
+<p>
 The name used for %extend should be the name of the struct and not the name of any typedef to the struct.
 For example:
 </p>
@@ -3070,13 +3204,6 @@
 be entirely synthesized from existing attributes of the structure or obtained elsewhere).
 </p>
 
-<p>
-<b>Compatibility note:</b>  The <tt>%extend</tt> directive is a new
-name for the <tt>%addmethods</tt> directive.  Since <tt>%addmethods</tt> could
-be used to extend a structure with more than just methods, a more suitable
-directive name has been chosen.
-</p>
-
 <H3><a name="SWIG_nested_structs">5.5.7 Nested structures</a></H3>
 
 
@@ -3197,7 +3324,7 @@
 <pre>
 static int
 _wrap_Vector_x_get(ClientData clientData, Tcl_Interp *interp, 
-                   int objc, Tcl_Obj *CONST objv[]) {
+                   int objc, Tcl_Obj *const objv[]) {
   struct Vector *arg1 ;
   double result ;
 
@@ -3508,8 +3635,8 @@
 other problems.  The best way to deal with this is to simply copy the offending
 code into a separate interface file and edit it.   However, the SWIG developers
 have worked very hard to improve the SWIG parser--you should report parsing errors
-to the <a href="http://www.swig.org/mail.html">swig-devel mailing list</a> or to the 
-<a href="http://www.swig.org/bugs.html">SWIG bug tracker</a>.
+to the <a href="https://www.swig.org/mail.html">swig-devel mailing list</a> or to the
+<a href="https://www.swig.org/bugs.html">SWIG bug tracker</a>.
 </p>
 
 <H3><a name="SWIG_nn47">5.7.2 The SWIG interface file</a></H3>
diff --git a/Doc/Manual/SWIGPlus.html b/Doc/Manual/SWIGPlus.html
index dc9ae0f..17cfde3 100644
--- a/Doc/Manual/SWIGPlus.html
+++ b/Doc/Manual/SWIGPlus.html
@@ -34,6 +34,12 @@
 <li><a href="#SWIGPlus_nn15">Protection</a>
 <li><a href="#SWIGPlus_nn16">Enums and constants</a>
 <li><a href="#SWIGPlus_nn17">Friends</a>
+<ul>
+<li><a href="#SWIGPlus_friend_classes">Friend classes</a>
+<li><a href="#SWIGPlus_friend_function_definitions">Friend function definitions</a>
+<li><a href="#SWIGPlus_friend_function_declarations">Friend function declarations</a>
+<li><a href="#SWIGPlus_friends_unqualified">Unqualified friend functions</a>
+</ul>
 <li><a href="#SWIGPlus_nn18">References and pointers</a>
 <li><a href="#SWIGPlus_nn19">Pass and return by value</a>
 <li><a href="#SWIGPlus_nn20">Inheritance</a>
@@ -48,12 +54,16 @@
 </ul>
 <li><a href="#SWIGPlus_nn28">Overloaded operators</a>
 <li><a href="#SWIGPlus_class_extension">Class extension</a>
+<ul>
+<li><a href="#SWIGPlus_replacing_methods">Replacing class methods</a>
+</ul>
 <li><a href="#SWIGPlus_nn30">Templates</a>
 <ul>
 <li><a href="#SWIGPlus_template_directive">The %template directive</a>
 <li><a href="#SWIGPlus_template_functions">Function templates</a>
 <li><a href="#SWIGPlus_template_classes">Default template arguments</a>
 <li><a href="#SWIGPlus_template_class_inheritance">Template base classes</a>
+<li><a href="#SWIGPlus_template_empty">Empty template instantiation</a>
 <li><a href="#SWIGPlus_template_specialization">Template specialization</a>
 <li><a href="#SWIGPlus_template_member">Member templates</a>
 <li><a href="#SWIGPlus_template_scoping">Scoping and templates</a>
@@ -89,8 +99,9 @@
 It is mostly concerned about C++ as defined by the C++ 98 and 03 standards.
 For additions to the original C++ standard, please read the
 <a href="CPlusPlus11.html#CPlusPlus11">SWIG and C++11</a>,
-<a href="CPlusPlus14.html#CPlusPlus14">SWIG and C++14</a> and
-<a href="CPlusPlus17.html#CPlusPlus17">SWIG and C++17</a> chapters.
+<a href="CPlusPlus14.html#CPlusPlus14">SWIG and C++14</a>,
+<a href="CPlusPlus17.html#CPlusPlus17">SWIG and C++17</a> and
+<a href="CPlusPlus20.html#CPlusPlus20">SWIG and C++20</a> chapters.
 As a prerequisite,
 you should first read the chapter <a href="SWIG.html#SWIG">SWIG Basics</a> to see
 how SWIG wraps ISO C.  Support for C++ builds upon ISO C
@@ -250,7 +261,7 @@
 </p>
 
 <b>Compatibility Note:</b> Early versions of SWIG generated just a flattened low-level C style API to C++ classes by default.
-The <tt>-noproxy</tt> commandline option is recognised by many target languages and will generate just this
+The <tt>-noproxy</tt> commandline option is recognised by some target languages and will generate just this
 interface as in earlier versions.
 
 <H2><a name="SWIGPlus_nn38">6.5 Proxy classes</a></H2>
@@ -580,7 +591,7 @@
 
 <li>
 If a C++ class does not declare an explicit copy constructor, SWIG will
-automatically generate a wrapper for one if the <tt>%copyctor</tt> is used.
+automatically generate a wrapper for one if <tt>%copyctor</tt> is used.
 </li>
 
 <li>
@@ -687,8 +698,7 @@
 <b>Compatibility Note:</b> The generation of default
 constructors/implicit destructors was made the default behavior in SWIG
 1.3.7. This may break certain older modules, but the old behavior can
-be easily restored using <tt>%nodefault</tt> or the
-<tt>-nodefault</tt> command line option.  Furthermore, in order for
+be easily restored using <tt>%nodefault</tt>.  Furthermore, in order for
 SWIG to properly generate (or not generate) default constructors, it
 must be able to gather information from both the <tt>private</tt> and
 <tt>protected</tt> sections (specifically, it needs to know if a private or
@@ -702,9 +712,9 @@
 
 <p>
 <b>Note:</b> The <tt>%nodefault</tt>
-directive/<tt>-nodefault</tt> options described above, which disable both the default
+directive described above, which disables both the default
 constructor and the implicit destructors, could lead to memory
-leaks, and so it is strongly recommended to not use them.
+leaks, and so it is strongly recommended to not use it.
 </p>
 
 
@@ -870,10 +880,12 @@
 
 <div class="code">
 <pre>
+%rename(CopyFoo) Foo::Foo(const Foo &amp;);
+
 class Foo {
 public:
   Foo();
-  %name(CopyFoo) Foo(const Foo &amp;);
+  Foo(const Foo &amp;);
   ...
 };
 </pre>
@@ -1084,13 +1096,6 @@
 </p>
 
 <p>
-<b>Compatibility note:</b> Read-only access used to be controlled by a pair of directives
-<tt>%readonly</tt> and <tt>%readwrite</tt>.   Although these directives still work, they
-generate a warning message.   Simply change the directives to <tt>%immutable;</tt> and
-<tt>%mutable;</tt> to silence the warning.  Don't forget the extra semicolon!
-</p>
-
-<p>
 <b>Compatibility note:</b> Prior to SWIG-1.3.12, all members of unknown type were
 wrapped into accessor functions using pointers.  For example, if you had a structure
 like this
@@ -1121,7 +1126,7 @@
 <p>
  SWIG wraps class members that are public following the C++
  conventions, i.e., by explicit public declaration or by the use of
- the <tt>using</tt> directive. In general, anything specified in a
+ <tt>using</tt> declarations. In general, anything specified in a
  private or protected section will be ignored, although the internal
  code generator sometimes looks at the contents of the private and
  protected sections so that it can properly generate code for default
@@ -1168,64 +1173,218 @@
 <H2><a name="SWIGPlus_nn17">6.9 Friends</a></H2>
 
 
+<H3><a name="SWIGPlus_friend_classes">6.9.1 Friend classes</a></H3>
+
+
 <p>
-Friend declarations are recognised by SWIG. For example, if
-you have this code:
+Friend classes are a C++ feature that do not affect SWIG wrappers.
+SWIG simply parses the friend class declarations, but they are effectively ignored
+as they have no meaningful effect for wrappers.
+An example of friend classes:
 </p>
 
 <div class="code">
 <pre>
-class Foo {
-public:
+class X;
+class Y;
+class C {
+  // Friend classes have no effect on generated wrappers
+  friend class X;
+  friend Y;
   ...
-  friend void blah(Foo *f);
+};
+</pre>
+</div>
+
+<H3><a name="SWIGPlus_friend_function_definitions">6.9.2 Friend function definitions</a></H3>
+
+
+<p>
+A friend function definition in a C++ class defines a non-member function of the class
+and simultaneously makes it a friend of the class.
+For example, if you have this code:
+</p>
+
+<div class="code">
+<pre>
+class Buddy {
+  int val;
+  friend int blah(Buddy *b) { return b-&gt;val; }
+public:
   ...
 };
 </pre>
 </div>
 
 <p>
-then the <tt>friend</tt> declaration does result in a wrapper code
-equivalent to one generated for the following declaration
+then the <tt>friend</tt> function definition results in wrapper code
+equivalent to one generated for the following:
 </p>
 
 <div class="code">
 <pre>
-class Foo {
+class Buddy {
+  int val;
+  friend int blah(Buddy *b);
 public:
   ...
 };
 
-void blah(Foo *f);    
+int blah(Buddy *b) { return b-&gt;val; }
 </pre>
 </div>
 
 <p>
-A friend declaration, as in C++, is understood to be in the same scope
-where the class is declared, hence, you can have
+Access from target languages is thus as if <tt>blah</tt> was wrapped as a non-member function.
+The function is available and wrapped even if the friend is defined with private or protected access.
+</p>
+
+<p>
+A friend definition, as in C++, is understood to be in the same scope
+that the class is defined in, hence the scoping required for SWIG directives, such as <tt>%ignore</tt>, is as follows:
 </p>
 
 <div class="code">
 <pre>
-
-%ignore bar::blah(Foo *f);
+%ignore bar::blah(Buddy *b);
+// Not: %ignore bar::Buddy::blah(Buddy *b);
 
 namespace bar {
-
-  class Foo {
+  class Buddy {
+    int val;
+    friend int blah(Buddy *b) { return b-&gt;val; }
   public:
     ...
-    friend void blah(Foo *f);
-    ...
   };
 }
 </pre>
 </div>
 
 <p>
-and a wrapper for the method 'blah' will not be generated.
+and a wrapper for <tt>blah</tt> will not be generated.
 </p>
 
+<H3><a name="SWIGPlus_friend_function_declarations">6.9.3 Friend function declarations</a></H3>
+
+
+<p>
+A C++ class can specify friends via friend function declarations.
+These functions are allowed access to the private and protected members of a class.
+This is pure C++ functionality and these friend function declarations are hence quietly ignored by SWIG and do not result in any wrappers.
+Well, not always! The C++ rules for friends that SWIG needs to follow are not that simple.
+Technically, only qualified function declarations are silently ignored by SWIG.
+Below are some examples of qualified friend declarations in <tt>A</tt> that are quietly ignored:
+</p>
+
+<div class="code">
+<pre>
+struct B {
+  int f();
+  B();
+  ~B();
+  ...
+};
+
+int g();
+
+class A {
+public:
+  // The following friend function-declarations are silently ignored (including constructor and destructor friends)
+  friend B::B();
+  friend B::~B();
+  friend int B::f();
+  friend int ::g();
+  ...
+};
+</pre>
+</div>
+
+<p>
+In the example above, if SWIG parses the struct <tt>B</tt> and global function <tt>g()</tt>,
+then they are of course wrapped as normal.
+</p>
+
+
+<H3><a name="SWIGPlus_friends_unqualified">6.9.4 Unqualified friend functions</a></H3>
+
+
+<p>
+Further clarification is required regarding both friend function definitions and declarations.
+In C++, friend function definitions can only be unqualified, whereas, friend function declarations can be either unqualified or qualified. Qualified friend function declarations are silently ignored by SWIG as covered in the previous section. SWIG does generate wrappers for any unqualified friend functions that it parses. This section goes through some of the complexities of wrapping unqualified friend functions.
+</p>
+
+<p>
+Consider an unqualified friend function definition:
+</p>
+
+<div class="code">
+<pre>
+class Chum {
+  int val;
+  friend int blah() { Chum c; c.private_function(); return c.val; }
+  void private_function();
+public:
+  ...
+};
+</pre>
+</div>
+
+<p>
+The <tt>Chum::blah()</tt> friend is very similar to the <tt>Buddy::blah(Buddy *)</tt> friend presented earlier.
+However, the generated code to call <tt>blah()</tt> may not compile unlike the code to call <tt>blah(Buddy *)</tt>.
+The compiler error will be something like:
+
+<div class="shell">
+<pre>
+error: 'blah' was not declared in this scope
+</pre>
+</div>
+
+<p>
+The reason one works and the other doesn't is due to the rules around unqualified friend definitions/declarations. Broadly, friends are not visible for lookup except via argument dependent lookup that considers the class that the friend is defined/declared in, unless there is a <i>matching declaration</i> at namespace scope.
+This will probably only make sense if you are conversant with this C++ concept, which is covered quite well at <a href="https://en.cppreference.com/w/cpp/language/adl">Argument-dependent lookup</a>.
+In our examples, <tt>blah(Buddy *)</tt> is visible via argument dependent lookup, but <tt>blah()</tt> is not. The solution is thus to provide a <i>matching declaration</i> in order to make the function visible to the compiler. Simply add:
+</p>
+
+<div class="code">
+<pre>
+int blah();
+</pre>
+</div>
+
+<p>
+SWIG does <b>not</b> have to parse it. In all likelihood, your code already has the <i>matching declaration</i> as it is required in order for the friend function definition to be usable from pure C++ code.
+</p>
+
+<p>
+The same potential problem applies to unqualified friend function declarations, such as:
+</p>
+
+<div class="code">
+<pre>
+class Mate {
+  int val;
+  friend int blah(); // Unqualified friend function declaration
+  void private_function();
+public:
+  ...
+};
+</pre>
+</div>
+
+<p>
+Again, the actual function declaration needs to be visible to the compiler.
+Or just the actual function definition as shown below.
+This must be defined in the same scope as <tt>Mate</tt>.
+Of course the function definition is necessary in order to avoid linking issues too.
+</p>
+
+<div class="code">
+<pre>
+int blah() { Mate m; m.private_function(); return m.val; }
+</pre>
+</div>
+
 <H2><a name="SWIGPlus_nn18">6.10 References and pointers</a></H2>
 
 
@@ -1348,16 +1507,19 @@
 <div class="code">
 <pre>
 Vector *wrap_cross_product(Vector *a, Vector *b) {
-  Vector x = *a;
-  Vector y = *b;
-  Vector r = cross_product(x, y);
+  Vector x;
+  Vector y;
+  Vector r;
+  x = *a;
+  y = *b;
+  r = cross_product(x, y);
   return new Vector(r);
 }</pre>
 </div>
 
 <p>
-In order for the wrapper code to compile, <tt>Vector</tt> must define a copy constructor and a 
-default constructor.
+In order for the wrapper code to compile, <tt>Vector</tt> must define a default constructor, copy assignment operator (and/or a move assignment operator for C++11 and later).
+The <a href="CPlusPlus11.html#CPlusPlus11_move_only">Movable and move-only types</a> section should be read regarding C++11 move semantics and return by value.
 </p>
 
 <p>
@@ -1370,9 +1532,12 @@
 <div class="code">
 <pre>
 Vector cross_product(Vector *a, Vector *b) {
-  SwigValueWrapper&lt;Vector&gt; x = *a;
-  SwigValueWrapper&lt;Vector&gt; y = *b;
-  SwigValueWrapper&lt;Vector&gt; r = cross_product(x, y);
+  SwigValueWrapper&lt;Vector&gt; x;
+  SwigValueWrapper&lt;Vector&gt; y;
+  SwigValueWrapper&lt;Vector&gt; r;
+  x = *a;
+  y = *b;
+  r = cross_product(x, y);
   return new Vector(r);
 }
 </pre>
@@ -1799,6 +1964,11 @@
 </p>
 
 <p>
+For C# please see the <a href="CSharp.html#CSharp_named_arguments">C# named and optional arguments</a> section for information on special
+handling of default arguments available specifically for C#.
+</p>
+
+<p>
 <b>Compatibility note:</b> Versions of SWIG prior to SWIG-1.3.23 wrapped default arguments slightly differently.
 Instead a single wrapper method was generated and the default values were copied into the C++ wrappers
 so that the method being wrapped was then called with all the arguments specified.
@@ -1824,6 +1994,7 @@
 which don't have optional arguments in the language, 
 Another restriction of this feature is that it cannot handle default arguments that are not public.
 The following example illustrates this:
+
 </p>
 
 <div class="code">
@@ -2079,7 +2250,6 @@
 <pre>
 example.i:4: Warning 516: Overloaded method foo(long) ignored,
 example.i:3: Warning 516: using foo(int) instead.
-at example.i:3 used.
 </pre>
 </div>
 
@@ -2138,7 +2308,7 @@
 but for some reason there is no type-checking rule that can be used to
 generate a working dispatch function.  The resulting behavior is then
 undefined.  You should report this as a bug to the
-<a href="http://www.swig.org/bugs.html">SWIG bug tracking database</a>
+<a href="https://www.swig.org/bugs.html">SWIG bug tracking database</a>
 if this is due to one of the typemaps supplied with SWIG.
 </p>
 
@@ -2315,7 +2485,7 @@
 Note: the <tt>*::</tt> syntax is non-standard C++, but the '*' is meant to be a
 wildcard that matches any class name (we couldn't think of a better
 alternative so if you have a better idea, send email to
-the <a href="http://www.swig.org/mail.html">swig-devel mailing list</a>.
+the <a href="https://www.swig.org/mail.html">swig-devel mailing list</a>.
 </p>
 
 <p>
@@ -2326,8 +2496,8 @@
 <div class="code">
 <pre>
 %ignore foo(double);          // Ignore all foo(double)
-%ignore Spam::foo;            // Ignore foo in class Spam
-%ignore Spam::foo(double);    // Ignore foo(double) in class Spam
+%ignore Spam::foo;            // Ignore foo in class Spam (and foo in any derived classes)
+%ignore Spam::foo(double);    // Ignore foo(double) in class Spam (and foo in any derived classes)
 %ignore *::foo(double);       // Ignore foo(double) in all classes
 </pre>
 </div>
@@ -2383,6 +2553,53 @@
 </li>
 
 <li><p>
+Renaming a class member, using an unparameterized but qualified name, such as <tt>Spam::foo</tt>, also applies to members in all derived classes
+that have members with the same name.
+This can be used to simply rename a method, across an entire class hierarchy for all overloaded and non-overloaded methods.
+This also applies to methods introduced via <tt>using</tt> declarations, see
+<a href="#SWIGPlus_nn35">Using declarations and inheritance</a>.
+For example:
+</p>
+
+<div class="code">
+<pre>
+%rename(foo_new) Spam::foo;
+
+class Spam {
+public:
+  virtual void foo(int);      // Renamed to foo_new
+};
+
+class Bar : public Spam {
+public:
+  virtual void foo(int);      // Renamed to foo_new
+  void foo(bool, short, int); // Renamed to foo_new
+};
+
+class Grok : public Bar {
+public:
+  virtual void foo(int);      // Renamed to foo_new
+  void foo(bool, int);        // Renamed to foo_new
+  void foo(const char *);     // Renamed to foo_new
+  void foo(Bar *);            // Renamed to foo_new
+};
+
+class Spok : public Grok {
+public:
+  void foo();                 // Renamed to foo_new
+};
+
+class Knock : public Spok {
+public:
+  using Grok::foo;            // Introduced methods renamed to foo_new
+};
+</pre>
+</div>
+
+</li>
+
+
+<li><p>
 The order in which <tt>%rename</tt> directives are defined does not matter
 as long as they appear before the declarations to be renamed.  Thus, there is no difference
 between saying:</p>
@@ -2936,13 +3153,59 @@
 section for further details.
 </p>
 
+<H3><a name="SWIGPlus_replacing_methods">6.17.1 Replacing class methods</a></H3>
+
+
 <p>
-<b>Compatibility note:</b>  The <tt>%extend</tt> directive is a new
-name for the <tt>%addmethods</tt> directive in SWIG1.1.  Since <tt>%addmethods</tt> could
-be used to extend a structure with more than just methods, a more suitable
-directive name has been chosen.
+Suppose there is a method in a class that you need to replace and keep the method name the same.
+This can be achieved combining the <tt>%extend</tt> and <tt>%ignore</tt> directives covered earlier.
+Here is an example to replace the <tt>MyClass::mymethod()</tt>:
+
+<div class="code">
+<pre>
+%extend MyClass {
+  void mymethod() {
+    std::cout &lt;&lt; "swig mymethod" &lt;&lt; std::endl;
+  }
+}
+
+%ignore MyClass::mymethod;
+
+%inline %{
+class MyClass {
+public:
+  void mymethod() {
+    std::cout &lt;&lt; "class mymethod" &lt;&lt; std::endl;
+  }
+};
+%}
+</pre>
+</div>
+
+<p>
+Or if your code organization makes more sense to put
+the <tt>%extend</tt> after the class definition, you would need the following:
 </p>
 
+<div class="code">
+<pre>
+%rename("") MyClass::mymethod; // unignores the method
+</pre>
+</div>
+
+<p>
+before the <tt>%extend</tt> or SWIG will continue to ignore
+<tt>mymethod()</tt>, even in an <tt>%extend</tt>.
+</p>
+
+<p>
+Note that you can call the class method from the method
+in <tt>%extend</tt>, just use <tt>self-&gt;mymethod()</tt> and it will call
+the class method, not the one in <tt>%extend</tt>.
+</p>
+
+
+
 <H2><a name="SWIGPlus_nn30">6.18 Templates</a></H2>
 
 
@@ -2954,22 +3217,24 @@
 <div class="code">
 <pre>
 void foo(vector&lt;int&gt; *a, int n);
-void bar(list&lt;int, 100&gt; *x);
+void bar(std::array&lt;int, 100&gt; *x);
 </pre>
 </div>
 
 <p>
 There are some restrictions on the use of non-type arguments.  Simple literals
-are supported, and so are some constant expressions.  However, use of '&lt;'
-and '&gt;' within a constant expressions currently is not supported by SWIG
-('&lt;=' and '&gt;=' are though).  For example:
+are supported, and so are most constant expressions.  However, there are some
+limitations on the use of '&lt;' and '&gt;' in constant expressions (but note
+that '&lt;=' and '&gt;=' are fully supported).  For example:
 </p>
 
 <div class="code">
 <pre>
-void bar(list&lt;int, 100&gt; *x);                // OK
-void bar(list&lt;int, 2*50&gt; *x);               // OK
-void bar(list&lt;int, (2&gt;1 ? 100 : 50)&gt; *x)    // Not supported
+void bar(std::array&lt;int, 100&gt; *x);                // OK
+void bar(std::array&lt;int, 2*50&gt; *x);               // OK
+void bar(std::array&lt;int, (1&lt;2 ? 100 : 50)&gt; *x)    // OK
+void bar(std::array&lt;int, 1&lt;2 ? 100 : 50&gt; *x)      // Not supported
+void bar(std::array&lt;int, (2&gt;1 ? 100 : 50)&gt; *x)    // Not supported
 </pre>
 </div>
 
@@ -3150,10 +3415,28 @@
 In this case, <tt>List&lt;Integer&gt;</tt> is exactly the same type as
 <tt>List&lt;int&gt;</tt>.  Any use of <tt>List&lt;Integer&gt;</tt> is mapped back to the 
 instantiation of <tt>List&lt;int&gt;</tt> created earlier.  Therefore, it is
-not necessary to instantiate a new class for the type <tt>Integer</tt> (doing so is
-redundant and will simply result in code bloat).
+not correct to instantiate a new class for the type <tt>Integer</tt>.
+An attempt to do so such as:
 </p>
 
+<div class="code">
+<pre>
+%template(intList) List&lt;int&gt;;
+%template(IntegerList) List&lt;Integer&gt;;   // Ignored
+</pre>
+</div>
+
+<p>
+will result in the duplicate instantiation being ignored with a warning:
+</p>
+
+<div class="shell">
+<pre>
+example.i:48: Warning 404: Duplicate template instantiation of 'List&lt; Integer &gt;' with name 'IntegerList' ignored,
+example.i:47: Warning 404: previous instantiation of 'List&lt; int &gt;' with name 'intList'.
+</pre>
+</div>
+
 <p>
 The template provided to <tt>%template</tt> for instantiation must be the actual template and not a typedef to a template.
 </p>
@@ -3222,36 +3505,49 @@
 
 <div class="code">
 <pre>
-template vector&lt;typename T, int max=100&gt; class vector {
+template &lt;typename T, int max=100&gt; class vector {
 ...
 };
 
-%template(intvec) vector&lt;int&gt;;           // OK
+%template(intvec) vector&lt;int&gt;;            // OK
 %template(vec1000) vector&lt;int, 1000&gt;;     // OK
 </pre>
 </div>
 
 <p>
 The <tt>%template</tt> directive should not be used to wrap the same
-template instantiation more than once in the same scope.  This will
-generate an error.  For example:
+template instantiation more than once. This also applies to default parameters
+where a template parameter specified in the instantiation is the same as the default parameter.
+For example:
 </p>
 
 <div class="code">
 <pre>
-%template(intList) List&lt;int&gt;;
-%template(Listint) List&lt;int&gt;;    // Error.   Template already wrapped.
+%template(vec) vector&lt;double&gt;;            // OK
+%template(vec100) vector&lt;double, 100&gt;;    // Ignored
 </pre>
 </div>
 
 <p>
-This error is caused because the template expansion results in two
-identical classes with the same name.  This generates a symbol table
-conflict.  Besides, it probably more efficient to only wrap a specific
-instantiation only once in order to reduce the potential for code
-bloat.
+will warn:
 </p>
 
+<div class="shell">
+<pre>
+example.i:59: Warning 404: Duplicate template instantiation of 'vector&lt; double,100 &gt;' with name 'vec100' ignored,
+example.i:58: Warning 404: previous instantiation of 'vector&lt; double &gt;' with name 'vec'.
+</pre>
+</div>
+
+<p>
+If this was not ignored, the template expansion would result in two identical classes.
+An identical instantiation is only wrapped once in order to reduce code bloat.
+</p>
+
+<p>
+<b>Compatibility Note</b>:  Versions prior to SWIG-4.2.0 would sometimes not detect and prevent duplicate
+instantiations, such as when the wrapped name was different.
+</p>
 <H3><a name="SWIGPlus_template_class_inheritance">6.18.4 Template base classes</a></H3>
 
 
@@ -3319,20 +3615,6 @@
 </p>
 
 <p>
-Occasionally, you may need to tell SWIG about base classes that are defined by templates,
-but which aren't supposed to be wrapped.  Since SWIG is not able to automatically
-instantiate templates for this purpose, you must do it manually.  To do this, simply
-use the empty template instantiation, that is, <tt>%template</tt> with no name.  For example:
-</p>
-
-<div class="code">
-<pre>
-// Instantiate traits&lt;double, double&gt;, but don't wrap it.
-%template() traits&lt;double, double&gt;;
-</pre>
-</div>
-
-<p>
 If you have to instantiate a lot of different classes for many different types,
 you might consider writing a SWIG macro.  For example:
 </p>
@@ -3357,7 +3639,66 @@
 Note the use of a vararg macro for the type T. If this wasn't used, the comma in the templated type in the last example would not be possible.
 </p>
 
-<H3><a name="SWIGPlus_template_specialization">6.18.5 Template specialization</a></H3>
+<H3><a name="SWIGPlus_template_empty">6.18.5 Empty template instantiation</a></H3>
+
+
+<p>
+Occasionally, you may need to tell SWIG about classes that are defined by templates,
+but which aren't supposed to be wrapped.  Since SWIG is not able to automatically
+instantiate templates for this purpose, you must do it manually.  To do this, simply
+use <tt>%template()</tt>, that is the empty template instantiation that omits providing a name.  For example:
+</p>
+
+<div class="code">
+<pre>
+template&lt;typename T&gt; struct Traits {
+  typedef T type;
+};
+%}
+
+%template() Traits&lt;int&gt;; // instantiate Traits&lt;int&gt;, but don't wrap it
+
+void traitor(Traits&lt;int&gt;::type val);
+</pre>
+</div>
+
+<p>
+Without a template instantiation, SWIG does not know that the first parameter to the <tt>traitor</tt>
+function is type int and passing an integer to this function from any target language won't work.
+The empty template instantiation adds the appropriate type information into SWIG's type system, without
+forcing one to wrap the <tt>Traits</tt> class.
+</p>
+
+<p>
+Duplicate template instantiation are not allowed, as described in the
+<a href="#SWIGPlus_template_classes">Default template arguments</a> section above.
+There is one exception where a named template instantiation can be followed by an empty template instantiation.
+Duplicate empty template instantiations are silently ignored, unlike duplicate named template instantiations.
+</p>
+
+<p>
+Unlike template class instantiations, template function instantiations must have a name.
+Consider the following:
+</p>
+
+<div class="code">
+<pre>
+template&lt;class T&gt; T tfunc(T x) { };
+%template() tfunc&lt;double&gt;;
+</pre>
+</div>
+
+<p>
+The empty template instantiation will be ignored with:
+</p>
+
+<div class="shell">
+<pre>
+example.i:9: Warning 519: %template() contains no name. Template method ignored: tfunc&lt; double &gt;(double)
+</pre>
+</div>
+
+<H3><a name="SWIGPlus_template_specialization">6.18.6 Template specialization</a></H3>
 
 
 <p>
@@ -3447,7 +3788,7 @@
 </pre>
 </div>
 
-<H3><a name="SWIGPlus_template_member">6.18.6 Member templates</a></H3>
+<H3><a name="SWIGPlus_template_member">6.18.7 Member templates</a></H3>
 
 
 <p>
@@ -3631,7 +3972,7 @@
 
 // Create default and conversion constructors 
 %extend pair&lt;double, double&gt; {
-  %template(paird) pair&lt;double, dobule&gt;;   // Default constructor
+  %template(paird) pair&lt;double, double&gt;;   // Default constructor
   %template(pairc) pair&lt;int, int&gt;;         // Conversion constructor
 };
 </pre>
@@ -3646,7 +3987,7 @@
 <pre>
 // Create default and conversion constructors 
 %extend pair&lt;double, double&gt; {
-  %template(pair) pair&lt;double, dobule&gt;;   // Default constructor
+  %template(pair) pair&lt;double, double&gt;;   // Default constructor
   %template(pair) pair&lt;int, int&gt;;         // Conversion constructor
 };
 </pre>
@@ -3659,7 +4000,7 @@
 type.
 </p>
 
-<H3><a name="SWIGPlus_template_scoping">6.18.7 Scoping and templates</a></H3>
+<H3><a name="SWIGPlus_template_scoping">6.18.8 Scoping and templates</a></H3>
 
 
 <p>
@@ -3760,7 +4101,7 @@
 </p>
 
  
-<H3><a name="SWIGPlus_template_more">6.18.8 More on templates</a></H3>
+<H3><a name="SWIGPlus_template_more">6.18.9 More on templates</a></H3>
 
 
 <p>
@@ -4016,23 +4357,23 @@
 <p>
 At this level, namespaces are relatively easy to manage.  However, things start to get 
 very ugly when you throw in the other ways a namespace can be used.  For example,
-selective symbols can be exported from a namespace with <tt>using</tt>.
+selective symbols can be exported from a namespace with a <tt>using</tt> declaration:
 </p>
 
 <div class="code">
 <pre>
-using math::Complex;
+using math::Complex;                // Using declaration
 double magnitude(Complex *c);       // Namespace prefix stripped
 </pre>
 </div>
 
 <p>
-Similarly, the contents of an entire namespace can be made available like this:
+Similarly, the contents of an entire namespace can be made available via a <tt>using</tt> directive:
 </p>
 
 <div class="code">
 <pre>
-using namespace math;
+using namespace math;               // Using directive
 double x = sin(1.0);
 double magnitude(Complex *c);
 </pre>
@@ -4162,8 +4503,8 @@
 
 <div class="shell">
 <pre>
-example.i:26. Error. 'foo' is multiply defined in the generated target language module.
-example.i:23. Previous declaration of 'foo'
+example.i:26: Error: 'foo' is multiply defined in the generated target language module.
+example.i:23: Error: Previous declaration of 'foo'
 </pre>
 </div>
 
@@ -4189,9 +4530,11 @@
 </p>
 
 <p>
-<tt>using</tt> declarations do not have any effect on the generated wrapper
-code. They are ignored by SWIG language modules and they do not result in any
-code.  However, these declarations <em>are</em> used by the internal type
+C++ <tt>using</tt> directives and <tt>using</tt> declarations
+do not add any code to the generated wrapper code.
+However, there is an exception in one context, see <a href="#SWIGPlus_nn35">Using declarations and inheritance</a>
+for introducing members of a base class into a derived class definition.
+C++ <tt>using</tt> declarations and directives <em>are</em> used by the internal type
 system to track type-names. Therefore, if you have code like this:
 </p>
 
@@ -5115,7 +5458,7 @@
 
 
 <p>
-<tt>using</tt> declarations are sometimes used to adjust access to members of
+C++ <tt>using</tt> declarations are sometimes used to introduce members of
 base classes.  For example:
 </p>
 
@@ -5123,7 +5466,7 @@
 <pre>
 class Foo {
 public:
-  int  blah(int x);
+  int blah(int x);
 };
 
 class Bar {
@@ -5171,7 +5514,13 @@
 </div>
 
 <p>
-<tt>using</tt> declarations can also be used to change access when applicable.  For example:
+The C++11 standard supports using declarations for inheriting constructors and this is covered in
+<a href="CPlusPlus11_object_construction_improvement">Object construction improvement</a>.
+</p>
+
+<p>
+C++ <tt>using</tt> declarations can also be used to change access when applicable.
+For example, protected methods in a base class can be made public in a derived class:
 </p>
 
 <div class="code">
@@ -5204,15 +5553,15 @@
 
 <p>
 Because a <tt>using</tt> declaration does not provide fine-grained
-control over the declarations that get imported, it may be difficult
+control over the declarations that get imported, because a single <tt>using</tt> declaration
+may introduce multiple methods, it may be difficult
 to manage such declarations in applications that make heavy use of
 SWIG customization features.  If you can't get <tt>using</tt> to work
-correctly, you can always change the interface to the following:
+correctly, you can always modify the C++ code to handle SWIG differently such as:
 </p>
 
 <div class="code">
 <pre>
-
 class FooBar : public Foo, public Bar {
 public:
 #ifndef SWIG
@@ -5229,12 +5578,35 @@
 </div>
 
 <p>
+If the C++ code being wrapped cannot be changed, make judicious usage of <tt>%extend</tt> and <tt>%rename</tt>
+to ignore and unignore declarations. The example below is effectively the same as above:
+</p>
+
+<div class="code">
+<pre>
+%extend FooBar {
+  int blah(int x) { return $self-&gt;Foo::blah(x); }
+  double blah(double x) { return $self-&gt;Bar::blah(x); }
+}
+%ignore FooBar::blah; // ignore all FooBar::blah below
+%rename("") FooBar::blah(const char *x); // parameterized unignore
+
+class FooBar : public Foo, public Bar {
+public:
+  using Foo::blah;
+  using Bar::blah;
+  char *blah(const char *x);
+};
+</pre>
+</div>
+
+<p>
 <b>Notes:</b>
 </p>
 
 <ul>
-<li><p>If a derived class redefines a method defined in a base class, then a <tt>using</tt> declaration
-won't cause a conflict.  For example:</p>
+<li><p>If a derived class introduces a method defined in a base class via a <tt>using</tt> declaration,
+there won't be a conflict due to incorrect additional methods.  For example:</p>
 
 <div class="code">
 <pre>
@@ -5246,14 +5618,14 @@
 
 class Bar : public Foo {
 public:
-  using Foo::blah;    // Only imports blah(double);
+  using Foo::blah;    // Only introduces blah(double);
   int blah(int);
 };
 </pre>
 </div>
 
-<li><p>Resolving ambiguity in overloading may prevent declarations from being
-imported by <tt>using</tt>.  For example:
+<li><p>Renaming methods may prevent methods from being
+introduced into the derived class via <tt>using</tt> declarations.  For example:
 </p>
 
 <div class="code">
@@ -5267,11 +5639,38 @@
 
 class Bar : public Foo {
 public:
-  using Foo::blah;     // Only imports blah(int)
+  using Foo::blah;     // Only introduces blah(int)
   double blah(double x);
 };
 </pre>
 </div>
+
+<p>
+The problem here is <tt>Foo::blah</tt> is renamed to <tt>blah_long</tt> in the target language, but
+the <tt>using</tt> declaration in Bar is not renamed in the target language and thinks all introduced methods should simply
+be called <tt>blah</tt>.
+It is not clear what target language names should be used in Bar and so the conflicting names are effectively ignored
+as they are not introduced into the derived class for the target language wrappers.
+In such situations SWIG will emit a warning:
+</p>
+
+<div class="shell">
+<pre>
+example.i:15: Warning 526: Using declaration Foo::blah, with name 'blah', is not actually using
+example.i:10: Warning 526: the method from Foo::blah(long), with name 'blah_long', as the names are different.
+</pre>
+</div>
+
+<p>
+<b>Compatibility Note:</b>
+This warning message was introduced in SWIG-4.1.0.
+Prior versions also effectively ignored the using declaration for the same reasons, but were silent about it.
+</p>
+
+<p>
+If methods really need different names, please use of combinations of <tt>%rename</tt>, <tt>%ignore</tt> and <tt>%extend</tt> to achieve the desired outcome.
+</p>
+
 </ul>
 
 <H2><a name="SWIGPlus_nested_classes">6.27 Nested classes</a></H2>
diff --git a/Doc/Manual/Scilab.html b/Doc/Manual/Scilab.html
index 88ab804..25b9db9 100644
--- a/Doc/Manual/Scilab.html
+++ b/Doc/Manual/Scilab.html
@@ -9,7 +9,7 @@
 
 <body bgcolor="#ffffff">
 
-<H1><a name="Scilab">35 SWIG and Scilab</a></H1>
+<H1><a name="Scilab">36 SWIG and Scilab</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -71,6 +71,7 @@
 <ul>
 <li><a href="#Scilab_generated_scripts_builder_script">Builder script</a>
 <li><a href="#Scilab_generated_scripts_loader_script">Loader script</a>
+<li><a href="#Scilab_generated_scripts_gateway">Gateway XML files</a>
 </ul>
 <li><a href="#Scilab_other_resources">Other resources</a>
 </ul>
@@ -80,7 +81,7 @@
 
 
 <p>
-Scilab is a scientific software package for numerical computations providing a powerful open computing environment for engineering and scientific applications that is mostly compatible with MATLAB. More information can be found at <a href="http://www.scilab.org">www.scilab.org</a>.
+Scilab is a scientific software package for numerical computations providing a powerful open computing environment for engineering and scientific applications that is mostly compatible with MATLAB. More information can be found at <a href="https://www.scilab.org">www.scilab.org</a>.
 </p>
 
 <p>
@@ -88,7 +89,7 @@
 </p>
 
 
-<H2><a name="Scilab_preliminaries">35.1 Preliminaries</a></H2>
+<H2><a name="Scilab_preliminaries">36.1 Preliminaries</a></H2>
 
 
 <p>
@@ -96,8 +97,7 @@
 </p>
 
 <p>
-Scilab is supported from version 5.3.3 onwards.
-The forthcoming version 6, as of January 2015, is also supported.
+Scilab is supported from version 5.3.3 onwards, the SWIG generated code is supported on both Scilab 5, Scilab 6 and more recent versions.
 </p>
 
 <p>
@@ -105,7 +105,7 @@
 </p>
 
 
-<H2><a name="Scilab_running_swig">35.2 Running SWIG</a></H2>
+<H2><a name="Scilab_running_swig">36.2 Running SWIG</a></H2>
 
 
 <p>
@@ -139,7 +139,7 @@
 </p>
 
 
-<H3><a name="Scilab_running_swig_generating_module">35.2.1 Generating the module</a></H3>
+<H3><a name="Scilab_running_swig_generating_module">36.2.1 Generating the module</a></H3>
 
 
 <p>
@@ -182,7 +182,7 @@
 </p>
 
 
-<H3><a name="Scilab_running_swig_building_module">35.2.2 Building the module</a></H3>
+<H3><a name="Scilab_running_swig_building_module">36.2.2 Building the module</a></H3>
 
 
 <p>
@@ -202,7 +202,7 @@
 Note: we supposed in this example that the path to the Scilab include directory is <tt>/usr/local/include/scilab</tt> (which is the case in a Debian environment), this should be changed for another environment.
 </p>
 
-<H3><a name="Scilab_running_swig_loading_module">35.2.3 Loading the module</a></H3>
+<H3><a name="Scilab_running_swig_loading_module">36.2.3 Loading the module</a></H3>
 
 
 <p>
@@ -226,7 +226,7 @@
 which means that Scilab has successfully loaded the shared library. The module functions and other symbols are now available in Scilab.
 </p>
 
-<H3><a name="Scilab_running_swig_using_module">35.2.4 Using the module</a></H3>
+<H3><a name="Scilab_running_swig_using_module">36.2.4 Using the module</a></H3>
 
 
 <p>
@@ -260,7 +260,7 @@
 Note: for conciseness, we assume in the subsequent Scilab code examples that the modules have been beforehand built and loaded in Scilab.
 </p>
 
-<H3><a name="Scilab_running_swig_options">35.2.5 Scilab command line options</a></H3>
+<H3><a name="Scilab_running_swig_options">36.2.5 Scilab command line options</a></H3>
 
 
 <p>
@@ -305,8 +305,8 @@
 </tr>
 
 <tr>
-<td><tt>-targetversion</tt></td>
-<td>Generate for Scilab target (major) version</td>
+<td><tt>-gatewayxml6</tt></td>
+<td>Generate a gateway XML file compatible with Scilab 6</td>
 </tr>
 
 </table>
@@ -320,10 +320,10 @@
 </pre></div>
 
 
-<H2><a name="Scilab_wrapping">35.3 A basic tour of C/C++ wrapping</a></H2>
+<H2><a name="Scilab_wrapping">36.3 A basic tour of C/C++ wrapping</a></H2>
 
 
-<H3><a name="Scilab_wrapping_overview">35.3.1 Overview</a></H3>
+<H3><a name="Scilab_wrapping_overview">36.3.1 Overview</a></H3>
 
 
 <p>
@@ -332,7 +332,7 @@
 There are a few exceptions, such as constants and enumerations, which can be wrapped directly as Scilab variables.
 </p>
 
-<H3><a name="Scilab_wrapping_identifiers">35.3.2 Identifiers</a></H3>
+<H3><a name="Scilab_wrapping_identifiers">36.3.2 Identifiers</a></H3>
 
 
 <p>
@@ -343,11 +343,7 @@
 In these cases, the <a href="SWIG.html#SWIG_rename_ignore">%rename directive</a> can be used to choose a different Scilab name.
 </p>
 
-<p>
-Note: truncations can be disabled by specifying the target version 6 of Scilab in the <tt>targetversion</tt> argument (i.e. <tt>-targetversion 6</tt>).
-</p>
-
-<H3><a name="Scilab_wrapping_functions">35.3.3 Functions</a></H3>
+<H3><a name="Scilab_wrapping_functions">36.3.3 Functions</a></H3>
 
 
 <p>
@@ -378,7 +374,7 @@
     24.
 </pre></div>
 
-<H4><a name="Scilab_nn13">35.3.3.1 Argument passing</a></H4>
+<H4><a name="Scilab_nn13">36.3.3.1 Argument passing</a></H4>
 
 
 <p>
@@ -431,7 +427,7 @@
     7.
 </pre></div>
 
-<H4><a name="Scilab_nn14">35.3.3.2 Multiple output arguments</a></H4>
+<H4><a name="Scilab_nn14">36.3.3.2 Multiple output arguments</a></H4>
 
 
 <p>
@@ -480,7 +476,7 @@
 </pre></div>
 
 
-<H3><a name="Scilab_wrapping_global_variables">35.3.4 Global variables</a></H3>
+<H3><a name="Scilab_wrapping_global_variables">36.3.4 Global variables</a></H3>
 
 
 <p>
@@ -549,10 +545,10 @@
 </pre></div>
 
 
-<H3><a name="Scilab_wrapping_constants_and_enums">35.3.5 Constants and enumerations</a></H3>
+<H3><a name="Scilab_wrapping_constants_and_enums">36.3.5 Constants and enumerations</a></H3>
 
 
-<H4><a name="Scilab_wrapping_constants">35.3.5.1 Constants</a></H4>
+<H4><a name="Scilab_wrapping_constants">36.3.5.1 Constants</a></H4>
 
 
 <p>
@@ -693,7 +689,7 @@
     3.14
 </pre></div>
 
-<H4><a name="Scilab_wrapping_enums">35.3.5.2 Enumerations</a></H4>
+<H4><a name="Scilab_wrapping_enums">36.3.5.2 Enumerations</a></H4>
 
 
 <p>
@@ -758,7 +754,7 @@
 
 </pre></div>
 
-<H3><a name="Scilab_wrapping_pointers">35.3.6 Pointers</a></H3>
+<H3><a name="Scilab_wrapping_pointers">36.3.6 Pointers</a></H3>
 
 
 <p>
@@ -768,7 +764,7 @@
 Also, thanks to the SWIG runtime which stores information about types, pointer types are tracked between exchanges Scilab and the native code. Indeed pointer types are stored alongside the pointer address.
 A pointer is mapped to a Scilab structure (<a href="https://help.scilab.org/docs/5.5.2/en_US/tlist.html">tlist</a>), which contains as fields the pointer address and the pointer type (in fact a pointer to the type information structure in the SWIG runtime).
 <br>
-Why a native pointer is not mapped to a Scilab pointer (type name: "pointer", type ID: 128) ? The big advantage of mapping to a <tt>tlist</tt> is that it exposes a new type for the pointer in Scilab, type which can be acessed in Scilab with the <a href="https://help.scilab.org/docs/5.5.2/en_US/typeof.html">typeof</a> function, and manipulated using the <a href="https://help.scilab.org/docs/5.5.2/en_US/overloading.html">overloading</a> mechanism.
+Why a native pointer is not mapped to a Scilab pointer (type name: "pointer", type ID: 128) ? The big advantage of mapping to a <tt>tlist</tt> is that it exposes a new type for the pointer in Scilab, type which can be accessed in Scilab with the <a href="https://help.scilab.org/docs/5.5.2/en_US/typeof.html">typeof</a> function, and manipulated using the <a href="https://help.scilab.org/docs/5.5.2/en_US/overloading.html">overloading</a> mechanism.
 </p>
 
 <p>
@@ -776,7 +772,7 @@
 </p>
 <ul>
 <li>type tracking needs the SWIG runtime to be first initialized with the appropriate function (see the <a href="#Scilab_module_initialization">Module initialization</a> section).</li>
-<li>for any reason, if a wrapped pointer type is unknown (or if the SWIG runtime is not initialized), SWIG maps it to a Scilab pointer. Also, a Scilab pointer is always accepted as a pointer argument of a wrapped function. The drawaback is that pointer type is lost.</li>
+<li>for any reason, if a wrapped pointer type is unknown (or if the SWIG runtime is not initialized), SWIG maps it to a Scilab pointer. Also, a Scilab pointer is always accepted as a pointer argument of a wrapped function. The drawback is that pointer type is lost.</li>
 </ul>
 
 <p>
@@ -820,7 +816,7 @@
 The user of a pointer is responsible for freeing it or, like in the example, closing any resources associated with it (just as is required in a C program).
 </p>
 
-<H4><a name="Scilab_wrapping_pointers_utility_functions">35.3.6.1 Utility functions</a></H4>
+<H4><a name="Scilab_wrapping_pointers_utility_functions">36.3.6.1 Utility functions</a></H4>
 
 
 <p>
@@ -861,7 +857,7 @@
 </pre></div>
 
 
-<H4><a name="Scilab_wrapping_pointers_null_pointers">35.3.6.2 Null pointers:</a></H4>
+<H4><a name="Scilab_wrapping_pointers_null_pointers">36.3.6.2 Null pointers:</a></H4>
 
 
 <p>
@@ -877,7 +873,7 @@
 </pre></div>
 
 
-<H3><a name="Scilab_wrapping_structs">35.3.7 Structures</a></H3>
+<H3><a name="Scilab_wrapping_structs">36.3.7 Structures</a></H3>
 
 
 <p>
@@ -986,7 +982,7 @@
 --&gt; delete_Bar(b);
 </pre></div>
 
-<H3><a name="Scilab_wrapping_cpp_classes">35.3.8 C++ classes</a></H3>
+<H3><a name="Scilab_wrapping_cpp_classes">36.3.8 C++ classes</a></H3>
 
 
 <p>
@@ -1054,7 +1050,7 @@
 --&gt; delete_Point(p);
 </pre></div>
 
-<H3><a name="Scilab_wrapping_cpp_inheritance">35.3.9 C++ inheritance</a></H3>
+<H3><a name="Scilab_wrapping_cpp_inheritance">36.3.9 C++ inheritance</a></H3>
 
 
 <p>
@@ -1129,7 +1125,7 @@
     18.84
 </pre></div>
 
-<H3><a name="Scilab_wrapping_cpp_overloading">35.3.10 C++ overloading</a></H3>
+<H3><a name="Scilab_wrapping_cpp_overloading">36.3.10 C++ overloading</a></H3>
 
 
 <p>
@@ -1169,7 +1165,7 @@
 </pre></div>
 
 
-<H3><a name="Scilab_wrapping_pointers_references_values_arrays">35.3.11 Pointers, references, values, and arrays</a></H3>
+<H3><a name="Scilab_wrapping_pointers_references_values_arrays">36.3.11 Pointers, references, values, and arrays</a></H3>
 
 
 <p>
@@ -1227,7 +1223,7 @@
 As the function <tt>spam7</tt> returns a value, new instance of <tt>Foo</tt> has to be allocated, and a pointer on this instance is returned.
 </p>
 
-<H3><a name="Scilab_wrapping_cpp_templates">35.3.12 C++ templates</a></H3>
+<H3><a name="Scilab_wrapping_cpp_templates">36.3.12 C++ templates</a></H3>
 
 
 <p>
@@ -1286,7 +1282,7 @@
 More details on template support can be found in the <a href="SWIGPlus.html#SWIGPlus_nn30">templates</a> documentation.
 </p>
 
-<H3><a name="Scilab_wrapping_cpp_operators">35.3.13 C++ operators</a></H3>
+<H3><a name="Scilab_wrapping_cpp_operators">36.3.13 C++ operators</a></H3>
 
 
 <p>
@@ -1339,7 +1335,7 @@
 </pre></div>
 
 
-<H3><a name="Scilab_wrapping_cpp_namespaces">35.3.14 C++ namespaces</a></H3>
+<H3><a name="Scilab_wrapping_cpp_namespaces">36.3.14 C++ namespaces</a></H3>
 
 
 <p>
@@ -1417,7 +1413,7 @@
 </p>
 
 
-<H3><a name="Scilab_wrapping_cpp_exceptions">35.3.15 C++ exceptions</a></H3>
+<H3><a name="Scilab_wrapping_cpp_exceptions">36.3.15 C++ exceptions</a></H3>
 
 
 <p>
@@ -1500,17 +1496,17 @@
 See the <a href="SWIGPlus.html#SWIGPlus">SWIG C++ documentation</a> for more details.
 </p>
 
-<H3><a name="Scilab_wrapping_cpp_stl">35.3.16 C++ STL</a></H3>
+<H3><a name="Scilab_wrapping_cpp_stl">36.3.16 C++ STL</a></H3>
 
 
 <p>
 The Standard Template Library (STL) is partially supported. See <a href="#Scilab_typemaps_stl">STL</a> for more details.
 </p>
 
-<H2><a name="Scilab_typemaps">35.4 Type mappings and libraries</a></H2>
+<H2><a name="Scilab_typemaps">36.4 Type mappings and libraries</a></H2>
 
 
-<H3><a name="Scilab_typemaps_primitive_types">35.4.1 Default primitive type mappings</a></H3>
+<H3><a name="Scilab_typemaps_primitive_types">36.4.1 Default primitive type mappings</a></H3>
 
 
 <p>
@@ -1561,7 +1557,7 @@
 
 
 
-<H3><a name="Scilab_typemaps_arrays">35.4.2 Arrays</a></H3>
+<H3><a name="Scilab_typemaps_arrays">36.4.2 Arrays</a></H3>
 
 
 <p>
@@ -1616,7 +1612,7 @@
 [ 0  1  2  3 ]
 </pre></div>
 
-<H3><a name="Scilab_typemaps_pointer-to-pointers">35.4.3 Pointer-to-pointers</a></H3>
+<H3><a name="Scilab_typemaps_pointer-to-pointers">36.4.3 Pointer-to-pointers</a></H3>
 
 
 <p>
@@ -1689,7 +1685,7 @@
 </pre></div>
 
 
-<H3><a name="Scilab_typemaps_matrices">35.4.4 Matrices</a></H3>
+<H3><a name="Scilab_typemaps_matrices">36.4.4 Matrices</a></H3>
 
 
 <p>
@@ -1782,7 +1778,7 @@
 <li>There is no control while converting <tt>double</tt> values to integers, <tt>double</tt> values are truncated without any checking or warning.</li>
 </ul>
 
-<H3><a name="Scilab_typemaps_stl">35.4.5 STL</a></H3>
+<H3><a name="Scilab_typemaps_stl">36.4.5 STL</a></H3>
 
 
 <p>
@@ -1982,7 +1978,7 @@
 --&gt; delete_PersonPtrSet(p);
 </pre></div>
 
-<H2><a name="Scilab_module_initialization">35.5 Module initialization</a></H2>
+<H2><a name="Scilab_module_initialization">36.5 Module initialization</a></H2>
 
 
 <p>
@@ -2006,7 +2002,7 @@
 --&gt; example_Init();
 </pre></div>
 
-<H2><a name="Scilab_building_modes">35.6 Building modes</a></H2>
+<H2><a name="Scilab_building_modes">36.6 Building modes</a></H2>
 
 
 <p>
@@ -2021,7 +2017,7 @@
 <li>the <tt>builder</tt> mode. In this mode, Scilab is responsible of building.
 </ul>
 
-<H3><a name="Scilab_building_modes_nobuilder_mode">35.6.1 No-builder mode</a></H3>
+<H3><a name="Scilab_building_modes_nobuilder_mode">36.6.1 No-builder mode</a></H3>
 
 
 <p>
@@ -2034,7 +2030,7 @@
 </p>
 
 
-<H3><a name="Scilab_building_modes_builder_mode">35.6.2 Builder mode</a></H3>
+<H3><a name="Scilab_building_modes_builder_mode">36.6.2 Builder mode</a></H3>
 
 
 <p>
@@ -2074,14 +2070,14 @@
 $ swig -scilab -builder -buildercflags -I/opt/foo/include -builderldflags "-L/opt/foo/lib -lfoo" -buildersources baa1.cxx, baa2.cxx example.i
 </pre></div>
 
-<H2><a name="Scilab_generated_scripts">35.7 Generated scripts</a></H2>
+<H2><a name="Scilab_generated_scripts">36.7 Generated scripts</a></H2>
 
 
 <p>
 In this part we give some details about the generated Scilab scripts.
 </p>
 
-<H3><a name="Scilab_generated_scripts_builder_script">35.7.1 Builder script</a></H3>
+<H3><a name="Scilab_generated_scripts_builder_script">36.7.1 Builder script</a></H3>
 
 
 <p>
@@ -2106,7 +2102,7 @@
 <li><tt><b>table</b></tt>: two column string matrix containing a table of pairs of 'scilab function name', 'C function name'.</li>
 </ul>
 
-<H3><a name="Scilab_generated_scripts_loader_script">35.7.2 Loader script</a></H3>
+<H3><a name="Scilab_generated_scripts_loader_script">36.7.2 Loader script</a></H3>
 
 
 <p>
@@ -2144,14 +2140,29 @@
 <li><tt><b>fcts</b></tt>: vector of character strings. The name of new Scilab function.</li>
 </ul>
 
+<H3><a name="Scilab_generated_scripts_gateway">36.7.3 Gateway XML files</a></H3>
 
-<H2><a name="Scilab_other_resources">35.8 Other resources</a></H2>
+
+<p>If you need to post-process the entry points, Scilab gateway files are XML files that can be used to retrieve all SWIG-generated entry points. With these XML files you can write your own <tt>builder_swig.sce</tt> file to add custom Scilab for building or linking the generated code. Documentation stubs can also be generated thanks to these function listings.</p>
+<p>As an example, for a SWIG <a href="Modules.html">module</a> named <tt>fmuswig</tt> the Scilab code below can be used to store all SWIG-generated functions in a variable named <tt>funs</tt>.</p>
+<div class="code"><pre>
+  // src_swig_path is a path to the directory containing the fmuswig.i file
+
+  doc = xmlRead(src_swig_path + "/fmuswig_gateway.xml");
+  names = xmlAsText(xmlXPath(doc, "//gateway/@name"));
+  funs = xmlAsText(xmlXPath(doc, "//gateway/@function"));
+  xmlDelete(doc);
+
+</pre></div>
+
+
+<H2><a name="Scilab_other_resources">36.8 Other resources</a></H2>
 
 
 <ul>
 <li>Example use cases can be found in the <tt>Examples/scilab</tt> directory.</li>
 <li>The test suite in the <tt>Examples/test-suite/scilab</tt> can be another source of useful use cases.</li>
-<li>The <a href="http://help.scilab.org/docs/5.5.0/en_US/api_scilab.html">Scilab API</a> is used in the generated code and is a useful reference when examining the output.</li>
-<li>This <a href="http://wiki.scilab.org/howto/Create%20a%20toolbox">guide</a> describes the Scilab external modules structure and files, in particular the files that are generated by SWIG for Scilab.</li>
+<li>The <a href="https://help.scilab.org/api_scilab.html">Scilab API</a> is used in the generated code and is a useful reference when examining the output.</li>
+<li>This <a href="https://wiki.scilab.org/howto/Create%20a%20toolbox">guide</a> describes the Scilab external modules structure and files, in particular the files that are generated by SWIG for Scilab.</li>
 </ul>
 
diff --git a/Doc/Manual/Sections.html b/Doc/Manual/Sections.html
index cc5f05e..cd848e0 100644
--- a/Doc/Manual/Sections.html
+++ b/Doc/Manual/Sections.html
@@ -1,14 +1,14 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <html>
 <head>
-<title>SWIG-4.0 Documentation</title>
+<title>SWIG-4.2 Documentation</title>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 </head>
 <body bgcolor="#ffffff">
-<H1><a name="Sections">SWIG-4.0 Documentation</a></H1>
+<H1><a name="Sections">SWIG-4.2 Documentation</a></H1>
 
 <p>
-Last update : SWIG-4.0.1 (21 Aug 2019)
+Last update : SWIG-4.2.1 (24 Feb 2024)
 </p>
 
 <H2><a name="Sections_Sections">Sections</a></H2>
@@ -24,6 +24,7 @@
 <li><a href="CPlusPlus11.html#CPlusPlus11">SWIG and C++11</a></li>
 <li><a href="CPlusPlus14.html#CPlusPlus14">SWIG and C++14</a></li>
 <li><a href="CPlusPlus17.html#CPlusPlus17">SWIG and C++17</a></li>
+<li><a href="CPlusPlus20.html#CPlusPlus20">SWIG and C++20</a></li>
 <li><a href="Preprocessor.html#Preprocessor">The SWIG preprocessor</a></li>
 <li><a href="Library.html#Library">The SWIG library</a></li>
 <li><a href="Arguments.html#Arguments">Argument handling</a></li>
diff --git a/Doc/Manual/Tcl.html b/Doc/Manual/Tcl.html
index ba5ca38..df9dd0f 100644
--- a/Doc/Manual/Tcl.html
+++ b/Doc/Manual/Tcl.html
@@ -7,7 +7,7 @@
 </head>
 
 <body bgcolor="#ffffff">
-<H1><a name="Tcl">36 SWIG and Tcl</a></H1>
+<H1><a name="Tcl">37 SWIG and Tcl</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -79,12 +79,12 @@
 </p>
 
 <p>
-This chapter discusses SWIG's support of Tcl. SWIG currently requires
-Tcl 8.0 or a later release.   Earlier releases of SWIG supported Tcl 7.x, but
-this is no longer supported.
+This chapter discusses SWIG's support of Tcl. Since SWIG 4.1.0, Tcl 8.4 or a
+later release is required.  Prior to that earlier Tcl 8.x releases were also
+supported.  Tcl 9.0 is supported since SWIG 4.2.1.
 </p>
 
-<H2><a name="Tcl_nn2">36.1 Preliminaries</a></H2>
+<H2><a name="Tcl_nn2">37.1 Preliminaries</a></H2>
 
 
 <p>
@@ -110,7 +110,7 @@
 need to compile this file and link it with the rest of your program.
 </p>
 
-<H3><a name="Tcl_nn3">36.1.1 Getting the right header files</a></H3>
+<H3><a name="Tcl_nn3">37.1.1 Getting the right header files</a></H3>
 
 
 <p>
@@ -128,7 +128,7 @@
 header file.
 </p>
 
-<H3><a name="Tcl_nn4">36.1.2 Compiling a dynamic module</a></H3>
+<H3><a name="Tcl_nn4">37.1.2 Compiling a dynamic module</a></H3>
 
 
 <p>
@@ -164,7 +164,7 @@
  <tt>-module</tt> command line option.
 </p>
 
-<H3><a name="Tcl_nn5">36.1.3 Static linking</a></H3>
+<H3><a name="Tcl_nn5">37.1.3 Static linking</a></H3>
 
 
 <p>
@@ -230,7 +230,7 @@
 hassle in the opinion of this author). 
 </p>
 
-<H3><a name="Tcl_nn6">36.1.4 Using your module</a></H3>
+<H3><a name="Tcl_nn6">37.1.4 Using your module</a></H3>
 
 
 <p>
@@ -358,7 +358,7 @@
 the man pages). 
 </p>
 
-<H3><a name="Tcl_nn7">36.1.5 Compilation of C++ extensions</a></H3>
+<H3><a name="Tcl_nn7">37.1.5 Compilation of C++ extensions</a></H3>
 
 
 <p>
@@ -441,7 +441,7 @@
 might want to investigate using a more formal standard such as COM.
 </p>
 
-<H3><a name="Tcl_nn8">36.1.6 Compiling for 64-bit platforms</a></H3>
+<H3><a name="Tcl_nn8">37.1.6 Compiling for 64-bit platforms</a></H3>
 
 
 <p>
@@ -468,7 +468,7 @@
 linking standard (e.g., -o32 and -n32 on Irix).
 </p>
 
-<H3><a name="Tcl_nn9">36.1.7 Setting a package prefix</a></H3>
+<H3><a name="Tcl_nn9">37.1.7 Setting a package prefix</a></H3>
 
 
 <p>
@@ -487,7 +487,7 @@
 call it "<tt>Foo_bar</tt>".
 </p>
 
-<H3><a name="Tcl_nn10">36.1.8 Using namespaces</a></H3>
+<H3><a name="Tcl_nn10">37.1.8 Using namespaces</a></H3>
 
 
 <p>
@@ -509,7 +509,7 @@
 are always accessed with the namespace name such as <tt>Foo::bar</tt>.
 </p>
 
-<H2><a name="Tcl_nn11">36.2 Building Tcl/Tk Extensions under Windows 95/NT</a></H2>
+<H2><a name="Tcl_nn11">37.2 Building Tcl/Tk Extensions under Windows 95/NT</a></H2>
 
 
 <p>
@@ -520,7 +520,7 @@
 although the procedure may be similar with other compilers.
 </p>
 
-<H3><a name="Tcl_nn12">36.2.1 Running SWIG from Developer Studio</a></H3>
+<H3><a name="Tcl_nn12">37.2.1 Running SWIG from Developer Studio</a></H3>
 
 
 <p>
@@ -578,7 +578,7 @@
 %
 </pre></div>
 
-<H3><a name="Tcl_nn13">36.2.2 Using NMAKE</a></H3>
+<H3><a name="Tcl_nn13">37.2.2 Using NMAKE</a></H3>
 
 
 <p>
@@ -636,12 +636,12 @@
 
 <p>
 To build the extension, run NMAKE (you may need to run vcvars32
-first).  This is a pretty minimal Makefile, but hopefully its enough
+first).  This is a pretty minimal Makefile, but hopefully it's enough
 to get you started.  With a little practice, you'll be making lots of
 Tcl extensions.
 </p>
 
-<H2><a name="Tcl_nn14">36.3 A tour of basic C/C++ wrapping</a></H2>
+<H2><a name="Tcl_nn14">37.3 A tour of basic C/C++ wrapping</a></H2>
 
 
 <p>
@@ -652,7 +652,7 @@
 wrapping.
 </p>
 
-<H3><a name="Tcl_nn15">36.3.1 Modules</a></H3>
+<H3><a name="Tcl_nn15">37.3.1 Modules</a></H3>
 
 
 <p>
@@ -686,7 +686,7 @@
 </pre>
 </div>
 
-<H3><a name="Tcl_nn16">36.3.2 Functions</a></H3>
+<H3><a name="Tcl_nn16">37.3.2 Functions</a></H3>
 
 
 <p>
@@ -711,7 +711,7 @@
 %
 </pre></div>
 
-<H3><a name="Tcl_nn17">36.3.3 Global variables</a></H3>
+<H3><a name="Tcl_nn17">37.3.3 Global variables</a></H3>
 
 
 <p>
@@ -791,7 +791,7 @@
 </pre>
 </div>
 
-<H3><a name="Tcl_nn18">36.3.4 Constants and enums</a></H3>
+<H3><a name="Tcl_nn18">37.3.4 Constants and enums</a></H3>
 
 
 <p>
@@ -826,7 +826,7 @@
 
 <p>
 Constants are not guaranteed to remain constant in Tcl---the value
-of the constant could be accidentally reassigned.You will just have to be careful.
+of the constant could be accidentally reassigned. You will just have to be careful.
 </p>
 
 <p>
@@ -843,39 +843,7 @@
 </pre>
 </div>
 
-<p>
-If a program relies on a lot of constants, this can be extremely annoying.  To fix the problem, consider using the
-following typemap rule:
-</p>
-
-<div class="code">
-<pre>
-%apply int CONSTANT { int x };
-#define FOO 42
-...
-void bar(int x);
-</pre>
-</div>
-
-<p>
-When applied to an input argument, the <tt>CONSTANT</tt> rule allows a constant to be passed to a function using
-its actual value or a symbolic identifier name.  For example:
-</p>
-
-<div class="code">
-<pre>
-proc blah {} {
-  bar FOO
-}
-</pre>
-</div>
-
-<p>
-When an identifier name is given, it is used to perform an implicit hash-table lookup of the value during argument 
-conversion.  This allows the <tt>global</tt> statement to be omitted.
-</p>
-
-<H3><a name="Tcl_nn19">36.3.5 Pointers</a></H3>
+<H3><a name="Tcl_nn19">37.3.5 Pointers</a></H3>
 
 
 <p>
@@ -971,7 +939,7 @@
 <tt>None</tt> if the conversion can't be performed.
 </p>
 
-<H3><a name="Tcl_nn20">36.3.6 Structures</a></H3>
+<H3><a name="Tcl_nn20">37.3.6 Structures</a></H3>
 
 
 <p>
@@ -1227,7 +1195,15 @@
 
 <p>
 Finally, to destroy objects created from Tcl, you can either let the object
-name go out of scope or you can explicitly delete the object.  For example:
+name go out of scope or you can explicitly delete the object as shown below.
+Objects won't get automatically destroyed when the Tcl program exits, so if
+it's important that the C++ destructor is called for a class you'll need to
+make sure that you explicitly do this for objects of that class before program
+exit.
+</p>
+
+<p>
+For example:
 </p>
 
 <div class="code">
@@ -1253,7 +1229,7 @@
 memory management section that appears shortly.
 </p>
 
-<H3><a name="Tcl_nn21">36.3.7 C++ classes</a></H3>
+<H3><a name="Tcl_nn21">37.3.7 C++ classes</a></H3>
 
 
 <p>
@@ -1319,7 +1295,7 @@
 </pre>
 </div>
 
-<H3><a name="Tcl_nn22">36.3.8 C++ inheritance</a></H3>
+<H3><a name="Tcl_nn22">37.3.8 C++ inheritance</a></H3>
 
 
 <p>
@@ -1368,7 +1344,7 @@
 It is safe to use multiple inheritance with SWIG.
 </p>
 
-<H3><a name="Tcl_nn23">36.3.9 Pointers, references, values, and arrays</a></H3>
+<H3><a name="Tcl_nn23">37.3.9 Pointers, references, values, and arrays</a></H3>
 
 
 <p>
@@ -1422,7 +1398,7 @@
 when the return value is garbage collected).
 </p>
 
-<H3><a name="Tcl_nn24">36.3.10 C++ overloaded functions</a></H3>
+<H3><a name="Tcl_nn24">37.3.10 C++ overloaded functions</a></H3>
 
 
 <p>
@@ -1545,7 +1521,7 @@
 Please refer to the "SWIG and C++" chapter for more information about overloading. 
 </p>
 
-<H3><a name="Tcl_nn25">36.3.11 C++ operators</a></H3>
+<H3><a name="Tcl_nn25">37.3.11 C++ operators</a></H3>
 
 
 <p>
@@ -1647,7 +1623,7 @@
 Keep reading.
 </p>
 
-<H3><a name="Tcl_nn26">36.3.12 C++ namespaces</a></H3>
+<H3><a name="Tcl_nn26">37.3.12 C++ namespaces</a></H3>
 
 
 <p>
@@ -1711,7 +1687,7 @@
 identical symbol names, well, then you get what you deserve.
 </p>
 
-<H3><a name="Tcl_nn27">36.3.13 C++ templates</a></H3>
+<H3><a name="Tcl_nn27">37.3.13 C++ templates</a></H3>
 
 
 <p>
@@ -1763,7 +1739,7 @@
 examples will appear later.
 </p>
 
-<H3><a name="Tcl_nn28">36.3.14 C++ Smart Pointers</a></H3>
+<H3><a name="Tcl_nn28">37.3.14 C++ Smart Pointers</a></H3>
 
 
 <p>
@@ -1847,7 +1823,7 @@
 </pre>
 </div>
 
-<H2><a name="Tcl_nn29">36.4 Further details on the Tcl class interface</a></H2>
+<H2><a name="Tcl_nn29">37.4 Further details on the Tcl class interface</a></H2>
 
 
 <p>
@@ -1860,7 +1836,7 @@
 of how the proxy classes work.
 </p>
 
-<H3><a name="Tcl_nn30">36.4.1 Proxy classes</a></H3>
+<H3><a name="Tcl_nn30">37.4.1 Proxy classes</a></H3>
 
 
 <p>
@@ -1925,7 +1901,7 @@
 as shown in the last section.
 </p>
 
-<H3><a name="Tcl_nn31">36.4.2 Memory management</a></H3>
+<H3><a name="Tcl_nn31">37.4.2 Memory management</a></H3>
 
 
 <p>
@@ -2113,7 +2089,7 @@
 </p>
 
 
-<H2><a name="Tcl_nn32">36.5 Input and output parameters</a></H2>
+<H2><a name="Tcl_nn32">37.5 Input and output parameters</a></H2>
 
 
 <p>
@@ -2235,7 +2211,7 @@
 <div class="code">
 <pre>
 /* send message, return number of bytes sent, along with success code */
-int send_message(char *text, int len, int *success);
+int send_message(char *text, int *success);
 </pre>
 </div>
 
@@ -2301,7 +2277,7 @@
 </pre>
 </div>
 
-<H2><a name="Tcl_nn33">36.6 Exception handling </a></H2>
+<H2><a name="Tcl_nn33">37.6 Exception handling </a></H2>
 
 
 <p>
@@ -2435,7 +2411,7 @@
 See the chapter on "<a href="Customization.html#Customization">Customization Features</a>" for more examples.
 </p>
 
-<H2><a name="Tcl_nn34">36.7 Typemaps</a></H2>
+<H2><a name="Tcl_nn34">37.7 Typemaps</a></H2>
 
 
 <p>
@@ -2452,7 +2428,7 @@
 C-Tcl interface.
 </p>
 
-<H3><a name="Tcl_nn35">36.7.1 What is a typemap?</a></H3>
+<H3><a name="Tcl_nn35">37.7.1 What is a typemap?</a></H3>
 
 
 <p>
@@ -2572,7 +2548,7 @@
 </pre>
 </div>
 
-<H3><a name="Tcl_nn36">36.7.2 Tcl typemaps</a></H3>
+<H3><a name="Tcl_nn36">37.7.2 Tcl typemaps</a></H3>
 
 
 <p>
@@ -2710,7 +2686,7 @@
 Examples of these methods will appear shortly.
 </p>
 
-<H3><a name="Tcl_nn37">36.7.3 Typemap variables</a></H3>
+<H3><a name="Tcl_nn37">37.7.3 Typemap variables</a></H3>
 
 
 <p>
@@ -2781,7 +2757,7 @@
 The Tcl name of the wrapper function being created.
 </div>
 
-<H3><a name="Tcl_nn38">36.7.4 Converting  a Tcl list to a char ** </a></H3>
+<H3><a name="Tcl_nn38">37.7.4 Converting  a Tcl list to a char ** </a></H3>
 
 
 <p>
@@ -2804,16 +2780,14 @@
   }
   $1 = (char **) malloc((nitems+1)*sizeof(char *));
   for (i = 0; i &lt; nitems; i++) {
-    $1[i] = Tcl_GetStringFromObj(listobjv[i], 0);
+    $1[i] = Tcl_GetString(listobjv[i]);
   }
   $1[i] = 0;
 }
 
 // This gives SWIG some cleanup code that will get called after the function call
 %typemap(freearg) char ** {
-  if ($1) {
-    free($1);
-  }
+  free($1);
 }
 
 // Now a test functions
@@ -2843,7 +2817,7 @@
 3
 </pre></div>
 
-<H3><a name="Tcl_nn39">36.7.5 Returning values in arguments</a></H3>
+<H3><a name="Tcl_nn39">37.7.5 Returning values in arguments</a></H3>
 
 
 <p>
@@ -2885,7 +2859,7 @@
 %
 </pre></div>
 
-<H3><a name="Tcl_nn40">36.7.6 Useful functions</a></H3>
+<H3><a name="Tcl_nn40">37.7.6 Useful functions</a></H3>
 
 
 <p>
@@ -2961,7 +2935,7 @@
 </pre>
 </div>
 
-<H3><a name="Tcl_nn41">36.7.7 Standard  typemaps</a></H3>
+<H3><a name="Tcl_nn41">37.7.7 Standard  typemaps</a></H3>
 
 
 <p>
@@ -3045,7 +3019,7 @@
 </pre>
 </div>
 
-<H3><a name="Tcl_nn42">36.7.8 Pointer handling</a></H3>
+<H3><a name="Tcl_nn42">37.7.8 Pointer handling</a></H3>
 
 
 <p>
@@ -3127,13 +3101,12 @@
 </pre>
 </div>
 
-<H2><a name="Tcl_nn43">36.8 Turning a SWIG module into a Tcl Package.</a></H2>
+<H2><a name="Tcl_nn43">37.8 Turning a SWIG module into a Tcl Package.</a></H2>
 
 
 <p>
-Tcl 7.4 introduced the idea of an extension package.  By default, SWIG
-generates all of the code necessary to create a package. To set the package version,
-simply use the <tt>-pkgversion</tt> option. For example:
+SWIG generates all of the code necessary to create a Tcl extension package.
+To set the package version use the <tt>-pkgversion</tt> option. For example:
 </p>
 
 <div class="code">
@@ -3144,7 +3117,7 @@
 
 <p>
 After building the SWIG generated module, you need to execute
-the "<tt>pkg_mkIndex</tt>" command inside tclsh.  For example :
+the <tt>pkg_mkIndex</tt> command inside tclsh.  For example :
 </p>
 
 <div class="code"><pre>
@@ -3199,7 +3172,7 @@
 to use the <tt>load</tt> command instead.
 </p>
 
-<H2><a name="Tcl_nn44">36.9 Building new kinds of Tcl interfaces (in Tcl)</a></H2>
+<H2><a name="Tcl_nn44">37.9 Building new kinds of Tcl interfaces (in Tcl)</a></H2>
 
 
 <p>
@@ -3298,7 +3271,7 @@
 with an out of bounds array access).
 </p>
 
-<H3><a name="Tcl_nn45">36.9.1 Proxy classes</a></H3>
+<H3><a name="Tcl_nn45">37.9.1 Proxy classes</a></H3>
 
 
 <p>
@@ -3419,12 +3392,12 @@
 interesting things.
 </p>
 
-<H2><a name="Tcl_nn46">36.10 Tcl/Tk Stubs</a></H2>
+<H2><a name="Tcl_nn46">37.10 Tcl/Tk Stubs</a></H2>
 
 
 <p>
 For background information about the Tcl Stubs feature, see
-<a href="http://www.tcl.tk/doc/howto/stubs.html">http://www.tcl.tk/doc/howto/stubs.html</a>.
+<a href="https://www.tcl.tk/doc/howto/stubs.html">https://www.tcl.tk/doc/howto/stubs.html</a>.
 </p>
 
 <p>
@@ -3434,11 +3407,17 @@
 
 <p>
 As of SWIG 1.3.40, the generated C/C++ wrapper will use the Tk Stubs
-feature if compiled with <tt>-DUSE_TK_STUBS</tt>.  Also, you can override
-the minimum version to support which is passed to <tt>Tcl_InitStubs()</tt>
-and <tt>Tk_InitStubs()</tt> with <tt>-DSWIG_TCL_STUBS_VERSION="8.3"</tt>
-or the version being compiled with using
-<tt>-DSWIG_TCL_STUBS_VERSION=TCL_VERSION</tt>.
+feature if compiled with <tt>-DUSE_TK_STUBS</tt>.
+</p>
+
+<p>
+By default SWIG sets the minimum Tcl version to support to the 8.4
+as that's the minimum Tcl version we aim to support (since SWIG 4.1.0; before
+this SWIG set it to 8.1, which was the first Tcl version with the stubs
+mechanism). This minimum version is passed to <tt>Tcl_InitStubs()</tt> and
+<tt>Tk_InitStubs()</tt>. You can override with a specific version using
+<tt>-DSWIG_TCL_STUBS_VERSION="8.5"</tt> or set it to the Tcl version being
+compiled with using <tt>-DSWIG_TCL_STUBS_VERSION=TCL_VERSION</tt>.
 </p>
 
 </body>
diff --git a/Doc/Manual/Typemaps.html b/Doc/Manual/Typemaps.html
index 0bacd39..5d8d6cf 100644
--- a/Doc/Manual/Typemaps.html
+++ b/Doc/Manual/Typemaps.html
@@ -7,7 +7,7 @@
 </head>
 
 <body bgcolor="#ffffff">
-<H1><a name="Typemaps">13 Typemaps</a></H1>
+<H1><a name="Typemaps">14 Typemaps</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -48,6 +48,7 @@
 <ul>
 <li><a href="#Typemaps_special_macro_descriptor">$descriptor(type)</a>
 <li><a href="#Typemaps_special_macro_typemap">$typemap(method, typepattern)</a>
+<li><a href="#Typemaps_special_macro_typemap_attribute">$typemap(method:attribute, typepattern)</a>
 </ul>
 <li><a href="#Typemaps_special_variable_attributes">Special variables and typemap attributes</a>
 <li><a href="#Typemaps_special_variables_and_macros">Special variables combined with special variable macros</a>
@@ -102,7 +103,7 @@
 
 
 
-<H2><a name="Typemaps_nn2">13.1 Introduction</a></H2>
+<H2><a name="Typemaps_nn2">14.1 Introduction</a></H2>
 
 
 <p>
@@ -119,7 +120,7 @@
 chapter with only a vague idea of what SWIG already does by default.
 </p>
 
-<H3><a name="Typemaps_nn3">13.1.1 Type conversion</a></H3>
+<H3><a name="Typemaps_nn3">14.1.1 Type conversion</a></H3>
 
 
 <p>
@@ -212,7 +213,7 @@
 how it works (an exercise left to the reader).
 </p>
 
-<H3><a name="Typemaps_nn4">13.1.2 Typemaps</a></H3>
+<H3><a name="Typemaps_nn4">14.1.2 Typemaps</a></H3>
 
 
 <p>
@@ -313,7 +314,7 @@
 possible to completely change the way in which values are converted.
 </p>
 
-<H3><a name="Typemaps_nn5">13.1.3 Pattern matching</a></H3>
+<H3><a name="Typemaps_nn5">14.1.3 Pattern matching</a></H3>
 
 
 <p>
@@ -415,7 +416,7 @@
 provides a hint to the unusual variable naming scheme involving <tt>$1</tt>, <tt>$2</tt>, and so forth.
 </p>
 
-<H3><a name="Typemaps_nn6">13.1.4 Reusing typemaps</a></H3>
+<H3><a name="Typemaps_nn6">14.1.4 Reusing typemaps</a></H3>
 
 
 <p>
@@ -493,7 +494,7 @@
 then SWIG already knows that the <tt>int</tt> typemaps apply.  You don't have to do anything.
 </p>
 
-<H3><a name="Typemaps_nn7">13.1.5 What can be done with typemaps?</a></H3>
+<H3><a name="Typemaps_nn7">14.1.5 What can be done with typemaps?</a></H3>
 
 
 <p>
@@ -605,7 +606,7 @@
 aspects of the Java bindings.  Consult language specific documentation for further details.
 </p>
 
-<H3><a name="Typemaps_nn8">13.1.6 What can't be done with typemaps?</a></H3>
+<H3><a name="Typemaps_nn8">14.1.6 What can't be done with typemaps?</a></H3>
 
 
 <p>
@@ -668,7 +669,7 @@
 </pre>
 </div>
 
-<H3><a name="Typemaps_aspects">13.1.7 Similarities to Aspect Oriented Programming</a></H3>
+<H3><a name="Typemaps_aspects">14.1.7 Similarities to Aspect Oriented Programming</a></H3>
 
 
 <p>
@@ -686,7 +687,7 @@
 Features such as <tt>%exception</tt> are also cross-cutting concerns as they encapsulate code that can be used to add logging or exception handling to any function.
 </p>
 
-<H3><a name="Typemaps_nn9">13.1.8 The rest of this chapter</a></H3>
+<H3><a name="Typemaps_nn9">14.1.8 The rest of this chapter</a></H3>
 
 
 <p>
@@ -706,14 +707,14 @@
 "The C++ Programming Language" by Stroustrup before going any further.
 </p>
 
-<H2><a name="Typemaps_nn10">13.2 Typemap specifications</a></H2>
+<H2><a name="Typemaps_nn10">14.2 Typemap specifications</a></H2>
 
 
 <p>
 This section describes the behavior of the <tt>%typemap</tt> directive itself.
 </p>
 
-<H3><a name="Typemaps_defining">13.2.1 Defining a typemap</a></H3>
+<H3><a name="Typemaps_defining">14.2.1 Defining a typemap</a></H3>
 
 
 <p>
@@ -786,7 +787,7 @@
 %typemap(in) int {
   $1 = PyInt_AsLong($input);
 }
-%typemap(in) int "$1 = PyInt_AsLong($input);";
+%typemap(in) int "$1 = PyInt_AsLong($input);"
 %typemap(in) int %{ 
   $1 = PyInt_AsLong($input);
 %}
@@ -802,7 +803,7 @@
 }
 
 /* Typemap with modifiers */
-%typemap(in, doc="integer") int "$1 = scm_to_int($input);";
+%typemap(in, doc="integer") int "$1 = scm_to_int($input);"
 
 /* Typemap applied to patterns of multiple arguments */
 %typemap(in) (char *str, int len),
@@ -826,7 +827,7 @@
 individual pieces will become clear.
 </p>
 
-<H3><a name="Typemaps_nn12">13.2.2 Typemap scope</a></H3>
+<H3><a name="Typemaps_nn12">14.2.2 Typemap scope</a></H3>
 
 
 <p>
@@ -876,7 +877,7 @@
 </pre>
 </div>
 
-<H3><a name="Typemaps_nn13">13.2.3 Copying a typemap</a></H3>
+<H3><a name="Typemaps_nn13">14.2.3 Copying a typemap</a></H3>
 
 
 <p>
@@ -934,7 +935,7 @@
 </pre>
 </div>
 
-<H3><a name="Typemaps_nn14">13.2.4 Deleting a typemap</a></H3>
+<H3><a name="Typemaps_nn14">14.2.4 Deleting a typemap</a></H3>
 
 
 <p>
@@ -968,7 +969,7 @@
 after the clear operation.
 </p>
 
-<H3><a name="Typemaps_nn15">13.2.5 Placement of typemaps</a></H3>
+<H3><a name="Typemaps_nn15">14.2.5 Placement of typemaps</a></H3>
 
 
 <p>
@@ -1048,7 +1049,7 @@
 within a particular namespace.  In this example, this is done using the forward class declaration <tt>class string</tt>.
 </p>
 
-<H2><a name="Typemaps_pattern_matching">13.3 Pattern matching rules</a></H2>
+<H2><a name="Typemaps_pattern_matching">14.3 Pattern matching rules</a></H2>
 
 
 <p>
@@ -1056,13 +1057,15 @@
 The matching rules can be observed in practice by using the debugging options also described.
 </p>
 
-<H3><a name="Typemaps_nn17">13.3.1 Basic matching rules</a></H3>
+<H3><a name="Typemaps_nn17">14.3.1 Basic matching rules</a></H3>
 
 
 <p>
-Typemaps are matched using both a type and a name (typically the name of a argument).  For a given
-<tt>TYPE NAME</tt> pair, the following rules are applied, in order, to find a match.  The first typemap found
-is used.
+Typemaps are matched using both a type and a name (typically the name of an
+argument, but in the case of <tt>out</tt> typemaps, the name of a function,
+qualified by the class name if it's a class method).  For a given <tt>TYPE
+NAME</tt> pair, the following rules are applied, in order, to find a match.
+The first typemap found is used.
 </p>
 
 <ul>
@@ -1155,7 +1158,7 @@
 stripped all qualifiers in one step.
 </p>
 
-<H3><a name="Typemaps_typedef_reductions">13.3.2 Typedef reductions matching</a></H3>
+<H3><a name="Typemaps_typedef_reductions">14.3.2 Typedef reductions matching</a></H3>
 
 
 <p>
@@ -1330,7 +1333,7 @@
 </pre>
 </div>
 
-<H3><a name="Typemaps_nn19">13.3.3 Default typemap matching rules</a></H3>
+<H3><a name="Typemaps_nn19">14.3.3 Default typemap matching rules</a></H3>
 
 
 <p>
@@ -1353,13 +1356,13 @@
 
 <div class="code">
 <pre>
-%typemap(in) int           "... convert to int ...";
-%typemap(in) short         "... convert to short ...";
-%typemap(in) float         "... convert to float ...";
+%typemap(in) int           "... convert to int ..."
+%typemap(in) short         "... convert to short ..."
+%typemap(in) float         "... convert to float ..."
 ...
-%typemap(in) const int &amp;   "... convert ...";
-%typemap(in) const short &amp; "... convert ...";
-%typemap(in) const float &amp; "... convert ...";
+%typemap(in) const int &amp;   "... convert ..."
+%typemap(in) const short &amp; "... convert ..."
+%typemap(in) const float &amp; "... convert ..."
 ...
 </pre>
 </div>
@@ -1379,16 +1382,16 @@
 
 <div class="code">
 <pre>
-%typemap(in) SWIGTYPE &amp;            { ... default reference handling ...                       };
-%typemap(in) SWIGTYPE *            { ... default pointer handling ...                         };
-%typemap(in) SWIGTYPE *const       { ... default pointer const handling ...                   };
-%typemap(in) SWIGTYPE *const&amp;      { ... default pointer const reference handling ...         };
-%typemap(in) SWIGTYPE[ANY]         { ... 1D fixed size arrays handling ...                    };
-%typemap(in) SWIGTYPE []           { ... unknown sized array handling ...                     };
-%typemap(in) enum SWIGTYPE         { ... default handling for enum values ...                 };
-%typemap(in) const enum SWIGTYPE &amp; { ... default handling for const enum reference values ... };
-%typemap(in) SWIGTYPE (CLASS::*)   { ... default pointer member handling ...                  };
-%typemap(in) SWIGTYPE              { ... simple default handling ...                          };
+%typemap(in) SWIGTYPE &amp;            { ... default reference handling ...                       }
+%typemap(in) SWIGTYPE *            { ... default pointer handling ...                         }
+%typemap(in) SWIGTYPE *const       { ... default pointer const handling ...                   }
+%typemap(in) SWIGTYPE *const&amp;      { ... default pointer const reference handling ...         }
+%typemap(in) SWIGTYPE[ANY]         { ... 1D fixed size arrays handling ...                    }
+%typemap(in) SWIGTYPE []           { ... unknown sized array handling ...                     }
+%typemap(in) enum SWIGTYPE         { ... default handling for enum values ...                 }
+%typemap(in) const enum SWIGTYPE &amp; { ... default handling for const enum reference values ... }
+%typemap(in) SWIGTYPE (CLASS::*)   { ... default pointer member handling ...                  }
+%typemap(in) SWIGTYPE              { ... simple default handling ...                          }
 </pre>
 </div>
 
@@ -1468,7 +1471,7 @@
 simpler scheme to match the current C++ class template partial specialization matching rules.
 </p>
 
-<H3><a name="Typemaps_multi_argument_typemaps_patterns">13.3.4 Multi-arguments typemaps</a></H3>
+<H3><a name="Typemaps_multi_argument_typemaps_patterns">14.3.4 Multi-arguments typemaps</a></H3>
 
 
 <p>
@@ -1498,7 +1501,7 @@
 </p>
 
 
-<H3><a name="Typemaps_matching_template_comparison">13.3.5 Matching rules compared to C++ templates</a></H3>
+<H3><a name="Typemaps_matching_template_comparison">14.3.5 Matching rules compared to C++ templates</a></H3>
 
 
 <p>
@@ -1657,7 +1660,7 @@
 </p>
 
 
-<H3><a name="Typemaps_debugging_search">13.3.6 Debugging typemap pattern matching</a></H3>
+<H3><a name="Typemaps_debugging_search">14.3.6 Debugging typemap pattern matching</a></H3>
 
 
 <p>
@@ -1870,7 +1873,7 @@
 </li>
 </ul>
 
-<H2><a name="Typemaps_nn21">13.4 Code generation rules</a></H2>
+<H2><a name="Typemaps_nn21">14.4 Code generation rules</a></H2>
 
 
 <p>
@@ -1878,7 +1881,7 @@
 the generated wrapper code.
 </p>
 
-<H3><a name="Typemaps_nn22">13.4.1 Scope</a></H3>
+<H3><a name="Typemaps_nn22">14.4.1 Scope</a></H3>
 
 
 <p>
@@ -1940,7 +1943,7 @@
 
 <div class="code">
 <pre>
-%typemap(in) int "$1 = PyInt_AsLong($input);";
+%typemap(in) int "$1 = PyInt_AsLong($input);"
 %typemap(in) int %{
 $1 = PyInt_AsLong($input);
 %}
@@ -1956,7 +1959,7 @@
 Note that only the third of the three typemaps have the typemap code passed through the SWIG preprocessor.
 </p>
 
-<H3><a name="Typemaps_nn23">13.4.2 Declaring new local variables</a></H3>
+<H3><a name="Typemaps_nn23">14.4.2 Declaring new local variables</a></H3>
 
 
 <p>
@@ -2123,7 +2126,7 @@
 </div>
 
 
-<H3><a name="Typemaps_special_variables">13.4.3 Special variables</a></H3>
+<H3><a name="Typemaps_special_variables">14.4.3 Special variables</a></H3>
 
 
 <p>
@@ -2375,7 +2378,7 @@
 </pre>
 </div>
 
-<H3><a name="Typemaps_special_variable_macros">13.4.4 Special variable macros</a></H3>
+<H3><a name="Typemaps_special_variable_macros">14.4.4 Special variable macros</a></H3>
 
 
 <p>
@@ -2387,7 +2390,7 @@
 The following special variable macros are available across all language modules.
 </p>
 
-<H4><a name="Typemaps_special_macro_descriptor">13.4.4.1 $descriptor(type)</a></H4>
+<H4><a name="Typemaps_special_macro_descriptor">14.4.4.1 $descriptor(type)</a></H4>
 
 
 <p>
@@ -2398,7 +2401,7 @@
 This macro is mostly used in the scripting target languages and is demonstrated later in the <a href="#Typemaps_runtime_type_checker_usage">Run-time type checker usage</a> section.
 </p>
 
-<H4><a name="Typemaps_special_macro_typemap">13.4.4.2 $typemap(method, typepattern)</a></H4>
+<H4><a name="Typemaps_special_macro_typemap">14.4.4.2 $typemap(method, typepattern)</a></H4>
 
 
 <p>
@@ -2455,8 +2458,43 @@
 </pre>
 </div>
 
+<H4><a name="Typemaps_special_macro_typemap_attribute">14.4.4.3 $typemap(method:attribute, typepattern)</a></H4>
 
-<H3><a name="Typemaps_special_variable_attributes">13.4.5 Special variables and typemap attributes</a></H3>
+
+<p>
+An enhanced version of <tt>$typemap</tt> provides access to typemap attributes by
+appending a colon and the attribute name after the method name. In the example below,
+"cstype" is the typemap method and "out" is the typemap attribute.
+</p>
+
+<div class="code">
+<pre>
+%typemap(cstype, out="object") XClass "XClass"
+%typemap(cscode) BarClass %{
+  $typemap(cstype:out, XClass) bar()
+  {
+    return null;
+  }
+</pre>
+</div>
+<p>
+which expands to
+</p>
+<div class="code">
+<pre>
+  object bar()
+  {
+    return null;
+  }
+</pre>
+</div>
+
+<p>
+<b>Compatibility note: </b> Support for typemap attributes in <tt>$typemap</tt>
+was introduced in SWIG-4.1.0.
+</p>
+
+<H3><a name="Typemaps_special_variable_attributes">14.4.5 Special variables and typemap attributes</a></H3>
 
 
 <p>
@@ -2483,7 +2521,7 @@
 </pre>
 </div>
 
-<H3><a name="Typemaps_special_variables_and_macros">13.4.6 Special variables combined with special variable macros</a></H3>
+<H3><a name="Typemaps_special_variables_and_macros">14.4.6 Special variables combined with special variable macros</a></H3>
 
 
 <p>
@@ -2525,7 +2563,7 @@
 </div>
 
 
-<H2><a name="Typemaps_nn25">13.5 Common typemap methods</a></H2>
+<H2><a name="Typemaps_nn25">14.5 Common typemap methods</a></H2>
 
 
 <p>
@@ -2533,7 +2571,7 @@
 the following typemap methods are nearly universal:
 </p>
 
-<H3><a name="Typemaps_nn26">13.5.1 "in" typemap</a></H3>
+<H3><a name="Typemaps_nn26">14.5.1 "in" typemap</a></H3>
 
 
 <p>
@@ -2588,12 +2626,7 @@
 <a href="#Typemaps_multi_argument_typemaps">Multi-argument typemaps</a> provide a similar concept where the number of arguments mapped from the target language to C/C++ can be changed for multiple adjacent C/C++ arguments.
 </p>
 
-<p>
-<b>Compatibility note: </b> Specifying <tt>numinputs=0</tt>
-is the same as the old "ignore" typemap.
-</p>
-
-<H3><a name="Typemaps_nn27">13.5.2 "typecheck" typemap</a></H3>
+<H3><a name="Typemaps_nn27">14.5.2 "typecheck" typemap</a></H3>
 
 
 <p>
@@ -2620,7 +2653,7 @@
 "typecheck" typemaps.  More details about this follow in the <a href="#Typemaps_overloading">Typemaps and overloading</a> section.
 </p>
 
-<H3><a name="Typemaps_nn28">13.5.3 "out" typemap</a></H3>
+<H3><a name="Typemaps_nn28">14.5.3 "out" typemap</a></H3>
 
 
 <p>
@@ -2651,7 +2684,7 @@
 The "out" typemap supports an optional attribute flag called "optimal". This is for code optimisation and is detailed in the <a href="#Typemaps_optimal">Optimal code generation when returning by value</a> section.
 </p>
 
-<H3><a name="Typemaps_nn29">13.5.4 "arginit" typemap</a></H3>
+<H3><a name="Typemaps_nn29">14.5.4 "arginit" typemap</a></H3>
 
 
 <p>
@@ -2670,7 +2703,7 @@
 </pre>
 </div>
 
-<H3><a name="Typemaps_nn30">13.5.5 "default" typemap</a></H3>
+<H3><a name="Typemaps_nn30">14.5.5 "default" typemap</a></H3>
 
 
 <p>
@@ -2703,7 +2736,7 @@
 for further information on default argument wrapping.
 </p>
 
-<H3><a name="Typemaps_nn31">13.5.6 "check" typemap</a></H3>
+<H3><a name="Typemaps_nn31">14.5.6 "check" typemap</a></H3>
 
 
 <p>
@@ -2722,7 +2755,7 @@
 </pre>
 </div>
 
-<H3><a name="Typemaps_nn32">13.5.7 "argout" typemap</a></H3>
+<H3><a name="Typemaps_nn32">14.5.7 "argout" typemap</a></H3>
 
 
 <p>
@@ -2768,7 +2801,7 @@
 See the <tt>typemaps.i</tt> library file for examples.
 </p>
 
-<H3><a name="Typemaps_nn33">13.5.8 "freearg" typemap</a></H3>
+<H3><a name="Typemaps_nn33">14.5.8 "freearg" typemap</a></H3>
 
 
 <p>
@@ -2801,7 +2834,7 @@
 prematurely.
 </p>
 
-<H3><a name="Typemaps_nn34">13.5.9 "newfree" typemap</a></H3>
+<H3><a name="Typemaps_nn34">14.5.9 "newfree" typemap</a></H3>
 
 
 <p>
@@ -2830,7 +2863,7 @@
 See <a href="Customization.html#Customization_ownership">Object ownership and %newobject</a> for further details.
 </p>
 
-<H3><a name="Typemaps_ret">13.5.10 "ret" typemap</a></H3>
+<H3><a name="Typemaps_ret">14.5.10 "ret" typemap</a></H3>
 
 
 <p>
@@ -2869,7 +2902,7 @@
 is no need to list all the functions that require the memory cleanup, it is purely done on types.
 </p>
 
-<H3><a name="Typemaps_nn35">13.5.11 "memberin" typemap</a></H3>
+<H3><a name="Typemaps_nn35">14.5.11 "memberin" typemap</a></H3>
 
 
 <p>
@@ -2891,7 +2924,7 @@
 a default implementation for arrays, strings, and other objects.
 </p>
 
-<H3><a name="Typemaps_nn36">13.5.12 "varin" typemap</a></H3>
+<H3><a name="Typemaps_nn36">14.5.12 "varin" typemap</a></H3>
 
 
 <p>
@@ -2899,7 +2932,7 @@
 purposes of assigning to a C/C++ global variable.    This is implementation specific.
 </p>
 
-<H3><a name="Typemaps_nn37">13.5.13 "varout" typemap</a></H3>
+<H3><a name="Typemaps_nn37">14.5.13 "varout" typemap</a></H3>
 
 
 <p>
@@ -2907,7 +2940,7 @@
 language when reading a C/C++ global variable.  This is implementation specific.
 </p>
 
-<H3><a name="Typemaps_throws_typemap">13.5.14 "throws" typemap</a></H3>
+<H3><a name="Typemaps_throws_typemap">14.5.14 "throws" typemap</a></H3>
 
 
 <p>
@@ -2957,7 +2990,7 @@
 Please also see the <a href="Customization.html#Customization_exception">Exception handling with %exception</a> section for another way to handle exceptions.
 </p>
 
-<H2><a name="Typemaps_nn39">13.6 Some typemap examples</a></H2>
+<H2><a name="Typemaps_nn39">14.6 Some typemap examples</a></H2>
 
 
 <p>
@@ -2965,7 +2998,7 @@
 for more examples.
 </p>
 
-<H3><a name="Typemaps_nn40">13.6.1 Typemaps for arrays</a></H3>
+<H3><a name="Typemaps_nn40">14.6.1 Typemaps for arrays</a></H3>
 
 
 <p>
@@ -3103,7 +3136,7 @@
   }
 }
 %typemap(freearg) float value[ANY] {
-  if ($1) free($1);
+  free($1);
 }
 </pre>
 </div>
@@ -3224,7 +3257,7 @@
 useless and has since been eliminated.   To return structure members, simply use the "out" typemap.
 </p>
 
-<H3><a name="Typemaps_nn41">13.6.2 Implementing constraints with typemaps</a></H3>
+<H3><a name="Typemaps_nn41">14.6.2 Implementing constraints with typemaps</a></H3>
 
 
 <p>
@@ -3272,7 +3305,7 @@
 segmentation faults or other run-time problems by raising an exception
 rather than blindly passing values to the underlying C/C++ program.</p>
 
-<H2><a name="Typemaps_nn43">13.7 Typemaps for multiple target languages</a></H2>
+<H2><a name="Typemaps_nn43">14.7 Typemaps for multiple target languages</a></H2>
 
 
 <p>
@@ -3298,11 +3331,11 @@
 </p>
 
 <p>
-<b>Compatibility note: </b> In SWIG-1.1 different languages could be distinguished with the language name being put within the <tt>%typemap</tt> directive, for example, <br>
+<b>Compatibility note: </b> In SWIG-1.1 different languages could be distinguished with the language name being put within the <tt>%typemap</tt> directive, but this was deprecated in SWIG 1.3.28 and support finally dropped completely in SWIG 4.1.0 so you'll need to update any remaining uses to use the approach above.  For example, <br>
 <tt>%typemap(ruby, in) int "$1 = NUM2INT($input);"</tt>.
 </p>
 
-<H2><a name="Typemaps_optimal">13.8 Optimal code generation when returning by value</a></H2>
+<H2><a name="Typemaps_optimal">14.8 Optimal code generation when returning by value</a></H2>
 
 
 <p>
@@ -3326,7 +3359,7 @@
 <div class="code">
 <pre>
 %typemap(out) SWIGTYPE %{
-  $result = new $1_ltype((const $1_ltype &amp;)$1);
+  $result = new $1_ltype($1);
 %}
 
 %inline %{
@@ -3376,7 +3409,7 @@
 <div class="code">
 <pre>
 %typemap(out, optimal="1") SWIGTYPE %{
-  $result = new $1_ltype((const $1_ltype &amp;)$1);
+  $result = new $1_ltype($1);
 %}
 </pre>
 </div>
@@ -3403,7 +3436,7 @@
   void * jresult ;
   XX result;
   result = XX::create();
-  jresult = new XX((const XX &amp;)result);
+  jresult = new XX(result);
   return jresult;
 }
 
@@ -3418,7 +3451,7 @@
 <pre>
 SWIGEXPORT void * SWIGSTDCALL CSharp_XX_create() {
   void * jresult ;
-  jresult = new XX((const XX &amp;)XX::create());
+  jresult = new XX(XX::create());
   return jresult;
 }
 </pre>
@@ -3475,7 +3508,7 @@
 </p>
 
 <p>
-Secondly, if the typemaps uses <tt>$1</tt> more than once, then multiple calls to the wrapped function
+Secondly, if the typemap uses <tt>$1</tt> more than once, then multiple calls to the wrapped function
 will be made. Obviously that is not very optimal.
 In fact SWIG attempts to detect this and will issue a warning something like:
 </p>
@@ -3491,7 +3524,7 @@
 However, it doesn't always get it right, for example when <tt>$1</tt> is within some commented out code.
 </p>
 
-<H2><a name="Typemaps_multi_argument_typemaps">13.9 Multi-argument typemaps</a></H2>
+<H2><a name="Typemaps_multi_argument_typemaps">14.9 Multi-argument typemaps</a></H2>
 
 
 <p>
@@ -3556,7 +3589,7 @@
 }
 
 %typemap(freearg) (int argc, char *argv[]) {
-  if ($2) free($2);
+  free($2);
 }
 
 /* Required for C++ method overloading */
@@ -3768,7 +3801,7 @@
 the arguments to make them consecutive will need to be written.
 </p>
 
-<H2><a name="Typemaps_warnings">13.10 Typemap warnings</a></H2>
+<H2><a name="Typemaps_warnings">14.10 Typemap warnings</a></H2>
 
 
 <p>
@@ -3777,7 +3810,7 @@
 </p>
 
 
-<H2><a name="Typemaps_fragments">13.11 Typemap fragments</a></H2>
+<H2><a name="Typemaps_fragments">14.11 Typemap fragments</a></H2>
 
 
 <p>
@@ -3835,7 +3868,7 @@
 
 <p>
 When the "in" or "varin" typemaps for MyClass are required, the
-contents of the fragment called "AsMyClass" is added to the "header" section within the generated code, and then the
+contents of the fragment called "AsMyClass" are added to the "header" section within the generated code, and then the
 typemap code is emitted. Hence, the method <tt>AsMyClass</tt> will be
 generated into the wrapper code before any typemap code that calls it.
 </p>
@@ -3983,19 +4016,34 @@
 
 <li>
 <p>
-A typemap can also use more than one fragment, but since the
-syntax is different, you need to specify the dependent fragments in a comma separated
-list. Consider:
+A typemap can also use more than one fragment:
 </p>
-
 <div class="code">
 <pre>
-%typemap(in, fragment="frag1, frag2, frag3") {...}
+%typemap("in", fragment="frag1", fragment="frag2", fragment="frag3") {...}
 </pre>
 </div>
 
 <p>
-which is equivalent to:
+<b>Compatibility note: </b> The ability to use multiple
+<tt>fragment</tt> keys as shown above was introduced in SWIG-4.1.0.
+</p>
+
+<p>
+Multiple fragments can alternatively be specified as a comma
+separated list value in a single <tt>fragment</tt> key.
+Note that no whitespace is allowed within this comma separated list.
+The following is the equivalent to the above:
+</p>
+
+<div class="code">
+<pre>
+%typemap(in, fragment="frag1,frag2,frag3") {...}
+</pre>
+</div>
+
+<p>
+which in turn is functionally equivalent to:
 </p>
 
 <div class="code">
@@ -4113,7 +4161,7 @@
 with some powerful but tricky macro and fragment usage that is used in parts of the SWIG typemap library.
 </p>
 
-<H3><a name="Typemaps_fragment_type_specialization">13.11.1 Fragment type specialization</a></H3>
+<H3><a name="Typemaps_fragment_type_specialization">14.11.1 Fragment type specialization</a></H3>
 
 
 <p>
@@ -4146,7 +4194,7 @@
 </pre>
 </div>
 
-<H3><a name="Typemaps_automatic_specialization">13.11.2 Fragments and automatic typemap specialization</a></H3>
+<H3><a name="Typemaps_automatic_specialization">14.11.2 Fragments and automatic typemap specialization</a></H3>
 
 
 <p>
@@ -4192,7 +4240,7 @@
 </p>
 
 
-<H2><a name="Typemaps_runtime_type_checker">13.12 The run-time type checker</a></H2>
+<H2><a name="Typemaps_runtime_type_checker">14.12 The run-time type checker</a></H2>
 
 
 <p>
@@ -4218,7 +4266,7 @@
 <li>Modules can be unloaded from the type system.</li>
 </ul>
 
-<H3><a name="Typemaps_nn45">13.12.1 Implementation</a></H3>
+<H3><a name="Typemaps_nn45">14.12.1 Implementation</a></H3>
 
 
 <p>
@@ -4412,7 +4460,7 @@
 structures are chained together in a circularly linked list.
 </p>
 
-<H3><a name="Typemaps_runtime_type_checker_usage">13.12.2 Usage</a></H3>
+<H3><a name="Typemaps_runtime_type_checker_usage">14.12.2 Usage</a></H3>
 
 
 <p>This section covers how to use these functions from typemaps.  To learn how to
@@ -4508,7 +4556,7 @@
 managed.
 </p>
 
-<H2><a name="Typemaps_overloading">13.13 Typemaps and overloading</a></H2>
+<H2><a name="Typemaps_overloading">14.13 Typemaps and overloading</a></H2>
 
 
 <p>
@@ -4847,7 +4895,7 @@
 </li>
 </ul>
 
-<H3><a name="Typemaps_typecheck_pointer">13.13.1 SWIG_TYPECHECK_POINTER precedence level and the typecheck typemap</a></H3>
+<H3><a name="Typemaps_typecheck_pointer">14.13.1 SWIG_TYPECHECK_POINTER precedence level and the typecheck typemap</a></H3>
 
 
 <p>
@@ -4949,7 +4997,7 @@
 The 'equivalent' attribute is used in the implementation for the <a href="Library.html#Library_std_shared_ptr">shared_ptr smart pointer</a> library.
 </p>
 
-<H2><a name="Typemaps_nn48">13.14 More about %apply and %clear</a></H2>
+<H2><a name="Typemaps_nn48">14.14 More about %apply and %clear</a></H2>
 
 
 <p>
@@ -5054,7 +5102,7 @@
 </pre>
 </div>
 
-<H2><a name="Typemaps_nn47">13.15 Passing data between typemaps</a></H2>
+<H2><a name="Typemaps_nn47">14.15 Passing data between typemaps</a></H2>
 
 
 <p>
@@ -5091,7 +5139,7 @@
 </p>
 
 
-<H2><a name="Typemaps_nn52">13.16 C++ "this" pointer</a></H2>
+<H2><a name="Typemaps_nn52">14.16 C++ "this" pointer</a></H2>
 
 
 <p>
@@ -5151,7 +5199,7 @@
 the method, but gives the argument a name other than <tt>self</tt>.
 </p>
 
-<H2><a name="Typemaps_nn51">13.17 Where to go for more information?</a></H2>
+<H2><a name="Typemaps_nn51">14.17 Where to go for more information?</a></H2>
 
 
 <p>
diff --git a/Doc/Manual/Varargs.html b/Doc/Manual/Varargs.html
index 9f20469..b7dd4bc 100644
--- a/Doc/Manual/Varargs.html
+++ b/Doc/Manual/Varargs.html
@@ -7,7 +7,7 @@
 </head>
 
 <body bgcolor="#ffffff">
-<H1><a name="Varargs">16 Variable Length Arguments</a></H1>
+<H1><a name="Varargs">17 Variable Length Arguments</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -43,7 +43,7 @@
 wisely chosen to avoid this issue.
 </p>
 
-<H2><a name="Varargs_nn2">16.1 Introduction</a></H2>
+<H2><a name="Varargs_nn2">17.1 Introduction</a></H2>
 
 
 <p>
@@ -140,7 +140,7 @@
 </pre>
 </div>
 
-<H2><a name="Varargs_nn3">16.2 The Problem</a></H2>
+<H2><a name="Varargs_nn3">17.2 The Problem</a></H2>
 
 
 <p>
@@ -233,7 +233,7 @@
 are willing to get hands dirty.  Keep reading.
 </p>
 
-<H2><a name="Varargs_nn4">16.3 Default varargs support</a></H2>
+<H2><a name="Varargs_nn4">17.3 Default varargs support</a></H2>
 
 
 <p>
@@ -302,7 +302,7 @@
 </p>
 
 
-<H2><a name="Varargs_nn5">16.4 Argument replacement using %varargs</a></H2>
+<H2><a name="Varargs_nn5">17.4 Argument replacement using %varargs</a></H2>
 
 
 <p>
@@ -413,7 +413,7 @@
 wrappers to such functions presents special problems (covered shortly).  
 </p>
 
-<H2><a name="Varargs_nn6">16.5 Varargs and typemaps</a></H2>
+<H2><a name="Varargs_nn6">17.5 Varargs and typemaps</a></H2>
 
 
 <p>
@@ -512,7 +512,7 @@
 <pre>
 %typemap(in) (...)(char *vargs[10]) {
   int i;
-  int argc;
+  Py_ssize_t argc;
   for (i = 0; i &lt; 10; i++) vargs[i] = 0;
   argc = PyTuple_Size(varargs);
   if (argc &gt; 10) {
@@ -523,6 +523,7 @@
     PyObject *pyobj = PyTuple_GetItem(varargs, i);
     char *str = 0;
 %#if PY_VERSION_HEX&gt;=0x03000000
+    const char *strtmp = 0;
     PyObject *pystr;
     if (!PyUnicode_Check(pyobj)) {
       PyErr_SetString(PyExc_ValueError, "Expected a string");
@@ -532,7 +533,10 @@
     if (!pystr) {
       SWIG_fail;
     }
-    str = strdup(PyBytes_AsString(pystr));
+    strtmp = PyBytes_AsString(pystr);
+    str = (char *)malloc(strlen(strtmp) + 1);
+    if (str)
+      strcpy(str, strtmp);
     Py_DECREF(pystr);
 %#else  
     if (!PyString_Check(pyobj)) {
@@ -593,7 +597,7 @@
 security, continue to the next section.
 </p>
 
-<H2><a name="Varargs_nn7">16.6 Varargs wrapping with libffi</a></H2>
+<H2><a name="Varargs_nn7">17.6 Varargs wrapping with libffi</a></H2>
 
 
 <p>
@@ -609,7 +613,7 @@
 <p>
 One way to do this is to use a special purpose library such as libffi
 (<a
-href="http://www.sourceware.org/libffi/">http://www.sourceware.org/libffi/</a>).
+href="https://www.sourceware.org/libffi/">https://www.sourceware.org/libffi/</a>).
 libffi is a library that allows you to dynamically construct
 call-stacks and invoke procedures in a relatively platform independent
 manner.  Details about the library can be found in the libffi
@@ -845,7 +849,7 @@
 values.   Please consult the chapter on each language module for more details.
 </p>
 
-<H2><a name="Varargs_nn8">16.7 Wrapping of va_list</a></H2>
+<H2><a name="Varargs_nn8">17.7 Wrapping of va_list</a></H2>
 
 
 <p>
@@ -899,7 +903,7 @@
 </pre>
 </div>
 
-<H2><a name="Varargs_nn9">16.8 C++ Issues</a></H2>
+<H2><a name="Varargs_nn9">17.8 C++ Issues</a></H2>
 
 
 <p>
@@ -968,7 +972,7 @@
 fully general wrapper to a varargs C++ member function.
 </p>
 
-<H2><a name="Varargs_nn10">16.9 Discussion</a></H2>
+<H2><a name="Varargs_nn10">17.9 Discussion</a></H2>
 
 
 <p>
diff --git a/Doc/Manual/Warnings.html b/Doc/Manual/Warnings.html
index c63d7de..0e646e5 100644
--- a/Doc/Manual/Warnings.html
+++ b/Doc/Manual/Warnings.html
@@ -7,7 +7,7 @@
 </head>
 
 <body bgcolor="#ffffff">
-<H1><a name="Warnings">18 Warning Messages</a></H1>
+<H1><a name="Warnings">19 Warning Messages</a></H1>
 <!-- INDEX -->
 <div class="sectiontoc">
 <ul>
@@ -37,7 +37,7 @@
 
 
 
-<H2><a name="Warnings_nn2">18.1 Introduction</a></H2>
+<H2><a name="Warnings_nn2">19.1 Introduction</a></H2>
 
 
 <p>
@@ -57,7 +57,7 @@
 work like you expect.
 </p>
 
-<H2><a name="Warnings_suppression">18.2 Warning message suppression</a></H2>
+<H2><a name="Warnings_suppression">19.2 Warning message suppression</a></H2>
 
 
 <p>
@@ -149,7 +149,7 @@
 </p>
 
 
-<H2><a name="Warnings_nn4">18.3 Enabling extra warnings</a></H2>
+<H2><a name="Warnings_nn4">19.3 Enabling extra warnings</a></H2>
 
 
 <p>
@@ -165,6 +165,15 @@
 </div>
 
 <p>
+Preprocessor warning 202 ("Could not evaluate expression <em>expr</em>.") was
+formally off by default and enabled by <tt>-Wextra</tt>, but since SWIG 4.1.0
+this warning is on by default because suppressing it tends to hide genuine
+problems.  If you really don't want to see it, you can suppress it with
+<tt>-w202</tt> or using <tt>%warnfilter</tt> as described below. Both will work
+with older versions of SWIG too.
+</p>
+
+<p>
 To selectively turn on extra warning messages, you can use the directives and options in the
 previous section--simply add a "+" to all warning numbers.  For example:
 </p>
@@ -211,7 +220,7 @@
 </div>
 
 <p>
-The warnings on the right take precedence over the warnings on the left, so in the above example <tt>-Wextra</tt> adds numerous warnings including 452, but then <tt>-w309,452</tt> overrides this and so 452 is suppressesed.
+The warnings on the right take precedence over the warnings on the left, so in the above example <tt>-Wextra</tt> adds numerous warnings including 452, but then <tt>-w309,452</tt> overrides this and so 452 is suppressed.
 </p>
 
 <p>
@@ -222,7 +231,7 @@
 or the <tt>-w</tt> option.
 </p>
 
-<H2><a name="Warnings_nn5">18.4 Issuing a warning message</a></H2>
+<H2><a name="Warnings_nn5">19.4 Issuing a warning message</a></H2>
 
 
 <p>
@@ -276,7 +285,7 @@
 </pre>
 </div>
 
-<H2><a name="Warnings_symbolic_symbols">18.5 Symbolic symbols</a></H2>
+<H2><a name="Warnings_symbolic_symbols">19.5 Symbolic symbols</a></H2>
 
 
 <p>
@@ -311,7 +320,7 @@
 </pre>
 </div>
 
-<H2><a name="Warnings_nn6">18.6 Commentary</a></H2>
+<H2><a name="Warnings_nn6">19.6 Commentary</a></H2>
 
 
 <p>
@@ -328,7 +337,7 @@
 messages.
 </p>
 
-<H2><a name="Warnings_nn7">18.7 Warnings as errors</a></H2>
+<H2><a name="Warnings_nn7">19.7 Warnings as errors</a></H2>
 
 
 <p>
@@ -337,7 +346,7 @@
 warning is encountered.
 </p>
 
-<H2><a name="Warnings_nn8">18.8 Message output format</a></H2>
+<H2><a name="Warnings_nn8">19.8 Message output format</a></H2>
 
 
 <p>
@@ -356,38 +365,17 @@
 example.i(4) : Syntax error in input(1).
 </pre></div>
 
-<H2><a name="Warnings_nn9">18.9 Warning number reference</a></H2>
+<H2><a name="Warnings_nn9">19.9 Warning number reference</a></H2>
 
 
-<H3><a name="Warnings_nn10">18.9.1 Deprecated features (100-199)</a></H3>
+<H3><a name="Warnings_nn10">19.9.1 Deprecated features (100-199)</a></H3>
 
 
 <ul>
-<li>101. Deprecated <tt>%extern</tt> directive.
-<li>102. Deprecated <tt>%val</tt> directive.
-<li>103. Deprecated <tt>%out</tt> directive.
-<li>104. Deprecated <tt>%disabledoc</tt> directive.
-<li>105. Deprecated <tt>%enabledoc</tt> directive.
-<li>106. Deprecated <tt>%doconly</tt> directive.
-<li>107. Deprecated <tt>%style</tt> directive.
-<li>108. Deprecated <tt>%localstyle</tt> directive.
-<li>109. Deprecated <tt>%title</tt> directive.
-<li>110. Deprecated <tt>%section</tt> directive.
-<li>111. Deprecated <tt>%subsection</tt> directive.
-<li>112. Deprecated <tt>%subsubsection</tt> directive.
-<li>113. Deprecated <tt>%addmethods</tt> directive.
-<li>114. Deprecated <tt>%readonly</tt> directive.
-<li>115. Deprecated <tt>%readwrite</tt> directive.
-<li>116. Deprecated <tt>%except</tt> directive.
-<li>117. Deprecated <tt>%new</tt> directive.
-<li>118. Deprecated <tt>%typemap(except)</tt>.
-<li>119. Deprecated <tt>%typemap(ignore)</tt>.
-<li>120. Deprecated command line option (-runtime, -noruntime).
-<li>121. Deprecated <tt>%name</tt> directive.
 <li>126. The 'nestedworkaround' feature is deprecated.
 </ul>
 
-<H3><a name="Warnings_nn11">18.9.2 Preprocessor (200-299)</a></H3>
+<H3><a name="Warnings_nn11">19.9.2 Preprocessor (200-299)</a></H3>
 
 
 <ul>
@@ -399,35 +387,38 @@
 <li>206. Unexpected tokens after #<em>directive</em> directive.
 </ul>
 
-<H3><a name="Warnings_nn12">18.9.3 C/C++ Parser (300-399)</a></H3>
+<H3><a name="Warnings_nn12">19.9.3 C/C++ Parser (300-399)</a></H3>
 
 
 <ul>
 <li>301. <tt>class</tt> keyword used, but not in C++ mode.
-<li>302. Identifier '<em>name</em>' redefined (ignored).
+<li>302. Redefinition of identifier '<em>name</em>' as <em>decl</em> ignored.
 <li>303. <tt>%extend</tt> defined for an undeclared class '<em>name</em>'.
 <li>304. Unsupported constant value (ignored).
 <li>305. Bad constant value (ignored).
-<li>306. '<em>identifier</em>' is private in this context.
-<li>307. Can't set default argument value (ignored)
 <li>308. Namespace alias '<em>name</em>' not allowed here. Assuming '<em>name</em>'
 <li>309. [private | protected] inheritance ignored.
-<li>310. Template '<em>name</em>' was already wrapped as '<em>name</em>' (ignored)
 <li>312. Unnamed nested class not currently supported (ignored).
 <li>313. Unrecognized extern type "<em>name</em>" (ignored).
 <li>314. '<em>identifier</em>' is a <em>lang</em> keyword.
 <li>315. Nothing known about '<em>identifier</em>'.
-<li>316. Repeated %module directive.
 <li>317. Specialization of non-template '<em>name</em>'.
 <li>318. Instantiation of template '<em>name</em>' is ambiguous, instantiation <em>templ</em> used, instantiation <em>templ</em> ignored.
 <li>319. No access specifier given for base class <em>name</em> (ignored).
 <li>320. Explicit template instantiation ignored.
 <li>321. <em>identifier</em> conflicts with a built-in name.
-<li>322. Redundant redeclaration of '<em>name</em>'.
+<li>322. Redundant redeclaration of identifier '<em>name</em>' as <em>decl</em> ignored.
 <li>323. Recursive scope inheritance of '<em>name</em>'.
 <li>324. Named nested template instantiations not supported. Processing as if no name was given to %template().
 <li>325. Nested <em>kind</em> not currently supported (<em>name</em> ignored).
 <li>326. Deprecated %extend name used - the <em>kind</em> name '<em>name</em>' should be used instead of the typedef name '<em>name</em>'.
+<li>327. Extern template ignored.
+<li>328. Value assigned to <em>name</em> not used due to limited parsing implementation.
+<li>329. Using declaration '<em>name</em>' for inheriting constructors uses base '<em>name</em>' which is not an immediate base of '<em>name</em>'.
+<li>340. Lambda expressions and closures are not fully supported yet.
+<li>344. Unable to deduce decltype for '<em>expr</em>'.
+<li>345. Unable to deduce auto return type for '<em>name</em>' (ignored).
+<li>346. Unable to deduce auto type for variable '<em>name</em>' (ignored).
 <li>350. operator new ignored.
 <li>351. operator delete ignored.
 <li>352. operator+ ignored.
@@ -474,19 +465,25 @@
 <li>393. operator&amp; ignored (unary).
 <li>394. operator new[] ignored.
 <li>395. operator delete[] ignored.
+<li>396. operator*() ignored.
+<li>397. operator&lt;=&gt; delete[] ignored.
 </ul>
 
-<H3><a name="Warnings_nn13">18.9.4 Types and typemaps (400-499) </a></H3>
+<H3><a name="Warnings_nn13">19.9.4 Types and typemaps (400-499) </a></H3>
 
 
 <ul>
 <li>401. Nothing known about class 'name'. Ignored.
 <li>402. Base class 'name' is incomplete.
 <li>403. Class 'name' might be abstract.
-<li>450. Deprecated typemap feature ($source/$target).
+<li>404. Duplicate template instantiation of '<em>type</em>' with name '<em>name</em>' ignored, previous instantiation of '<em>type</em>' with name '<em>name</em>'.
+<li>405. Method with rvalue ref-qualifier <em>name</em> ignored.
+<li>450. Reserved
 <li>451. Setting const char * variable may leak memory.
 <li>452. Reserved
 <li>453. Can't apply (pattern). No typemaps are defined.
+<li>454. Setting a pointer/reference variable may leak memory
+<li>455. Setting a const wchar_t * variable may leak memory.
 <li>460. Unable to use type <em>type</em> as a function argument.
 <li>461. Unable to use return type <em>type</em> in function <em>name</em>.
 <li>462. Unable to set variable of type <em>type</em>.
@@ -499,15 +496,18 @@
 <li>469. No or improper directorin typemap defined for <em>type</em>
 <li>470. Thread/reentrant unsafe wrapping, consider returning by value instead.
 <li>471. Unable to use return type <em>type</em> in director method
+<li>472. Overloaded method <em>method</em> with no explicit typecheck typemap for arg <em>number</em> of type '<em>type</em>'
+<li>473. Returning a reference, pointer or pointer wrapper in a director method is not recommended.
 <li>474. Method <em>method</em> usage of the optimal attribute ignored in the out typemap as the following cannot be used to generate optimal code: <em>code</em>
 <li>475. Multiple calls to <em>method</em> might be generated due to optimal attribute usage in the out typemap.
 <li>476. Initialization using std::initializer_list.
 <li>477. No directorthrows typemap defined for <em>type</em>
+<li>490. Fragment '<em>name</em>' not found.
 </ul>
 
 
 
-<H3><a name="Warnings_nn14">18.9.5 Code generation (500-559)</a></H3>
+<H3><a name="Warnings_nn14">19.9.5 Code generation (500-559)</a></H3>
 
 
 <ul>
@@ -536,9 +536,10 @@
 <li>523. Use of an illegal destructor name '<em>name</em>' in %extend is deprecated, the destructor name should be '<em>name</em>'.
 <li>524. Experimental target language. Target language <em>language</em> specified by <em>lang</em> is an experimental language. Please read about SWIG experimental languages, <em>htmllink</em>.
 <li>525. Destructor <em>declaration</em> is final, <em>name</em> cannot be a director class.
+<li>526. Using declaration <em>declaration</em>, with name '<em>name</em>', is not actually using the method from <em>declaration</em>, with name '<em>name</em>', as the names are different.
 </ul>
 
-<H3><a name="Warnings_doxygen">18.9.6 Doxygen comments (560-599)</a></H3>
+<H3><a name="Warnings_doxygen">19.9.6 Doxygen comments (560-599)</a></H3>
 
 
 <ul>
@@ -549,7 +550,7 @@
   <li>564: Error parsing Doxygen command <em>command</em>: <em>error text</em>. Command ignored."</li>
 </ul>
 
-<H3><a name="Warnings_nn15">18.9.7 Language module specific (700-899) </a></H3>
+<H3><a name="Warnings_nn15">19.9.7 Language module specific (700-899) </a></H3>
 
 
 <ul>
@@ -600,14 +601,14 @@
 <li>871. Unrecognized pragma <em>pragma</em>.   (Php).
 </ul>
 
-<H3><a name="Warnings_nn16">18.9.8 User defined (900-999)</a></H3>
+<H3><a name="Warnings_nn16">19.9.8 User defined (900-999)</a></H3>
 
 
 <p>
 These numbers can be used by your own application.
 </p>
 
-<H2><a name="Warnings_nn17">18.10 History</a></H2>
+<H2><a name="Warnings_nn17">19.10 History</a></H2>
 
 
 <p>
diff --git a/Doc/Manual/Windows.html b/Doc/Manual/Windows.html
index 800e2e4..88bfd95 100644
--- a/Doc/Manual/Windows.html
+++ b/Doc/Manual/Windows.html
@@ -29,16 +29,16 @@
 </ul>
 <li><a href="#Windows_other_compilers">Instructions for using the Examples with other compilers</a>
 </ul>
-<li><a href="#Windows_cygwin_mingw">SWIG on Cygwin and MinGW</a>
-<ul>
 <li><a href="#Windows_swig_exe">Building swig.exe on Windows</a>
 <ul>
+<li><a href="#Windows_cmake">Building swig.exe using CMake</a>
+<li><a href="#Windows_msys2">Building swig.exe using MSYS2</a>
 <li><a href="#Windows_mingw_msys">Building swig.exe using MinGW and MSYS</a>
 <li><a href="#Windows_cygwin">Building swig.exe using Cygwin</a>
-<li><a href="#Windows_building_alternatives">Building swig.exe alternatives</a>
-</ul>
+<ul>
 <li><a href="#Windows_examples_cygwin">Running the examples on Windows using Cygwin</a>
 </ul>
+</ul>
 <li><a href="#Windows_interface_file">Microsoft extensions and other Windows quirks</a>
 </ul>
 </div>
@@ -60,7 +60,7 @@
 SWIG does not come with the usual Windows type installation program, however it is quite easy to get started. The main steps are:
 </p>
 <ul>
-        <li>Download the swigwin zip package from the <a href="http://www.swig.org">SWIG website</a> and unzip into a directory. This is all that needs downloading for the Windows platform.
+        <li>Download the swigwin zip package from the <a href="https://www.swig.org">SWIG website</a> and unzip into a directory. This is all that needs downloading for the Windows platform.
         <li>Set environment variables as described in the <a href="#Windows_examples">SWIG Windows Examples</a> section in order to run examples using Visual C++.
 </ul>
 
@@ -77,10 +77,10 @@
 
 
 <p>
-Using Microsoft Visual C++ is the most common approach to compiling and linking SWIG's output. 
+Microsoft Visual C++ is the most commonly used compiler for compiling and linking SWIG's output on Windows.
 The Examples directory has a few Visual C++ project files (.dsp files). 
 These were produced by Visual C++ 6.
-Newer versions of Visual Studio should be able to open and convert these project files.
+Newer versions of Visual Studio are able to open and convert these project files.
 Each C# example comes with a Visual Studio 2005 solution and associated project files instead of Visual C++ 6 project files.
 The project files have been set up to execute SWIG in a custom build rule for the SWIG interface (.i) file. 
 Alternatively run the <a href="#Windows_examples_cygwin">examples using Cygwin</a>.
@@ -95,9 +95,11 @@
 Ensure the SWIG executable is as supplied in the SWIG root directory in order for the examples to work. 
 Most languages require some environment variables to be set <b>before</b> running Visual C++. 
 Note that Visual C++ must be re-started to pick up any changes in environment variables. 
-Open up an example .dsp file, Visual C++ will create a workspace for you (.dsw file). 
-Ensure the Release build is selected then do a Rebuild All from the Build menu.
-The required environment variables are displayed with their current values.
+Open up an example .dsp file, Visual C++ will prompt you to upgrade the project and convert
+it into an MSBuild project (.vcxproj file) and Solution (.sln file).
+Note that older versions of Visual C++ will simply create a workspace for you (.dsw file).
+Ensure the Release build is selected then do a Rebuild Solution from the Build menu.
+The required environment variables are displayed with their current values during the build.
 </p>
 <p>
 The list of required environment variables for each module language is also listed below.
@@ -111,7 +113,7 @@
 
 <p>
 The C# examples do not require any environment variables to be set as a C# project file is included.
-Just open up the .sln solution file in Visual Studio .NET 2003 or later, select Release Build, and do a Rebuild All from the Build menu.
+Just open up the .sln solution file in Visual Studio 2005 or later, select Release Build, and do a Rebuild Solution from the Build menu.
 The accompanying C# and C++ project files are automatically used by the solution file.
 </p>
 
@@ -207,38 +209,171 @@
 If you do not have access to Visual C++ you will have to set up project files / Makefiles for your chosen compiler. There is a section in each of the language modules detailing what needs setting up using Visual C++ which may be of some guidance. Alternatively you may want to use Cygwin as described in the following section.
 </p>
 
-<H2><a name="Windows_cygwin_mingw">3.3 SWIG on Cygwin and MinGW</a></H2>
+<H2><a name="Windows_swig_exe">3.3 Building swig.exe on Windows</a></H2>
 
 
 <p>
-SWIG can also be compiled and run using <a href="http://www.cygwin.com">Cygwin</a> or <a href="http://www.mingw.org">MinGW</a> which provides a Unix like front end to Windows and comes free with gcc, an ISO C/C++ compiler. However, this is not a recommended approach as the prebuilt executable is supplied. 
+The SWIG distribution provides a pre-built swig.exe and so it is not necessary for users to build the SWIG executable.
+However, this section is provided for those that want to modify the SWIG source code in a Windows environment. 
+Normally this is not needed, so most people will want to ignore this section.
 </p>
 
-<H3><a name="Windows_swig_exe">3.3.1 Building swig.exe on Windows</a></H3>
+<p>
+There are various ways to build the SWIG executable including <a href="https://cmake.org/">CMake</a> which is able to generate project files for building with Visual Studio.
+SWIG can also be compiled and run using <a href="https://www.msys2.org/">MSYS2</a>, <a href="https://www.cygwin.com">Cygwin</a> or <a href="https://osdn.net/projects/mingw/">MinGW</a>, all of which provide a Unix like front end to Windows and comes free with the gcc C/C++ compiler.
+</p>
+
+
+<H3><a name="Windows_cmake">3.3.1 Building swig.exe using CMake</a></H3>
 
 
 <p>
-If you want to replicate the build of swig.exe that comes with the download, follow the MinGW instructions below.
-This is not necessary to use the supplied swig.exe. 
-This information is provided for those that want to modify the SWIG source code in a Windows environment. 
-Normally this is not needed, so most people will want to ignore this section. 
+SWIG can be built using <a href="https://cmake.org/">CMake</a> and Visual Studio rather than autotools. As with the other approaches to 
+building SWIG the dependencies need to be installed. The steps below are one of a number of ways of installing the dependencies without requiring Cygwin or MinGW.
+For fully working build steps always check the Continuous Integration (CI) setups currently detailed in the <a href="https://github.com/swig/swig/tree/master/.github/workflows/nuget.yml">GitHub Actions YAML file</a>.
 </p>
 
-<H4><a name="Windows_mingw_msys">3.3.1.1 Building swig.exe using MinGW and MSYS</a></H4>
+<ol>
+    <li>
+        Install Nuget from <a href="https://www.nuget.org/downloads">https://www.nuget.org/downloads</a> (v6.0.0 is used in this example, and installed to <tt>C:\Tools</tt>). Nuget is the package manager
+        for .NET, but allows us to easily install <a href="https://cmake.org/">CMake</a> and other dependencies required by SWIG.
+    </li>
+    <li>
+        Install <a href="https://www.nuget.org/packages/CMake-win64/">CMake-win64 Nuget package</a> using the following command: <pre>C:\Tools\nuget install CMake-win64 -Version 3.15.5 -OutputDirectory C:\Tools\CMake</pre>
+        Using PowerShell the equivalent syntax is: <pre>&amp; "C:\Tools\nuget" install CMake-win64 -Version 3.15.5 -OutputDirectory C:\Tools\CMake</pre>
+        Alternatively you can download CMake from <a href="https://cmake.org/download/">https://cmake.org/download/</a>.
+    </li>
+    <li>
+        Install the <a href="https://www.nuget.org/packages/bison/">Bison Nuget package</a> using the following command: <pre>C:\Tools\nuget install Bison -Version 3.7.4 -OutputDirectory C:\Tools\bison</pre>
+        Alternatively download Bison from <a href="https://sourceforge.net/projects/winflexbison/files/">https://sourceforge.net/projects/winflexbison/files/</a> (Bison 3.7.4 is used in this example)
+        and save to a folder e.g. <tt>C:\Tools\Bison</tt>
+    </li>
+    <li>
+        Install the <a href="https://www.nuget.org/packages/pcre2/">PCRE2 Nuget package</a> using the following command: <pre>C:\Tools\nuget install PCRE2 -Version 10.39 -OutputDirectory C:\Tools\pcre2</pre>
+        Note this is a x64 build, if this is not suitable PCRE2 can be built from source using <a href="https://github.com/PhilipHazel/pcre2/">https://github.com/PhilipHazel/pcre2/</a>.
+        Alternatively, set <tt>WITH_PCRE=OFF</tt> to disable PCRE2 support if you are sure you do not require it. 
+    </li>
+    <li>
+        We will also need the SWIG source code. Either download a zipped archive from GitHub, or if git is installed clone the latest codebase
+        using: <pre>git clone https://github.com/swig/swig.git</pre>
+        In this example we are assuming the source code is available at <tt>C:\swig</tt>
+    </li>
+    <li>
+    <p>
+        Now we have all the required dependencies we can build SWIG using PowerShell and the commands below. We are assuming Visual Studio 2019 is installed. For other versions of Visual Studio change <tt>"Visual Studio 16 2019 -A x64"</tt> to the relevant
+        <a href="https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html#visual-studio-generators">Visual Studio Generator</a> and
+        architecture. We add the required build tools to the system PATH, and then
+        build a Release version of SWIG. If all runs successfully a new swig.exe should be generated in the <tt>C:/swig/install2/bin</tt> folder.
+    </p>
+    </li>
+</ol>
+<div class="shell"><pre>
+cd C:\swig
 
+$env:PATH="C:\Tools\CMake\CMake-win64.3.15.5\bin;C:\Tools\bison\Bison.3.7.4\bin;" + $env:PATH
+$PCRE_ROOT="C:\Tools\pcre2\PCRE2.10.39.0"
+$PCRE_PLATFORM="x64"
+
+cmake -G "Visual Studio 16 2019" -A "x64" `
+-DCMAKE_INSTALL_PREFIX="C:/swig/install2" `
+-DCMAKE_C_FLAGS="/DPCRE2_STATIC" `
+-DCMAKE_CXX_FLAGS="/DPCRE2_STATIC" `
+-DPCRE2_INCLUDE_DIR="$PCRE_ROOT/include" `
+-DPCRE2_LIBRARY="$PCRE_ROOT/lib/pcre2-8-static.lib" `
+-S . -B build
+
+cmake --build build --config Release
+cmake --install build --config Release
+
+# to test the exe built correctly
+cd install2/bin
+./swig.exe -version
+./swig.exe -help
+</pre></div>
+
+<p>
+    In addition to Release builds you can create a Debug build using:
+</p>
+<div class="shell">
+    <pre>cmake --build build --config Debug</pre>
+</div>
+<p>
+    A Visual Studio solution file should be generated named swig.sln. This can be opened and debugged by running the swig project and setting <tt>Properties &gt; Debugging &gt; Command Arguments</tt>. For example to debug one of the test-suite .i files included with the SWIG source use the following:
+</p>
+<div class="shell">
+    <pre>-python -c++ -o C:\Temp\doxygen_parsing.cpp C:\swig\Examples\test-suite\doxygen_parsing.i</pre>
+</div>
+
+<H3><a name="Windows_msys2">3.3.2 Building swig.exe using MSYS2</a></H3>
+
+
+<p>
+Download and install MSYS2 from <a href="https://www.msys2.org/">www.msys2.org</a> (tested with version msys2-x86_64-20201109).
+Launch the MSYS2 shell.
+</p>
+<p>
+Install the packages needed to build swig:<br>
+</p>
+
+<div class="shell">
+<pre>
+pacman -S git autoconf automake bison gcc make pcre2-devel
+</pre>
+</div>
+
+<p>
+Clone the repository to /usr/src/:
+</p>
+
+<div class="shell">
+<pre>
+mkdir /usr/src/
+cd /usr/src/
+git clone https://github.com/swig/swig.git
+</pre>
+</div>
+
+<p>
+Configure and build:
+</p>
+
+<div class="shell">
+<pre>
+cd /usr/src/swig
+./autogen.sh
+./configure
+make
+</pre>
+</div>
+
+<p>
+Finally you may also want to install SWIG:
+</p>
+
+<div class="shell">
+<pre>
+make install
+</pre>
+</div>
+
+<H3><a name="Windows_mingw_msys">3.3.3 Building swig.exe using MinGW and MSYS</a></H3>
+
+
+<p>Warning: These instructions were added in 2006 and have barely changed since
+so are unlikely to work exactly as written.</p>
 
 <p>
 The short abbreviated instructions follow...
 </p>
 
 <ul>
-    <li>Install MinGW and MSYS from the <a href="http://www.mingw.org">MinGW</a> site. This provides a Unix environment on Windows.
+    <li>Install MinGW and MSYS from the <a href="https://osdn.net/projects/mingw/">MinGW</a> site. This provides a Unix environment on Windows.
     <li>Follow the usual Unix instructions in the README file in the SWIG root directory to build swig.exe from the MinGW command prompt.
 </ul>
 
 <p>
 The step by step instructions to download and install MinGW and MSYS, then download and build the latest version of SWIG from Github follow...
-Note that the instructions for obtaining SWIG from Github are also online at <a href="http://www.swig.org/svn.html">SWIG Bleeding Edge</a>.
+Note that the instructions for obtaining SWIG from Github are also online at <a href="https://www.swig.org/svn.html">SWIG Bleeding Edge</a>.
 </p>
 
 <p>
@@ -248,8 +383,7 @@
 
 <ol>
   <li>
-  Download the following packages from the <a href="http://www.mingw.org/download.shtml">MinGW download page</a>
-  or <a href="https://sourceforge.net/projects/mingw/files/">MinGW SourceForge download page</a>.
+  Download the following packages from the <a href="https://osdn.net/projects/mingw/releases/">MinGW download page</a>.
   Note that at the time of writing, the majority of these are in the Current
   release list and some are in the Snapshot or Previous release list.
   <ul>
@@ -319,10 +453,10 @@
   </li>
 
   <li>
-The PCRE third party library needs to be built next. 
-Download the latest PCRE source tarball, such as <tt>pcre-8.10.tar.bz2</tt>, from 
-<a href=http://www.pcre.org>PCRE</a> and place in the <tt>/usr/src/swig</tt> directory.
-Build PCRE as a static library using the Tools/pcre-build.sh script as follows:
+The PCRE2 third party library needs to be built next.
+Download the latest PCRE2 source tarball, such as <tt>pcre2-10.39.tar.bz2</tt>, from
+<a href=https://www.pcre.org>www.pcre.org</a> and place in the <tt>/usr/src/swig</tt> directory.
+Build PCRE2 as a static library using the Tools/pcre-build.sh script as follows:
 
 <div class="shell"><pre>
 cd /usr/src/swig
@@ -342,7 +476,7 @@
 </ol>
 
 
-<H4><a name="Windows_cygwin">3.3.1.2 Building swig.exe using Cygwin</a></H4>
+<H3><a name="Windows_cygwin">3.3.4 Building swig.exe using Cygwin</a></H3>
 
 
 <p>
@@ -353,17 +487,8 @@
 These files are generated using the <tt>autogen.sh</tt> script and will only need regenerating in circumstances such as changing the build system.
 </p>
 
-<H4><a name="Windows_building_alternatives">3.3.1.3 Building swig.exe alternatives</a></H4>
 
-
-<p>
-If you don't want to install Cygwin or MinGW, use a different compiler to build 
-SWIG. For example, all the source code files can be added to a Visual C++ project 
-file in order to build swig.exe from the Visual C++ IDE.
-</p>
-
-
-<H3><a name="Windows_examples_cygwin">3.3.2 Running the examples on Windows using Cygwin</a></H3>
+<H4><a name="Windows_examples_cygwin">3.3.4.1 Running the examples on Windows using Cygwin</a></H4>
 
 
 <p>
diff --git a/Doc/Manual/chapters b/Doc/Manual/chapters
index 2cb2b18..994b288 100644
--- a/Doc/Manual/chapters
+++ b/Doc/Manual/chapters
@@ -7,6 +7,7 @@
 CPlusPlus11.html
 CPlusPlus14.html
 CPlusPlus17.html
+CPlusPlus20.html
 Preprocessor.html
 Library.html
 Arguments.html
diff --git a/Doc/Manual/index.html b/Doc/Manual/index.html
index e720e70..f17d4f1 100644
--- a/Doc/Manual/index.html
+++ b/Doc/Manual/index.html
@@ -1,11 +1,11 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <html>
 <head>
-<title>SWIG-4.0 Documentation</title>
+<title>SWIG Documentation</title>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
 </head>
 <body bgcolor="#ffffff">
-<H1><a name="index">SWIG-4.0 Documentation</a></H1>
+<H1><a name="index">SWIG Documentation</a></H1>
 
 The SWIG documentation is available in one of the following formats.
 <ul>
diff --git a/Doc/Manual/makechap.py b/Doc/Manual/makechap.py
index e30d14e..9c43f6a 100644
--- a/Doc/Manual/makechap.py
+++ b/Doc/Manual/makechap.py
@@ -11,10 +11,8 @@
 # then change the heading link name to something that does not look like an
 # autogenerated link name.
 ###############################################################################
-
 import sys
 import re
-import string
 
 ###############################################################################
 # Functions
@@ -58,11 +56,11 @@
 ###############################################################################
 
 if len(sys.argv) != 3:
-    print "usage: makechap.py filename num"
+    print("usage: makechap.py filename num")
     sys.exit(1)
 
 filename = sys.argv[1]
-filenamebase = string.split(filename,".")[0]
+filenamebase = filename.split(".")[0]
 num      = int(sys.argv[2])
 
 section = 0
@@ -223,6 +221,6 @@
 # Print the TOC data to stdout correcting the anchor links for external referencing
 
 index = index.replace("<li><a href=\"#","<li><a href=\"%s#" % filename)
-print """<h3><a href="%s#%s">%d %s</a></h3>\n""" % (filename,filenamebase,num,name)
-print index
+print("""<h3><a href="%s#%s">%d %s</a></h3>\n""" % (filename,filenamebase,num,name))
+print(index)
 
diff --git a/Doc/Manual/maketoc.py b/Doc/Manual/maketoc.py
index dc86264..8322e37 100644
--- a/Doc/Manual/maketoc.py
+++ b/Doc/Manual/maketoc.py
@@ -5,7 +5,7 @@
 chs = open("chapters").readlines()
 
 f = open("Contents.html","w")
-print >>f, """
+f.write("""
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <HTML>
 <HEAD>
@@ -17,7 +17,8 @@
 <H1><a name="Contents"></a>SWIG Users Manual</H1>
 
 <p>
-"""
+
+""")
 
 f.close()
 
@@ -25,15 +26,16 @@
 
 for c in chs:
     c = c.strip()
-    print "Processing %s" % c
+    print("Processing " + c)
     if c:
         os.system("python makechap.py %s %d >> Contents.html" % (c,num))
     num += 1
-    
+
 f = open("Contents.html","a")
-print >>f, """
+f.write("""
 </BODY>
 </HTML>
-"""
+
+""")
 
 
diff --git a/Doc/Manual/style.css b/Doc/Manual/style.css
index 45e51e3..ffadb87 100644
--- a/Doc/Manual/style.css
+++ b/Doc/Manual/style.css
@@ -65,6 +65,10 @@
   font-family: "Courier New", Courier, "Courier 10 Pitch", monospace;
 }
 
+div.diagram li {
+    margin-left: 0;
+}
+
 ul li p {
   margin-left: 0;
   margin-right: 0;
diff --git a/Examples/Makefile.in b/Examples/Makefile.in
index 6fbca29..887f6b9 100644
--- a/Examples/Makefile.in
+++ b/Examples/Makefile.in
@@ -46,8 +46,8 @@
 CC         = @CC@
 CXX        = @CXX@
 CPPFLAGS   = $(SRCDIR_INCLUDE)
-CFLAGS     = @PLATCFLAGS@
-CXXFLAGS   = @BOOST_CPPFLAGS@ @PLATCXXFLAGS@
+CFLAGS     = @PLATCFLAGS@ $(EXTRA_CFLAGS)
+CXXFLAGS   = @BOOST_CPPFLAGS@ @PLATCXXFLAGS@ $(EXTRA_CXXFLAGS)
 LDFLAGS    =
 prefix     = @prefix@
 exec_prefix= @exec_prefix@
@@ -58,6 +58,7 @@
 INTERFACEDIR  =
 INTERFACEPATH = $(SRCDIR)$(INTERFACEDIR)$(INTERFACE)
 SWIGOPT    =
+PCHSUPPORT = @PCHSUPPORT@
 
 # SWIG_LIB_DIR and SWIGEXE must be explicitly set by Makefiles using this Makefile
 SWIG_LIB_DIR = ./Lib
@@ -136,7 +137,6 @@
 
 distclean:
 	rm -f Makefile
-	rm -f d/example.mk
 	rm -f xml/Makefile
 
 ##################################################################
@@ -147,340 +147,364 @@
 	$(SWIG) $(SWIGOPT)
 
 ##################################################################
-#####                       Tcl/Tk                          ######
+#####                       ANDROID                         ######
 ##################################################################
 
-# Set these to your local copy of Tcl/Tk.
+ANDROID = @ANDROID@
+ANDROID_NDK_BUILD = @NDKBUILD@
+ANDROID_ADB = @ADB@
+ANT = @ANT@
+TARGETID = 1
 
-TCLSH       = tclsh
-TCL_INCLUDE = @TCLINCLUDE@
-TCL_LIB     = @TCLLIB@
-TCL_OPTS    = @LIBS@
-TK_OPTS     = -ltk -ltcl @LIBS@
+# ----------------------------------------------------------------
+# Build an Android dynamically loadable module (C)
+# ----------------------------------------------------------------
 
-# Extra Tcl specific dynamic linking options
-TCL_DLNK   = @TCLDYNAMICLINKING@
-TCL_SO     = @TCL_SO@
-TCLLDSHARED = @TCLLDSHARED@
-TCLCXXSHARED = @TCLCXXSHARED@
-TCL_SCRIPT = $(SRCDIR)$(RUNME).tcl
+android: $(SRCDIR_SRCS)
+	$(ANDROID) $(SILENT_OPTION) update project --target $(TARGETID) --name $(PROJECTNAME) --path .
+	$(SWIG) -java $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.c $(INTERFACEPATH)
+	+$(ANDROID_NDK_BUILD) $(SILENT_PIPE)
+	$(ANT) $(ANT_QUIET) debug
 
-# -----------------------------------------------------------
-# Build a new version of the tclsh shell
-# -----------------------------------------------------------
+# ----------------------------------------------------------------
+# Build an Android dynamically loadable module (C++)
+# ----------------------------------------------------------------
 
-tclsh: $(SRCDIR_SRCS)
-	$(SWIG) -tcl8 $(SWIGOPT) $(TCL_SWIGOPTS) -ltclsh.i -o $(ISRCS) $(INTERFACEPATH)
-	$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(TCL_INCLUDE) \
-	$(TCL_LIB)  $(TCL_OPTS) $(LIBS) $(SYSLIBS) -o $(TARGET)
+android_cpp: $(SRCDIR_SRCS)
+	$(ANDROID) $(SILENT_OPTION) update project --target $(TARGETID) --name $(PROJECTNAME) --path .
+	$(SWIG) -java -c++ $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.cpp $(INTERFACEPATH)
+	+$(ANDROID_NDK_BUILD) $(SILENT_PIPE)
+	$(ANT) $(ANT_QUIET) debug
 
-tclsh_cpp: $(SRCDIR_SRCS)
-	$(SWIG) -tcl8 -c++ $(SWIGOPT) $(TCL_SWIGOPTS) -ltclsh.i -o $(ICXXSRCS) $(INTERFACEPATH)
-	$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(TCL_INCLUDE) \
-	$(TCL_LIB) $(TCL_OPTS) $(LIBS) $(SYSLIBS) -o $(TARGET)
+# ----------------------------------------------------------------
+# Android install
+# ----------------------------------------------------------------
 
-# -----------------------------------------------------------
-# Build a Tcl dynamic loadable module (you might need to tweak this)
-# -----------------------------------------------------------
-
-tcl:  $(SRCDIR_SRCS)
-	$(SWIG) -tcl8 $(SWIGOPT) $(TCL_SWIGOPTS) -o $(ISRCS) $(INTERFACEPATH)
-	$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(TCL_INCLUDE)
-	$(TCLLDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(TCL_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(TCL_SO)
-
-# -----------------------------------------------------------
-# Build a Tcl7.5 dynamic loadable module for C++
-# -----------------------------------------------------------
-
-tcl_cpp: $(SRCDIR_SRCS)
-	$(SWIG) -tcl8 -c++ $(SWIGOPT) $(TCL_SWIGOPTS) -o $(ICXXSRCS) $(INTERFACEPATH)
-	$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(TCL_INCLUDE)
-	$(TCLCXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(TCL_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(TCL_SO)
-
-# -----------------------------------------------------------------
-# Run Tcl example
-# -----------------------------------------------------------------
-
-tcl_run:
-	$(RUNTOOL) $(TCLSH) $(TCL_SCRIPT) $(RUNPIPE)
+android_install:
+	-$(ANDROID_ADB) uninstall $(PACKAGENAME)
+	$(ANDROID_ADB) install $(INSTALLOPTIONS) bin/$(PROJECTNAME)-debug.apk
 
 # -----------------------------------------------------------------
 # Version display
 # -----------------------------------------------------------------
 
-tcl_version:
-	echo 'puts $$tcl_version;exit 0' | $(TCLSH)
+android_version:
+	$(ANDROID_ADB) version
 
 # -----------------------------------------------------------------
-# Cleaning the Tcl examples
+# Cleaning the Android examples
 # -----------------------------------------------------------------
 
-tcl_clean:
-	rm -f *_wrap* *~ .~* mytclsh@EXEEXT@
+android_clean:
+	test -n "$(SRCDIR)" && cd $(SRCDIR) ; $(ANT) -q -logfile /dev/null clean
+	rm -f $(INTERFACEDIR)$(TARGET)_wrap.*
+	rm -f `find $(PACKAGEDIR) -name \*.java | grep -v $(PROJECTNAME).java`
+	rm -rf obj
+
+##################################################################
+#####                       CSHARP                          ######
+##################################################################
+
+# Extra CSharp specific dynamic linking options
+CSHARP_DLNK  = @CSHARPDYNAMICLINKING@
+CSHARP_LIBPREFIX = @CSHARPLIBRARYPREFIX@
+CSHARPCOMPILER = @CSHARPCOMPILER@
+CSHARPCILINTERPRETER = @CSHARPCILINTERPRETER@
+CSHARPCILINTERPRETER_FLAGS = @CSHARPCILINTERPRETER_FLAGS@
+CSHARPCFLAGS = @CSHARPCFLAGS@
+CSHARPFLAGS =
+CSHARPOPTIONS =
+CSHARPSO = @CSHARPSO@
+CSHARP_RUNME = ./$(RUNME).exe
+
+# ----------------------------------------------------------------
+# Build a CSharp dynamically loadable module (C)
+# ----------------------------------------------------------------
+
+csharp: $(SRCDIR_SRCS)
+	$(SWIG) -csharp $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+	$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(CSHARPCFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES)
+	$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(CSHARP_DLNK) $(LIBS) -o $(CSHARP_LIBPREFIX)$(TARGET)$(CSHARPSO)
+
+# ----------------------------------------------------------------
+# Build a CSharp dynamically loadable module (C++)
+# ----------------------------------------------------------------
+
+csharp_cpp: $(SRCDIR_SRCS)
+	$(SWIG) -csharp -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+	$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(CSHARPCFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES)
+	$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(CSHARP_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(CSHARP_LIBPREFIX)$(TARGET)$(CSHARPSO)
+
+# ----------------------------------------------------------------
+# Compile CSharp files
+# ----------------------------------------------------------------
+
+ifneq (,$(SRCDIR))
+SRCDIR_CSHARPSRCS = $(addprefix $(SRCDIR),$(CSHARPSRCS))
+else
+SRCDIR_CSHARPSRCS =
+endif
+
+csharp_compile: $(SRCDIR_SRCS)
+	$(COMPILETOOL) $(CSHARPCOMPILER) $(CSHARPFLAGS) $(CSHARPOPTIONS) $(CSHARPSRCS) $(SRCDIR_CSHARPSRCS)
+
+# -----------------------------------------------------------------
+# Run CSharp example
+# -----------------------------------------------------------------
+
+csharp_run:
+	env LD_LIBRARY_PATH=$$PWD $(RUNTOOL) $(CSHARPCILINTERPRETER) $(CSHARPCILINTERPRETER_FLAGS) $(CSHARP_RUNME) $(RUNPIPE)
+
+# -----------------------------------------------------------------
+# Version display
+# -----------------------------------------------------------------
+
+# Version check below also works with MS csc.exe which does not understand --version
+csharp_version:
+	$(CSHARPCOMPILER) --version | head -n 1
+	if test -n "$(CSHARPCILINTERPRETER)" ; then "$(CSHARPCILINTERPRETER)" --version ; fi
+
+# -----------------------------------------------------------------
+# Cleaning the CSharp examples
+# -----------------------------------------------------------------
+
+csharp_clean:
+	rm -f *_wrap* *~ .~* $(RUNME) $(RUNME).exe *.exe.mdb gc.log `find . -name \*.cs | grep -v $(RUNME).cs`
 	rm -f core @EXTRA_CLEAN@
-	rm -f *.@OBJEXT@ *$(TCL_SO)
+	rm -f *.@OBJEXT@ *@CSHARPSO@
 
 ##################################################################
-#####                       PERL 5                          ######
+#####                       D                               ######
 ##################################################################
 
-# You need to set this variable to the Perl5 directory containing the
-# files "perl.h", "EXTERN.h" and "XSUB.h".   With Perl5.003, it's
-# usually something like /usr/local/lib/perl5/arch-osname/5.003/CORE.
+DLIBPREFIX = @DLIBPREFIX@
 
-PERL5_INCLUDE= @PERL5EXT@
+SWIGD = $(SWIG) -d
+DCOMPILER = @D2COMPILER@
 
-# Extra Perl specific dynamic linking options
-PERL5_DLNK   = @PERL5DYNAMICLINKING@
-PERL5_CCFLAGS = @PERL5CCFLAGS@
-PERL5_CCDLFLAGS = @PERL5CCDLFLAGS@
-PERL5_CCCDLFLAGS = @PERL5CCCDLFLAGS@
-PERL5_LDFLAGS = @PERL5LDFLAGS@
-PERL = @PERL@
-PERL5_LIB = -L$(PERL5_INCLUDE) -l@PERL5LIB@ @LIBS@ $(SYSLIBS)
-PERL5_SCRIPT = $(SRCDIR)$(RUNME).pl
+D_RUNME = ./$(RUNME)
 
 # ----------------------------------------------------------------
-# Build a Perl5 dynamically loadable module (C)
+# Build a dynamically loadable D wrapper for a C module
 # ----------------------------------------------------------------
 
-perl5: $(SRCDIR_SRCS)
-	$(SWIG) -perl5 $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
-	$(CC) -c -Dbool=char $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(PERL5_CCFLAGS) $(PERL5_CCCDLFLAGS) -I$(PERL5_INCLUDE)
-	$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(PERL5_CCDLFLAGS) $(OBJS) $(IOBJS) $(PERL5_LDFLAGS) $(PERL5_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
+d: $(SRCDIR_SRCS)
+	$(SWIGD) $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+	$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(DCFLAGS) $(EXTRA_CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES)
+	$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(DCFLAGS) $(EXTRA_LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(DLIBPREFIX)$(TARGET)$(SO)
 
 # ----------------------------------------------------------------
-# Build a Perl5 dynamically loadable module (C++)
+# Build a dynamically loadable D wrapper for a C++ module
 # ----------------------------------------------------------------
 
-perl5_cpp: $(SRCDIR_SRCS)
-	$(SWIG) -perl5 -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-	$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(PERL5_CCFLAGS) $(PERL5_CCCDLFLAGS) -I$(PERL5_INCLUDE)
-	$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(PERL5_CCDLFLAGS) $(OBJS) $(IOBJS) $(PERL5_LDFLAGS) $(PERL5_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
+d_cpp: $(SRCDIR_SRCS)
+	$(SWIGD) -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+	$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(DCFLAGS) $(EXTRA_CFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES)
+	$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(DCFLAGS) $(EXTRA_LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(DLIBPREFIX)$(TARGET)$(SO)
 
 # ----------------------------------------------------------------
-# Build a module from existing XS C source code.   (ie. from xsubpp).
-# ----------------------------------------------------------------
-perl5_xs: $(SRCDIR_SRCS)
-	$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(INCLUDES) -I$(PERL5_INCLUDE)
-	$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $(TARGET)$(SO)
-
-# ----------------------------------------------------------------
-# Build a statically linked Perl5 executable
+# Compile D files
 # ----------------------------------------------------------------
 
-perl5_static: $(SRCDIR_SRCS)
-	$(SWIG) -perl5 -static -lperlmain.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
-	$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Dbool=char $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) -I$(PERL5_INCLUDE) $(PERL5_LIB) $(LIBS) -o $(TARGET)
-
-perl5_static_cpp: $(SRCDIR_SRCS)
-	$(SWIG) -perl5 -c++ -static -lperlmain.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-	$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) -I$(PERL5_INCLUDE) $(PERL5_LIB) $(LIBS) -o $(TARGET)
+# Clear the DFLAGS environment variable for the compiler call itself
+# to work around a discrepancy in argument handling between DMD and LDC.
+d_compile: $(SRCDIR_SRCS)
+	DFLAGS="" $(COMPILETOOL) $(DCOMPILER) $(DFLAGS) $(DSRCS)
 
 # -----------------------------------------------------------------
-# Running a Perl5 example
+# Run D example
 # -----------------------------------------------------------------
 
-perl5_run:
-	$(RUNTOOL) $(PERL) -I. $(PERL5_SCRIPT) $(RUNPIPE)
+d_run:
+	env LD_LIBRARY_PATH=$$PWD $(RUNTOOL) $(D_RUNME) $(RUNPIPE)
 
 # -----------------------------------------------------------------
 # Version display
 # -----------------------------------------------------------------
 
-perl5_version:
-	$(PERL) -v | grep "This is"
+d_version:
+	$(DCOMPILER) --version 2> /dev/null | head -n 3
 
 # -----------------------------------------------------------------
-# Cleaning the Perl5 examples
+# Clean the D examples
 # -----------------------------------------------------------------
 
-perl5_clean:
-	rm -f *_wrap* *~ .~* myperl@EXEEXT@ *.pm
+d_clean:
+	rm -f *_wrap* *~ .~* $(RUNME) $(RUNME).exe `find . -name \*.d | grep -v $(RUNME).d`
 	rm -f core @EXTRA_CLEAN@
 	rm -f *.@OBJEXT@ *@SO@
 
 ##################################################################
-#####                       PYTHON                          ######
+#####                       Go                              ######
 ##################################################################
 
-PYTHON_FLAGS =
+# TODO: The Go make targets need simplifying to use configure time
+# configuration or to use Make's ifeq rather than using lots of
+# runtime shell code. The output will then be a lot less verbose.
 
-# Make sure these locate your Python installation
-ifeq (,$(PY3))
-  PYTHON_INCLUDE= $(DEFS) @PYINCLUDE@
-  PYTHON_LIB    = @PYLIB@
-  PYTHON        = @PYTHON@ $(PYTHON_FLAGS)
-else
-  PYTHON_INCLUDE= $(DEFS) @PY3INCLUDE@
-  PYTHON_LIB    = @PY3LIB@
-  PYTHON        = @PYTHON3@ $(PYTHON_FLAGS)
-endif
+GO = @GO@
+GOGCC = @GOGCC@
+GCCGO = @GCCGO@
+GOOPT = @GOOPT@
+GCCGOOPT = @GCCGOOPT@
+GOVERSIONOPTION = @GOVERSIONOPTION@
 
-# Extra Python specific linking options
-ifeq (,$(PY3))
-  PYTHON_DLNK   = @PYTHONDYNAMICLINKING@
-  PYTHON_LINK   = @PYLINK@
-else
-  PYTHON_DLNK   = @PYTHON3DYNAMICLINKING@
-  PYTHON_LINK   = @PY3LINK@
-endif
-PYTHON_SO     = @PYTHON_SO@
+GOSWIGARG = `if $(GOGCC) ; then echo -gccgo; fi`
 
-# SWIG option for Python3
-ifeq (,$(PY3))
-  SWIGOPTPY3 =
-else
-  SWIGOPTPY3 = -py3
-endif
+GOSRCS = $(INTERFACE:.i=.go)
+GOCSRCS = $(INTERFACE:.i=_gc.c)
 
-PYCODESTYLE       = @PYCODESTYLE@
-PYCODESTYLE_FLAGS = --ignore=E252,E30,E402,E501,E731,W291,W391
+GOPACKAGE = $(notdir $(INTERFACE:.i=.a))
+
+GOPATHPARENTDIR = gopath/$(GOMOD)/src
+GOPATHDIR = $(GOPATHPARENTDIR)/$(INTERFACE:.i=)
 
 # ----------------------------------------------------------------
-# Build a C dynamically loadable module
+# Build a Go module (C)
 # ----------------------------------------------------------------
 
-python: $(SRCDIR_SRCS)
-	$(SWIG) -python $(SWIGOPTPY3) $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
-	$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) $(PYTHON_INCLUDE)
-	$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO)
+$(GOPATHPARENTDIR)/go.mod:
+	@mkdir gopath 2>/dev/null || true
+	@mkdir gopath/$(GOMOD) 2>/dev/null || true
+	@mkdir gopath/$(GOMOD)/src 2>/dev/null || true
+	@mkdir $(GOPATHDIR) 2>/dev/null || true
+	echo "module swigtests" > $(GOPATHDIR)/go.mod
+	echo "" >> $(GOPATHDIR)/go.mod
+	echo "go 1.12" >> $(GOPATHDIR)/go.mod
+	mv -f $(GOPATHDIR)/go.mod $(GOPATHPARENTDIR)/go.mod
+
+go: $(SRCDIR_SRCS) $(GOPATHPARENTDIR)/go.mod
+	$(SWIG) -go -import-prefix swigtests $(GOOPT) $(GOSWIGARG) $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+	@mkdir gopath 2>/dev/null || true
+	@mkdir gopath/$(GOMOD) 2>/dev/null || true
+	@mkdir gopath/$(GOMOD)/src 2>/dev/null || true
+	@mkdir $(GOPATHDIR) 2>/dev/null || true
+	rm -rf $(GOPATHDIR)/*
+	cp $(ISRCS) $(GOPATHDIR)/
+	if test -f $(IWRAP:.i=.h); then \
+	  cp $(IWRAP:.i=.h) $(GOPATHDIR)/; \
+	fi
+	if test -n "$(SRCDIR_SRCS)"; then \
+	  cp $(SRCDIR_SRCS) $(GOPATHDIR)/; \
+	fi
+	cp $(GOSRCS) $(GOPATHDIR)/
+	@if test -f $(SRCDIR)$(RUNME).go; then \
+	  mkdir gopath/$(GOMOD)/src/runme 2>/dev/null || true; \
+	  rm -f gopath/$(GOMOD)/src/runme/*; \
+	fi
+	if test -f $(SRCDIR)$(RUNME).go; then \
+	  cp $(SRCDIR)$(RUNME).go gopath/$(GOMOD)/src/runme/; \
+	fi
+	GOPATH=`pwd`/gopath/$(GOMOD); \
+	export GOPATH; \
+	CGO_CPPFLAGS="$(CPPFLAGS) $(INCLUDES) -I `cd $(SRCDIR) && pwd` -I `pwd`"; \
+	export CGO_CPPFLAGS; \
+	CGO_CFLAGS="$(CFLAGS)"; \
+	export CGO_CFLAGS; \
+	CGO_LDFLAGS="$(LDFLAGS) -lm"; \
+	export CGO_LDFLAGS; \
+	(cd $(GOPATHDIR)/ && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o $(GOPACKAGE)); \
+	stat=$$?; \
+	if test $$stat != 0; then \
+	  exit $$stat; \
+	fi; \
+	if $(GOGCC); then \
+	  cp $(GOPATHDIR)/$(GOPACKAGE) $(GOPATHDIR)/$(GOPACKAGE:.a=.gox); \
+	fi; \
+	if test -f $(SRCDIR)$(RUNME).go; then \
+	  mkdir gopath/$(GOMOD)/src/swigtests 2>/dev/null || true; \
+	  mkdir gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=) 2>/dev/null || true; \
+	  cp $(GOPATHDIR)/* gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=)/; \
+	  (cd gopath/$(GOMOD)/src/runme && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o runme $(RUNME).go); \
+	  stat=$$?; \
+	  if test $$stat != 0; then \
+	    exit $$stat; \
+	  fi; \
+	  cp gopath/$(GOMOD)/src/runme/runme $(RUNME); \
+	fi
+
+# ----------------------------------------------------------------
+# Build a Go module (C++)
+# ----------------------------------------------------------------
+
+go_cpp: $(SRCDIR_SRCS) $(GOPATHPARENTDIR)/go.mod
+	$(SWIG) -go -c++ -import-prefix swigtests $(GOOPT) $(GOSWIGARG) $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+	@mkdir gopath 2>/dev/null || true
+	@mkdir gopath/$(GOMOD) 2>/dev/null || true
+	@mkdir gopath/$(GOMOD)/src 2>/dev/null || true
+	@mkdir $(GOPATHDIR) 2>/dev/null || true
+	rm -rf $(GOPATHDIR)/*
+	cp $(ICXXSRCS) $(GOPATHDIR)/
+	if test -f $(IWRAP:.i=.h); then \
+	  cp $(IWRAP:.i=.h) $(GOPATHDIR)/; \
+	fi
+	if test -n "$(SRCDIR_CXXSRCS)"; then \
+	  cp $(SRCDIR_CXXSRCS) $(GOPATHDIR)/; \
+	fi
+	if test -n "$(SRCDIR_SRCS)"; then \
+	  cp $(SRCDIR_SRCS) $(GOPATHDIR)/; \
+	fi
+	cp $(GOSRCS) $(GOPATHDIR)/
+	@if test -f $(SRCDIR)$(RUNME).go; then \
+	  mkdir gopath/$(GOMOD)/src/runme 2>/dev/null || true; \
+	  rm -f gopath/$(GOMOD)/src/runme/*; \
+	fi
+	if test -f $(SRCDIR)$(RUNME).go; then \
+	  cp $(SRCDIR)$(RUNME).go gopath/$(GOMOD)/src/runme/; \
+	fi
+	GOPATH=`pwd`/gopath/$(GOMOD); \
+	export GOPATH; \
+	CGO_CPPFLAGS="$(CPPFLAGS) $(INCLUDES) -I `cd $(SRCDIR) && pwd` -I `pwd`"; \
+	export CGO_CPPFLAGS; \
+	CGO_CFLAGS="$(CFLAGS)"; \
+	export CGO_CFLAGS; \
+	CGO_CXXFLAGS="$(CXXFLAGS)"; \
+	export CGO_CXXFLAGS; \
+	CGO_LDFLAGS="$(LDFLAGS) -lm"; \
+	export CGO_LDFLAGS; \
+	(cd $(GOPATHDIR) && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o $(GOPACKAGE)); \
+	stat=$$?; \
+	if test $$stat != 0; then \
+	  exit $$stat; \
+	fi; \
+	if $(GOGCC); then \
+	  cp $(GOPATHDIR)/$(GOPACKAGE) $(GOPATHDIR)/$(GOPACKAGE:.a=.gox); \
+	fi; \
+	if test -f $(SRCDIR)$(RUNME).go; then \
+	  mkdir gopath/$(GOMOD)/src/swigtests 2>/dev/null || true; \
+	  mkdir gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=) 2>/dev/null || true; \
+	  cp $(GOPATHDIR)/* gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=)/; \
+	  (cd gopath/$(GOMOD)/src/runme && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o runme $(RUNME).go); \
+	  stat=$$?; \
+	  if test $$stat != 0; then \
+	    exit $$stat; \
+	  fi; \
+	  cp gopath/$(GOMOD)/src/runme/runme $(RUNME); \
+	fi
 
 # -----------------------------------------------------------------
-# Build a C++ dynamically loadable module
+# Running Go example
 # -----------------------------------------------------------------
 
-python_cpp: $(SRCDIR_SRCS)
-	$(SWIG) -python $(SWIGOPTPY3) -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-	$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(PYTHON_INCLUDE)
-	$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO)
-
-# -----------------------------------------------------------------
-# Build statically linked Python interpreter
-#
-# These should only be used in conjunction with the %include embed.i
-# library file
-# -----------------------------------------------------------------
-
-#TKINTER = -L/usr/X11R6.3/lib -L/usr/local/compat/lib -ltk4.0 -ltcl7.4 -lX11
-TKINTER =
-PYTHON_LIBOPTS = $(PYTHON_LINK) @LIBS@ $(TKINTER) $(SYSLIBS)
-
-python_static: $(SRCDIR_SRCS)
-	$(SWIG) -python $(SWIGOPTPY3) -lembed.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
-	$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) @LINKFORSHARED@ $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) \
-	$(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET)
-
-python_static_cpp: $(SRCDIR_SRCS)
-	$(SWIG) -python $(SWIGOPTPY3) -c++ -lembed.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-	$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) \
-	$(PYTHON_INCLUDE) $(LIBS)  -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET)
-
-# -----------------------------------------------------------------
-# Running a Python example
-# -----------------------------------------------------------------
-
-ifeq (,$(PY3))
-  PYSCRIPT = $(RUNME).py
-else
-  PYSCRIPT = $(RUNME)3.py
-endif
-
-PY2TO3 = @PY2TO3@ `@PY2TO3@ -l | grep -v -E "Available|import$$" | awk '{print "-f "$$0}'`
-
-python_run: $(PYSCRIPT)
-ifneq (,$(PYCODESTYLE))
-	$(COMPILETOOL) $(PYCODESTYLE) $(PYCODESTYLE_FLAGS) $(PYSCRIPT)
-endif
-	env PYTHONPATH=$$PWD $(RUNTOOL) $(PYTHON) $(PYSCRIPT) $(RUNPIPE)
-
-ifneq (,$(SRCDIR))
-$(RUNME).py: $(SRCDIR)$(RUNME).py
-	cp $< $@
-endif
-
-$(RUNME)3.py: $(SRCDIR)$(RUNME).py
-	cp $< $@
-	$(PY2TO3) -w $@ >/dev/null 2>&1
+go_run:
+	env $(RUNTOOL) ./$(RUNME) $(RUNPIPE)
 
 # -----------------------------------------------------------------
 # Version display
 # -----------------------------------------------------------------
 
-python_version:
-	$(PYTHON) -V
+go_version:
+	$(GO) $(GOVERSIONOPTION)
 
 # -----------------------------------------------------------------
-# Cleaning the python examples
+# Cleaning the Go examples
 # -----------------------------------------------------------------
 
-python_clean:
-	rm -rf __pycache__
-	rm -f *_wrap* *~ .~* mypython@EXEEXT@ *.pyc
+go_clean:
+	rm -f *_wrap* *_gc* *.gox .~* $(RUNME) $(GOSRCS)
+	rm -rf gopath
 	rm -f core @EXTRA_CLEAN@
-	rm -f *.@OBJEXT@ *@SO@ *$(PYTHON_SO)
-	rm -f $(TARGET).py
-	if test -f $(SRCDIR)$(RUNME).py; then rm -f $(RUNME)3.py $(RUNME)3.py.bak; fi
-	case "x$(SRCDIR)" in x|x./);; *) rm -f $(RUNME).py;; esac
-
-
-##################################################################
-#####                       OCTAVE                          ######
-##################################################################
-
-# Make sure these locate your Octave installation
-OCTAVE        = @OCTAVE@
-OCTAVE_CXX    = $(DEFS) @OCTAVE_CPPFLAGS@ @OCTAVE_CXXFLAGS@
-
-# Extra Octave specific dynamic linking options
-OCTAVE_DLNK   = @OCTAVE_LDFLAGS@
-OCTAVE_SO     = @OCTAVE_SO@
-
-OCTAVE_SCRIPT = $(SRCDIR)$(RUNME).m
-
-# ----------------------------------------------------------------
-# Build a C dynamically loadable module
-# Note: Octave requires C++ compiler when compiling C wrappers
-# ----------------------------------------------------------------
-
-octave: $(SRCDIR_SRCS)
-	$(SWIG) -octave $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-	$(CXX) -g -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
-	$(CC) -g -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CSRCS) $(INCLUDES)
-	$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(OCTAVE_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(OCTAVE_SO)
-
-# -----------------------------------------------------------------
-# Build a C++ dynamically loadable module
-# -----------------------------------------------------------------
-
-octave_cpp: $(SRCDIR_SRCS)
-	$(SWIG) -c++ -octave $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-	$(CXX) -g -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
-	$(CXXSHARED) -g $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(OCTAVE_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(OCTAVE_SO)
-
-# -----------------------------------------------------------------
-# Running an Octave example
-# -----------------------------------------------------------------
-
-octave_run:
-	env OCTAVE_PATH= OCTAVE_HISTFILE=/dev/null $(RUNTOOL) $(OCTAVE) $(OCTAVE_SCRIPT) $(RUNPIPE)
-
-# -----------------------------------------------------------------
-# Version display
-# -----------------------------------------------------------------
-
-octave_version:
-	$(OCTAVE) --version | head -n 1
-
-# -----------------------------------------------------------------
-# Cleaning the Octave examples
-# -----------------------------------------------------------------
-
-octave_clean:
-	rm -rf __pycache__
-	rm -f *_wrap* *~ .~* myoctave@EXEEXT@ *.pyc
-	rm -f core @EXTRA_CLEAN@
-	rm -f *.@OBJEXT@ *@SO@ *$(OCTAVE_SO)
+	rm -f *.@OBJEXT@ *.[568] *.a *@SO@
 
 ##################################################################
 #####                       GUILE                           ######
@@ -524,23 +548,11 @@
 # -----------------------------------------------------------------
 
 guile_static: $(SRCDIR_SRCS)
-	$(SWIG) -guile -lguilemain.i -Linkage ltdlmod $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
-	$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) \
-	  -DSWIGINIT="SCM scm_init_$(TARGET)_module(void); scm_init_$(TARGET)_module();" \
-	  $(GUILE_CFLAGS) $(GUILE_LIBS) $(LIBS) $(GUILE_LIBOPTS) -o $(TARGET)-guile
-
-guile_static_cpp: $(SRCDIR_SRCS)
-	$(SWIG) -c++ -guile -lguilemain.i -Linkage ltdlmod $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-	$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) \
-	  -DSWIGINIT="SCM scm_init_$(TARGET)_module(void); scm_init_$(TARGET)_module();" \
-	  $(GUILE_CFLAGS) $(GUILE_LIBS) $(LIBS) $(GUILE_LIBOPTS) -o $(TARGET)-guile
-
-guile_simple: $(SRCDIR_SRCS)
 	$(SWIG) -guile -lguilemain.i -Linkage simple $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
 	$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) \
 	  $(GUILE_CFLAGS) $(GUILE_LIBS) $(LIBS) $(GUILE_LIBOPTS) -o $(TARGET)-guile
 
-guile_simple_cpp: $(SRCDIR_SRCS)
+guile_static_cpp: $(SRCDIR_SRCS)
 	$(SWIG) -c++ -guile -lguilemain.i -Linkage simple $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
 	$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) \
 	  $(GUILE_CFLAGS) $(GUILE_LIBS) $(LIBS) $(GUILE_LIBOPTS) -o $(TARGET)-guile
@@ -653,29 +665,60 @@
 JSDYNAMICLINKING = @JSCOREDYNAMICLINKING@ @JSV8DYNAMICLINKING@
 NODEJS = @NODEJS@
 NODEGYP = @NODEGYP@
+ifneq (, $(ENGINE))
+    JSENGINE=$(ENGINE)
+else
+ifneq (, $(NODEJS))
+    JSENGINE=node
+else
+ifneq (, @JSCENABLED@)
+    JSENGINE=jsc
+else
+ifneq (, @JSV8ENABLED@)
+    JSENGINE=v8
+else
+    # Shouldn't happen, but avoid empty value if it does.
+    JSENGINE=node
+endif
+endif
+endif
+endif
 
 # ----------------------------------------------------------------
 # Creating and building Javascript wrappers
 # ----------------------------------------------------------------
 
+NAPI_DIR = @NODENAPI_DIR@
+
 javascript_wrapper:
-	$(SWIG) -javascript $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.c $(INTERFACEPATH)
+ifeq ($(JSENGINE), $(filter $(JSENGINE), node napi))
+	$(SWIG) -javascript $(SWIGOPT) -$(JSENGINE) -o $(INTERFACEDIR)$(TARGET)_wrap.cxx $(INTERFACEPATH)
+else
+	$(SWIG) -javascript $(SWIGOPT) -$(JSENGINE) -o $(INTERFACEDIR)$(TARGET)_wrap.c $(INTERFACEPATH)
+endif
 
 javascript_wrapper_cpp: $(SRCDIR_SRCS)
-	$(SWIG) -javascript -c++ $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.cxx $(INTERFACEPATH)
+	$(SWIG) -javascript -c++ $(SWIGOPT) -$(JSENGINE) -o $(INTERFACEDIR)$(TARGET)_wrap.cxx $(INTERFACEPATH)
 
 javascript_build: $(SRCDIR_SRCS)
-	$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) $(JSINCLUDES)
-	$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
-
-javascript_build_cpp: $(SRCDIR_SRCS)
 ifeq (node,$(JSENGINE))
 	sed -e 's|$$srcdir|./$(SRCDIR)|g' $(SRCDIR)binding.gyp.in > binding.gyp
 	MAKEFLAGS= $(NODEGYP) --loglevel=silent configure build 1>>/dev/null
+else ifeq (napi,$(JSENGINE))
+	sed -e 's|$$srcdir|./$(SRCDIR)|g' $(SRCDIR)binding.gyp.in > binding.gyp
+	MAKEFLAGS= CXXFLAGS="$(CXXFLAGS) -I$(NAPI_DIR)" $(NODEGYP) --loglevel=silent configure build 1>>/dev/null
+else
+	$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) $(JSINCLUDES)
+	$(LDSHARED) $(CCSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
+endif
+
+javascript_build_cpp: $(SRCDIR_SRCS)
+ifeq ($(JSENGINE), $(filter $(JSENGINE), node napi))
+	sed -e 's|$$srcdir|./$(SRCDIR)|g' $(SRCDIR)binding.gyp.in > binding.gyp
+	MAKEFLAGS= CXXFLAGS="$(CXXFLAGS) -I$(NAPI_DIR)" $(NODEGYP) --loglevel=silent configure build 1>>/dev/null
 else
 	$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(JSINCLUDES)
 	$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(JSDYNAMICLINKING) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
-
 endif
 
 # These targets are used by the test-suite:
@@ -702,7 +745,7 @@
 javascript_custom_interpreter:
 	(cd $(ROOT_DIR)/Tools/javascript && $(MAKE) JSENGINE='$(JSENGINE)')
 
-ifeq (node,$(JSENGINE))
+ifeq ($(JSENGINE), $(filter $(JSENGINE), node napi))
 javascript_run:
 	env NODE_PATH=$$PWD:$(SRCDIR) $(RUNTOOL) $(NODEJS) $(SRCDIR)$(RUNME).js $(RUNPIPE)
 else
@@ -723,15 +766,15 @@
 	  echo "Version depends on the interpreter"; \
 	fi
 endif
-ifeq (node, $(ENGINE))
+ifeq ($(ENGINE), $(filter $(ENGINE), node napi))
 	echo "Node.js: `($(NODEJS) --version)`"
 	echo "node-gyp: `($(NODEGYP) --version)`"
 endif
 ifeq (jsc, $(ENGINE))
 	@if [ "@JSCOREVERSION@" != "" ]; then \
-	  echo "@JSCOREVERSION@"; \
+	  echo "JavaScriptCore: @JSCOREVERSION@"; \
 	else \
-	  echo "Unknown JavascriptCore version."; \
+	  echo "Unknown JavaScriptCore version."; \
 	fi
 endif
 ifeq (v8, $(ENGINE))
@@ -751,409 +794,7 @@
 	cd $(ROOT_DIR)/Tools/javascript && $(MAKE) -s clean
 
 ##################################################################
-#####                       ANDROID                         ######
-##################################################################
-
-ANDROID = @ANDROID@
-ANDROID_NDK_BUILD = @NDKBUILD@
-ANDROID_ADB = @ADB@
-ANT = @ANT@
-TARGETID = 1
-
-# ----------------------------------------------------------------
-# Build an Android dynamically loadable module (C)
-# ----------------------------------------------------------------
-
-android: $(SRCDIR_SRCS)
-	$(ANDROID) $(SILENT_OPTION) update project --target $(TARGETID) --name $(PROJECTNAME) --path .
-	$(SWIG) -java $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.c $(INTERFACEPATH)
-	+$(ANDROID_NDK_BUILD) $(SILENT_PIPE)
-	$(ANT) $(ANT_QUIET) debug
-
-# ----------------------------------------------------------------
-# Build an Android dynamically loadable module (C++)
-# ----------------------------------------------------------------
-
-android_cpp: $(SRCDIR_SRCS)
-	$(ANDROID) $(SILENT_OPTION) update project --target $(TARGETID) --name $(PROJECTNAME) --path .
-	$(SWIG) -java -c++ $(SWIGOPT) -o $(INTERFACEDIR)$(TARGET)_wrap.cpp $(INTERFACEPATH)
-	+$(ANDROID_NDK_BUILD) $(SILENT_PIPE)
-	$(ANT) $(ANT_QUIET) debug
-
-# ----------------------------------------------------------------
-# Android install
-# ----------------------------------------------------------------
-
-android_install:
-	-$(ANDROID_ADB) uninstall $(PACKAGENAME)
-	$(ANDROID_ADB) install $(INSTALLOPTIONS) bin/$(PROJECTNAME)-debug.apk
-
-# -----------------------------------------------------------------
-# Version display
-# -----------------------------------------------------------------
-
-android_version:
-	$(ANDROID_ADB) version
-
-# -----------------------------------------------------------------
-# Cleaning the Android examples
-# -----------------------------------------------------------------
-
-android_clean:
-	test -n "$(SRCDIR)" && cd $(SRCDIR) ; $(ANT) -q -logfile /dev/null clean
-	rm -f $(INTERFACEDIR)$(TARGET)_wrap.*
-	rm -f `find $(PACKAGEDIR) -name \*.java | grep -v $(PROJECTNAME).java`
-	rm -rf obj
-
-##################################################################
-#####                       MZSCHEME                        ######
-##################################################################
-
-MZSCHEME = mzscheme
-MZC = @MZC@
-MZDYNOBJ = @MZDYNOBJ@
-MZSCHEME_SO = @MZSCHEME_SO@
-MZSCHEME_SCRIPT = $(SRCDIR)$(RUNME).scm
-
-# ----------------------------------------------------------------
-# Build a C/C++ dynamically loadable module
-# ----------------------------------------------------------------
-
-mzscheme: $(SRCDIR_SRCS)
-	$(SWIG) -mzscheme $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
-	$(COMPILETOOL) $(MZC) `echo " $(CPPFLAGS) $(INCLUDES) $(CFLAGS)" | sed 's/ -/ ++ccf -/g'` --cc $(ISRCS) $(SRCDIR_SRCS)
-	$(COMPILETOOL) $(MZC) --ld $(TARGET)$(MZSCHEME_SO) $(OBJS) $(IOBJS)
-
-mzscheme_cpp: $(SRCDIR_SRCS)
-	$(SWIG) -mzscheme -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-	env CFLAGS= $(COMPILETOOL) $(MZC) `echo " $(CPPFLAGS) $(INCLUDES) $(CXXFLAGS)" | sed 's/ -/ ++ccf -/g'` --cc $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
-	$(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $(LIBPREFIX)$(TARGET)$(MZSCHEME_SO) $(OBJS) $(IOBJS) $(MZDYNOBJ) $(CPP_DLLIBS)
-
-# -----------------------------------------------------------------
-# Run mzscheme example
-# -----------------------------------------------------------------
-
-mzscheme_run:
-	env LD_LIBRARY_PATH=$$PWD $(RUNTOOL) $(MZSCHEME) -r $(MZSCHEME_SCRIPT) $(RUNPIPE)
-
-# -----------------------------------------------------------------
-# Version display
-# -----------------------------------------------------------------
-
-mzscheme_version:
-	$(MZSCHEME) -v
-	$(MZC) -v
-
-# -----------------------------------------------------------------
-# Cleaning the mzscheme examples
-# -----------------------------------------------------------------
-
-mzscheme_clean:
-	rm -f *_wrap* *~ .~*
-	rm -f core @EXTRA_CLEAN@
-	rm -f *.@OBJEXT@ *$(MZSCHEME_SO)
-
-##################################################################
-#####                          Ocaml                         #####
-##################################################################
-
-OCC=$(COMPILETOOL) @OCAMLC@
-OCC_WITH_PP=env TMPDIR=./localtmp $(OCC)
-# TMPDIR above is a workaround for some ocamlc versions, such as 4.05.0, which always create a temp file of the same name breaking parallel make (seemingly only when -pp is used)
-OCAMLDLGEN=$(COMPILETOOL) @OCAMLDLGEN@
-OCAMLFIND=$(COMPILETOOL) @OCAMLFIND@
-OCAMLMKTOP=$(COMPILETOOL) @OCAMLMKTOP@
-NOLINK ?= false
-OCAMLPP= -pp "camlp4o ./swigp4.cmo"
-OCAMLP4WHERE=`$(COMPILETOOL) @CAMLP4@ -where`
-
-ocaml_core:
-	mkdir -p ./localtmp
-	$(SWIG) -ocaml -co swig.mli 2>/dev/null
-	$(SWIG) -ocaml -co swig.ml 2>/dev/null
-	$(SWIG) -ocaml -co swigp4.ml 2>/dev/null
-	$(OCC) -c swig.mli
-	$(OCC) -c swig.ml
-	$(OCC_WITH_PP) -I $(OCAMLP4WHERE) -pp "camlp4o pa_extend.cmo q_MLast.cmo" -c swigp4.ml
-
-ocaml_static: $(SRCDIR_SRCS)
-	$(SWIG) -ocaml $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
-	$(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS)
-	$(OCC) -g -c $(INTERFACE:%.i=%.mli)
-	$(OCC) -w -U -g -c $(INTERFACE:%.i=%.ml)
-	test -z "$(PROGFILE)" || $(OCC_WITH_PP) -o $(PROGFILE:%.ml=%) $(OCAMLPP) -c $(SRCDIR)$(PROGFILE)
-	$(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(RUNME) swig.cmo $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)"
-
-ocaml_dynamic: $(SRCDIR_SRCS)
-	$(SWIG) -ocaml $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
-	$(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS)
-	$(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(CCSHARED) -o $(INTERFACE:%.i=%@SO@) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) $(LIBS)
-	$(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > $(INTERFACE:%.i=%_dynamic.ml)
-	mv $(INTERFACE:%.i=%_dynamic.ml) $(INTERFACE:%.i=%.ml)
-	rm $(INTERFACE:%.i=%.mli)
-	$(OCAMLFIND) $(OCC) -g -c -package dl $(INTERFACE:%.i=%.ml)
-	test -z "$(PROGFILE)" || $(OCC_WITH_PP) -o $(PROGFILE:%.ml=%) $(OCAMLPP) -c $(SRCDIR)$(PROGFILE)
-	$(NOLINK) || $(OCAMLFIND) $(OCC) -g -ccopt -g -cclib -g -custom -o $(RUNME) swig.cmo -package dl -linkpkg $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo)
-
-ocaml_static_toplevel: $(SRCDIR_SRCS)
-	$(SWIG) -ocaml $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
-	$(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS)
-	$(OCC) -g -c $(INTERFACE:%.i=%.mli)
-	$(OCC) -w -U -g -c $(INTERFACE:%.i=%.ml)
-	test -z "$(PROGFILE)" || $(OCC_WITH_PP) -o $(PROGFILE:%.ml=%) $(OCAMLPP) -c $(SRCDIR)$(PROGFILE)
-	$(NOLINK) || $(OCAMLMKTOP) swig.cmo -I $(OCAMLP4WHERE) dynlink.cma camlp4o.cma swigp4.cmo -cclib "$(LIBS)" -g -ccopt -g -cclib -g -custom -o $(RUNME)_top $(INTERFACE:%.i=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS)
-
-ocaml_static_cpp: $(SRCDIR_SRCS)
-	$(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-	cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
-	$(OCC) -cc '$(CXX) $(CPPFLAGS)' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
-	$(OCC) -g -c $(INTERFACE:%.i=%.mli)
-	$(OCC) -w -U -g -c $(INTERFACE:%.i=%.ml)
-	test -z "$(PROGFILE)" || $(OCC_WITH_PP) -o $(PROGFILE:%.ml=%) $(OCAMLPP) -c $(SRCDIR)$(PROGFILE)
-	$(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(RUNME) swig.cmo $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)" -cc '$(CXX)'
-
-ocaml_static_cpp_toplevel: $(SRCDIR_SRCS)
-	$(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-	cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
-	$(OCC) -cc '$(CXX) $(CPPFLAGS)' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
-	$(OCC) -g -c $(INTERFACE:%.i=%.mli)
-	$(OCC) -w -U -g -c $(INTERFACE:%.i=%.ml)
-	test -z "$(PROGFILE)" || $(OCC_WITH_PP) -o $(PROGFILE:%.ml=%) $(OCAMLPP) -c $(SRCDIR)$(PROGFILE)
-	$(NOLINK) || $(OCAMLMKTOP) -cc '$(CXX) $(CPPFLAGS)' swig.cmo -I $(OCAMLP4WHERE) dynlink.cma camlp4o.cma swigp4.cmo -cclib "$(LIBS)" -g -ccopt -g -cclib -g -custom -o $(RUNME)_top $(INTERFACE:%.i=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS)
-
-ocaml_dynamic_cpp: $(SRCDIR_SRCS)
-	$(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-	cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
-	$(OCC) -cc '$(CXX) $(CPPFLAGS)' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) -ccopt -fPIC
-	$(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $(INTERFACE:%.i=%@SO@) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) $(CPP_DLLIBS) $(LIBS)
-	$(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > $(INTERFACE:%.i=%_dynamic.ml)
-	mv $(INTERFACE:%.i=%_dynamic.ml) $(INTERFACE:%.i=%.ml)
-	rm $(INTERFACE:%.i=%.mli)
-	$(OCAMLFIND) $(OCC) -g -c -package dl $(INTERFACE:%.i=%.ml)
-	test -z "$(PROGFILE)" || $(OCC_WITH_PP) -o $(PROGFILE:%.ml=%) $(OCAMLPP) -c $(SRCDIR)$(PROGFILE)
-	$(NOLINK) || $(OCAMLFIND) swig.cmo $(OCC) -cclib -export-dynamic -g -ccopt -g -cclib -g -custom -o $(RUNME) -package dl -linkpkg $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) -cc '$(CXX)'
-
-# -----------------------------------------------------------------
-# Run ocaml example
-# -----------------------------------------------------------------
-
-ocaml_run:
-	$(RUNTOOL) ./$(RUNME) $(RUNPIPE)
-
-# -----------------------------------------------------------------
-# Version display
-# -----------------------------------------------------------------
-
-ocaml_version:
-	$(OCC) -version
-
-# -----------------------------------------------------------------
-# Cleaning the Ocaml examples
-# -----------------------------------------------------------------
-
-ocaml_clean:
-	rm -f *_wrap* *~ .~* *.cmo *.cmi *.mli $(TARGET).ml $(RUNME) $(RUNME)_top swig.ml swigp4.ml
-	rm -f core @EXTRA_CLEAN@
-	rm -f *.@OBJEXT@ *@SO@
-	rm -rf ./localtmp
-
-##################################################################
-#####                       RUBY                            ######
-##################################################################
-
-# Make sure these locate your Ruby installation
-RUBY_CFLAGS= @RUBYCCDLFLAGS@ $(DEFS)
-RUBY_INCLUDE= @RUBYINCLUDE@
-RUBY_LIB     = @RUBYLIB@
-RUBY_DLNK = @RUBYDYNAMICLINKING@
-RUBY_LIBOPTS = @RUBYLINK@ @LIBS@ $(SYSLIBS)
-RUBY_SO = @RUBYSO@
-RUBY = @RUBY@
-RUBY_SCRIPT = $(SRCDIR)$(RUNME).rb
-
-
-# ----------------------------------------------------------------
-# Build a C dynamically loadable module
-# ----------------------------------------------------------------
-
-ruby: $(SRCDIR_SRCS)
-	$(SWIG) -ruby $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
-	$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(RUBY_CFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) $(RUBY_INCLUDE)
-	$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(RUBY_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(RUBY_SO)
-
-# -----------------------------------------------------------------
-# Build a C++ dynamically loadable module
-# -----------------------------------------------------------------
-
-ruby_cpp: $(SRCDIR_SRCS)
-	$(SWIG) -c++ -ruby $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-	$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(RUBY_CFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(RUBY_INCLUDE)
-	$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(RUBY_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(RUBY_SO)
-
-# -----------------------------------------------------------------
-# Build statically linked Ruby interpreter
-#
-# These should only be used in conjunction with the %include embed.i
-# library file
-# -----------------------------------------------------------------
-
-ruby_static: $(SRCDIR_SRCS)
-	$(SWIG) -ruby -lembed.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
-	$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(RUBY_CFLAGS) @LINKFORSHARED@ $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) \
-	$(RUBY_INCLUDE) $(LIBS) -L$(RUBY_LIB) $(RUBY_LIBOPTS) -o $(TARGET)
-
-ruby_cpp_static: $(SRCDIR_SRCS)
-	$(SWIG) -c++ -ruby -lembed.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-	$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(RUBY_CFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) \
-	$(RUBY_INCLUDE) $(LIBS)  -L$(RUBY_LIB) $(RUBY_LIBOPTS) -o $(TARGET)
-
-# -----------------------------------------------------------------
-# Run Ruby example
-# -----------------------------------------------------------------
-
-ruby_run:
-	$(RUNTOOL) $(RUBY) $(RUBYFLAGS) -I. $(RUBY_SCRIPT) $(RUNPIPE)
-
-# -----------------------------------------------------------------
-# Version display
-# -----------------------------------------------------------------
-
-ruby_version:
-	$(RUBY) -v
-
-# -----------------------------------------------------------------
-# Cleaning the Ruby examples
-# -----------------------------------------------------------------
-
-ruby_clean:
-	rm -f *_wrap* *~ .~* myruby@EXEEXT@
-	rm -f core @EXTRA_CLEAN@
-	rm -f *.@OBJEXT@ *$(RUBY_SO)
-
-##################################################################
-#####                       PHP7                            ######
-##################################################################
-
-PHP         = @PHP@
-PHP_INCLUDE = @PHPINC@
-PHP_SO      = @PHP_SO@
-PHP_SCRIPT  = $(SRCDIR)$(RUNME).php
-
-# -------------------------------------------------------------------
-# Build a PHP dynamically loadable module (C)
-# -------------------------------------------------------------------
-
-php: $(SRCDIR_SRCS)
-	$(SWIG) -php7 $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
-	$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(PHP_INCLUDE)
-	$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(PHP_SO)
-
-# --------------------------------------------------------------------
-# Build a PHP dynamically loadable module (C++)
-# --------------------------------------------------------------------
-
-php_cpp: $(SRCDIR_SRCS)
-	$(SWIG) -php7 -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-	$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(PHP_INCLUDE)
-	$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(PHP_SO)
-
-# -----------------------------------------------------------------
-# Running a PHP example
-# -----------------------------------------------------------------
-
-php_run:
-	$(RUNTOOL) $(PHP) -n -q -d extension_dir=. -d safe_mode=Off -d display_errors=stderr $(PHP_SCRIPT) $(RUNPIPE)
-
-# -----------------------------------------------------------------
-# Version display
-# -----------------------------------------------------------------
-
-php_version:
-	$(PHP) -v | head -n 1
-
-# -----------------------------------------------------------------
-# Cleaning the PHP examples
-# -----------------------------------------------------------------
-
-php_clean:
-	rm -f *_wrap* *~ .~* example.php php_example.h
-	rm -f core @EXTRA_CLEAN@
-	rm -f *.@OBJEXT@ *$(PHP_SO)
-
-##################################################################
-#####                      CSHARP                           ######
-##################################################################
-
-# Extra CSharp specific dynamic linking options
-CSHARP_DLNK  = @CSHARPDYNAMICLINKING@
-CSHARP_LIBPREFIX = @CSHARPLIBRARYPREFIX@
-CSHARPCOMPILER = @CSHARPCOMPILER@
-CSHARPCILINTERPRETER = @CSHARPCILINTERPRETER@
-CSHARPCILINTERPRETER_FLAGS = @CSHARPCILINTERPRETER_FLAGS@
-CSHARPCFLAGS = @CSHARPCFLAGS@
-CSHARPFLAGS =
-CSHARPOPTIONS =
-CSHARPSO = @CSHARPSO@
-CSHARP_RUNME = ./$(RUNME).exe
-
-# ----------------------------------------------------------------
-# Build a CSharp dynamically loadable module (C)
-# ----------------------------------------------------------------
-
-csharp: $(SRCDIR_SRCS)
-	$(SWIG) -csharp $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
-	$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(CSHARPCFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES)
-	$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(CSHARP_DLNK) $(LIBS) -o $(CSHARP_LIBPREFIX)$(TARGET)$(CSHARPSO)
-
-# ----------------------------------------------------------------
-# Build a CSharp dynamically loadable module (C++)
-# ----------------------------------------------------------------
-
-csharp_cpp: $(SRCDIR_SRCS)
-	$(SWIG) -csharp -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-	$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(CSHARPCFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES)
-	$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(CSHARP_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(CSHARP_LIBPREFIX)$(TARGET)$(CSHARPSO)
-
-# ----------------------------------------------------------------
-# Compile CSharp files
-# ----------------------------------------------------------------
-
-ifneq (,$(SRCDIR))
-SRCDIR_CSHARPSRCS = $(addprefix $(SRCDIR),$(CSHARPSRCS))
-else
-SRCDIR_CSHARPSRCS =
-endif
-
-csharp_compile: $(SRCDIR_SRCS)
-	$(COMPILETOOL) $(CSHARPCOMPILER) $(CSHARPFLAGS) $(CSHARPOPTIONS) $(CSHARPSRCS) $(SRCDIR_CSHARPSRCS)
-
-# -----------------------------------------------------------------
-# Run CSharp example
-# -----------------------------------------------------------------
-
-csharp_run:
-	env LD_LIBRARY_PATH=$$PWD $(RUNTOOL) $(CSHARPCILINTERPRETER) $(CSHARPCILINTERPRETER_FLAGS) $(CSHARP_RUNME) $(RUNPIPE)
-
-# -----------------------------------------------------------------
-# Version display
-# -----------------------------------------------------------------
-
-# Version check below also works with MS csc.exe which does not understand --version
-csharp_version:
-	$(CSHARPCOMPILER) --version | head -n 1
-	if test -n "$(CSHARPCILINTERPRETER)" ; then "$(CSHARPCILINTERPRETER)" --version ; fi
-
-# -----------------------------------------------------------------
-# Cleaning the CSharp examples
-# -----------------------------------------------------------------
-
-csharp_clean:
-	rm -f *_wrap* *~ .~* $(RUNME) $(RUNME).exe *.exe.mdb gc.log `find . -name \*.cs | grep -v $(RUNME).cs`
-	rm -f core @EXTRA_CLEAN@
-	rm -f *.@OBJEXT@ *@CSHARPSO@
-
-##################################################################
-#####                      LUA                              ######
+#####                       LUA                             ######
 ##################################################################
 
 # lua flags
@@ -1235,87 +876,480 @@
 	rm -f *.@OBJEXT@ *$(LUA_SO)
 
 ##################################################################
-#####                   ALLEGRO CL                          ######
+#####                       MZSCHEME                        ######
 ##################################################################
 
-ALLEGROCL    = @ALLEGROCLBIN@
-ALLEGROCL_SCRIPT=$(RUNME).lisp
+MZSCHEME = mzscheme
+MZC = @MZC@
+MZDYNOBJ = @MZDYNOBJ@
+MZSCHEME_SO = @MZSCHEME_SO@
+MZSCHEME_SCRIPT = $(SRCDIR)$(RUNME).scm
 
-allegrocl: $(SRCDIR_SRCS)
-	$(SWIG) -allegrocl -cwrap $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
-	$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(ISRCS) $(INCLUDES) $(SRCDIR_SRCS)
-	$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
+# ----------------------------------------------------------------
+# Build a C/C++ dynamically loadable module
+# ----------------------------------------------------------------
 
-allegrocl_cpp: $(SRCDIR_SRCS)
-	$(SWIG) -c++ -allegrocl $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-	$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES)
-	$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
+mzscheme: $(SRCDIR_SRCS)
+	$(SWIG) -mzscheme $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+	$(COMPILETOOL) $(MZC) `echo " $(CPPFLAGS) $(INCLUDES) $(CFLAGS)" | sed 's/ -/ ++ccf -/g'` --cc $(ISRCS) $(SRCDIR_SRCS)
+	$(COMPILETOOL) $(MZC) --ld $(TARGET)$(MZSCHEME_SO) $(OBJS) $(IOBJS)
+
+mzscheme_cpp: $(SRCDIR_SRCS)
+	$(SWIG) -mzscheme -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+	env CFLAGS= $(COMPILETOOL) $(MZC) `echo " $(CPPFLAGS) $(INCLUDES) $(CXXFLAGS)" | sed 's/ -/ ++ccf -/g'` --cc $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
+	$(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $(LIBPREFIX)$(TARGET)$(MZSCHEME_SO) $(OBJS) $(IOBJS) $(MZDYNOBJ) $(CPP_DLLIBS)
 
 # -----------------------------------------------------------------
-# Run ALLEGRO CL example
+# Run mzscheme example
 # -----------------------------------------------------------------
 
-allegrocl_run:
-	$(RUNTOOL) $(ALLEGROCL) -batch -s $(ALLEGROCL_SCRIPT) $(RUNPIPE)
+mzscheme_run:
+	env LD_LIBRARY_PATH=$$PWD $(RUNTOOL) $(MZSCHEME) -r $(MZSCHEME_SCRIPT) $(RUNPIPE)
 
 # -----------------------------------------------------------------
 # Version display
 # -----------------------------------------------------------------
 
-allegrocl_version:
-	$(ALLEGROCL) --version
+mzscheme_version:
+	$(MZSCHEME) -v
+	$(MZC) -v
 
 # -----------------------------------------------------------------
-# Cleaning the ALLEGRO CL examples
+# Cleaning the mzscheme examples
 # -----------------------------------------------------------------
 
-allegrocl_clean:
+mzscheme_clean:
 	rm -f *_wrap* *~ .~*
 	rm -f core @EXTRA_CLEAN@
-	rm -f *.@OBJEXT@ *@SO@
+	rm -f *.@OBJEXT@ *$(MZSCHEME_SO)
 
 ##################################################################
-#####                      CFFI                             ######
+#####                       OCAML                           ######
 ##################################################################
 
-CFFI = @CFFIBIN@
-CFFI_SCRIPT=$(RUNME).lisp
+OCC=$(COMPILETOOL) @OCAMLC@
+OCC_WITH_PP=env TMPDIR=./localtmp $(OCC)
+# TMPDIR above is a workaround for some ocamlc versions, such as 4.05.0, which always create a temp file of the same name breaking parallel make (seemingly only when -pp is used)
+OCAMLDLGEN=$(COMPILETOOL) @OCAMLDLGEN@
+OCAMLFIND=$(COMPILETOOL) @OCAMLFIND@
+OCAMLMKTOP=$(COMPILETOOL) @OCAMLMKTOP@
+NOLINK ?= false
+OCAMLPP= -pp "camlp4o ./swigp4.cmo"
+OCAMLP4WHERE=`$(COMPILETOOL) @CAMLP4@ -where`
 
-cffi: $(SRCDIR_SRCS)
-	$(SWIG) -cffi $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
-#	$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(ISRCS) $(INCLUDES) $(SRCDIR_SRCS)
-#	$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
+ocaml_core:
+	mkdir -p ./localtmp
+	$(SWIG) -ocaml -co swig.mli 2>/dev/null
+	$(SWIG) -ocaml -co swig.ml 2>/dev/null
+	$(SWIG) -ocaml -co swigp4.ml 2>/dev/null
+	$(OCC) -c swig.mli
+	$(OCC) -c swig.ml
+	$(OCC_WITH_PP) -I $(OCAMLP4WHERE) -pp "camlp4o pa_extend.cmo q_MLast.cmo" -c swigp4.ml
 
-cffi_cpp: $(SRCDIR_SRCS)
-	$(SWIG) -c++ -cffi $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-	$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES)
-	$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
+ocaml_static: $(SRCDIR_SRCS)
+	$(SWIG) -ocaml $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+	$(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS)
+	$(OCC) -g -c $(INTERFACE:%.i=%.mli)
+	$(OCC) -w -U -g -c $(INTERFACE:%.i=%.ml)
+	test -z "$(PROGFILE)" || $(OCC_WITH_PP) -o $(PROGFILE:%.ml=%) $(OCAMLPP) -c $(SRCDIR)$(PROGFILE)
+	$(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(RUNME) swig.cmo $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)"
+
+ocaml_dynamic: $(SRCDIR_SRCS)
+	$(SWIG) -ocaml $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+	$(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS)
+	$(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(CCSHARED) -o $(INTERFACE:%.i=%@SO@) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) $(LIBS)
+	$(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > $(INTERFACE:%.i=%_dynamic.ml)
+	mv $(INTERFACE:%.i=%_dynamic.ml) $(INTERFACE:%.i=%.ml)
+	rm $(INTERFACE:%.i=%.mli)
+	$(OCAMLFIND) $(OCC) -g -c -package dl $(INTERFACE:%.i=%.ml)
+	test -z "$(PROGFILE)" || $(OCC_WITH_PP) -o $(PROGFILE:%.ml=%) $(OCAMLPP) -c $(SRCDIR)$(PROGFILE)
+	$(NOLINK) || $(OCAMLFIND) $(OCC) -g -ccopt -g -cclib -g -custom -o $(RUNME) swig.cmo -package dl -linkpkg $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo)
+
+ocaml_static_toplevel: $(SRCDIR_SRCS)
+	$(SWIG) -ocaml $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+	$(OCC) -g -c -ccopt -g -ccopt "$(INCLUDES)" $(ISRCS) $(SRCDIR_SRCS)
+	$(OCC) -g -c $(INTERFACE:%.i=%.mli)
+	$(OCC) -w -U -g -c $(INTERFACE:%.i=%.ml)
+	test -z "$(PROGFILE)" || $(OCC_WITH_PP) -o $(PROGFILE:%.ml=%) $(OCAMLPP) -c $(SRCDIR)$(PROGFILE)
+	$(NOLINK) || $(OCAMLMKTOP) swig.cmo -I $(OCAMLP4WHERE) dynlink.cma camlp4o.cma swigp4.cmo -cclib "$(LIBS)" -g -ccopt -g -cclib -g -custom -o $(RUNME)_top $(INTERFACE:%.i=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS)
+
+ocaml_static_cpp: $(SRCDIR_SRCS)
+	$(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+	cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
+	$(OCC) -cc '$(CXX) $(CPPFLAGS) $(CXXFLAGS)' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
+	$(OCC) -g -c $(INTERFACE:%.i=%.mli)
+	$(OCC) -w -U -g -c $(INTERFACE:%.i=%.ml)
+	test -z "$(PROGFILE)" || $(OCC_WITH_PP) -o $(PROGFILE:%.ml=%) $(OCAMLPP) -c $(SRCDIR)$(PROGFILE)
+	$(NOLINK) || $(OCC) -g -ccopt -g -cclib -g -custom -o $(RUNME) swig.cmo $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) -cclib "$(LIBS)" -cc '$(CXX)'
+
+ocaml_static_cpp_toplevel: $(SRCDIR_SRCS)
+	$(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+	cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
+	$(OCC) -cc '$(CXX) $(CPPFLAGS) $(CXXFLAGS)' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS)
+	$(OCC) -g -c $(INTERFACE:%.i=%.mli)
+	$(OCC) -w -U -g -c $(INTERFACE:%.i=%.ml)
+	test -z "$(PROGFILE)" || $(OCC_WITH_PP) -o $(PROGFILE:%.ml=%) $(OCAMLPP) -c $(SRCDIR)$(PROGFILE)
+	$(NOLINK) || $(OCAMLMKTOP) -cc '$(CXX) $(CPPFLAGS)' swig.cmo -I $(OCAMLP4WHERE) dynlink.cma camlp4o.cma swigp4.cmo -cclib "$(LIBS)" -g -ccopt -g -cclib -g -custom -o $(RUNME)_top $(INTERFACE:%.i=%.cmo) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS)
+
+ocaml_dynamic_cpp: $(SRCDIR_SRCS)
+	$(SWIG) -ocaml -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+	cp $(ICXXSRCS) $(ICXXSRCS:%.cxx=%.c)
+	$(OCC) -cc '$(CXX) $(CPPFLAGS) $(CXXFLAGS)' -g -c -ccopt -g -ccopt "-xc++ $(INCLUDES)" $(ICXXSRCS:%.cxx=%.c) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) -ccopt -fPIC
+	$(CXXSHARED) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -o $(INTERFACE:%.i=%@SO@) $(INTERFACE:%.i=%_wrap.@OBJEXT@) $(OBJS) $(CPP_DLLIBS) $(LIBS)
+	$(OCAMLDLGEN) $(INTERFACE:%.i=%.ml) $(INTERFACE:%.i=%@SO@) > $(INTERFACE:%.i=%_dynamic.ml)
+	mv $(INTERFACE:%.i=%_dynamic.ml) $(INTERFACE:%.i=%.ml)
+	rm $(INTERFACE:%.i=%.mli)
+	$(OCAMLFIND) $(OCC) -g -c -package dl $(INTERFACE:%.i=%.ml)
+	test -z "$(PROGFILE)" || $(OCC_WITH_PP) -o $(PROGFILE:%.ml=%) $(OCAMLPP) -c $(SRCDIR)$(PROGFILE)
+	$(NOLINK) || $(OCAMLFIND) swig.cmo $(OCC) -cclib -export-dynamic -g -ccopt -g -cclib -g -custom -o $(RUNME) -package dl -linkpkg $(INTERFACE:%.i=%.cmo) $(PROGFILE:%.ml=%.cmo) -cc '$(CXX)'
 
 # -----------------------------------------------------------------
-# Run CFFI example
+# Run ocaml example
 # -----------------------------------------------------------------
 
-cffi_run:
-	$(RUNTOOL) $(CFFI) -batch -s $(CFFI_SCRIPT) $(RUNPIPE)
+ocaml_run:
+	$(RUNTOOL) ./$(RUNME) $(RUNPIPE)
 
 # -----------------------------------------------------------------
 # Version display
 # -----------------------------------------------------------------
 
-cffi_version:
-	$(CFFI) --version
+ocaml_version:
+	$(OCC) -version
 
 # -----------------------------------------------------------------
-# Cleaning the CFFI examples
+# Cleaning the Ocaml examples
 # -----------------------------------------------------------------
 
-cffi_clean:
-	rm -f *_wrap* *~ .~*
+ocaml_clean:
+	rm -f *_wrap* *~ .~* *.cmo *.cmi *.mli $(TARGET).ml $(RUNME) $(RUNME)_top swig.ml swigp4.ml
+	rm -f core @EXTRA_CLEAN@
+	rm -f *.@OBJEXT@ *@SO@
+	rm -rf ./localtmp
+
+##################################################################
+#####                       OCTAVE                          ######
+##################################################################
+
+# Make sure these locate your Octave installation
+OCTAVE        = @OCTAVE@
+OCTAVE_CXX    = $(DEFS) @OCTAVE_CPPFLAGS@ @OCTAVE_CXXFLAGS@
+
+# Extra Octave specific dynamic linking options
+OCTAVE_DLNK   = @OCTAVE_LDFLAGS@
+OCTAVE_SO     = @OCTAVE_SO@
+
+OCTAVE_SCRIPT = $(SRCDIR)$(RUNME).m
+
+# ----------------------------------------------------------------
+# Pre-compile Octave headers, if supported
+# ----------------------------------------------------------------
+
+ifeq (yes,$(PCHSUPPORT))
+
+octave_precompile_headers:
+	echo "precompiling $(OCTHEADERS)"
+	cp -f $(OCTHEADERSSRC) $(OCTHEADERS)
+	if $(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(INCLUDES) $(OCTAVE_CXX) $(OCTHEADERS); then \
+		: ; \
+	else \
+		rm -f $(OCTHEADERSGCH); \
+		exit 1; \
+	fi
+
+else
+
+octave_precompile_headers:
+	echo "precompiling Octave headers not supported"; exit 1
+
+endif
+
+# ----------------------------------------------------------------
+# Build a C dynamically loadable module
+# Note: Octave requires C++ compiler when compiling C wrappers
+# ----------------------------------------------------------------
+
+octave: $(SRCDIR_SRCS)
+	$(SWIG) -octave $(SWIGOCTHDROPT) $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+	$(CXX) -g -c $(IOCTHEADERS) $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
+	$(CC) -g -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CSRCS) $(INCLUDES)
+	$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(OCTAVE_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(OCTAVE_SO)
+
+# -----------------------------------------------------------------
+# Build a C++ dynamically loadable module
+# -----------------------------------------------------------------
+
+octave_cpp: $(SRCDIR_SRCS)
+	$(SWIG) -c++ -octave $(SWIGOCTHDROPT) $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+	$(CXX) -g -c $(IOCTHEADERS) $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(OCTAVE_CXX)
+	$(CXXSHARED) -g $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(OCTAVE_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(OCTAVE_SO)
+
+# -----------------------------------------------------------------
+# Running an Octave example
+# -----------------------------------------------------------------
+
+octave_run:
+	env OCTAVE_PATH= OCTAVE_HISTFILE=/dev/null $(RUNTOOL) $(OCTAVE) $(OCTAVE_SCRIPT) $(RUNPIPE)
+
+# -----------------------------------------------------------------
+# Version display
+# -----------------------------------------------------------------
+
+octave_version:
+	$(OCTAVE) --version | head -n 1
+
+# -----------------------------------------------------------------
+# Cleaning the Octave examples
+# -----------------------------------------------------------------
+
+octave_clean:
+	rm -rf __pycache__
+	rm -f *_wrap* *~ .~* myoctave@EXEEXT@ *.pyc
+	rm -f core @EXTRA_CLEAN@
+	rm -f *.@OBJEXT@ *@SO@ *$(OCTAVE_SO)
+	rm -f $(OCTHEADERS) $(OCTHEADERSGCH)
+
+##################################################################
+#####                       PERL 5                          ######
+##################################################################
+
+# You need to set this variable to the Perl5 directory containing the
+# files "perl.h", "EXTERN.h" and "XSUB.h".   With Perl5.003, it's
+# usually something like /usr/local/lib/perl5/arch-osname/5.003/CORE.
+
+PERL5_INCLUDE= @PERL5EXT@
+
+# Extra Perl specific dynamic linking options
+PERL5_DLNK   = @PERL5DYNAMICLINKING@
+PERL5_CCFLAGS = @PERL5CCFLAGS@
+PERL5_CCDLFLAGS = @PERL5CCDLFLAGS@
+PERL5_CCCDLFLAGS = @PERL5CCCDLFLAGS@
+PERL5_LDFLAGS = @PERL5LDFLAGS@
+PERL = @PERL@
+PERL5_LIB = -L$(PERL5_INCLUDE) -l@PERL5LIB@ @LIBS@ $(SYSLIBS)
+PERL5_SCRIPT = $(SRCDIR)$(RUNME).pl
+
+# ----------------------------------------------------------------
+# Build a Perl5 dynamically loadable module (C)
+# ----------------------------------------------------------------
+
+perl5: $(SRCDIR_SRCS)
+	$(SWIG) -perl5 $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+	$(CC) -c -Dbool=char $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(PERL5_CCFLAGS) $(PERL5_CCCDLFLAGS) -I$(PERL5_INCLUDE)
+	$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(PERL5_CCDLFLAGS) $(OBJS) $(IOBJS) $(PERL5_LDFLAGS) $(PERL5_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
+
+# ----------------------------------------------------------------
+# Build a Perl5 dynamically loadable module (C++)
+# ----------------------------------------------------------------
+
+perl5_cpp: $(SRCDIR_SRCS)
+	$(SWIG) -perl5 -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+	$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(PERL5_CCFLAGS) $(PERL5_CCCDLFLAGS) -I$(PERL5_INCLUDE)
+	$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(PERL5_CCDLFLAGS) $(OBJS) $(IOBJS) $(PERL5_LDFLAGS) $(PERL5_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(SO)
+
+# ----------------------------------------------------------------
+# Build a module from existing XS C source code.   (ie. from xsubpp).
+# ----------------------------------------------------------------
+perl5_xs: $(SRCDIR_SRCS)
+	$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(INCLUDES) -I$(PERL5_INCLUDE)
+	$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) -o $(TARGET)$(SO)
+
+# ----------------------------------------------------------------
+# Build a statically linked Perl5 executable
+# ----------------------------------------------------------------
+
+perl5_static: $(SRCDIR_SRCS)
+	$(SWIG) -perl5 -static -lperlmain.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+	$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -Dbool=char $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) -I$(PERL5_INCLUDE) $(PERL5_LIB) $(LIBS) -o $(TARGET)
+
+perl5_static_cpp: $(SRCDIR_SRCS)
+	$(SWIG) -perl5 -c++ -static -lperlmain.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+	$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) -I$(PERL5_INCLUDE) $(PERL5_LIB) $(LIBS) -o $(TARGET)
+
+# -----------------------------------------------------------------
+# Running a Perl5 example
+# -----------------------------------------------------------------
+
+perl5_run:
+	$(RUNTOOL) $(PERL) -I. $(PERL5_SCRIPT) $(RUNPIPE)
+
+# -----------------------------------------------------------------
+# Version display
+# -----------------------------------------------------------------
+
+perl5_version:
+	$(PERL) -v | grep "This is"
+
+# -----------------------------------------------------------------
+# Cleaning the Perl5 examples
+# -----------------------------------------------------------------
+
+perl5_clean:
+	rm -f *_wrap* *~ .~* myperl@EXEEXT@ *.pm
 	rm -f core @EXTRA_CLEAN@
 	rm -f *.@OBJEXT@ *@SO@
 
 ##################################################################
-#####                      R                                ######
+#####                       PHP                             ######
+##################################################################
+
+PHP         = @PHP@
+PHP_INCLUDE = @PHPINC@
+PHP_SO      = @PHP_SO@
+PHP_SCRIPT  = $(SRCDIR)$(RUNME).php
+PHP_EXTENSION = example$(PHP_SO)
+
+# -------------------------------------------------------------------
+# Build a PHP dynamically loadable module (C)
+# -------------------------------------------------------------------
+
+php: $(SRCDIR_SRCS)
+	$(SWIG) -php $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+	$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(PHP_INCLUDE)
+	$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(PHP_SO)
+
+# --------------------------------------------------------------------
+# Build a PHP dynamically loadable module (C++)
+# --------------------------------------------------------------------
+
+php_cpp: $(SRCDIR_SRCS)
+	$(SWIG) -php -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+	$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(PHP_INCLUDE)
+	$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(PHP_SO)
+
+# -----------------------------------------------------------------
+# Running a PHP example
+# -----------------------------------------------------------------
+
+php_run:
+	$(RUNTOOL) $(PHP) -n -d extension_dir=. -d extension=$(PHP_EXTENSION) -d display_errors=stderr -r 'set_error_handler(function($$n,$$s,$$f,$$l){if($$f!==Null){print$$f;if($$l!==Null)print":$$l";print": ";}print"$$s\n";exit(1);});if(strlen($$argv[1]))include($$argv[1]);' '$(PHP_SCRIPT)' $(RUNPIPE)
+
+php_run_multi:
+	$(RUNTOOL) $(PHP) -n -d extension_dir=. `while read e ; do echo ' -d extension=$(TARGETPREFIX)'"$$e"'@PHP_SO@' ; done < $(PHP_EXTENSION_LIST)` -d display_errors=stderr -r 'set_error_handler(function($$n,$$s,$$f,$$l){if($$f!==Null){print$$f;if($$l!==Null)print":$$l";print": ";}print"$$s\n";exit(1);});if(strlen($$argv[1]))include($$argv[1]);' '$(PHP_SCRIPT)' $(RUNPIPE)
+
+# -----------------------------------------------------------------
+# Version display
+# -----------------------------------------------------------------
+
+php_version:
+	$(PHP) -v | head -n 1
+
+# -----------------------------------------------------------------
+# Cleaning the PHP examples
+# -----------------------------------------------------------------
+
+php_clean:
+	rm -f *_wrap* *~ .~* example.php php_example.h
+	rm -f core @EXTRA_CLEAN@
+	rm -f *.@OBJEXT@ *$(PHP_SO)
+
+##################################################################
+#####                       PYTHON                          ######
+##################################################################
+
+PYTHON_FLAGS =
+
+# Make sure these locate your Python installation
+ifneq (,$(PY2))
+  PYTHON_INCLUDE= $(DEFS) @PYINCLUDE@
+  PYTHON_LIB    = @PYLIB@
+  PYTHON        = @PYTHON@ $(PYTHON_FLAGS)
+else
+  PYTHON_INCLUDE= $(DEFS) @PY3INCLUDE@
+  PYTHON_LIB    = @PY3LIB@
+  PYTHON        = @PYTHON3@ $(PYTHON_FLAGS)
+endif
+
+# Extra Python specific linking options
+ifneq (,$(PY2))
+  PYTHON_DLNK   = @PYTHONDYNAMICLINKING@
+  PYTHON_LINK   = @PYLINK@
+else
+  PYTHON_DLNK   = @PYTHON3DYNAMICLINKING@
+  PYTHON_LINK   = @PY3LINK@
+endif
+PYTHON_SO     = @PYTHON_SO@
+
+PYCODESTYLE       = @PYCODESTYLE@
+PYCODESTYLE_FLAGS = --ignore=E252,E30,E402,E501,E731,W291,W391
+
+# ----------------------------------------------------------------
+# Build a C dynamically loadable module
+# ----------------------------------------------------------------
+
+python: $(SRCDIR_SRCS)
+	$(SWIG) -python $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+	$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) $(PYTHON_INCLUDE)
+	$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO)
+
+# -----------------------------------------------------------------
+# Build a C++ dynamically loadable module
+# -----------------------------------------------------------------
+
+python_cpp: $(SRCDIR_SRCS)
+	$(SWIG) -python -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+	$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(PYTHON_INCLUDE)
+	$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(PYTHON_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)_$(TARGET)$(PYTHON_SO)
+
+# -----------------------------------------------------------------
+# Build statically linked Python interpreter
+#
+# These should only be used in conjunction with the %include embed.i
+# library file
+# -----------------------------------------------------------------
+
+#TKINTER = -L/usr/X11R6.3/lib -L/usr/local/compat/lib -ltk4.0 -ltcl7.4 -lX11
+TKINTER =
+PYTHON_LIBOPTS = $(PYTHON_LINK) @LIBS@ $(TKINTER) $(SYSLIBS)
+
+python_static: $(SRCDIR_SRCS)
+	$(SWIG) -python -lembed.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+	$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) @LINKFORSHARED@ $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) \
+	$(PYTHON_INCLUDE) $(LIBS) -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET)
+
+python_static_cpp: $(SRCDIR_SRCS)
+	$(SWIG) -python -c++ -lembed.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+	$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) \
+	$(PYTHON_INCLUDE) $(LIBS)  -L$(PYTHON_LIB) $(PYTHON_LIBOPTS) -o $(TARGET)
+
+# -----------------------------------------------------------------
+# Running a Python example
+# -----------------------------------------------------------------
+
+PYSCRIPT = $(RUNME).py
+
+python_run: $(PYSCRIPT)
+ifneq (,$(PYCODESTYLE))
+	$(COMPILETOOL) $(PYCODESTYLE) $(PYCODESTYLE_FLAGS) $(PYSCRIPT)
+endif
+	env PYTHONPATH=$$PWD $(RUNTOOL) $(PYTHON) $(PYSCRIPT) $(RUNPIPE)
+
+ifneq (,$(SRCDIR))
+$(RUNME).py: $(SRCDIR)$(RUNME).py
+	cp $< $@
+endif
+
+# -----------------------------------------------------------------
+# Version display
+# -----------------------------------------------------------------
+
+python_version:
+	$(PYTHON) -V
+
+# -----------------------------------------------------------------
+# Cleaning the python examples
+# -----------------------------------------------------------------
+
+python_clean:
+	rm -rf __pycache__
+	rm -f *_wrap* *~ .~* mypython@EXEEXT@ *.pyc
+	rm -f core @EXTRA_CLEAN@
+	rm -f *.@OBJEXT@ *@SO@ *$(PYTHON_SO)
+	rm -f $(TARGET).py
+	case "x$(SRCDIR)" in x|x./);; *) rm -f $(RUNME).py;; esac
+
+##################################################################
+#####                       R                               ######
 ##################################################################
 
 R = R
@@ -1375,12 +1409,86 @@
 	rm -f $(RRSRC) $(RUNME).Rout .RData
 
 ##################################################################
-#####                 SCILAB                                ######
+#####                       RUBY                            ######
+##################################################################
+
+# Make sure these locate your Ruby installation
+RUBY_CFLAGS= @RUBYCCDLFLAGS@ $(DEFS)
+RUBY_INCLUDE= @RUBYINCLUDE@
+RUBY_LIB     = @RUBYLIB@
+RUBY_DLNK = @RUBYDYNAMICLINKING@
+RUBY_LIBOPTS = @RUBYLINK@ @LIBS@ $(SYSLIBS)
+RUBY_SO = @RUBYSO@
+RUBY = @RUBY@
+RUBY_SCRIPT = $(SRCDIR)$(RUNME).rb
+
+
+# ----------------------------------------------------------------
+# Build a C dynamically loadable module
+# ----------------------------------------------------------------
+
+ruby: $(SRCDIR_SRCS)
+	$(SWIG) -ruby $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+	$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(RUBY_CFLAGS) $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) $(RUBY_INCLUDE)
+	$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(RUBY_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(RUBY_SO)
+
+# -----------------------------------------------------------------
+# Build a C++ dynamically loadable module
+# -----------------------------------------------------------------
+
+ruby_cpp: $(SRCDIR_SRCS)
+	$(SWIG) -c++ -ruby $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+	$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(RUBY_CFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) $(RUBY_INCLUDE)
+	$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(RUBY_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(RUBY_SO)
+
+# -----------------------------------------------------------------
+# Build statically linked Ruby interpreter
+#
+# These should only be used in conjunction with the %include embed.i
+# library file
+# -----------------------------------------------------------------
+
+ruby_static: $(SRCDIR_SRCS)
+	$(SWIG) -ruby -lembed.i $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
+	$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(RUBY_CFLAGS) @LINKFORSHARED@ $(ISRCS) $(SRCDIR_SRCS) $(INCLUDES) \
+	$(RUBY_INCLUDE) $(LIBS) -L$(RUBY_LIB) $(RUBY_LIBOPTS) -o $(TARGET)
+
+ruby_cpp_static: $(SRCDIR_SRCS)
+	$(SWIG) -c++ -ruby -lembed.i $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
+	$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(RUBY_CFLAGS) $(ICXXSRCS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(INCLUDES) \
+	$(RUBY_INCLUDE) $(LIBS)  -L$(RUBY_LIB) $(RUBY_LIBOPTS) -o $(TARGET)
+
+# -----------------------------------------------------------------
+# Run Ruby example
+# -----------------------------------------------------------------
+
+ruby_run:
+	$(RUNTOOL) $(RUBY) $(RUBYFLAGS) -I. $(RUBY_SCRIPT) $(RUNPIPE)
+
+# -----------------------------------------------------------------
+# Version display
+# -----------------------------------------------------------------
+
+ruby_version:
+	$(RUBY) -v
+
+# -----------------------------------------------------------------
+# Cleaning the Ruby examples
+# -----------------------------------------------------------------
+
+ruby_clean:
+	rm -f *_wrap* *~ .~* myruby@EXEEXT@
+	rm -f core @EXTRA_CLEAN@
+	rm -f *.@OBJEXT@ *$(RUBY_SO)
+
+##################################################################
+#####                       SCILAB                          ######
 ##################################################################
 
 SCILAB = @SCILAB@
 SCILAB_INC= @SCILABINCLUDE@
 SCILAB_OPT = @SCILABOPT@
+SCILAB_VERSION = @SCILAB_VERSION@
 SCILAB_LIBPREFIX = lib
 
 # ----------------------------------------------------------------
@@ -1413,7 +1521,7 @@
 # -----------------------------------------------------------------
 
 scilab_version:
-	echo `$(SCILAB) -version | head -1`
+	echo `$(SCILAB) -nwni -version | head -1`
 
 # -----------------------------------------------------------------
 # Cleaning the scilab examples
@@ -1426,228 +1534,76 @@
 	rm -f *.sce
 
 ##################################################################
-#####                        Go                             ######
+#####                       TCL                             ######
 ##################################################################
 
-# TODO: The Go make targets need simplifying to use configure time
-# configuration or to use Make's ifeq rather than using lots of
-# runtime shell code. The output will then be a lot less verbose.
+# Set these to your local copy of Tcl
 
-GO = @GO@
-GOGCC = @GOGCC@
-GCCGO = @GCCGO@
-GOOPT = @GOOPT@
-GCCGOOPT = @GCCGOOPT@
-GOVERSIONOPTION = @GOVERSIONOPTION@
+TCLSH       = tclsh
+TCL_INCLUDE = @TCLINCLUDE@
+TCL_LIB     = @TCLLIB@
+TCL_OPTS    = @LIBS@
+TK_OPTS     = -ltk -ltcl @LIBS@
 
-GOSWIGARG = `if $(GOGCC) ; then echo -gccgo; fi`
+# Extra Tcl specific dynamic linking options
+TCL_DLNK   = @TCLDYNAMICLINKING@
+TCL_SO     = @TCL_SO@
+TCLLDSHARED = @TCLLDSHARED@
+TCLCXXSHARED = @TCLCXXSHARED@
+TCL_SCRIPT = $(SRCDIR)$(RUNME).tcl
+TCL_LINK   = @TCLLINK@
 
-GOSRCS = $(INTERFACE:.i=.go)
-GOCSRCS = $(INTERFACE:.i=_gc.c)
+# -----------------------------------------------------------
+# Build a new version of the tclsh shell
+# -----------------------------------------------------------
 
-GOPACKAGE = $(notdir $(INTERFACE:.i=.a))
+tclsh: $(SRCDIR_SRCS)
+	$(SWIG) -tcl8 $(SWIGOPT) $(TCL_SWIGOPTS) -ltclsh.i -o $(ISRCS) $(INTERFACEPATH)
+	$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(TCL_INCLUDE) \
+	$(TCL_LIB)  $(TCL_OPTS) $(LIBS) $(SYSLIBS) -o $(TARGET)
 
-GOPATHPARENTDIR = gopath/$(GOMOD)/src
-GOPATHDIR = $(GOPATHPARENTDIR)/$(INTERFACE:.i=)
+tclsh_cpp: $(SRCDIR_SRCS)
+	$(SWIG) -tcl8 -c++ $(SWIGOPT) $(TCL_SWIGOPTS) -ltclsh.i -o $(ICXXSRCS) $(INTERFACEPATH)
+	$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(TCL_INCLUDE) \
+	$(TCL_LIB) $(TCL_OPTS) $(LIBS) $(SYSLIBS) -o $(TARGET)
 
-# ----------------------------------------------------------------
-# Build a Go module (C)
-# ----------------------------------------------------------------
+# -----------------------------------------------------------
+# Build a Tcl dynamic loadable module (you might need to tweak this)
+# -----------------------------------------------------------
 
-$(GOPATHPARENTDIR)/go.mod:
-	@mkdir gopath 2>/dev/null || true
-	@mkdir gopath/$(GOMOD) 2>/dev/null || true
-	@mkdir gopath/$(GOMOD)/src 2>/dev/null || true
-	@mkdir $(GOPATHDIR) 2>/dev/null || true
-	echo "module swigtests" > $(GOPATHDIR)/go.mod
-	echo "" >> $(GOPATHDIR)/go.mod
-	echo "go 1.12" >> $(GOPATHDIR)/go.mod
-	mv -f $(GOPATHDIR)/go.mod $(GOPATHPARENTDIR)/go.mod
+tcl:  $(SRCDIR_SRCS)
+	$(SWIG) -tcl8 $(SWIGOPT) $(TCL_SWIGOPTS) -o $(ISRCS) $(INTERFACEPATH)
+	$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES) $(TCL_INCLUDE)
+	$(TCLLDSHARED) $(CFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(TCL_DLNK) $(LIBS) -o $(LIBPREFIX)$(TARGET)$(TCL_SO) $(TCL_LINK)
 
-go: $(SRCDIR_SRCS) $(GOPATHPARENTDIR)/go.mod
-	$(SWIG) -go -import-prefix swigtests $(GOOPT) $(GOSWIGARG) $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
-	@mkdir gopath 2>/dev/null || true
-	@mkdir gopath/$(GOMOD) 2>/dev/null || true
-	@mkdir gopath/$(GOMOD)/src 2>/dev/null || true
-	@mkdir $(GOPATHDIR) 2>/dev/null || true
-	rm -rf $(GOPATHDIR)/*
-	cp $(ISRCS) $(GOPATHDIR)/
-	if test -f $(IWRAP:.i=.h); then \
-	  cp $(IWRAP:.i=.h) $(GOPATHDIR)/; \
-	fi
-	if test -n "$(SRCDIR_SRCS)"; then \
-	  cp $(SRCDIR_SRCS) $(GOPATHDIR)/; \
-	fi
-	cp $(GOSRCS) $(GOPATHDIR)/
-	@if test -f $(SRCDIR)$(RUNME).go; then \
-	  mkdir gopath/$(GOMOD)/src/runme 2>/dev/null || true; \
-	  rm -f gopath/$(GOMOD)/src/runme/*; \
-	fi
-	if test -f $(SRCDIR)$(RUNME).go; then \
-	  cp $(SRCDIR)$(RUNME).go gopath/$(GOMOD)/src/runme/; \
-	fi
-	GOPATH=`pwd`/gopath/$(GOMOD); \
-	export GOPATH; \
-	CGO_CPPFLAGS="$(CPPFLAGS) $(INCLUDES) -I `cd $(SRCDIR) && pwd` -I `pwd`"; \
-	export CGO_CPPFLAGS; \
-	CGO_CFLAGS="$(CFLAGS)"; \
-	export CGO_CFLAGS; \
-	CGO_LDFLAGS="$(LDFLAGS) -lm"; \
-	export CGO_LDFLAGS; \
-	(cd $(GOPATHDIR)/ && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o $(GOPACKAGE)); \
-	if $(GOGCC); then \
-	  cp $(GOPATHDIR)/$(GOPACKAGE) $(GOPATHDIR)/$(GOPACKAGE:.a=.gox); \
-	fi; \
-	if test -f $(SRCDIR)$(RUNME).go; then \
-	  mkdir gopath/$(GOMOD)/src/swigtests 2>/dev/null || true; \
-	  mkdir gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=) 2>/dev/null || true; \
-	  cp $(GOPATHDIR)/* gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=)/; \
-	  (cd gopath/$(GOMOD)/src/runme && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o runme $(RUNME).go); \
-	  cp gopath/$(GOMOD)/src/runme/runme $(RUNME); \
-	fi
+# -----------------------------------------------------------
+# Build a Tcl dynamic loadable module for C++
+# -----------------------------------------------------------
 
-# ----------------------------------------------------------------
-# Build a Go module (C++)
-# ----------------------------------------------------------------
-
-go_cpp: $(SRCDIR_SRCS) $(GOPATHPARENTDIR)/go.mod
-	$(SWIG) -go -c++ -import-prefix swigtests $(GOOPT) $(GOSWIGARG) $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-	@mkdir gopath 2>/dev/null || true
-	@mkdir gopath/$(GOMOD) 2>/dev/null || true
-	@mkdir gopath/$(GOMOD)/src 2>/dev/null || true
-	@mkdir $(GOPATHDIR) 2>/dev/null || true
-	rm -rf $(GOPATHDIR)/*
-	cp $(ICXXSRCS) $(GOPATHDIR)/
-	if test -f $(IWRAP:.i=.h); then \
-	  cp $(IWRAP:.i=.h) $(GOPATHDIR)/; \
-	fi
-	if test -n "$(SRCDIR_CXXSRCS)"; then \
-	  cp $(SRCDIR_CXXSRCS) $(GOPATHDIR)/; \
-	fi
-	if test -n "$(SRCDIR_SRCS)"; then \
-	  cp $(SRCDIR_SRCS) $(GOPATHDIR)/; \
-	fi
-	cp $(GOSRCS) $(GOPATHDIR)/
-	@if test -f $(SRCDIR)$(RUNME).go; then \
-	  mkdir gopath/$(GOMOD)/src/runme 2>/dev/null || true; \
-	  rm -f gopath/$(GOMOD)/src/runme/*; \
-	fi
-	if test -f $(SRCDIR)$(RUNME).go; then \
-	  cp $(SRCDIR)$(RUNME).go gopath/$(GOMOD)/src/runme/; \
-	fi
-	GOPATH=`pwd`/gopath/$(GOMOD); \
-	export GOPATH; \
-	CGO_CPPFLAGS="$(CPPFLAGS) $(INCLUDES) -I `cd $(SRCDIR) && pwd` -I `pwd`"; \
-	export CGO_CPPFLAGS; \
-	CGO_CFLAGS="$(CFLAGS)"; \
-	export CGO_CFLAGS; \
-	CGO_CXXFLAGS="$(CXXFLAGS)"; \
-	export CGO_CXXFLAGS; \
-	CGO_LDFLAGS="$(LDFLAGS) -lm"; \
-	export CGO_LDFLAGS; \
-	(cd $(GOPATHDIR) && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o $(GOPACKAGE)); \
-	if $(GOGCC); then \
-	  cp $(GOPATHDIR)/$(GOPACKAGE) $(GOPATHDIR)/$(GOPACKAGE:.a=.gox); \
-	fi; \
-	if test -f $(SRCDIR)$(RUNME).go; then \
-	  mkdir gopath/$(GOMOD)/src/swigtests 2>/dev/null || true; \
-	  mkdir gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=) 2>/dev/null || true; \
-	  cp $(GOPATHDIR)/* gopath/$(GOMOD)/src/swigtests/$(INTERFACE:.i=)/; \
-	  (cd gopath/$(GOMOD)/src/runme && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o runme $(RUNME).go); \
-	  cp gopath/$(GOMOD)/src/runme/runme $(RUNME); \
-	fi
+tcl_cpp: $(SRCDIR_SRCS)
+	$(SWIG) -tcl8 -c++ $(SWIGOPT) $(TCL_SWIGOPTS) -o $(ICXXSRCS) $(INTERFACEPATH)
+	$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES) $(TCL_INCLUDE)
+	$(TCLCXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(OBJS) $(IOBJS) $(TCL_DLNK) $(LIBS) $(CPP_DLLIBS) -o $(LIBPREFIX)$(TARGET)$(TCL_SO) $(TCL_LINK)
 
 # -----------------------------------------------------------------
-# Running Go example
+# Run Tcl example
 # -----------------------------------------------------------------
 
-go_run:
-	env $(RUNTOOL) ./$(RUNME) $(RUNPIPE)
+tcl_run:
+	$(RUNTOOL) $(TCLSH) $(TCL_SCRIPT) $(RUNPIPE)
 
 # -----------------------------------------------------------------
 # Version display
 # -----------------------------------------------------------------
 
-go_version:
-	$(GO) $(GOVERSIONOPTION)
+tcl_version:
+	echo 'puts $$tcl_version;exit 0' | $(TCLSH)
 
 # -----------------------------------------------------------------
-# Cleaning the Go examples
+# Cleaning the Tcl examples
 # -----------------------------------------------------------------
 
-go_clean:
-	rm -f *_wrap* *_gc* *.gox .~* $(RUNME) $(GOSRCS)
-	rm -rf gopath
+tcl_clean:
+	rm -f *_wrap* *~ .~* mytclsh@EXEEXT@
 	rm -f core @EXTRA_CLEAN@
-	rm -f *.@OBJEXT@ *.[568] *.a *@SO@
-
-##################################################################
-#####                         D                             ######
-##################################################################
-
-DLIBPREFIX = @DLIBPREFIX@
-
-ifeq (,$(D_VERSION))
-  D_VERSION = @DDEFAULTVERSION@
-endif
-
-ifeq (2,$(D_VERSION))
-  SWIGD = $(SWIG) -d -d2
-  DCOMPILER = @D2COMPILER@
-else
-  SWIGD = $(SWIG) -d
-  DCOMPILER = @D1COMPILER@
-endif
-
-D_RUNME = ./$(RUNME)
-
-# ----------------------------------------------------------------
-# Build a dynamically loadable D wrapper for a C module
-# ----------------------------------------------------------------
-
-d: $(SRCDIR_SRCS)
-	$(SWIGD) $(SWIGOPT) -o $(ISRCS) $(INTERFACEPATH)
-	$(CC) -c $(CCSHARED) $(CPPFLAGS) $(CFLAGS) $(DCFLAGS) $(EXTRA_CFLAGS) $(SRCDIR_SRCS) $(ISRCS) $(INCLUDES)
-	$(LDSHARED) $(CFLAGS) $(LDFLAGS) $(DCFLAGS) $(EXTRA_LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) -o $(DLIBPREFIX)$(TARGET)$(SO)
-
-# ----------------------------------------------------------------
-# Build a dynamically loadable D wrapper for a C++ module
-# ----------------------------------------------------------------
-
-d_cpp: $(SRCDIR_SRCS)
-	$(SWIGD) -c++ $(SWIGOPT) -o $(ICXXSRCS) $(INTERFACEPATH)
-	$(CXX) -c $(CCSHARED) $(CPPFLAGS) $(CXXFLAGS) $(DCFLAGS) $(EXTRA_CFLAGS) $(SRCDIR_SRCS) $(SRCDIR_CXXSRCS) $(ICXXSRCS) $(INCLUDES)
-	$(CXXSHARED) $(CXXFLAGS) $(LDFLAGS) $(DCFLAGS) $(EXTRA_LDFLAGS) $(OBJS) $(IOBJS) $(LIBS) $(CPP_DLLIBS) -o $(DLIBPREFIX)$(TARGET)$(SO)
-
-# ----------------------------------------------------------------
-# Compile D files
-# ----------------------------------------------------------------
-
-# Clear the DFLAGS environment variable for the compiler call itself
-# to work around a discrepancy in argument handling between DMD and LDC.
-d_compile: $(SRCDIR_SRCS)
-	DFLAGS="" $(COMPILETOOL) $(DCOMPILER) $(DFLAGS) $(DSRCS)
-
-# -----------------------------------------------------------------
-# Run D example
-# -----------------------------------------------------------------
-
-d_run:
-	env LD_LIBRARY_PATH=$$PWD $(RUNTOOL) $(D_RUNME) $(RUNPIPE)
-
-# -----------------------------------------------------------------
-# Version display
-# -----------------------------------------------------------------
-
-d_version:
-	# Needs improvement!
-	echo D version guess - $(D_VERSION)
-
-# -----------------------------------------------------------------
-# Clean the D examples
-# -----------------------------------------------------------------
-
-d_clean:
-	rm -f *_wrap* *~ .~* $(RUNME) $(RUNME).exe `find . -name \*.d | grep -v $(RUNME).d`
-	rm -f core @EXTRA_CLEAN@
-	rm -f *.@OBJEXT@ *@SO@
+	rm -f *.@OBJEXT@ *$(TCL_SO)
diff --git a/Examples/chicken/README b/Examples/chicken/README
deleted file mode 100644
index d4f91ba..0000000
--- a/Examples/chicken/README
+++ /dev/null
@@ -1,12 +0,0 @@
-This directory contains examples for CHICKEN.
-
-class       -- illustrates the proxy class C++ interface
-constants   -- handling #define and %constant literals
-egg         -- examples of building chicken extension libraries
-multimap    -- typemaps with multiple sub-types
-overload    -- C++ function overloading
-simple      -- the simple example from the user manual
-zlib        -- a wrapping of the zlib compression library
-
-You should be able to run make in each of the examples.  By default, a shared
-library will be built.  Run make check to execute the test.
diff --git a/Examples/chicken/check.list b/Examples/chicken/check.list
deleted file mode 100644
index 9ea022b..0000000
--- a/Examples/chicken/check.list
+++ /dev/null
@@ -1,6 +0,0 @@
-# see top-level Makefile.in
-class
-constants
-multimap
-overload
-simple
diff --git a/Examples/chicken/class/Makefile b/Examples/chicken/class/Makefile
deleted file mode 100644
index ea2d8b6..0000000
--- a/Examples/chicken/class/Makefile
+++ /dev/null
@@ -1,40 +0,0 @@
-TOP        = ../..
-SWIGEXE    = $(TOP)/../swig
-SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-INTERFACE  = example.i
-SRCS       =
-CXXSRCS    = example.cxx
-TARGET     = class
-INCLUDE    =
-SWIGOPT    =
-VARIANT    =
-
-# uncomment the following lines to build a static exe (only pick one of the CHICKEN_MAIN lines)
-#CHICKEN_MAIN = runme-lowlevel.scm
-#CHICKEN_MAIN = runme-tinyclos.scm
-#VARIANT    = _static
-
-check: build
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CHICKEN_SCRIPT='runme-lowlevel.scm' chicken_run
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CHICKEN_SCRIPT='runme-tinyclos.scm' chicken_run
-
-build: $(TARGET) $(TARGET)_proxy
-
-$(TARGET): $(INTERFACE) $(SRCS)
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
-	SRCS='$(SRCS)' CXXSRCS='$(CXXSRCS)' CHICKEN_MAIN='$(CHICKEN_MAIN)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	INCLUDE='$(INCLUDE)' SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' \
-	INTERFACE='$(INTERFACE)' CHICKENOPTS='$(CHICKENOPTS)' chicken$(VARIANT)_cpp
-
-$(TARGET)_proxy: $(INTERFACE) $(SRCS)
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
-	SRCS='$(SRCS)' CXXSRCS='$(CXXSRCS)' CHICKEN_MAIN='$(CHICKEN_MAIN)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	INCLUDE='$(INCLUDE)' SWIGOPT='$(SWIGOPT) -proxy' TARGET='$(TARGET)_proxy' \
-	INTERFACE='$(INTERFACE)' CHICKENOPTS='$(CHICKENOPTS)' chicken$(VARIANT)_cpp
-
-clean:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' chicken_clean
-	rm -f example.scm
-	rm -f $(TARGET)
diff --git a/Examples/chicken/class/example.cxx b/Examples/chicken/class/example.cxx
deleted file mode 100644
index 0463045..0000000
--- a/Examples/chicken/class/example.cxx
+++ /dev/null
@@ -1,28 +0,0 @@
-/* File : example.cxx */
-
-#include "example.h"
-#define M_PI 3.14159265358979323846
-
-/* Move the shape to a new location */
-void Shape::move(double dx, double dy) {
-  x += dx;
-  y += dy;
-}
-
-int Shape::nshapes = 0;
-
-double Circle::area() {
-  return M_PI*radius*radius;
-}
-
-double Circle::perimeter() {
-  return 2*M_PI*radius;
-}
-
-double Square::area() {
-  return width*width;
-}
-
-double Square::perimeter() {
-  return 4*width;
-}
diff --git a/Examples/chicken/class/example.h b/Examples/chicken/class/example.h
deleted file mode 100644
index 5bad316..0000000
--- a/Examples/chicken/class/example.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* File : example.h */
-
-class Shape {
-public:
-  Shape() {
-    nshapes++;
-  }
-  virtual ~Shape() {
-    nshapes--;
-  }
-  double  x, y;
-  void    move(double dx, double dy);
-  virtual double area() = 0;
-  virtual double perimeter() = 0;
-  static  int nshapes;
-
-  enum SomeEnum {
-    First = 0,
-    Second,
-    Third,
-    Last = 1000
-  };
-};
-
-class Circle : public Shape {
-private:
-  double radius;
-public:
-  Circle(double r) : radius(r) { }
-  virtual double area();
-  virtual double perimeter();
-};
-
-class Square : public Shape {
-private:
-  double width;
-public:
-  Square(double w) : width(w) { }
-  virtual double area();
-  virtual double perimeter();
-};
diff --git a/Examples/chicken/class/example.i b/Examples/chicken/class/example.i
deleted file mode 100644
index fbdf724..0000000
--- a/Examples/chicken/class/example.i
+++ /dev/null
@@ -1,9 +0,0 @@
-/* File : example.i */
-%module example
-
-%{
-#include "example.h"
-%}
-
-/* Let's just grab the original header file here */
-%include "example.h"
diff --git a/Examples/chicken/class/runme-lowlevel.scm b/Examples/chicken/class/runme-lowlevel.scm
deleted file mode 100644
index 7c59c0a..0000000
--- a/Examples/chicken/class/runme-lowlevel.scm
+++ /dev/null
@@ -1,76 +0,0 @@
-;; This file illustrates the low-level C++ interface generated
-;; by SWIG.
-
-(load-library 'example "class.so")
-(declare (uses example))
-
-;; ----- Object creation -----
-
-(display "Creating some objects:\n")
-(define c (new-Circle 10.0))
-(display "    Created circle ")
-(display c)
-(display "\n")
-(define s (new-Square 10.0))
-(display "    Created square ")
-(display s)
-(display "\n")
-
-;; ----- Access a static member -----
-
-(display "\nA total of ")
-(display (Shape-nshapes))
-(display " shapes were created\n")
-
-;; ----- Member data access -----
-
-;; Set the location of the object
-
-(Shape-x-set c 20.0)
-(Shape-y-set c 30.0)
-
-(Shape-x-set s -10.0)
-(Shape-y-set s 5.0)
-
-(display "\nHere is their current position:\n")
-(display "    Circle = (")
-(display (Shape-x-get c))
-(display ", ")
-(display (Shape-y-get c))
-(display ")\n")
-(display "    Square = (")
-(display (Shape-x-get s))
-(display ", ")
-(display (Shape-y-get s))
-(display ")\n")
-
-;; ----- Call some methods -----
-
-(display "\nHere are some properties of the shapes:\n")
-(let
-    ((disp (lambda (o)
-             (display "   ")
-             (display o)
-             (display "\n")
-             (display "        area      = ")
-             (display (Shape-area o))
-             (display "\n")
-             (display "        perimeter = ")
-             (display (Shape-perimeter o))
-             (display "\n"))))
-  (disp c)
-  (disp s))
-
-(display "\nGuess I'll clean up now\n")
-
-;; Note: this invokes the virtual destructor
-(set! c #f)
-(set! s #f)
-(gc #t)
-
-(set! s 3)
-(display (Shape-nshapes))
-(display " shapes remain\n")
-(display "Goodbye\n")
-
-(exit)
diff --git a/Examples/chicken/class/runme-tinyclos.scm b/Examples/chicken/class/runme-tinyclos.scm
deleted file mode 100644
index 5ba1d6a..0000000
--- a/Examples/chicken/class/runme-tinyclos.scm
+++ /dev/null
@@ -1,76 +0,0 @@
-;; This file illustrates the proxy C++ interface generated
-;; by SWIG.
-
-(load-library 'example "class_proxy.so")
-(declare (uses example))
-(declare (uses tinyclos))
-
-;; ----- Object creation -----
-
-(display "Creating some objects:\n")
-(define c (make <Circle> 10.0))
-(display "    Created circle ")
-(display c)
-(display "\n")
-(define s (make <Square> 10.0))
-(display "    Created square ")
-(display s)
-(display "\n")
-
-;; ----- Access a static member -----
-
-(display "\nA total of ")
-(display (Shape-nshapes))
-(display " shapes were created\n")
-
-;; ----- Member data access -----
-
-;; Set the location of the object
-
-(slot-set! c 'x 20.0)
-(slot-set! c 'y 30.0)
-
-(slot-set! s 'x -10.0)
-(slot-set! s 'y 5.0)
-
-(display "\nHere is their current position:\n")
-(display "    Circle = (")
-(display (slot-ref c 'x))
-(display ", ")
-(display (slot-ref c 'y))
-(display ")\n")
-(display "    Square = (")
-(display (slot-ref s 'x))
-(display ", ")
-(display (slot-ref s 'y))
-(display ")\n")
-
-;; ----- Call some methods -----
-
-(display "\nHere are some properties of the shapes:\n")
-(let
-    ((disp (lambda (o)
-             (display "   ")
-             (display o)
-             (display "\n")
-             (display "        area      = ")
-             (display (area o))
-             (display "\n")
-             (display "        perimeter = ")
-             (display (perimeter o))
-             (display "\n"))))
-  (disp c)
-  (disp s))
-
-(display "\nGuess I'll clean up now\n")
-
-;; Note: Invoke the virtual destructors by forcing garbage collection
-(set! c 77)
-(set! s 88)
-(gc #t)
-
-(display (Shape-nshapes))
-(display " shapes remain\n")
-(display "Goodbye\n")
-
-(exit)
diff --git a/Examples/chicken/constants/Makefile b/Examples/chicken/constants/Makefile
deleted file mode 100644
index 2fdde0a..0000000
--- a/Examples/chicken/constants/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-TOP        = ../..
-SWIGEXE    = $(TOP)/../swig
-SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-INTERFACE  = example.i
-SRCS       =
-CXXSRCS    =
-TARGET     = constants
-INCLUDE    =
-SWIGOPT    =
-VARIANT    =
-
-# uncomment the following two lines to build a static exe
-#CHICKEN_MAIN = runme.scm
-#VARIANT      = _static
-
-check: build
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' chicken_run
-
-build: $(TARGET)
-
-$(TARGET): $(INTERFACE) $(SRCS)
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
-	SRCS='$(SRCS)' CXXSRCS='$(CXXSRCS)' CHICKEN_MAIN='$(CHICKEN_MAIN)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	INCLUDE='$(INCLUDE)' SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' \
-	INTERFACE='$(INTERFACE)' CHICKENOPTS='$(CHICKENOPTS)' chicken$(VARIANT)
-
-clean:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' chicken_clean
-	rm -f example.scm
-	rm -f $(TARGET)
diff --git a/Examples/chicken/constants/example.i b/Examples/chicken/constants/example.i
deleted file mode 100644
index 0995c19..0000000
--- a/Examples/chicken/constants/example.i
+++ /dev/null
@@ -1,27 +0,0 @@
-/* File : example.i */
-%module example
-
-/* A few preprocessor macros */
-
-#define    ICONST      42
-#define    FCONST      2.1828
-#define    CCONST      'x'
-#define    CCONST2     '\n'
-#define    SCONST      "Hello World"
-#define    SCONST2     "\"Hello World\""
-
-/* This should work just fine */
-#define    EXPR        ICONST + 3*(FCONST)
-
-/* This shouldn't do anything */
-#define    EXTERN      extern
-
-/* Neither should this (BAR isn't defined) */
-#define    FOO         (ICONST + BAR)
-
-/* The following directives also produce constants.  Remember that
-   CHICKEN is normally case-insensitive, so don't rely on differing
-   case to differentiate variable names */
-
-%constant int iconstX = 37;
-%constant double fconstX = 3.14;
diff --git a/Examples/chicken/constants/runme.scm b/Examples/chicken/constants/runme.scm
deleted file mode 100644
index 1b10b26..0000000
--- a/Examples/chicken/constants/runme.scm
+++ /dev/null
@@ -1,16 +0,0 @@
-;; feel free to uncomment and comment sections
-
-(load-library 'example "./constants.so")
-
-(display "starting test ... you will see 'finished' if successful.\n")
-(or (= (ICONST) 42) (exit 1))
-(or (< (abs (- (FCONST) 2.1828)) 0.00001) (exit 1))
-(or (char=? (CCONST) #\x) (exit 1))
-(or (char=? (CCONST2) #\newline) (exit 1))
-(or (string=? (SCONST) "Hello World") (exit 1))
-(or (string=? (SCONST2) "\"Hello World\"") (exit 1))
-(or (< (abs (- (EXPR) (+ (ICONST) (* 3 (FCONST))))) 0.00001) (exit 1))
-(or (= (iconstX) 37) (exit 1))
-(or (< (abs (- (fconstX) 3.14)) 0.00001) (exit 1))
-(display "finished test.\n")
-(exit 0)
diff --git a/Examples/chicken/egg/Makefile b/Examples/chicken/egg/Makefile
deleted file mode 100644
index 0137dc0..0000000
--- a/Examples/chicken/egg/Makefile
+++ /dev/null
@@ -1,41 +0,0 @@
-TOP        = ../..
-SWIGEXE    = $(TOP)/../swig
-SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-
-check: build
-	cd eggs/install && csi ../../test.scm
-
-build: single multi
-
-# This creates an egg which contains only the single module.  Any additional implementation files
-# that implement the interface being wrapped should also be added to this egg
-single: single_wrap.cxx
-	mkdir -p eggs
-	tar czf eggs/single.egg single.setup single.scm single_wrap.cxx
-	rm -f single.scm single_wrap.cxx
-
-# compile the single module with -nounit
-single_wrap.cxx: single.i
-	$(SWIGEXE) -chicken -c++ -proxy -nounit single.i
-
-# Now build both mod1 and mod2 into a single egg
-multi: mod1_wrap.cxx mod2_wrap.cxx
-	mkdir -p eggs
-	tar czf eggs/multi.egg multi.setup multi_init.scm mod1.scm mod1_wrap.cxx mod2.scm mod2_wrap.cxx
-	rm -f mod1.scm mod1_wrap.cxx mod2.scm mod2_wrap.cxx
-
-mod1_wrap.cxx: mod1.i
-	$(SWIGEXE) -chicken -c++ -proxy mod1.i
-
-mod2_wrap.cxx: mod2.i
-	$(SWIGEXE) -chicken -c++ -proxy mod2.i
-
-clean:
-	rm -rf eggs
-
-# this part is for testing...
-setup:
-	cd eggs && \
-	mkdir -p install && \
-	chicken-setup -repository `pwd`/install single.egg && \
-	chicken-setup -repository `pwd`/install multi.egg
diff --git a/Examples/chicken/egg/README b/Examples/chicken/egg/README
deleted file mode 100644
index b5df0e6..0000000
--- a/Examples/chicken/egg/README
+++ /dev/null
@@ -1,19 +0,0 @@
-These examples show how to build a chicken extension module in the form of an
-egg.  There are two eggs that get built, single.egg which contains a single
-module which is built with -nounit and multi.egg, which contains two modules
-mod1 and mod2.  These are built normally, and multi_init.scm loads them both.
-Read section "17.4.2 Building chicken extension libraries" in the manual
-for a description of these two techniques.
-
-To build:
-
-$ make
-$ make setup
-$ make run
-
-$ make clean
-
-The eggs are built into an eggs subdirectory, because chicken-setup has
-problems installing eggs when there are other files named similar in
-the same directory.  The make setup step runs chicken-setup to install
-the eggs into the eggs/install directory.
diff --git a/Examples/chicken/egg/mod1.i b/Examples/chicken/egg/mod1.i
deleted file mode 100644
index 6a2940b..0000000
--- a/Examples/chicken/egg/mod1.i
+++ /dev/null
@@ -1,8 +0,0 @@
-%module mod1
-
-%inline %{
-class Bar {
-  public:
-    int b;
-};
-%}
diff --git a/Examples/chicken/egg/mod2.i b/Examples/chicken/egg/mod2.i
deleted file mode 100644
index e9ae4a6..0000000
--- a/Examples/chicken/egg/mod2.i
+++ /dev/null
@@ -1,17 +0,0 @@
-%module mod2
-
-%import "mod1.i"
-
-%{
-class Bar {
-  public:
-    int b;
-};
-%}
-
-%inline %{
-  class Bar2 : public Bar {
-    public:
-      int c;
-  };
-%}
diff --git a/Examples/chicken/egg/multi.setup b/Examples/chicken/egg/multi.setup
deleted file mode 100644
index 95aeb00..0000000
--- a/Examples/chicken/egg/multi.setup
+++ /dev/null
@@ -1,2 +0,0 @@
-(run (csc -s -o multi.so multi_init.scm mod1.scm mod1_wrap.cxx mod2.scm mod2_wrap.cxx))
-(install-extension 'multi '("multi.so"))
diff --git a/Examples/chicken/egg/multi_init.scm b/Examples/chicken/egg/multi_init.scm
deleted file mode 100644
index 600491d..0000000
--- a/Examples/chicken/egg/multi_init.scm
+++ /dev/null
@@ -1,2 +0,0 @@
-(declare (uses mod1))
-(declare (uses mod2))
diff --git a/Examples/chicken/egg/single.i b/Examples/chicken/egg/single.i
deleted file mode 100644
index 46266b4..0000000
--- a/Examples/chicken/egg/single.i
+++ /dev/null
@@ -1,8 +0,0 @@
-%module single
-
-%inline %{
-class Foo {
-  public:
-    int a;
-};
-%}
diff --git a/Examples/chicken/egg/single.setup b/Examples/chicken/egg/single.setup
deleted file mode 100644
index 4b503ec..0000000
--- a/Examples/chicken/egg/single.setup
+++ /dev/null
@@ -1,2 +0,0 @@
-(run (csc -s -o single.so single.scm single_wrap.cxx))
-(install-extension 'single '("single.so"))
diff --git a/Examples/chicken/egg/test.scm b/Examples/chicken/egg/test.scm
deleted file mode 100644
index 4ec94ed..0000000
--- a/Examples/chicken/egg/test.scm
+++ /dev/null
@@ -1,18 +0,0 @@
-(require-extension single)
-(require-extension multi)
-
-(define f (make <Foo>))
-(slot-set! f 'a 3)
-(print (slot-ref f 'a))
-
-(define b (make <Bar>))
-(slot-set! b 'b 2)
-(print (slot-ref b 'b))
-
-(define b2 (make <Bar2>))
-(slot-set! b2 'b 4)
-(slot-set! b2 'c 6)
-(print (slot-ref b2 'b))
-(print (slot-ref b2 'c))
-
-(exit 0)
diff --git a/Examples/chicken/multimap/Makefile b/Examples/chicken/multimap/Makefile
deleted file mode 100644
index 551d1c7..0000000
--- a/Examples/chicken/multimap/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-TOP        = ../..
-SWIGEXE    = $(TOP)/../swig
-SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-INTERFACE  = example.i
-SRCS       = example.c
-CXXSRCS    =
-TARGET     = multimap
-INCLUDE    =
-SWIGOPT    =
-VARIANT    =
-
-# uncomment the following two lines to build a static exe
-#CHICKEN_MAIN = runme.scm
-#VARIANT    = _static
-
-check: build
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' chicken_run
-
-build: $(TARGET)
-
-$(TARGET): $(INTERFACE) $(SRCS)
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
-	SRCS='$(SRCS)' CXXSRCS='$(CXXSRCS)' CHICKEN_MAIN='$(CHICKEN_MAIN)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	INCLUDE='$(INCLUDE)' SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' \
-	INTERFACE='$(INTERFACE)' CHICKENOPTS='$(CHICKENOPTS)' chicken$(VARIANT)
-
-clean:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' chicken_clean
-	rm -f example.scm
-	rm -f $(TARGET)
diff --git a/Examples/chicken/multimap/example.c b/Examples/chicken/multimap/example.c
deleted file mode 100644
index b8360fa..0000000
--- a/Examples/chicken/multimap/example.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/* File : example.c */
-#include <stdio.h>
-#include <stdlib.h>
-#include <ctype.h>
-
-/* Compute the greatest common divisor of positive integers */
-int gcd(int x, int y) {
-  int g;
-  g = y;
-  while (x > 0) {
-    g = x;
-    x = y % x;
-    y = g;
-  }
-  return g;
-}
-
-int gcdmain(int argc, char *argv[]) {
-  int x,y;
-  if (argc != 3) {
-    printf("usage: gcd x y\n");
-    return -1;
-  }
-  x = atoi(argv[1]);
-  y = atoi(argv[2]);
-  printf("gcd(%d,%d) = %d\n", x,y,gcd(x,y));
-  return 0;
-}
-
-int count(char *bytes, int len, char c) {
-  int i;
-  int count = 0;
-  for (i = 0; i < len; i++) {
-    if (bytes[i] == c) count++;
-  }
-  return count;
-}
-
-void capitalize(char *str, int len) {
-  int i;
-  for (i = 0; i < len; i++) {
-    str[i] = (char)toupper(str[i]);
-  }
-}
-
-void circle(double x, double y) {
-  double a = x*x + y*y;
-  if (a > 1.0) {
-    printf("Bad points %g, %g\n", x,y);
-  } else {
-    printf("Good points %g, %g\n", x,y);
-  }
-}
diff --git a/Examples/chicken/multimap/example.i b/Examples/chicken/multimap/example.i
deleted file mode 100644
index 02567f4..0000000
--- a/Examples/chicken/multimap/example.i
+++ /dev/null
@@ -1,96 +0,0 @@
-/* File : example.i */
-%module example
-
-%{
-extern int gcd(int x, int y);
-extern int gcdmain(int argc, char *argv[]);
-extern int count(char *bytes, int len, char c);
-extern void capitalize (char *str, int len);
-extern void circle (double cx, double cy);
-extern int squareCubed (int n, int *OUTPUT);
-%}
-
-%include exception.i
-%include typemaps.i
-
-extern int    gcd(int x, int y);
-
-%typemap(in) (int argc, char *argv[]) {
-  int i;
-  if (!C_swig_is_vector ($input)) {
-    swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument $input is not a vector");
-  }
-  $1 = C_header_size ($input);
-  $2 = (char **) malloc(($1+1)*sizeof(char *));
-  for (i = 0; i < $1; i++) {
-    C_word o = C_block_item ($input, i);
-    if (!C_swig_is_string (o)) {
-      char err[50];
-      free($2);
-      sprintf (err, "$input[%d] is not a string", i);
-      swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, err);
-    }
-    $2[i] = C_c_string (o);
-  }
-  $2[i] = 0;
-}
-
-%typemap(freearg) (int argc, char *argv[]) {
-  free($2);
-}
-extern int gcdmain(int argc, char *argv[]);
-
-%typemap(in) (char *bytes, int len) {
-  if (!C_swig_is_string ($input)) {
-    swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument $input is not a string");
-  }	
-  $1 = C_c_string ($input);
-  $2 = C_header_size ($input);
-}
-
-extern int count(char *bytes, int len, char c);
-
-
-/* This example shows how to wrap a function that mutates a string */
-
-%typemap(in) (char *str, int len) 
-%{  if (!C_swig_is_string ($input)) {
-    swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument $input is not a string");
-  }
-  $2 = C_header_size ($input);
-  $1 = (char *) malloc ($2+1);
-  memmove ($1, C_c_string ($input), $2);
-%}
-
-/* Return the mutated string as a new object.  Notice the if MANY construct ... they must be at column 0. */
-
-%typemap(argout) (char *str, int len) (C_word *scmstr) 
-%{  scmstr = C_alloc (C_SIZEOF_STRING ($2));
-  SWIG_APPEND_VALUE(C_string (&scmstr, $2, $1));
-  free ($1);
-%}
-
-extern void capitalize (char *str, int len);
-
-/* A multi-valued constraint.  Force two arguments to lie
-   inside the unit circle */
-
-%typemap(check) (double cx, double cy) {
-  double a = $1*$1 + $2*$2;
-  if (a > 1.0) {
-    SWIG_exception (SWIG_ValueError, "cx and cy must be in unit circle");
-  }
-}
-
-extern void circle (double cx, double cy);
-
-/* Test out multiple return values */
-
-extern int squareCubed (int n, int *OUTPUT);
-%{
-/* Returns n^3 and set n2 to n^2 */
-int squareCubed (int n, int *n2) {
-  *n2 = n * n;
-  return (*n2) * n;
-};
-%}
diff --git a/Examples/chicken/multimap/runme.scm b/Examples/chicken/multimap/runme.scm
deleted file mode 100644
index ebe6440..0000000
--- a/Examples/chicken/multimap/runme.scm
+++ /dev/null
@@ -1,58 +0,0 @@
-;; feel free to uncomment and comment sections
-
-(load-library 'example "multimap.so")
-
-(display "(gcd 90 12): ")
-(display (gcd 90 12))
-(display "\n")
-
-(display "(circle 0.5 0.5): ")
-(display (circle 0.5 0.5))
-(display "\n")
-
-(display "(circle 1.0 1.0): ")
-(handle-exceptions exvar
-  (if (= (car exvar) 9)
-    (display "success: exception thrown")
-    (display "an incorrect exception was thrown"))
-  (begin
-    (circle 1.0 1.0)
-    (display "an exception was not thrown when it should have been")))
-(display "\n")
-
-(display "(circle 1 1): ")
-(handle-exceptions exvar
-  (if (= (car exvar) 9)
-    (display "success: exception thrown")
-    (display "an incorrect exception was thrown"))
-  (begin
-    (circle 1 1)
-    (display "an exception was not thrown when it should have been")))
-(display "\n")
-
-(display "(capitalize \"will this be all capital letters?\"): ")
-(display (capitalize "will this be all capital letters?"))
-(display "\n")
-
-(display "(count \"jumpity little spider\" #\\t): ")
-(display (count "jumpity little spider" #\t))
-(display "\n")
-
-(display "(gcdmain '#(\"hi\" \"there\")): ")
-(display (gcdmain '#("hi" "there")))
-(display "\n")
-
-(display "(gcdmain '#(\"gcd\" \"9\" \"28\")): ")
-(gcdmain '#("gcd" "9" "28"))
-(display "\n")
-
-(display "(gcdmain '#(\"gcd\" \"12\" \"90\")): ")
-(gcdmain '#("gcd" "12" "90"))
-(display "\n")
-
-(display "squarecubed 3: ")
-(call-with-values (lambda() (squareCubed 3)) 
-		  (lambda (a b) (printf "~A ~A" a b)))
-(display "\n")
-
-(exit)
diff --git a/Examples/chicken/overload/Makefile b/Examples/chicken/overload/Makefile
deleted file mode 100644
index 0193901..0000000
--- a/Examples/chicken/overload/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-TOP        = ../..
-SWIGEXE    = $(TOP)/../swig
-SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-INTERFACE  = example.i
-SRCS       =
-CXXSRCS    = example.cxx
-TARGET     = overload
-INCLUDE    =
-SWIGOPT    = -proxy -unhideprimitive
-VARIANT    =
-
-# uncomment the following lines to build a static exe
-#CHICKEN_MAIN = runme.scm
-#VARIANT    = _static
-
-check: build
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' chicken_run
-
-build: $(TARGET)
-
-$(TARGET): $(INTERFACE) $(SRCS)
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
-	SRCS='$(SRCS)' CXXSRCS='$(CXXSRCS)' CHICKEN_MAIN='$(CHICKEN_MAIN)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	INCLUDE='$(INCLUDE)' SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' \
-	INTERFACE='$(INTERFACE)' CHICKENOPTS='$(CHICKENOPTS)' chicken$(VARIANT)_cpp
-
-clean:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' chicken_clean
-	rm -f example.scm
-	rm -f $(TARGET)
diff --git a/Examples/chicken/overload/README b/Examples/chicken/overload/README
deleted file mode 100644
index 9487c3f..0000000
--- a/Examples/chicken/overload/README
+++ /dev/null
@@ -1,2 +0,0 @@
-Overloading example from Chapter 5.14 of SWIG Core Documentation for
-version 1.3.
diff --git a/Examples/chicken/overload/example.cxx b/Examples/chicken/overload/example.cxx
deleted file mode 100644
index 65e7439..0000000
--- a/Examples/chicken/overload/example.cxx
+++ /dev/null
@@ -1,33 +0,0 @@
-/* File : example.c */
-
-#include "example.h"
-#include <stdio.h>
-
-void foo(int x) {
-  printf("x is %d\n", x);
-}
-
-void foo(char *x) {
-  printf("x is '%s'\n", x);
-}
-
-Foo::Foo () {
-  myvar = 55;
-  printf ("Foo constructor called\n");
-}
-
-Foo::Foo (const Foo &) {
-  myvar = 66;
-  printf ("Foo copy constructor called\n");
-}
-
-void Foo::bar (int x) {
-  printf ("Foo::bar(x) method ... \n");
-  printf("x is %d\n", x);
-}
-
-void Foo::bar (char *s, int y) {
-  printf ("Foo::bar(s,y) method ... \n");
-  printf ("s is '%s'\n", s);
-  printf ("y is %d\n", y);
-}
diff --git a/Examples/chicken/overload/example.h b/Examples/chicken/overload/example.h
deleted file mode 100644
index 1c135d5..0000000
--- a/Examples/chicken/overload/example.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* File : example.h */
-
-extern void foo (int x);
-extern void foo (char *x);
-
-class Foo {
- private:
-  int myvar;
- public:
-  Foo();
-  Foo(const Foo &);   // Copy constructor
-  void bar(int x);
-  void bar(char *s, int y);
-};
diff --git a/Examples/chicken/overload/example.i b/Examples/chicken/overload/example.i
deleted file mode 100644
index 23a2998..0000000
--- a/Examples/chicken/overload/example.i
+++ /dev/null
@@ -1,16 +0,0 @@
-/* File : example.i */
-%module example
-
-%{
-#include "example.h"
-%}
-
-/* Let "Foo" objects be converted back and forth from TinyCLOS into
-   low-level CHICKEN SWIG procedures */
-
-%typemap(clos_in) Foo * = SIMPLE_CLOS_OBJECT *;
-%typemap(clos_out) Foo * = SIMPLE_CLOS_OBJECT *;
-
-/* Let's just grab the original header file here */
-%include "example.h"
-
diff --git a/Examples/chicken/overload/runme.scm b/Examples/chicken/overload/runme.scm
deleted file mode 100644
index 168490f..0000000
--- a/Examples/chicken/overload/runme.scm
+++ /dev/null
@@ -1,45 +0,0 @@
-;; This file demonstrates the overloading capabilities of SWIG
-
-(load-library 'example "overload.so")
-
-;; Low level
-;; ---------
-
-(display "
-Trying low level code ...
-  (foo 1)
-  (foo \"some string\")
-  (define A-FOO (new-Foo))
-  (define ANOTHER-FOO (new-Foo A-FOO)) ;; copy constructor
-  (Foo-bar A-FOO 2)
-  (Foo-bar ANOTHER-FOO \"another string\" 3)
-")
-
-(primitive:foo 1)
-(primitive:foo "some string")
-(define A-FOO (slot-ref (primitive:new-Foo) 'swig-this))
-(define ANOTHER-FOO (slot-ref (primitive:new-Foo A-FOO) 'swig-this)) ;; copy constructor
-(primitive:Foo-bar A-FOO 2)
-(primitive:Foo-bar ANOTHER-FOO "another string" 3)
-
-;; TinyCLOS
-;; --------
-
-(display "
-Trying TinyCLOS code ...
-  (+foo+ 1)
-  (+foo+ \"some string\")
-  (define A-FOO (make <Foo>))
-  (define ANOTHER-FOO (make <Foo> A-FOO)) ;; copy constructor
-  (-bar- A-FOO 2)
-  (-bar- ANOTHER-FOO \"another string\" 3)
-")
-
-(foo 1)
-(foo "some string")
-(define A-FOO (make <Foo>))
-(define ANOTHER-FOO (make <Foo> A-FOO)) ;; copy constructor
-(bar A-FOO 2)
-(bar ANOTHER-FOO "another string" 3)
-
-(exit)
diff --git a/Examples/chicken/simple/Makefile b/Examples/chicken/simple/Makefile
deleted file mode 100644
index f5dd1a9..0000000
--- a/Examples/chicken/simple/Makefile
+++ /dev/null
@@ -1,31 +0,0 @@
-TOP        = ../..
-SWIGEXE    = $(TOP)/../swig
-SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-INTERFACE  = example.i
-SRCS       = example.c
-CXXSRCS    =
-TARGET     = simple
-INCLUDE    =
-SWIGOPT    =
-VARIANT    =
-
-# uncomment the following two lines to build a static exe
-#CHICKEN_MAIN = runme.scm
-#VARIANT    = _static
-
-check: build
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' chicken_run
-
-build: $(TARGET)
-
-$(TARGET): $(INTERFACE) $(SRCS)
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' \
-	SRCS='$(SRCS)' CXXSRCS='$(CXXSRCS)' CHICKEN_MAIN='$(CHICKEN_MAIN)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	INCLUDE='$(INCLUDE)' SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' \
-	INTERFACE='$(INTERFACE)' CHICKENOPTS='$(CHICKENOPTS)' chicken$(VARIANT)
-
-clean:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' chicken_clean
-	rm -f example.scm example-generic.scm example-clos.scm
-	rm -f $(TARGET)
diff --git a/Examples/chicken/simple/README b/Examples/chicken/simple/README
deleted file mode 100644
index 07e8da0..0000000
--- a/Examples/chicken/simple/README
+++ /dev/null
@@ -1 +0,0 @@
-Simple example from users manual.
diff --git a/Examples/chicken/simple/example.c b/Examples/chicken/simple/example.c
deleted file mode 100644
index f2b0747..0000000
--- a/Examples/chicken/simple/example.c
+++ /dev/null
@@ -1,24 +0,0 @@
-/* Simple example from documentation */
-/* File : example.c */
-
-#include <time.h>
-
-double My_variable = 3.0;
-
-/* Compute factorial of n */
-int fact(int n) {
-  if (n <= 1) return 1;
-  else return n*fact(n-1);
-}
-
-/* Compute n mod m */
-int my_mod(int n, int m) {
-  return (n % m);
-}
-
-
-char *get_time() {
-    long            ltime;
-    time(&ltime);
-    return ctime(&ltime);
-}
diff --git a/Examples/chicken/simple/example.i b/Examples/chicken/simple/example.i
deleted file mode 100644
index 5b3e955..0000000
--- a/Examples/chicken/simple/example.i
+++ /dev/null
@@ -1,16 +0,0 @@
-/* File : example.i */
-%module example
-%{
-/* Put headers and other declarations here */
-%}
-
-%include typemaps.i
-
-%rename(mod) my_mod;
-
-%inline %{
-extern double My_variable;
-extern int    fact(int);
-extern int    my_mod(int n, int m);
-extern char   *get_time();
-%}
diff --git a/Examples/chicken/simple/runme.scm b/Examples/chicken/simple/runme.scm
deleted file mode 100644
index 05aa870..0000000
--- a/Examples/chicken/simple/runme.scm
+++ /dev/null
@@ -1,28 +0,0 @@
-;; feel free to uncomment and comment sections
-(load-library 'example "simple.so")
-
-(display "(My-variable): ")
-(display (My-variable))
-(display "\n")
-
-(display "(My-variable 3.141259): ")
-(display (My-variable 3.141259))
-(display "\n")
-
-(display "(My-variable): ")
-(display (My-variable))
-(display "\n")
-
-(display "(fact 5): ")
-(display (fact 5))
-(display "\n")
-
-(display "(mod 75 7): ")
-(display (mod 75 7))
-(display "\n")
-
-(display "(get-time): ")
-(display (get-time))
-(display "\n")
-
-(exit)
diff --git a/Examples/contract/simple_c/example.c b/Examples/contract/simple_c/example.c
deleted file mode 100644
index 85a3e14..0000000
--- a/Examples/contract/simple_c/example.c
+++ /dev/null
@@ -1,11 +0,0 @@
-#include <stdio.h>
-
-int Circle (int x, int y, int radius) {
-  /* Draw Circle */
-  printf("Drawing the circle...\n");
-  /* Return -1 to test contract post assertion */
-  if (radius == 2)
-    return -1;
-  else
-    return 1;
-}
diff --git a/Examples/contract/simple_c/example.i b/Examples/contract/simple_c/example.i
deleted file mode 100644
index 49df09a..0000000
--- a/Examples/contract/simple_c/example.i
+++ /dev/null
@@ -1,19 +0,0 @@
-/* File : example.i */
-
-/* Basic C example for swig contract */
-/* Tiger, University of Chicago, 2003 */
-
-%module example
-
-%contract Circle (int x, int y, int radius) {
-require:
-     x      >= 0;
-     y      >= 0;
-     radius >  x;
-ensure:
-     Circle >= 0;
-}
-
-%inline %{
-extern int Circle (int x, int y, int radius);
-%}
diff --git a/Examples/contract/simple_c/runme1.py b/Examples/contract/simple_c/runme1.py
deleted file mode 100644
index abd8df6..0000000
--- a/Examples/contract/simple_c/runme1.py
+++ /dev/null
@@ -1,17 +0,0 @@
-import example 
-# Call the Circle() function correctly
-
-x = 1;
-y = 1;
-r = 3;
-
-c = example.Circle(x, y, r)
-
-# test post-assertion
-x = 1;
-y = 1;
-r = 2;
-
-c = example.Circle(x, y, r)
-
-print "The return value of Circle(%d, %d, %d) is %d" % (x,y,r,c)
diff --git a/Examples/contract/simple_c/runme2.py b/Examples/contract/simple_c/runme2.py
deleted file mode 100644
index 48d4a3f..0000000
--- a/Examples/contract/simple_c/runme2.py
+++ /dev/null
@@ -1,20 +0,0 @@
-import example 
-
-# Call the Circle() function correctly
-
-x = 1;
-y = 1;
-r = 3;
-
-c = example.Circle(x, y, r)
-
-print "The return value of Circle(%d, %d, %d) is %d" % (x,y,r,c)
-
-# test pre-assertion
-x = 1;
-y = -1;
-r = 3;
-
-c = example.Circle(x, y, r)
-
-print "The return value of Circle(%d, %d, %d) is %d" % (x,y,r,c)
diff --git a/Examples/contract/simple_cxx/example.cxx b/Examples/contract/simple_cxx/example.cxx
deleted file mode 100644
index e3dd2ca..0000000
--- a/Examples/contract/simple_cxx/example.cxx
+++ /dev/null
@@ -1,30 +0,0 @@
-#include "example.h"
-
-#define M_PI 3.14159265358979323846
-
-/* Move the shape to a new location */
-void Shape::move(double dx, double dy) {
-  x += dx;
-  y += dy;
-}
-
-int Shape::nshapes = 0;
-
-double Circle::area(void) {
-  /* return -1 is to test post-assertion */
-  if (radius == 1)
-    return -1;
-  return M_PI*radius*radius;
-}
-
-double Circle::perimeter(void) {
-  return 2*M_PI*radius;
-}
-
-double Square::area(void) {
-  return width*width;
-}
-
-double Square::perimeter(void) {
-  return 4*width;
-}
diff --git a/Examples/contract/simple_cxx/example.h b/Examples/contract/simple_cxx/example.h
deleted file mode 100644
index de708bb..0000000
--- a/Examples/contract/simple_cxx/example.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* File : example.h */
-
-class Shape {
-public:
-  Shape() {
-    nshapes++;
-  }
-  virtual ~Shape() {
-    nshapes--;
-  }
-  double  x, y;   
-  void    move(double dx, double dy);
-  virtual double area(void) = 0;
-  virtual double perimeter(void) = 0;
-  static  int nshapes;
-};
-
-class Circle : public Shape {
-private:
-  double radius;
-public:
-  Circle(double r) : radius(r) { }
-  virtual double area(void);
-  virtual double perimeter(void);
-};
-
-class Square : public Shape {
-private:
-  double width;
-public:
-  Square(double w) : width(w) { }
-  virtual double area(void);
-  virtual double perimeter(void);
-};
diff --git a/Examples/contract/simple_cxx/example.i b/Examples/contract/simple_cxx/example.i
deleted file mode 100644
index 9b47409..0000000
--- a/Examples/contract/simple_cxx/example.i
+++ /dev/null
@@ -1,28 +0,0 @@
-%module example
-
-%contract Circle::Circle(double radius) {
-require:
-    radius > 0;
-}
-
-%contract Circle::area(void) {
-ensure:
-    area > 0;
-}
-
-%contract Shape::move(double dx, double dy) {
-require:
-    dx > 0;
-}
-
-/* should be no effect, since there is no move() for class Circle */
-%contract Circle::move(double dx, double dy) {
-require:
-    dy > 1;
-}
-
-# include must be after contracts
-%{
-#include "example.h"
-%}
-%include "example.h"
diff --git a/Examples/contract/simple_cxx/runme1.py b/Examples/contract/simple_cxx/runme1.py
deleted file mode 100644
index 9028d02..0000000
--- a/Examples/contract/simple_cxx/runme1.py
+++ /dev/null
@@ -1,33 +0,0 @@
-import example 
-
-# Create the Circle object
-
-r = 2;
-print "  Creating circle (radium: %d) :" % r
-c = example.Circle(r)
-
-# Set the location of the object
-
-c.x = 20
-c.y = 30
-print "  Here is its current position:"
-print "    Circle = (%f, %f)" % (c.x,c.y)
-
-# ----- Call some methods -----
-
-print "\n  Here are some properties of the Circle:"
-print "    area      = ", c.area()
-print "    perimeter = ", c.perimeter()
-dx = 1;
-dy = 1;
-print "    Moving with (%d, %d)..." % (dx, dy)
-c.move(dx, dy)
-
-del c
-
-print "==================================="
-
-# test construction */
-r = -1;
-print "  Creating circle (radium: %d) :" % r 
-c = example.Circle(r)
diff --git a/Examples/contract/simple_cxx/runme2.py b/Examples/contract/simple_cxx/runme2.py
deleted file mode 100644
index 5f9c0df..0000000
--- a/Examples/contract/simple_cxx/runme2.py
+++ /dev/null
@@ -1,44 +0,0 @@
-import example 
-
-# Create the Circle object
-
-r = 2;
-print "  Creating circle (radium: %d) :" % r
-c = example.Circle(r)
-
-# Set the location of the object
-
-c.x = 20
-c.y = 30
-print "  Here is its current position:"
-print "    Circle = (%f, %f)" % (c.x,c.y)
-
-# ----- Call some methods -----
-
-print "\n  Here are some properties of the Circle:"
-print "    area      = ", c.area()
-print "    perimeter = ", c.perimeter()
-dx = 1;
-dy = 1;
-print "    Moving with (%d, %d)..." % (dx, dy)
-c.move(dx, dy)
-
-del c
-
-print "==================================="
-
-# test area function */
-r = 1;
-print "  Creating circle (radium: %d) :" % r 
-c = example.Circle(r)
-# Set the location of the object
-
-c.x = 20
-c.y = 30
-print "  Here is its current position:"
-print "    Circle = (%f, %f)" % (c.x,c.y)
-
-# ----- Call some methods -----
-
-print "\n  Here are some properties of the Circle:"
-print "    area      = ", c.area()
diff --git a/Examples/contract/simple_cxx/runme3.py b/Examples/contract/simple_cxx/runme3.py
deleted file mode 100644
index a663732..0000000
--- a/Examples/contract/simple_cxx/runme3.py
+++ /dev/null
@@ -1,57 +0,0 @@
-import example 
-
-# Create the Circle object
-
-r = 2;
-print "  Creating circle (radium: %d) :" % r
-c = example.Circle(r)
-
-# Set the location of the object
-
-c.x = 20
-c.y = 30
-print "  Here is its current position:"
-print "    Circle = (%f, %f)" % (c.x,c.y)
-
-# ----- Call some methods -----
-
-print "\n  Here are some properties of the Circle:"
-print "    area      = ", c.area()
-print "    perimeter = ", c.perimeter()
-dx = 1;
-dy = 1;
-print "    Moving with (%d, %d)..." % (dx, dy)
-c.move(dx, dy)
-
-del c
-
-print "==================================="
-
-# test move function */
-r = 2;
-print "  Creating circle (radium: %d) :" % r 
-c = example.Circle(r)
-# Set the location of the object
-
-c.x = 20
-c.y = 30
-print "  Here is its current position:"
-print "    Circle = (%f, %f)" % (c.x,c.y)
-
-# ----- Call some methods -----
-
-print "\n  Here are some properties of the Circle:"
-print "    area      = ", c.area()
-print "    perimeter = ", c.perimeter()
-
-# no error for Circle's pre-assertion
-dx = 1;
-dy = -1;
-print "    Moving with (%d, %d)..." % (dx, dy)
-c.move(dx, dy)
-
-# error with Shape's pre-assertion
-dx = -1;
-dy = 1;
-print "    Moving with (%d, %d)..." % (dx, dy)
-c.move(dx, dy)
diff --git a/Examples/d/callback/Makefile b/Examples/d/callback/Makefile
index ad84231..a80ecf1 100644
--- a/Examples/d/callback/Makefile
+++ b/Examples/d/callback/Makefile
@@ -1 +1 @@
-include ../example.mk
+include $(SRCDIR)../example.mk
diff --git a/Examples/d/callback/d1/runme.d b/Examples/d/callback/d1/runme.d
deleted file mode 100644
index e34e096..0000000
--- a/Examples/d/callback/d1/runme.d
+++ /dev/null
@@ -1,36 +0,0 @@
-module runme;
-
-import tango.io.Stdout;
-import example;
-
-public class DCallback : Callback {
-  public override void run() {
-    Stdout( "DCallback.run()" ).newline;
-  }
-}
-
-void main() {
-  auto caller = new Caller();
-
-  Stdout( "Adding and calling a normal C++ callback" ).newline;
-  Stdout( "----------------------------------------" ).newline;
-  {
-    scope auto callback = new Callback();
-    caller.setCallback(callback);
-    caller.call();
-    caller.resetCallback();
-  }
-
-  Stdout.newline;
-  Stdout( "Adding and calling a D callback" ).newline;
-  Stdout( "-------------------------------" ).newline;
-  {
-    scope auto callback = new DCallback();
-    caller.setCallback(callback);
-    caller.call();
-    caller.resetCallback();
-  }
-
-  Stdout.newline;
-  Stdout( "D exit" ).newline;
-}
diff --git a/Examples/d/class/Makefile b/Examples/d/class/Makefile
index ad84231..a80ecf1 100644
--- a/Examples/d/class/Makefile
+++ b/Examples/d/class/Makefile
@@ -1 +1 @@
-include ../example.mk
+include $(SRCDIR)../example.mk
diff --git a/Examples/d/class/d1/runme.d b/Examples/d/class/d1/runme.d
deleted file mode 100644
index b0c4263..0000000
--- a/Examples/d/class/d1/runme.d
+++ /dev/null
@@ -1,58 +0,0 @@
-// This example illustrates how C++ classes can be used from D using SWIG.
-// The D class gets mapped onto the C++ class and behaves as if it is a D class.
-module runme;
-
-import tango.io.Stdout;
-import example;
-
-void main() {
-  // ----- Object creation -----
-
-  Stdout( "Creating some objects:" ).newline;
-
-  {
-    scope Square s = new Square(10);
-    scope Circle c = new Circle(10);
-
-    // ----- Access a static member -----
-    Stdout.format( "{} shapes were created.", Shape.nshapes ).newline;
-
-    // ----- Member data access -----
-
-    // Notice how we can do this using functions specific to
-    // the 'Circle' class.
-    c.x = 20;
-    c.y = 30;
-
-    // Now use the same functions in the base class
-    Shape shape = s;
-    shape.x = -10;
-    shape.y = 5;
-
-    Stdout( "\nHere is their current position:" ).newline;
-    Stdout.format( "    Circle = ( {}, {} )", c.x, c.y ).newline;
-    Stdout.format( "    Square = ( {}, {} )", s.x, s.y ).newline;
-
-    // ----- Call some methods -----
-
-    Stdout( "\nHere are some properties of the shapes:" ).newline;
-    Shape[] shapes = [ cast(Shape) c, cast(Shape) s ];
-    foreach ( currentShape; shapes )
-    {
-      Stdout.format( "    {}", currentShape.classinfo.name ).newline;
-      Stdout.format( "        area      = {}", currentShape.area() ).newline;
-      Stdout.format( "        perimeter = {}", currentShape.perimeter() ).newline;
-    }
-
-    // Notice how the area() and perimeter() functions really
-    // invoke the appropriate virtual method on each object.
-
-    // ----- Delete everything -----
-    Stdout( "\nGuess I'll clean up now:" ).newline;
-    // Note: when this using scope is exited the D destructors are called which
-    // in turn call the C++ destructors.
-  }
-
-  Stdout.format( "{} shapes remain", Shape.nshapes ).newline;
-  Stdout( "\nGoodbye!" ).newline;
-}
diff --git a/Examples/d/constants/Makefile b/Examples/d/constants/Makefile
index ad84231..a80ecf1 100644
--- a/Examples/d/constants/Makefile
+++ b/Examples/d/constants/Makefile
@@ -1 +1 @@
-include ../example.mk
+include $(SRCDIR)../example.mk
diff --git a/Examples/d/constants/d1/runme.d b/Examples/d/constants/d1/runme.d
deleted file mode 100644
index 47362cb..0000000
--- a/Examples/d/constants/d1/runme.d
+++ /dev/null
@@ -1,28 +0,0 @@
-module runme;
-
-import tango.io.Stdout;
-static import example;
-
-void main() {
-  Stdout.formatln("ICONST  = {} (should be 42)", example.ICONST);
-  Stdout.formatln("FCONST  = {} (should be 2.18)", example.FCONST);
-  Stdout.formatln("CCONST  = {} (should be 'x')", example.CCONST);
-  Stdout.formatln("CCONST2 = {} (this should be on a new line)", example.CCONST2);
-  Stdout.formatln("SCONST  = {} (should be 'Hello World')", example.SCONST);
-  Stdout.formatln("SCONST2 = {} (should be '\"Hello World\"')", example.SCONST2);
-  Stdout.formatln("EXPR    = {} (should be 48.55)", example.EXPR);
-  Stdout.formatln("iconst  = {} (should be 37)", example.iconst);
-  Stdout.formatln("fconst  = {} (should be 3.14)", example.fconst);
-
-  static if (is(typeof(example.EXTERN))) {
-    Stdout.formatln("EXTERN should not be defined, but is: {}.", example.EXTERN );
-  } else {
-    Stdout.formatln("EXTERN isn't defined (good)");
-  }
-
-  static if (is(typeof(example.FOO))) {
-    Stdout.formatln("FOO should not be defined, but is: {}.", example.FOO);
-  } else {
-    Stdout.formatln("FOO isn't defined (good)");
-  }
-}
diff --git a/Examples/d/enum/Makefile b/Examples/d/enum/Makefile
index ad84231..a80ecf1 100644
--- a/Examples/d/enum/Makefile
+++ b/Examples/d/enum/Makefile
@@ -1 +1 @@
-include ../example.mk
+include $(SRCDIR)../example.mk
diff --git a/Examples/d/enum/d1/runme.d b/Examples/d/enum/d1/runme.d
deleted file mode 100644
index d986986..0000000
--- a/Examples/d/enum/d1/runme.d
+++ /dev/null
@@ -1,28 +0,0 @@
-module runme;
-
-import tango.io.Stdout;
-import example;
-
-void main() {
-  Stdout( "Printing out some enum values:" ).newline;
-  Stdout("  color:").newline;
-  Stdout.formatln("    {} = {}", color.RED, cast(int)color.RED);
-  Stdout.formatln("    {} = {}", color.BLUE, cast(int)color.BLUE);
-  Stdout.formatln("    {} = {}", color.GREEN, cast(int)color.GREEN);
-
-  Stdout("\n  Foo.speed:").newline;
-  Stdout.formatln("    Foo.{} = {}", Foo.speed.IMPULSE, cast(int)Foo.speed.IMPULSE);
-  Stdout.formatln("    Foo.{} = {}", Foo.speed.WARP, cast(int)Foo.speed.WARP);
-  Stdout.formatln("    Foo.{} = {}", Foo.speed.LUDICROUS , cast(int)Foo.speed.LUDICROUS);
-
-  Stdout("\nTesting use of enums with functions:").newline;
-  example.enum_test(color.RED, Foo.speed.IMPULSE);
-  example.enum_test(color.BLUE, Foo.speed.WARP);
-  example.enum_test(color.GREEN, Foo.speed.LUDICROUS);
-
-  Stdout( "\nTesting use of enum with class method:" ).newline;
-  scope f = new Foo();
-  f.enum_test(Foo.speed.IMPULSE);
-  f.enum_test(Foo.speed.WARP);
-  f.enum_test(Foo.speed.LUDICROUS);
-}
diff --git a/Examples/d/example.mk b/Examples/d/example.mk
new file mode 100644
index 0000000..766057f
--- /dev/null
+++ b/Examples/d/example.mk
@@ -0,0 +1,50 @@
+#
+# Common Makefile code for building D examples.
+#
+# This file is supposed to be included from a Makefile in the subdirectory
+# corresponding to a specific example.
+#
+
+EXAMPLES_TOP   = ../../..
+SWIG_TOP       = ../../../..
+SWIGEXE        = $(SWIG_TOP)/swig
+SWIG_LIB_DIR   = $(SWIG_TOP)/$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
+EXTRA_CFLAGS   =
+EXTRA_CXXFLAGS =
+EXTRA_LDFLAGS  =
+TARGET         = example_wrap
+SWIGOPT        = -outcurrentdir
+DFLAGS         = -ofrunme
+
+ifeq (,$(SRCDIR))
+DSRCS          = *.d
+else
+DSRCS          = *.d $(addprefix ../$(SRCDIR)d2/,runme.d)
+endif
+
+
+check: build
+	$(MAKE) -C d2/ -f $(EXAMPLES_TOP)/Makefile SRCDIR='../$(SRCDIR)' d_run
+
+build:
+	mkdir -p d2/
+	if [ -f $(SRCDIR)example.cxx ]; then \
+		$(MAKE) -C d2/ -f $(EXAMPLES_TOP)/Makefile SRCDIR='../$(SRCDIR)' EXTRA_CXXFLAGS='$(EXTRA_CXXFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' \
+		SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
+		SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='example.i' CXXSRCS='example.cxx' d_cpp; \
+	elif [ -f $(SRCDIR)example.c ]; then \
+		$(MAKE) -C d2/ -f $(EXAMPLES_TOP)/Makefile SRCDIR='../$(SRCDIR)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' \
+		SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
+		SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='example.i' SRCS='example.c' d; \
+	else \
+		$(MAKE) -C d2/ -f $(EXAMPLES_TOP)/Makefile SRCDIR='../$(SRCDIR)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' \
+		SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
+		SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='example.i' SRCS='' d; \
+	fi
+	$(MAKE) -C d2/ -f $(EXAMPLES_TOP)/Makefile SRCDIR='../$(SRCDIR)' DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile
+
+clean:
+	if [ -d d2/ ]; then \
+		$(MAKE) -C d2/ -f $(EXAMPLES_TOP)/Makefile SRCDIR='../$(SRCDIR)' d_clean; \
+	fi
+	test -f d2/runme.d || rm -rf d2/ # Only delete dir if out of source
diff --git a/Examples/d/example.mk.in b/Examples/d/example.mk.in
deleted file mode 100644
index 84b3ceb..0000000
--- a/Examples/d/example.mk.in
+++ /dev/null
@@ -1,66 +0,0 @@
-#
-# Common Makefile code for building D examples.
-#
-# We actually need to configure this to gain access to the default D version to
-# use when D_VERSION is not set. Using Examples/Makefile.in is not enough, as
-# the location of the source files (d1/ or d2/) depends on it. The alternative
-# would be to add the functionality specific to Examples/d (as opposed to the
-# test suite) directly to Examples/Makefile.in.
-#
-# This file is supposed to be included from a Makefile in the subdirectory
-# corresponding to a specific example.
-#
-
-ifeq (,$(D_VERSION))
-	D_VERSION = @DDEFAULTVERSION@
-endif
-
-ifeq (1,$(D_VERSION))
-	VERSION_DIR = d1/
-else
-	VERSION_DIR = d2/
-endif
-
-EXAMPLES_TOP   = ../../..
-SWIG_TOP       = ../../../..
-SWIGEXE        = $(SWIG_TOP)/swig
-SWIG_LIB_DIR   = $(SWIG_TOP)/$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-EXTRA_CFLAGS   =
-EXTRA_CXXFLAGS =
-EXTRA_LDFLAGS  =
-TARGET         = example_wrap
-SWIGOPT        = -outcurrentdir
-DFLAGS         = -ofrunme
-
-ifeq (,$(SRCDIR))
-DSRCS          = *.d
-else
-DSRCS          = *.d $(addprefix ../$(SRCDIR)$(VERSION_DIR),runme.d)
-endif
-
-
-check: build
-	$(MAKE) -C $(VERSION_DIR) -f $(EXAMPLES_TOP)/Makefile SRCDIR='../$(SRCDIR)' d_run
-
-build:
-	mkdir -p $(VERSION_DIR)
-	if [ -f $(SRCDIR)example.cxx ]; then \
-		$(MAKE) -C $(VERSION_DIR) -f $(EXAMPLES_TOP)/Makefile SRCDIR='../$(SRCDIR)' EXTRA_CXXFLAGS='$(EXTRA_CXXFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' \
-		SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-		SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='example.i' CXXSRCS='example.cxx' d_cpp; \
-	elif [ -f $(SRCDIR)example.c ]; then \
-		$(MAKE) -C $(VERSION_DIR) -f $(EXAMPLES_TOP)/Makefile SRCDIR='../$(SRCDIR)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' \
-		SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-		SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='example.i' SRCS='example.c' d; \
-	else \
-		$(MAKE) -C $(VERSION_DIR) -f $(EXAMPLES_TOP)/Makefile SRCDIR='../$(SRCDIR)' EXTRA_CFLAGS='$(EXTRA_CFLAGS)' EXTRA_LDFLAGS='$(EXTRA_LDFLAGS)' \
-		SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-		SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='example.i' SRCS='' d; \
-	fi
-	$(MAKE) -C $(VERSION_DIR) -f $(EXAMPLES_TOP)/Makefile SRCDIR='../$(SRCDIR)' DSRCS='$(DSRCS)' DFLAGS='$(DFLAGS)' d_compile
-
-clean:
-	if [ -d $(VERSION_DIR) ]; then \
-		$(MAKE) -C $(VERSION_DIR) -f $(EXAMPLES_TOP)/Makefile SRCDIR='../$(SRCDIR)' d_clean; \
-	fi
-	test -f $(VERSION_DIR)runme.d || rm -rf $(VERSION_DIR) # Only delete dir if out of source
diff --git a/Examples/d/extend/Makefile b/Examples/d/extend/Makefile
index ad84231..a80ecf1 100644
--- a/Examples/d/extend/Makefile
+++ b/Examples/d/extend/Makefile
@@ -1 +1 @@
-include ../example.mk
+include $(SRCDIR)../example.mk
diff --git a/Examples/d/extend/d1/runme.d b/Examples/d/extend/d1/runme.d
deleted file mode 100644
index 0584320..0000000
--- a/Examples/d/extend/d1/runme.d
+++ /dev/null
@@ -1,75 +0,0 @@
-/// This file illustrates the cross language polymorphism using directors.
-module runme;
-
-import example;
-import tango.io.Stdout;
-
-// CEO class, which overrides Employee.getPosition().
-class CEO : Manager {
-public:
-  this( char[] name ) {
-    super( name );
-  }
-
-  override char[] getPosition() {
-    return "CEO";
-  }
-
-  // Public method to stop the SWIG proxy base class from thinking it owns the underlying C++ memory.
-  void disownMemory() {
-    swigCMemOwn = false;
-  }
-}
-
-void main() {
-  // Create an instance of CEO, a class derived from the D proxy of the
-  // underlying C++ class. The calls to getName() and getPosition() are standard,
-  // the call to getTitle() uses the director wrappers to call CEO.getPosition().
-
-  auto e = new CEO( "Alice" );
-  Stdout.formatln( "{} is a {}.", e.getName(), e.getPosition() );
-  Stdout.formatln( "Just call her '{}'.", e.getTitle() );
-  Stdout( "----------------------" ).newline;
-
-  {
-    // Create a new EmployeeList instance.  This class does not have a C++
-    // director wrapper, but can be used freely with other classes that do.
-    scope auto list = new EmployeeList();
-
-    // EmployeeList owns its items, so we must surrender ownership of objects we add.
-    e.disownMemory();
-    list.addEmployee(e);
-    Stdout( "----------------------" ).newline;
-
-    // Now we access the first four items in list (three are C++ objects that
-    // EmployeeList's constructor adds, the last is our CEO). The virtual
-    // methods of all these instances are treated the same. For items 0, 1, and
-    // 2, all methods resolve in C++. For item 3, our CEO, getTitle calls
-    // getPosition which resolves in D. The call to getPosition is
-    // slightly different, however, because of the overridden getPosition() call, since
-    // now the object reference has been "laundered" by passing through
-    // EmployeeList as an Employee*. Previously, D resolved the call
-    // immediately in CEO, but now D thinks the object is an instance of
-    // class Employee. So the call passes through the
-    // Employee proxy class and on to the C wrappers and C++ director,
-    // eventually ending up back at the D CEO implementation of getPosition().
-    // The call to getTitle() for item 3 runs the C++ Employee::getTitle()
-    // method, which in turn calls getPosition(). This virtual method call
-    // passes down through the C++ director class to the D implementation
-    // in CEO. All this routing takes place transparently.
-
-    Stdout( "(position, title) for items 0-3:" ).newline;
-    Stdout.formatln( "  {}, '{}'", list.getItem(0).getPosition(), list.getItem(0).getTitle() );
-    Stdout.formatln( "  {}, '{}'", list.getItem(1).getPosition(), list.getItem(1).getTitle() );
-    Stdout.formatln( "  {}, '{}'", list.getItem(2).getPosition(), list.getItem(2).getTitle() );
-    Stdout.formatln( "  {}, '{}'", list.getItem(3).getPosition(), list.getItem(3).getTitle() );
-    Stdout( "----------------------" ).newline;
-
-    // All Employees will be destroyed when the EmployeeList goes out of scope,
-    // including the CEO instance.
-  }
-  Stdout( "----------------------" ).newline;
-
-  // All done.
-  Stdout( "Exiting cleanly from D code." ).newline;
-}
diff --git a/Examples/d/funcptr/Makefile b/Examples/d/funcptr/Makefile
index ad84231..a80ecf1 100644
--- a/Examples/d/funcptr/Makefile
+++ b/Examples/d/funcptr/Makefile
@@ -1 +1 @@
-include ../example.mk
+include $(SRCDIR)../example.mk
diff --git a/Examples/d/funcptr/d1/runme.d b/Examples/d/funcptr/d1/runme.d
deleted file mode 100644
index 1461c15..0000000
--- a/Examples/d/funcptr/d1/runme.d
+++ /dev/null
@@ -1,42 +0,0 @@
-module runme;
-
-import tango.io.Stdout;
-static import example;
-
-extern(C) int add(int a, int b) {
-  return a + b;
-}
-
-extern(C) int sub(int a, int b) {
-  return a - b;
-}
-
-extern(C) int mul(int a, int b) {
-  return a * b;
-}
-
-void main() {
-  int a = 37;
-  int b = 42;
-
-  Stdout( "a = " )( a ).newline;
-  Stdout( "b = " )( b ).newline;
-
-  Stdout( "Trying some C callback functions:" ).newline;
-  Stdout( "    ADD(a,b) = " )( example.do_op( a, b, example.ADD ) ).newline;
-  Stdout( "    SUB(a,b) = " )( example.do_op( a, b, example.SUB ) ).newline;
-  Stdout( "    MUL(a,b) = " )( example.do_op( a, b, example.MUL ) ).newline;
-
-  version (LDC) {
-    // Currently, there is no way to specify the calling convention for
-    // function pointer parameters in D, but LDC does strict typechecking for
-    // them (which is reasonable, but not covered by the language spec yet).
-    // As a result, there is no way to make the code below compile with LDC at
-    // the moment, so just skip it.
-  } else {
-    Stdout( "Now the same with callback functions defined in D:" ).newline;
-    Stdout( "    add(a,b) = " )( example.do_op( a, b, &add ) ).newline;
-    Stdout( "    sub(a,b) = " )( example.do_op( a, b, &sub ) ).newline;
-    Stdout( "    mul(a,b) = " )( example.do_op( a, b, &mul ) ).newline;
-  }
-}
diff --git a/Examples/d/simple/Makefile b/Examples/d/simple/Makefile
index ad84231..a80ecf1 100644
--- a/Examples/d/simple/Makefile
+++ b/Examples/d/simple/Makefile
@@ -1 +1 @@
-include ../example.mk
+include $(SRCDIR)../example.mk
diff --git a/Examples/d/simple/d1/runme.d b/Examples/d/simple/d1/runme.d
deleted file mode 100644
index 1293f18..0000000
--- a/Examples/d/simple/d1/runme.d
+++ /dev/null
@@ -1,27 +0,0 @@
-module runme;
-
-import tango.io.Stdout;
-static import example;
-
-void main() {
-  /*
-   * Call our gcd() function.
-   */
-  int x = 42;
-  int y = 105;
-  int g = example.gcd( x, y );
-  Stdout.format( "The gcd of {} and {} is {}.", x, y, g ).newline;
-
-  /*
-   * Manipulate the Foo global variable.
-   */
-
-  // Output its current value
-  Stdout.format( "Foo = {}", example.Foo ).newline;
-
-  // Change its value
-  example.Foo = 3.1415926;
-
-  // See if the change took effect
-  Stdout.format( "Foo = {}", example.Foo ).newline;
-}
diff --git a/Examples/d/variables/Makefile b/Examples/d/variables/Makefile
index ad84231..a80ecf1 100644
--- a/Examples/d/variables/Makefile
+++ b/Examples/d/variables/Makefile
@@ -1 +1 @@
-include ../example.mk
+include $(SRCDIR)../example.mk
diff --git a/Examples/d/variables/d1/runme.d b/Examples/d/variables/d1/runme.d
deleted file mode 100644
index 35c896b..0000000
--- a/Examples/d/variables/d1/runme.d
+++ /dev/null
@@ -1,71 +0,0 @@
-// This example illustrates global variable access from C#.
-module runme;
-
-import tango.io.Stdout;
-static import example;
-
-void main() {
-  // Try to set the values of some global variables
-  example.ivar    =  42;
-  example.svar    = -31000;
-  example.lvar    =  65537;
-  example.uivar   =  123456;
-  example.usvar   =  61000;
-  example.ulvar   =  654321;
-  example.scvar   =  -13;
-  example.ucvar   =  251;
-  example.cvar    =  'S';
-  example.fvar    =  3.14159f;
-  example.dvar    =  2.1828;
-  example.strvar  =  "Hello World";
-  example.iptrvar = example.new_int(37);
-  example.ptptr   = example.new_Point(37,42);
-  example.name    = "Bill";
-
-  // Now print out the values of the variables
-  Stdout.formatln( "Variables (printed from D):" );
-  Stdout.formatln( "ivar      = {}", example.ivar );
-  Stdout.formatln( "svar      = {}", example.svar );
-  Stdout.formatln( "lvar      = {}", example.lvar );
-  Stdout.formatln( "uivar     = {}", example.uivar );
-  Stdout.formatln( "usvar     = {}", example.usvar );
-  Stdout.formatln( "ulvar     = {}", example.ulvar );
-  Stdout.formatln( "scvar     = {}", example.scvar );
-  Stdout.formatln( "ucvar     = {}", example.ucvar );
-  Stdout.formatln( "fvar      = {}", example.fvar );
-  Stdout.formatln( "dvar      = {}", example.dvar );
-  Stdout.formatln( "cvar      = {}", example.cvar );
-  Stdout.formatln( "strvar    = {}", example.strvar );
-  Stdout.formatln( "cstrvar   = {}", example.cstrvar );
-  Stdout.formatln( "iptrvar   = {}", example.iptrvar );
-  Stdout.formatln( "name      = {}", example.name );
-  Stdout.formatln( "ptptr     = {} {}", example.ptptr, example.Point_print(example.ptptr) );
-  Stdout.formatln( "pt        = {} {}", example.pt, example.Point_print(example.pt) );
-  Stdout.formatln( "status    = {}", example.status );
-
-  Stdout.formatln( "\nVariables (printed from the C library):" );
-  example.print_vars();
-
-  Stdout.formatln( "\nNow I'm going to try and modify some read only variables:" );
-  Stdout.formatln( "Checking that the read only variables are readonly..." );
-
-  Stdout( "     'path'..." );
-  static if ( is( typeof( example.path = "a" ) ) )
-    Stdout.formatln("Oh dear, this variable is not read only!");
-  else
-    Stdout.formatln("Good.");
-
-  Stdout( "     'status'..." );
-  static if ( is( typeof( example.status = 2 ) ) )
-    Stdout.formatln("Oh dear, this variable is not read only!");
-  else
-    Stdout.formatln("Good.");
-
-  Stdout.formatln( "\nI'm going to try and update a structure variable:" );
-
-  example.pt = example.ptptr;
-
-  Stdout( "The new value is " ).flush;
-  example.pt_print();
-  Stdout.formatln( "You should see the value {}", example.Point_print(example.ptptr) );
-}
diff --git a/Examples/go/check.list b/Examples/go/check.list
index b3f34b3..6046c83 100644
--- a/Examples/go/check.list
+++ b/Examples/go/check.list
@@ -12,3 +12,4 @@
 simple
 template
 variables
+goin
diff --git a/Examples/go/goin/Makefile b/Examples/go/goin/Makefile
new file mode 100644
index 0000000..f79b083
--- /dev/null
+++ b/Examples/go/goin/Makefile
@@ -0,0 +1,18 @@
+TOP        = ../..
+SWIGEXE    = $(TOP)/../swig
+SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
+CXXSRCS    =
+TARGET     = example
+INTERFACE  = example.i
+SWIGOPT    =
+
+check: build
+	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_run
+
+build:
+	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
+	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
+	SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' go_cpp
+
+clean:
+	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' INTERFACE='$(INTERFACE)' go_clean
diff --git a/Examples/go/goin/example.i b/Examples/go/goin/example.i
new file mode 100644
index 0000000..b819b80
--- /dev/null
+++ b/Examples/go/goin/example.i
@@ -0,0 +1,106 @@
+
+%module(directors="1") example
+
+%inline %{
+// Helper functions for converting string arrays
+#include <stdlib.h>
+void *alloc_ptr_array(unsigned int len)
+{
+    return calloc(len, sizeof(void *));
+}
+void set_ptr_array(void *ain, unsigned int pos, void *val)
+{
+    void **a = (void **) ain;
+    a[pos] = val;
+}
+void *get_ptr_array(void *ain, unsigned int pos)
+{
+    void **a = (void **) ain;
+    return a[pos];
+}
+void free_ptr_array(void *ain)
+{
+    void **a = (void **) ain;
+    unsigned int i;
+
+    if (!a)
+        return;
+    for (i = 0; a[i]; i++) {
+        free(a[i]);
+    }
+    free(a);
+}
+char *uintptr_to_string(void *in)
+{
+    return (char *) in;
+}
+void *string_to_uintptr(char *in)
+{
+    return strdup(in);
+}
+%}
+
+// These typemaps convert between an array of strings in Go and a
+// const char** that is NULL terminated in C++.
+%typemap(gotype) (const char * const *) "[]string"
+%typemap(imtype) (const char * const *) "uintptr"
+%typemap(goin) (const char * const *) {
+	if $input == nil || len($input) == 0 {
+		$result = 0
+	} else {
+		$result = Alloc_ptr_array(uint(len($input) + 1))
+		defer func() {
+			Free_ptr_array($result)
+		}()
+		var i uint
+		for i = 0; i < uint(len($input)); i++ {
+			Set_ptr_array($result, i, String_to_uintptr($input[i]))
+		}
+	}
+}
+%typemap(in) (const char * const *) {
+    $1 = (char **) $input;
+}
+%typemap(godirectorin) (const char * const *) {
+	if ($input == 0) {
+		$result = nil
+	} else {
+		var i uint
+		for i = 0; ; i++ {
+			var v uintptr = Get_ptr_array($input, i)
+			if v == 0 {
+				break
+			}
+		}
+		if i == 0 {
+			$result = nil
+		} else {
+			$result = make([]string, i)
+			for i = 0; ; i++ {
+				var v uintptr = Get_ptr_array($input, i)
+				if v == 0 {
+					break
+				}
+				$result[i] = Uintptr_to_string(v)
+			}
+		}
+	}
+}
+
+%feature("director") callbacks;
+
+%inline %{
+    class callbacks {
+    public:
+	virtual bool call1(int v, const char * const *strarray);
+	virtual ~callbacks() {}
+    };
+
+    bool check1(callbacks *c, int v, const char * const *strarray) {
+	return c->call1(v, strarray);
+    }
+
+    bool callbacks::call1(int v, const char * const *strarray) {
+        return false;
+    }
+%}
diff --git a/Examples/go/goin/index.html b/Examples/go/goin/index.html
new file mode 100644
index 0000000..852b068
--- /dev/null
+++ b/Examples/go/goin/index.html
@@ -0,0 +1,26 @@
+<html>
+<head>
+<title>SWIG:Examples:go:going</title>
+</head>
+
+<body bgcolor="#ffffff">
+
+
+<tt>SWIG/Examples/go/goin/</tt>
+<hr>
+
+<H2>Example of using goin and godirectorin</H2>
+
+<p>
+This example converts between a Go []string and a "const char * const *"
+in C/C++.  It does this for a director and for a normal call.
+
+<p>
+<ul>
+<li><a href="example.i">example.i</a>.  SWIG interface file.
+<li><a href="runme.go">runme.go</a>. Sample Go program.
+</ul>
+
+<hr>
+</body>
+</html>
diff --git a/Examples/go/goin/runme.go b/Examples/go/goin/runme.go
new file mode 100644
index 0000000..dfc7b09
--- /dev/null
+++ b/Examples/go/goin/runme.go
@@ -0,0 +1,38 @@
+package main
+
+import (
+	"fmt"
+	"swigtests/example"
+)
+
+type mycallbacks struct {
+	example.Callbacks
+}
+
+var tststrs = []string{ "A", "BCD", "EFGH" }
+var tstint int = 5
+
+func (v *mycallbacks) Call1(val int, strarray []string) bool {
+	var rv bool = true
+
+	for i, s := range strarray {
+		fmt.Printf("%d: %s\n", i, s)
+		if s != tststrs[i] {
+			fmt.Printf("  ***Mismatch, expected %s\n", tststrs[i])
+			rv = false
+		}
+	}
+	if val != tstint {
+		rv = false
+	}
+	return rv
+}
+
+func main() {
+	cbs := &mycallbacks{}
+	cbs.Callbacks = example.NewDirectorCallbacks(cbs)
+	worked := example.Check1(cbs, tstint, tststrs)
+	if !worked {
+		panic("Data mismatch")
+	}
+}
diff --git a/Examples/go/index.html b/Examples/go/index.html
index 467f4ec..b8af100 100644
--- a/Examples/go/index.html
+++ b/Examples/go/index.html
@@ -24,6 +24,7 @@
 <li><a href="callback/index.html">callback</a>. C++ callbacks using directors.
 <li><a href="extend/index.html">extend</a>. Polymorphism using directors.
 <li><a href="director/index.html">director</a>. Example how to utilize the director feature.
+<li><a href="goin/index.html">director</a>. Example how to use goin and godirectorin.
 </ul>
 
 <h2>Compilation Issues</h2>
@@ -93,6 +94,6 @@
 </ul>
 
 Your mileage may vary.  If you experience a problem, please let us know by
-contacting us on the <a href="http://www.swig.org/mail.html">mailing lists</a>.
+contacting us on the <a href="https://www.swig.org/mail.html">mailing lists</a>.
 </body>
 </html>
diff --git a/Examples/go/reference/index.html b/Examples/go/reference/index.html
index 5e85893..ebf366b 100644
--- a/Examples/go/reference/index.html
+++ b/Examples/go/reference/index.html
@@ -99,7 +99,7 @@
 class VectorArray {
 public:
  ...
-   %addmethods {
+   %extend {
     Vector &amp;get(int index) {
       return (*self)[index];
     }
diff --git a/Examples/go/template/index.html b/Examples/go/template/index.html
index cf2b133..a389c19 100644
--- a/Examples/go/template/index.html
+++ b/Examples/go/template/index.html
@@ -42,7 +42,7 @@
     v[index] = val;
   }
 #ifdef SWIG
-  %addmethods {
+  %extend {
     T getitem(int index) {
       return self-&gt;get(index);
     }
@@ -54,7 +54,7 @@
 };
 </pre>
 </blockquote>
-The %addmethods is used for a neater interface from Go as the
+The %extend is used for a neater interface from Go as the
 functions <tt>get</tt> and <tt>set</tt> use C++ references to
 primitive types. These are tricky to use from Go as they end up as
 pointers, which only work when the C++ and Go types correspond
diff --git a/Examples/guile/check.list b/Examples/guile/check.list
index 726e6ab..1f22adf 100644
--- a/Examples/guile/check.list
+++ b/Examples/guile/check.list
@@ -1,9 +1,9 @@
 # see top-level Makefile.in
-constants
 class
-port
-simple
-std_vector
+constants
 matrix
 multimap
 multivalue
+port
+simple
+std_vector
diff --git a/Examples/guile/matrix/example.i b/Examples/guile/matrix/example.i
index 3f801dc..6f8fa88 100644
--- a/Examples/guile/matrix/example.i
+++ b/Examples/guile/matrix/example.i
@@ -14,4 +14,8 @@
 
 %include math.i
 
-extern double drand48();
+%{
+/* Add drand48 declaration as it is posix only and is not in stdlib.h when using strict c99 and later */
+extern double drand48(void);
+%}
+extern double drand48(void);
diff --git a/Examples/guile/multimap/example.i b/Examples/guile/multimap/example.i
index c24d45d..776eb30 100644
--- a/Examples/guile/multimap/example.i
+++ b/Examples/guile/multimap/example.i
@@ -78,7 +78,7 @@
 
 %typemap(argout) (char *str, int len) {
   SWIG_APPEND_VALUE(scm_from_locale_stringn($1,$2));
-  if ($1) SWIG_free($1);
+  SWIG_free($1);
 }   
 
 extern void capitalize(char *str, int len);
diff --git a/Examples/java/index.html b/Examples/java/index.html
index 007e14d..bebf1b1 100644
--- a/Examples/java/index.html
+++ b/Examples/java/index.html
@@ -58,7 +58,7 @@
 </ul>
 
 Your mileage may vary.  If you experience a problem, please let us know by 
-contacting us on the <a href="http://www.swig.org/mail.html">mailing lists</a>.
+contacting us on the <a href="https://www.swig.org/mail.html">mailing lists</a>.
 </body>
 </html>
 
diff --git a/Examples/java/reference/index.html b/Examples/java/reference/index.html
index 33c80c5..97729e1 100644
--- a/Examples/java/reference/index.html
+++ b/Examples/java/reference/index.html
@@ -104,7 +104,7 @@
 class VectorArray {
 public:
  ...
-   %addmethods {
+   %extend {
     Vector &amp;get(int index) {
       return (*self)[index];
     }
diff --git a/Examples/java/template/index.html b/Examples/java/template/index.html
index 31dba6d..027aa60 100644
--- a/Examples/java/template/index.html
+++ b/Examples/java/template/index.html
@@ -41,7 +41,7 @@
     v[index] = val;
   }
 #ifdef SWIG
-  %addmethods {
+  %extend {
     T getitem(int index) {
       return self-&gt;get(index);
     }
@@ -53,7 +53,7 @@
 };
 </pre>
 </blockquote>
-The %addmethods is used for a neater interface from Java as the functions <tt>get</tt> and <tt>set</tt> use C++ references to primitive types. These are tricky to use from Java as they end up as a pointer in Java (Java long).
+The %extend is used for a neater interface from Java as the functions <tt>get</tt> and <tt>set</tt> use C++ references to primitive types. These are tricky to use from Java as they end up as a pointer in Java (Java long).
 
 <h2>The SWIG interface</h2>
 
diff --git a/Examples/javascript/class/Makefile b/Examples/javascript/class/Makefile
index 54a8f7b..b680557 100644
--- a/Examples/javascript/class/Makefile
+++ b/Examples/javascript/class/Makefile
@@ -1,3 +1,4 @@
-SRCS = example.cxx
+CXXSRCS = example.cxx
+_CPP = _cpp
 
 include $(SRCDIR)../example.mk
diff --git a/Examples/javascript/class/runme.js b/Examples/javascript/class/runme.js
index 6a77b8d..9808910 100644
--- a/Examples/javascript/class/runme.js
+++ b/Examples/javascript/class/runme.js
@@ -7,6 +7,12 @@
 console.log("Created circle " + c);
 s = new example.Square(10);
 console.log("Created square " + s);
+try {
+  new example.Shape();
+  console.error("Should have thrown");
+} catch {
+  console.log("Instantiating abstract class Shape failed");
+}
 
 // ----- Access a static member -----
 console.log("\nA total of " + example.Shape.nshapes + " shapes were created"); // access static member as properties of the class object
@@ -21,6 +27,15 @@
 s.x = -10;
 s.y = 5;
 
+// ----- Check inheritance -----
+console.log("Square instanceof Shape: ", s instanceof example.Shape);
+console.log("Square instanceof Circle: ", s instanceof example.Circle);
+console.log("Square instanceof Square: ", s instanceof example.Square);
+
+// ----- Use an inherited method -----
+s.move(1, 1);
+c.move(-1, -1);
+
 console.log("\nHere is their new position:");
 console.log("Circle = (" + c.x + "," + c.y + ")");
 console.log("Square = (" + s.x + "," + s.y + ")");
diff --git a/Examples/javascript/constant/Makefile b/Examples/javascript/constant/Makefile
index 0402f8d..a80ecf1 100644
--- a/Examples/javascript/constant/Makefile
+++ b/Examples/javascript/constant/Makefile
@@ -1,3 +1 @@
-SRCS =
-
 include $(SRCDIR)../example.mk
diff --git a/Examples/javascript/enum/Makefile b/Examples/javascript/enum/Makefile
index 54a8f7b..b680557 100644
--- a/Examples/javascript/enum/Makefile
+++ b/Examples/javascript/enum/Makefile
@@ -1,3 +1,4 @@
-SRCS = example.cxx
+CXXSRCS = example.cxx
+_CPP = _cpp
 
 include $(SRCDIR)../example.mk
diff --git a/Examples/javascript/example.mk b/Examples/javascript/example.mk
index 3ef012a..5a9ba8a 100644
--- a/Examples/javascript/example.mk
+++ b/Examples/javascript/example.mk
@@ -1,12 +1,6 @@
 # Note: as a convention an example must be in a child directory of this.
 # These paths are relative to such an example directory
 
-ifneq (, $(ENGINE))
-	JSENGINE=$(ENGINE)
-else
-	JSENGINE=node
-endif
-
 ifneq (, $(V8_VERSION))
 	JSV8_VERSION=$(V8_VERSION)
 else
@@ -19,18 +13,22 @@
 SWIG_LIB_DIR   = $(SWIG_TOP)/$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
 TARGET         = example
 INTERFACE      = example.i
-SWIGOPT        = -$(JSENGINE) -DV8_VERSION=$(JSV8_VERSION)
+SWIGOPT        =
+
+ifneq (jsc, $(ENGINE))
+SWIGOPT += -DV8_VERSION=$(JSV8_VERSION)
+endif
 
 check: build
-	$(MAKE) -f $(EXAMPLES_TOP)/Makefile SRCDIR='$(SRCDIR)' JSENGINE='$(JSENGINE)' TARGET='$(TARGET)' javascript_run
+	$(MAKE) -f $(EXAMPLES_TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='$(TARGET)' javascript_run
 
 build:
-	$(MAKE) -f $(EXAMPLES_TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(SRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper_cpp
-	$(MAKE) -f $(EXAMPLES_TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(SRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' JSENGINE='$(JSENGINE)' javascript_build_cpp
+	$(MAKE) -f $(EXAMPLES_TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
+	SRCS='$(SRCS)' SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
+	SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_wrapper$(_CPP)
+	$(MAKE) -f $(EXAMPLES_TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
+	SRCS='$(SRCS)' SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
+	SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' javascript_build$(_CPP)
 
 clean:
 	$(MAKE) -f $(EXAMPLES_TOP)/Makefile SRCDIR='$(SRCDIR)' javascript_clean
diff --git a/Examples/javascript/exception/Makefile b/Examples/javascript/exception/Makefile
index 54a8f7b..b680557 100644
--- a/Examples/javascript/exception/Makefile
+++ b/Examples/javascript/exception/Makefile
@@ -1,3 +1,4 @@
-SRCS = example.cxx
+CXXSRCS = example.cxx
+_CPP = _cpp
 
 include $(SRCDIR)../example.mk
diff --git a/Examples/javascript/exception/example.h b/Examples/javascript/exception/example.h
index bc744cd..c76c46a 100644
--- a/Examples/javascript/exception/example.h
+++ b/Examples/javascript/exception/example.h
@@ -10,7 +10,7 @@
 public:
   Exc(int c, const char *m) {
     code = c;
-    strncpy(msg,m,256);
+    strncpy(msg,m,255);
   }
   int code;
   char msg[256];
diff --git a/Examples/javascript/exception/runme.js b/Examples/javascript/exception/runme.js
index 1001a71..646a33d 100644
--- a/Examples/javascript/exception/runme.js
+++ b/Examples/javascript/exception/runme.js
@@ -10,7 +10,7 @@
   if(error == -1) {
     console.log("t.unknown() didn't throw");
   } else {
-    console.log("successfully caught throw in Test::unknown().");
+    console.log("successfully caught throw in Test::unknown() :" + error);
   }
 }
 
@@ -22,7 +22,7 @@
   if(error == -1) {
     console.log("t.simple() did not throw");
   } else {
-    console.log("successfully caught throw in Test::simple().");
+    console.log("successfully caught throw in Test::simple() :" + error);
   }
 }
 
@@ -33,7 +33,7 @@
   if(error == -1) {
     console.log("t.message() did not throw");
   } else {
-    console.log("successfully caught throw in Test::message().");
+    console.log("successfully caught throw in Test::message() :" + error);
   }
 }
     
@@ -45,7 +45,7 @@
   if(error == -1) {
     console.log("t.hosed() did not throw");
   } else {
-    console.log("successfully caught throw in Test::hosed().");
+    console.log("successfully caught throw in Test::hosed() :" + error);
   }
 }
 
@@ -58,7 +58,7 @@
     if(error == -1) {
       console.log("t.multi(" + i + ") did not throw");
     } else {
-      console.log("successfully caught throw in Test::multi().");
+      console.log("successfully caught throw in Test::multi() :" + error);
     }
   }
-}    
+}
diff --git a/Examples/javascript/functor/Makefile b/Examples/javascript/functor/Makefile
index 0402f8d..8085356 100644
--- a/Examples/javascript/functor/Makefile
+++ b/Examples/javascript/functor/Makefile
@@ -1,3 +1,3 @@
-SRCS =
+_CPP = _cpp
 
 include $(SRCDIR)../example.mk
diff --git a/Examples/javascript/functor/runme.js b/Examples/javascript/functor/runme.js
index 28dc643..15cd7c2 100644
--- a/Examples/javascript/functor/runme.js
+++ b/Examples/javascript/functor/runme.js
@@ -1,15 +1,19 @@
 var example = require("example");
 
-a = new example.intSum(0);
+a = new example.intSum(1);
 b = new example.doubleSum(100.0);
+c = new example.intSum();
 
 // Use the objects.  They should be callable just like a normal
 // javascript function.
 
-for (i=1;i<=100;i++) 
+for (i=1;i<=100;i++) {
     a.call(i);                // Note: function call
     b.call(Math.sqrt(i));     // Note: function call
+    c.call(i);
+}
 
 console.log(a.result());
 console.log(b.result());
+console.log(c.result());
 
diff --git a/Examples/javascript/native/Makefile b/Examples/javascript/native/Makefile
index 0402f8d..8085356 100644
--- a/Examples/javascript/native/Makefile
+++ b/Examples/javascript/native/Makefile
@@ -1,3 +1,3 @@
-SRCS =
+_CPP = _cpp
 
 include $(SRCDIR)../example.mk
diff --git a/Examples/javascript/native/example.i b/Examples/javascript/native/example.i
index 8c61600..7444ae6 100644
--- a/Examples/javascript/native/example.i
+++ b/Examples/javascript/native/example.i
@@ -10,12 +10,12 @@
 // actual demo code
 %wrapper
 %{
-#ifdef SWIG_V8_VERSION /* Engine: Node || V8 */
+#if defined(SWIG_V8_VERSION) /* Engine: Node || V8 */
     
     static SwigV8ReturnValue JavaScript_do_work(const SwigV8Arguments &args) {
         SWIGV8_HANDLESCOPE();
         const int MY_MAGIC_NUMBER = 5;
-        v8::Handle<v8::Value> jsresult =
+        SWIGV8_VALUE jsresult =
             SWIG_From_int(static_cast< int >(MY_MAGIC_NUMBER));
         if (args.Length() != 0)
             SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments.");
@@ -24,6 +24,21 @@
         SWIGV8_RETURN(SWIGV8_UNDEFINED());
     }
 
+#elif defined(NAPI_VERSION) /* Engine: NAPI */
+
+    static Napi::Value JavaScript_do_work(const Napi::CallbackInfo &args) {
+        Napi::Env env = args.Env();
+        Napi::EscapableHandleScope scope(env);
+        const int MY_MAGIC_NUMBER = 5;
+        Napi::Value jsresult =
+            SWIG_From_int(env, static_cast< int >(MY_MAGIC_NUMBER));
+        if (args.Length() != 0)
+            SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments.");
+        return scope.Escape(jsresult);
+    fail:
+        return Napi::Value();
+    }
+
 #else /* Engine: JavaScriptCore */
 
     static JSValueRef JavaScript_do_work(JSContextRef context,
diff --git a/Examples/javascript/nspace/Makefile b/Examples/javascript/nspace/Makefile
index 0402f8d..8085356 100644
--- a/Examples/javascript/nspace/Makefile
+++ b/Examples/javascript/nspace/Makefile
@@ -1,3 +1,3 @@
-SRCS =
+_CPP = _cpp
 
 include $(SRCDIR)../example.mk
diff --git a/Examples/javascript/nspace/example.h b/Examples/javascript/nspace/example.h
index 5306698..b2e46e9 100644
--- a/Examples/javascript/nspace/example.h
+++ b/Examples/javascript/nspace/example.h
@@ -1,5 +1,5 @@
-#ifndef _example_guardian_
-#define _example_guardian_
+#ifndef EXAMPLE_H
+#define EXAMPLE_H
 
 int module_function() { return 7; }
 int module_variable = 9;
diff --git a/Examples/javascript/operator/Makefile b/Examples/javascript/operator/Makefile
index 0402f8d..8085356 100644
--- a/Examples/javascript/operator/Makefile
+++ b/Examples/javascript/operator/Makefile
@@ -1,3 +1,3 @@
-SRCS =
+_CPP = _cpp
 
 include $(SRCDIR)../example.mk
diff --git a/Examples/javascript/overload/Makefile b/Examples/javascript/overload/Makefile
index 0402f8d..8085356 100644
--- a/Examples/javascript/overload/Makefile
+++ b/Examples/javascript/overload/Makefile
@@ -1,3 +1,3 @@
-SRCS =
+_CPP = _cpp
 
 include $(SRCDIR)../example.mk
diff --git a/Examples/javascript/pointer/Makefile b/Examples/javascript/pointer/Makefile
index 54a8f7b..413b64b 100644
--- a/Examples/javascript/pointer/Makefile
+++ b/Examples/javascript/pointer/Makefile
@@ -1,3 +1,3 @@
-SRCS = example.cxx
+SRCS = example.c
 
 include $(SRCDIR)../example.mk
diff --git a/Examples/javascript/pointer/binding.gyp.in b/Examples/javascript/pointer/binding.gyp.in
index cb2b45e..cfd4854 100644
--- a/Examples/javascript/pointer/binding.gyp.in
+++ b/Examples/javascript/pointer/binding.gyp.in
@@ -2,7 +2,7 @@
   "targets": [
     {
       "target_name": "example",
-      "sources": [ "<!(cp $srcdir/example.cxx example-gypcopy.cxx && echo example-gypcopy.cxx)", "example_wrap.cxx" ],
+      "sources": [ "<!(cp $srcdir/example.c example-gypcopy.cxx && echo example-gypcopy.cxx)", "example_wrap.cxx" ],
       "include_dirs": ["$srcdir"]
     }
   ]
diff --git a/Examples/javascript/pointer/example.cxx b/Examples/javascript/pointer/example.c
similarity index 100%
rename from Examples/javascript/pointer/example.cxx
rename to Examples/javascript/pointer/example.c
diff --git a/Examples/javascript/reference/Makefile b/Examples/javascript/reference/Makefile
index 54a8f7b..b680557 100644
--- a/Examples/javascript/reference/Makefile
+++ b/Examples/javascript/reference/Makefile
@@ -1,3 +1,4 @@
-SRCS = example.cxx
+CXXSRCS = example.cxx
+_CPP = _cpp
 
 include $(SRCDIR)../example.mk
diff --git a/Examples/javascript/simple/Makefile b/Examples/javascript/simple/Makefile
index 54a8f7b..413b64b 100644
--- a/Examples/javascript/simple/Makefile
+++ b/Examples/javascript/simple/Makefile
@@ -1,3 +1,3 @@
-SRCS = example.cxx
+SRCS = example.c
 
 include $(SRCDIR)../example.mk
diff --git a/Examples/javascript/simple/binding.gyp.in b/Examples/javascript/simple/binding.gyp.in
index cb2b45e..cfd4854 100644
--- a/Examples/javascript/simple/binding.gyp.in
+++ b/Examples/javascript/simple/binding.gyp.in
@@ -2,7 +2,7 @@
   "targets": [
     {
       "target_name": "example",
-      "sources": [ "<!(cp $srcdir/example.cxx example-gypcopy.cxx && echo example-gypcopy.cxx)", "example_wrap.cxx" ],
+      "sources": [ "<!(cp $srcdir/example.c example-gypcopy.cxx && echo example-gypcopy.cxx)", "example_wrap.cxx" ],
       "include_dirs": ["$srcdir"]
     }
   ]
diff --git a/Examples/modula3/simple/example.c b/Examples/javascript/simple/example.c
similarity index 100%
rename from Examples/modula3/simple/example.c
rename to Examples/javascript/simple/example.c
diff --git a/Examples/javascript/simple/example.cxx b/Examples/javascript/simple/example.cxx
deleted file mode 100644
index 1c2af78..0000000
--- a/Examples/javascript/simple/example.cxx
+++ /dev/null
@@ -1,18 +0,0 @@
-/* File : example.c */
-
-/* A global variable */
-double Foo = 3.0;
-
-/* Compute the greatest common divisor of positive integers */
-int gcd(int x, int y) {
-  int g;
-  g = y;
-  while (x > 0) {
-    g = x;
-    x = y % x;
-    y = g;
-  }
-  return g;
-}
-
-
diff --git a/Examples/javascript/template/Makefile b/Examples/javascript/template/Makefile
index 0402f8d..8085356 100644
--- a/Examples/javascript/template/Makefile
+++ b/Examples/javascript/template/Makefile
@@ -1,3 +1,3 @@
-SRCS =
+_CPP = _cpp
 
 include $(SRCDIR)../example.mk
diff --git a/Examples/javascript/variables/Makefile b/Examples/javascript/variables/Makefile
index 54a8f7b..413b64b 100644
--- a/Examples/javascript/variables/Makefile
+++ b/Examples/javascript/variables/Makefile
@@ -1,3 +1,3 @@
-SRCS = example.cxx
+SRCS = example.c
 
 include $(SRCDIR)../example.mk
diff --git a/Examples/javascript/variables/binding.gyp.in b/Examples/javascript/variables/binding.gyp.in
index cb2b45e..cfd4854 100644
--- a/Examples/javascript/variables/binding.gyp.in
+++ b/Examples/javascript/variables/binding.gyp.in
@@ -2,7 +2,7 @@
   "targets": [
     {
       "target_name": "example",
-      "sources": [ "<!(cp $srcdir/example.cxx example-gypcopy.cxx && echo example-gypcopy.cxx)", "example_wrap.cxx" ],
+      "sources": [ "<!(cp $srcdir/example.c example-gypcopy.cxx && echo example-gypcopy.cxx)", "example_wrap.cxx" ],
       "include_dirs": ["$srcdir"]
     }
   ]
diff --git a/Examples/javascript/variables/example.cxx b/Examples/javascript/variables/example.c
similarity index 100%
rename from Examples/javascript/variables/example.cxx
rename to Examples/javascript/variables/example.c
diff --git a/Examples/lua/arrays/example.i b/Examples/lua/arrays/example.i
index eafd8ff..54bc31b 100644
--- a/Examples/lua/arrays/example.i
+++ b/Examples/lua/arrays/example.i
@@ -9,12 +9,12 @@
 
 %include <carrays.i>    // array helpers
 
-// this declares a batch of function for manipulating C integer arrays
+// this declares a batch of functions for manipulating C integer arrays
 %array_functions(int,int)
 
 // this adds some lua code directly into the module
 // warning: you need the example. prefix if you want it added into the module
-// admittedly this code is a bit tedious, but its a one off effort
+// admittedly this code is a bit tedious, but it's a one off effort
 %luacode {
 function example.sort_int2(t)
 -- local len=table.maxn(t) -- the len - maxn deprecated in 5.3
diff --git a/Examples/lua/constants/runme.lua b/Examples/lua/constants/runme.lua
index ad6bd45..bc7ca24 100644
--- a/Examples/lua/constants/runme.lua
+++ b/Examples/lua/constants/runme.lua
@@ -30,6 +30,6 @@
 end
 
 -- these should fail
--- example.EXTERN is a nil value, so concatentatin will make it fail
+-- example.EXTERN is a nil value, so concatenation will make it fail
 checkfail(function() print("EXTERN = "..example.EXTERN) end)
 checkfail(function() print("FOO = "..example.FOO) end)
diff --git a/Examples/lua/embed/embed.c b/Examples/lua/embed/embed.c
index 1f10cc8..2cb4728 100644
--- a/Examples/lua/embed/embed.c
+++ b/Examples/lua/embed/embed.c
@@ -23,7 +23,7 @@
 #define lua_open luaL_newstate
 #endif
 
-/* the SWIG wrappered library */
+/* the SWIG wrapped library */
 extern int luaopen_example(lua_State*L);
 
 /* a really simple way of calling lua from C
diff --git a/Examples/lua/embed2/embed2.c b/Examples/lua/embed2/embed2.c
index 0ce9f8f..5507877 100644
--- a/Examples/lua/embed2/embed2.c
+++ b/Examples/lua/embed2/embed2.c
@@ -41,7 +41,7 @@
 
 /* This is an example of how to call the Lua function
     int add(int,int) 
-  its very tedious, but gives you an idea of the issues involved.
+  it's very tedious, but gives you an idea of the issues involved.
   (look below for a better idea)
 */
 int call_add(lua_State *L,int a,int b,int* res) {
@@ -75,7 +75,7 @@
   return 1;
 }
 
-/* This is a variargs call function for calling from C into Lua.
+/* This is a varargs call function for calling from C into Lua.
 Original Code from Programming in Lua (PIL) by Roberto Ierusalimschy
 ISBN 85-903798-1-7 
 http://www.lua.org/pil/25.3.html
@@ -186,7 +186,7 @@
   luaopen_base(L);
   luaopen_string(L);
   luaopen_math(L);
-  printf("[C] now loading the SWIG wrappered library\n");
+  printf("[C] now loading the SWIG wrapped library\n");
   luaopen_example(L);
   printf("[C] all looks ok\n");
   printf("\n");
@@ -226,8 +226,8 @@
   printf("\n");
   printf("[C] Note: no protection if you mess up the va-args, this is C\n");
   printf("\n");
-  printf("[C] Finally we will call the wrappered gcd function gdc(6,9):\n");
-  printf("[C] This will pass the values to Lua, then call the wrappered function\n");
+  printf("[C] Finally we will call the wrapped gcd function gdc(6,9):\n");
+  printf("[C] This will pass the values to Lua, then call the wrapped function\n");
   printf("    Which will get the values from Lua, call the C code \n");
   printf("    and return the value to Lua and eventually back to C\n");
   printf("[C] Certainly not the best way to do it :-)\n");
diff --git a/Examples/lua/embed3/embed3.cpp b/Examples/lua/embed3/embed3.cpp
index 9be49ad..c3c5d38 100644
--- a/Examples/lua/embed3/embed3.cpp
+++ b/Examples/lua/embed3/embed3.cpp
@@ -61,7 +61,7 @@
 
 /* This is an example of how to call the Lua function
     void onEvent(Event e) 
-  its very tedious, but gives you an idea of the issues involed.
+  it's very tedious, but gives you an idea of the issues involved.
 */
 int call_onEvent(lua_State *L, Event e) {
   int top;
@@ -105,7 +105,7 @@
   /* this code will pass a pointer into lua, but C++ still owns the object
   this is a little tedious, to do, but let's do it
   we need to pass the pointer (obviously), the type name 
-  and a flag which states if Lua should delete the pointer once its finished with it
+  and a flag which states if Lua should delete the pointer once it's finished with it
   The type name is a class name string which is registered with SWIG
   (normally, just look in the wrapper file to get this)
   in this case we don't want Lua to delete the pointer so the ownership flag is 0
diff --git a/Examples/lua/exception/example.h b/Examples/lua/exception/example.h
index bc744cd..c76c46a 100644
--- a/Examples/lua/exception/example.h
+++ b/Examples/lua/exception/example.h
@@ -10,7 +10,7 @@
 public:
   Exc(int c, const char *m) {
     code = c;
-    strncpy(msg,m,256);
+    strncpy(msg,m,255);
   }
   int code;
   char msg[256];
diff --git a/Examples/lua/lua.c b/Examples/lua/lua.c
index 8cffaa5..a153337 100644
--- a/Examples/lua/lua.c
+++ b/Examples/lua/lua.c
@@ -291,7 +291,7 @@
     }
   }
   lua_settop(L, 0);  /* clear stack */
-  fputs("\n", stdout);
+  fputc('\n', stdout);
   progname = oldprogname;
 }
 
diff --git a/Examples/lua/nspace/example.h b/Examples/lua/nspace/example.h
index 5306698..b2e46e9 100644
--- a/Examples/lua/nspace/example.h
+++ b/Examples/lua/nspace/example.h
@@ -1,5 +1,5 @@
-#ifndef _example_guardian_
-#define _example_guardian_
+#ifndef EXAMPLE_H
+#define EXAMPLE_H
 
 int module_function() { return 7; }
 int module_variable = 9;
diff --git a/Examples/lua/owner/example.cxx b/Examples/lua/owner/example.cxx
index c2c073d..a4dcc68 100644
--- a/Examples/lua/owner/example.cxx
+++ b/Examples/lua/owner/example.cxx
@@ -3,7 +3,9 @@
 #include "example.h"
 #include <stdio.h>
 
+#ifndef M_PI
 #define M_PI 3.14159265358979323846
+#endif
 
 /* Move the shape to a new location */
 void Shape::move(double dx, double dy) {
diff --git a/Examples/modula3/check.list b/Examples/modula3/check.list
deleted file mode 100644
index 37ac8c1..0000000
--- a/Examples/modula3/check.list
+++ /dev/null
@@ -1,7 +0,0 @@
-# see top-level Makefile.in
-class
-enum
-exception
-reference
-simple
-typemap
diff --git a/Examples/modula3/class/Makefile b/Examples/modula3/class/Makefile
deleted file mode 100644
index b25f636..0000000
--- a/Examples/modula3/class/Makefile
+++ /dev/null
@@ -1,26 +0,0 @@
-TOP        = ../..
-SWIGEXE    = $(TOP)/../swig
-SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-SRCS       =
-TARGET     = example
-PLATFORM   = LINUXLIBC6
-INTERFACE  = example.i
-SWIGOPT    = -c++
-MODULA3SRCS = *.[im]3
-
-check: build
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_run
-
-build:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' modula3
-	m3ppinplace $(MODULA3SRCS)
-# compilation of example_wrap.cxx is started by cm3
-#	$(CXX) -c $(TARGET)_wrap.cxx
-	mv example_wrap.cxx m3makefile $(MODULA3SRCS) src/
-	ln -sf ../example.h src/example.h
-	cm3
-
-clean:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_clean
diff --git a/Examples/modula3/class/example.cxx b/Examples/modula3/class/example.cxx
deleted file mode 100644
index 0463045..0000000
--- a/Examples/modula3/class/example.cxx
+++ /dev/null
@@ -1,28 +0,0 @@
-/* File : example.cxx */
-
-#include "example.h"
-#define M_PI 3.14159265358979323846
-
-/* Move the shape to a new location */
-void Shape::move(double dx, double dy) {
-  x += dx;
-  y += dy;
-}
-
-int Shape::nshapes = 0;
-
-double Circle::area() {
-  return M_PI*radius*radius;
-}
-
-double Circle::perimeter() {
-  return 2*M_PI*radius;
-}
-
-double Square::area() {
-  return width*width;
-}
-
-double Square::perimeter() {
-  return 4*width;
-}
diff --git a/Examples/modula3/class/example.h b/Examples/modula3/class/example.h
deleted file mode 100644
index 0dff185..0000000
--- a/Examples/modula3/class/example.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* File : example.h */
-
-class Shape {
-public:
-  Shape() {
-    nshapes++;
-  }
-  virtual ~Shape() {
-    nshapes--;
-  }
-  double  x, y;
-  void    move(double dx, double dy);
-  virtual double area() = 0;
-  virtual double perimeter() = 0;
-  static  int nshapes;
-};
-
-class Circle : public Shape {
-private:
-  double radius;
-public:
-  Circle(double r) : radius(r) { }
-  virtual double area();
-  virtual double perimeter();
-};
-
-class Square : public Shape {
-private:
-  double width;
-public:
-  Square(double w) : width(w) { }
-  virtual double area();
-  virtual double perimeter();
-};
diff --git a/Examples/modula3/class/example.i b/Examples/modula3/class/example.i
deleted file mode 100644
index 2fafadb..0000000
--- a/Examples/modula3/class/example.i
+++ /dev/null
@@ -1,32 +0,0 @@
-/* File : example.i */
-%module Example
-
-%{
-#include "example.h"
-%}
-
-%insert(m3makefile) %{template("../swig")
-cxx_source("example_wrap")%}
-
-%typemap(m3rawinmode)    Shape *, Circle *, Square * ""
-%typemap(m3rawrettype)   Shape *, Circle *, Square * "$1_basetype"
-
-%typemap(m3wrapinmode)   Shape *, Circle *, Square * ""
-%typemap(m3wrapargraw)   Shape *, Circle *, Square * "self.cxxObj"
-
-%typemap(m3wrapretvar)   Circle *, Square * "cxxObj : ExampleRaw.$1_basetype;"
-%typemap(m3wrapretraw)   Circle *, Square * "cxxObj"
-%typemap(m3wrapretconv)  Circle *, Square * "NEW($1_basetype,cxxObj:=cxxObj)"
-%typemap(m3wraprettype)  Circle *, Square * "$1_basetype"
-
-/* Should work with and without renaming
-%rename(M3Shape) Shape;
-%rename(M3Circle) Circle;
-%rename(M3Square) Square;
-%typemap(m3wrapintype)   Shape *, Circle *, Square * "M3$1_basetype"
-%typemap(m3wraprettype)  Shape *, Circle *, Square * "M3$1_basetype"
-%typemap(m3wrapretconv)           Circle *, Square * "NEW(M3$1_basetype,cxxObj:=cxxObj)"
-*/
-
-/* Let's just grab the original header file here */
-%include "example.h"
diff --git a/Examples/modula3/class/swig.tmpl b/Examples/modula3/class/swig.tmpl
deleted file mode 100644
index e3e9bf1..0000000
--- a/Examples/modula3/class/swig.tmpl
+++ /dev/null
@@ -1,11 +0,0 @@
-
-readonly proc cxx_source (X) is
-  local cxxfile = X&".cxx"
-  local objfile = X&".o"
-  %exec("echo $PWD")
-  if stale(objfile,cxxfile)
-    exec("cd",path(),"; g++ -I.. -c -o",objfile,cxxfile)
-  end
-  import_obj(X)
-  %unlink_file(path()&SL&objfile)
-end
diff --git a/Examples/modula3/enum/Makefile b/Examples/modula3/enum/Makefile
deleted file mode 100644
index 2c5c9b0..0000000
--- a/Examples/modula3/enum/Makefile
+++ /dev/null
@@ -1,27 +0,0 @@
-TOP        = ../..
-SWIGEXE    = $(TOP)/../swig
-SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-SRCS       =
-TARGET     = example
-INTERFACE  = example.i
-CONSTNUMERIC = example_const
-SWIGOPT      = -c++
-MODULA3SRCS  = *.[im]3
-
-check: build
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_run
-
-build:
-	$(SWIGEXE) -modula3 $(SWIGOPT) -module Example -generateconst $(CONSTNUMERIC) $(TARGET).h
-	$(CXX) -Wall $(CONSTNUMERIC).c -o $(CONSTNUMERIC)
-	$(CONSTNUMERIC) >$(CONSTNUMERIC).i
-
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' modula3
-	m3ppinplace $(MODULA3SRCS)
-	mv m3makefile $(MODULA3SRCS) src/
-	cm3
-
-clean:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_clean
diff --git a/Examples/modula3/enum/example.cxx b/Examples/modula3/enum/example.cxx
deleted file mode 100644
index bd808ff..0000000
--- a/Examples/modula3/enum/example.cxx
+++ /dev/null
@@ -1,32 +0,0 @@
-/* File : example.cxx */
-
-#include "example.h"
-#include <stdio.h>
-
-void Foo::enum_test(speed s) {
-  if (s == IMPULSE) {
-    printf("IMPULSE speed\n");
-  } else if (s == WARP) {
-    printf("WARP speed\n");
-  } else if (s == LUDICROUS) {
-    printf("LUDICROUS speed\n");
-  } else if (s == HYPER) {
-    printf("HYPER speed\n");
-  } else {
-    printf("Unknown speed\n");
-  }
-}
-
-void enum_test(color c, Foo::speed s) {
-  if (c == RED) {
-    printf("color = RED, ");
-  } else if (c == BLUE) {
-    printf("color = BLUE, ");
-  } else if (c == GREEN) {
-    printf("color = GREEN, ");
-  } else {
-    printf("color = Unknown color!, ");
-  }
-  Foo obj;
-  obj.enum_test(s);
-}
diff --git a/Examples/modula3/enum/example.h b/Examples/modula3/enum/example.h
deleted file mode 100644
index 2f44a6c..0000000
--- a/Examples/modula3/enum/example.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/* File : example.h */
-
-#define PI 3.141
-
-#define DAY_MONDAY    0
-#define DAY_TUESDAY   1
-#define DAY_WEDNESDAY 2
-#define DAY_THURSDAY  3
-#define DAY_FRIDAY    4
-#define DAY_SATURDAY  5
-#define DAY_SUNDAY    6
-
-enum color { BLUE, RED, GREEN };
-
-#define CLB_BLACK   0
-#define CLB_BLUE    1
-#define CLB_RED     2
-#define CLB_MAGENTA 3
-#define CLB_GREEN   4
-#define CLB_CYAN    5
-#define CLB_YELLOW  6
-#define CLB_WHITE   7
-
-/* Using this would be good style
-   which cannot be expected for general C header files.
-   Instead I want to demonstrate how to live without it.
-enum month {
-  MTHF_JANUARY,
-  MTHF_FEBRUARY,
-  MTHF_MARCH,
-  MTHF_APRIL,
-  MTHF_MAY,
-  MTHF_JUNE,
-  MTHF_JULY,
-  MTHF_AUGUST,
-  MTHF_SEPTEMBER,
-  MTHF_OCTOBER,
-  MTHF_NOVEMBER,
-  MTHF_DECEMBER,
-}
-*/
-
-/* Since there are no compile time constants in C / C++
-   it is a common abuse
-   to declare bit set (flag) constants
-   as enumerations. */
-enum calendar {
-  MTHB_JANUARY   = 1 <<  0,     /* 1 << MTHF_JANUARY, */
-  MTHB_FEBRUARY  = 1 <<  1,     /* 1 << MTHF_FEBRUARY, */
-  MTHB_MARCH     = 1 <<  2,     /* 1 << MTHF_MARCH, */
-  MTHB_APRIL     = 1 <<  3,     /* 1 << MTHF_APRIL, */
-  MTHB_MAY       = 1 <<  4,     /* 1 << MTHF_MAY, */
-  MTHB_JUNE      = 1 <<  5,     /* 1 << MTHF_JUNE, */
-  MTHB_JULY      = 1 <<  6,     /* 1 << MTHF_JULY, */
-  MTHB_AUGUST    = 1 <<  7,     /* 1 << MTHF_AUGUST, */
-  MTHB_SEPTEMBER = 1 <<  8,     /* 1 << MTHF_SEPTEMBER, */
-  MTHB_OCTOBER   = 1 <<  9,     /* 1 << MTHF_OCTOBER, */
-  MTHB_NOVEMBER  = 1 << 10,     /* 1 << MTHF_NOVEMBER, */
-  MTHB_DECEMBER  = 1 << 11,     /* 1 << MTHF_DECEMBER, */
-
-  MTHB_SPRING    = MTHB_MARCH     | MTHB_APRIL   | MTHB_MAY,
-  MTHB_SUMMER    = MTHB_JUNE      | MTHB_JULY    | MTHB_AUGUST,
-  MTHB_AUTUMN    = MTHB_SEPTEMBER | MTHB_OCTOBER | MTHB_NOVEMBER,
-  MTHB_WINTER    = MTHB_DECEMBER  | MTHB_JANUARY | MTHB_FEBRUARY,
-};
-
-
-namespace Answer {
-  enum {
-    UNIVERSE_AND_EVERYTHING = 42,
-    SEVENTEEN_AND_FOUR = 21,
-    TWOHUNDRED_PERCENT_OF_NOTHING = 0,
-  };
-
-  class Foo {
-   public:
-    Foo() { }
-    enum speed { IMPULSE  = -2, WARP = 0, HYPER, LUDICROUS = 3};
-    void enum_test(speed s);
-  };
-};
-
-void enum_test(color c, Answer::Foo::speed s);
diff --git a/Examples/modula3/enum/example.i b/Examples/modula3/enum/example.i
deleted file mode 100644
index f5947b3..0000000
--- a/Examples/modula3/enum/example.i
+++ /dev/null
@@ -1,72 +0,0 @@
-/* File : example.i */
-%module Example
-
-%{
-#include "example.h"
-%}
-
-%include "example_const.i"
-
-// such features are generated by the following pragmas
-#if 0
-%feature("modula3:enumitem:enum","Days")    DAY_MONDAY;
-%feature("modula3:enumitem:name","monday")  DAY_MONDAY;
-%feature("modula3:enumitem:conv","int:int") DAY_MONDAY;
-
-%feature("modula3:enumitem:enum","Month")     MTHB_JANUARY;
-%feature("modula3:enumitem:name","january")   MTHB_JANUARY;
-%feature("modula3:enumitem:conv","set:int")   MTHB_JANUARY;
-//%feature("modula3:constset:type","MonthSet")      MTHB_JANUARY;  /*type in the constant definition*/
-%feature("modula3:constset:set", "MonthSet")      MTHB_JANUARY;  /*remarks that the 'type' is a set type*/
-%feature("modula3:constset:base","Month")         MTHB_JANUARY;
-%feature("modula3:constset:name","monthsJanuary") MTHB_JANUARY;
-%feature("modula3:constset:conv","set:set")       MTHB_JANUARY;  /*conversion of the bit pattern: no change*/
-
-%feature("modula3:enumitem:enum","Color")     BLUE;
-%feature("modula3:enumitem:name","blue")      BLUE;
-%feature("modula3:enumitem:conv","int:int")   BLUE;
-
-%feature("modula3:constint:type","INTEGER") Foo::IMPULSE;
-%feature("modula3:constint:name","impulse") Foo::IMPULSE;
-%feature("modula3:constint:conv","int:int") Foo::IMPULSE;
-#endif
-
-%rename(pi) PI;
-
-%pragma(modula3) enumitem="prefix=DAY_;int;srcstyle=underscore;Day";
-
-%pragma(modula3) enumitem="enum=color;int;srcstyle=underscore;Color";
-%pragma(modula3) makesetofenum="Color";
-%pragma(modula3) constset="prefix=CLB_;set;srcstyle=underscore,prefix=clb;ColorSet,Color";
-
-%pragma(modula3) enumitem="prefix=MTHB_,enum=calendar;set;srcstyle=underscore;Month";
-%pragma(modula3) makesetofenum="Month";
-%pragma(modula3) constset="prefix=MTHB_,enum=calendar;set;srcstyle=underscore,prefix=monthset;MonthSet,Month";
-
-%pragma(modula3) constint="prefix=Answer::Foo::,enum=Answer::Foo::speed;int;srcstyle=underscore,prefix=speed;INTEGER";
-
-%pragma(modula3) constint="prefix=Answer::,enum=Answer::;int;srcstyle=underscore,prefix=answer;CARDINAL";
-
-%rename(AnswerFoo) Answer::Foo;
-%typemap("m3rawrettype")   Answer::Foo * %{AnswerFoo%}
-%typemap("m3rawintype")    Answer::Foo * %{AnswerFoo%}
-%typemap("m3rawinmode")    Answer::Foo * %{%}
-%typemap("m3wraprettype")  Answer::Foo * %{AnswerFoo%}
-%typemap("m3wrapintype")   Answer::Foo * %{AnswerFoo%}
-%typemap("m3wrapinmode")   Answer::Foo * %{%}
-%typemap("m3wrapargraw")   Answer::Foo * %{self.cxxObj%}
-
-%typemap("m3wrapretvar")   Answer::Foo * %{cxxObj : ExampleRaw.AnswerFoo;%}
-%typemap("m3wrapretraw")   Answer::Foo * %{cxxObj%}
-%typemap("m3wrapretconv")  Answer::Foo * %{NEW(AnswerFoo,cxxObj:=cxxObj)%}
-
-
-%typemap("m3rawintype")        Answer::Foo::speed %{C.int%};
-%typemap("m3rawintype:import") Answer::Foo::speed %{Ctypes AS C%};
-%typemap("m3wrapintype")       Answer::Foo::speed %{[-2..3]%};
-
-%typemap("m3wrapintype")       color %{Color%};
-%typemap("m3wrapargraw")       color %{ORD($1_name)%};
-
-/* Let's just grab the original header file here */
-%include "example.h"
diff --git a/Examples/modula3/exception/Makefile b/Examples/modula3/exception/Makefile
deleted file mode 100644
index 8d12ef1..0000000
--- a/Examples/modula3/exception/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-TOP        = ../..
-SWIGEXE    = $(TOP)/../swig
-SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-CXXSRCS    = example.cxx
-TARGET     = example
-INTERFACE  = example.i
-SWIGOPT    =
-MODULA3SRCS = *.[im]3
-MODULA3FLAGS= -o runme
-
-check: build
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_run
-
-build:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' modula3_cpp
-#	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' MODULA3SRCS='$(MODULA3SRCS)' MODULA3FLAGS='$(MODULA3FLAGS)' modula3_compile
-	m3ppinplace $(MODULA3SRCS)
-	mv m3makefile $(MODULA3SRCS) src/
-	cm3
-
-clean:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_clean
diff --git a/Examples/modula3/exception/example.h b/Examples/modula3/exception/example.h
deleted file mode 100644
index 0e9e0e8..0000000
--- a/Examples/modula3/exception/example.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/* File : example.h */
-
-enum error {OK, OVERFLOW, DIVISION_BY_ZERO, NEGATIVE_RADICAND, NEGATIVE_BASE};
-typedef error errorstate;  /* just to separate the typemaps */
-
-error acc_add (double &x, double y);
-error acc_sub (double &x, double y);
-error acc_mul (double &x, double y);
-error acc_div (double &x, double y);
-
-double op_add (double x, double y, errorstate &err);
-double op_sub (double x, double y, errorstate &err);
-double op_mul (double x, double y, errorstate &err);
-double op_div (double x, double y, errorstate &err);
-double op_sqrt (double x, errorstate &err);
-double op_pow (double x, double y, errorstate &err);
-
-double op_noexc (double x, double y);
diff --git a/Examples/modula3/exception/example.i b/Examples/modula3/exception/example.i
deleted file mode 100644
index 92a716f..0000000
--- a/Examples/modula3/exception/example.i
+++ /dev/null
@@ -1,43 +0,0 @@
-/* File : example.i */
-%module Example
-
-%{
-#include "example.h"
-%}
-
-%insert(m3wrapintf) %{
-EXCEPTION E(Error);
-%}
-%insert(m3wrapimpl) %{
-IMPORT Ctypes AS C;
-%}
-
-%pragma(modula3) enumitem="enum=error;int;srcstyle=underscore;Error";
-
-%typemap("m3rawintype")   double & %{C.double%};
-%typemap("m3wrapintype")  double & %{LONGREAL%};
-
-%typemap("m3wraprettype") error ""
-%typemap("m3wrapretvar") error "rawerr: C.int;"
-%typemap("m3wrapretraw")  error "rawerr"
-%typemap("m3wrapretcheck:throws") error "E"
-%typemap("m3wrapretcheck") error
-%{VAR err := VAL(rawerr, Error);
-BEGIN
-IF err # Error.ok THEN
-RAISE E(err);
-END;
-END;%}
-
-%typemap("m3rawintype")              errorstate & %{C.int%};
-%typemap("m3wrapintype",numinputs=0) errorstate & %{%};
-%typemap("m3wrapargvar")             errorstate & %{err:C.int:=ORD(Error.ok);%};
-%typemap("m3wrapoutcheck:throws")    errorstate & "E";
-%typemap("m3wrapoutcheck")           errorstate &
-%{IF VAL(err,Error) # Error.ok THEN
-RAISE E(VAL(err,Error));
-END;%}
-
-/* Let's just grab the original header file here */
-
-%include "example.h"
diff --git a/Examples/modula3/reference/Makefile b/Examples/modula3/reference/Makefile
deleted file mode 100644
index eaceceb..0000000
--- a/Examples/modula3/reference/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-TOP        = ../..
-SWIGEXE    = $(TOP)/../swig
-SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-SRCS       =
-TARGET     = example
-INTERFACE  = example.i
-SWIGOPT    = -c++
-MODULA3SRCS = *.[im]3
-
-check: build
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_run
-
-build:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' modula3
-	m3ppinplace $(MODULA3SRCS)
-	mv m3makefile $(MODULA3SRCS) src/
-	cm3
-
-clean:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_clean
diff --git a/Examples/modula3/reference/example.cxx b/Examples/modula3/reference/example.cxx
deleted file mode 100644
index 9dbaed2..0000000
--- a/Examples/modula3/reference/example.cxx
+++ /dev/null
@@ -1,46 +0,0 @@
-/* File : example.cxx */
-
-/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
-#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER)
-# define _CRT_SECURE_NO_DEPRECATE
-#endif
-
-#include "example.h"
-#include <stdio.h>
-#include <stdlib.h>
-
-Vector operator+(const Vector &a, const Vector &b) {
-  Vector r;
-  r.x = a.x + b.x;
-  r.y = a.y + b.y;
-  r.z = a.z + b.z;
-  return r;
-}
-
-char *Vector::print() {
-  static char temp[512];
-  sprintf(temp,"Vector %p (%g,%g,%g)", (void *)this, x,y,z);
-  return temp;
-}
-
-VectorArray::VectorArray(int size) {
-  items = new Vector[size];
-  maxsize = size;
-}
-
-VectorArray::~VectorArray() {
-  delete [] items;
-}
-
-Vector &VectorArray::operator[](int index) {
-  if ((index < 0) || (index >= maxsize)) {
-    printf("Panic! Array index out of bounds.\n");
-    exit(1);
-  }
-  return items[index];
-}
-
-int VectorArray::size() {
-  return maxsize;
-}
-
diff --git a/Examples/modula3/reference/example.h b/Examples/modula3/reference/example.h
deleted file mode 100644
index 7b4ba8f..0000000
--- a/Examples/modula3/reference/example.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* File : example.h */
-
-struct Vector {
-private:
-  double x,y,z;
-public:
-  Vector() : x(0), y(0), z(0) { }
-  Vector(double x, double y, double z) : x(x), y(y), z(z) { }
-  Vector operator+(const Vector &b) const;
-  char *print();
-};
-
-struct VectorArray {
-private:
-  Vector *items;
-  int     maxsize;
-public:
-  VectorArray(int maxsize);
-  ~VectorArray();
-  Vector &operator[](int);
-  int size();
-};
diff --git a/Examples/modula3/reference/example.i b/Examples/modula3/reference/example.i
deleted file mode 100644
index 0020909..0000000
--- a/Examples/modula3/reference/example.i
+++ /dev/null
@@ -1,32 +0,0 @@
-/* File : example.i */
-
-/* This file has a few "typical" uses of C++ references. */
-
-%module Example
-
-%{
-#include "example.h"
-%}
-
-%pragma(modula3) unsafe="1";
-
-%insert(m3wrapintf) %{FROM ExampleRaw IMPORT Vector, VectorArray;%}
-%insert(m3wrapimpl) %{FROM ExampleRaw IMPORT Vector, VectorArray;%}
-
-%typemap(m3wrapretvar)  Vector %{vec: UNTRACED REF Vector;%}
-%typemap(m3wrapretraw)  Vector %{vec%}
-%typemap(m3wrapretconv) Vector %{vec^%}
-
-
-/* This helper function calls an overloaded operator */
-%inline %{
-Vector addv(const Vector &a, const Vector &b) {
-  return a+b;
-}
-%}
-
-%rename(Vector_Clear) Vector::Vector();
-%rename(Add) Vector::operator+;
-%rename(GetItem) VectorArray::operator[];
-
-%include "example.h"
diff --git a/Examples/modula3/simple/Makefile b/Examples/modula3/simple/Makefile
deleted file mode 100644
index 3ba35d1..0000000
--- a/Examples/modula3/simple/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-TOP        = ../..
-SWIGEXE    = $(TOP)/../swig
-SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-SRCS       =
-TARGET     = example
-INTERFACE  = example.i
-SWIGOPT    =
-MODULA3SRCS = *.[im]3
-
-check: build
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_run
-
-build:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' modula3
-	m3ppinplace $(MODULA3SRCS)
-	mv m3makefile $(MODULA3SRCS) src/
-	cm3
-
-clean:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_clean
diff --git a/Examples/modula3/simple/example.i b/Examples/modula3/simple/example.i
deleted file mode 100644
index 1694e6d..0000000
--- a/Examples/modula3/simple/example.i
+++ /dev/null
@@ -1,7 +0,0 @@
-/* File : example.i */
-%module Example
-
-%inline %{
-extern int    gcd(int x, int y);
-extern double Foo;
-%}
diff --git a/Examples/modula3/typemap/Makefile b/Examples/modula3/typemap/Makefile
deleted file mode 100644
index 3ba35d1..0000000
--- a/Examples/modula3/typemap/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-TOP        = ../..
-SWIGEXE    = $(TOP)/../swig
-SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-SRCS       =
-TARGET     = example
-INTERFACE  = example.i
-SWIGOPT    =
-MODULA3SRCS = *.[im]3
-
-check: build
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_run
-
-build:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' modula3
-	m3ppinplace $(MODULA3SRCS)
-	mv m3makefile $(MODULA3SRCS) src/
-	cm3
-
-clean:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' modula3_clean
diff --git a/Examples/modula3/typemap/example.i b/Examples/modula3/typemap/example.i
deleted file mode 100644
index 2f454ef..0000000
--- a/Examples/modula3/typemap/example.i
+++ /dev/null
@@ -1,90 +0,0 @@
-/* File : example.i */
-%module Example
-
-%pragma(modula3) unsafe="true";
-
-%insert(m3wrapintf) %{FROM ExampleRaw IMPORT Window, Point;
-%}
-%insert(m3wrapimpl) %{FROM ExampleRaw IMPORT Window, Point;
-IMPORT M3toC;
-IMPORT Ctypes AS C;
-%}
-
-/* Typemap applied to patterns of multiple arguments */
-
-%typemap(m3rawinmode)   (char *outstr) %{VAR%}
-%typemap(m3rawintype)   (char *outstr) %{CHAR%}
-%typemap(m3wrapinmode)  (char *outstr, int size) %{VAR%}
-%typemap(m3wrapintype)  (char *outstr, int size) %{ARRAY OF CHAR%}
-%typemap(m3wrapargraw)  (char *outstr, int size) %{$1_name[0], NUMBER($1_name)%}
-
-
-%typemap(m3rawinmode)   (const struct Window *) %{READONLY%}
-%typemap(m3wrapinmode)  (const struct Window *) %{READONLY%}
-%typemap(m3rawintype)   (      struct Window *) %{Window%}
-%typemap(m3wrapintype)  (      struct Window *) %{Window%}
-
-%typemap(m3rawinmode)   (const char *str []) %{READONLY%}
-%typemap(m3wrapinmode)  (const char *str []) %{READONLY%}
-%typemap(m3rawintype)   (const char *str []) %{(*ARRAY OF*) C.char_star%}
-%typemap(m3wrapintype)  (const char *str []) %{ARRAY OF TEXT%}
-%typemap(m3wrapargvar)  (const char *str []) %{$1: REF ARRAY OF C.char_star;%}
-%typemap(m3wrapargraw)  (const char *str []) %{$1[0]%}
-%typemap(m3wrapinconv)  (const char *str []) %{$1:= NEW(REF ARRAY OF C.char_star,NUMBER($1_name));
-FOR i:=FIRST($1_name) TO LAST($1_name) DO
-$1[i]:=M3toC.SharedTtoS($1_name[i]);
-END;%}
-%typemap(m3wrapfreearg) (const char *str [])
-%{FOR i:=FIRST($1_name) TO LAST($1_name) DO
-M3toC.FreeSharedS($1_name[i],$1[i]);
-END;%}
-
-%typemap(m3wraprettype) char * %{TEXT%}
-%typemap(m3wrapretvar)  char * %{result_string: C.char_star;%}
-%typemap(m3wrapretraw)  char * %{result_string%}
-%typemap(m3wrapretconv) char * %{M3toC.CopyStoT(result_string)%}
-
-struct Window {
-  char *label;
-  int left,top,width,height;
-};
-
-
-%typemap(m3wrapinname) (int x, int y) %{p%}
-%typemap(m3wrapinmode) (int x, int y) %{READONLY%}
-%typemap(m3wrapintype) (int x, int y) %{Point%}
-%typemap(m3wrapargraw) (int x, int y) %{p.$1_name, p.$2_name%}
-
-%typemap(m3wrapargraw)  (int &x, int &y) %{p.$1_name, p.$2_name%}
-%typemap(m3wrapintype)  (int &x, int &y) %{Point%}
-%typemap(m3wrapoutname) (int &x, int &y) %{p%}
-%typemap(m3wrapouttype) (int &x, int &y) %{Point%}
-%typemap(m3wrapargdir)  (int &x, int &y) "out"
-
-
-%typemap(m3wrapargvar)  int &left, int &top, int &width, int &height "$1:C.int;"
-%typemap(m3wrapargraw)  int &left, int &top, int &width, int &height "$1"
-%typemap(m3wrapoutconv) int &left, int &top, int &width, int &height "$1"
-
-%typemap(m3wrapargdir)  int &left, int &top "out"
-
-%typemap(m3wrapouttype) int &width, int &height "CARDINAL"
-%typemap(m3wrapargdir)  int &width, int &height "out"
-
-struct Point {
-  int x,y;
-};
-
-%m3multiretval get_box;
-
-void  set_label       (      struct Window *win, const char *str, bool activate);
-void  set_multi_label (      struct Window *win, const char *str []);
-void  write_label     (const struct Window *win,       char *outstr, int size);
-int   get_label       (const struct Window *win,       char *outstr, int size);
-char *get_label_ptr   (const struct Window *win);
-void  move(struct Window *win, int x, int y);
-int   get_area(const struct Window *win);
-void  get_box(const struct Window *win, int &left, int &top, int &width, int &height);
-void  get_left(const struct Window *win, int &left);
-void  get_mouse(const struct Window *win, int &x, int &y);
-int   get_attached_data(const struct Window *win, const char *id);
diff --git a/Examples/ocaml/shapes/example.i b/Examples/ocaml/shapes/example.i
index ac0fa4a..a261b92 100644
--- a/Examples/ocaml/shapes/example.i
+++ b/Examples/ocaml/shapes/example.i
@@ -1,10 +1,8 @@
 /* File : example.i */
 %module(directors="1") example
-#ifndef SWIGSEXP
 %{
 	#include "example.h"
 %}
-#endif
 
 %feature("director");
 %include "example.h"
diff --git a/Examples/ocaml/std_vector/runme.ml b/Examples/ocaml/std_vector/runme.ml
index 0f5519b..dc2fcf9 100644
--- a/Examples/ocaml/std_vector/runme.ml
+++ b/Examples/ocaml/std_vector/runme.ml
@@ -23,13 +23,13 @@
 let rec fill_dv v x =
   if x < 0.0001 then v else 
     begin
-      v -> push_back ((x to float)) ;
+      ignore(v -> push_back ((x to float))) ;
       fill_dv v (x *. x)
     end
 let _ = fill_dv v 0.999
 let _ = print_DoubleVector v
 let u = new_IntVector '()
 let _ = for i = 1 to 4 do
-  u -> push_back ((i to int))
+  ignore(u -> push_back ((i to int)))
 done
 let _ = (print_float ((_average u) as float) ; print_newline ())
diff --git a/Examples/ocaml/stl/runme.ml b/Examples/ocaml/stl/runme.ml
index 2fa5d20..3875b2a 100644
--- a/Examples/ocaml/stl/runme.ml
+++ b/Examples/ocaml/stl/runme.ml
@@ -7,7 +7,7 @@
 
 let _ = 
   for i = 0 to (Array.length Sys.argv) - 1 do
-    let str = (Sys.argv.(i)) to string in v -> push_back (str)
+    let str = (Sys.argv.(i)) to string in ignore(v -> push_back (str))
   done
 
 let _ = _vec_write '(v)
diff --git a/Examples/ocaml/strings_test/example.i b/Examples/ocaml/strings_test/example.i
index d360715..e0697b0 100644
--- a/Examples/ocaml/strings_test/example.i
+++ b/Examples/ocaml/strings_test/example.i
@@ -12,4 +12,5 @@
 %}
 
 %include "std_string.i"
+%apply std::string& INOUT { std::string &inout }
 %include example.h
diff --git a/Examples/octave/check.list b/Examples/octave/check.list
index e9c7192..54a5910 100644
--- a/Examples/octave/check.list
+++ b/Examples/octave/check.list
@@ -8,8 +8,8 @@
 funcptr
 funcptr2
 functor
-operator
 module_load
+operator
 pointer
 reference
 simple
diff --git a/Examples/octave/example.mk b/Examples/octave/example.mk
index 1ab96f0..88608a1 100644
--- a/Examples/octave/example.mk
+++ b/Examples/octave/example.mk
@@ -8,25 +8,25 @@
 INTERFACE  = example.i
 
 check: build
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' octave_run
+	$(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' octave_run
 
 build:
 ifneq (,$(SRCS))
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
+	$(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
 	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
 	SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' octave
 else
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
+	$(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
 	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
 	SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' octave_cpp
 endif
 ifneq (,$(TARGET2)$(SWIGOPT2))
 ifneq (,$(SRCS))
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
+	$(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
 	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
 	SWIGOPT='$(SWIGOPT2)' TARGET='$(TARGET2)' INTERFACE='$(INTERFACE)' octave
 else
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
+	$(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
 	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
 	SWIGOPT='$(SWIGOPT2)' TARGET='$(TARGET2)' INTERFACE='$(INTERFACE)' octave_cpp
 endif
@@ -34,4 +34,4 @@
 
 
 clean:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' octave_clean
+	$(MAKE) -f $(TOP)/Makefile PCHSUPPORT=no SRCDIR='$(SRCDIR)' octave_clean
diff --git a/Examples/octave/module_load/runme.m b/Examples/octave/module_load/runme.m
index beab121..4e52c6e 100644
--- a/Examples/octave/module_load/runme.m
+++ b/Examples/octave/module_load/runme.m
@@ -19,7 +19,8 @@
 # load module in a function globally before base context
 clear all;
 function testme_1
-  assert(exist("swigexample") == 3);
+  % exist("swigexample") returns 1 (variable) in octave >= 4.4 < 6 but 3 (.oct file) in octave >= 6
+  assert(exist("swigexample"));
   swigexample;
   assert(isglobal("swigexample"));
   assert(cvar.ivar == ifunc);
@@ -32,7 +33,8 @@
 assert(cvar.ivar == ifunc);
 clear all
 function testme_2
-  assert(exist("swigexample") == 3);
+  % exist("swigexample") returns 1 (variable) in octave >= 4.4 < 6 but 3 (.oct file) in octave >= 6
+  assert(exist("swigexample"));
   swigexample;
   assert(isglobal("swigexample"));
   assert(cvar.ivar == ifunc);
@@ -52,7 +54,8 @@
 assert(isglobal("swigexample"));
 assert(cvar.ivar == ifunc);
 function testme_3
-  assert(exist("swigexample") == 3);
+  % exist("swigexample") returns 1 (variable) in octave >= 4.4 < 6 but 3 (.oct file) in octave >= 6
+  assert(exist("swigexample"));
   swigexample;
   assert(isglobal("swigexample"));
   assert(cvar.ivar == ifunc);
@@ -65,7 +68,8 @@
 assert(isglobal("swigexample"));
 assert(cvar.ivar == ifunc);
 function testme_4
-  assert(exist("swigexample") == 3);
+  % exist("swigexample") returns 1 (variable) in octave >= 4.4 < 6 but 3 (.oct file) in octave >= 6
+  assert(exist("swigexample"));
   swigexample;
   assert(isglobal("swigexample"));
   assert(cvar.ivar == ifunc);
diff --git a/Examples/octave/operator/@swig_ref/horzcat.m b/Examples/octave/operator/@swig_ref/horzcat.m
new file mode 100644
index 0000000..6d4a55b
--- /dev/null
+++ b/Examples/octave/operator/@swig_ref/horzcat.m
@@ -0,0 +1,9 @@
+% test octaves concatenation operator
+function ret=horzcat(varargin)
+  % return the concatenation of several ComplexVal values as a cell array.
+  % (not really useful but it tests the concatenation of swig_ref objects)
+  ret={};
+  for i=1:length(varargin)
+    ret{i}=varargin{i};
+  end
+end
diff --git a/Examples/octave/operator/runme.m b/Examples/octave/operator/runme.m
index e17494a..ff8b594 100644
--- a/Examples/octave/operator/runme.m
+++ b/Examples/octave/operator/runme.m
@@ -3,6 +3,9 @@
   crash_dumps_octave_core(0);
 endif
 
+scriptDir = fileparts(mfilename('fullpath'));
+addpath(scriptDir);
+
 # Operator overloading example
 swigexample
 
@@ -42,3 +45,7 @@
   printf("conj(a) = %s\n", disp(conj(a)));
   printf("exp(a) = %s\n", disp(exp(a)));
 endif
+
+# concatenation operator, note: calls @swig_ref/horzcat.m
+g = [a, b, c];
+printf("g   = %s\n",disp(g));
diff --git a/Examples/perl5/index.html b/Examples/perl5/index.html
index 23c8ff6..2daabaa 100644
--- a/Examples/perl5/index.html
+++ b/Examples/perl5/index.html
@@ -72,7 +72,7 @@
 Due to wide variations in the Perl C API and differences between versions such as the ActivePerl release for Windows,
 the code generated by SWIG is extremely messy.
 If the code doesn't compile or work with your version of Perl, please let us know by 
-contacting us on the <a href="http://www.swig.org/mail.html">mailing lists</a>.
+contacting us on the <a href="https://www.swig.org/mail.html">mailing lists</a>.
 Better yet, send us a patch.
 
 </body>
diff --git a/Examples/perl5/multimap/example.i b/Examples/perl5/multimap/example.i
index 64eb6a7..f2dff24 100644
--- a/Examples/perl5/multimap/example.i
+++ b/Examples/perl5/multimap/example.i
@@ -15,7 +15,7 @@
 
 extern int    gcd(int x, int y);
 
-%typemap(arginit) (int argc, char *argv[]) "$2 = 0;";
+%typemap(arginit) (int argc, char *argv[]) "$2 = 0;"
 
 %typemap(in) (int argc, char *argv[]) {
   AV *tempav;
diff --git a/Examples/perl5/pointer/index.html b/Examples/perl5/pointer/index.html
index 94467bc..b248c81 100644
--- a/Examples/perl5/pointer/index.html
+++ b/Examples/perl5/pointer/index.html
@@ -72,23 +72,25 @@
 
 <blockquote>
 <pre>
-%include "pointer.i"
+%include "cpointer.i"
 </pre>
-</blockquote?
+</blockquote>
 
 and in a script you would do this:
 
 <blockquote>
 <pre>
-$a = ptrcreate("int",37);
-$b = ptrcreate("int",42);
-$c = ptrcreate("int");
-add($a,$b,$c);
-$r = ptrvalue($c);
+$a = example::new_intp();
+$b = example::new_intp();
+$c = example::new_intp();
+example::intp_assign($a,37);
+example::intp_assign($b,42);
+example::add($a,$b,$c);
+$r = example::intp_value($c);
 print "Result = $r\n";
-ptrfree($a);
-ptrfree($b);
-ptrfree($c);
+example::delete_intp($a);
+example::delete_intp($b);
+example::delete_intp($c);
 </pre>
 </blockquote>
 
@@ -156,14 +158,8 @@
 make it.
 
 <p>
-<li>More documentation on the typemaps.i and pointer.i library files can be
+<li>More documentation on the typemaps.i and cpointer.i library files can be
 found in the SWIG user manual.  The files also contain documentation.
-
-<p>
-<li>The pointer.i library is designed primarily for convenience.  If you
-are concerned about performance, you probably want to use a different
-approach.
-
 </ul>
 
 <hr>
diff --git a/Examples/perl5/reference/index.html b/Examples/perl5/reference/index.html
index 70b4f3d..5b29125 100644
--- a/Examples/perl5/reference/index.html
+++ b/Examples/perl5/reference/index.html
@@ -104,7 +104,7 @@
 class VectorArray {
 public:
  ...
-   %addmethods {
+   %extend {
     Vector &amp;get(int index) {
       return (*self)[index];
     }
diff --git a/Examples/php/callback/runme.php b/Examples/php/callback/runme.php
index 2be7199..e709320 100644
--- a/Examples/php/callback/runme.php
+++ b/Examples/php/callback/runme.php
@@ -2,8 +2,6 @@
 
 # This file illustrates the cross language polymorphism using directors.
 
-require("example.php");
-
 # Class, which overwrites Callback::run().
 
 class PhpCallback extends Callback {
@@ -43,5 +41,3 @@
 # All done.
 
 print "php exit\n";
-
-?>
diff --git a/Examples/php/class/runme.php b/Examples/php/class/runme.php
index 99c253b..0f66769 100644
--- a/Examples/php/class/runme.php
+++ b/Examples/php/class/runme.php
@@ -2,8 +2,6 @@
 
 # This example illustrates how member variables are wrapped.
 
-require("example.php");
-
 # ----- Object creation -----
 
 print "Creating some objects:\n";
@@ -56,5 +54,3 @@
 
 print Shape::nshapes() . " shapes remain\n";
 print "Goodbye\n";
-
-?>
diff --git a/Examples/php/constants/runme.php b/Examples/php/constants/runme.php
index 91c597a..e561626 100644
--- a/Examples/php/constants/runme.php
+++ b/Examples/php/constants/runme.php
@@ -1,7 +1,5 @@
 <?php
 
-require "example.php";
-
 print "ICONST  = " . ICONST . " (should be 42)\n";
 print "FCONST  = " . FCONST . " (should be 2.1828)\n";
 print "CCONST  = " . CCONST . " (should be 'x')\n";
@@ -19,6 +17,3 @@
 if (array_key_exists("FOO", $c)) {
     print "FOO    = " . $c["FOO"] . " (Arg! This shouldn't print anything)\n";
 }
-
-
-?>
diff --git a/Examples/php/cpointer/runme.php b/Examples/php/cpointer/runme.php
index 22e8a68..f552ed7 100644
--- a/Examples/php/cpointer/runme.php
+++ b/Examples/php/cpointer/runme.php
@@ -1,7 +1,5 @@
 <?php
 
-	require "example.php";
-
 	# First create some objects using the pointer library.
 
 	print "Testing the pointer library\n";
@@ -43,5 +41,3 @@
 	# $q = $a[0]
 	# $r = $a[1]
 	# print "	42/37 = $q remainder $r\n";
-
-?>
diff --git a/Examples/php/disown/example.cxx b/Examples/php/disown/example.cxx
index 6393735..247eb6a 100644
--- a/Examples/php/disown/example.cxx
+++ b/Examples/php/disown/example.cxx
@@ -39,7 +39,6 @@
 }
 
 ShapeContainer::~ShapeContainer() {
-  iterator i=shapes.begin();
   for( iterator i = shapes.begin(); i != shapes.end(); ++i ) {
     delete *i;
   }
diff --git a/Examples/php/disown/runme.php b/Examples/php/disown/runme.php
index a70d7b0..e847dc7 100644
--- a/Examples/php/disown/runme.php
+++ b/Examples/php/disown/runme.php
@@ -4,8 +4,6 @@
 # created by SWIG.  In this case, all of our C++ classes
 # get converted into function calls.
 
-require("example.php");
-
 # ----- Object creation -----
 
 print "Creating some objects:\n";
@@ -45,5 +43,3 @@
 print "\nA total of " . Shape::nshapes() . " shapes remain\n";
 
 print "Goodbye\n";
-
-?>
diff --git a/Examples/php/enum/runme.php b/Examples/php/enum/runme.php
index 8134766..bf5ba88 100644
--- a/Examples/php/enum/runme.php
+++ b/Examples/php/enum/runme.php
@@ -1,7 +1,5 @@
 <?php
 
-require "example.php";
-
 # ----- Object creation -----
 
 # Print out the value of some enums
@@ -28,5 +26,3 @@
 $f->enum_test(Foo::IMPULSE);
 $f->enum_test(Foo::WARP);
 $f->enum_test(Foo::LUDICROUS);
-
-?>
diff --git a/Examples/php/extend/runme.php b/Examples/php/extend/runme.php
index 1586831..b770e5c 100644
--- a/Examples/php/extend/runme.php
+++ b/Examples/php/extend/runme.php
@@ -2,8 +2,6 @@
 
 # This file illustrates the cross language polymorphism using directors.
 
-require("example.php");
-
 # CEO class, which overrides Employee::getPosition().
 
 class CEO extends Manager {
@@ -27,7 +25,7 @@
 $list = new EmployeeList();
 
 # EmployeeList owns its items, so we must surrender ownership of objects
-# we add. This involves first clearing the ->disown member to tell the
+# we add. This involves first clearing the ->thisown member to tell the
 # C++ director to start reference counting.
 
 $e->thisown = 0;
@@ -72,5 +70,3 @@
 # All done.
 
 print "php exit\n";
-
-?>
diff --git a/Examples/php/funcptr/runme.php b/Examples/php/funcptr/runme.php
index 712d414..d76a19b 100644
--- a/Examples/php/funcptr/runme.php
+++ b/Examples/php/funcptr/runme.php
@@ -1,7 +1,5 @@
 <?php
 
-require "example.php";
-
 $a = 37;
 $b = 42;
 
@@ -10,15 +8,11 @@
 print "Trying some C callback functions\n";
 print "    a        = $a\n";
 print "    b        = $b\n";
-print "    ADD(a,b) = ". do_op($a,$b,ADD)."\n";
-print "    SUB(a,b) = ". do_op($a,$b,SUB)."\n";
-print "    MUL(a,b) = ". do_op($a,$b,MUL)."\n";
+print "    ADD(a,b) = ". do_op($a,$b,example::ADD)."\n";
+print "    SUB(a,b) = ". do_op($a,$b,example::SUB)."\n";
+print "    MUL(a,b) = ". do_op($a,$b,example::MUL)."\n";
 
 print "Here is what the C callback function objects look like in php\n";
-print "Using swig style string pointers as we need them registered as constants\n";
-print "    ADD      = " . ADD . "\n";
-print "    SUB      = " . SUB . "\n";
-print "    MUL      = " . MUL . "\n";
-
-?>
-
+print "    ADD      = " . example::ADD . "\n";
+print "    SUB      = " . example::SUB . "\n";
+print "    MUL      = " . example::MUL . "\n";
diff --git a/Examples/php/overloading/runme.php b/Examples/php/overloading/runme.php
index 56d5151..d4df899 100644
--- a/Examples/php/overloading/runme.php
+++ b/Examples/php/overloading/runme.php
@@ -4,8 +4,6 @@
 # created by SWIG.  In this case, all of our C++ classes
 # get converted into function calls.
 
-include("example.php");
-
 # ----- Object creation -----
 
 print "Creating some objects:\n";
@@ -54,5 +52,3 @@
 print Shape::nshapes() . " shapes remain\n";
 
 print "Goodbye\n";
-
-?>
diff --git a/Examples/php/pointer/example.i b/Examples/php/pointer/example.i
index 1f00594..31d2a03 100644
--- a/Examples/php/pointer/example.i
+++ b/Examples/php/pointer/example.i
@@ -21,10 +21,5 @@
 
 /* Next we'll use typemaps and the %apply directive */
 
-//%apply int *OUTPUT { int *r };
-//extern int divide(int n, int d, int *r);
-
-
-
-
-
+%apply int *OUTPUT { int *r };
+extern int divide(int n, int d, int *r);
diff --git a/Examples/php/pointer/runme.php b/Examples/php/pointer/runme.php
index e79b238..8dc3ab8 100644
--- a/Examples/php/pointer/runme.php
+++ b/Examples/php/pointer/runme.php
@@ -1,7 +1,5 @@
 <?php
 
-	require "example.php";
-
 	# First create some objects using the pointer library.
 
 	print "Testing the pointer library\n";
@@ -14,7 +12,7 @@
 	print "	b = $b\n";
 	print "	c = $c\n";
 
-	# Call the add() function wuth some pointers
+	# Call the add() function with some pointers
 	add($a,$b,$c);
 
 	print "	$a + $b = $c\n";
@@ -28,8 +26,8 @@
 	print "	37 - 42 = $r\n";
 
 	# Now try the version with multiple return values
-	# print "Testing multiple return values\n";
-	# ($q,$r) = divide(42,37);
-	# print "	42/37 = $q remainder $r\n";
-
-?>
+	print "Testing multiple return values\n";
+	$a = divide(42,37);
+	$q = $a[0];
+	$r = $a[1];
+	print "	42/37 = $q remainder $r\n";
diff --git a/Examples/php/pragmas/include.php b/Examples/php/pragmas/include.php
index 11d985d..442f8e2 100644
--- a/Examples/php/pragmas/include.php
+++ b/Examples/php/pragmas/include.php
@@ -2,6 +2,3 @@
 
 # This code is inserted into example.php
 echo "This is include.php\n";
-
-
-?>
diff --git a/Examples/php/pragmas/runme.php b/Examples/php/pragmas/runme.php
index 7b2c179..e2b2763 100644
--- a/Examples/php/pragmas/runme.php
+++ b/Examples/php/pragmas/runme.php
@@ -6,4 +6,3 @@
 require "example.php";
 
 echo "Version - " . ((new ReflectionExtension('example'))->getVersion()) . "\n";
-?>
diff --git a/Examples/php/proxy/runme.php b/Examples/php/proxy/runme.php
index e70ab22..0f156b6 100644
--- a/Examples/php/proxy/runme.php
+++ b/Examples/php/proxy/runme.php
@@ -4,8 +4,6 @@
 # created by SWIG.  In this case, all of our C++ classes
 # get converted into function calls.
 
-include("example.php");
-
 # ----- Object creation -----
 
 print "Creating some objects:\n";
@@ -64,5 +62,3 @@
 print Shape::get_nshapes() ." == 42\n";
 
 print "Goodbye\n";
-
-?>
diff --git a/Examples/php/reference/runme.php b/Examples/php/reference/runme.php
index 5d264ee..5c7fc9a 100644
--- a/Examples/php/reference/runme.php
+++ b/Examples/php/reference/runme.php
@@ -2,8 +2,6 @@
 
 # This file illustrates the manipulation of C++ references in PHP.
 
-require "example.php";
-
 # ----- Object creation -----
 
 print "Creating some objects:\n";
@@ -45,5 +43,3 @@
 for ($i = 0; $i < 5; $i++) {
     print "    va[$i] = {$va->get($i)->as_string()}\n";
 }
-
-?>
diff --git a/Examples/php/simple/runme.php b/Examples/php/simple/runme.php
index 0e96fe8..2795f32 100644
--- a/Examples/php/simple/runme.php
+++ b/Examples/php/simple/runme.php
@@ -1,7 +1,5 @@
 <?php
 
-require "example.php";
-
 # Call our gcd() function
 
 $x = "42 aaa";
@@ -21,5 +19,3 @@
 #				  manual for why. )
 print "Foo = "  . Foo_get() . "\n";
 print_Foo();
-
-?>
diff --git a/Examples/php/sync/example.cxx b/Examples/php/sync/example.cxx
index 0942279..2001a5b 100644
--- a/Examples/php/sync/example.cxx
+++ b/Examples/php/sync/example.cxx
@@ -1,13 +1,19 @@
 #include "example.h"
-#include <stdio.h>
+#include <iostream>
 
 int x = 42;
-char *s = (char *)"Test";
+std::string s = "Test";
 
-void Sync::printer(void) {
+void Sync::printer() {
+    std::cout << "The value of global s is " << ::s << '\n';
+    std::cout << "The value of global x is " << ::x << '\n';
+    std::cout << "The value of class s is " << this->s << '\n';
+    std::cout << "The value of class x is " << this->x << '\n';
+}
 
-	printf("The value of global s is %s\n", s);
-	printf("The value of global x is %d\n", x);
-	printf("The value of class s is %s\n", s);
-	printf("The value of class x is %d\n", x);
+void Sync::all_change() {
+    ::s = "global change";
+    ++::x;
+    this->s = "local change";
+    ++this->x;
 }
diff --git a/Examples/php/sync/example.h b/Examples/php/sync/example.h
index d67ec21..381473f 100644
--- a/Examples/php/sync/example.h
+++ b/Examples/php/sync/example.h
@@ -1,9 +1,14 @@
-extern char *s;
+#include <string>
+
+extern std::string s;
 extern int x;
 
 class Sync {
-	public:
-		int x;
-		char *s;
-		void printer(void);
+  public:
+    int x;
+    std::string s;
+    void printer();
+    void all_change();
+
+    Sync() : x(0) { }
 };
diff --git a/Examples/php/sync/example.i b/Examples/php/sync/example.i
index 17ff87c..bc10e0f 100644
--- a/Examples/php/sync/example.i
+++ b/Examples/php/sync/example.i
@@ -1,5 +1,7 @@
 %module example
 
+%include <std_string.i>
+
 %{
 #include "example.h"
 %}
diff --git a/Examples/php/sync/runme.php b/Examples/php/sync/runme.php
index a7c4347..f01a9b3 100644
--- a/Examples/php/sync/runme.php
+++ b/Examples/php/sync/runme.php
@@ -1,15 +1,29 @@
 <?
 
-// Load module and PHP classes.
-include("example.php");
+echo "PHP reading globals: string is '", s_get(), "' and value is ", x_get(), "\n";
 
-echo "Got new object\n";
-echo "Got string $s and value $x \n";
-
-$s = new Sync();
+$o = new Sync();
 echo "Got new object\n";
 
-$s->printer();
+echo "PHP reading object: string is '", $o->s, "' and value is ", $o->x, "\n";
 
-?>
+$o->printer();
 
+example::s_set("global string");
+example::x_set(42);
+
+$o->s = "object string";
+$o->x = 1234;
+
+echo "PHP reading globals: string is '", example::s_get(), "' and int is ", example::x_get(), "\n";
+echo "PHP reading object: string is '", $o->s, "' and int is ", $o->x, "\n";
+
+$o->printer();
+
+echo "Calling all_change() method\n";
+$o->all_change();
+
+echo "PHP reading globals: string is '", example::s_get(), "' and int is ", example::x_get(), "\n";
+echo "PHP reading object: string is '", $o->s, "' and int is ", $o->x, "\n";
+
+$o->printer();
diff --git a/Examples/php/value/runme.php b/Examples/php/value/runme.php
index 569c87c..754f942 100644
--- a/Examples/php/value/runme.php
+++ b/Examples/php/value/runme.php
@@ -1,8 +1,5 @@
 <?php
 
-	require "example.php";
-
-
 	$v = new Vector();
         $v->x = 1.0;
         $v->y = 2.0;
@@ -34,10 +31,6 @@
 
 	echo "\nNow I'm going to clean up the return result\n";
 
-#	free($r);
+	unset($r);
 
 	echo "Good\n";
-
-?>
-
-
diff --git a/Examples/php/variables/runme.php b/Examples/php/variables/runme.php
index 14f27f3..a14fede 100644
--- a/Examples/php/variables/runme.php
+++ b/Examples/php/variables/runme.php
@@ -1,6 +1,5 @@
 <?php
 
-	require "example.php";
 	echo "\nVariables (values printed from C)\n";
 
 	print_vars();
@@ -91,6 +90,3 @@
 	/* And this */
 	//status_set(0);
 	echo "Status = ".status_get()."\n";
-
-?>
-
diff --git a/Examples/pike/check.list b/Examples/pike/check.list
deleted file mode 100644
index d6c8e2e..0000000
--- a/Examples/pike/check.list
+++ /dev/null
@@ -1,7 +0,0 @@
-# see top-level Makefile.in
-class
-constants
-enum
-overload
-simple
-template
diff --git a/Examples/pike/class/Makefile b/Examples/pike/class/Makefile
deleted file mode 100644
index e5319db..0000000
--- a/Examples/pike/class/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-TOP        = ../..
-SWIGEXE    = $(TOP)/../swig
-SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-CXXSRCS    = example.cxx
-TARGET     = example
-INTERFACE  = example.i
-LIBS       = -lm
-
-check: build
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' pike_run
-
-build:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' pike_cpp
-
-static:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	TARGET='mypike' INTERFACE='$(INTERFACE)' pike_cpp_static
-
-clean:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' pike_clean
diff --git a/Examples/pike/class/example.cxx b/Examples/pike/class/example.cxx
deleted file mode 100644
index 0463045..0000000
--- a/Examples/pike/class/example.cxx
+++ /dev/null
@@ -1,28 +0,0 @@
-/* File : example.cxx */
-
-#include "example.h"
-#define M_PI 3.14159265358979323846
-
-/* Move the shape to a new location */
-void Shape::move(double dx, double dy) {
-  x += dx;
-  y += dy;
-}
-
-int Shape::nshapes = 0;
-
-double Circle::area() {
-  return M_PI*radius*radius;
-}
-
-double Circle::perimeter() {
-  return 2*M_PI*radius;
-}
-
-double Square::area() {
-  return width*width;
-}
-
-double Square::perimeter() {
-  return 4*width;
-}
diff --git a/Examples/pike/class/example.h b/Examples/pike/class/example.h
deleted file mode 100644
index 0dff185..0000000
--- a/Examples/pike/class/example.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/* File : example.h */
-
-class Shape {
-public:
-  Shape() {
-    nshapes++;
-  }
-  virtual ~Shape() {
-    nshapes--;
-  }
-  double  x, y;
-  void    move(double dx, double dy);
-  virtual double area() = 0;
-  virtual double perimeter() = 0;
-  static  int nshapes;
-};
-
-class Circle : public Shape {
-private:
-  double radius;
-public:
-  Circle(double r) : radius(r) { }
-  virtual double area();
-  virtual double perimeter();
-};
-
-class Square : public Shape {
-private:
-  double width;
-public:
-  Square(double w) : width(w) { }
-  virtual double area();
-  virtual double perimeter();
-};
diff --git a/Examples/pike/class/example.i b/Examples/pike/class/example.i
deleted file mode 100644
index fbdf724..0000000
--- a/Examples/pike/class/example.i
+++ /dev/null
@@ -1,9 +0,0 @@
-/* File : example.i */
-%module example
-
-%{
-#include "example.h"
-%}
-
-/* Let's just grab the original header file here */
-%include "example.h"
diff --git a/Examples/pike/class/runme.pike b/Examples/pike/class/runme.pike
deleted file mode 100644
index a637760..0000000
--- a/Examples/pike/class/runme.pike
+++ /dev/null
@@ -1,53 +0,0 @@
-import .example;
-
-int main()
-{
-    // ----- Object creation -----
-
-    write("Creating some objects:\n");
-    Circle c = Circle(10.0);
-    write("    Created circle.\n");
-    Square s = Square(10.0);
-    write("    Created square.\n");
-
-    // ----- Access a static member -----
-
-    write("\nA total of " + Shape_nshapes_get() + " shapes were created\n");
-
-    // ----- Member data access -----
-
-    // Set the location of the object
-
-    c->x_set(20.0);
-    c->y_set(30.0);
-
-    s->x_set(-10.0);
-    s->y_set(5.0);
-
-    write("\nHere is their current position:\n");
-    write("    Circle = (%f, %f)\n", c->x_get(), c->y_get());
-    write("    Square = (%f, %f)\n", s->x_get(), s->y_get());
-
-    // ----- Call some methods -----
-
-    write("\nHere are some properties of the shapes:\n");
-    write("   The circle:\n");
-    write("        area      = %f.\n", c->area());
-    write("        perimeter = %f.\n", c->perimeter());
-    write("   The square:\n");
-    write("        area      = %f.\n", s->area());
-    write("        perimeter = %f.\n", s->perimeter());
-
-    write("\nGuess I'll clean up now\n");
-
-    /* See if we can force 's' to be garbage-collected */
-    s = 0;
-    
-    /* Now we should be down to only 1 shape */
-    write("%d shapes remain\n", Shape_nshapes_get());
-    
-    /* Done */
-    write("Goodbye\n");
-    
-    return 0;
-}
diff --git a/Examples/pike/constants/Makefile b/Examples/pike/constants/Makefile
deleted file mode 100644
index 45da7d2..0000000
--- a/Examples/pike/constants/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-TOP        = ../..
-SWIGEXE    = $(TOP)/../swig
-SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-SRCS       =
-TARGET     = example
-INTERFACE  = example.i
-
-check: build
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' pike_run
-
-build:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' pike
-
-static:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	TARGET='mypike' INTERFACE='$(INTERFACE)' pike_static
-
-clean:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' pike_clean
diff --git a/Examples/pike/constants/example.i b/Examples/pike/constants/example.i
deleted file mode 100644
index 4f7b1a4..0000000
--- a/Examples/pike/constants/example.i
+++ /dev/null
@@ -1,27 +0,0 @@
-/* File : example.i */
-%module example
-
-/* A few preprocessor macros */
-
-#define    ICONST      42
-#define    FCONST      2.1828
-#define    CCONST      'x'
-#define    CCONST2     '\n'
-#define    SCONST      "Hello World"
-#define    SCONST2     "\"Hello World\""
-
-/* This should work just fine */
-#define    EXPR        ICONST + 3*(FCONST)
-
-/* This shouldn't do anything */
-#define    EXTERN      extern
-
-/* Neither should this (BAR isn't defined) */
-#define    FOO         (ICONST + BAR)
-
-/* The following directives also produce constants */
-
-%constant int iconst = 37;
-%constant double fconst = 3.14;
-
-
diff --git a/Examples/pike/constants/runme.pike b/Examples/pike/constants/runme.pike
deleted file mode 100644
index a8d9f94..0000000
--- a/Examples/pike/constants/runme.pike
+++ /dev/null
@@ -1,24 +0,0 @@
-int main()
-{
-  write("ICONST  = %d (should be 42)\n", .example.ICONST);
-  write("FCONST  = %f (should be 2.1828)\n", .example.FCONST);
-  write("CCONST  = %c (should be 'x')\n", .example.CCONST);
-  write("CCONST2 = %c (this should be on a new line)\n", .example.CCONST2);
-  write("SCONST  = %s (should be 'Hello World')\n", .example.SCONST);
-  write("SCONST2 = %s (should be '\"Hello World\"')\n", .example.SCONST2);
-  write("EXPR    = %f (should be 48.5484)\n", .example.EXPR);
-  write("iconst  = %d (should be 37)\n", .example.iconst);
-  write("fconst  = %f (should be 3.14)\n", .example.fconst);
-
-  if (search(indices(.example), "EXTERN") == -1)
-    write("EXTERN isn't defined (good)\n");
-  else
-    write("EXTERN is defined (bad)\n");
-
-  if (search(indices(.example), "FOO") == -1)
-    write("FOO isn't defined (good)\n");
-  else
-    write("FOO is defined (bad)\n");
-
-  return 0;
-}
diff --git a/Examples/pike/enum/Makefile b/Examples/pike/enum/Makefile
deleted file mode 100644
index e5319db..0000000
--- a/Examples/pike/enum/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-TOP        = ../..
-SWIGEXE    = $(TOP)/../swig
-SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-CXXSRCS    = example.cxx
-TARGET     = example
-INTERFACE  = example.i
-LIBS       = -lm
-
-check: build
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' pike_run
-
-build:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' pike_cpp
-
-static:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	TARGET='mypike' INTERFACE='$(INTERFACE)' pike_cpp_static
-
-clean:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' pike_clean
diff --git a/Examples/pike/enum/README b/Examples/pike/enum/README
deleted file mode 100644
index 055aa9f..0000000
--- a/Examples/pike/enum/README
+++ /dev/null
@@ -1,13 +0,0 @@
-This example will not compile with Pike versions 7.4.20 unless you first
-patch the Pike sources. The problem is for line 91 of Pike's "stralloc.h"
-(usually installed as /usr/local/pike/7.4.10/include/pike/stralloc.h). That
-line reads:
-
-    tmp.ptr=ptr;
-
-but should be patched to read:
-
-    tmp.ptr=(p_wchar0 *) ptr;
-
-This bug has been reported to the Pike developers.
-
diff --git a/Examples/pike/enum/example.cxx b/Examples/pike/enum/example.cxx
deleted file mode 100644
index 6785e57..0000000
--- a/Examples/pike/enum/example.cxx
+++ /dev/null
@@ -1,37 +0,0 @@
-/* File : example.c */
-
-#include "example.h"
-#include <stdio.h>
-
-void Foo::enum_test(speed s) {
-  if (s == IMPULSE) {
-    printf("IMPULSE speed\n");
-  } else if (s == WARP) {
-    printf("WARP speed\n");
-  } else if (s == LUDICROUS) {
-    printf("LUDICROUS speed\n");
-  } else {
-    printf("Unknown speed\n");
-  }
-}
-
-void enum_test(color c, Foo::speed s) {
-  if (c == RED) {
-    printf("color = RED, ");
-  } else if (c == BLUE) {
-    printf("color = BLUE, ");
-  } else if (c == GREEN) {
-    printf("color = GREEN, ");
-  } else {
-    printf("color = Unknown color!, ");
-  }
-  if (s == Foo::IMPULSE) {
-    printf("speed = IMPULSE speed\n");
-  } else if (s == Foo::WARP) {
-    printf("speed = WARP speed\n");
-  } else if (s == Foo::LUDICROUS) {
-    printf("speed = LUDICROUS speed\n");
-  } else {
-    printf("speed = Unknown speed!\n");
-  }
-}
diff --git a/Examples/pike/enum/example.h b/Examples/pike/enum/example.h
deleted file mode 100644
index 525d62a..0000000
--- a/Examples/pike/enum/example.h
+++ /dev/null
@@ -1,13 +0,0 @@
-/* File : example.h */
-
-enum color { RED, BLUE, GREEN };
-
-class Foo {
- public:
-  Foo() { }
-  enum speed { IMPULSE, WARP, LUDICROUS };
-  void enum_test(speed s);
-};
-
-void enum_test(color c, Foo::speed s);
-
diff --git a/Examples/pike/enum/example.i b/Examples/pike/enum/example.i
deleted file mode 100644
index 23ee8a8..0000000
--- a/Examples/pike/enum/example.i
+++ /dev/null
@@ -1,11 +0,0 @@
-/* File : example.i */
-%module example
-
-%{
-#include "example.h"
-%}
-
-/* Let's just grab the original header file here */
-
-%include "example.h"
-
diff --git a/Examples/pike/enum/runme.pike b/Examples/pike/enum/runme.pike
deleted file mode 100644
index 4846356..0000000
--- a/Examples/pike/enum/runme.pike
+++ /dev/null
@@ -1,28 +0,0 @@
-int main()
-{
-    write("*** color ***\n");
-    write("    RED    = " + .example.RED + "\n");
-    write("    BLUE   = " + .example.BLUE + "\n");
-    write("    GREEN  = " + .example.GREEN + "\n");
-
-    write("\n*** Foo::speed ***\n");
-    write("    Foo_IMPULSE   = " + .example.Foo.IMPULSE + "\n");
-    write("    Foo_WARP      = " + .example.Foo.WARP + "\n");
-    write("    Foo_LUDICROUS = " + .example.Foo.LUDICROUS + "\n");
-
-    write("\nTesting use of enums with functions\n\n");
-
-    .example.enum_test(.example.RED,   .example.Foo.IMPULSE);
-    .example.enum_test(.example.BLUE,  .example.Foo.WARP);
-    .example.enum_test(.example.GREEN, .example.Foo.LUDICROUS);
-    .example.enum_test(1234, 5678);
-
-    write("\nTesting use of enum with class method\n");
-    .example.Foo f = .example.Foo();
-
-    f->enum_test(.example.Foo.IMPULSE);
-    f->enum_test(.example.Foo.WARP);
-    f->enum_test(.example.Foo.LUDICROUS);
-    
-    return 0;
-}
diff --git a/Examples/pike/overload/Makefile b/Examples/pike/overload/Makefile
deleted file mode 100644
index 5e5fe66..0000000
--- a/Examples/pike/overload/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-TOP        = ../..
-SWIGEXE    = $(TOP)/../swig
-SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-CXXSRCS    = example.cxx
-TARGET     = example
-INTERFACE  = example.i
-LIBS       = -lstdc++ -lm
-
-check: build
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' pike_run
-
-build:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' pike_cpp
-
-static:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	TARGET='mypike' INTERFACE='$(INTERFACE)' pike_cpp_static
-
-clean:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' pike_clean
diff --git a/Examples/pike/overload/example.cxx b/Examples/pike/overload/example.cxx
deleted file mode 100644
index 3760fdd..0000000
--- a/Examples/pike/overload/example.cxx
+++ /dev/null
@@ -1,115 +0,0 @@
-#include <iostream>
-
-#include "example.h"
-
-// Overloaded constructors for class Bar
-Bar::Bar() {
-    std::cout << "Called Bar::Bar()" << std::endl;
-}
-
-Bar::Bar(const Bar&) {
-    std::cout << "Called Bar::Bar(const Bar&)" << std::endl;
-}
-
-Bar::Bar(double x) {
-    std::cout << "Called Bar::Bar(double) with x = " << x << std::endl;
-}
-
-Bar::Bar(double x, char *y) {
-    std::cout << "Called Bar::Bar(double, char *) with x, y = " << x << ", \"" << y << "\"" << std::endl;
-}
-
-Bar::Bar(int x, int y) {
-    std::cout << "Called Bar::Bar(int, int) with x, y = " << x << ", " << y << std::endl;
-}
-
-Bar::Bar(char *x) {
-    std::cout << "Called Bar::Bar(char *) with x = \"" << x << "\"" << std::endl;
-}
-
-Bar::Bar(int x) {
-    std::cout << "Called Bar::Bar(int) with x = " << x << std::endl;
-}
-
-Bar::Bar(long x) {
-    std::cout << "Called Bar::Bar(long) with x = " << x << std::endl;
-}
-
-Bar::Bar(Bar *x) {
-    std::cout << "Called Bar::Bar(Bar *) with x = " << x << std::endl;
-}
-
-// Overloaded member functions
-void Bar::foo(const Bar& x) {
-    std::cout << "Called Bar::foo(const Bar&) with &x = " << &x << std::endl;
-}
-
-void Bar::foo(double x) {
-    std::cout << "Called Bar::foo(double) with x = " << x << std::endl;
-}
-
-void Bar::foo(double x, char *y) {
-    std::cout << "Called Bar::foo(double, char *) with x, y = " << x << ", \"" << y << "\"" << std::endl;
-}
-
-void Bar::foo(int x, int y) {
-    std::cout << "Called Bar::foo(int, int) with x, y = " << x << ", " << y << std::endl;
-}
-
-void Bar::foo(char *x) {
-    std::cout << "Called Bar::foo(char *) with x = \"" << x << "\"" << std::endl;
-}
-
-void Bar::foo(int x) {
-    std::cout << "Called Bar::foo(int) with x = " << x << std::endl;
-}
-
-void Bar::foo(long x) {
-    std::cout << "Called Bar::foo(long) with x = " << x << std::endl;
-}
-
-void Bar::foo(Bar *x) {
-    std::cout << "Called Bar::foo(Bar *) with x = " << x << std::endl;
-}
-
-void Bar::spam(int x, int y, int z) {
-    std::cout << "Called Bar::spam(int, int, int) with x, y, z = " << x << ", " << y << ", " << z << std::endl;
-}
-
-void Bar::spam(double x, int y, int z) {
-    std::cout << "Called Bar::spam(double, int, int) with x, y, z = " << x << ", " << y << ", " << z << std::endl;
-}
-
-// Overloaded global methods
-void foo(const Bar& x) {
-    std::cout << "Called foo(const Bar& x) with &x = " << &x << std::endl;
-}
-
-void foo(double x) {
-    std::cout << "Called foo(double) with x = " << x << std::endl;
-}
-
-void foo(double x, char *y) {
-    std::cout << "Called foo(double, char *) with x, y = " << x << ", \"" << y << "\"" << std::endl;
-}
-
-void foo(int x, int y) {
-    std::cout << "Called foo(int, int) with x, y = " << x << ", " << y << std::endl;
-}
-
-void foo(char *x) {
-    std::cout << "Called foo(char *) with x = \"" << x << "\"" << std::endl;
-}
-
-void foo(int x) {
-    std::cout << "Called foo(int) with x = " << x << std::endl;
-}
-
-void foo(long x) {
-    std::cout << "Called foo(long) with x = " << x << std::endl;
-}
-
-void foo(Bar *x) {
-    std::cout << "Called foo(Bar *) with x = " << x << std::endl;
-}
-
diff --git a/Examples/pike/overload/example.h b/Examples/pike/overload/example.h
deleted file mode 100644
index e47a122..0000000
--- a/Examples/pike/overload/example.h
+++ /dev/null
@@ -1,41 +0,0 @@
-#ifndef EXAMPLE_H
-#define EXAMPLE_H
-
-class Bar {
-public:
-    Bar();
-    Bar(const Bar&);
-    Bar(double);
-    Bar(double, char *);
-    Bar(int, int);
-    Bar(char *);
-    Bar(long);
-    Bar(int);
-    Bar(Bar *);
-
-    void foo(const Bar&);
-    void foo(double);
-    void foo(double, char *);
-    void foo(int, int);
-    void foo(char *);
-    void foo(long);
-    void foo(int);
-    void foo(Bar *);
-    
-    void spam(int x, int y=2, int z=3);
-    void spam(double x, int y=2, int z=3);
-};
-
-void foo(const Bar&);
-void foo(double);
-void foo(double, char *);
-void foo(int, int);
-void foo(char *);
-void foo(int);
-void foo(long);
-void foo(Bar *);
-
-void spam(int x, int y=2, int z=3);
-void spam(double x, int y=2, int z=3);
-
-#endif
diff --git a/Examples/pike/overload/example.i b/Examples/pike/overload/example.i
deleted file mode 100644
index ddcd006..0000000
--- a/Examples/pike/overload/example.i
+++ /dev/null
@@ -1,28 +0,0 @@
-/* File : example.i */
-%module example
-
-%{
-#include "example.h"
-%}
-
-/**
- * These overloaded declarations conflict with other overloads (as far as
- * SWIG's Ruby module's implementation for overloaded methods is concerned).
- * One option is use the %rename directive to rename the conflicting methods;
- * here, we're just using %ignore to avoid wrapping some of the overloaded
- * functions altogether.
- */
-
-%ignore Bar;
-
-%ignore Bar::Bar(Bar *);
-%ignore Bar::Bar(long);
-
-%ignore Bar::foo(const Bar&);
-%ignore Bar::foo(long);
-
-%ignore ::foo(const Bar&);
-%ignore ::foo(int);
-
-/* Let's just grab the original header file here */
-%include "example.h"
diff --git a/Examples/pike/overload/runme.pike b/Examples/pike/overload/runme.pike
deleted file mode 100644
index d30e947..0000000
--- a/Examples/pike/overload/runme.pike
+++ /dev/null
@@ -1,83 +0,0 @@
-// import .example;
-
-int main()
-{
-	// This should invoke foo(double)
-	.example.foo(3.14159);
-
-	// This should invoke foo(double, char *)
-	.example.foo(3.14159, "Pi");
-
-	// This should invoke foo(int, int)
-	.example.foo(3, 4);
-
-	//  This should invoke foo(char *)
-	.example.foo("This is a test");
-
-	// This should invoke foo(long)
-	.example.foo(42);
-
-	/*
-	// This should invoke Bar::Bar() followed by foo(Bar *)
-	foo(Bar.new);
-
-	// Skip a line
-	write("\n");
-
-	// This should invoke Bar::Bar(double)
-	Bar.new(3.14159);
-
-	// This should invoke Bar::Bar(double, char *)
-	Bar.new(3.14159, "Pi");
-
-	// This should invoke Bar::Bar(int, int)
-	Bar.new(3, 4);
-
-	// This should invoke Bar::Bar(char *)
-	Bar.new("This is a test");
-
-	// This should invoke Bar::Bar(int)
-	Bar.new(42);
-
-	// This should invoke Bar::Bar() for the input argument,
-	// followed by Bar::Bar(const Bar&).
-	Bar.new(Bar.new);
-
-	// Skip a line
-	write("\n");
-	*/
-
-	// Construct a new Bar instance (invokes Bar::Bar())
-	/*
-	bar = Bar.new;
-
-	// This should invoke Bar::foo(double)
-	bar.foo(3.14159);
-
-	// This should invoke Bar::foo(double, char *)
-	bar.foo(3.14159, "Pi");
-
-	// This should invoke Bar::foo(int, int)
-	bar.foo(3, 4);
-
-	// This should invoke Bar::foo(char *)
-	bar.foo("This is a test");
-
-	// This should invoke Bar::foo(int)
-	bar.foo(42);
-
-	// This should invoke Bar::Bar() to construct the input
-	// argument, followed by Bar::foo(Bar *).
-	bar.foo(Example::Bar.new);
-
-	// This should invoke Bar::spam(int x, int y, int z)
-	bar.spam(1);
-
-	// This should invoke Bar::spam(double x, int y, int z)
-	bar.spam(3.14159);
-	*/
-
-   	write("Goodbye\n");
-    
-   	return 0;
-}
diff --git a/Examples/pike/simple/Makefile b/Examples/pike/simple/Makefile
deleted file mode 100644
index 8b49b4e..0000000
--- a/Examples/pike/simple/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-TOP        = ../..
-SWIGEXE    = $(TOP)/../swig
-SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-SRCS       = example.c
-TARGET     = example
-INTERFACE  = example.i
-
-check: build
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' pike_run
-
-build:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' pike
-
-static:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	TARGET='mypike' INTERFACE='$(INTERFACE)' pike_static
-
-clean:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' pike_clean
diff --git a/Examples/pike/simple/example.c b/Examples/pike/simple/example.c
deleted file mode 100644
index 1c2af78..0000000
--- a/Examples/pike/simple/example.c
+++ /dev/null
@@ -1,18 +0,0 @@
-/* File : example.c */
-
-/* A global variable */
-double Foo = 3.0;
-
-/* Compute the greatest common divisor of positive integers */
-int gcd(int x, int y) {
-  int g;
-  g = y;
-  while (x > 0) {
-    g = x;
-    x = y % x;
-    y = g;
-  }
-  return g;
-}
-
-
diff --git a/Examples/pike/simple/example.i b/Examples/pike/simple/example.i
deleted file mode 100644
index 24093b9..0000000
--- a/Examples/pike/simple/example.i
+++ /dev/null
@@ -1,7 +0,0 @@
-/* File : example.i */
-%module example
-
-%inline %{
-extern int    gcd(int x, int y);
-extern double Foo;
-%}
diff --git a/Examples/pike/simple/runme.pike b/Examples/pike/simple/runme.pike
deleted file mode 100644
index a6a78e9..0000000
--- a/Examples/pike/simple/runme.pike
+++ /dev/null
@@ -1,20 +0,0 @@
-int main()
-{
-    /* Call our gcd() function */
-    int x = 42;
-    int y = 105;
-    int g = .example.gcd(x, y);
-    write("The gcd of %d and %d is %d\n", x, y, g);
-
-    /* Manipulate the Foo global variable */
-    /* Output its current value */
-    write("Foo = %f\n", .example->Foo_get());
-
-    /* Change its value */
-    .example->Foo_set(3.1415926);
-
-    /* See if the change took effect */
-    write("Foo = %f\n", .example->Foo_get());
-    
-    return 0;
-}
diff --git a/Examples/pike/template/Makefile b/Examples/pike/template/Makefile
deleted file mode 100644
index 513dc3b..0000000
--- a/Examples/pike/template/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-TOP        = ../..
-SWIGEXE    = $(TOP)/../swig
-SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-CXXSRCS    =
-TARGET     = example
-INTERFACE  = example.i
-LIBS       = -lm
-SWIGOPT    =
-
-check: build
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' pike_run
-
-build:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' pike_cpp
-
-static:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	SWIGOPT='$(SWIGOPT)' TARGET='mypike' INTERFACE='$(INTERFACE)' pike_cpp_static
-
-clean:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' pike_clean
diff --git a/Examples/pike/template/example.h b/Examples/pike/template/example.h
deleted file mode 100644
index 7401df6..0000000
--- a/Examples/pike/template/example.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/* File : example.h */
-
-// Some template definitions
-
-template<class T> T max(T a, T b) { return  a>b ? a : b; }
-
-template<class T> class vector {
-  T *v;
-  int sz;
- public:
-  vector(int _sz) {
-    v = new T[_sz];
-    sz = _sz;
-  }
-  T &get(int index) {
-    return v[index];
-  }
-  void set(int index, T &val) {
-    v[index] = val;
-  }
-#ifdef SWIG
-  %extend {
-    T getitem(int index) {
-      return $self->get(index);
-    }
-    void setitem(int index, T val) {
-      $self->set(index,val);
-    }
-  }
-#endif
-};
-
diff --git a/Examples/pike/template/example.i b/Examples/pike/template/example.i
deleted file mode 100644
index 8f94c4d..0000000
--- a/Examples/pike/template/example.i
+++ /dev/null
@@ -1,17 +0,0 @@
-/* File : example.i */
-%module example
-
-%{
-#include "example.h"
-%}
-
-/* Let's just grab the original header file here */
-%include "example.h"
-
-/* Now instantiate some specific template declarations */
-
-%template(maxint) max<int>;
-%template(maxdouble) max<double>;
-%template(vecint) vector<int>;
-%template(vecdouble) vector<double>;
-
diff --git a/Examples/pike/template/runme.pike b/Examples/pike/template/runme.pike
deleted file mode 100644
index 36825c3..0000000
--- a/Examples/pike/template/runme.pike
+++ /dev/null
@@ -1,33 +0,0 @@
-int main()
-{
-    // Call some templated functions
-    write(sprintf("%d\n", .example.maxint(3, 7)));
-    write(sprintf("%f\n", .example.maxdouble(3.14, 2.18)));
-    
-    // Create some objects
-    .example.vecint iv = .example.vecint(100);
-    .example.vecdouble dv = .example.vecdouble(1000);
-    
-    for (int i = 0; i < 100; i++) {
-        iv->setitem(i, 2*i);
-    }
-
-    for (int i = 0; i < 1000; i++) {
-        dv->setitem(i, 1.0/(i+1));
-    }
-    
-    int isum = 0;
-    for (int i = 0; i < 100; i++) {
-        isum += iv->getitem(i);
-    }
-    
-    write(sprintf("%d\n", isum));
-    
-    float fsum = 0.0;
-    for (int i = 0; i < 1000; i++) {
-        fsum += dv->getitem(i);
-    }
-    write(sprintf("%f\n", fsum));
-    
-    return 0;
-}
diff --git a/Examples/python/callback/runme.py b/Examples/python/callback/runme.py
index 345a3eb..41deb83 100644
--- a/Examples/python/callback/runme.py
+++ b/Examples/python/callback/runme.py
@@ -11,7 +11,7 @@
         example.Callback.__init__(self)
 
     def run(self):
-        print "PyCallback.run()"
+        print("PyCallback.run()")
 
 # Create an Caller instance
 
@@ -20,8 +20,8 @@
 # Add a simple C++ callback (caller owns the callback, so
 # we disown it first by clearing the .thisown flag).
 
-print "Adding and calling a normal C++ callback"
-print "----------------------------------------"
+print("Adding and calling a normal C++ callback")
+print("----------------------------------------")
 
 callback = example.Callback()
 callback.thisown = 0
@@ -29,9 +29,9 @@
 caller.call()
 caller.delCallback()
 
-print
-print "Adding and calling a Python callback"
-print "------------------------------------"
+print("")
+print("Adding and calling a Python callback")
+print("------------------------------------")
 
 # Add a Python callback (caller owns the callback, so we
 # disown it first by calling __disown__).
@@ -40,9 +40,9 @@
 caller.call()
 caller.delCallback()
 
-print
-print "Adding and calling another Python callback"
-print "------------------------------------------"
+print("")
+print("Adding and calling another Python callback")
+print("------------------------------------------")
 
 # Let's do the same but use the weak reference this time.
 
@@ -53,5 +53,5 @@
 
 # All done.
 
-print
-print "python exit"
+print("")
+print("python exit")
diff --git a/Examples/python/check.list b/Examples/python/check.list
index 0798b5f..a9c4aef 100644
--- a/Examples/python/check.list
+++ b/Examples/python/check.list
@@ -13,17 +13,16 @@
 funcptr2
 functor
 import
-import_template
 import_packages
-#libffi
+import_template
 multimap
 operator
 pointer
 reference
 simple
 smartptr
-std_vector
 std_map
+std_vector
 template
 varargs
 variables
diff --git a/Examples/python/class/runme.py b/Examples/python/class/runme.py
index 34d2150..adade74 100644
--- a/Examples/python/class/runme.py
+++ b/Examples/python/class/runme.py
@@ -7,15 +7,15 @@
 
 # ----- Object creation -----
 
-print "Creating some objects:"
+print("Creating some objects:")
 c = example.Circle(10)
-print "    Created circle", c
+print("    Created circle %s" % c)
 s = example.Square(10)
-print "    Created square", s
+print("    Created square %s" % s)
 
 # ----- Access a static member -----
 
-print "\nA total of", example.cvar.Shape_nshapes, "shapes were created"
+print("\nA total of %d shapes were created" % example.cvar.Shape_nshapes)
 
 # ----- Member data access -----
 
@@ -27,25 +27,25 @@
 s.x = -10
 s.y = 5
 
-print "\nHere is their current position:"
-print "    Circle = (%f, %f)" % (c.x, c.y)
-print "    Square = (%f, %f)" % (s.x, s.y)
+print("\nHere is their current position:")
+print("    Circle = (%f, %f)" % (c.x, c.y))
+print("    Square = (%f, %f)" % (s.x, s.y))
 
 # ----- Call some methods -----
 
-print "\nHere are some properties of the shapes:"
+print("\nHere are some properties of the shapes:")
 for o in [c, s]:
-    print "   ", o
-    print "        area      = ", o.area()
-    print "        perimeter = ", o.perimeter()
+    print("    %s" % o)
+    print("        area      = %s" % o.area())
+    print("        perimeter = %s" % o.perimeter())
 # prevent o from holding a reference to the last object looked at
 o = None
 
-print "\nGuess I'll clean up now"
+print("\nGuess I'll clean up now")
 
 # Note: this invokes the virtual destructor
 del c
 del s
 
-print example.cvar.Shape_nshapes, "shapes remain"
-print "Goodbye"
+print("%d shapes remain" % example.cvar.Shape_nshapes)
+print("Goodbye")
diff --git a/Examples/python/constants/runme.py b/Examples/python/constants/runme.py
index 415d1ad..808bf1f 100644
--- a/Examples/python/constants/runme.py
+++ b/Examples/python/constants/runme.py
@@ -2,22 +2,24 @@
 
 import example
 
-print "ICONST  =", example.ICONST, "(should be 42)"
-print "FCONST  =", example.FCONST, "(should be 2.1828)"
-print "CCONST  =", example.CCONST, "(should be 'x')"
-print "CCONST2 =", example.CCONST2, "(this should be on a new line)"
-print "SCONST  =", example.SCONST, "(should be 'Hello World')"
-print "SCONST2 =", example.SCONST2, "(should be '\"Hello World\"')"
-print "EXPR    =", example.EXPR, "(should be 48.5484)"
-print "iconst  =", example.iconst, "(should be 37)"
-print "fconst  =", example.fconst, "(should be 3.14)"
+print("ICONST  = %s (should be 42)" % example.ICONST)
+print("FCONST  = %s (should be 2.1828)" % example.FCONST)
+print("CCONST  = %s (should be 'x')" % example.CCONST)
+print("CCONST2 = %s (this should be on a new line)" % example.CCONST2)
+print("SCONST  = %s (should be 'Hello World')" % example.SCONST)
+print("SCONST2 = %s (should be '\"Hello World\"')" % example.SCONST2)
+print("EXPR    = %s (should be 48.5484)" % example.EXPR)
+print("iconst  = %s (should be 37)" % example.iconst)
+print("fconst  = %s (should be 3.14)" % example.fconst)
 
 try:
-    print "EXTERN = ", example.EXTERN, "(Arg! This shouldn't print anything)"
+    x = example.EXTERN
+    print("%s (Arg! This shouldn't print anything)" % x)
 except AttributeError:
-    print "EXTERN isn't defined (good)"
+    print("EXTERN isn't defined (good)")
 
 try:
-    print "FOO    = ", example.FOO, "(Arg! This shouldn't print anything)"
+    x = example.FOO
+    print("%s (Arg! This shouldn't print anything)" % x)
 except AttributeError:
-    print "FOO isn't defined (good)"
+    print("FOO isn't defined (good)")
diff --git a/Examples/python/contract/runme.py b/Examples/python/contract/runme.py
index ce01e5a..ec0aceb 100644
--- a/Examples/python/contract/runme.py
+++ b/Examples/python/contract/runme.py
@@ -7,15 +7,15 @@
 x = 42
 y = 105
 g = example.gcd(x, y)
-print "The gcd of %d and %d is %d" % (x, y, g)
+print("The gcd of %d and %d is %d" % (x, y, g))
 
 # Manipulate the Foo global variable
 
 # Output its current value
-print "Foo = ", example.cvar.Foo
+print("Foo = %s" % example.cvar.Foo)
 
 # Change its value
 example.cvar.Foo = 3.1415926
 
 # See if the change took effect
-print "Foo = ", example.cvar.Foo
+print("Foo = %s" % example.cvar.Foo)
diff --git a/Examples/python/docstrings/Makefile b/Examples/python/docstrings/Makefile
index f1365a5..0f70524 100644
--- a/Examples/python/docstrings/Makefile
+++ b/Examples/python/docstrings/Makefile
@@ -5,7 +5,6 @@
 TARGET     = example
 INTERFACE  = example.i
 LIBS       = -lm
-SWIGOPT    = -O
 
 check: build
 	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' python_run
diff --git a/Examples/python/docstrings/runme.py b/Examples/python/docstrings/runme.py
index c25d291..76386d2 100644
--- a/Examples/python/docstrings/runme.py
+++ b/Examples/python/docstrings/runme.py
@@ -2,4 +2,4 @@
 
 import example
 
-print "example.Foo.bar.__doc__  =", repr(example.Foo.bar.__doc__), "(Should be 'No comment')"
+print("example.Foo.bar.__doc__ = %s (Should be 'No comment')" % repr(example.Foo.bar.__doc__))
diff --git a/Examples/python/doxygen/runme.py b/Examples/python/doxygen/runme.py
index e235288..657535c 100644
--- a/Examples/python/doxygen/runme.py
+++ b/Examples/python/doxygen/runme.py
@@ -5,24 +5,24 @@
 
 import example
 
-print "Creating some objects:"
+print("Creating some objects:")
 c = example.MakeCircle(10)
-print "    Created circle", c
+print("    Created circle %s" % c)
 s = example.MakeSquare(10)
-print "    Created square", s
+print("    Created square %s" % s)
 r = example.MakeRectangleInt(10, 20)
-print "    Created rectangle", r
+print("    Created rectangle %s" % r)
 
-print "\nHere are some properties of the shapes:"
+print("\nHere are some properties of the shapes:")
 for o in [c, s, r]:
-    print "   ", o
-    print "        area      = ", o.area()
-    print "        perimeter = ", o.perimeter()
+    print("    %s" % o)
+    print("        area      = %s" % o.area())
+    print("        perimeter = %s" % o.perimeter())
 
-print "\nRunning pydoc, this is the equivalent to executing: pydoc -w ./example.py"
+print("\nRunning pydoc, this is the equivalent to executing: pydoc -w ./example.py")
 
 import pydoc
 
 pydoc.writedoc("example")
 
-print "Open example.html in your browser to view the generated python docs"
+print("Open example.html in your browser to view the generated python docs")
diff --git a/Examples/python/enum/runme.py b/Examples/python/enum/runme.py
index def01b1..4920c1d 100644
--- a/Examples/python/enum/runme.py
+++ b/Examples/python/enum/runme.py
@@ -5,24 +5,24 @@
 # ----- Object creation -----
 
 # Print out the value of some enums
-print "*** color ***"
-print "    RED    =", example.RED
-print "    BLUE   =", example.BLUE
-print "    GREEN  =", example.GREEN
+print("*** color ***")
+print("    RED    = %s" % example.RED)
+print("    BLUE   = %s" % example.BLUE)
+print("    GREEN  = %s" % example.GREEN)
 
-print "\n*** Foo::speed ***"
-print "    Foo_IMPULSE   =", example.Foo.IMPULSE
-print "    Foo_WARP      =", example.Foo.WARP
-print "    Foo_LUDICROUS =", example.Foo.LUDICROUS
+print("\n*** Foo::speed ***")
+print("    Foo_IMPULSE   = %s" % example.Foo.IMPULSE)
+print("    Foo_WARP      = %s" % example.Foo.WARP)
+print("    Foo_LUDICROUS = %s" % example.Foo.LUDICROUS)
 
-print "\nTesting use of enums with functions\n"
+print("\nTesting use of enums with functions\n")
 
 example.enum_test(example.RED, example.Foo.IMPULSE)
 example.enum_test(example.BLUE, example.Foo.WARP)
 example.enum_test(example.GREEN, example.Foo.LUDICROUS)
 example.enum_test(1234, 5678)
 
-print "\nTesting use of enum with class method"
+print("\nTesting use of enum with class method")
 f = example.Foo()
 
 f.enum_test(example.Foo.IMPULSE)
diff --git a/Examples/python/exception/example.h b/Examples/python/exception/example.h
index bc744cd..c76c46a 100644
--- a/Examples/python/exception/example.h
+++ b/Examples/python/exception/example.h
@@ -10,7 +10,7 @@
 public:
   Exc(int c, const char *m) {
     code = c;
-    strncpy(msg,m,256);
+    strncpy(msg,m,255);
   }
   int code;
   char msg[256];
diff --git a/Examples/python/exception/runme.py b/Examples/python/exception/runme.py
index 7fae490..7b5c10d 100644
--- a/Examples/python/exception/runme.py
+++ b/Examples/python/exception/runme.py
@@ -7,36 +7,36 @@
 t = example.Test()
 try:
     t.unknown()
-except RuntimeError, e:
-    print "incomplete type", e.args[0]
+except RuntimeError as e:
+    print("incomplete type %s" % e.args[0])
 
 try:
     t.simple()
-except RuntimeError, e:
-    print e.args[0]
+except RuntimeError as e:
+    print(e.args[0])
 
 try:
     t.message()
-except RuntimeError, e:
-    print e.args[0]
+except RuntimeError as e:
+    print(e.args[0])
 
 if not example.is_python_builtin():
     try:
         t.hosed()
-    except example.Exc, e:
-        print e.code, e.msg
+    except example.Exc as e:
+        print("%s %s" % (e.code, e.msg))
 else:
     try:
         t.hosed()
-    except BaseException, e:
+    except BaseException as e:
         # Throwing builtin classes as exceptions not supported (-builtin
         # option)
-        print e
+        print(e)
 
 for i in range(1, 4):
     try:
         t.multi(i)
-    except RuntimeError, e:
-        print e.args[0]
-    except example.Exc, e:
-        print e.code, e.msg
+    except RuntimeError as e:
+        print(e.args[0])
+    except example.Exc as e:
+        print("%s %s" % (e.code, e.msg))
diff --git a/Examples/python/exceptproxy/example.h b/Examples/python/exceptproxy/example.h
index 3ee6d76..7148d4d 100644
--- a/Examples/python/exceptproxy/example.h
+++ b/Examples/python/exceptproxy/example.h
@@ -31,7 +31,7 @@
     last = (last + 1) % maxsize;
     nitems++;
   }
-  T dequeue()  {
+  T dequeue() {
     T x;
     if (nitems == 0) throw EmptyError();
     x = items[(last + maxsize - nitems) % maxsize];
diff --git a/Examples/python/exceptproxy/runme.py b/Examples/python/exceptproxy/runme.py
index 970d620..d25fb6d 100644
--- a/Examples/python/exceptproxy/runme.py
+++ b/Examples/python/exceptproxy/runme.py
@@ -2,44 +2,44 @@
 import example
 
 if example.is_python_builtin():
-    print "Skipping example: -builtin option does not support %exceptionclass"
+    print("Skipping example: -builtin option does not support %exceptionclass")
     exit(0)
 
 q = example.intQueue(10)
 
-print "Inserting items into intQueue"
+print("Inserting items into intQueue")
 
-print type(example.FullError)
+print(type(example.FullError))
 
 try:
     for i in range(0, 100):
         q.enqueue(i)
-except example.FullError, e:
-    print "Maxsize is", e.maxsize
+except example.FullError as e:
+    print("Maxsize is %s" % e.maxsize)
 
-print "Removing items"
+print("Removing items")
 
 try:
-    while 1:
+    while True:
         q.dequeue()
-except example.EmptyError, e:
+except example.EmptyError as e:
     pass
 
 
 q = example.doubleQueue(1000)
 
-print "Inserting items into doubleQueue"
+print("Inserting items into doubleQueue")
 
 try:
     for i in range(0, 10000):
         q.enqueue(i * 1.5)
-except example.FullError, e:
-    print "Maxsize is", e.maxsize
+except example.FullError as e:
+    print("Maxsize is %s" % e.maxsize)
 
-print "Removing items"
+print("Removing items")
 
 try:
-    while 1:
+    while True:
         q.dequeue()
-except example.EmptyError, e:
+except example.EmptyError as e:
     pass
diff --git a/Examples/python/extend/runme.py b/Examples/python/extend/runme.py
index e97358b..d7e626e 100644
--- a/Examples/python/extend/runme.py
+++ b/Examples/python/extend/runme.py
@@ -21,9 +21,9 @@
 # the director wrappers to call CEO.getPosition.
 
 e = CEO("Alice")
-print e.getName(), "is a", e.getPosition()
-print "Just call her \"%s\"" % e.getTitle()
-print "----------------------"
+print("%s is a %s" % (e.getName(), e.getPosition()))
+print("Just call her \"%s\"" % e.getTitle())
+print("----------------------")
 
 
 # Create a new EmployeeList instance.  This class does not have a C++
@@ -40,7 +40,7 @@
 
 e = e.__disown__()
 list.addEmployee(e)
-print "----------------------"
+print("----------------------")
 
 # Now we access the first four items in list (three are C++ objects that
 # EmployeeList's constructor adds, the last is our CEO). The virtual
@@ -59,13 +59,13 @@
 # passes down through the C++ director class to the Python implementation
 # in CEO. All this routing takes place transparently.
 
-print "(position, title) for items 0-3:"
+print("(position, title) for items 0-3:")
 
-print "  %s, \"%s\"" % (list.get_item(0).getPosition(), list.get_item(0).getTitle())
-print "  %s, \"%s\"" % (list.get_item(1).getPosition(), list.get_item(1).getTitle())
-print "  %s, \"%s\"" % (list.get_item(2).getPosition(), list.get_item(2).getTitle())
-print "  %s, \"%s\"" % (list.get_item(3).getPosition(), list.get_item(3).getTitle())
-print "----------------------"
+print("  %s, \"%s\"" % (list.get_item(0).getPosition(), list.get_item(0).getTitle()))
+print("  %s, \"%s\"" % (list.get_item(1).getPosition(), list.get_item(1).getTitle()))
+print("  %s, \"%s\"" % (list.get_item(2).getPosition(), list.get_item(2).getTitle()))
+print("  %s, \"%s\"" % (list.get_item(3).getPosition(), list.get_item(3).getTitle()))
+print("----------------------")
 
 # Time to delete the EmployeeList, which will delete all the Employee*
 # items it contains. The last item is our CEO, which gets destroyed as its
@@ -75,8 +75,8 @@
 # usual to destroy the object.
 
 del list
-print "----------------------"
+print("----------------------")
 
 # All done.
 
-print "python exit"
+print("python exit")
diff --git a/Examples/python/funcptr/runme.py b/Examples/python/funcptr/runme.py
index bf0c6e1..4248f92 100644
--- a/Examples/python/funcptr/runme.py
+++ b/Examples/python/funcptr/runme.py
@@ -7,14 +7,14 @@
 
 # Now call our C function with a bunch of callbacks
 
-print "Trying some C callback functions"
-print "    a        =", a
-print "    b        =", b
-print "    ADD(a,b) =", example.do_op(a, b, example.ADD)
-print "    SUB(a,b) =", example.do_op(a, b, example.SUB)
-print "    MUL(a,b) =", example.do_op(a, b, example.MUL)
+print("Trying some C callback functions")
+print("    a        = %s" % a)
+print("    b        = %s" % b)
+print("    ADD(a,b) = %s" % example.do_op(a, b, example.ADD))
+print("    SUB(a,b) = %s" % example.do_op(a, b, example.SUB))
+print("    MUL(a,b) = %s" % example.do_op(a, b, example.MUL))
 
-print "Here is what the C callback function objects look like in Python"
-print "    ADD      =", example.ADD
-print "    SUB      =", example.SUB
-print "    MUL      =", example.MUL
+print("Here is what the C callback function objects look like in Python")
+print("    ADD      = %s" % example.ADD)
+print("    SUB      = %s" % example.SUB)
+print("    MUL      = %s" % example.MUL)
diff --git a/Examples/python/funcptr2/runme.py b/Examples/python/funcptr2/runme.py
index a4405d9..afa2e2d 100644
--- a/Examples/python/funcptr2/runme.py
+++ b/Examples/python/funcptr2/runme.py
@@ -7,18 +7,18 @@
 
 # Now call our C function with a bunch of callbacks
 
-print "Trying some C callback functions"
-print "    a        =", a
-print "    b        =", b
-print "    ADD(a,b) =", example.do_op(a, b, example.ADD)
-print "    SUB(a,b) =", example.do_op(a, b, example.SUB)
-print "    MUL(a,b) =", example.do_op(a, b, example.MUL)
+print("Trying some C callback functions")
+print("    a        = %s" % a)
+print("    b        = %s" % b)
+print("    ADD(a,b) = %s" % example.do_op(a, b, example.ADD))
+print("    SUB(a,b) = %s" % example.do_op(a, b, example.SUB))
+print("    MUL(a,b) = %s" % example.do_op(a, b, example.MUL))
 
-print "Here is what the C callback function objects look like in Python"
-print "    ADD      =", example.ADD
-print "    SUB      =", example.SUB
-print "    MUL      =", example.MUL
+print("Here is what the C callback function objects look like in Python")
+print("    ADD      = %s" % example.ADD)
+print("    SUB      = %s" % example.SUB)
+print("    MUL      = %s" % example.MUL)
 
-print "Call the functions directly..."
-print "    add(a,b) =", example.add(a, b)
-print "    sub(a,b) =", example.sub(a, b)
+print("Call the functions directly...")
+print("    add(a,b) = %s" % example.add(a, b))
+print("    sub(a,b) = %s" % example.sub(a, b))
diff --git a/Examples/python/functor/runme.py b/Examples/python/functor/runme.py
index 7f6f2b6..69289a7 100644
--- a/Examples/python/functor/runme.py
+++ b/Examples/python/functor/runme.py
@@ -12,5 +12,5 @@
     a(i)                # Note: function call
     b(math.sqrt(i))     # Note: function call
 
-print a.result()
-print b.result()
+print(a.result())
+print(b.result())
diff --git a/Examples/python/import/runme.py b/Examples/python/import/runme.py
index 0e83aca..7970dec 100644
--- a/Examples/python/import/runme.py
+++ b/Examples/python/import/runme.py
@@ -1,15 +1,22 @@
 # file: runme.py
 # Test various properties of classes defined in separate modules
+import sys
 
-print "Testing the %import directive"
+print("Testing the %import directive")
+
 import base
 import foo
 import bar
 import spam
 
+def write_flush(s):
+    # Python 2/3 compatible write and flush
+    sys.stdout.write(s)
+    sys.stdout.flush()
+
 # Create some objects
 
-print "Creating some objects"
+print("Creating some objects")
 
 a = base.Base()
 b = foo.Foo()
@@ -17,91 +24,74 @@
 d = spam.Spam()
 
 # Try calling some methods
-print "Testing some methods"
-print "",
-print "Should see 'Base::A' ---> ",
+print("Testing some methods")
+
+write_flush("  Should see 'Base::A' ---> ")
 a.A()
-print "Should see 'Base::B' ---> ",
+write_flush("  Should see 'Base::B' ---> ")
 a.B()
 
-print "Should see 'Foo::A' ---> ",
+write_flush("  Should see 'Foo::A' ---> ")
 b.A()
-print "Should see 'Foo::B' ---> ",
+write_flush("  Should see 'Foo::B' ---> ")
 b.B()
 
-print "Should see 'Bar::A' ---> ",
+write_flush("  Should see 'Bar::A' ---> ")
 c.A()
-print "Should see 'Bar::B' ---> ",
+write_flush("  Should see 'Bar::B' ---> ")
 c.B()
 
-print "Should see 'Spam::A' ---> ",
+write_flush("  Should see 'Spam::A' ---> ")
 d.A()
-print "Should see 'Spam::B' ---> ",
+write_flush("  Should see 'Spam::B' ---> ")
 d.B()
 
 # Try some casts
 
-print "\nTesting some casts\n"
-print "",
+print("\nTesting some casts\n")
 
 x = a.toBase()
-print "Should see 'Base::A' ---> ",
+write_flush("  Should see 'Base::A' ---> ")
 x.A()
-print "Should see 'Base::B' ---> ",
+write_flush("  Should see 'Base::B' ---> ")
 x.B()
 
 x = b.toBase()
-print "Should see 'Foo::A' ---> ",
+write_flush("  Should see 'Foo::A' ---> ")
 x.A()
 
-print "Should see 'Base::B' ---> ",
+write_flush("  Should see 'Base::B' ---> ")
 x.B()
 
 x = c.toBase()
-print "Should see 'Bar::A' ---> ",
+write_flush("  Should see 'Bar::A' ---> ")
 x.A()
 
-print "Should see 'Base::B' ---> ",
+write_flush("  Should see 'Base::B' ---> ")
 x.B()
 
 x = d.toBase()
-print "Should see 'Spam::A' ---> ",
+write_flush("  Should see 'Spam::A' ---> ")
 x.A()
 
-print "Should see 'Base::B' ---> ",
+write_flush("  Should see 'Base::B' ---> ")
 x.B()
 
 x = d.toBar()
-print "Should see 'Bar::B' ---> ",
+write_flush("  Should see 'Bar::B' ---> ")
 x.B()
 
-print "\nTesting some dynamic casts\n"
+print("\nTesting some dynamic casts\n")
 x = d.toBase()
 
-print " Spam -> Base -> Foo : ",
-y = foo.Foo_fromBase(x)
-if y:
-    print "bad swig"
-else:
-    print "good swig"
+y = foo.Foo.fromBase(x)
+print("  Spam -> Base -> Foo : {} swig".format("bad" if y else "good"))
 
-print " Spam -> Base -> Bar : ",
-y = bar.Bar_fromBase(x)
-if y:
-    print "good swig"
-else:
-    print "bad swig"
+y = bar.Bar.fromBase(x)
+print("  Spam -> Base -> Bar : {} swig".format("good" if y else "bad"))
 
-print " Spam -> Base -> Spam : ",
-y = spam.Spam_fromBase(x)
-if y:
-    print "good swig"
-else:
-    print "bad swig"
+y = spam.Spam.fromBase(x)
+print("  Spam -> Base -> Spam : {} swig".format("good" if y else "bad"))
 
-print " Foo -> Spam : ",
-y = spam.Spam_fromBase(b)
-if y:
-    print "bad swig"
-else:
-    print "good swig"
+y = spam.Spam.fromBase(b)
+print("  Foo -> Spam : {} swig".format("bad" if y else "good"))
diff --git a/Examples/python/import_packages/from_init1/Makefile b/Examples/python/import_packages/from_init1/Makefile
index 90c92ab..f08c334 100644
--- a/Examples/python/import_packages/from_init1/Makefile
+++ b/Examples/python/import_packages/from_init1/Makefile
@@ -1,7 +1,7 @@
 TOP        = ../../..
 LIBS       =
 
-ifeq (,$(PY3))
+ifneq (,$(PY2))
   PKG1DIR  = "py2"
 else
   PKG1DIR  = "py3"
diff --git a/Examples/python/import_packages/from_init1/runme.py b/Examples/python/import_packages/from_init1/runme.py
index a663a13..1ed8898 100644
--- a/Examples/python/import_packages/from_init1/runme.py
+++ b/Examples/python/import_packages/from_init1/runme.py
@@ -4,28 +4,28 @@
 
 def run_except_on_windows(commandline, env=None):
     if os.name != "nt" and sys.platform != "cygwin":
-        # Strange failures on windows/cygin/mingw
+        # Strange failures on windows/cygwin/mingw
         subprocess.check_call(commandline, env=env, shell=True)
-        print("  Finished running: " + commandline)
+        print(("  Finished running: " + commandline))
 
 # Test import of modules content from within __init__.py
 testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
-print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
+print("Testing " + testname + " - %module(package=...) + python 'import' in __init__.py")
 
 if sys.version_info < (2, 5):
-    print "  Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
+    print("  Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'")
     sys.exit(0)
 
 if sys.version_info < (3, 0):
     import py2.pkg2
-    print "  Finished importing py2.pkg2"
+    print("  Finished importing py2.pkg2")
     commandline = sys.executable + " -m py2.pkg2.bar"
     run_except_on_windows(commandline)
     commandline = sys.executable + " -m py2.pkg2.foo"
     run_except_on_windows(commandline)
 else:
     import py3.pkg2
-    print "  Finished importing py3.pkg2"
+    print("  Finished importing py3.pkg2")
     # commandline = sys.executable + " -m py3.pkg2.bar"
     # run_except_on_windows(commandline)
     # commandline = sys.executable + " -m py3.pkg2.foo"
diff --git a/Examples/python/import_packages/from_init2/Makefile b/Examples/python/import_packages/from_init2/Makefile
index 90c92ab..f08c334 100644
--- a/Examples/python/import_packages/from_init2/Makefile
+++ b/Examples/python/import_packages/from_init2/Makefile
@@ -1,7 +1,7 @@
 TOP        = ../../..
 LIBS       =
 
-ifeq (,$(PY3))
+ifneq (,$(PY2))
   PKG1DIR  = "py2"
 else
   PKG1DIR  = "py3"
diff --git a/Examples/python/import_packages/from_init2/runme.py b/Examples/python/import_packages/from_init2/runme.py
index 3c7b126..100c97b 100644
--- a/Examples/python/import_packages/from_init2/runme.py
+++ b/Examples/python/import_packages/from_init2/runme.py
@@ -4,26 +4,26 @@
 
 def run_except_on_windows(commandline, env=None):
     if os.name != "nt" and sys.platform != "cygwin":
-        # Strange failures on windows/cygin/mingw
+        # Strange failures on windows/cygwin/mingw
         subprocess.check_call(commandline, env=env, shell=True)
-        print("  Finished running: " + commandline)
+        print(("  Finished running: " + commandline))
 
 # Test import of modules content from within __init__.py
 testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
-print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
+print("Testing " + testname + " - %module(package=...) + python 'import' in __init__.py")
 
 if sys.version_info < (2, 5):
-    print "  Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
+    print("  Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'")
     sys.exit(0)
 
 if sys.version_info < (3, 0):
     import py2.pkg2
-    print "  Finished importing py2.pkg2"
+    print("  Finished importing py2.pkg2")
     commandline = sys.executable + " -m py2.pkg2.bar"
     run_except_on_windows(commandline)
 else:
     import py3.pkg2
-    print "  Finished importing py3.pkg2"
+    print("  Finished importing py3.pkg2")
     # commandline = sys.executable + " -m py3.pkg2.bar"
     # run_except_on_windows(commandline)
 
diff --git a/Examples/python/import_packages/from_init3/Makefile b/Examples/python/import_packages/from_init3/Makefile
index 90c92ab..f08c334 100644
--- a/Examples/python/import_packages/from_init3/Makefile
+++ b/Examples/python/import_packages/from_init3/Makefile
@@ -1,7 +1,7 @@
 TOP        = ../../..
 LIBS       =
 
-ifeq (,$(PY3))
+ifneq (,$(PY2))
   PKG1DIR  = "py2"
 else
   PKG1DIR  = "py3"
diff --git a/Examples/python/import_packages/from_init3/runme.py b/Examples/python/import_packages/from_init3/runme.py
index 3c7b126..100c97b 100644
--- a/Examples/python/import_packages/from_init3/runme.py
+++ b/Examples/python/import_packages/from_init3/runme.py
@@ -4,26 +4,26 @@
 
 def run_except_on_windows(commandline, env=None):
     if os.name != "nt" and sys.platform != "cygwin":
-        # Strange failures on windows/cygin/mingw
+        # Strange failures on windows/cygwin/mingw
         subprocess.check_call(commandline, env=env, shell=True)
-        print("  Finished running: " + commandline)
+        print(("  Finished running: " + commandline))
 
 # Test import of modules content from within __init__.py
 testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
-print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
+print("Testing " + testname + " - %module(package=...) + python 'import' in __init__.py")
 
 if sys.version_info < (2, 5):
-    print "  Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
+    print("  Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'")
     sys.exit(0)
 
 if sys.version_info < (3, 0):
     import py2.pkg2
-    print "  Finished importing py2.pkg2"
+    print("  Finished importing py2.pkg2")
     commandline = sys.executable + " -m py2.pkg2.bar"
     run_except_on_windows(commandline)
 else:
     import py3.pkg2
-    print "  Finished importing py3.pkg2"
+    print("  Finished importing py3.pkg2")
     # commandline = sys.executable + " -m py3.pkg2.bar"
     # run_except_on_windows(commandline)
 
diff --git a/Examples/python/import_packages/module_is_init/runme.py b/Examples/python/import_packages/module_is_init/runme.py
index b5e646e..42d4899 100644
--- a/Examples/python/import_packages/module_is_init/runme.py
+++ b/Examples/python/import_packages/module_is_init/runme.py
@@ -3,18 +3,10 @@
 
 # Test import of a SWIG generated module renamed as the package's __init__.py
 testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
-print "Testing " + testname + " - module renamed as __init__.py"
-
-if sys.version_info >= (3, 0, 0) and sys.version_info < (3, 3, 0):
-    print "  Not importing as Python version is >= 3.0 and < 3.3"
-    # Package detection does not work in these versions.
-    # Can be fixed by using this in the interface file:
-    #   %module(moduleimport="from . import $module") foo   # without -builtin
-    #   %module(moduleimport="from .$module import *") foo  # with -builtin
-    sys.exit(0)
+print("Testing " + testname + " - module renamed as __init__.py")
 
 import pkg1
-print "  Finished importing pkg1"
+print("  Finished importing pkg1")
 
 if pkg1.foofunction(123) != 1230:
     raise RuntimeError("foofunction failed")
@@ -23,4 +15,4 @@
 if fc.foomethod(1) != 6:
     raise RuntimeError("foomethod failed")
 
-print "  Finished testing pkg1"
+print("  Finished testing pkg1")
diff --git a/Examples/python/import_packages/namespace_pkg/nonpkg.py b/Examples/python/import_packages/namespace_pkg/nonpkg.py
index 52be74d..e872890 100644
--- a/Examples/python/import_packages/namespace_pkg/nonpkg.py
+++ b/Examples/python/import_packages/namespace_pkg/nonpkg.py
@@ -4,7 +4,7 @@
 
 def run_except_on_windows(commandline, env=None):
     if os.name != "nt" and sys.platform != "cygwin":
-        # Strange failures on windows/cygin/mingw
+        # Strange failures on windows/cygwin/mingw
         subprocess.check_call(commandline, env=env, shell=True)
         print("  Finished running: " + commandline)
 
diff --git a/Examples/python/import_packages/namespace_pkg/normal.py b/Examples/python/import_packages/namespace_pkg/normal.py
index 0eb8f51..f8fb025 100644
--- a/Examples/python/import_packages/namespace_pkg/normal.py
+++ b/Examples/python/import_packages/namespace_pkg/normal.py
@@ -4,7 +4,7 @@
 
 def run_except_on_windows(commandline, env=None):
     if os.name != "nt" and sys.platform != "cygwin":
-        # Strange failures on windows/cygin/mingw
+        # Strange failures on windows/cygwin/mingw
         subprocess.check_call(commandline, env=env, shell=True)
         print("  Finished running: " + commandline)
 
diff --git a/Examples/python/import_packages/namespace_pkg/nstest.py b/Examples/python/import_packages/namespace_pkg/nstest.py
index 4d618a6..0cd2a99 100644
--- a/Examples/python/import_packages/namespace_pkg/nstest.py
+++ b/Examples/python/import_packages/namespace_pkg/nstest.py
@@ -6,7 +6,7 @@
 
 def run_except_on_windows(commandline, env=None):
     if os.name != "nt" and sys.platform != "cygwin":
-        # Strange failures on windows/cygin/mingw
+        # Strange failures on windows/cygwin/mingw
         subprocess.check_call(commandline, env=env, shell=True)
         print("  Finished running: " + commandline)
 
diff --git a/Examples/python/import_packages/namespace_pkg/runme.py b/Examples/python/import_packages/namespace_pkg/runme.py
index d2af056..54a8e4e 100644
--- a/Examples/python/import_packages/namespace_pkg/runme.py
+++ b/Examples/python/import_packages/namespace_pkg/runme.py
@@ -5,14 +5,14 @@
 import sys
 
 testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
-print "Testing " + testname + " - namespace packages"
+print("Testing " + testname + " - namespace packages")
 
 if sys.version_info < (3, 3, 0):
-    print "  Not importing nstest as Python version is < 3.3"
+    print("  Not importing nstest as Python version is < 3.3")
     sys.exit(0)
 
 import nstest
 
-print "  Finished importing nstest"
+print("  Finished importing nstest")
 
 nstest.main()
diff --git a/Examples/python/import_packages/namespace_pkg/split.py b/Examples/python/import_packages/namespace_pkg/split.py
index 9d786dc..ed259b6 100644
--- a/Examples/python/import_packages/namespace_pkg/split.py
+++ b/Examples/python/import_packages/namespace_pkg/split.py
@@ -4,7 +4,7 @@
 
 def run_except_on_windows(commandline, env=None):
     if os.name != "nt" and sys.platform != "cygwin":
-        # Strange failures on windows/cygin/mingw
+        # Strange failures on windows/cygwin/mingw
         subprocess.check_call(commandline, env=env, shell=True)
         print("  Finished running: " + commandline)
 
diff --git a/Examples/python/import_packages/namespace_pkg/zipsplit.py b/Examples/python/import_packages/namespace_pkg/zipsplit.py
index 30434f9..474f2c7 100644
--- a/Examples/python/import_packages/namespace_pkg/zipsplit.py
+++ b/Examples/python/import_packages/namespace_pkg/zipsplit.py
@@ -4,7 +4,7 @@
 
 def run_except_on_windows(commandline, env=None):
     if os.name != "nt" and sys.platform != "cygwin":
-        # Strange failures on windows/cygin/mingw
+        # Strange failures on windows/cygwin/mingw
         subprocess.check_call(commandline, env=env, shell=True)
         print("  Finished running: " + commandline)
 
diff --git a/Examples/python/import_packages/relativeimport1/Makefile b/Examples/python/import_packages/relativeimport1/Makefile
index 90c92ab..f08c334 100644
--- a/Examples/python/import_packages/relativeimport1/Makefile
+++ b/Examples/python/import_packages/relativeimport1/Makefile
@@ -1,7 +1,7 @@
 TOP        = ../../..
 LIBS       =
 
-ifeq (,$(PY3))
+ifneq (,$(PY2))
   PKG1DIR  = "py2"
 else
   PKG1DIR  = "py3"
diff --git a/Examples/python/import_packages/relativeimport1/runme.py b/Examples/python/import_packages/relativeimport1/runme.py
index 87101ea..ff8ca04 100644
--- a/Examples/python/import_packages/relativeimport1/runme.py
+++ b/Examples/python/import_packages/relativeimport1/runme.py
@@ -4,28 +4,28 @@
 
 def run_except_on_windows(commandline, env=None):
     if os.name != "nt" and sys.platform != "cygwin":
-        # Strange failures on windows/cygin/mingw
+        # Strange failures on windows/cygwin/mingw
         subprocess.check_call(commandline, env=env, shell=True)
-        print("  Finished running: " + commandline)
+        print(("  Finished running: " + commandline))
 
 # Test import of modules content from within __init__.py
 testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
-print "Testing " + testname + " - %module(package=...) with -relativeimport"
+print("Testing " + testname + " - %module(package=...) with -relativeimport")
 
 if sys.version_info < (2, 5):
-    print "  Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
+    print("  Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'")
     sys.exit(0)
 
 if sys.version_info < (3, 0):
     import py2.pkg2.bar
-    print "  Finished importing py2.pkg2.bar"
+    print("  Finished importing py2.pkg2.bar")
     commandline = sys.executable + " -m py2.pkg2.bar"
     run_except_on_windows(commandline)
     commandline = sys.executable + " -m py2.pkg2.pkg3.foo"
     run_except_on_windows(commandline)
 else:
     import py3.pkg2.bar
-    print "  Finished importing py3.pkg2.bar"
+    print("  Finished importing py3.pkg2.bar")
     commandline = sys.executable + " -m py3.pkg2.bar"
     run_except_on_windows(commandline)
     commandline = sys.executable + " -m py3.pkg2.pkg3.foo"
diff --git a/Examples/python/import_packages/relativeimport2/Makefile b/Examples/python/import_packages/relativeimport2/Makefile
index 90c92ab..f08c334 100644
--- a/Examples/python/import_packages/relativeimport2/Makefile
+++ b/Examples/python/import_packages/relativeimport2/Makefile
@@ -1,7 +1,7 @@
 TOP        = ../../..
 LIBS       =
 
-ifeq (,$(PY3))
+ifneq (,$(PY2))
   PKG1DIR  = "py2"
 else
   PKG1DIR  = "py3"
diff --git a/Examples/python/import_packages/relativeimport2/runme.py b/Examples/python/import_packages/relativeimport2/runme.py
index f5b5578..35c57e1 100644
--- a/Examples/python/import_packages/relativeimport2/runme.py
+++ b/Examples/python/import_packages/relativeimport2/runme.py
@@ -4,28 +4,28 @@
 
 def run_except_on_windows(commandline, env=None):
     if os.name != "nt" and sys.platform != "cygwin":
-        # Strange failures on windows/cygin/mingw
+        # Strange failures on windows/cygwin/mingw
         subprocess.check_call(commandline, env=env, shell=True)
-        print("  Finished running: " + commandline)
+        print(("  Finished running: " + commandline))
 
 # Test import of modules content from within __init__.py
 testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
-print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
+print("Testing " + testname + " - %module(package=...) + python 'import' in __init__.py")
 
 if sys.version_info < (2, 5):
-    print "  Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
+    print("  Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'")
     sys.exit(0)
 
 if sys.version_info < (3, 0):
     import py2.pkg2.bar
-    print "  Finished importing py2.pkg2.bar"
+    print("  Finished importing py2.pkg2.bar")
     commandline = sys.executable + " -m py2.pkg2.bar"
     run_except_on_windows(commandline)
     commandline = sys.executable + " -m py2.pkg2.pkg3.pkg4.foo"
     run_except_on_windows(commandline)
 else:
     import py3.pkg2.bar
-    print "  Finished importing py3.pkg2.bar"
+    print("  Finished importing py3.pkg2.bar")
     commandline = sys.executable + " -m py3.pkg2.bar"
     run_except_on_windows(commandline)
     commandline = sys.executable + " -m py3.pkg2.pkg3.pkg4.foo"
diff --git a/Examples/python/import_packages/relativeimport3/Makefile b/Examples/python/import_packages/relativeimport3/Makefile
index 90c92ab..f08c334 100644
--- a/Examples/python/import_packages/relativeimport3/Makefile
+++ b/Examples/python/import_packages/relativeimport3/Makefile
@@ -1,7 +1,7 @@
 TOP        = ../../..
 LIBS       =
 
-ifeq (,$(PY3))
+ifneq (,$(PY2))
   PKG1DIR  = "py2"
 else
   PKG1DIR  = "py3"
diff --git a/Examples/python/import_packages/relativeimport3/runme.py b/Examples/python/import_packages/relativeimport3/runme.py
index 87101ea..ff8ca04 100644
--- a/Examples/python/import_packages/relativeimport3/runme.py
+++ b/Examples/python/import_packages/relativeimport3/runme.py
@@ -4,28 +4,28 @@
 
 def run_except_on_windows(commandline, env=None):
     if os.name != "nt" and sys.platform != "cygwin":
-        # Strange failures on windows/cygin/mingw
+        # Strange failures on windows/cygwin/mingw
         subprocess.check_call(commandline, env=env, shell=True)
-        print("  Finished running: " + commandline)
+        print(("  Finished running: " + commandline))
 
 # Test import of modules content from within __init__.py
 testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
-print "Testing " + testname + " - %module(package=...) with -relativeimport"
+print("Testing " + testname + " - %module(package=...) with -relativeimport")
 
 if sys.version_info < (2, 5):
-    print "  Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'"
+    print("  Skipping test as Python version is < 2.5 and does not support relative import syntax: 'from . import x'")
     sys.exit(0)
 
 if sys.version_info < (3, 0):
     import py2.pkg2.bar
-    print "  Finished importing py2.pkg2.bar"
+    print("  Finished importing py2.pkg2.bar")
     commandline = sys.executable + " -m py2.pkg2.bar"
     run_except_on_windows(commandline)
     commandline = sys.executable + " -m py2.pkg2.pkg3.foo"
     run_except_on_windows(commandline)
 else:
     import py3.pkg2.bar
-    print "  Finished importing py3.pkg2.bar"
+    print("  Finished importing py3.pkg2.bar")
     commandline = sys.executable + " -m py3.pkg2.bar"
     run_except_on_windows(commandline)
     commandline = sys.executable + " -m py3.pkg2.pkg3.foo"
diff --git a/Examples/python/import_packages/same_modnames1/runme.py b/Examples/python/import_packages/same_modnames1/runme.py
index a64551b..41d84aa 100644
--- a/Examples/python/import_packages/same_modnames1/runme.py
+++ b/Examples/python/import_packages/same_modnames1/runme.py
@@ -4,23 +4,23 @@
 
 def run_except_on_windows(commandline, env=None):
     if os.name != "nt" and sys.platform != "cygwin":
-        # Strange failures on windows/cygin/mingw
+        # Strange failures on windows/cygwin/mingw
         subprocess.check_call(commandline, env=env, shell=True)
-        print("  Finished running: " + commandline)
+        print(("  Finished running: " + commandline))
 
 # Test import of same modules from different packages
 testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
-print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
+print("Testing " + testname + " - %module(package=...) + python 'import' in __init__.py")
 
 import pkg2.foo
-print "  Finished importing pkg2.foo"
+print("  Finished importing pkg2.foo")
 
 var2 = pkg2.foo.Pkg2_Foo()
 
 classname = str(type(var2))
 if classname.find("pkg2.foo.Pkg2_Foo") == -1:
     raise RuntimeError("failed type checking: " + classname)
-print "  Successfully created object pkg2.foo.Pkg2_Foo"
+print("  Successfully created object pkg2.foo.Pkg2_Foo")
 
 commandline = sys.executable + " -m pkg2.foo"
 run_except_on_windows(commandline)
diff --git a/Examples/python/import_packages/same_modnames2/runme.py b/Examples/python/import_packages/same_modnames2/runme.py
index c2cf274..48c209b 100644
--- a/Examples/python/import_packages/same_modnames2/runme.py
+++ b/Examples/python/import_packages/same_modnames2/runme.py
@@ -4,22 +4,22 @@
 
 def run_except_on_windows(commandline, env=None):
     if os.name != "nt" and sys.platform != "cygwin":
-        # Strange failures on windows/cygin/mingw
+        # Strange failures on windows/cygwin/mingw
         subprocess.check_call(commandline, env=env, shell=True)
-        print("  Finished running: " + commandline)
+        print(("  Finished running: " + commandline))
 
 testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
-print "Testing " + testname + " - %module(package=...) + python 'import' in __init__.py"
+print("Testing " + testname + " - %module(package=...) + python 'import' in __init__.py")
 
 import pkg1.pkg2.foo
-print "  Finished importing pkg1.pkg2.foo"
+print("  Finished importing pkg1.pkg2.foo")
 
 var2 = pkg1.pkg2.foo.Pkg2_Foo()
 
 classname = str(type(var2))
 if classname.find("pkg1.pkg2.foo.Pkg2_Foo") == -1:
     raise RuntimeError("failed type checking: " + classname)
-print "  Successfully created object pkg1.pkg2.foo.Pkg2_Foo"
+print("  Successfully created object pkg1.pkg2.foo.Pkg2_Foo")
 
 commandline = sys.executable + " -m pkg1.pkg2.foo"
 run_except_on_windows(commandline)
diff --git a/Examples/python/import_packages/split_modules/README b/Examples/python/import_packages/split_modules/README
index d2ca15e..41de834 100644
--- a/Examples/python/import_packages/split_modules/README
+++ b/Examples/python/import_packages/split_modules/README
@@ -4,7 +4,7 @@
 supported this sort of thing.
 From SWIG 4.0.0 onwards, split modules are not supported by default.
 The %module directive needs to be customised with the moduleimport attribute
-in order to import the a global C/C++ module.
+in order to import a global C/C++ module.
 
 vanilla        # "plane Jane" module both halves in pkg1
 vanilla_split  # python 1/2 in pkg1 C 1/2 in global namespace
diff --git a/Examples/python/import_packages/split_modules/vanilla/runme.py b/Examples/python/import_packages/split_modules/vanilla/runme.py
index 79d79b4..963adca 100644
--- a/Examples/python/import_packages/split_modules/vanilla/runme.py
+++ b/Examples/python/import_packages/split_modules/vanilla/runme.py
@@ -4,18 +4,18 @@
 
 def run_except_on_windows(commandline, env=None):
     if os.name != "nt" and sys.platform != "cygwin":
-        # Strange failures on windows/cygin/mingw
+        # Strange failures on windows/cygwin/mingw
         subprocess.check_call(commandline, env=env, shell=True)
-        print("  Finished running: " + commandline)
+        print(("  Finished running: " + commandline))
 
 testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
-print "Testing " + testname + " - split modules"
+print("Testing " + testname + " - split modules")
 
 import pkg1.foo
 
-print "  Finished importing pkg1.foo"
+print("  Finished importing pkg1.foo")
 
-if not(pkg1.foo.count() == 3):
+if not pkg1.foo.count() == 3:
     raise RuntimeError("test failed")
 
 commandline = sys.executable + " -m pkg1.foo"
diff --git a/Examples/python/import_packages/split_modules/vanilla_split/runme.py b/Examples/python/import_packages/split_modules/vanilla_split/runme.py
index 79d79b4..963adca 100644
--- a/Examples/python/import_packages/split_modules/vanilla_split/runme.py
+++ b/Examples/python/import_packages/split_modules/vanilla_split/runme.py
@@ -4,18 +4,18 @@
 
 def run_except_on_windows(commandline, env=None):
     if os.name != "nt" and sys.platform != "cygwin":
-        # Strange failures on windows/cygin/mingw
+        # Strange failures on windows/cygwin/mingw
         subprocess.check_call(commandline, env=env, shell=True)
-        print("  Finished running: " + commandline)
+        print(("  Finished running: " + commandline))
 
 testname = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
-print "Testing " + testname + " - split modules"
+print("Testing " + testname + " - split modules")
 
 import pkg1.foo
 
-print "  Finished importing pkg1.foo"
+print("  Finished importing pkg1.foo")
 
-if not(pkg1.foo.count() == 3):
+if not pkg1.foo.count() == 3:
     raise RuntimeError("test failed")
 
 commandline = sys.executable + " -m pkg1.foo"
diff --git a/Examples/python/import_template/runme.py b/Examples/python/import_template/runme.py
index 35f8924..74a9184 100644
--- a/Examples/python/import_template/runme.py
+++ b/Examples/python/import_template/runme.py
@@ -1,15 +1,22 @@
 # file: runme.py
 # Test various properties of classes defined in separate modules
+import sys
 
-print "Testing the %import directive with templates"
+print("Testing the %import directive with templates")
+
 import base
 import foo
 import bar
 import spam
 
+def write_flush(s):
+    # Python 2/3 compatible write and flush
+    sys.stdout.write(s)
+    sys.stdout.flush()
+
 # Create some objects
 
-print "Creating some objects"
+print("Creating some objects")
 
 a = base.intBase()
 b = foo.intFoo()
@@ -17,91 +24,74 @@
 d = spam.intSpam()
 
 # Try calling some methods
-print "Testing some methods"
-print "",
-print "Should see 'Base::A' ---> ",
+print("Testing some methods")
+
+write_flush("  Should see 'Base::A' ---> ")
 a.A()
-print "Should see 'Base::B' ---> ",
+write_flush("  Should see 'Base::B' ---> ")
 a.B()
 
-print "Should see 'Foo::A' ---> ",
+write_flush("  Should see 'Foo::A' ---> ")
 b.A()
-print "Should see 'Foo::B' ---> ",
+write_flush("  Should see 'Foo::B' ---> ")
 b.B()
 
-print "Should see 'Bar::A' ---> ",
+write_flush("  Should see 'Bar::A' ---> ")
 c.A()
-print "Should see 'Bar::B' ---> ",
+write_flush("  Should see 'Bar::B' ---> ")
 c.B()
 
-print "Should see 'Spam::A' ---> ",
+write_flush("  Should see 'Spam::A' ---> ")
 d.A()
-print "Should see 'Spam::B' ---> ",
+write_flush("  Should see 'Spam::B' ---> ")
 d.B()
 
 # Try some casts
 
-print "\nTesting some casts\n"
-print "",
+print("\nTesting some casts\n")
 
 x = a.toBase()
-print "Should see 'Base::A' ---> ",
+write_flush("  Should see 'Base::A' ---> ")
 x.A()
-print "Should see 'Base::B' ---> ",
+write_flush("  Should see 'Base::B' ---> ")
 x.B()
 
 x = b.toBase()
-print "Should see 'Foo::A' ---> ",
+write_flush("  Should see 'Foo::A' ---> ")
 x.A()
 
-print "Should see 'Base::B' ---> ",
+write_flush("  Should see 'Base::B' ---> ")
 x.B()
 
 x = c.toBase()
-print "Should see 'Bar::A' ---> ",
+write_flush("  Should see 'Bar::A' ---> ")
 x.A()
 
-print "Should see 'Base::B' ---> ",
+write_flush("  Should see 'Base::B' ---> ")
 x.B()
 
 x = d.toBase()
-print "Should see 'Spam::A' ---> ",
+write_flush("  Should see 'Spam::A' ---> ")
 x.A()
 
-print "Should see 'Base::B' ---> ",
+write_flush("  Should see 'Base::B' ---> ")
 x.B()
 
 x = d.toBar()
-print "Should see 'Bar::B' ---> ",
+write_flush("  Should see 'Bar::B' ---> ")
 x.B()
 
-print "\nTesting some dynamic casts\n"
+print("\nTesting some dynamic casts\n")
 x = d.toBase()
 
-print " Spam -> Base -> Foo : ",
-y = foo.intFoo_fromBase(x)
-if y:
-    print "bad swig"
-else:
-    print "good swig"
+y = foo.intFoo.fromBase(x)
+print("  Spam -> Base -> Foo : {} swig".format("bad" if y else "good"))
 
-print " Spam -> Base -> Bar : ",
-y = bar.intBar_fromBase(x)
-if y:
-    print "good swig"
-else:
-    print "bad swig"
+y = bar.intBar.fromBase(x)
+print("  Spam -> Base -> Bar : {} swig".format("good" if y else "bad"))
 
-print " Spam -> Base -> Spam : ",
-y = spam.intSpam_fromBase(x)
-if y:
-    print "good swig"
-else:
-    print "bad swig"
+y = spam.intSpam.fromBase(x)
+print("  Spam -> Base -> Spam : {} swig".format("good" if y else "bad"))
 
-print " Foo -> Spam : ",
-y = spam.intSpam_fromBase(b)
-if y:
-    print "bad swig"
-else:
-    print "good swig"
+y = spam.intSpam.fromBase(b)
+print("  Foo -> Spam : {} swig".format("bad" if y else "good"))
diff --git a/Examples/python/index.html b/Examples/python/index.html
index 3bbdd66..fcb7eac 100644
--- a/Examples/python/index.html
+++ b/Examples/python/index.html
@@ -88,12 +88,11 @@
 
 <h2>Compatibility</h2>
 
-For Python 3, set the environment variable <tt>PY3=1</tt>.
-This will ensure the 2to3 program is run prior to running any example.
+For Python 2, set the environment variable <tt>PY2=1</tt>.
 
 <p>
 Your mileage may vary.  If you experience a problem, please let us know by 
-contacting us on the <a href="http://www.swig.org/mail.html">mailing lists</a>.
+contacting us on the <a href="https://www.swig.org/mail.html">mailing lists</a>.
 </body>
 </html>
 
diff --git a/Examples/python/libffi/Makefile b/Examples/python/libffi/Makefile
deleted file mode 100644
index 0875fdd..0000000
--- a/Examples/python/libffi/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-TOP        = ../..
-SWIGEXE    = $(TOP)/../swig
-SWIG_LIB_DIR = $(TOP)/../$(TOP_BUILDDIR_TO_TOP_SRCDIR)Lib
-SRCS       =
-TARGET     = example
-INTERFACE  = example.i
-
-check: build
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' python_run
-
-build:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' LIBS='-L/usr/local/lib -lffi' python
-
-static:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' SRCS='$(SRCS)' \
-	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	TARGET='mypython' INTERFACE='$(INTERFACE)' python_static
-
-clean:
-	$(MAKE) -f $(TOP)/Makefile SRCDIR='$(SRCDIR)' TARGET='$(TARGET)' python_clean
diff --git a/Examples/python/libffi/example.i b/Examples/python/libffi/example.i
deleted file mode 100644
index 3f5d766..0000000
--- a/Examples/python/libffi/example.i
+++ /dev/null
@@ -1,176 +0,0 @@
-/* File : example.i */
-%module example
-
-%{
-#include <unistd.h>
-#include <ffi.h>
-%}
-
-/* A wrapper for execlp() using libffi to handle an arbitrary
-   number of arguments */
-
-%typemap(in) (...) {
-   char **argv;
-   int    argc;
-   int    i;
-
-   argc = PyTuple_Size(varargs);
-   argv = (char **) malloc(sizeof(char *)*(argc+1));
-   for (i = 0; i < argc; i++) {
-      PyObject *o = PyTuple_GetItem(varargs,i);
-      if (!PyString_Check(o)) {
-          PyErr_SetString(PyExc_ValueError,"Expected a string");
-          SWIG_fail;
-      }
-      argv[i] = PyString_AsString(o);
-   }
-   argv[i] = NULL;
-   $1 = (void *) argv;
-}
-
-/* Rewrite the function call, using libffi */    
-%feature("action") execlp {
-  int       i, vc;
-  ffi_cif   cif;
-  ffi_type  **types;
-  void      **values;
-  char      **args;
-
-  vc = PyTuple_Size(varargs);
-  types  = (ffi_type **) malloc((vc+3)*sizeof(ffi_type *));
-  values = (void **) malloc((vc+3)*sizeof(void *));
-  args   = (char **) arg3;
-
-  /* Set up path parameter */
-  types[0] = &ffi_type_pointer;
-  values[0] = &arg1;
-  
-  /* Set up first argument */
-  types[1] = &ffi_type_pointer;
-  values[1] = &arg2;
-
-  /* Set up rest of parameters */
-  for (i = 0; i <= vc; i++) {
-    types[2+i] = &ffi_type_pointer;
-    values[2+i] = &args[i];
-  }
-  if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+3,
-                   &ffi_type_uint, types) == FFI_OK) {
-    ffi_call(&cif, (void (*)()) execlp, &result, values);
-  } else {
-    free(types);
-    free(values);
-    free(arg3);
-    PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
-    SWIG_fail;
-  }
-  free(types);
-  free(values);
-  free(arg3);
-}
-
-int execlp(const char *path, const char *arg1, ...);
-
-
-/* A wrapper for printf() using libffi */
-
-%{
-  typedef struct {
-    int type;
-    union {
-      int    ivalue;
-      double dvalue;
-      void   *pvalue;
-    } val;
-  } vtype;
-  enum { VT_INT, VT_DOUBLE, VT_POINTER };
-  %}
-
-%typemap(in) (const char *fmt, ...) {
-  vtype *argv;
-  int    argc;
-  int    i;
-
-  $1 = PyString_AsString($input);
-
-  argc = PyTuple_Size(varargs);
-  argv = (vtype *) malloc(argc*sizeof(vtype));
-  for (i = 0; i < argc; i++) {
-    PyObject *o = PyTuple_GetItem(varargs,i);
-    if (PyInt_Check(o)) {
-      argv[i].type = VT_INT;
-      argv[i].val.ivalue = PyInt_AsLong(o);
-    } else if (PyFloat_Check(o)) {
-      argv[i].type = VT_DOUBLE;
-      argv[i].val.dvalue = PyFloat_AsDouble(o);
-    } else if (PyString_Check(o)) {
-      argv[i].type = VT_POINTER;
-      argv[i].val.pvalue = (void *) PyString_AsString(o);
-    } else {
-      free(argv);
-      PyErr_SetString(PyExc_ValueError,"Unsupported argument type");
-      SWIG_fail;
-    }
-  }
-
-  $2 = (void *) argv;
-}
-
-/* Rewrite the function call, using libffi */    
-%feature("action") printf {
-  int       i, vc;
-  ffi_cif   cif;
-  ffi_type  **types;
-  void      **values;
-  vtype     *args;
-
-  vc = PyTuple_Size(varargs);
-  types  = (ffi_type **) malloc((vc+1)*sizeof(ffi_type *));
-  values = (void **) malloc((vc+1)*sizeof(void *));
-  args   = (vtype *) arg2;
-
-  /* Set up fmt parameter */
-  types[0] = &ffi_type_pointer;
-  values[0] = &arg1;
-
-  /* Set up rest of parameters */
-  for (i = 0; i < vc; i++) {
-    switch(args[i].type) {
-    case VT_INT:
-      types[1+i] = &ffi_type_uint;
-      values[1+i] = &args[i].val.ivalue;
-      break;
-    case VT_DOUBLE:
-      types[1+i] = &ffi_type_double;
-      values[1+i] = &args[i].val.dvalue;
-      break;
-    case VT_POINTER:
-      types[1+i] = &ffi_type_pointer;
-      values[1+i] = &args[i].val.pvalue;
-      break;
-    default:
-      abort();    /* Whoa! We're seriously hosed */
-      break;   
-    }
-  }
-  if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, vc+1,
-                   &ffi_type_uint, types) == FFI_OK) {
-    ffi_call(&cif, (void (*)()) printf, &result, values);
-  } else {
-    free(types);
-    free(values);
-    free(args);
-    PyErr_SetString(PyExc_RuntimeError, "Whoa!!!!!");
-    SWIG_fail;
-  }
-  free(types);
-  free(values);
-  free(args);
-}
-
-int printf(const char *fmt, ...);
-
-
-  
-
-
diff --git a/Examples/python/multimap/example.i b/Examples/python/multimap/example.i
index 3ff5d52..7087d42 100644
--- a/Examples/python/multimap/example.i
+++ b/Examples/python/multimap/example.i
@@ -39,12 +39,14 @@
 %#if PY_VERSION_HEX >= 0x03000000
     {
       PyObject *utf8str = PyUnicode_AsUTF8String(s);
-      const char *cstr;
+      const char *strtmp = 0;
       if (!utf8str) {
         SWIG_fail;
       }
-      cstr = PyBytes_AsString(utf8str);
-      $2[i] = strdup(cstr);
+      strtmp = PyBytes_AsString(utf8str);
+      $2[i] = (char *)malloc(strlen(strtmp) + 1);
+      if ($2[i])
+        strcpy($2[i], strtmp);
       Py_DECREF(utf8str);
     }
 %#else
diff --git a/Examples/python/multimap/runme.py b/Examples/python/multimap/runme.py
index ad693b7..e24f54e 100644
--- a/Examples/python/multimap/runme.py
+++ b/Examples/python/multimap/runme.py
@@ -7,14 +7,14 @@
 x = 42
 y = 105
 g = example.gcd(x, y)
-print "The gcd of %d and %d is %d" % (x, y, g)
+print("The gcd of %d and %d is %d" % (x, y, g))
 
 # Call the gcdmain() function
 example.gcdmain(["gcdmain", "42", "105"])
 
 # Call the count function
-print example.count("Hello World", "l")
+print(example.count("Hello World", "l"))
 
 # Call the capitalize function
 
-print example.capitalize("hello world")
+print(example.capitalize("hello world"))
diff --git a/Examples/python/operator/runme.py b/Examples/python/operator/runme.py
index ac48f26..ee479f0 100644
--- a/Examples/python/operator/runme.py
+++ b/Examples/python/operator/runme.py
@@ -4,17 +4,17 @@
 a = example.Complex(2, 3)
 b = example.Complex(-5, 10)
 
-print "a   =", a
-print "b   =", b
+print("a   = %s" % a)
+print("b   = %s" % b)
 
 c = a + b
-print "c   =", c
-print "a*b =", a * b
-print "a-c =", a - c
+print("c   = %s" % c)
+print("a*b = %s" % (a * b))
+print("a-c = %s" % (a - c))
 
 e = example.ComplexCopy(a - c)
-print "e   =", e
+print("e   = %s" % e)
 
 # Big expression
 f = ((a + b) * (c + b * e)) + (-a)
-print "f   =", f
+print("f   = %s" % f)
diff --git a/Examples/python/pointer/index.html b/Examples/python/pointer/index.html
index ae52edd..a49c6b1 100644
--- a/Examples/python/pointer/index.html
+++ b/Examples/python/pointer/index.html
@@ -72,23 +72,25 @@
 
 <blockquote>
 <pre>
-%include "pointer.i"
+%include "cpointer.i"
 </pre>
-</blockquote?
+</blockquote>
 
 and in a script you would do this:
 
 <blockquote>
 <pre>
-a = ptrcreate("int",37)
-b = ptrcreate("int",42)
-c = ptrcreate("int")
-add(a,b,c)
-r = ptrvalue(c)
-print "Result =",r
-ptrfree(a)
-ptrfree(b)
-ptrfree(c)
+a = example.new_intp()
+b = example.new_intp()
+c = example.new_intp()
+example.intp_assign(a, 37)
+example.intp_assign(b, 42)
+example.add(a, b, c)
+r = example.intp_value(c)
+print("Result = %s" % r)
+example.delete_intp(a)
+example.delete_intp(b)
+example.delete_intp(c)
 </pre>
 </blockquote>
 
@@ -156,14 +158,9 @@
 make it.
 
 <p>
-<li>More documentation on the typemaps.i and pointer.i library files can be
+<li>More documentation on the typemaps.i and cpointer.i library files can be
 found in the SWIG user manual.  The files also contain documentation.
 
-<p>
-<li>The pointer.i library is designed primarily for convenience.  If you
-are concerned about performance, you probably want to use a different
-approach.
-
 </ul>
 
 <hr>
diff --git a/Examples/python/pointer/runme.py b/Examples/python/pointer/runme.py
index 5b5f16b..46371b8 100644
--- a/Examples/python/pointer/runme.py
+++ b/Examples/python/pointer/runme.py
@@ -3,23 +3,23 @@
 import example
 
 # First create some objects using the pointer library.
-print "Testing the pointer library"
+print("Testing the pointer library")
 a = example.new_intp()
 b = example.new_intp()
 c = example.new_intp()
 example.intp_assign(a, 37)
 example.intp_assign(b, 42)
 
-print "     a =", a
-print "     b =", b
-print "     c =", c
+print("     a = %s" % a)
+print("     b = %s" % b)
+print("     c = %s" % c)
 
 # Call the add() function with some pointers
 example.add(a, b, c)
 
 # Now get the result
 r = example.intp_value(c)
-print "     37 + 42 =", r
+print("     37 + 42 = %s" % r)
 
 # Clean up the pointers
 example.delete_intp(a)
@@ -30,12 +30,12 @@
 # This should be much easier. Now how it is no longer
 # necessary to manufacture pointers.
 
-print "Trying the typemap library"
+print("Trying the typemap library")
 r = example.sub(37, 42)
-print "     37 - 42 =", r
+print("     37 - 42 = %s" % r)
 
 # Now try the version with multiple return values
 
-print "Testing multiple return values"
+print("Testing multiple return values")
 q, r = example.divide(42, 37)
-print "     42/37 = %d remainder %d" % (q, r)
+print("     42/37 = %d remainder %d" % (q, r))
diff --git a/Examples/python/reference/index.html b/Examples/python/reference/index.html
index 7ad3979..49bd3fa 100644
--- a/Examples/python/reference/index.html
+++ b/Examples/python/reference/index.html
@@ -104,7 +104,7 @@
 class VectorArray {
 public:
  ...
-   %addmethods {
+   %extend {
     Vector &amp;get(int index) {
       return (*self)[index];
     }
diff --git a/Examples/python/reference/runme.py b/Examples/python/reference/runme.py
index 0ff217b..8a96e03 100644
--- a/Examples/python/reference/runme.py
+++ b/Examples/python/reference/runme.py
@@ -6,12 +6,12 @@
 
 # ----- Object creation -----
 
-print "Creating some objects:"
+print("Creating some objects:")
 a = example.Vector(3, 4, 5)
 b = example.Vector(10, 11, 12)
 
-print "    Created", a.cprint()
-print "    Created", b.cprint()
+print("    Created %s" % a.cprint())
+print("    Created %s" % b.cprint())
 
 # ----- Call an overloaded operator -----
 
@@ -21,9 +21,9 @@
 #
 # It returns a new allocated object.
 
-print "Adding a+b"
+print("Adding a+b")
 c = example.addv(a, b)
-print "    a+b =", c.cprint()
+print("    a+b = %s" % c.cprint())
 
 # Note: Unless we free the result, a memory leak will occur
 del c
@@ -31,9 +31,9 @@
 # ----- Create a vector array -----
 
 # Note: Using the high-level interface here
-print "Creating an array of vectors"
+print("Creating an array of vectors")
 va = example.VectorArray(10)
-print "    va = ", va
+print("    va = %s" % va)
 
 # ----- Set some values in the array -----
 
@@ -45,17 +45,17 @@
 
 # Get some values from the array
 
-print "Getting some array values"
+print("Getting some array values")
 for i in range(0, 5):
-    print "    va(%d) = %s" % (i, va.get(i).cprint())
+    print("    va(%d) = %s" % (i, va.get(i).cprint()))
 
 # Watch under resource meter to check on this
-print "Making sure we don't leak memory."
-for i in xrange(0, 1000000):
+print("Making sure we don't leak memory.")
+for i in range(0, 1000000):
     c = va.get(i % 10)
 
 # ----- Clean up -----
-print "Cleaning up"
+print("Cleaning up")
 
 del va
 del a
diff --git a/Examples/python/simple/runme.py b/Examples/python/simple/runme.py
index ce01e5a..ec0aceb 100644
--- a/Examples/python/simple/runme.py
+++ b/Examples/python/simple/runme.py
@@ -7,15 +7,15 @@
 x = 42
 y = 105
 g = example.gcd(x, y)
-print "The gcd of %d and %d is %d" % (x, y, g)
+print("The gcd of %d and %d is %d" % (x, y, g))
 
 # Manipulate the Foo global variable
 
 # Output its current value
-print "Foo = ", example.cvar.Foo
+print("Foo = %s" % example.cvar.Foo)
 
 # Change its value
 example.cvar.Foo = 3.1415926
 
 # See if the change took effect
-print "Foo = ", example.cvar.Foo
+print("Foo = %s" % example.cvar.Foo)
diff --git a/Examples/python/smartptr/runme.py b/Examples/python/smartptr/runme.py
index 5f8b734..f01636a 100644
--- a/Examples/python/smartptr/runme.py
+++ b/Examples/python/smartptr/runme.py
@@ -7,17 +7,17 @@
 
 # ----- Object creation -----
 
-print "Creating some objects:"
+print("Creating some objects:")
 cc = example.Circle(10)
 c = example.ShapePtr(cc)
-print "    Created circle", c
+print("    Created circle %s" % c)
 ss = example.Square(10)
 s = example.ShapePtr(ss)
-print "    Created square", s
+print("    Created square %s" % s)
 
 # ----- Access a static member -----
 
-print "\nA total of", example.cvar.Shape_nshapes, "shapes were created"
+print("\nA total of %s shapes were created" % example.cvar.Shape_nshapes)
 
 # ----- Member data access -----
 
@@ -29,19 +29,19 @@
 s.x = -10
 s.y = 5
 
-print "\nHere is their current position:"
-print "    Circle = (%f, %f)" % (c.x, c.y)
-print "    Square = (%f, %f)" % (s.x, s.y)
+print("\nHere is their current position:")
+print("    Circle = (%f, %f)" % (c.x, c.y))
+print("    Square = (%f, %f)" % (s.x, s.y))
 
 # ----- Call some methods -----
 
-print "\nHere are some properties of the shapes:"
+print("\nHere are some properties of the shapes:")
 for o in [c, s]:
-    print "   ", o
-    print "        area      = ", o.area()
-    print "        perimeter = ", o.perimeter()
+    print("    %s" % o)
+    print("        area      = %s" % o.area())
+    print("        perimeter = %s" % o.perimeter())
 
-print "\nGuess I'll clean up now"
+print("\nGuess I'll clean up now")
 
 # Note: this invokes the virtual destructor
 del c
@@ -50,5 +50,5 @@
 del ss
 
 s = 3
-print example.cvar.Shape_nshapes, "shapes remain"
-print "Goodbye"
+print("%d shapes remain" % example.cvar.Shape_nshapes)
+print("Goodbye")
diff --git a/Examples/python/std_map/runme.py b/Examples/python/std_map/runme.py
index 26031f3..e86f613 100644
--- a/Examples/python/std_map/runme.py
+++ b/Examples/python/std_map/runme.py
@@ -11,45 +11,45 @@
 dmap["hello"] = 1.0
 dmap["hi"] = 2.0
 
-print dmap.items()
-print dmap.keys()
-print dmap.values()
+print(list(dmap.items()))
+print(list(dmap.keys()))
+print(list(dmap.values()))
 
-print dmap
+print(dmap)
 hmap = example.halfd(dmap)
 dmap = hmap
 
-print dmap
-for i in dmap.iterkeys():
-    print "key", i
+print(dmap)
+for i in dmap.keys():
+    print("key %s" % i)
 
-for i in dmap.itervalues():
-    print "val", i
+for i in dmap.values():
+    print("val %s" % i)
 
-for k, v in dmap.iteritems():
-    print "item", k, v
+for k, v in dmap.items():
+    print("item %s %s" % (k, v))
 
 dmap = example.DoubleMap()
 dmap["hello"] = 1.0
 dmap["hi"] = 2.0
 
-for i in dmap.iterkeys():
-    print "key", i
+for i in dmap.keys():
+    print("key %s" % i)
 
-for i in dmap.itervalues():
-    print "val", i
+for i in dmap.values():
+    print("val %s" % i)
 
-for k, v in dmap.iteritems():
-    print "item", k, v
+for k, v in dmap.items():
+    print("item %s %s" % (k, v))
 
 
-print dmap.items()
-print dmap.keys()
-print dmap.values()
+print(list(dmap.items()))
+print(list(dmap.keys()))
+print(list(dmap.values()))
 
 hmap = example.halfd(dmap)
-print hmap.keys()
-print hmap.values()
+print(list(hmap.keys()))
+print(list(hmap.values()))
 
 
 dmap = {}
@@ -57,23 +57,23 @@
 dmap["hi"] = 4
 
 hmap = example.halfi(dmap)
-print hmap
-print hmap.keys()
-print hmap.values()
+print(hmap)
+print(list(hmap.keys()))
+print(list(hmap.values()))
 
 
 dmap = hmap
 
-for i in dmap.iterkeys():
-    print "key", i
+for i in dmap.keys():
+    print("key %s" % i)
 
-for i in dmap.itervalues():
-    print "val", i
+for i in dmap.values():
+    print("val %s" % i)
 
-for i in dmap.iteritems():
-    print "item", i
+for i in dmap.items():
+    print("item %s" % str(i))
 
-for k, v in dmap.iteritems():
-    print "item", k, v
+for k, v in dmap.items():
+    print("item %s %s" % (k, v))
 
-print dmap
+print(dmap)
diff --git a/Examples/python/std_vector/runme.py b/Examples/python/std_vector/runme.py
index d7d3c2e..3f1106d 100644
--- a/Examples/python/std_vector/runme.py
+++ b/Examples/python/std_vector/runme.py
@@ -4,32 +4,30 @@
 
 # Call average with a Python list...
 
-print example.average([1, 2, 3, 4])
+print(example.average([1, 2, 3, 4]))
 
 # ... or a wrapped std::vector<int>
 
 v = example.IntVector(4)
 for i in range(len(v)):
     v[i] = i + 1
-print example.average(v)
+print(example.average(v))
 
 
 # half will return a Python list.
 # Call it with a Python tuple...
 
-print example.half((1.0, 1.5, 2.0, 2.5, 3.0))
+print(example.half((1.0, 1.5, 2.0, 2.5, 3.0)))
 
 # ... or a wrapped std::vector<double>
 
 v = example.DoubleVector()
 for i in [1, 2, 3, 4]:
     v.append(i)
-print example.half(v)
+print(example.half(v))
 
 
 # now halve a wrapped std::vector<double> in place
 
 example.halve_in_place(v)
-for i in range(len(v)):
-    print v[i], "; ",
-print
+print([i for i in v])
diff --git a/Examples/python/template/runme.py b/Examples/python/template/runme.py
index e408e15..85b1ba9 100644
--- a/Examples/python/template/runme.py
+++ b/Examples/python/template/runme.py
@@ -3,8 +3,8 @@
 import example
 
 # Call some templated functions
-print example.maxint(3, 7)
-print example.maxdouble(3.14, 2.18)
+print(example.maxint(3, 7))
+print(example.maxdouble(3.14, 2.18))
 
 # Create some class
 
@@ -21,12 +21,12 @@
 for i in range(0, 100):
     sum = sum + iv.getitem(i)
 
-print sum
+print(sum)
 
 sum = 0.0
 for i in range(0, 1000):
     sum = sum + dv.getitem(i)
-print sum
+print(sum)
 
 del iv
 del dv
diff --git a/Examples/python/variables/runme.py b/Examples/python/variables/runme.py
index 4d34e92..f305fbe 100644
--- a/Examples/python/variables/runme.py
+++ b/Examples/python/variables/runme.py
@@ -2,6 +2,8 @@
 
 import example
 
+print("Variables = " + str(example.cvar))
+
 # Try to set the values of some global variables
 
 example.cvar.ivar = 42
@@ -22,51 +24,51 @@
 
 # Now print out the values of the variables
 
-print "Variables (values printed from Python)"
+print("\nVariables (values printed from Python)")
 
-print "ivar      =", example.cvar.ivar
-print "svar      =", example.cvar.svar
-print "lvar      =", example.cvar.lvar
-print "uivar     =", example.cvar.uivar
-print "usvar     =", example.cvar.usvar
-print "ulvar     =", example.cvar.ulvar
-print "scvar     =", example.cvar.scvar
-print "ucvar     =", example.cvar.ucvar
-print "fvar      =", example.cvar.fvar
-print "dvar      =", example.cvar.dvar
-print "cvar      =", example.cvar.cvar
-print "strvar    =", example.cvar.strvar
-print "cstrvar   =", example.cvar.cstrvar
-print "iptrvar   =", example.cvar.iptrvar
-print "name      =", example.cvar.name
-print "ptptr     =", example.cvar.ptptr, example.Point_print(example.cvar.ptptr)
-print "pt        =", example.cvar.pt, example.Point_print(example.cvar.pt)
+print("ivar      = %s" % example.cvar.ivar)
+print("svar      = %s" % example.cvar.svar)
+print("lvar      = %s" % example.cvar.lvar)
+print("uivar     = %s" % example.cvar.uivar)
+print("usvar     = %s" % example.cvar.usvar)
+print("ulvar     = %s" % example.cvar.ulvar)
+print("scvar     = %s" % example.cvar.scvar)
+print("ucvar     = %s" % example.cvar.ucvar)
+print("fvar      = %s" % example.cvar.fvar)
+print("dvar      = %s" % example.cvar.dvar)
+print("cvar      = %s" % example.cvar.cvar)
+print("strvar    = %s" % example.cvar.strvar)
+print("cstrvar   = %s" % example.cvar.cstrvar)
+print("iptrvar   = %s" % example.cvar.iptrvar)
+print("name      = %s" % example.cvar.name)
+print("ptptr     = %s %s" % (example.cvar.ptptr, example.Point_print(example.cvar.ptptr)))
+print("pt        = %s %s" % (example.cvar.pt, example.Point_print(example.cvar.pt)))
 
-print "\nVariables (values printed from C)"
+print("\nVariables (values printed from C)")
 
 example.print_vars()
 
-print "\nNow I'm going to try and modify some read only variables"
+print("\nNow I'm going to try and modify some read only variables")
 
-print "     Trying to set 'path'"
+print("     Trying to set 'path'")
 try:
     example.cvar.path = "Whoa!"
-    print "Hey, what's going on?!?! This shouldn't work"
+    print("Hey, what's going on?!?! This shouldn't work")
 except Exception:
-    print "Good."
+    print("Good.")
 
-print "     Trying to set 'status'"
+print("     Trying to set 'status'")
 try:
     example.cvar.status = 0
-    print "Hey, what's going on?!?! This shouldn't work"
+    print("Hey, what's going on?!?! This shouldn't work")
 except Exception:
-    print "Good."
+    print("Good.")
 
 
-print "\nI'm going to try and update a structure variable.\n"
+print("\nI'm going to try and update a structure variable.\n")
 
 example.cvar.pt = example.cvar.ptptr
 
-print "The new value is"
+print("The new value is")
 example.pt_print()
-print "You should see the value", example.Point_print(example.cvar.ptptr)
+print("You should see the value %s" % example.Point_print(example.cvar.ptptr))
diff --git a/Examples/ruby/exceptproxy/example.h b/Examples/ruby/exceptproxy/example.h
index 3ee6d76..7148d4d 100644
--- a/Examples/ruby/exceptproxy/example.h
+++ b/Examples/ruby/exceptproxy/example.h
@@ -31,7 +31,7 @@
     last = (last + 1) % maxsize;
     nitems++;
   }
-  T dequeue()  {
+  T dequeue() {
     T x;
     if (nitems == 0) throw EmptyError();
     x = items[(last + maxsize - nitems) % maxsize];
diff --git a/Examples/ruby/exceptproxy/example.i b/Examples/ruby/exceptproxy/example.i
index ad0c23a..3a3077f 100644
--- a/Examples/ruby/exceptproxy/example.i
+++ b/Examples/ruby/exceptproxy/example.i
@@ -16,7 +16,7 @@
 
 /* The EmptyError doesn't appear in a throw declaration, and hence
   we need to tell SWIG that the dequeue method throws it.  This can
-  now be done via the %catchs feature. */
+  now be done via the %catches feature. */
 %catches(FullError) *::enqueue;
 %catches(EmptyError) *::dequeue();
 
diff --git a/Examples/ruby/free_function/example.h b/Examples/ruby/free_function/example.h
index 933bb36..c709cde 100644
--- a/Examples/ruby/free_function/example.h
+++ b/Examples/ruby/free_function/example.h
@@ -1,5 +1,5 @@
-#ifndef _EXAMPLE_H_
-#define _EXAMPLE_H_
+#ifndef EXAMPLE_H
+#define EXAMPLE_H
 
 #include <vector>
 #include <string>
@@ -46,4 +46,4 @@
 	Animal* get_animal(size_t i) const;
 };
 
-#endif /*_EXAMPLE_H_*/
+#endif /* EXAMPLE_H */
diff --git a/Examples/ruby/index.html b/Examples/ruby/index.html
index 4f4aa0a..ceb6c92 100644
--- a/Examples/ruby/index.html
+++ b/Examples/ruby/index.html
@@ -87,7 +87,7 @@
 </ul>
 
 Your mileage may vary.  If you experience a problem, please let us know by 
-contacting us on the <a href="http://www.swig.org/mail.html">mailing lists</a>.
+contacting us on the <a href="https://www.swig.org/mail.html">mailing lists</a>.
 </body>
 </html>
 
diff --git a/Examples/ruby/mark_function/example.h b/Examples/ruby/mark_function/example.h
index 933bb36..c709cde 100644
--- a/Examples/ruby/mark_function/example.h
+++ b/Examples/ruby/mark_function/example.h
@@ -1,5 +1,5 @@
-#ifndef _EXAMPLE_H_
-#define _EXAMPLE_H_
+#ifndef EXAMPLE_H
+#define EXAMPLE_H
 
 #include <vector>
 #include <string>
@@ -46,4 +46,4 @@
 	Animal* get_animal(size_t i) const;
 };
 
-#endif /*_EXAMPLE_H_*/
+#endif /* EXAMPLE_H */
diff --git a/Examples/ruby/pointer/index.html b/Examples/ruby/pointer/index.html
index c9d5b9c..aff6bcd 100644
--- a/Examples/ruby/pointer/index.html
+++ b/Examples/ruby/pointer/index.html
@@ -54,15 +54,17 @@
 
 <blockquote>
 <pre>
-a = new_int(37)
-b = new_int(42)
-c = new_int(0)
-add(a,b,c)
-r = get_int(c)
+a = Example::new_intp()
+b = Example::new_intp()
+c = Example::new_intp()
+Example::intp_assign(a,37)
+Example::intp_assign(b,42)
+Example::add(a, b, c)
+r = Example::intp_value(c)
 print "Result = #{r}\n"
-delete_int(a)
-delete_int(b)
-delete_int(c)
+Example::delete_intp(a)
+Example::delete_intp(b)
+Example::delete_intp(c)
 </pre>
 </blockquote>
 
@@ -72,7 +74,7 @@
 
 <blockquote>
 <pre>
-%include "pointer.i"
+%include "cpointer.i"
 </pre>
 </blockquote>
 
@@ -156,14 +158,8 @@
 make it.
 
 <p>
-<li>More documentation on the typemaps.i and pointer.i library files can be
+<li>More documentation on the typemaps.i and cpointer.i library files can be
 found in the SWIG user manual.  The files also contain documentation.
-
-<p>
-<li>The pointer.i library is designed primarily for convenience.  If you
-are concerned about performance, you probably want to use a different
-approach.
-
 </ul>
 
 <hr>
diff --git a/Examples/ruby/reference/index.html b/Examples/ruby/reference/index.html
index d45dbe3..f5d134f 100644
--- a/Examples/ruby/reference/index.html
+++ b/Examples/ruby/reference/index.html
@@ -104,7 +104,7 @@
 class VectorArray {
 public:
  ...
-   %addmethods {
+   %extend {
     Vector &amp;get(int index) {
       return (*self)[index];
     }
diff --git a/Examples/s-exp/uffi.lisp b/Examples/s-exp/uffi.lisp
deleted file mode 100644
index aea9a14..0000000
--- a/Examples/s-exp/uffi.lisp
+++ /dev/null
@@ -1,389 +0,0 @@
-;;; This is experimental code that uses the s-expression
-;;; representation of a C/C++ library interface to generate Foreign
-;;; Function Interface definitions for use with Kevin Rosenberg's
-;;; UFFI.
-;;;
-;;; Written by Matthias Koeppe <mkoeppe@mail.math.uni-magdeburg.de>
-
-(eval-when (:compile-toplevel :load-toplevel :execute)
-  (require 'port)				; from CLOCC
-  (require 'uffi))
-
-(in-package :cl-user)
-
-;; Interaction with the SWIG binary
-
-(defvar *swig-source-directory* #p"/home/mkoeppe/s/swig1.3/")
-
-(defvar *swig-program* (merge-pathnames "swig" *swig-source-directory*))
-
-(defun run-swig (swig-interface-file-name &key directory-search-list module
-		 ignore-errors c++)
-  (let ((temp-file-name "/tmp/swig.lsp"))
-    (let ((process
-	   (port:run-prog (namestring *swig-program*)
-			  :output t
-			  :args `(,@(and c++ '("-c++"))
-				  "-sexp"
-				  ,@(mapcar (lambda (dir)
-				       (concatenate 'string
-						    "-I" (namestring dir)))
-					    directory-search-list)
-				  ,@(and module
-					 `("-module" ,module))
-				  "-o" ,temp-file-name
-				  ,(namestring swig-interface-file-name)))))
-      #+cmu (unless (or (zerop (ext:process-exit-code process))
-			ignore-errors)
-	      (error "Process swig exited abnormally"))
-      (with-open-file (s temp-file-name)
-	(read s)))))
-
-;; Type system
-
-(defun parse-swigtype (type-string &key start end junk-ok)
-  "Parse TYPE-STRING as SWIG's internal representation of C/C++
-types. Return two values: The type description (an improper list) and
-the terminating index into TYPE-STRING."
-  ;; SWIG's internal representation is described in Source/Swig/stype.c
-  (unless start
-    (setq start 0))
-  (unless end
-    (setq end (length type-string)))
-  (flet ((prefix-match (prefix)
-	   (let ((position (mismatch prefix type-string :start2 start :end2 end)))
-	     (or (not position)
-		 (= position (length prefix)))))
-	 (bad-type-error (reason)
-	   (error "Bad SWIG type (~A): ~A" reason
-		  (subseq type-string start end)))
-	 (type-char (index)
-	   (and (< index (length type-string))
-		(char type-string index)))	       
-	 (cons-and-recurse (prefix start end)
-	   (multiple-value-bind (type-description index)
-	       (parse-swigtype type-string :start start :end end
-				:junk-ok junk-ok)
-	     (values (cons prefix type-description)
-		     index))))
-    (cond
-      ((prefix-match "p.")		; pointer
-       (cons-and-recurse '* (+ start 2) end))
-      ((prefix-match "r.")		; C++ reference
-       (cons-and-recurse '& (+ start 2) end))
-      ((prefix-match "a(")		; array
-       (let ((closing-paren (position #\) type-string
-				  :start (+ start 2)
-				  :end end)))
-	 (unless closing-paren
-	   (bad-type-error "missing right paren"))
-	 (unless (eql (type-char (+ closing-paren 1)) #\.)
-	   (bad-type-error "missing dot"))
-	 (cons-and-recurse (list 'ARRAY (subseq type-string (+ start 2) closing-paren))
-			   (+ closing-paren 2) end)))
-      ((prefix-match "q(")		; qualifier (const, volatile)
-       (let ((closing-paren (position #\) type-string
-				  :start (+ start 2)
-				  :end end)))
-	 (unless closing-paren
-	   (bad-type-error "missing right paren"))
-	 (unless (eql (type-char (+ closing-paren 1)) #\.)
-	   (bad-type-error "missing dot"))
-	 (cons-and-recurse (list 'QUALIFIER (subseq type-string (+ start 2) closing-paren))
-			   (+ closing-paren 2) end)))
-      ((prefix-match "m(")		; C++ member pointer
-       (multiple-value-bind (class-type class-end-index)
-	   (parse-swigtype type-string :junk-ok t
-			    :start (+ start 2) :end end)
-	 (unless (eql (type-char class-end-index) #\))
-	   (bad-type-error "missing right paren"))
-	 (unless (eql (type-char (+ class-end-index 1)) #\.)
-	   (bad-type-error "missing dot"))
-	 (cons-and-recurse (list 'MEMBER-POINTER class-type)
-			   (+ class-end-index 2) end)))	 
-      ((prefix-match "f(")		; function
-       (loop with index = (+ start 2) 
-	     until (eql (type-char index) #\))
-	     collect (multiple-value-bind (arg-type arg-end-index)
-			 (parse-swigtype type-string :junk-ok t
-					  :start index :end end)
-		       (case (type-char arg-end-index)
-			 (#\, (setq index (+ arg-end-index 1)))
-			 (#\) (setq index arg-end-index))
-			 (otherwise (bad-type-error "comma or right paren expected"))) 
-		       arg-type)
-	     into arg-types
-	     finally (unless (eql (type-char (+ index 1)) #\.)
-		       (bad-type-error "missing dot"))
-	     (return (cons-and-recurse (cons 'FUNCTION arg-types)
-				       (+ index 2) end))))
-      ((prefix-match "v(")		;varargs
-       (let ((closing-paren (position #\) type-string
-				  :start (+ start 2)
-				  :end end)))
-	 (unless closing-paren
-	   (bad-type-error "missing right paren"))
-	 (values (list 'VARARGS (subseq type-string (+ start 2) closing-paren))
-		 (+ closing-paren 1))))
-      (t (let ((junk-position (position-if (lambda (char)
-					     (member char '(#\, #\( #\) #\.)))
-					   type-string
-					   :start start :end end)))
-	   (cond (junk-position		; found junk
-		  (unless junk-ok
-		    (bad-type-error "trailing junk"))
-		  (values (subseq type-string start junk-position)
-			  junk-position))
-		 (t
-		  (values (subseq type-string start end)
-			  end))))))))
-
-(defun swigtype-function-p (swigtype)
-  "Check whether SWIGTYPE designates a function.  If so, the second
-value is the list of argument types, and the third value is the return
-type."
-  (if (and (consp swigtype)
-	   (consp (first swigtype))
-	   (eql (first (first swigtype)) 'FUNCTION))
-      (values t (rest (first swigtype)) (rest swigtype))
-      (values nil nil nil)))
-	      
-
-;; UFFI
-
-(defvar *uffi-definitions* '())
-
-(defconstant *uffi-default-primitive-type-alist*
-  '(("char" . :char)
-    ("unsigned char" . :unsigned-byte)
-    ("signed char" . :byte)
-    ("short" . :short)
-    ("signed short" . :short)
-    ("unsigned short" . :unsigned-short)
-    ("int" . :int)
-    ("signed int" . :int)
-    ("unsigned int" . :unsigned-int)
-    ("long" . :long)
-    ("signed long" . :long)
-    ("unsigned long" . :unsigned-long)
-    ("float" . :float)
-    ("double" . :double)
-    ((* . "char") . :cstring)
-    ((* . "void") . :pointer-void)
-    ("void" . :void)))
-
-(defvar *uffi-primitive-type-alist* *uffi-default-primitive-type-alist*)
-
-(defun uffi-type-spec (type-list)
-  "Return the UFFI type spec equivalent to TYPE-LIST, or NIL if there
-is no representation."
-  (let ((primitive-type-pair
-	 (assoc type-list *uffi-primitive-type-alist* :test 'equal)))
-    (cond
-      (primitive-type-pair
-       (cdr primitive-type-pair))
-      ((and (consp type-list)
-	    (eql (first type-list) '*))
-       (let ((base-type-spec (uffi-type-spec (rest type-list))))
-	 (cond
-	   ((not base-type-spec)
-	    :pointer-void)
-	   (t
-	    (list '* base-type-spec)))))
-      (t nil))))
-
-;; Parse tree
-
-(defvar *uffi-output* nil)
-
-(defun emit-uffi-definition (uffi-definition)
-  (format *uffi-output* "~&~S~%" uffi-definition)
-  (push uffi-definition *uffi-definitions*))
-
-(defun make-cl-symbol (c-identifier &key uninterned)
-  (let ((name (substitute #\- #\_ (string-upcase c-identifier))))
-    (if uninterned
-	(make-symbol name)
-	(intern name))))
-
-(defvar *class-scope* '() "A stack of names of nested C++ classes.")
-
-(defvar *struct-fields* '())
-
-(defvar *linkage* :C "NIL or :C")
-
-(defgeneric handle-node (node-type &key &allow-other-keys)
-  (:documentation "Handle a node of SWIG's parse tree of a C/C++ program"))
-
-(defmethod handle-node ((node-type t) &key &allow-other-keys)
-  ;; do nothing for unknown node types
-  nil)
-
-(defmethod handle-node ((node-type (eql 'cdecl)) &key name decl storage parms type &allow-other-keys)
-  (let ((swigtype (parse-swigtype (concatenate 'string decl type))))
-    (let ((*print-pretty* nil) ; or FUNCTION would be printed as #' by cmucl
-	  (*print-circle* t))
-      (format *uffi-output* "~&;; C Declaration: ~A ~A ~A ~A~%;;  with-parms ~W~%;;   of-type ~W~%"
-	      storage type name decl parms swigtype))
-    (multiple-value-bind (function-p arg-swigtype-list return-swigtype)
-	(swigtype-function-p swigtype)
-      (declare (ignore arg-swigtype-list))
-      (cond
-	((and (null *class-scope*) function-p
-	      (or (eql *linkage* :c)
-		  (string= storage "externc")))
-	 ;; ordinary top-level function with C linkage
-	 (let ((argnum 0)
-	       (argname-list '()))
-	   (flet ((unique-argname (name)
-		    ;; Sometimes the functions in SWIG interfaces
-		    ;; do not have unique names.  Make them unique
-		    ;; by adding a suffix.  Also avoid symbols
-		    ;; that are specially bound.
-		    (unless name
-		      (setq name (format nil "arg~D" argnum)))
-		    (let ((argname (make-cl-symbol name)))
-		      (when (boundp argname) ;specially bound
-			(setq argname (make-cl-symbol name :uninterned t)))
-		      (push argname argname-list)
-		      argname)))
-	     (let ((uffi-arg-list
-		    (mapcan (lambda (param)
-			      (incf argnum)
-			      (destructuring-bind (&key name type &allow-other-keys) param
-				(let ((uffi-type (uffi-type-spec (parse-swigtype type))))
-				  (cond
-				    ((not uffi-type)
-				     (format *uffi-output* "~&;; Warning: Cannot handle type ~S of argument `~A'~%"
-					     type name)
-				     (return-from handle-node))
-				    ((eq uffi-type :void)
-				     '())
-				    (t
-				     (let ((symbol (unique-argname name)))
-				       (list `(,symbol ,uffi-type))))))))
-			    parms))
-		   (uffi-return-type
-		    (uffi-type-spec return-swigtype)))
-	       (unless uffi-return-type
-		 (format *uffi-output* "~&;; Warning: Cannot handle return type `~S'~%"
-			 return-swigtype)
-		 (return-from handle-node))
-	       (emit-uffi-definition `(UFFI:DEF-FUNCTION ,name ,uffi-arg-list :RETURNING ,uffi-return-type))))))
-	((and (not (null *class-scope*)) (null (rest *class-scope*))
-	      (not function-p))	; class/struct member (no nested structs)
-	 (let ((uffi-type (uffi-type-spec swigtype)))
-	   (unless  uffi-type
-	     (format *uffi-output* "~&;; Warning: Cannot handle type ~S of struct field `~A'~%"
-		     type name)
-	     (return-from handle-node))
-	   (push `(,(make-cl-symbol name) ,uffi-type) *struct-fields*)))))))
-
-(defmethod handle-node ((node-type (eql 'class)) &key name children kind &allow-other-keys)
-  (format *uffi-output* "~&;; Class ~A~%" name)
-  (let ((*class-scope* (cons name *class-scope*))
-	(*struct-fields* '()))
-    (dolist (child children)
-      (apply 'handle-node child))
-    (emit-uffi-definition `(,(if (string= kind "union")
-				 'UFFI:DEF-UNION
-				 'UFFI:DEF-STRUCT)
-			    ,(make-cl-symbol name) ,@(nreverse *struct-fields*)))))
-
-(defmethod handle-node ((node-type (eql 'top)) &key children &allow-other-keys)
-  (dolist (child children)
-    (apply 'handle-node child)))
-  
-(defmethod handle-node ((node-type (eql 'include)) &key name children &allow-other-keys)
-  (format *uffi-output* ";; INCLUDE ~A~%" name)
-  (dolist (child children)
-    (apply 'handle-node child)))
-
-(defmethod handle-node ((node-type (eql 'extern)) &key name children &allow-other-keys)
-  (format *uffi-output* ";; EXTERN \"C\" ~A~%" name)
-  (let ((*linkage* :c))
-    (dolist (child children)
-      (apply 'handle-node child))))
-
-;;(defun compute-uffi-definitions (swig-interface)
-;;  (let ((*uffi-definitions* '()))
-;;    (handle-node swig-interface)
-;;    *uffi-definitions*))
-
-;; Test instances
-
-;;; Link to SWIG itself
-
-#||
-
-(defparameter *c++-compiler* "g++")
-
-(defun stdc++-library (&key env)
-  (let ((error-output (make-string-output-stream)))
-    (let ((name-output (make-string-output-stream)))
-      (let ((proc (ext:run-program
-		   *c++-compiler*
-		   '("-print-file-name=libstdc++.so")
-		   :env env
-		   :input nil
-		   :output name-output
-		   :error error-output)))
-	(unless proc
-	  (error "Could not run ~A" *c++-compiler*))
-	(unless (zerop (ext:process-exit-code proc))
-	  (system:serve-all-events 0)
-	  (error "~A failed:~%~A" *c++-compiler*
-		 (get-output-stream-string error-output))))
-      (string-right-trim '(#\Newline) (get-output-stream-string name-output)))))
-
-(defvar *swig-interface* nil)
-
-(defvar *swig-uffi-pathname* #p"/tmp/swig-uffi.lisp")
-
-(defun link-swig ()
-  (setq *swig-interface*
-	(run-swig (merge-pathnames "Source/swig.i" *swig-source-directory*)
-		  :directory-search-list
-		  (list (merge-pathnames "Source/" *swig-source-directory*))
-		  :module "swig"
-		  :ignore-errors t
-		  :c++ t))
-  (with-open-file (f *swig-uffi-pathname* :direction :output)
-    (let ((*linkage* :c++)
-	  (*uffi-definitions* '())
-	  (*uffi-output* f)
-	  (*uffi-primitive-type-alist* *uffi-default-primitive-type-alist*))
-      (apply 'handle-node *swig-interface*)))
-  (compile-file *swig-uffi-pathname*)
-  (alien:load-foreign (merge-pathnames "Source/libswig.a"
-				       *swig-source-directory*)
-		      :libraries (list (stdc++-library)))
-  ;; FIXME: UFFI stuffes a "-l" in front of the passed library names
-  ;;  (uffi:load-foreign-library (merge-pathnames "Source/libswig.a"
-  ;;                                              *swig-source-directory*)
-  ;;                             :supporting-libraries
-  ;;                             (list (stdc++-library)))
-  (load (compile-file-pathname *swig-uffi-pathname*)))
-
-||#
-
-;;;; TODO:
-
-;; * How to do type lookups?  Is everything important that SWIG knows
-;;   about the types written out?  What to make of typemaps?
-;;
-;; * Wrapped functions should probably automatically COERCE their
-;;   arguments (as of type DOUBLE-FLOAT), to make the functions more
-;;   flexible?
-;;
-;; * Why are the functions created by FFI interpreted?
-;;
-;; * We can't deal with more complicated structs and C++ classes
-;; directly with the FFI; we have to emit SWIG wrappers that access
-;; those classes.
-;;
-;; * A CLOS layer where structure fields are mapped as slots.  It
-;; looks like we need MOP functions to implement this.
-;;
-;; * Maybe modify SWIG so that key-value hashes are distinguished from
-;; value-value hashes.
diff --git a/Examples/scilab/check.list b/Examples/scilab/check.list
index 0bcf457..d57cfab 100644
--- a/Examples/scilab/check.list
+++ b/Examples/scilab/check.list
@@ -13,4 +13,3 @@
 struct
 template
 variables
-
diff --git a/Examples/scilab/matrix2/example.c b/Examples/scilab/matrix2/example.c
index 476067d..0246034 100644
--- a/Examples/scilab/matrix2/example.c
+++ b/Examples/scilab/matrix2/example.c
@@ -29,12 +29,12 @@
  	}
 }
 
-void getDoubleMatrix(double **resultMatrix, int *nbRowRes, int *nbColRes)
+void getDoubleMatrix(int nbRow, int nbCol, double **resultMatrix, int *nbRowRes, int *nbColRes)
 {
 	int i;
 	int size;
-	*nbRowRes = 5;
-	*nbColRes = 3;
+	*nbRowRes = nbRow;
+	*nbColRes = nbCol;
 	size = (*nbRowRes) * (*nbColRes);
    	*resultMatrix = (double*) malloc(size * sizeof(double));
 	for (i=0; i<size; i++)
@@ -43,6 +43,30 @@
 	}
 }
 
+void extractDoubleMatrix(double *inputMatrix, int nbRow, int nbCol, int* indexes, int nbIndexes, double **resultMatrix, int *nbRowRes, int *nbColRes)
+{
+	if (nbIndexes < 0)
+	{
+		int sz = nbRow * nbCol;
+		*nbRowRes = sz;
+		*nbColRes = 1;
+
+		*resultMatrix = malloc(sz * sizeof(double));
+		memcpy(*resultMatrix, inputMatrix, sz * sizeof(double));
+	} else {
+		int i;
+
+		*nbRowRes = nbIndexes;
+		*nbColRes = 1;
+
+		*resultMatrix = malloc(nbIndexes * sizeof(double));
+		for (i = 0; i < nbIndexes; i++)
+		{
+			(*resultMatrix)[i] = inputMatrix[indexes[i]];
+		}
+	}
+}
+
 // Integer matrix functions
 
 int sumIntegerMatrix(int *inputMatrix, int nbRow, int nbCol)
@@ -108,7 +132,7 @@
    	*resultVector = (char**) malloc((*sizeRes) * sizeof(char*));
 	for (i=0; i<*sizeRes; i++)
 	{
-		char* pc = (char*) calloc(3, sizeof(char));
+		char* pc = (char*) calloc(16, sizeof(char));
 		sprintf(pc, "%d", i);
 		(*resultVector)[i] = pc;
 	}
diff --git a/Examples/scilab/matrix2/example.i b/Examples/scilab/matrix2/example.i
index e37cd11..1584691 100644
--- a/Examples/scilab/matrix2/example.i
+++ b/Examples/scilab/matrix2/example.i
@@ -4,6 +4,7 @@
 
 %apply (double *IN, int IN_ROWCOUNT, int IN_COLCOUNT) { (double *inputMatrix, int nbRow, int nbCol) }
 %apply (double **OUT, int *OUT_ROWCOUNT, int *OUT_COLCOUNT) { (double **resultMatrix, int *nbRowRes, int *nbColRes) }
+%apply (int *IN, int IN_SIZE) { (int* indexes, int nbIndexes) }
 
 %apply (int *IN, int IN_ROWCOUNT, int IN_COLCOUNT) { (int *inputMatrix, int nbRow, int nbCol) }
 %apply (int **OUT, int *OUT_ROWCOUNT, int *OUT_COLCOUNT) { (int **resultMatrix, int *nbRowRes, int *nbColRes) }
@@ -14,7 +15,8 @@
 %inline %{
   extern double sumDoubleMatrix(double *inputMatrix, int nbRow, int nbCol);
   extern void squareDoubleMatrix(double *inputMatrix, int nbRow, int nbCol, double **resultMatrix, int *nbRowRes, int *nbColRes);
-  extern void getDoubleMatrix(double **resultMatrix, int *nbRowRes, int *nbColRes);
+  extern void getDoubleMatrix(int nbRow, int nbCol,double **resultMatrix, int *nbRowRes, int *nbColRes);
+  extern void extractDoubleMatrix(double *inputMatrix, int nbRow, int nbCol, int* indexes, int nbIndexes, double **resultMatrix, int *nbRowRes, int *nbColRes);
 
   extern int sumIntegerMatrix(int *inputMatrix, int nbRow, int nbCol);
   extern void squareIntegerMatrix(int *inputMatrix, int nbRow, int nbCol, int **resultMatrix, int *nbRowRes, int *nbColRes);
diff --git a/Examples/scilab/matrix2/runme.sci b/Examples/scilab/matrix2/runme.sci
index 0af7df4..4264991 100644
--- a/Examples/scilab/matrix2/runme.sci
+++ b/Examples/scilab/matrix2/runme.sci
@@ -8,7 +8,7 @@
 
 // Test lib double matrix functions
 disp("Call lib function getDoubleMatrix()");
-doubleMatrix = getDoubleMatrix();
+doubleMatrix = getDoubleMatrix(5, 3);
 disp(doubleMatrix);
 
 disp("Call lib function sumDoubleMatrix()");
@@ -19,6 +19,12 @@
 sqrd = squareDoubleMatrix(doubleMatrix);
 disp(sqrd);
 
+disp("Extract various indexes");
+disp(extractDoubleMatrix(doubleMatrix, 2));
+disp(extractDoubleMatrix(doubleMatrix, 2:5));
+disp(extractDoubleMatrix(doubleMatrix, :));
+
+
 
 // Test lib integer matrix functions
 
diff --git a/Examples/tcl/class/runme.tcl b/Examples/tcl/class/runme.tcl
index c7f4725..f6b6034 100644
--- a/Examples/tcl/class/runme.tcl
+++ b/Examples/tcl/class/runme.tcl
@@ -3,7 +3,7 @@
 # This file illustrates the high level C++ interface.
 # In this case C++ classes work kind of like Tk widgets
 
-catch { load ./example[info sharedlibextension] example}
+catch { load ./example[info sharedlibextension] Example}
 
 # ----- Object creation -----
 
diff --git a/Examples/tcl/class/runme2.tcl b/Examples/tcl/class/runme2.tcl
index 88ec2f6..5583b2a 100644
--- a/Examples/tcl/class/runme2.tcl
+++ b/Examples/tcl/class/runme2.tcl
@@ -4,7 +4,7 @@
 # created by SWIG.  In this case, all of our C++ classes
 # get converted into function calls.
 
-catch { load ./example[info sharedlibextension] example}
+catch { load ./example[info sharedlibextension] Example}
 
 # ----- Object creation -----
 
diff --git a/Examples/tcl/constants/runme.tcl b/Examples/tcl/constants/runme.tcl
index b504ba8..1355cd8 100644
--- a/Examples/tcl/constants/runme.tcl
+++ b/Examples/tcl/constants/runme.tcl
@@ -1,6 +1,6 @@
 # file: runme.tcl
 
-catch { load ./example[info sharedlibextension] example}
+catch { load ./example[info sharedlibextension] Example}
 
 puts "ICONST  = $ICONST (should be 42)"
 puts "FCONST  = $FCONST (should be 2.1828)"
diff --git a/Examples/tcl/contract/runme.tcl b/Examples/tcl/contract/runme.tcl
index 3a6ce10..c021a99 100644
--- a/Examples/tcl/contract/runme.tcl
+++ b/Examples/tcl/contract/runme.tcl
@@ -1,7 +1,7 @@
 # file: runme.tcl
 # Try to load as a dynamic module.
 
-catch { load ./example[info sharedlibextension] example}
+catch { load ./example[info sharedlibextension] Example}
 
 # Call our gcd() function
 set x 42
diff --git a/Examples/tcl/enum/runme.tcl b/Examples/tcl/enum/runme.tcl
index 3d4e52a..70a9b29 100644
--- a/Examples/tcl/enum/runme.tcl
+++ b/Examples/tcl/enum/runme.tcl
@@ -1,6 +1,6 @@
 # file: runme.tcl
 
-catch { load ./example[info sharedlibextension] example}
+catch { load ./example[info sharedlibextension] Example}
 
 # ----- Object creation -----
 
diff --git a/Examples/tcl/funcptr/runme.tcl b/Examples/tcl/funcptr/runme.tcl
index 7e676c2..61564f4 100644
--- a/Examples/tcl/funcptr/runme.tcl
+++ b/Examples/tcl/funcptr/runme.tcl
@@ -1,6 +1,6 @@
 # file: runme.tcl
 
-catch { load ./example[info sharedlibextension] example}
+catch { load ./example[info sharedlibextension] Example}
 
 set a 37
 set b 42
diff --git a/Examples/tcl/import/runme.tcl b/Examples/tcl/import/runme.tcl
index 1227d7b..cbc1727 100644
--- a/Examples/tcl/import/runme.tcl
+++ b/Examples/tcl/import/runme.tcl
@@ -2,10 +2,10 @@
 # Test various properties of classes defined in separate modules
 
 puts "Testing the %import directive"
-catch { load ./base[info sharedlibextension] base}
-catch { load ./foo[info sharedlibextension] foo}
-catch { load ./bar[info sharedlibextension] bar}
-catch { load ./spam[info sharedlibextension] spam}
+catch { load ./base[info sharedlibextension] Base}
+catch { load ./foo[info sharedlibextension] Foo}
+catch { load ./bar[info sharedlibextension] Bar}
+catch { load ./spam[info sharedlibextension] Spam}
 
 # Create some objects
 
diff --git a/Examples/tcl/index.html b/Examples/tcl/index.html
index b327260..acd9002 100644
--- a/Examples/tcl/index.html
+++ b/Examples/tcl/index.html
@@ -63,7 +63,7 @@
 </ul>
 
 Your mileage may vary.  If you experience a problem, please let us know by 
-contacting us on the <a href="http://www.swig.org/mail.html">mailing lists</a>.
+contacting us on the <a href="https://www.swig.org/mail.html">mailing lists</a>.
 </body>
 </html>
 
diff --git a/Examples/tcl/multimap/example.i b/Examples/tcl/multimap/example.i
index 9a141b6..60ab419 100644
--- a/Examples/tcl/multimap/example.i
+++ b/Examples/tcl/multimap/example.i
@@ -14,32 +14,34 @@
 
 extern int    gcd(int x, int y);
 
-%typemap(arginit) (int argc, char *argv[]) "$2 = 0;";
+%typemap(arginit) (int argc, char *argv[]) "$2 = 0;"
 
 %typemap(in) (int argc, char *argv[]) {
   Tcl_Obj **listobjv = 0;
   int i;
-  if (Tcl_ListObjGetElements(interp,$input, &$1, &listobjv) == TCL_ERROR) {
+  Tcl_Size tmpSize;
+  if (Tcl_ListObjGetElements(interp,$input, &tmpSize, &listobjv) == TCL_ERROR) {
     SWIG_exception(SWIG_ValueError,"Expected a list");
     return TCL_ERROR;
   }
+  $1 = (int)tmpSize;
   $2 = (char **) malloc(($1+1)*sizeof(char *));
   for (i = 0; i < $1; i++) {
-    $2[i] = Tcl_GetStringFromObj(listobjv[i],0);
+    $2[i] = Tcl_GetString(listobjv[i]);
   }
   $2[i] = 0;
 }
 
 %typemap(freearg) char *argv[] {
-  if ($1) {
-    free($1);
-  }
+  free($1);
 }
 
 extern int gcdmain(int argc, char *argv[]);
 
 %typemap(in) (char *bytes, int len) {
-  $1 = Tcl_GetStringFromObj($input,&$2);
+  Tcl_Size tmpSize;
+  $1 = Tcl_GetStringFromObj($input,&tmpSize);
+  $2 = (int)tmpSize;
 }
 
 extern int count(char *bytes, int len, char c);
@@ -49,7 +51,9 @@
 
 %typemap(in) (char *str, int len) {
   char *temp;
-  temp = Tcl_GetStringFromObj($input,&$2);
+  Tcl_Size tmpSize;
+  temp = Tcl_GetStringFromObj($input,&tmpSize);
+  $2 = (int)tmpSize;
   $1 = (char *) malloc($2+1);
   memmove($1,temp,$2);
 }
diff --git a/Examples/tcl/multimap/runme.tcl b/Examples/tcl/multimap/runme.tcl
index bafa281..81e6889 100644
--- a/Examples/tcl/multimap/runme.tcl
+++ b/Examples/tcl/multimap/runme.tcl
@@ -1,7 +1,7 @@
 # file: runme.tcl
 # Try to load as a dynamic module.
 
-catch { load ./example[info sharedlibextension] example}
+catch { load ./example[info sharedlibextension] Example}
 
 # Call our gcd() function
 set x 42
diff --git a/Examples/tcl/operator/runme.tcl b/Examples/tcl/operator/runme.tcl
index 9216455..46d73e3 100644
--- a/Examples/tcl/operator/runme.tcl
+++ b/Examples/tcl/operator/runme.tcl
@@ -1,6 +1,6 @@
 # Operator overloading example
 
-catch { load ./example[info sharedlibextension] example}
+catch { load ./example[info sharedlibextension] Example}
 
 set a [Complex -args 2 3]
 set b [Complex -args -5 10]
diff --git a/Examples/tcl/pointer/index.html b/Examples/tcl/pointer/index.html
index 4073802..0e97771 100644
--- a/Examples/tcl/pointer/index.html
+++ b/Examples/tcl/pointer/index.html
@@ -72,23 +72,25 @@
 
 <blockquote>
 <pre>
-%include "pointer.i"
+%include "cpointer.i"
 </pre>
-</blockquote?
+</blockquote>
 
 and in a script you would do this:
 
 <blockquote>
 <pre>
-set a [ptrcreate int 37]
-set b [ptrcreate int 42]
-set c [ptrcreate int]
+set a [new_intp]
+set b [new_intp]
+set c [new_intp]
+intp_assign $a 37
+intp_assign $b 42
 add $a $b $c
-set r [ptrvalue $c]
+set r [intp_value $c]
 puts "Result = $r"
-ptrfree $a
-ptrfree $b
-ptrfree $c
+delete_intp $a
+delete_intp $b
+delete_intp $c
 </pre>
 </blockquote>
 
@@ -156,14 +158,8 @@
 make it.
 
 <p>
-<li>More documentation on the typemaps.i and pointer.i library files can be
+<li>More documentation on the typemaps.i and cpointer.i library files can be
 found in the SWIG user manual.  The files also contain documentation.
-
-<p>
-<li>The pointer.i library is designed primarily for convenience.  If you
-are concerned about performance, you probably want to use a different
-approach.
-
 </ul>
 
 <hr>
diff --git a/Examples/tcl/pointer/runme.tcl b/Examples/tcl/pointer/runme.tcl
index efe9bb4..1793b67 100644
--- a/Examples/tcl/pointer/runme.tcl
+++ b/Examples/tcl/pointer/runme.tcl
@@ -1,6 +1,6 @@
 # file: runme.tcl
 
-catch { load ./example[info sharedlibextension] example}
+catch { load ./example[info sharedlibextension] Example}
 
 # First create some objects using the pointer library.
 puts "Testing the pointer library"
diff --git a/Examples/tcl/reference/index.html b/Examples/tcl/reference/index.html
index ef799fa..95059c0 100644
--- a/Examples/tcl/reference/index.html
+++ b/Examples/tcl/reference/index.html
@@ -104,7 +104,7 @@
 class VectorArray {
 public:
  ...
-   %addmethods {
+   %extend {
     Vector &amp;get(int index) {
       return (*self)[index];
     }
diff --git a/Examples/tcl/reference/runme.tcl b/Examples/tcl/reference/runme.tcl
index 6560cf4..7da44b9 100644
--- a/Examples/tcl/reference/runme.tcl
+++ b/Examples/tcl/reference/runme.tcl
@@ -2,7 +2,7 @@
 
 # This file illustrates the manipulation of C++ references in Tcl
 
-catch { load ./example[info sharedlibextension] example}
+catch { load ./example[info sharedlibextension] Example}
 
 # ----- Object creation -----
 
diff --git a/Examples/tcl/simple/runme.tcl b/Examples/tcl/simple/runme.tcl
index 3a6ce10..c021a99 100644
--- a/Examples/tcl/simple/runme.tcl
+++ b/Examples/tcl/simple/runme.tcl
@@ -1,7 +1,7 @@
 # file: runme.tcl
 # Try to load as a dynamic module.
 
-catch { load ./example[info sharedlibextension] example}
+catch { load ./example[info sharedlibextension] Example}
 
 # Call our gcd() function
 set x 42
diff --git a/Examples/tcl/std_vector/runme.tcl b/Examples/tcl/std_vector/runme.tcl
index 2cece96..4207680 100644
--- a/Examples/tcl/std_vector/runme.tcl
+++ b/Examples/tcl/std_vector/runme.tcl
@@ -1,6 +1,6 @@
 # file: runme.tcl
 
-catch { load ./example[info sharedlibextension] example}
+catch { load ./example[info sharedlibextension] Example}
 
 # Exercise IntVector
 
diff --git a/Examples/tcl/value/runme.tcl b/Examples/tcl/value/runme.tcl
index 1f6f4af..ea0b57d 100644
--- a/Examples/tcl/value/runme.tcl
+++ b/Examples/tcl/value/runme.tcl
@@ -1,7 +1,7 @@
 # file: runme.tcl
 # Try to load as a dynamic module.
 
-catch { load ./example[info sharedlibextension] example}
+catch { load ./example[info sharedlibextension] Example}
 
 # Create a couple of a vectors
 
diff --git a/Examples/tcl/variables/runme.tcl b/Examples/tcl/variables/runme.tcl
index 71aec38..ae1a978 100644
--- a/Examples/tcl/variables/runme.tcl
+++ b/Examples/tcl/variables/runme.tcl
@@ -1,6 +1,6 @@
 # file: runme.tcl
 
-catch { load ./example[info sharedlibextension] example}
+catch { load ./example[info sharedlibextension] Example}
 
 # Try to set the values of some global variables
 
diff --git a/Examples/test-suite/abstract_basecast.i b/Examples/test-suite/abstract_basecast.i
new file mode 100644
index 0000000..b6a21aa
--- /dev/null
+++ b/Examples/test-suite/abstract_basecast.i
@@ -0,0 +1,20 @@
+%module abstract_basecast
+
+%inline %{
+class BaseClass {
+public:
+    virtual ~BaseClass() { }
+
+    virtual void g() = 0;
+};
+
+class DerivedClass : public BaseClass {
+public:
+
+    virtual void g() { }
+
+    BaseClass& f() {
+        return *this;
+    }
+};
+%}
diff --git a/Examples/test-suite/abstract_inherit_using.i b/Examples/test-suite/abstract_inherit_using.i
new file mode 100644
index 0000000..25c37ec
--- /dev/null
+++ b/Examples/test-suite/abstract_inherit_using.i
@@ -0,0 +1,31 @@
+%module abstract_inherit_using
+
+%inline %{
+class AbstractBase
+{
+public:
+  virtual void f(int n) = 0;
+  void f(const char *another_representation_of_n) {}
+  virtual ~AbstractBase() {}
+};
+
+class ConcreteDerived1 : public AbstractBase
+{
+public:
+  ConcreteDerived1() {}
+
+  // Abstract test always worked
+  virtual void f(int n) {}
+  using AbstractBase::f;
+};
+
+class ConcreteDerived2 : public AbstractBase
+{
+public:
+  ConcreteDerived2() {}
+
+  // SWIG thought this class was abstract when using declaration was before method f and didn't generate constructor
+  using AbstractBase::f;
+  virtual void f(int n) {}
+};
+%}
diff --git a/Examples/test-suite/abstract_signature.i b/Examples/test-suite/abstract_signature.i
index 5d68fd0..8d41998 100644
--- a/Examples/test-suite/abstract_signature.i
+++ b/Examples/test-suite/abstract_signature.i
@@ -7,8 +7,8 @@
 class abstract_foo 
 { 
 public: 
-  abstract_foo() { }; 
-  virtual ~abstract_foo() { }; 
+  abstract_foo() { }
+  virtual ~abstract_foo() { }
   virtual int   meth(int meth_param) = 0; 
 }; 
  
@@ -16,9 +16,9 @@
 class abstract_bar : public abstract_foo 
 { 
 public: 
-  abstract_bar() { }; 
+  abstract_bar() { }
  
-  virtual ~abstract_bar() { }; 
+  virtual ~abstract_bar() { }
   virtual int   meth(int meth_param) = 0; 
   int           meth(int meth_param_1, int meth_param_2) { return 0; }
 }; 
diff --git a/Examples/test-suite/abstract_virtual.i b/Examples/test-suite/abstract_virtual.i
index d8372c9..40c52c2 100644
--- a/Examples/test-suite/abstract_virtual.i
+++ b/Examples/test-suite/abstract_virtual.i
@@ -11,7 +11,7 @@
 
 %inline %{
 #if defined(_MSC_VER)
-  #pragma warning( disable : 4250) // warning C4250: 'D' : inherits 'B::B::foo' via dominance
+  #pragma warning(disable : 4250) // warning C4250: 'D' : inherits 'B::B::foo' via dominance
 #endif
   struct A 
   {
diff --git a/Examples/test-suite/access_change.i b/Examples/test-suite/access_change.i
index aca5af3..a0c97b9 100644
--- a/Examples/test-suite/access_change.i
+++ b/Examples/test-suite/access_change.i
@@ -47,5 +47,3 @@
 %template(BaseInt) Base<int>;
 %template(DerivedInt) Derived<int>;
 %template(BottomInt) Bottom<int>;
-
-
diff --git a/Examples/test-suite/aggregate.i b/Examples/test-suite/aggregate.i
index dc00f06..8ac31ec 100644
--- a/Examples/test-suite/aggregate.i
+++ b/Examples/test-suite/aggregate.i
@@ -6,7 +6,7 @@
    To support contracts, you need to add a macro to the runtime.
    For Python, it looks like this:
 
-#define SWIG_contract_assert(expr, msg)  if (!(expr)) { PyErr_SetString(PyExc_RuntimeError, (char *) msg #expr ); goto fail; } else
+#define SWIG_contract_assert(expr, msg)  do { if (!(expr)) { PyErr_SetString(PyExc_RuntimeError, (char *) msg #expr ); goto fail; } } while (0)
 
    Note: It is used like this:
    SWIG_contract_assert(x == 1, "Some kind of error message");
diff --git a/Examples/test-suite/allegrocl/Makefile.in b/Examples/test-suite/allegrocl/Makefile.in
deleted file mode 100644
index b13d546..0000000
--- a/Examples/test-suite/allegrocl/Makefile.in
+++ /dev/null
@@ -1,126 +0,0 @@
-#######################################################################
-# Makefile for allegrocl test-suite
-#######################################################################
-
-LANGUAGE     = allegrocl
-ALLEGROCL    = @ALLEGROCLBIN@
-SCRIPTSUFFIX = _runme.lisp
-
-srcdir       = @srcdir@
-top_srcdir   = @top_srcdir@
-top_builddir = @top_builddir@
-
-
-# these cpp tests generate warnings/errors when compiling
-# the wrapper .cxx file.
-CPP_TEST_BROKEN_CXX =
-# the error is wrap:action code generated by swig. \
-# error: can't convert [std::string] 'b' to 'bool' \
-# might just need a bool overload op for std::string. \
-	global_vars \
-# same as w/ global_vars but with more errors in cxx file \
-	naturalvar \
-
-# these cpp tests aren't working. Fix 'em
-# need to further separate these into tests requiring
-# std libraries, or the $ldestructor problem.
-CPP_TEST_BROKEN_ACL = \
-	contract \
-	allprotected \
-# 'throws' typemap entries. \
-	cplusplus_throw \
-# 'throws' typemap entries. \
-	default_args \
-# missing typemaps. suspect module support needed \
-	dynamic_cast \
-	extend_variable \
-# cdata.i support needed \
-	li_cdata_cpp \
-# warning generated. otherwise all good. \
-	operator_overload \
-# std_common.i support \
-	sizet \
-# std_vector.i support. \
-	template_default \
-# *** line 31. can't copy typemap?? \
-	typemap_namespace \
-
-# these aren't working due to longlong support. (low hanging fruit)
-CPP_TEST_BROKEN_LONGLONG = \
-	arrays_dimensionless \
-	arrays_global \
-	arrays_global_twodim \
-	li_typemaps \
-	li_windows \
-	long_long_apply \
-	primitive_ref \
-	reference_global_vars \
-	template_default_arg
-
-# These are currently unsupported.
-CPP_TEST_CASES_ACL_UNSUPPORTED = \
-# contract support \
-	aggregate \
-# directors support \
-	apply_signed_char \
-# contract support \
-	contract \
-	director_exception \
-	director_protected \
-	exception_order \
-# 'throws' typemap support \
-	extern_throws \
-	throw_exception \
-	using_pointers \
-
-C_TEST_CASES_ACL_BROKEN = \
-# 'cdate.i' module support \
-	li_cdata \
-# adding an existing type defnition... \
-	typedef_struct \
-# swigrun.swg support. \
-	typemap_subst
-
-C_TEST_BROKEN_LONGLONG = \
-	long_long
-
-
-# std lib support hasn't been done yet.
-SKIP_CPP_STD_CASES = Yes
-
-include $(srcdir)/../common.mk
-
-# Overridden variables here
-# SWIGOPT += -debug-module 4
-
-# Custom tests - tests with additional commandline options
-# none!
-
-# Rules for the different types of tests
-%.cpptest:
-	$(setup)
-	+$(swig_and_compile_cpp)
-	$(run_testcase)
-
-%.ctest:
-	$(setup)
-	+$(swig_and_compile_c)
-	$(run_testcase)
-
-%.multicpptest:
-	$(setup)
-	+$(swig_and_compile_multi_cpp)
-	$(run_testcase)
-
-# Runs the testcase. A testcase is only run if
-# a file is found which has _runme.lisp appended after the testcase name.
-run_testcase = \
-	if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
-	  env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(ALLEGROCLBIN) -batch -s $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \
-	fi
-
-%.clean:
-	@rm -f $*.cl
-
-clean:
-	$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR="$(SRCDIR)" allegrocl_clean
diff --git a/Examples/test-suite/allowexcept.i b/Examples/test-suite/allowexcept.i
index c901295..229e65c 100644
--- a/Examples/test-suite/allowexcept.i
+++ b/Examples/test-suite/allowexcept.i
@@ -26,17 +26,6 @@
 struct XYZ {
 };
 
-// The operator& trick doesn't work for SWIG/PHP because the generated code
-// takes the address of the variable in the code in the "vinit" section.
-#ifdef SWIGPHP
-%{
-struct XYZ {
-  void foo() {}
-private:
-  XYZ& operator=(const XYZ& other); // prevent assignment used in normally generated set method
-};
-%}
-#else
 %{
 struct XYZ {
   void foo() {}
@@ -45,7 +34,6 @@
   XYZ* operator&(); // prevent dereferencing used in normally generated get method
 };
 %}
-#endif
 #if defined(SWIGUTL)
 %exception {
   /* 
diff --git a/Examples/test-suite/allprotected.i b/Examples/test-suite/allprotected.i
index e9b4eb3..292cf7b 100644
--- a/Examples/test-suite/allprotected.i
+++ b/Examples/test-suite/allprotected.i
@@ -85,3 +85,34 @@
 };
 %}
 
+%ignore AllProtectedTop;
+%feature("director") AllProtectedBottom;
+
+%inline %{
+  class AllProtectedTop {
+  public:
+    virtual ~AllProtectedTop() {}
+    void doSomething(int row) {}
+    void doSomething() {}
+    void usingOverloaded(int row) {}
+    void usingOverloaded() {}
+    void usingSingle() {}
+    void private1() {}
+    void private2() {}
+    void private2(int) {}
+  };
+
+  class AllProtectedBottom : public AllProtectedTop {
+  public:
+    virtual void apb() {}
+  protected:
+    // allprotected makes the following public in the director class
+    using AllProtectedTop::usingOverloaded;
+    using AllProtectedTop::usingSingle;
+    void doSomething(int row) {}
+    void doSomething() {}
+  private:
+    using AllProtectedTop::private1;
+    using AllProtectedTop::private2;
+  };
+%}
diff --git a/Examples/test-suite/apply_signed_char.i b/Examples/test-suite/apply_signed_char.i
index d3116f0..a33b285 100644
--- a/Examples/test-suite/apply_signed_char.i
+++ b/Examples/test-suite/apply_signed_char.i
@@ -35,7 +35,5 @@
     const char memberconstchar;
 
     virtual ~DirectorTest() {}
-  private:
-    DirectorTest& operator=(const DirectorTest &);
   };
 %}
diff --git a/Examples/test-suite/apply_strings.i b/Examples/test-suite/apply_strings.i
index 695dd06..14283bb 100644
--- a/Examples/test-suite/apply_strings.i
+++ b/Examples/test-suite/apply_strings.i
@@ -44,8 +44,6 @@
 // unsigned char* as strings
 #if defined(SWIGJAVA) || defined(SWIGCSHARP)
 
-/* Note: Chicken does not allow unsigned char * in strings */
-
 %apply char [ANY] {TAscii[ANY]}
 %apply char [] {TAscii []}
 %apply char * {TAscii *}
diff --git a/Examples/test-suite/argcargvtest.i b/Examples/test-suite/argcargvtest.i
index ed5aa09..a00dee1 100644
--- a/Examples/test-suite/argcargvtest.i
+++ b/Examples/test-suite/argcargvtest.i
@@ -1,8 +1,10 @@
 %module argcargvtest
 
+#ifndef SWIGOCAML
 %include <argcargv.i>
 
 %apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
+#endif
 
 %inline %{
 
@@ -13,7 +15,7 @@
 
 const char* mainv(size_t argc, const char **argv, int idx) 
 {
-  return argv[idx];
+  return argv[idx] ? argv[idx] : "<<NULL>>";
 }   
 
 void initializeApp(size_t argc, const char **argv, bool setPGid = true, bool isMakeline = false)
diff --git a/Examples/test-suite/arrays.i b/Examples/test-suite/arrays.i
index 07162aa..f98dd07 100644
--- a/Examples/test-suite/arrays.i
+++ b/Examples/test-suite/arrays.i
@@ -73,4 +73,8 @@
 cartPosition_t p;
 } CartPoseData_t;
 
+/* Test left shift in array size doesn't trigger "Bad template type" error.
+ * Regression test for https://sourceforge.net/p/swig/bugs/983/ */
+char array_shifted_size[(1<<2)];
+
 %}
diff --git a/Examples/test-suite/arrays_global.i b/Examples/test-suite/arrays_global.i
index fd53a22..a9894b5 100644
--- a/Examples/test-suite/arrays_global.i
+++ b/Examples/test-suite/arrays_global.i
@@ -57,15 +57,15 @@
   return hi;
 }
 
-char* test_b(name a, const namea b)  {
+char* test_b(name a, const namea b) {
   return a;
 }
 
-int test_a(int a)  {
+int test_a(int a) {
   return a;
 }
 
-int test_b(int a)  {
+int test_b(int a) {
   return a;
 }
  
diff --git a/Examples/test-suite/assign_const.i b/Examples/test-suite/assign_const.i
new file mode 100644
index 0000000..ba0c9ce
--- /dev/null
+++ b/Examples/test-suite/assign_const.i
@@ -0,0 +1,155 @@
+%module assign_const
+
+%{
+#if defined(_MSC_VER)
+  #pragma warning(disable : 4351) // warning C4351: new behavior: elements of array 'AssignArray::ArrayMember' will be default initialized
+#endif
+%}
+
+// Similar to assign_reference.i testcase but reference member variables replaced by const members
+
+%rename(Assign) *::operator=;
+
+// (1) Test directly non-assignable member variables
+%inline %{
+struct AssignValue {
+  AssignValue() : ValueMember() {}
+  const int ValueMember;
+};
+
+struct AssignArray {
+  AssignArray() : ArrayMember() {}
+  const int ArrayMember[1];
+};
+
+struct AssignPtr {
+  AssignPtr() : PtrMember() {}
+  int *const PtrMember;
+};
+
+struct AssignMatrix {
+  AssignMatrix() : MatrixMember() {}
+  const int MatrixMember[2][2];
+};
+
+struct MemberVars {
+  // These will only have getters
+  AssignValue MemberValue;
+  AssignArray MemberArray;
+  AssignPtr MemberPtr;
+  AssignMatrix MemberMatrix;
+};
+
+// (2) Test indirectly non-assignable member variables via inheritance
+struct AssignValueDerived : AssignValue {};
+struct AssignArrayDerived : AssignArray {};
+struct AssignPtrDerived : AssignPtr {};
+struct AssignMatrixDerived : AssignMatrix {};
+struct AssignValueDerivedSettable : AssignValue {
+  AssignValueDerivedSettable& operator=(const AssignValueDerivedSettable &) { return *this; }
+};
+struct AssignArrayDerivedSettable : AssignArray {
+  AssignArrayDerivedSettable& operator=(const AssignArrayDerivedSettable &) { return *this; }
+};
+struct AssignPtrDerivedSettable : AssignPtr {
+  AssignPtrDerivedSettable& operator=(const AssignPtrDerivedSettable &) { return *this; }
+};
+struct AssignMatrixDerivedSettable : AssignMatrix {
+  AssignMatrixDerivedSettable& operator=(const AssignMatrixDerivedSettable &) { return *this; }
+};
+
+struct InheritedMemberVars {
+  // These will only have getters
+  AssignValueDerived MemberValueDerived;
+  AssignArrayDerived MemberArrayDerived;
+  AssignPtrDerived MemberPtrDerived;
+  AssignMatrixDerived MemberMatrixDerived;
+
+  static AssignValueDerived StaticMemberValueDerived;
+  static AssignArrayDerived StaticMemberArrayDerived;
+  static AssignPtrDerived StaticMemberPtrDerived;
+  static AssignMatrixDerived StaticMemberMatrixDerived;
+
+  // These will have getters and setters
+  AssignValueDerivedSettable MemberValueDerivedSettable;
+  AssignArrayDerivedSettable MemberArrayDerivedSettable;
+  AssignPtrDerivedSettable MemberPtrDerivedSettable;
+  AssignMatrixDerivedSettable MemberMatrixDerivedSettable;
+
+  static AssignValueDerivedSettable StaticMemberValueDerivedSettable;
+  static AssignArrayDerivedSettable StaticMemberArrayDerivedSettable;
+  static AssignPtrDerivedSettable StaticMemberPtrDerivedSettable;
+  static AssignMatrixDerivedSettable StaticMemberMatrixDerivedSettable;
+};
+
+AssignValueDerived InheritedMemberVars::StaticMemberValueDerived;
+AssignArrayDerived InheritedMemberVars::StaticMemberArrayDerived;
+AssignPtrDerived InheritedMemberVars::StaticMemberPtrDerived;
+AssignMatrixDerived InheritedMemberVars::StaticMemberMatrixDerived;
+
+AssignValueDerivedSettable InheritedMemberVars::StaticMemberValueDerivedSettable;
+AssignArrayDerivedSettable InheritedMemberVars::StaticMemberArrayDerivedSettable;
+AssignPtrDerivedSettable InheritedMemberVars::StaticMemberPtrDerivedSettable;
+AssignMatrixDerivedSettable InheritedMemberVars::StaticMemberMatrixDerivedSettable;
+
+// These will only have getters
+AssignValueDerived GlobalValueDerived;
+AssignArrayDerived GlobalArrayDerived;
+AssignPtrDerived GlobalPtrDerived;
+AssignMatrixDerived GlobalMatrixDerived;
+
+// These will have getters and setters
+AssignValueDerivedSettable GlobalValueDerivedSettable;
+AssignArrayDerivedSettable GlobalArrayDerivedSettable;
+AssignPtrDerivedSettable GlobalPtrDerivedSettable;
+AssignMatrixDerivedSettable GlobalMatrixDerivedSettable;
+%}
+
+// (3) Test indirectly non-assignable member variables via classes that themselves have non-assignable member variables
+%inline %{
+struct MemberValueVar {
+  AssignValue MemberValue;
+};
+
+struct MemberArrayVar {
+  AssignArray MemberArray;
+};
+
+struct MemberPtrVar {
+  AssignPtr MemberPtr;
+};
+
+struct MemberMatrixVar {
+  AssignMatrix MemberMatrix;
+};
+
+struct MembersMemberVars {
+  // These will only have getters
+  MemberValueVar MemberValue;
+  MemberArrayVar MemberArray;
+  MemberPtrVar MemberPtr;
+  MemberMatrixVar MemberMatrix;
+};
+
+struct StaticMembersMemberVars {
+  static MemberValueVar StaticMemberValue;
+  static MemberArrayVar StaticMemberArray;
+  static MemberPtrVar StaticMemberPtr;
+  static MemberMatrixVar StaticMemberMatrix;
+};
+MemberValueVar StaticMembersMemberVars::StaticMemberValue;
+MemberArrayVar StaticMembersMemberVars::StaticMemberArray;
+MemberPtrVar StaticMembersMemberVars::StaticMemberPtr;
+MemberMatrixVar StaticMembersMemberVars::StaticMemberMatrix;
+
+MemberValueVar GlobalMemberValue;
+MemberArrayVar GlobalMemberArray;
+MemberPtrVar GlobalMemberPtr;
+MemberMatrixVar GlobalMemberMatrix;
+
+// Setters and getters available
+struct StaticMembersMemberVarsHolder {
+    StaticMembersMemberVars Member;
+};
+StaticMembersMemberVars GlobalStaticMembersMemberVars;
+%}
diff --git a/Examples/test-suite/assign_reference.i b/Examples/test-suite/assign_reference.i
new file mode 100644
index 0000000..1dbccd4
--- /dev/null
+++ b/Examples/test-suite/assign_reference.i
@@ -0,0 +1,130 @@
+%module assign_reference
+
+// Copy of cpp11_assign_delete.i testcase with deleted assignment operators replaced by reference member variables
+
+%rename(Assign) *::operator=;
+
+// (1) Test directly non-assignable member variables
+%inline %{
+int GlobalInt = 0;
+int& getGlobalIntRef() { return GlobalInt; }
+struct AssignPublic {
+  AssignPublic() : PublicMember(GlobalInt) {}
+  int &PublicMember;
+};
+
+struct AssignProtected {
+  AssignProtected() : ProtectedMember(GlobalInt) {}
+protected:
+  int &ProtectedMember;
+};
+
+typedef const int& ConstIntRef; // also check typedef resolution
+struct AssignPrivate {
+  AssignPrivate() : PrivateMember(GlobalInt) {}
+private:
+  ConstIntRef PrivateMember;
+};
+
+struct MemberVars {
+  // These will only have getters
+  AssignPublic MemberPublic;
+  AssignProtected MemberProtected;
+  AssignPrivate MemberPrivate;
+};
+
+// (2) Test indirectly non-assignable member variables via inheritance
+struct AssignPublicDerived : AssignPublic {};
+struct AssignProtectedDerived : AssignProtected {};
+struct AssignPrivateDerived : AssignPrivate {};
+struct AssignPublicDerivedSettable : AssignPublic {
+  AssignPublicDerivedSettable& operator=(const AssignPublicDerivedSettable &) { return *this; }
+};
+struct AssignProtectedDerivedSettable : AssignProtected {
+  AssignProtectedDerivedSettable& operator=(const AssignProtectedDerivedSettable &) { return *this; }
+};
+struct AssignPrivateDerivedSettable : AssignPrivate {
+  AssignPrivateDerivedSettable& operator=(const AssignPrivateDerivedSettable &) { return *this; }
+};
+
+struct InheritedMemberVars {
+  // These will only have getters
+  AssignPublicDerived MemberPublicDerived;
+  AssignProtectedDerived MemberProtectedDerived;
+  AssignPrivateDerived MemberPrivateDerived;
+
+  static AssignPublicDerived StaticMemberPublicDerived;
+  static AssignProtectedDerived StaticMemberProtectedDerived;
+  static AssignPrivateDerived StaticMemberPrivateDerived;
+
+  // These will have getters and setters
+  AssignPublicDerivedSettable MemberPublicDerivedSettable;
+  AssignProtectedDerivedSettable MemberProtectedDerivedSettable;
+  AssignPrivateDerivedSettable MemberPrivateDerivedSettable;
+
+  static AssignPublicDerivedSettable StaticMemberPublicDerivedSettable;
+  static AssignProtectedDerivedSettable StaticMemberProtectedDerivedSettable;
+  static AssignPrivateDerivedSettable StaticMemberPrivateDerivedSettable;
+};
+
+AssignPublicDerived InheritedMemberVars::StaticMemberPublicDerived;
+AssignProtectedDerived InheritedMemberVars::StaticMemberProtectedDerived;
+AssignPrivateDerived InheritedMemberVars::StaticMemberPrivateDerived;
+
+AssignPublicDerivedSettable InheritedMemberVars::StaticMemberPublicDerivedSettable;
+AssignProtectedDerivedSettable InheritedMemberVars::StaticMemberProtectedDerivedSettable;
+AssignPrivateDerivedSettable InheritedMemberVars::StaticMemberPrivateDerivedSettable;
+
+// These will only have getters
+AssignPublicDerived GlobalPublicDerived;
+AssignProtectedDerived GlobalProtectedDerived;
+AssignPrivateDerived GlobalPrivateDerived;
+
+// These will have getters and setters
+AssignPublicDerivedSettable GlobalPublicDerivedSettable;
+AssignProtectedDerivedSettable GlobalProtectedDerivedSettable;
+AssignPrivateDerivedSettable GlobalPrivateDerivedSettable;
+%}
+
+// (3) Test indirectly non-assignable member variables via classes that themselves have non-assignable member variables
+%inline %{
+struct MemberPublicVar {
+  AssignPublic MemberPublic;
+};
+
+struct MemberProtectedVar {
+protected:
+  AssignProtected MemberProtected;
+};
+
+struct MemberPrivateVar {
+private:
+  AssignPrivate MemberPrivate;
+};
+
+struct MembersMemberVars {
+  // These will only have getters
+  MemberPublicVar MemberPublic;
+  MemberProtectedVar MemberProtected;
+  MemberPrivateVar MemberPrivate;
+};
+
+struct StaticMembersMemberVars {
+  static MemberPublicVar StaticMemberPublic;
+  static MemberProtectedVar StaticMemberProtected;
+  static MemberPrivateVar StaticMemberPrivate;
+};
+MemberPublicVar StaticMembersMemberVars::StaticMemberPublic;
+MemberProtectedVar StaticMembersMemberVars::StaticMemberProtected;
+MemberPrivateVar StaticMembersMemberVars::StaticMemberPrivate;
+
+MemberPublicVar GlobalMemberPublic;
+MemberProtectedVar GlobalMemberProtected;
+MemberPrivateVar GlobalMemberPrivate;
+
+// Setters and getters available
+struct StaticMembersMemberVarsHolder {
+    StaticMembersMemberVars Member;
+};
+StaticMembersMemberVars GlobalStaticMembersMemberVars;
+%}
diff --git a/Examples/test-suite/autodoc.i b/Examples/test-suite/autodoc.i
index 9f4365e..0716ea6 100644
--- a/Examples/test-suite/autodoc.i
+++ b/Examples/test-suite/autodoc.i
@@ -5,8 +5,8 @@
 %feature("autodoc");
 
 // special typemap and its docs
-%typemap(in) (int c, int d) "$1 = 0; $2 = 0;";
-%typemap(doc,name="hello",type="Tuple") (int c, int d) "hello: int tuple[2]";
+%typemap(in) (int c, int d) "$1 = 0; $2 = 0;"
+%typemap(doc,name="hello",type="Tuple") (int c, int d) "hello: int tuple[2]"
 
 // testing for different documentation levels
 %feature("autodoc","0") A::func0; // names
@@ -69,8 +69,8 @@
 %typemap(doc) (int c, int d);
 
 // docs for some parameters
-%typemap(doc) int a "a: special comment for parameter a";
-%typemap(doc) int b "b: another special comment for parameter b";
+%typemap(doc) int a "a: special comment for parameter a"
+%typemap(doc) int b "b: another special comment for parameter b"
 
 %feature("autodoc","0") C::C(int a, int b, Hola h); // names
 %feature("autodoc","1") D::D(int a, int b, Hola h); // names + types
@@ -183,3 +183,12 @@
 typedef long int some_type;
 int process_complex_defval(int val = PROCESS_DEFAULT_VALUE, int factor = some_type(-1)) { return val*factor; }
 %}
+
+// Test for empty docstring, which should be ignored.
+%feature("docstring") ""
+
+%inline %{
+struct a_structure{
+  char my_array[1];
+};
+%}
diff --git a/Examples/test-suite/begin_code.i b/Examples/test-suite/begin_code.i
new file mode 100644
index 0000000..5b6b371
--- /dev/null
+++ b/Examples/test-suite/begin_code.i
@@ -0,0 +1,39 @@
+// Tests the csbegin, dbegin and javabegin for %module
+
+%define CSBEGIN_CODE
+"
+/* Copyright statement */
+using System.Text;
+// #nullable enable // commented out: only works with very modern versions of C#
+"
+%enddef
+
+%module(csbegin=CSBEGIN_CODE, dbegin="/* D common comment */", javabegin="/* Java common comment */\n") begin_code
+
+
+%inline %{
+struct ABC {
+    void abc_method() {}
+};
+%}
+
+#if defined(SWIGCSHARP)
+%extend ABC {
+%proxycode %{
+public StringBuilder TestBeginProxy(string input) {
+  return new StringBuilder(input);
+}
+%}
+}
+%pragma(csharp) imclasscode=%{
+public StringBuilder TestBeginIM(string input) {
+  return new StringBuilder(input);
+}
+%}
+%pragma(csharp) modulecode=%{
+public StringBuilder TestBeginModule(string input) {
+  return new StringBuilder(input);
+}
+%}
+#endif
+
diff --git a/Examples/test-suite/bools.i b/Examples/test-suite/bools.i
index 2ef3d93..ef2d38a 100644
--- a/Examples/test-suite/bools.i
+++ b/Examples/test-suite/bools.i
@@ -5,6 +5,12 @@
 %rename(BoolSt) BoolStructure;
 #endif
 
+/* We had to rename this in the C++ API being wrapped due to a collision with
+ * a value typedef in newer ocaml headers, so use %rename to avoid having to
+ * update all the runme files which use it.
+ */
+%rename(value) bool_value;
+
 %warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK);                   /* memory leak when setting a ptr/ref variable */
 %warnfilter(SWIGWARN_RUBY_WRONG_NAME) constbool;         /* Ruby, wrong class name */
 
@@ -44,7 +50,7 @@
 }
 
 // helper function
-bool value(bool* b) {
+bool bool_value(bool* b) {
     return *b;
 }
 
@@ -62,8 +68,6 @@
     m_rbool(m_bool2),
     m_const_pbool(m_pbool),
     m_const_rbool(m_rbool) {}
-private:
-  BoolStructure& operator=(const BoolStructure &);
 };
 %}
 
diff --git a/Examples/test-suite/c_delete.i b/Examples/test-suite/c_delete.i
index 0c69f9f..9c28330 100644
--- a/Examples/test-suite/c_delete.i
+++ b/Examples/test-suite/c_delete.i
@@ -4,7 +4,8 @@
 
 %warnfilter(SWIGWARN_PARSE_KEYWORD) delete;
 
-#if !defined(SWIGOCTAVE) && !defined(SWIG_JAVASCRIPT_V8) /* Octave and Javascript/v8 compiles wrappers as C++ */
+/* Octave and Javascript/v8 compiles wrappers as C++ */
+#if !defined(SWIGOCTAVE) && !defined(SWIG_JAVASCRIPT_V8) && !defined(SWIG_JAVASCRIPT_NAPI)
 
 %inline %{
 struct delete {
diff --git a/Examples/test-suite/c_delete_function.i b/Examples/test-suite/c_delete_function.i
index 8164d06..9bcbf0e 100644
--- a/Examples/test-suite/c_delete_function.i
+++ b/Examples/test-suite/c_delete_function.i
@@ -4,7 +4,8 @@
 
 %warnfilter(SWIGWARN_PARSE_KEYWORD) delete;
 
-#if !defined(SWIGOCTAVE) && !defined(SWIG_JAVASCRIPT_V8) /* Octave and Javascript/v8 compiles wrappers as C++ */
+/* Octave and Javascript/v8 compiles wrappers as C++ */
+#if !defined(SWIGOCTAVE) && !defined(SWIG_JAVASCRIPT_V8) && !defined(SWIG_JAVASCRIPT_NAPI)
 
 %inline %{
 double delete(double d) { return d; }
diff --git a/Examples/test-suite/callback.i b/Examples/test-suite/callback.i
index 4db6335..e406615 100644
--- a/Examples/test-suite/callback.i
+++ b/Examples/test-suite/callback.i
@@ -13,6 +13,7 @@
 %callback("%s") A::foom;
 #endif
 %callback("%(uppercase)s_Cb_Ptr") foo_T;  // this works in Python too
+%callback("%s_cb") identity_finger;
 
 %inline %{
 
@@ -85,6 +86,15 @@
   const T& ident(const T& x) {
     return x;
   }
+
+  // Test callbacks for enum types
+  typedef enum {One, Two, Three, Four, Five} finger;
+  typedef finger (*finger_finger)(finger);
+  finger identity_finger(finger f) { return f; }
+  finger apply_finger_cb(finger f, finger_finger cb) {
+      return cb(f);
+  }
+
 %}
 
 %template(foo_i) foo_T<int>;
diff --git a/Examples/test-suite/catches_strings.i b/Examples/test-suite/catches_strings.i
new file mode 100644
index 0000000..818a622
--- /dev/null
+++ b/Examples/test-suite/catches_strings.i
@@ -0,0 +1,17 @@
+%module catches_strings
+
+%include <std_string.i>
+
+%catches(const char *) StringsThrower::charstring;
+%catches(std::string) StringsThrower::stdstring;
+
+%inline %{
+struct StringsThrower {
+  static void charstring() {
+    throw "charstring message";
+  }
+  static void stdstring() {
+    throw std::string("stdstring message");
+  }
+};
+%}
diff --git a/Examples/test-suite/ccomplextest.i b/Examples/test-suite/ccomplextest.i
new file mode 100644
index 0000000..0530aa0
--- /dev/null
+++ b/Examples/test-suite/ccomplextest.i
@@ -0,0 +1,86 @@
+%module ccomplextest
+
+%include <complex.i>
+
+%{
+#include <complex.h>
+
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L && !defined __STDC_NO_COMPLEX__
+#define HAS_C99_COMPLEX_FOR_TESTING 1
+#else
+/* c99 complex not supported - super hack tests to just test plain floating point numbers */
+/* some pre c99 compilers (gcc-4.x) don't define _Complex but do define complex */
+#define _Complex
+#if !defined(complex)
+#  define complex
+#endif
+#define conj
+#define conjf
+#define creal
+#define cimag
+#if defined(I)
+#  undef I
+#  define I 1
+#endif
+#define HAS_C99_COMPLEX_FOR_TESTING 0
+#endif
+%}
+
+%inline %{
+static float _Complex CPLX_CONSTANT_ = 0;
+%}
+%constant CPLX_CONSTANT = CPLX_CONSTANT_;
+
+%inline
+{
+  int has_c99_complex(void) {
+    return HAS_C99_COMPLEX_FOR_TESTING;
+  }
+
+  complex double Conj(complex double a)
+  {
+    return conj(a);
+  }
+
+
+  complex float Conjf(complex float a)
+  {
+    return conjf(a);
+  }
+
+
+  double complex Conj1(double complex a)
+  {
+    return conj(a);
+  }
+
+
+  float complex Conjf1(float complex a)
+  {
+    return conjf(a);
+  }
+
+
+  _Complex double Conj2(_Complex double a)
+  {
+    return conj(a);
+  }
+
+
+  _Complex float Conjf2(_Complex float a)
+  {
+    return conjf(a);
+  }
+
+
+  double _Complex Conj3(double _Complex a)
+  {
+    return conj(a);
+  }
+
+
+  float _Complex Conjf3(float _Complex a)
+  {
+    return conjf(a);
+  }
+}
diff --git a/Examples/test-suite/cffi/Makefile.in b/Examples/test-suite/cffi/Makefile.in
deleted file mode 100644
index 6eebaa0..0000000
--- a/Examples/test-suite/cffi/Makefile.in
+++ /dev/null
@@ -1,51 +0,0 @@
-#######################################################################
-# Makefile for cffi test-suite
-#######################################################################
-
-LANGUAGE     = cffi
-CFFI         = @CFFIBIN@
-SCRIPTSUFFIX = _runme.lisp
-
-srcdir       = @srcdir@
-top_srcdir   = @top_srcdir@
-top_builddir = @top_builddir@
-
-include $(srcdir)/../common.mk
-
-# Overridden variables here
-# no C++ tests for now
-CPP_TEST_CASES =
-#C_TEST_CASES +=
-
-# Custom tests - tests with additional commandline options
-# none!
-
-# Rules for the different types of tests
-%.cpptest:
-	$(setup)
-	+$(swig_and_compile_cpp)
-	$(run_testcase)
-
-%.ctest:
-	$(setup)
-	+$(swig_and_compile_c)
-	$(run_testcase)
-
-%.multicpptest:
-	$(setup)
-	+$(swig_and_compile_multi_cpp)
-	$(run_testcase)
-
-# Runs the testcase. A testcase is only run if
-# a file is found which has _runme.lisp appended after the testcase name.
-run_testcase = \
-	if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
-	  env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(CFFI) -batch -s $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \
-	fi
-
-# Clean: (does nothing, we dont generate extra cffi code)
-%.clean:
-	@exit 0
-
-clean:
-	$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' cffi_clean
diff --git a/Examples/test-suite/char_strings.i b/Examples/test-suite/char_strings.i
index 9a87df4..aa3b125 100644
--- a/Examples/test-suite/char_strings.i
+++ b/Examples/test-suite/char_strings.i
@@ -11,6 +11,7 @@
 
 %{
 #include <stdio.h>
+#include <string.h>
 
 #define OTHERLAND_MSG "Little message from the safe world."
 #define CPLUSPLUS_MSG "A message from the deep dark world of C++, where anything is possible."
@@ -150,11 +151,11 @@
 %inline {
   struct Formatpos;
   struct OBFormat;
-  
+
   static int GetNextFormat(Formatpos& itr, const  char*& str,OBFormat*& pFormat) {
     return 0;
   }
-  
+
 
 
 }
diff --git a/Examples/test-suite/chicken/Makefile.in b/Examples/test-suite/chicken/Makefile.in
deleted file mode 100644
index b3dccc9..0000000
--- a/Examples/test-suite/chicken/Makefile.in
+++ /dev/null
@@ -1,101 +0,0 @@
-#######################################################################
-# Makefile for chicken test-suite
-#######################################################################
-
-LANGUAGE     = chicken
-VARIANT      =
-SCRIPTSUFFIX = _runme.ss
-PROXYSUFFIX  = _runme_proxy.ss
-
-srcdir       = @srcdir@
-top_srcdir   = @top_srcdir@
-top_builddir = @top_builddir@
-
-CHICKEN_CSI  = @CHICKEN_CSI@ -quiet -batch -no-init
-SO           = @SO@
-
-#C_TEST_CASES = long_long list_vector pointer_in_out multivalue
-
-# Skip the STD cases for now, except for li_std_string.i
-SKIP_CPP_STD_CASES = Yes
-
-CPP_TEST_CASES += li_std_string
-
-EXTRA_TEST_CASES += chicken_ext_test.externaltest
-
-include $(srcdir)/../common.mk
-
-# Overridden variables here
-SWIGOPT += -nounit
-
-# Custom tests - tests with additional commandline options
-# If there exists a PROXYSUFFIX runme file, we also generate the wrapper
-# with the -proxy argument
-%.cppproxy: SWIGOPT += -proxy
-%.cppproxy: SCRIPTSUFFIX = $(PROXYSUFFIX)
-
-%.cproxy: SWIGOPT += -proxy
-%.cproxy: SCRIPTSUFFIX = $(PROXYSUFFIX)
-
-%.multiproxy: SWIGOPT += -proxy -noclosuses
-%.multiproxy: SCRIPTSUFFIX = $(PROXYSUFFIX)
-
-# Rules for the different types of tests
-%.cpptest:
-	$(setup)
-	+$(swig_and_compile_cpp)
-	$(run_testcase)
-	if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(PROXYSUFFIX) ]; then \
-	  $(MAKE) $*.cppproxy; \
-	fi
-
-%.ctest:
-	$(setup)
-	+$(swig_and_compile_c)
-	$(run_testcase)
-	if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(PROXYSUFFIX) ]; then \
-	  $(MAKE) $*.cproxy; \
-	fi
-
-%.multicpptest:
-	$(setup)
-	+$(swig_and_compile_multi_cpp)
-	$(run_testcase)
-	if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(PROXYSUFFIX) ]; then \
-	  $(MAKE) $*.multiproxy; \
-	fi
-
-%.externaltest:
-	$(setup)
-	+$(swig_and_compile_external)
-	$(run_testcase)
-
-%.cppproxy:
-	echo "$(ACTION)ing $(LANGUAGE) testcase $* (with run test) with -proxy"
-	+$(swig_and_compile_cpp)
-	$(run_testcase)
-
-%.cproxy:
-	echo "$(ACTION)ing $(LANGUAGE) testcase $* (with run test) with -proxy"
-	+$(swig_and_compile_c)
-	$(run_testcase)
-
-%.multiproxy:
-	echo "$(ACTION)ing $(LANGUAGE) testcase $* (with run test) with -proxy"
-	+$(swig_and_compile_multi_cpp)
-	$(run_testcase)
-
-# Runs the testcase. A testcase is only run if
-# a file is found which has _runme.scm appended after the testcase name.
-run_testcase = \
-	if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
-	  env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(CHICKEN_CSI) $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \
-	fi
-
-# Clean
-%.clean:
-	@exit 0
-
-clean:
-	$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' chicken_clean
-	rm -f *.scm
diff --git a/Examples/test-suite/chicken/README b/Examples/test-suite/chicken/README
deleted file mode 100644
index aad730e..0000000
--- a/Examples/test-suite/chicken/README
+++ /dev/null
@@ -1,11 +0,0 @@
-See ../README for common README file.
-
-Any testcases which have _runme.ss appended after the testcase name will be detected and run.
-NOTE: I had to use _runme.ss because otherwise it would be hard to implement make clean
-Since when SWIG runs it generates an example.scm file for every test, to clean those files
-I needed to add a rm -f *.scm to make clean.  But we don't want the runme scripts to
-disappear as well!
-
-Any testcases which have _runme_proxy.ss appended after the testcase name will be detected
-and run with the -proxy argument passed to SWIG.  SWIG will not be run with the -unhide-primitive
-option, so the _runme_proxy.ss file must use only the tinyclos exported interface.
diff --git a/Examples/test-suite/chicken/casts_runme.ss b/Examples/test-suite/chicken/casts_runme.ss
deleted file mode 100644
index 2eca461..0000000
--- a/Examples/test-suite/chicken/casts_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "casts.so")
-(include "../schemerunme/casts.scm")
diff --git a/Examples/test-suite/chicken/char_constant_runme.ss b/Examples/test-suite/chicken/char_constant_runme.ss
deleted file mode 100644
index 50dff30..0000000
--- a/Examples/test-suite/chicken/char_constant_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "char_constant.so")
-(include "../schemerunme/char_constant.scm")
diff --git a/Examples/test-suite/chicken/chicken_ext_test_external.cxx b/Examples/test-suite/chicken/chicken_ext_test_external.cxx
deleted file mode 100644
index 1dd6a7d..0000000
--- a/Examples/test-suite/chicken/chicken_ext_test_external.cxx
+++ /dev/null
@@ -1,21 +0,0 @@
-#include <chicken/chicken_ext_test_wrap_hdr.h>
-#include <imports_a.h>
-
-void test_create(C_word,C_word,C_word) C_noret;
-void test_create(C_word argc, C_word closure, C_word continuation) {
-  C_word resultobj;
-  swig_type_info *type;
-  A *newobj;
-  C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
-
-  C_trace("test-create");
-  if (argc!=2) C_bad_argc(argc,2);
-
-
-  newobj = new A();
-
-  type = SWIG_TypeQuery("A *");
-  resultobj = SWIG_NewPointerObj(newobj, type, 1);
-
-  C_kontinue(continuation, resultobj);
-}
diff --git a/Examples/test-suite/chicken/chicken_ext_test_runme.ss b/Examples/test-suite/chicken/chicken_ext_test_runme.ss
deleted file mode 100644
index 65fa4e0..0000000
--- a/Examples/test-suite/chicken/chicken_ext_test_runme.ss
+++ /dev/null
@@ -1,5 +0,0 @@
-(load "chicken_ext_test.so")
-
-(define a (test-create))
-
-(A-hello a)
diff --git a/Examples/test-suite/chicken/class_ignore_runme.ss b/Examples/test-suite/chicken/class_ignore_runme.ss
deleted file mode 100644
index ba84810..0000000
--- a/Examples/test-suite/chicken/class_ignore_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "class_ignore.so")
-(include "../schemerunme/class_ignore.scm")
diff --git a/Examples/test-suite/chicken/clientdata_prop_runme_proxy.ss b/Examples/test-suite/chicken/clientdata_prop_runme_proxy.ss
deleted file mode 100644
index 62f2c20..0000000
--- a/Examples/test-suite/chicken/clientdata_prop_runme_proxy.ss
+++ /dev/null
@@ -1,95 +0,0 @@
-(require 'clientdata_prop_a)
-(require 'clientdata_prop_b)
-
-(define a (make <A>))
-(test-A a)
-(test-tA a)
-(test-t2A a)
-(test-t3A a)
-(fA a)
-
-(define b (make <B>))
-(test-A b)
-(test-tA b)
-(test-t2A b)
-(test-t3A b)
-(test-B b)
-(fA b)
-(fB b)
-
-(define c (make <C>))
-(test-A c)
-(test-tA c)
-(test-t2A c)
-(test-t3A c)
-(test-C c)
-(fA c)
-(fC c)
-
-(define d (make <D>))
-(test-A d)
-(test-tA d)
-(test-t2A d)
-(test-t3A d)
-(test-D d)
-(test-tD d)
-(test-t2D d)
-(fA d)
-(fD d)
-
-;; here are the real tests... if the clientdata is correctly
-;; propegated, new-tA, new-t2A, should all return wrapped proxy's
-;; of class <A>
-
-(define a2 (new-tA))
-(if (not (eq? (class-of a2) <A>))
-  (error "Error 1"))
-(test-A a2)
-(test-tA a2)
-(test-t2A a2)
-(test-t3A a2)
-(fA a2)
-
-(define a3 (new-t2A))
-(if (not (eq? (class-of a3) <A>))
-  (error "Error 2"))
-(test-A a3)
-(test-tA a3)
-(test-t2A a3)
-(test-t3A a3)
-(fA a3)
-
-(define a4 (new-t3A))
-(if (not (eq? (class-of a4) <A>))
-  (error "Error 3"))
-(test-A a4)
-(test-tA a4)
-(test-t2A a4)
-(test-t3A a4)
-(fA a4)
-
-(define d2 (new-tD))
-(if (not (eq? (class-of d2) <D>))
-  (error "Error 4"))
-(test-A d2)
-(test-tA d2)
-(test-t2A d2)
-(test-t3A d2)
-(test-D d2)
-(test-tD d2)
-(fA d2)
-(fD d2)
-
-(define d3 (new-t2D))
-(if (not (eq? (class-of d3) <D>))
-  (error "Error 5"))
-(test-A d3)
-(test-tA d3)
-(test-t2A d3)
-(test-t3A d3)
-(test-D d3)
-(test-tD d3)
-(fA d3)
-(fD d3)
-
-(exit 0)
diff --git a/Examples/test-suite/chicken/constover_runme.ss b/Examples/test-suite/chicken/constover_runme.ss
deleted file mode 100644
index eb39c7f..0000000
--- a/Examples/test-suite/chicken/constover_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "constover.so")
-(include "../schemerunme/constover.scm")
diff --git a/Examples/test-suite/chicken/contract_runme.ss b/Examples/test-suite/chicken/contract_runme.ss
deleted file mode 100644
index 006bcfd..0000000
--- a/Examples/test-suite/chicken/contract_runme.ss
+++ /dev/null
@@ -1,3 +0,0 @@
-(load "contract.so")
-(include "testsuite.ss")
-(include "../schemerunme/contract.scm")
diff --git a/Examples/test-suite/chicken/cpp_basic_runme_proxy.ss b/Examples/test-suite/chicken/cpp_basic_runme_proxy.ss
deleted file mode 100644
index 7b0b6d7..0000000
--- a/Examples/test-suite/chicken/cpp_basic_runme_proxy.ss
+++ /dev/null
@@ -1,64 +0,0 @@
-(require 'cpp_basic)
-
-(define-macro (check test)
-  `(if (not ,test) (error "Error in test " ',test)))
-
-(define f (make <Foo> 4))
-(check (= (slot-ref f 'num) 4))
-(slot-set! f 'num -17)
-(check (= (slot-ref f 'num) -17))
-
-(define b (make <Bar>))
-
-(slot-set! b 'fptr f)
-(check (= (slot-ref (slot-ref b 'fptr) 'num) -17))
-(check (= (test b -3 (slot-ref b 'fptr)) -5))
-(slot-set! f 'num 12)
-(check (= (slot-ref (slot-ref b 'fptr) 'num) 12))
-
-(check (= (slot-ref (slot-ref b 'fref) 'num) -4))
-(check (= (test b 12 (slot-ref b 'fref)) 23))
-;; references don't take ownership, so if we didn't define this here it might get garbage collected
-(define f2 (make <Foo> 23))
-(slot-set! b 'fref f2)
-(check (= (slot-ref (slot-ref b 'fref) 'num) 23))
-(check (= (test b -3 (slot-ref b 'fref)) 35))
-
-(check (= (slot-ref (slot-ref b 'fval) 'num) 15))
-(check (= (test b 3 (slot-ref b 'fval)) 33))
-(slot-set! b 'fval (make <Foo> -15))
-(check (= (slot-ref (slot-ref b 'fval) 'num) -15))
-(check (= (test b 3 (slot-ref b 'fval)) -27))
-
-(define f3 (testFoo b 12 (slot-ref b 'fref)))
-(check (= (slot-ref f3 'num) 32))
-
-;; now test global
-(define f4 (make <Foo> 6))
-(Bar-global-fptr f4)
-(check (= (slot-ref (Bar-global-fptr) 'num) 6))
-(slot-set! f4 'num 8)
-(check (= (slot-ref (Bar-global-fptr) 'num) 8))
-
-(check (= (slot-ref (Bar-global-fref) 'num) 23))
-(Bar-global-fref (make <Foo> -7))
-(check (= (slot-ref (Bar-global-fref) 'num) -7))
-
-(check (= (slot-ref (Bar-global-fval) 'num) 3))
-(Bar-global-fval (make <Foo> -34))
-(check (= (slot-ref (Bar-global-fval) 'num) -34))
-
-;; Now test function pointers
-(define func1ptr (get-func1-ptr))
-(define func2ptr (get-func2-ptr))
-
-(slot-set! f 'num 4)
-(check (= (func1 f 2) 16))
-(check (= (func2 f 2) -8))
-
-(slot-set! f 'func-ptr func1ptr)
-(check (= (test-func-ptr f 2) 16))
-(slot-set! f 'func-ptr func2ptr)
-(check (= (test-func-ptr f 2) -8))
-
-(exit 0)
diff --git a/Examples/test-suite/chicken/cpp_enum_runme.ss b/Examples/test-suite/chicken/cpp_enum_runme.ss
deleted file mode 100644
index 4d4ec76..0000000
--- a/Examples/test-suite/chicken/cpp_enum_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "cpp_enum.so")
-(include "../schemerunme/cpp_enum.scm")
diff --git a/Examples/test-suite/chicken/cpp_namespace_runme.ss b/Examples/test-suite/chicken/cpp_namespace_runme.ss
deleted file mode 100644
index 800172e..0000000
--- a/Examples/test-suite/chicken/cpp_namespace_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "cpp_namespace.so")
-(include "../schemerunme/cpp_namespace.scm")
diff --git a/Examples/test-suite/chicken/dynamic_cast_runme.ss b/Examples/test-suite/chicken/dynamic_cast_runme.ss
deleted file mode 100644
index 1e81d55..0000000
--- a/Examples/test-suite/chicken/dynamic_cast_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "dynamic_cast.so")
-(include "../schemerunme/dynamic_cast.scm")
diff --git a/Examples/test-suite/chicken/global_vars_runme.ss b/Examples/test-suite/chicken/global_vars_runme.ss
deleted file mode 100644
index 802205b..0000000
--- a/Examples/test-suite/chicken/global_vars_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(require 'global_vars)
-(load "../schemerunme/global_vars.scm")
diff --git a/Examples/test-suite/chicken/global_vars_runme_proxy.ss b/Examples/test-suite/chicken/global_vars_runme_proxy.ss
deleted file mode 100644
index 3c4500d..0000000
--- a/Examples/test-suite/chicken/global_vars_runme_proxy.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(require 'global_vars)
-(load "../schemerunme/global_vars_proxy.scm")
diff --git a/Examples/test-suite/chicken/import_nomodule_runme.ss b/Examples/test-suite/chicken/import_nomodule_runme.ss
deleted file mode 100644
index 7e64053..0000000
--- a/Examples/test-suite/chicken/import_nomodule_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "import_nomodule.so")
-(include "../schemerunme/import_nomodule.scm")
diff --git a/Examples/test-suite/chicken/imports_runme.ss b/Examples/test-suite/chicken/imports_runme.ss
deleted file mode 100644
index ac5fb98..0000000
--- a/Examples/test-suite/chicken/imports_runme.ss
+++ /dev/null
@@ -1,3 +0,0 @@
-(load "imports_a.so")
-(load "imports_b.so")
-(include "../schemerunme/imports.scm")
diff --git a/Examples/test-suite/chicken/inherit_missing_runme.ss b/Examples/test-suite/chicken/inherit_missing_runme.ss
deleted file mode 100644
index 50a084a..0000000
--- a/Examples/test-suite/chicken/inherit_missing_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "inherit_missing.so")
-(include "../schemerunme/inherit_missing.scm")
diff --git a/Examples/test-suite/chicken/li_std_string_runme.ss b/Examples/test-suite/chicken/li_std_string_runme.ss
deleted file mode 100644
index cc64287..0000000
--- a/Examples/test-suite/chicken/li_std_string_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "li_std_string.so")
-(include "../schemerunme/li_std_string.scm")
diff --git a/Examples/test-suite/chicken/li_std_string_runme_proxy.ss b/Examples/test-suite/chicken/li_std_string_runme_proxy.ss
deleted file mode 100644
index e1e2409..0000000
--- a/Examples/test-suite/chicken/li_std_string_runme_proxy.ss
+++ /dev/null
@@ -1,47 +0,0 @@
-(load "li_std_string.so")
-
-(define x "hello")
-
-(if (not (string=? (test-value x) x))
-  (begin (error "Error 1") (exit 1)))
-
-(if (not (string=? (test-const-reference x) x))
-  (begin (error "Error 2") (exit 1)))
-
-(define y (test-pointer-out))
-(test-pointer y)
-(define z (test-const-pointer-out))
-(test-const-pointer z)
-
-(define a (test-reference-out))
-(test-reference a)
-
-;; test global variables
-(GlobalString "whee")
-(if (not (string=? (GlobalString) "whee"))
-  (error "Error 3"))
-(if (not (string=? (GlobalString2) "global string 2"))
-  (error "Error 4"))
-
-(define struct (make <Structure>))
-
-;; MemberString should be a wrapped class
-(if (not (string=? (slot-ref struct 'MemberString) ""))
-  (error "Error 4.5"))
-;(slot-set! (slot-ref struct 'MemberString) "and how")
-;;(if (not (string=? (slot-ref struct 'MemberString) "and how"))
-;;  (error "Error 5"))
-(if (not (string=? (slot-ref struct 'MemberString2) "member string 2"))
-  (error "Error 6"))
-(Structure-StaticMemberString "static str")
-(if (not (string=? (Structure-StaticMemberString) "static str"))
-  (error "Error 7"))
-(if (not (string=? (Structure-StaticMemberString2) "static member string 2"))
-  (error "Error 8"))
-
-;(if (not (string=? (Structure-ConstMemberString-get struct) "const member string"))
-;  (error "Error 9"))
-(if (not (string=? (Structure-ConstStaticMemberString) "const static member string"))
-  (error "Error 10"))
-
-(exit 0)
diff --git a/Examples/test-suite/chicken/li_typemaps_runme.ss b/Examples/test-suite/chicken/li_typemaps_runme.ss
deleted file mode 100644
index 1ad6e92..0000000
--- a/Examples/test-suite/chicken/li_typemaps_runme.ss
+++ /dev/null
@@ -1,12 +0,0 @@
-(require 'li_typemaps)
-(load "../schemerunme/li_typemaps.scm")
-
-(call-with-values (lambda () (inoutr-int2 3 -2))
-		  (lambda (a b)
-		    (if (not (and (= a 3) (= b -2)))
-		      (error "Error in inoutr-int2"))))
-(call-with-values (lambda () (out-foo 4))
-		  (lambda (a b)
-		    (if (not (and (= (Foo-a-get a) 4) (= b 8)))
-		      (error "Error in out-foo"))))
-(exit 0)
diff --git a/Examples/test-suite/chicken/li_typemaps_runme_proxy.ss b/Examples/test-suite/chicken/li_typemaps_runme_proxy.ss
deleted file mode 100644
index 52997c6..0000000
--- a/Examples/test-suite/chicken/li_typemaps_runme_proxy.ss
+++ /dev/null
@@ -1,13 +0,0 @@
-(require 'li_typemaps)
-(load "../schemerunme/li_typemaps_proxy.scm")
-
-(call-with-values (lambda () (inoutr-int2 3 -2))
-		  (lambda (a b)
-		    (if (not (and (= a 3) (= b -2)))
-		      (error "Error in inoutr-int2"))))
-(call-with-values (lambda () (out-foo 4))
-		  (lambda (a b)
-		    (if (not (and (= (slot-ref a 'a) 4) (= b 8)))
-		      (error "Error in out-foo"))))
-
-(exit 0)
diff --git a/Examples/test-suite/chicken/list_vector_runme.ss b/Examples/test-suite/chicken/list_vector_runme.ss
deleted file mode 100644
index 67d52f6..0000000
--- a/Examples/test-suite/chicken/list_vector_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "list_vector.so")
-(include "../schemerunme/list_vector.scm")
diff --git a/Examples/test-suite/chicken/member_pointer_runme.ss b/Examples/test-suite/chicken/member_pointer_runme.ss
deleted file mode 100644
index f2226b2..0000000
--- a/Examples/test-suite/chicken/member_pointer_runme.ss
+++ /dev/null
@@ -1,28 +0,0 @@
-(require 'member_pointer)
-
-(define (check-eq? msg expected actual)
-  (if (not (= expected actual))
-    (error "Error " msg ": expected " expected " got " actual)))
-
-(define area-pt (areapt))
-(define perim-pt (perimeterpt))
-
-(define s (new-Square 10))
-
-(check-eq? "Square area" 100.0 (do-op s area-pt))
-(check-eq? "Square perim" 40.0 (do-op s perim-pt))
-
-(check-eq? "Square area" 100.0 (do-op s (areavar)))
-(check-eq? "Square perim" 40.0 (do-op s (perimetervar)))
-
-;; Set areavar to return value of function
-(areavar perim-pt)
-(check-eq? "Square perim" 40 (do-op s (areavar)))
-
-(check-eq? "Square area" 100.0 (do-op s (AREAPT)))
-(check-eq? "Square perim" 40.0 (do-op s (PERIMPT)))
-
-(define test (NULLPT))
-
-(perimetervar (AREAPT))
-(check-eq? "Square area" 100.0 (do-op s (perimetervar)))
diff --git a/Examples/test-suite/chicken/multiple_inheritance_runme_proxy.ss b/Examples/test-suite/chicken/multiple_inheritance_runme_proxy.ss
deleted file mode 100644
index 313157c..0000000
--- a/Examples/test-suite/chicken/multiple_inheritance_runme_proxy.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(require 'multiple_inheritance)
-(load "../schemerunme/multiple_inheritance_proxy.scm")
diff --git a/Examples/test-suite/chicken/multivalue_runme.ss b/Examples/test-suite/chicken/multivalue_runme.ss
deleted file mode 100644
index f5aafcb..0000000
--- a/Examples/test-suite/chicken/multivalue_runme.ss
+++ /dev/null
@@ -1,4 +0,0 @@
-;; this doesn't work yet :(
-(load "multivalue.so")
-(include "../schemerunme/multivalue.scm")
-(exit 0)
diff --git a/Examples/test-suite/chicken/name_runme.ss b/Examples/test-suite/chicken/name_runme.ss
deleted file mode 100644
index 938915d..0000000
--- a/Examples/test-suite/chicken/name_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "name.so")
-(include "../schemerunme/name.scm")
diff --git a/Examples/test-suite/chicken/newobject1_runme_proxy.ss b/Examples/test-suite/chicken/newobject1_runme_proxy.ss
deleted file mode 100644
index 7bc5a24..0000000
--- a/Examples/test-suite/chicken/newobject1_runme_proxy.ss
+++ /dev/null
@@ -1,30 +0,0 @@
-(require 'newobject1)
-
-(define-macro (check-count val)
-  `(if (not (= (Foo-fooCount) ,val)) (error "Error checking val " ,val " != " ,(Foo-fooCount))))
-
-(define f (Foo-makeFoo))
-
-(check-count 1)
-
-(define f2 (makeMore f))
-
-(check-count 2)
-
-(set! f #f)
-(gc #t)
-
-(check-count 1)
-
-(define f3 (makeMore f2))
-
-(check-count 2)
-
-(set! f3 #f)
-(set! f2 #f)
-
-(gc #t)
-
-(check-count 0)
-
-(exit 0)
diff --git a/Examples/test-suite/chicken/newobject2_runme.ss b/Examples/test-suite/chicken/newobject2_runme.ss
deleted file mode 100644
index cc445f4..0000000
--- a/Examples/test-suite/chicken/newobject2_runme.ss
+++ /dev/null
@@ -1,29 +0,0 @@
-(load "newobject2.so")
-
-(define f (new-Foo))
-
-(Foo-dummy-set f 14)
-(if (not (= (Foo-dummy-get f) 14))
-  (error "Bad dummy value"))
-
-(if (not (= (fooCount) 0))
-  (error "Bad foo count 1"))
-
-(define f2 (makeFoo))
-
-(if (not (= (fooCount) 1))
-  (error "Bad foo count 2"))
-
-(Foo-dummy-set f2 16)
-(if (not (= (Foo-dummy-get f2) 16))
-  (error "Bad dummy value for f2"))
-
-(set! f #f)
-(set! f2 #f)
-
-(gc #t)
-
-(if (not (= (fooCount) -1))
-  (error "Bad foo count 3"))
-
-(exit 0)
diff --git a/Examples/test-suite/chicken/newobject2_runme_proxy.ss b/Examples/test-suite/chicken/newobject2_runme_proxy.ss
deleted file mode 100644
index 36b8cda..0000000
--- a/Examples/test-suite/chicken/newobject2_runme_proxy.ss
+++ /dev/null
@@ -1,29 +0,0 @@
-(load "newobject2.so")
-
-(define f (make <Foo>))
-
-(slot-set! f 'dummy 14)
-(if (not (= (slot-ref f 'dummy) 14))
-  (error "Bad dummy value"))
-
-(if (not (= (fooCount) 0))
-  (error "Bad foo count 1"))
-
-(define f2 (makeFoo))
-
-(if (not (= (fooCount) 1))
-  (error "Bad foo count 2"))
-
-(slot-set! f2 'dummy 16)
-(if (not (= (slot-ref f2 'dummy) 16))
-  (error "Bad dummy value for f2"))
-
-(set! f #f)
-(set! f2 #f)
-
-(gc #t)
-
-(if (not (= (fooCount) -1))
-  (error "Bad foo count 3"))
-
-(exit 0)
diff --git a/Examples/test-suite/chicken/overload_complicated_runme.ss b/Examples/test-suite/chicken/overload_complicated_runme.ss
deleted file mode 100644
index f89f70b..0000000
--- a/Examples/test-suite/chicken/overload_complicated_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "overload_complicated.so")
-(include "../schemerunme/overload_complicated.scm")
diff --git a/Examples/test-suite/chicken/overload_copy_runme.ss b/Examples/test-suite/chicken/overload_copy_runme.ss
deleted file mode 100644
index 4ec5422..0000000
--- a/Examples/test-suite/chicken/overload_copy_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "overload_copy.so")
-(include "../schemerunme/overload_copy.scm")
diff --git a/Examples/test-suite/chicken/overload_copy_runme_proxy.ss b/Examples/test-suite/chicken/overload_copy_runme_proxy.ss
deleted file mode 100644
index 5f48080..0000000
--- a/Examples/test-suite/chicken/overload_copy_runme_proxy.ss
+++ /dev/null
@@ -1,6 +0,0 @@
-(load "./overload_copy.so")
-
-(define f (make <Foo>))
-(define g (make <Foo> f))
-
-(exit 0)
diff --git a/Examples/test-suite/chicken/overload_extend_c_runme.ss b/Examples/test-suite/chicken/overload_extend_c_runme.ss
deleted file mode 100644
index 75c0ea8..0000000
--- a/Examples/test-suite/chicken/overload_extend_c_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "overload_extend_c.so")
-(include "../schemerunme/overload_extend_c.scm")
diff --git a/Examples/test-suite/chicken/overload_extend_runme.ss b/Examples/test-suite/chicken/overload_extend_runme.ss
deleted file mode 100644
index a19cb29..0000000
--- a/Examples/test-suite/chicken/overload_extend_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "overload_extend.so")
-(include "../schemerunme/overload_extend.scm")
diff --git a/Examples/test-suite/chicken/overload_extend_runme_proxy.ss b/Examples/test-suite/chicken/overload_extend_runme_proxy.ss
deleted file mode 100644
index 2a6867e..0000000
--- a/Examples/test-suite/chicken/overload_extend_runme_proxy.ss
+++ /dev/null
@@ -1,14 +0,0 @@
-(load "./overload_extend.so")
-
-(define f (make <Foo>))
-
-(if (not (= (test f 3) 1))
-  (error "test integer bad"))
-
-(if (not (= (test f "hello") 2))
-  (error "test string bad"))
-
-(if (not (= (test f 3.5 2.5) 6.0))
-  (error "test reals bad"))
-
-(exit 0)
diff --git a/Examples/test-suite/chicken/overload_simple_runme.ss b/Examples/test-suite/chicken/overload_simple_runme.ss
deleted file mode 100644
index 24fa67a..0000000
--- a/Examples/test-suite/chicken/overload_simple_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "overload_simple.so")
-(include "../schemerunme/overload_simple.scm")
diff --git a/Examples/test-suite/chicken/overload_simple_runme_proxy.ss b/Examples/test-suite/chicken/overload_simple_runme_proxy.ss
deleted file mode 100644
index 0ae3e62..0000000
--- a/Examples/test-suite/chicken/overload_simple_runme_proxy.ss
+++ /dev/null
@@ -1,56 +0,0 @@
-(load "overload_simple.so")
-
-(define-macro (check test)
-  `(if (not ,test) (error ',test)))
-
-(check (string=? (foo) "foo:"))
-(check (string=? (foo 3) "foo:int"))
-(check (string=? (foo 3.01) "foo:double"))
-(check (string=? (foo "hey") "foo:char *"))
-
-(define f (make <Foo>))
-(define b (make <Bar>))
-(define b2 (make <Bar> 3))
-
-(check (= (slot-ref b 'num) 0))
-(check (= (slot-ref b2 'num) 3))
-
-(check (string=? (foo f) "foo:Foo *"))
-(check (string=? (foo b) "foo:Bar *"))
-(check (string=? (foo f 3) "foo:Foo *,int"))
-(check (string=? (foo 3.2 b) "foo:double,Bar *"))
-
-;; now check blah
-(check (string=? (blah 2.01) "blah:double"))
-(check (string=? (blah "hey") "blah:char *"))
-
-;; now check spam member functions
-(define s (make <Spam>))
-(define s2 (make <Spam> 3))
-(define s3 (make <Spam> 3.2))
-(define s4 (make <Spam> "whee"))
-(define s5 (make <Spam> f))
-(define s6 (make <Spam> b))
-
-(check (string=? (slot-ref s 'type) "none"))
-(check (string=? (slot-ref s2 'type) "int"))
-(check (string=? (slot-ref s3 'type) "double"))
-(check (string=? (slot-ref s4 'type) "char *"))
-(check (string=? (slot-ref s5 'type) "Foo *"))
-(check (string=? (slot-ref s6 'type) "Bar *"))
-
-;; now check Spam member functions
-(check (string=? (foo s 2) "foo:int"))
-(check (string=? (foo s 2.1) "foo:double"))
-(check (string=? (foo s "hey") "foo:char *"))
-(check (string=? (foo s f) "foo:Foo *"))
-(check (string=? (foo s b) "foo:Bar *"))
-
-;; check static member funcs
-(check (string=? (Spam-bar 3) "bar:int"))
-(check (string=? (Spam-bar 3.2) "bar:double"))
-(check (string=? (Spam-bar "hey") "bar:char *"))
-(check (string=? (Spam-bar f) "bar:Foo *"))
-(check (string=? (Spam-bar b) "bar:Bar *"))
-
-(exit 0)
diff --git a/Examples/test-suite/chicken/overload_subtype_runme.ss b/Examples/test-suite/chicken/overload_subtype_runme.ss
deleted file mode 100644
index b3663b7..0000000
--- a/Examples/test-suite/chicken/overload_subtype_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "overload_subtype.so")
-(include "../schemerunme/overload_subtype.scm")
diff --git a/Examples/test-suite/chicken/overload_subtype_runme_proxy.ss b/Examples/test-suite/chicken/overload_subtype_runme_proxy.ss
deleted file mode 100644
index d83d59a..0000000
--- a/Examples/test-suite/chicken/overload_subtype_runme_proxy.ss
+++ /dev/null
@@ -1,12 +0,0 @@
-(load "./overload_subtype.so")
-
-(define f (make <Foo>))
-(define b (make <Bar>))
-
-(if (not (= (spam f) 1))
-  (error "Error in foo"))
-
-(if (not (= (spam b) 2))
-  (error "Error in bar"))
-
-(exit 0)
diff --git a/Examples/test-suite/chicken/pointer_in_out_runme.ss b/Examples/test-suite/chicken/pointer_in_out_runme.ss
deleted file mode 100644
index 807c4eb..0000000
--- a/Examples/test-suite/chicken/pointer_in_out_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "pointer_in_out.so")
-(include "../schemerunme/pointer_in_out.scm")
diff --git a/Examples/test-suite/chicken/reference_global_vars_runme.ss b/Examples/test-suite/chicken/reference_global_vars_runme.ss
deleted file mode 100644
index 1e1914b..0000000
--- a/Examples/test-suite/chicken/reference_global_vars_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "reference_global_vars.so")
-(include "../schemerunme/reference_global_vars.scm")
diff --git a/Examples/test-suite/chicken/testsuite.ss b/Examples/test-suite/chicken/testsuite.ss
deleted file mode 100644
index e1152a6..0000000
--- a/Examples/test-suite/chicken/testsuite.ss
+++ /dev/null
@@ -1,12 +0,0 @@
-(define (lookup-ext-tag tag)
-  (cond
-    ((equal? tag '(quote swig-contract-assertion-failed))
-      '( ((exn type) #f)) )
-    (#t '())))
-
-(define-macro (expect-throw tag-form form)
-  `(if (condition-case (begin ,form #t)
-         ,@(lookup-ext-tag tag-form)
-         ((exn) (print "The form threw a different error than expected: " ',form) (exit 1))
-         (var () (print "The form did not error as expected: " ',form) (exit 1)))
-   (begin (print "The form returned normally when it was expected to throw an error: " ',form) (exit 1))))
diff --git a/Examples/test-suite/chicken/throw_exception_runme.ss b/Examples/test-suite/chicken/throw_exception_runme.ss
deleted file mode 100644
index 62bc7be..0000000
--- a/Examples/test-suite/chicken/throw_exception_runme.ss
+++ /dev/null
@@ -1,29 +0,0 @@
-(load "throw_exception.so")
-
-(define-macro (check-throw expr check)
- `(if (handle-exceptions exvar (if ,check #f (begin (print "Error executing: " ',expr " " exvar) (exit 1))) ,expr #t)
-    (print "Expression did not throw an error: " ',expr)))
-
-(define f (new-Foo))
-
-(check-throw (Foo-test-int f) (= exvar 37))
-(check-throw (Foo-test-msg f) (string=? exvar "Dead"))
-(check-throw (Foo-test-cls f) (test-is-Error exvar))
-(check-throw (Foo-test-cls-ptr f) (test-is-Error exvar))
-(check-throw (Foo-test-cls-ref f) (test-is-Error exvar))
-(check-throw (Foo-test-cls-td f) (test-is-Error exvar))
-(check-throw (Foo-test-cls-ptr-td f) (test-is-Error exvar))
-(check-throw (Foo-test-cls-ref-td f) (test-is-Error exvar))
-(check-throw (Foo-test-enum f) (= exvar (enum2)))
-
-; don't know how to test this... it is returning a SWIG wrapped int *
-;(check-throw (Foo-test-array f) (equal? exvar '(0 1 2 3 4 5 6 7 8 9)))
-
-(check-throw (Foo-test-multi f 1) (= exvar 37))
-(check-throw (Foo-test-multi f 2) (string=? exvar "Dead"))
-(check-throw (Foo-test-multi f 3) (test-is-Error exvar))
-
-(set! f #f)
-(gc #t)
-
-(exit 0)
diff --git a/Examples/test-suite/chicken/typedef_inherit_runme.ss b/Examples/test-suite/chicken/typedef_inherit_runme.ss
deleted file mode 100644
index 111296d..0000000
--- a/Examples/test-suite/chicken/typedef_inherit_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "typedef_inherit.so")
-(include "../schemerunme/typedef_inherit.scm")
diff --git a/Examples/test-suite/chicken/typename_runme.ss b/Examples/test-suite/chicken/typename_runme.ss
deleted file mode 100644
index 60fc320..0000000
--- a/Examples/test-suite/chicken/typename_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "typename.so")
-(include "../schemerunme/typename.scm")
diff --git a/Examples/test-suite/chicken/unions_runme.ss b/Examples/test-suite/chicken/unions_runme.ss
deleted file mode 100644
index 465784a..0000000
--- a/Examples/test-suite/chicken/unions_runme.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "unions.so")
-(include "../schemerunme/unions.scm")
diff --git a/Examples/test-suite/chicken/unions_runme_proxy.ss b/Examples/test-suite/chicken/unions_runme_proxy.ss
deleted file mode 100644
index 4dd1414..0000000
--- a/Examples/test-suite/chicken/unions_runme_proxy.ss
+++ /dev/null
@@ -1,2 +0,0 @@
-(load "unions.so")
-(include "../schemerunme/unions_proxy.scm")
diff --git a/Examples/test-suite/chicken_ext_test.i b/Examples/test-suite/chicken_ext_test.i
deleted file mode 100644
index b4f726c..0000000
--- a/Examples/test-suite/chicken_ext_test.i
+++ /dev/null
@@ -1,21 +0,0 @@
-%module chicken_ext_test
-
-/* just use the imports_a.h header... for this test we only need a class */
-%{
-#include "imports_a.h"
-%}
-
-%include "imports_a.h"
-
-%{
-void test_create(C_word,C_word,C_word) C_noret;
-%}
-
-%init %{
- {
-    C_word *space = C_alloc(2 + C_SIZEOF_INTERNED_SYMBOL(11));
-    sym = C_intern (&space, 11, "test-create");
-    C_mutate ((C_word*)sym+1, (*space=C_CLOSURE_TYPE|1, space[1]=(C_word)test_create, tmp=(C_word)space, space+=2, tmp));
- }
-%}
-
diff --git a/Examples/test-suite/class_case.i b/Examples/test-suite/class_case.i
new file mode 100644
index 0000000..e9438d8
--- /dev/null
+++ b/Examples/test-suite/class_case.i
@@ -0,0 +1,18 @@
+%module class_case
+
+// Regression test for SWIG/Go bug #676
+
+%inline %{
+
+class ClassA {};
+
+class classB {};
+class classB2 : public classB {};
+
+int Test1(ClassA* a) { return 1; }
+int Test1(int i) { return 0; }
+
+int Test2(classB* a) { return 1; }
+int Test2(int i) { return 0; }
+
+%}
diff --git a/Examples/test-suite/class_scope_namespace.i b/Examples/test-suite/class_scope_namespace.i
index 47d9181..a24932a 100644
--- a/Examples/test-suite/class_scope_namespace.i
+++ b/Examples/test-suite/class_scope_namespace.i
@@ -15,6 +15,7 @@
     void aaa(Space1::SubSpace1::A, SubSpace1::A, A) {}
   }
 }
+void global_namespace_a(A*) {}
 
 namespace Space2 {
   struct B;
diff --git a/Examples/test-suite/class_scope_weird.i b/Examples/test-suite/class_scope_weird.i
index cc55dc8..d7409f2 100644
--- a/Examples/test-suite/class_scope_weird.i
+++ b/Examples/test-suite/class_scope_weird.i
@@ -3,22 +3,24 @@
 // Use this version with extra qualifiers to test SWIG as some compilers accept this
 class Foo {
 public:
-  Foo::Foo(void) {}
+  Foo::Foo() {}
   Foo::Foo(int) {}
   int Foo::bar(int x) {
     return x;
   }
+  void Foo::member() { }
 };
 
 // Remove extra qualifiers for the compiler as some compilers won't compile the extra qaulification (eg gcc-4.1 onwards) 
 %{
 class Foo {
 public:
-  Foo(void) {}
+  Foo() {}
   Foo(int) {}
   int bar(int x) {
     return x;
   }
+  void member() { }
 };
 %}
 
@@ -37,7 +39,7 @@
   Quat::Quat(const matrix4& m){}
 };
 
-// Remove extra qualifiers for the compiler as some compilers won't compile the extra qaulification (eg gcc-4.1 onwards) 
+// Remove extra qualifiers for the compiler as some compilers won't compile the extra qualification (eg gcc-4.1 onwards)
 %{
 class Quat {
 public:
diff --git a/Examples/test-suite/clientdata_prop_a.h b/Examples/test-suite/clientdata_prop_a.h
index 5f82e98..52c5406 100644
--- a/Examples/test-suite/clientdata_prop_a.h
+++ b/Examples/test-suite/clientdata_prop_a.h
@@ -6,7 +6,7 @@
 
 typedef A tA;
 
-void test_A(A *a) {}
-void test_tA(tA *a) {}
+inline void test_A(A *a) {}
+inline void test_tA(tA *a) {}
 
-tA *new_tA() { return new tA(); }
+inline tA *new_tA() { return new tA(); }
diff --git a/Examples/test-suite/clisp/Makefile.in b/Examples/test-suite/clisp/Makefile.in
deleted file mode 100644
index 3d20717..0000000
--- a/Examples/test-suite/clisp/Makefile.in
+++ /dev/null
@@ -1,51 +0,0 @@
-#######################################################################
-# Makefile for clisp test-suite
-#######################################################################
-
-LANGUAGE     = clisp
-CLISP        = @CLISPBIN@
-SCRIPTSUFFIX = _runme.lisp
-
-srcdir       = @srcdir@
-top_srcdir   = @top_srcdir@
-top_builddir = @top_builddir@
-
-include $(srcdir)/../common.mk
-
-# Overridden variables here
-# no C++ tests for now
-CPP_TEST_CASES =
-#C_TEST_CASES +=
-
-# Custom tests - tests with additional commandline options
-# none!
-
-# Rules for the different types of tests
-%.cpptest:
-	$(setup)
-	+$(swig_and_compile_cpp)
-	$(run_testcase)
-
-%.ctest:
-	$(setup)
-	+$(swig_and_compile_c)
-	$(run_testcase)
-
-%.multicpptest:
-	$(setup)
-	+$(swig_and_compile_multi_cpp)
-	$(run_testcase)
-
-# Runs the testcase. A testcase is only run if
-# a file is found which has _runme.lisp appended after the testcase name.
-run_testcase = \
-	if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
-	  env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(CLISP) -batch -s $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \
-	fi
-
-# Clean: (does nothing, we dont generate extra clisp code)
-%.clean:
-	@exit 0
-
-clean:
-	$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' clisp_clean
diff --git a/Examples/test-suite/command_line_define.i b/Examples/test-suite/command_line_define.i
new file mode 100644
index 0000000..86f45a9
--- /dev/null
+++ b/Examples/test-suite/command_line_define.i
@@ -0,0 +1,23 @@
+%module command_line_define
+
+// Test handling of -D without a value specified.
+
+#if FOO-0 != 1
+# error "-DFOO didn't set FOO to 1"
+#endif
+
+// Test handling of -D with a value specified
+
+#if BAR-0 != 123
+# error "-DBAR=123 didn't set BAR to 123"
+#endif
+
+// Test handling of -U
+
+#ifdef BAZ
+# error "-UBAZ didn't undefine BAZ"
+#endif
+
+#ifdef NOTSET
+# error "-UNOTSET resulted in NOTSET getting set!"
+#endif
diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index 5f77928..b75d7fe 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -88,11 +88,11 @@
 	extend_variable \
 	li_boost_shared_ptr_template \
 	nested_private \
-	rename_camel \
 	template_default_pointer \
-	template_private_assignment \
-	template_expr \
-	$(CPP11_TEST_BROKEN)
+	$(CPP11_TEST_BROKEN) \
+	$(CPP14_TEST_BROKEN) \
+	$(CPP17_TEST_BROKEN) \
+	$(CPP20_TEST_BROKEN)
 
 
 # Broken C test cases. (Can be run individually using: make testcase.ctest)
@@ -102,8 +102,10 @@
 # C++ test cases. (Can be run individually using: make testcase.cpptest)
 CPP_TEST_CASES += \
 	abstract_access \
+	abstract_basecast \
 	abstract_inherit \
 	abstract_inherit_ok \
+	abstract_inherit_using \
 	abstract_signature \
 	abstract_typedef \
 	abstract_typedef2 \
@@ -117,6 +119,7 @@
 	anonymous_bitfield \
 	apply_signed_char \
 	apply_strings \
+	argcargvtest \
 	argout \
 	array_member \
 	array_typedef_memberin \
@@ -125,15 +128,20 @@
 	arrays_global \
 	arrays_global_twodim \
 	arrays_scope \
+	assign_const \
+	assign_reference \
 	autodoc \
+	begin_code \
 	bloody_hell \
 	bools \
 	catches \
+	catches_strings \
 	cast_operator \
 	casts \
 	char_binary \
 	char_strings \
 	chartest \
+	class_case \
 	class_scope_namespace \
 	class_forward \
 	class_ignore \
@@ -141,9 +149,11 @@
 	compactdefaultargs \
 	const_const_2 \
 	constant_directive \
+	constant_expr \
 	constant_pointers \
 	constover \
 	constructor_copy \
+	constructor_copy_non_const \
 	constructor_exception \
 	constructor_explicit \
 	constructor_ignore \
@@ -154,18 +164,15 @@
 	conversion_namespace \
 	conversion_ns_template \
 	conversion_operators \
+	copyctor \
 	cplusplus_throw \
 	cpp_basic \
 	cpp_enum \
 	cpp_namespace \
 	cpp_nodefault \
+	cpp_parameters \
 	cpp_static \
 	cpp_typedef \
-	cpp14_binary_integer_literals \
-	cpp17_hex_floating_literals \
-	cpp17_nested_namespaces \
-	cpp17_nspace_nested_namespaces \
-	cpp17_u8_char_literals \
 	curiously_recurring_template_pattern \
 	default_args \
 	default_arg_expressions \
@@ -183,6 +190,8 @@
 	director_classes \
 	director_classic \
 	director_constructor \
+	director_comparison_operators \
+	director_conversion_operators \
 	director_default \
 	director_detect \
 	director_enum \
@@ -194,6 +203,7 @@
 	director_frob \
 	director_ignore \
 	director_keywords \
+	director_multiple_inheritance \
 	director_namespace_clash \
 	director_nested \
 	director_nspace \
@@ -208,13 +218,19 @@
 	director_protected_overloaded \
 	director_redefined \
 	director_ref \
+	director_simple \
 	director_smartptr \
+	director_template \
 	director_thread \
 	director_unroll \
+	director_unwrap_result \
 	director_using \
+	director_using_member_scopes \
 	director_void \
 	director_wombat \
 	disown \
+	duplicate_class_name_in_ns \
+	duplicate_parm_names \
 	dynamic_cast \
 	empty \
 	enum_ignore \
@@ -229,6 +245,7 @@
 	evil_diamond_ns \
 	evil_diamond_prop \
 	exception_classname \
+	exception_memory_leak \
 	exception_order \
 	extend \
 	extend_constructor_destructor \
@@ -246,10 +263,12 @@
 	features \
 	fragments \
 	friends \
+	friends_operator_overloading \
 	friends_template \
 	funcptr_cpp \
 	functors \
 	fvirtual \
+	global_immutable_vars_cpp \
 	global_namespace \
 	global_ns_arg \
 	global_scope_types \
@@ -299,6 +318,7 @@
 	multiple_inheritance_abstract \
 	multiple_inheritance_interfaces \
 	multiple_inheritance_nspace \
+	multiple_inheritance_overload \
 	multiple_inheritance_shared_ptr \
 	name_cxx \
 	name_warnings \
@@ -309,6 +329,7 @@
 	namespace_forward_declaration \
 	namespace_nested \
 	namespace_spaces \
+	namespace_struct \
 	namespace_template \
 	namespace_typedef_class \
 	namespace_typemap \
@@ -326,12 +347,13 @@
 	nested_ignore \
 	nested_inheritance_interface \
 	nested_in_template \
-	nested_scope \
+	nested_scope_flat \
 	nested_template_base \
 	nested_workaround \
 	newobject1 \
 	newobject3 \
 	null_pointer \
+	numeric_bounds_checking \
 	operator_overload \
 	operator_overload_break \
 	operator_pointer_ref \
@@ -354,6 +376,8 @@
 	overload_template_fast \
 	pointer_reference \
 	preproc_constants \
+	preproc_cpp \
+	preproc_predefined_stdcpp \
 	primitive_ref \
 	private_assign \
 	proxycode \
@@ -367,6 +391,7 @@
 	rename2 \
 	rename3 \
 	rename4 \
+	rename_camel \
 	rename_rstrip_encoder \
 	rename_scope \
 	rename_simple \
@@ -414,6 +439,7 @@
 	struct_value \
 	swig_exception \
 	symbol_clash \
+	sym \
 	template_arg_replace \
 	template_arg_scope \
 	template_arg_typename \
@@ -437,15 +463,18 @@
 	template_default_inherit \
 	template_default_qualify \
 	template_default_vw \
+	template_duplicate \
 	template_empty_inherit \
 	template_enum \
 	template_enum_ns_inherit \
 	template_enum_typedef \
 	template_explicit \
+	template_expr \
 	template_extend1 \
 	template_extend2 \
 	template_extend_overload \
 	template_extend_overload_2 \
+	template_function_parm \
 	template_forward \
 	template_inherit \
 	template_inherit_abstract \
@@ -453,9 +482,12 @@
 	template_keyword_in_type \
 	template_methods \
 	template_namespace_forward_declaration \
+	template_private_assignment \
 	template_using_directive_and_declaration_forward \
 	template_using_directive_typedef \
+	template_using_member_default_arg \
 	template_nested \
+	template_nested_flat \
 	template_nested_typemaps \
 	template_ns \
 	template_ns2 \
@@ -468,6 +500,7 @@
 	template_parameters_global_scope \
 	template_partial_arg \
 	template_partial_specialization \
+	template_partial_specialization_more \
 	template_partial_specialization_typedef \
 	template_qualifier \
 	template_ref_type \
@@ -476,9 +509,12 @@
 	template_specialization \
 	template_specialization_defarg \
 	template_specialization_enum \
+	template_specialization_using_declaration \
 	template_static \
 	template_tbase_template \
 	template_template_parameters \
+	template_template_template_parameters \
+	template_type_collapse \
 	template_typedef \
 	template_typedef_class_template \
 	template_typedef_cplx \
@@ -541,6 +577,9 @@
 	using_directive_and_declaration_forward \
 	using_extend \
 	using_inherit \
+	using_member \
+	using_member_multiple_inherit \
+	using_member_scopes \
 	using_namespace \
 	using_namespace_loop \
 	using_pointers \
@@ -566,13 +605,21 @@
 	cpp11_alias_nested_template_scoping \
 	cpp11_alignment \
 	cpp11_alternate_function_syntax \
+	cpp11_assign_delete \
+	cpp11_assign_rvalue_reference \
+	cpp11_attribute_specifiers \
+	cpp11_auto_variable \
+	cpp11_brackets_expression \
 	cpp11_constexpr \
+	cpp11_copyctor_delete \
 	cpp11_decltype \
 	cpp11_default_delete \
 	cpp11_delegating_constructors \
 	cpp11_director_enums \
+	cpp11_director_using_constructor \
 	cpp11_directors \
 	cpp11_explicit_conversion_operators \
+	cpp11_final_class \
 	cpp11_final_directors \
 	cpp11_final_override \
 	cpp11_function_objects \
@@ -580,6 +627,9 @@
 	cpp11_initializer_list \
 	cpp11_initializer_list_extend \
 	cpp11_lambda_functions \
+        cpp11_move_only \
+        cpp11_move_typemaps \
+        cpp11_move_only_valuewrapper \
 	cpp11_noexcept \
 	cpp11_null_pointer_constant \
 	cpp11_raw_string_literals \
@@ -590,38 +640,82 @@
 	cpp11_rvalue_reference \
 	cpp11_rvalue_reference2 \
 	cpp11_rvalue_reference3 \
+	cpp11_rvalue_reference_move \
 	cpp11_sizeof_object \
 	cpp11_static_assert \
 	cpp11_std_array \
+	cpp11_std_unique_ptr \
 	cpp11_strongly_typed_enumerations \
 	cpp11_thread_local \
 	cpp11_template_double_brackets \
 	cpp11_template_explicit \
+	cpp11_template_parameters_decltype \
+	cpp11_template_templated_methods \
 	cpp11_template_typedefs \
 	cpp11_type_traits \
 	cpp11_type_aliasing \
 	cpp11_uniform_initialization \
 	cpp11_unrestricted_unions \
 	cpp11_userdefined_literals \
+	cpp11_using_constructor \
+	cpp11_using_typedef_struct \
+	cpp11_variadic_function_templates \
+	cpp11_variadic_templates \
 
 # Broken C++11 test cases.
 CPP11_TEST_BROKEN = \
-#	cpp11_variadic_templates \    # Broken for some languages (such as Java)
 #	cpp11_reference_wrapper \     # No typemaps
 
+# C++14 test cases.
+CPP14_TEST_CASES += \
+	cpp14_auto_return_type \
+	cpp14_binary_integer_literals \
+
+# Broken C++14 test cases.
+CPP14_TEST_BROKEN = \
+
+# C++17 test cases.
+CPP17_TEST_CASES += \
+	cpp17_director_string_view \
+	cpp17_enable_if_t \
+	cpp17_hex_floating_literals \
+	cpp17_map_no_default_ctor \
+	cpp17_nested_namespaces \
+	cpp17_nspace_nested_namespaces \
+	cpp17_string_view \
+	cpp17_u8_char_literals \
+
+# Broken C++17 test cases.
+CPP17_TEST_BROKEN = \
+
+# C++20 test cases.
+CPP20_TEST_CASES += \
+	cpp20_constexpr_destructor \
+	cpp20_lambda_template \
+	cpp20_spaceship_operator \
+
+# Broken C++20 test cases.
+CPP20_TEST_BROKEN = \
+
 # Doxygen support test cases: can only be used with languages supporting
-# Doxygen comment translation, currently only Python and Java.
+# Doxygen comment translation (currently Python and Java) and only if not
+# disabled by configure via SKIP_DOXYGEN_TEST_CASES.
+ifneq ($(SKIP_DOXYGEN_TEST_CASES),1)
 python_HAS_DOXYGEN := 1
 java_HAS_DOXYGEN := 1
 
 $(eval HAS_DOXYGEN := $($(LANGUAGE)_HAS_DOXYGEN))
+endif
 
 ifdef HAS_DOXYGEN
 DOXYGEN_TEST_CASES += \
 	doxygen_alias \
+	doxygen_autodoc_docstring \
 	doxygen_basic_notranslate \
 	doxygen_basic_translate \
 	doxygen_basic_translate_style2 \
+	doxygen_basic_translate_style3 \
+	doxygen_code_blocks \
 	doxygen_ignore \
 	doxygen_misc_constructs \
 	doxygen_nested_class \
@@ -656,6 +750,7 @@
 	li_std_vector_enum \
 	li_std_vector_member_var\
 	li_std_vector_ptr \
+	li_std_vector_vector \
 	li_std_wstring \
 	smart_pointer_inherit \
 	template_typedef_fnc \
@@ -666,10 +761,22 @@
 CPP_TEST_CASES += ${CPP_STD_TEST_CASES}
 endif
 
-ifneq (,$(HAVE_CXX11_COMPILER))
+ifeq (1,$(HAVE_CXX11))
 CPP_TEST_CASES += $(CPP11_TEST_CASES)
 endif
 
+ifeq (1,$(HAVE_CXX14))
+CPP_TEST_CASES += $(CPP14_TEST_CASES)
+endif
+
+ifeq (1,$(HAVE_CXX17))
+CPP_TEST_CASES += $(CPP17_TEST_CASES)
+endif
+
+ifeq (1,$(HAVE_CXX20))
+CPP_TEST_CASES += $(CPP20_TEST_CASES)
+endif
+
 # C test cases. (Can be run individually using: make testcase.ctest)
 C_TEST_CASES += \
 	arrays \
@@ -677,8 +784,10 @@
 	c_delete \
 	c_delete_function \
 	char_constant \
+	command_line_define \
 	const_const \
-	constant_expr \
+	constant_expr_c \
+	contract_c \
 	default_args_c \
 	empty_c \
 	enums \
@@ -686,9 +795,11 @@
 	enum_macro \
 	enum_missing \
 	extern_declaration \
+	final_c \
 	funcptr \
 	function_typedef \
 	global_functions \
+	global_immutable_vars \
 	immutable_values \
 	inctest \
 	infinity \
@@ -708,14 +819,18 @@
 	nested_extend_c \
 	nested_structs \
 	newobject2 \
+	not_c_keywords \
 	overload_extend_c \
 	overload_extend2 \
 	preproc \
 	preproc_constants_c \
 	preproc_defined \
+	preproc_expr \
 	preproc_gcc_output \
 	preproc_include \
 	preproc_line_file \
+	preproc_predefined \
+	preproc_predefined_stdc \
 	register_par \
 	ret_by_value \
 	simple_array \
@@ -744,10 +859,17 @@
 # Custom tests - tests with additional commandline options
 wallkw.cpptest: SWIGOPT += -Wallkw
 preproc_include.ctest: SWIGOPT += -includeall
+command_line_define.ctest: SWIGOPT += -DFOO -DBAR=123 -DBAZ -UBAZ -UNOTSET
+preproc_predefined_stdc.ctest: SWIGOPT += -std=c23
+preproc_predefined_stdcpp.cpptest: SWIGOPT += -std=c++23
 
 # Allow modules to define temporarily failing tests.
 C_TEST_CASES := $(filter-out $(FAILING_C_TESTS),$(C_TEST_CASES))
 CPP_TEST_CASES := $(filter-out $(FAILING_CPP_TESTS),$(CPP_TEST_CASES))
+CPP11_TEST_CASES := $(filter-out $(FAILING_CPP_TESTS),$(CPP11_TEST_CASES))
+CPP14_TEST_CASES := $(filter-out $(FAILING_CPP_TESTS),$(CPP14_TEST_CASES))
+CPP17_TEST_CASES := $(filter-out $(FAILING_CPP_TESTS),$(CPP17_TEST_CASES))
+CPP20_TEST_CASES := $(filter-out $(FAILING_CPP_TESTS),$(CPP20_TEST_CASES))
 MULTI_CPP_TEST_CASES := $(filter-out $(FAILING_MULTI_CPP_TESTS),$(MULTI_CPP_TEST_CASES))
 
 
@@ -760,6 +882,10 @@
 			$(C_TEST_BROKEN:=.ctest)
 
 ALL_CLEAN = 		$(CPP_TEST_CASES:=.clean) \
+			$(CPP11_TEST_CASES:=.clean) \
+			$(CPP14_TEST_CASES:=.clean) \
+			$(CPP17_TEST_CASES:=.clean) \
+			$(CPP20_TEST_CASES:=.clean) \
 			$(C_TEST_CASES:=.clean) \
 			$(MULTI_CPP_TEST_CASES:=.clean) \
 			$(CPP_TEST_BROKEN:=.clean) \
@@ -788,6 +914,14 @@
 
 check-cpp11: $(CPP11_TEST_CASES:=.cpptest)
 
+check-cpp14: $(CPP14_TEST_CASES:=.cpptest)
+
+check-cpp17: $(CPP17_TEST_CASES:=.cpptest)
+
+check-cpp20: $(CPP20_TEST_CASES:=.cpptest)
+
+check-multicpp: $(MULTI_CPP_TEST_CASES:=.multicpptest)
+
 ifdef HAS_DOXYGEN
 check-doxygen: $(DOXYGEN_TEST_CASES:=.cpptest)
 endif
@@ -805,6 +939,14 @@
 partialcheck:
 	$(MAKE) check CC=true CXX=true LDSHARED=true CXXSHARED=true RUNTOOL=true COMPILETOOL=true
 
+swig_and_compile_cpp_helper = \
+	$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
+	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
+	LIBS='$(LIBS)' INCLUDES='$(INCLUDES)' SWIGOPT=$(2) NOLINK=true \
+	TARGET="$(TARGETPREFIX)$(1)$(TARGETSUFFIX)" INTERFACEDIR='$(INTERFACEDIR)' INTERFACE="$(1).i" \
+	EXTRA_CXXFLAGS="$(3)" \
+	$(LANGUAGE)$(VARIANT)_cpp
+
 swig_and_compile_cpp =  \
 	$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
 	SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
@@ -821,11 +963,7 @@
 
 swig_and_compile_multi_cpp = \
 	for f in `cat $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list` ; do \
-	  $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
-	  SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	  LIBS='$(LIBS)' INCLUDES='$(INCLUDES)' SWIGOPT='$(SWIGOPT)' NOLINK=true \
-	  TARGET="$(TARGETPREFIX)$${f}$(TARGETSUFFIX)" INTERFACEDIR='$(INTERFACEDIR)' INTERFACE="$$f.i" \
-	  $(LANGUAGE)$(VARIANT)_cpp; \
+	  $(call swig_and_compile_cpp_helper,$${f},'$(SWIGOPT)'); \
 	done
 
 swig_and_compile_external =  \
@@ -848,8 +986,6 @@
 	  echo "$(ACTION)ing $(LANGUAGE) testcase $*" ;		  \
 	fi
 
-
-
 #######################################################################
 # Clean
 #######################################################################
diff --git a/Examples/test-suite/complextest.i b/Examples/test-suite/complextest.i
index 592512b..6c7b1f4 100644
--- a/Examples/test-suite/complextest.i
+++ b/Examples/test-suite/complextest.i
@@ -2,7 +2,6 @@
 
 %include <complex.i>
 
-#ifdef __cplusplus
 %{
 #include <algorithm>
 #include <functional>
@@ -10,9 +9,7 @@
 %}
 %include <std_vector.i>
 
-#if 1
 %template(VectorStdCplx) std::vector<std::complex<double> >;
-#endif
 
 %inline
 {
@@ -63,26 +60,3 @@
   }
 }
 
-
-#else
-
-
-%{
-%}
-
-%inline
-{
-  complex Conj(complex a)
-  {
-    return conj(a);
-  }
-
-
-  complex float Conjf(float complex a)
-  {
-    return conj(a);
-  }
-}
-
-
-#endif
diff --git a/Examples/test-suite/constant_directive.i b/Examples/test-suite/constant_directive.i
index 3e4775d..f30123b 100644
--- a/Examples/test-suite/constant_directive.i
+++ b/Examples/test-suite/constant_directive.i
@@ -52,3 +52,13 @@
 /* Regular constant */
 %constant int TYPE_INT = 0;
 %constant enum EnumType newValue = enumValue;
+
+/* Test handling of %constant with an implicit type which SWIG can't handle. */
+#pragma SWIG nowarn=SWIGWARN_PARSE_UNSUPPORTED_VALUE
+%ignore ignored_int_variable;
+%inline %{
+int ignored_int_variable = 42;
+%}
+%constant unsupported_constant_value1 = &ignored_int_variable;
+%constant unsupported_constant_value2 = getType1Instance;
+%constant unsupported_constant_value3 = &getType1Instance;
diff --git a/Examples/test-suite/constant_expr.i b/Examples/test-suite/constant_expr.i
index 8e5c8ae..a5ba5c6 100644
--- a/Examples/test-suite/constant_expr.i
+++ b/Examples/test-suite/constant_expr.i
@@ -1,11 +1,37 @@
 %module constant_expr;
-/* Tests of constant expressions. */
+/* Tests of constant expressions (C++ version). */
+
+%include "constant_expr_c.i"
 
 %inline %{
 
-/* % didn't work in SWIG 1.3.40 and earlier. */
-const int X = 123%7;
-#define FOO 12 % 9
-double d_array[12 % 9];
+// Testcase from https://sourceforge.net/p/swig/bugs/1139/
+template<typename Tp>
+struct SizeInfo {
+enum {
+isLarge = (sizeof(Tp)>sizeof(void*)),
+isPointer = false
+};
+};
+
+/* Regression test for #300, fixed in 4.1.0.
+ *
+ * Now `a%b` without a space after the `%` is handled as a modulus operator,
+ * but it gave a cryptic `Syntax error in input(1)` before SWIG 3.0.4, and from
+ * SWIG 3.0.4 until 4.1.0, `Unknown directive '%a'`.
+ */
+int a;
+int test2(int b = 9%a) { return b; }
+
+/* Example from manual, adapted to avoid C++11 requirement. */
+namespace fakestd {
+  template<typename T, unsigned N>
+  class array {
+      T a[N];
+    public:
+      array() {}
+  };
+}
+void bar(fakestd::array<int, (1<2? 100 : 50)> *x) { }
 
 %}
diff --git a/Examples/test-suite/constant_expr_c.i b/Examples/test-suite/constant_expr_c.i
new file mode 100644
index 0000000..41c4749
--- /dev/null
+++ b/Examples/test-suite/constant_expr_c.i
@@ -0,0 +1,72 @@
+%module constant_expr_c;
+/* Tests of constant expressions (C version). */
+
+%inline %{
+#if defined __GNUC__ && __GNUC__ >= 5
+// Suppress warnings about constant comparisons.
+# pragma GCC diagnostic ignored "-Wbool-compare"
+#endif
+
+#if defined(_MSC_VER)
+  #pragma warning(disable : 4804) // warning C4804: '<': unsafe use of type 'bool' in operation
+#endif
+
+/* % didn't work in SWIG 1.3.40 and earlier. */
+const int X = 123%7;
+#define FOO 12 % 9
+double d_array[12 % 9];
+
+/* `<` and `>` in constant expressions caused parse errors before SWIG 4.1.0.
+ * They're now supported if inside parentheses (and with some restrictions
+ * on the LHS of `<`.
+ */
+
+// Testcase from https://github.com/swig/swig/issues/635
+#define TEST_A 1
+#define TEST_B 2
+#define TEST_C (TEST_A < TEST_B)
+#define TEST_D (TEST_A > TEST_B)
+// These have been supported since 1.3.41.
+#define TEST_E (TEST_A <= TEST_B)
+#define TEST_F (TEST_A >= TEST_B)
+// For completeness
+#define TEST_G (TEST_A == TEST_B)
+#define TEST_H (TEST_A != TEST_B)
+
+// No warning
+#if (TEST_A < TEST_B)
+#define TEST_I 1
+#else
+#define TEST_I 0
+#endif
+
+/* Regression test for bug with losing parentheses around < and > operators,
+ * fixed in 4.2.0.
+ */
+#define XX (2<(2<2))
+#define YY (2>(2>2))
+int xx() { return (int)(XX); }
+int yy() { return (int)(YY); }
+
+/* sizeof didn't work on an expression before SWIG 4.1.0 except for cases where
+ * the expression was in parentheses and looked syntactically like a type (so
+ * sizeof(X) worked because X could be a type syntactically).
+ */
+const int s1a = sizeof(X); /* worked before 4.1.0 */
+//const int s1b = sizeof X; /* not currently supported */
+const int s2a = sizeof("a string" );
+const int s2b = sizeof "a string";
+const int s3a = sizeof('c');
+const int s3b = sizeof('c');
+const int s4a = sizeof(L"a wstring");
+const int s4b = sizeof L"a wstring";
+const int s5a = sizeof(L'C');
+const int s5b = sizeof L'C';
+const int s6a = sizeof(sizeof(X));
+const int s6b = sizeof sizeof(X);
+const int s7a = sizeof(3.14);
+const int s7b = sizeof 3.14;
+const int s8a = sizeof(2.1e-6);
+const int s8b = sizeof 2.1e-6;
+
+%}
diff --git a/Examples/test-suite/constant_pointers.i b/Examples/test-suite/constant_pointers.i
index 9094e9d..1e03b29 100644
--- a/Examples/test-suite/constant_pointers.i
+++ b/Examples/test-suite/constant_pointers.i
@@ -53,8 +53,6 @@
     int* array_member1[ARRAY_SIZE];
     ParametersTest* array_member2[ARRAY_SIZE];
     MemberVariablesTest() : member3(NULL), member4(NULL) {}
-private:
-  MemberVariablesTest& operator=(const MemberVariablesTest&);
 };
 void foofunction(const int *const i) {}
 
@@ -80,8 +78,6 @@
     void ret8(int*const& a) {}
     int*const& ret9() {return GlobalIntPtr;}
     ReturnValuesTest() : int3(NULL) {}
-private:
-  ReturnValuesTest& operator=(const ReturnValuesTest&);
 };
 
 const int* globalRet1() {return &GlobalInt;}
@@ -113,8 +109,6 @@
     A* ap;
     const A* cap;
     Acptr acptr;  
-  private:
-    B& operator=(const B&);
   };
 
   const B* bar(const B* b) {
diff --git a/Examples/test-suite/constructor_copy_non_const.i b/Examples/test-suite/constructor_copy_non_const.i
new file mode 100644
index 0000000..a8b9b09
--- /dev/null
+++ b/Examples/test-suite/constructor_copy_non_const.i
@@ -0,0 +1,71 @@
+%module(ruby_minherit="1") constructor_copy_non_const
+
+// Tests %copyctor and non-const copy constructors in inheritance chain
+
+%warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE,
+	    SWIGWARN_CSHARP_MULTIPLE_INHERITANCE,
+	    SWIGWARN_D_MULTIPLE_INHERITANCE,
+	    SWIGWARN_PHP_MULTIPLE_INHERITANCE) CCDerived; /* C#, D, Java, PHP multiple inheritance */
+%warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE,
+	    SWIGWARN_CSHARP_MULTIPLE_INHERITANCE,
+	    SWIGWARN_D_MULTIPLE_INHERITANCE,
+	    SWIGWARN_PHP_MULTIPLE_INHERITANCE) CCProtectedDerived; /* C#, D, Java, PHP multiple inheritance */
+
+%inline %{
+  struct CCBase1 {
+    CCBase1() {}
+  };
+%}
+
+%copyctor;
+
+%inline %{
+  struct CCBase2 {
+    CCBase2() {}
+    CCBase2(CCBase2& other) {} // non-const copyctor
+  };
+
+  struct CCDerived : CCBase1, CCBase2 {
+    CCDerived() {}
+    // implicitly declared non-const copyctor
+  };
+  struct CCMoreDerived : CCDerived {
+    // implicitly declared default ctor
+    // implicitly declared non-const copyctor
+  };
+  struct CCMoreDerived2 : CCDerived {
+    CCMoreDerived2() {}
+    CCMoreDerived2(const CCMoreDerived2& other) {} // const copyctor
+  };
+  struct CCMoreMoreDerived2 : CCMoreDerived2 {
+    // implicitly declared default ctor
+    // implicitly declared const copyctor
+  };
+%}
+
+
+// Repeat but with protected non-const copyctor
+%inline %{
+  struct CCProtectedBase2 {
+    CCProtectedBase2() {}
+  protected:
+    CCProtectedBase2(CCProtectedBase2& other) {} // non-const copyctor
+  };
+
+  struct CCProtectedDerived : CCBase1, CCProtectedBase2 {
+    CCProtectedDerived() {}
+    // implicitly declared non-const copyctor
+  };
+  struct CCProtectedMoreDerived : CCProtectedDerived {
+    // implicitly declared default ctor
+    // implicitly declared non-const copyctor
+  };
+  struct CCProtectedMoreDerived2 : CCProtectedDerived {
+    CCProtectedMoreDerived2() {}
+    CCProtectedMoreDerived2(const CCProtectedMoreDerived2& other) {} // const copyctor
+  };
+  struct CCProtectedMoreMoreDerived2 : CCProtectedMoreDerived2 {
+    // implicitly declared default ctor
+    // implicitly declared const copyctor
+  };
+%}
diff --git a/Examples/test-suite/contract.i b/Examples/test-suite/contract.i
index 0ad7e8e..de662c1 100644
--- a/Examples/test-suite/contract.i
+++ b/Examples/test-suite/contract.i
@@ -48,6 +48,7 @@
 }
 %}
 
+#ifdef __cplusplus
 /* Class tests */
 
 %contract Foo::test_preassert(int x, int y) {
@@ -235,4 +236,4 @@
 };
 
 }
-
+#endif
diff --git a/Examples/test-suite/contract_c.i b/Examples/test-suite/contract_c.i
new file mode 100644
index 0000000..465a7de
--- /dev/null
+++ b/Examples/test-suite/contract_c.i
@@ -0,0 +1,5 @@
+%module contract_c;
+
+%include <exception.i>
+
+%include "contract.i"
diff --git a/Examples/test-suite/copyctor.i b/Examples/test-suite/copyctor.i
new file mode 100644
index 0000000..6153be3
--- /dev/null
+++ b/Examples/test-suite/copyctor.i
@@ -0,0 +1,22 @@
+%module copyctor
+
+%copyctor;
+
+%inline %{
+struct Bar {};
+struct Car {};
+
+struct Foo {
+    Foo() {}
+    template <class T> Foo(const T* p) {}
+    Foo(const Bar& other) {}
+};
+
+struct Hoo {
+    Hoo() {}
+    template <class T> Hoo(const T* p) {}
+    Hoo(const Bar& other) {}
+};
+%}
+
+%template(Hoo) Hoo::Hoo<Car>;
diff --git a/Examples/test-suite/cpp11_alternate_function_syntax.i b/Examples/test-suite/cpp11_alternate_function_syntax.i
index b3ecabc..2f5aaa4 100644
--- a/Examples/test-suite/cpp11_alternate_function_syntax.i
+++ b/Examples/test-suite/cpp11_alternate_function_syntax.i
@@ -3,6 +3,8 @@
 %module cpp11_alternate_function_syntax
 
 %inline %{
+struct Hello {};
+
 struct SomeStruct {
   int addNormal(int x, int y);
   auto addAlternate(int x, int y) -> int;
@@ -12,6 +14,9 @@
   auto addAlternateMemberPtrParm(int x, int (SomeStruct::*mp)(int, int)) -> int;
   auto addAlternateMemberPtrConstParm(int x, int (SomeStruct::*mp)(int, int) const) const -> int;
 
+  // Returning a reference didn't parse in SWIG < 4.1.0 (#231)
+  auto output() -> Hello&;
+
   virtual auto addFinal(int x, int y) const noexcept -> int final { return x + y; }
   virtual ~SomeStruct() = default;
 };
@@ -27,5 +32,6 @@
 auto SomeStruct::addAlternateMemberPtrConstParm(int x, int (SomeStruct::*mp)(int, int) const) const -> int {
   return 1000*x + (this->*mp)(x, x);
 }
+auto SomeStruct::output() -> Hello& { static Hello h; return h; }
 
 %}
diff --git a/Examples/test-suite/cpp11_assign_delete.i b/Examples/test-suite/cpp11_assign_delete.i
new file mode 100644
index 0000000..dd2b180
--- /dev/null
+++ b/Examples/test-suite/cpp11_assign_delete.i
@@ -0,0 +1,172 @@
+%module cpp11_assign_delete
+
+%rename(Assign) *::operator=;
+
+// (1) Test directly non-assignable member variables
+%inline %{
+struct AssignPublic {
+  AssignPublic& operator=(const AssignPublic &) = delete;
+};
+
+struct AssignProtected {
+protected:
+  AssignProtected& operator=(const AssignProtected &) = delete;
+};
+
+struct AssignPrivate {
+private:
+  AssignPrivate& operator=(const AssignPrivate &) = delete;
+};
+
+struct MemberVars {
+  // These will only have getters
+  AssignPublic MemberPublic;
+  AssignProtected MemberProtected;
+  AssignPrivate MemberPrivate;
+};
+
+struct MemberArrayVars {
+  // These will only have getters
+  AssignPublic ArrayMemberPublic[1];
+  AssignProtected ArrayMemberProtected[1];
+  AssignPrivate ArrayMemberPrivate[1];
+};
+
+// (2) Test indirectly non-assignable member variables via inheritance
+struct AssignPublicDerived : AssignPublic {};
+struct AssignProtectedDerived : AssignProtected {};
+struct AssignPrivateDerived : AssignPrivate {};
+struct AssignPublicDerivedSettable : AssignPublic {
+  AssignPublicDerivedSettable& operator=(const AssignPublicDerivedSettable &) { return *this; }
+};
+struct AssignProtectedDerivedSettable : AssignProtected {
+  AssignProtectedDerivedSettable& operator=(const AssignProtectedDerivedSettable &) { return *this; }
+};
+struct AssignPrivateDerivedSettable : AssignPrivate {
+  AssignPrivateDerivedSettable& operator=(const AssignPrivateDerivedSettable &) { return *this; }
+};
+
+struct InheritedMemberVars {
+  // These will only have getters
+  AssignPublicDerived MemberPublicDerived;
+  AssignProtectedDerived MemberProtectedDerived;
+  AssignPrivateDerived MemberPrivateDerived;
+
+  static AssignPublicDerived StaticMemberPublicDerived;
+  static AssignProtectedDerived StaticMemberProtectedDerived;
+  static AssignPrivateDerived StaticMemberPrivateDerived;
+
+  // These will have getters and setters
+  AssignPublicDerivedSettable MemberPublicDerivedSettable;
+  AssignProtectedDerivedSettable MemberProtectedDerivedSettable;
+  AssignPrivateDerivedSettable MemberPrivateDerivedSettable;
+
+  static AssignPublicDerivedSettable StaticMemberPublicDerivedSettable;
+  static AssignProtectedDerivedSettable StaticMemberProtectedDerivedSettable;
+  static AssignPrivateDerivedSettable StaticMemberPrivateDerivedSettable;
+};
+
+AssignPublicDerived InheritedMemberVars::StaticMemberPublicDerived;
+AssignProtectedDerived InheritedMemberVars::StaticMemberProtectedDerived;
+AssignPrivateDerived InheritedMemberVars::StaticMemberPrivateDerived;
+
+AssignPublicDerivedSettable InheritedMemberVars::StaticMemberPublicDerivedSettable;
+AssignProtectedDerivedSettable InheritedMemberVars::StaticMemberProtectedDerivedSettable;
+AssignPrivateDerivedSettable InheritedMemberVars::StaticMemberPrivateDerivedSettable;
+
+// These will only have getters
+AssignPublicDerived GlobalPublicDerived;
+AssignProtectedDerived GlobalProtectedDerived;
+AssignPrivateDerived GlobalPrivateDerived;
+
+// These will have getters and setters
+AssignPublicDerivedSettable GlobalPublicDerivedSettable;
+AssignProtectedDerivedSettable GlobalProtectedDerivedSettable;
+AssignPrivateDerivedSettable GlobalPrivateDerivedSettable;
+%}
+
+// (3) Test indirectly non-assignable member variables via classes that themselves have non-assignable member variables
+%inline %{
+struct MemberPublicVar {
+  AssignPublic MemberPublic;
+};
+
+struct MemberProtectedVar {
+protected:
+  AssignProtected MemberProtected;
+};
+
+struct MemberPrivateVar {
+private:
+  AssignPrivate MemberPrivate;
+};
+
+struct MembersMemberVars {
+  // These will only have getters
+  MemberPublicVar MemberPublic;
+  MemberProtectedVar MemberProtected;
+  MemberPrivateVar MemberPrivate;
+};
+
+struct StaticMembersMemberVars {
+  static MemberPublicVar StaticMemberPublic;
+  static MemberProtectedVar StaticMemberProtected;
+  static MemberPrivateVar StaticMemberPrivate;
+};
+MemberPublicVar StaticMembersMemberVars::StaticMemberPublic;
+MemberProtectedVar StaticMembersMemberVars::StaticMemberProtected;
+MemberPrivateVar StaticMembersMemberVars::StaticMemberPrivate;
+
+MemberPublicVar GlobalMemberPublic;
+MemberProtectedVar GlobalMemberProtected;
+MemberPrivateVar GlobalMemberPrivate;
+
+// Setters and getters available
+struct StaticMembersMemberVarsHolder {
+    StaticMembersMemberVars Member;
+};
+StaticMembersMemberVars GlobalStaticMembersMemberVars;
+%}
+
+// (4) Test indirectly non-assignable member variables via classes that themselves have non-assignable array member variables
+%inline %{
+struct MemberPublicArrayVar {
+  AssignPublic MemberPublic[1];
+};
+
+struct MemberProtectedArrayVar {
+protected:
+  AssignProtected MemberProtected[1];
+};
+
+struct MemberPrivateArrayVar {
+private:
+  AssignPrivate MemberPrivate[1];
+};
+
+struct MembersMemberArrayVars {
+  // These will only have getters
+  MemberPublicArrayVar MemberPublic;
+  MemberProtectedArrayVar MemberProtected;
+  MemberPrivateArrayVar MemberPrivate;
+};
+
+struct StaticMembersMemberArrayVars {
+  static MemberPublicArrayVar StaticMemberPublic;
+  static MemberProtectedArrayVar StaticMemberProtected;
+  static MemberPrivateArrayVar StaticMemberPrivate;
+};
+MemberPublicArrayVar StaticMembersMemberArrayVars::StaticMemberPublic;
+MemberProtectedArrayVar StaticMembersMemberArrayVars::StaticMemberProtected;
+MemberPrivateArrayVar StaticMembersMemberArrayVars::StaticMemberPrivate;
+
+MemberPublicArrayVar GlobalArrayMemberPublic;
+MemberProtectedArrayVar GlobalArrayMemberProtected;
+MemberPrivateArrayVar GlobalArrayMemberPrivate;
+
+// Setters and getters available
+struct StaticMembersMemberArrayVarsHolder {
+    StaticMembersMemberArrayVars Member;
+};
+StaticMembersMemberArrayVars GlobalStaticMembersMemberArrayVars;
+%}
diff --git a/Examples/test-suite/cpp11_assign_rvalue_reference.i b/Examples/test-suite/cpp11_assign_rvalue_reference.i
new file mode 100644
index 0000000..82614de
--- /dev/null
+++ b/Examples/test-suite/cpp11_assign_rvalue_reference.i
@@ -0,0 +1,130 @@
+%module cpp11_assign_rvalue_reference
+
+// Copy of assign_reference.i testcase replacing reference member variables with rvalue reference member variables
+
+%rename(Assign) *::operator=;
+
+// (1) Test directly non-assignable member variables
+%inline %{
+int GlobalInt = 0;
+int&& getAnIntRValueRef() { return std::move(*new int()); }
+struct AssignPublic {
+  AssignPublic() : PublicMember(std::move(*new int())) {}
+  int &&PublicMember;
+};
+
+struct AssignProtected {
+  AssignProtected() : ProtectedMember(std::move(*new int())) {}
+protected:
+  int &&ProtectedMember;
+};
+
+typedef const int&& ConstIntRValueRef; // also check typedef resolution
+struct AssignPrivate {
+  AssignPrivate() : PrivateMember(std::move(*new int())) {}
+private:
+  ConstIntRValueRef PrivateMember;
+};
+
+struct MemberVars {
+  // These will only have getters
+  AssignPublic MemberPublic;
+  AssignProtected MemberProtected;
+  AssignPrivate MemberPrivate;
+};
+
+// (2) Test indirectly non-assignable member variables via inheritance
+struct AssignPublicDerived : AssignPublic {};
+struct AssignProtectedDerived : AssignProtected {};
+struct AssignPrivateDerived : AssignPrivate {};
+struct AssignPublicDerivedSettable : AssignPublic {
+  AssignPublicDerivedSettable& operator=(const AssignPublicDerivedSettable &) { return *this; }
+};
+struct AssignProtectedDerivedSettable : AssignProtected {
+  AssignProtectedDerivedSettable& operator=(const AssignProtectedDerivedSettable &) { return *this; }
+};
+struct AssignPrivateDerivedSettable : AssignPrivate {
+  AssignPrivateDerivedSettable& operator=(const AssignPrivateDerivedSettable &) { return *this; }
+};
+
+struct InheritedMemberVars {
+  // These will only have getters
+  AssignPublicDerived MemberPublicDerived;
+  AssignProtectedDerived MemberProtectedDerived;
+  AssignPrivateDerived MemberPrivateDerived;
+
+  static AssignPublicDerived StaticMemberPublicDerived;
+  static AssignProtectedDerived StaticMemberProtectedDerived;
+  static AssignPrivateDerived StaticMemberPrivateDerived;
+
+  // These will have getters and setters
+  AssignPublicDerivedSettable MemberPublicDerivedSettable;
+  AssignProtectedDerivedSettable MemberProtectedDerivedSettable;
+  AssignPrivateDerivedSettable MemberPrivateDerivedSettable;
+
+  static AssignPublicDerivedSettable StaticMemberPublicDerivedSettable;
+  static AssignProtectedDerivedSettable StaticMemberProtectedDerivedSettable;
+  static AssignPrivateDerivedSettable StaticMemberPrivateDerivedSettable;
+};
+
+AssignPublicDerived InheritedMemberVars::StaticMemberPublicDerived;
+AssignProtectedDerived InheritedMemberVars::StaticMemberProtectedDerived;
+AssignPrivateDerived InheritedMemberVars::StaticMemberPrivateDerived;
+
+AssignPublicDerivedSettable InheritedMemberVars::StaticMemberPublicDerivedSettable;
+AssignProtectedDerivedSettable InheritedMemberVars::StaticMemberProtectedDerivedSettable;
+AssignPrivateDerivedSettable InheritedMemberVars::StaticMemberPrivateDerivedSettable;
+
+// These will only have getters
+AssignPublicDerived GlobalPublicDerived;
+AssignProtectedDerived GlobalProtectedDerived;
+AssignPrivateDerived GlobalPrivateDerived;
+
+// These will have getters and setters
+AssignPublicDerivedSettable GlobalPublicDerivedSettable;
+AssignProtectedDerivedSettable GlobalProtectedDerivedSettable;
+AssignPrivateDerivedSettable GlobalPrivateDerivedSettable;
+%}
+
+// (3) Test indirectly non-assignable member variables via classes that themselves have non-assignable member variables
+%inline %{
+struct MemberPublicVar {
+  AssignPublic MemberPublic;
+};
+
+struct MemberProtectedVar {
+protected:
+  AssignProtected MemberProtected;
+};
+
+struct MemberPrivateVar {
+private:
+  AssignPrivate MemberPrivate;
+};
+
+struct MembersMemberVars {
+  // These will only have getters
+  MemberPublicVar MemberPublic;
+  MemberProtectedVar MemberProtected;
+  MemberPrivateVar MemberPrivate;
+};
+
+struct StaticMembersMemberVars {
+  static MemberPublicVar StaticMemberPublic;
+  static MemberProtectedVar StaticMemberProtected;
+  static MemberPrivateVar StaticMemberPrivate;
+};
+MemberPublicVar StaticMembersMemberVars::StaticMemberPublic;
+MemberProtectedVar StaticMembersMemberVars::StaticMemberProtected;
+MemberPrivateVar StaticMembersMemberVars::StaticMemberPrivate;
+
+MemberPublicVar GlobalMemberPublic;
+MemberProtectedVar GlobalMemberProtected;
+MemberPrivateVar GlobalMemberPrivate;
+
+// Setters and getters available
+struct StaticMembersMemberVarsHolder {
+    StaticMembersMemberVars Member;
+};
+StaticMembersMemberVars GlobalStaticMembersMemberVars;
+%}
diff --git a/Examples/test-suite/cpp11_attribute_specifiers.i b/Examples/test-suite/cpp11_attribute_specifiers.i
new file mode 100644
index 0000000..f14c87b
--- /dev/null
+++ b/Examples/test-suite/cpp11_attribute_specifiers.i
@@ -0,0 +1,55 @@
+%module cpp11_attribute_specifiers
+
+%inline %{
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // We're using a deprecated attribute here...
+#pragma GCC diagnostic ignored "-Wattributes"              // likely is C++20
+#pragma GCC diagnostic ignored "-Wunused-variable"         // We are using an unused variable on purpose here
+#pragma GCC diagnostic ignored "-Wunused-parameter"        // We are using an unused param on purpose here
+#endif
+
+#if defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+#pragma clang diagnostic ignored "-Wattributes"
+#pragma clang diagnostic ignored "-Wunused-variable"
+#pragma clang diagnostic ignored "-Wunused-parameter"
+#endif
+
+#if defined(_MSC_VER)
+#pragma warning(disable : 4996) // For the deprecated attributes in this testcase
+#pragma warning(disable : 5030) // attribute is not recognized ('likely' and 'unlikely')
+#endif
+
+
+[[noreturn]] void noReturn() { throw; }
+[[nodiscard]] bool noDiscard() { return true; }
+[[nodiscard, deprecated("This has been replaced")]] bool noDiscardDeprecated() { return true; }
+void maybeUnused1([[maybe_unused]] bool b) { }
+bool maybeUnused2(bool a, [[maybe_unused]] bool b) { return a; }
+
+[[deprecated, nodiscard]] bool likely([[maybe_unused]] bool a, bool b) {
+  [[maybe_unused]] bool c = b;
+  if (b) [[likely]] {
+    return true;
+  } else [[unlikely]] {
+    if(a) {
+      return true;
+    }
+  }
+  return false;
+}
+
+struct [[nodiscard]] S { };
+
+const char *test_string_literal() { return "Test [[ and ]] in string literal"; }
+
+#if 0
+// Check that SWIG doesn't choke on ]] when it's not part of an attribute.
+// FIXME: SWIG's parser doesn't handle this case currently.
+int *a;
+int b = a[a[0]];
+#endif
+
+%}
diff --git a/Examples/test-suite/cpp11_auto_variable.i b/Examples/test-suite/cpp11_auto_variable.i
new file mode 100644
index 0000000..3f8983e
--- /dev/null
+++ b/Examples/test-suite/cpp11_auto_variable.i
@@ -0,0 +1,52 @@
+%module cpp11_auto_variable
+
+%inline %{
+
+static auto t = true;
+static constexpr auto f = false;
+
+static auto zero = 0;
+static constexpr auto one = 1;
+
+static auto la = 1.0L;
+static auto da = 1.0;
+static auto fa = 1.0f;
+static constexpr auto lc = 1.0L;
+static constexpr auto dc = 1.0;
+static constexpr auto fc = 1.0f;
+
+static constexpr auto pi_approx = 355. / 133;
+
+static constexpr auto Bar = "foo";
+static constexpr auto Foo = "bar";
+
+static constexpr auto Bar2 = Bar;
+static constexpr auto Foo2 = Foo;
+
+static auto Bar3 = f ? zero : t;
+static constexpr auto Foo3 = f ? f : one;
+
+%}
+
+// SWIG currently can't deduce the type for examples below.
+// Test two approaches to suppressing the warning.
+%ignore Bad1;
+%ignore Bad2;
+%warnfilter(SWIGWARN_CPP11_AUTO) Bad3;
+%warnfilter(SWIGWARN_CPP11_AUTO) Bad4;
+
+%inline %{
+
+static auto Bad1 = &t;
+static constexpr auto Bad2 = &f;
+static auto Bad3 = &zero;
+static constexpr auto Bad4 = &one;
+
+%}
+
+%inline %{
+
+// FIXME: Not currently handled by SWIG's parser:
+//static auto constexpr greeting = "Hello";
+
+%}
diff --git a/Examples/test-suite/cpp11_brackets_expression.i b/Examples/test-suite/cpp11_brackets_expression.i
new file mode 100644
index 0000000..3e739f5
--- /dev/null
+++ b/Examples/test-suite/cpp11_brackets_expression.i
@@ -0,0 +1,35 @@
+%module cpp11_brackets_expression
+
+%warnfilter(SWIGWARN_PARSE_ASSIGNED_VALUE) Piece::kMaxSize;
+%warnfilter(SWIGWARN_PARSE_ASSIGNED_VALUE) Piece::Just123;
+%warnfilter(SWIGWARN_PARSE_ASSIGNED_VALUE) ::kMaxSizeGlobal;
+
+%inline %{
+
+#include <limits>
+
+static constexpr int global_as_you_expect(int val) { return val; }
+static constexpr int global_one_two_three() { return 123; }
+
+class Piece {
+public:
+    typedef size_t size_type;
+    typedef int difference_type;
+
+    static constexpr size_type kOk2 = std::numeric_limits<difference_type>::max();
+
+    // Failed to parse (issue #2640):
+    static constexpr size_type kMaxSize = (std::numeric_limits<difference_type>::max)();
+
+    // Also fails to parse:
+//    int f(int x = (std::numeric_limits<difference_type>::max)());
+
+    static constexpr size_type SimpleAsYouExpect123 = global_as_you_expect(123);
+    static constexpr size_type SimpleJust123 = global_one_two_three();
+
+    static constexpr size_type AsYouExpect123 = (global_as_you_expect)(123); // Did parse okay
+    static constexpr size_type Just123 = (global_one_two_three)();           // Did not parse okay
+};
+
+static const Piece::size_type kMaxSizeGlobal = (std::numeric_limits<Piece::difference_type>::max)();
+%}
diff --git a/Examples/test-suite/cpp11_constexpr.i b/Examples/test-suite/cpp11_constexpr.i
index 420db4f..77f4e74 100644
--- a/Examples/test-suite/cpp11_constexpr.i
+++ b/Examples/test-suite/cpp11_constexpr.i
@@ -11,8 +11,13 @@
 // For MMM() and NNN()
 #pragma clang diagnostic ignored "-Wconstexpr-not-const"
 #endif
+
+#include <limits>
 %}
 
+%ignore operator==(ConstExpressions,ConstExpressions);
+%ignore operator!=(ConstExpressions,ConstExpressions);
+
 %inline %{
 #ifdef SWIG
 #define SWIGTESTCONST const
@@ -39,10 +44,11 @@
   // Regression tests for https://github.com/swig/swig/issues/284 :
   explicit constexpr ConstExpressions(int) { }
   constexpr explicit ConstExpressions(double) { }
+  // Regression tests for  https://github.com/swig/swig/issues/2079 :
+  constexpr friend bool operator==(ConstExpressions,ConstExpressions) { return true; }
+  friend constexpr bool operator!=(ConstExpressions,ConstExpressions) { return false; }
 };
-%}
 
-%{
 int Array10[AAA];
 int Array20[BBB];
 int Array30[CCC()];
@@ -52,4 +58,20 @@
 int Array300[ConstExpressions::LLL];
 //int Array400[ConstExpressions::MMM()];
 //int Array500[ConstExpressions::NNN()];
+
+// Regression test for https://github.com/swig/swig/issues/2486 fixed in 4.2.0
+// (the array size is constexpr in C++11):
+unsigned char myarray[std::numeric_limits<unsigned char>::max()];
+// Also check that `<(` and `)>` in the expression are handled, since these have
+// special meanings for SWIG's type system.  SWIG should rewrite them as `< (`
+// and `) >` here to avoid problems.
+template<int N> constexpr int inc() { return N + 1; };
+unsigned char myarray2[inc<(1)>()];
+
+// Test handling of ID PERIOD ID in constant expressions (supported since 4.1.0).
+struct A {
+    int i;
+};
+constexpr A a{42};
+constexpr int N = a.i;
 %}
diff --git a/Examples/test-suite/cpp11_copyctor_delete.i b/Examples/test-suite/cpp11_copyctor_delete.i
new file mode 100644
index 0000000..d708ba8
--- /dev/null
+++ b/Examples/test-suite/cpp11_copyctor_delete.i
@@ -0,0 +1,192 @@
+%module cpp11_copyctor_delete
+
+%{
+#if defined(_MSC_VER)
+  #pragma warning(disable : 4624) // warning C4624: 'StackOnlyDerived1': destructor was implicitly defined as deleted
+#endif
+%}
+
+%inline %{
+struct DeletedPublic1 {
+  DeletedPublic1() = delete;
+};
+struct DeletedPublic2 {
+  DeletedPublic2() = delete;
+  DeletedPublic2(const DeletedPublic2&) = delete;
+};
+struct DeletedPublic3 {
+  DeletedPublic3(const DeletedPublic3&) = delete;
+};
+struct DeletedPublic4 {
+  DeletedPublic4() = default;
+  DeletedPublic4(const DeletedPublic4&) = delete;
+};
+struct DeletedPublic5 {
+  DeletedPublic5() = default;
+  DeletedPublic5(const DeletedPublic5&) = delete;
+};
+
+struct DeletedProtected1 {
+protected:
+  DeletedProtected1() = delete;
+};
+struct DeletedProtected2 {
+protected:
+  DeletedProtected2() = delete;
+  DeletedProtected2(const DeletedProtected2&) = delete;
+};
+struct DeletedProtected3 {
+protected:
+  DeletedProtected3(const DeletedProtected3&) = delete;
+};
+struct DeletedProtected4 {
+protected:
+  DeletedProtected4() = default;
+  DeletedProtected4(const DeletedProtected4&) = delete;
+};
+struct DeletedProtected5 {
+protected:
+  DeletedProtected5() = default;
+  DeletedProtected5(const DeletedProtected5&) = delete;
+};
+
+struct DeletedPrivate1 {
+private:
+  DeletedPrivate1() = delete;
+};
+struct DeletedPrivate2 {
+private:
+  DeletedPrivate2() = delete;
+  DeletedPrivate2(const DeletedPrivate2&) = delete;
+};
+struct DeletedPrivate3 {
+private:
+  DeletedPrivate3(const DeletedPrivate3&) = delete;
+};
+struct DeletedPrivate4 {
+private:
+  DeletedPrivate4() = default;
+  DeletedPrivate4(const DeletedPrivate4&) = delete;
+};
+struct DeletedPrivate5 {
+private:
+  DeletedPrivate5() = default;
+  DeletedPrivate5(const DeletedPrivate5&) = delete;
+};
+
+struct StackOnly1 {
+  // Only constructible on the stack
+  ~StackOnly1() = delete;
+};
+struct StackOnlyDerived1 : StackOnly1 {
+  // this class is not constructible due to deleted base destructor
+};
+struct StackOnlyDerivedMore1 : StackOnlyDerived1 {
+  // this class is not constructible due to deleted base destructor
+};
+%}
+
+// copyctor feature turned on
+%copyctor;
+%inline %{
+struct CopyCtorDeletedPublic1 {
+#if __cplusplus >= 202002L
+  // Uniform/aggregate initialization was removed in C++20 if there is a user declared constructor, so the initialization in make() below does not work
+  // This example can only be tested for C++11 to C++17, in C++20 the constructor declaration is removed by making it an aggregate
+  // SWIG still sees the deleted constructor below
+#else
+  CopyCtorDeletedPublic1() = delete;
+#endif
+  static CopyCtorDeletedPublic1 make() { return {}; }
+};
+struct CopyCtorDeletedPublic2 {
+  CopyCtorDeletedPublic2() = delete;
+  CopyCtorDeletedPublic2(const CopyCtorDeletedPublic2&) = delete;
+};
+struct CopyCtorDeletedPublic3 {
+  CopyCtorDeletedPublic3(const CopyCtorDeletedPublic3&) = delete;
+};
+struct CopyCtorDeletedPublic4 {
+  CopyCtorDeletedPublic4() = default;
+  CopyCtorDeletedPublic4(const CopyCtorDeletedPublic4&) = delete;
+};
+struct CopyCtorDeletedPublic5 {
+  CopyCtorDeletedPublic5() = default;
+  CopyCtorDeletedPublic5(const CopyCtorDeletedPublic5&) = delete;
+};
+
+struct CopyCtorDeletedProtected1 {
+protected:
+#if __cplusplus >= 202002L
+  // Uniform/aggregate initialization was removed in C++20 if there is a user declared constructor, so the initialization in make() below does not work
+  // This example can only be tested for C++11 to C++17, in C++20 the constructor declaration is removed by making it an aggregate
+  // SWIG still sees the deleted constructor below
+#else
+  CopyCtorDeletedProtected1() = delete;
+#endif
+public:
+  static CopyCtorDeletedProtected1 make() { return {}; }
+};
+struct CopyCtorDeletedProtected2 {
+protected:
+  CopyCtorDeletedProtected2() = delete;
+  CopyCtorDeletedProtected2(const CopyCtorDeletedProtected2&) = delete;
+};
+struct CopyCtorDeletedProtected3 {
+protected:
+  CopyCtorDeletedProtected3(const CopyCtorDeletedProtected3&) = delete;
+};
+struct CopyCtorDeletedProtected4 {
+protected:
+  CopyCtorDeletedProtected4() = default;
+  CopyCtorDeletedProtected4(const CopyCtorDeletedProtected4&) = delete;
+};
+struct CopyCtorDeletedProtected5 {
+protected:
+  CopyCtorDeletedProtected5() = default;
+  CopyCtorDeletedProtected5(const CopyCtorDeletedProtected5&) = delete;
+};
+
+struct CopyCtorDeletedPrivate1 {
+private:
+#if __cplusplus >= 202002L
+  // Uniform/aggregate initialization was removed in C++20 if there is a user declared constructor, so the initialization in make() below does not work
+  // This example can only be tested for C++11 to C++17, in C++20 the constructor declaration is removed by making it an aggregate
+  // SWIG still sees the deleted constructor below
+#else
+  CopyCtorDeletedPrivate1() = delete;
+#endif
+public:
+  static CopyCtorDeletedPrivate1 make() { return {}; }
+};
+struct CopyCtorDeletedPrivate2 {
+private:
+  CopyCtorDeletedPrivate2() = delete;
+  CopyCtorDeletedPrivate2(const CopyCtorDeletedPrivate2&) = delete;
+};
+struct CopyCtorDeletedPrivate3 {
+private:
+  CopyCtorDeletedPrivate3(const CopyCtorDeletedPrivate3&) = delete;
+};
+struct CopyCtorDeletedPrivate4 {
+private:
+  CopyCtorDeletedPrivate4() = default;
+  CopyCtorDeletedPrivate4(const CopyCtorDeletedPrivate4&) = delete;
+};
+struct CopyCtorDeletedPrivate5 {
+private:
+  CopyCtorDeletedPrivate5() = default;
+  CopyCtorDeletedPrivate5(const CopyCtorDeletedPrivate5&) = delete;
+};
+
+struct CopyCtorStackOnly1 {
+  // Only constructible on the stack
+  ~CopyCtorStackOnly1() = delete;
+};
+struct CopyCtorStackOnlyDerived1 : CopyCtorStackOnly1 {
+  // this class is not constructible due to deleted base destructor
+};
+struct CopyCtorStackOnlyDerivedMore1 : CopyCtorStackOnlyDerived1 {
+  // this class is not constructible due to deleted base destructor
+};
+%}
diff --git a/Examples/test-suite/cpp11_decltype.i b/Examples/test-suite/cpp11_decltype.i
index deedd59..6855f3d 100644
--- a/Examples/test-suite/cpp11_decltype.i
+++ b/Examples/test-suite/cpp11_decltype.i
@@ -3,17 +3,89 @@
 */
 %module cpp11_decltype
 
+%{
+#if defined(_MSC_VER)
+  #pragma warning(disable : 4804) // warning C4804: '-': unsafe use of type 'bool' in operation
+  // For: decltype(-false) should_be_int2;
+#endif
+%}
+
+#ifdef SWIGGO
+// FIXME: SWIG/Go tries to wrap this by generating code which tries to
+// assign a const char* value to a char* variable.
+%ignore should_be_string;
+#endif
+
 %inline %{
   class A {
   public:
     int i;
     decltype(i) j;
 
-    auto foo( decltype(i) a ) -> decltype(i) {
+    auto get_number(decltype(i) a) -> decltype(i) {
       if (a==5)
         return 10;
       else
         return 0;
     }
   };
-  %}
+%}
+
+
+// These are ignored as unable to deduce decltype for (&i)
+%ignore B::k;
+%ignore B::get_number_address;
+#pragma SWIG nowarn=SWIGWARN_CPP11_DECLTYPE
+
+%ignore hidden_global_char;
+
+%inline %{
+#define DECLARE(VAR, VAL) decltype(VAL) VAR = VAL
+  static const char hidden_global_char = '\0';
+  class B {
+  public:
+    int i;
+    decltype(i) j;
+    decltype(i+j) ij;
+    decltype(&i) k;
+    DECLARE(a, false);
+    DECLARE(b, true);
+
+    // SWIG < 4.2.0 failed to perform type promotion for the result of unary
+    // plus and unary minus, so these would end up wrapped as bool and char.
+    decltype(+true) should_be_int;
+    decltype(-false) should_be_int2;
+    decltype(~'x') should_be_int3;
+
+    decltype(int(0)) should_be_int4;
+    decltype((int)0.0) should_be_int5;
+    decltype((6)-7) should_be_int6;
+    decltype((6)+7) should_be_int7;
+    decltype((6)*7) should_be_int8;
+    decltype((6)&7) should_be_int9;
+    enum e { E1 };
+    decltype(+E1) should_be_int10;
+
+    static constexpr decltype(*"abc") should_be_char = 0;
+
+    static constexpr decltype(&hidden_global_char) should_be_string = "xyzzy";
+
+    // SWIG < 4.2.0 incorrectly used int for the result of logical not in C++
+    // so this would end up wrapped as int.
+    decltype(!0) should_be_bool;
+
+    decltype(E1) should_be_enum;
+
+    auto get_number_sum(decltype(i+j) a) -> decltype(i+j) {
+      return i+j;
+    }
+
+    auto get_number_address(decltype(&i) a) -> decltype(&i) {
+      return &i;
+    }
+
+    auto negate(decltype(true) b) -> decltype(b) {
+      return !b;
+    }
+  };
+%}
diff --git a/Examples/test-suite/cpp11_default_delete.i b/Examples/test-suite/cpp11_default_delete.i
index 0c20fb7..408027c 100644
--- a/Examples/test-suite/cpp11_default_delete.i
+++ b/Examples/test-suite/cpp11_default_delete.i
@@ -57,9 +57,34 @@
   sometype() = delete;
   sometype(int) = delete;
   sometype(double);
+  static sometype make(double d) { return sometype(d); }
+  static void take(sometype s) {}
 };
 sometype::sometype(double) {}
 
+struct sometype2 {
+  sometype2() = delete;
+  sometype2(double) {}
+  static sometype2 make(double d) { return sometype2(d); }
+  static void take(sometype2 s) {}
+};
+
+struct sometype3 {
+  int num;
+#if __cplusplus >= 202002L
+  // Uniform/aggregate initialization was removed in C++20 if there is a user declared constructor, so the initialization in make() below does not work
+  // This example can only be tested for C++11 to C++17, in C++20 the constructor declaration is removed by making it an aggregate
+  // SWIG still sees the deleted constructor below
+#else
+  sometype3() = delete;
+#endif
+  static sometype3 make(int n) {
+    // Note: Can only be constructed via copy constructor, so use C++11 uniform initialization to create
+    return sometype3 {n};
+  }
+  static void take(sometype3 s) {}
+};
+
 /* Not working with prerelease of gcc-4.8
 struct nonew {
   void *operator new(std::size_t) = delete;
diff --git a/Examples/test-suite/cpp11_director_using_constructor.i b/Examples/test-suite/cpp11_director_using_constructor.i
new file mode 100644
index 0000000..91d2571
--- /dev/null
+++ b/Examples/test-suite/cpp11_director_using_constructor.i
@@ -0,0 +1,12 @@
+%module(directors="1") cpp11_director_using_constructor
+
+// This testcase uses cpp11_using_constructor.i for testing that the expected
+// constructors are available in director mode.
+
+%feature("director");
+
+%warnfilter(SWIGWARN_LANG_DIRECTOR_ABSTRACT) TemplateConstructor1Derived;
+%warnfilter(SWIGWARN_LANG_DIRECTOR_ABSTRACT) TemplateConstructor2Base;
+%warnfilter(SWIGWARN_LANG_DIRECTOR_ABSTRACT) TemplateConstructor2Derived;
+
+%include "cpp11_using_constructor.i"
diff --git a/Examples/test-suite/cpp11_final_class.i b/Examples/test-suite/cpp11_final_class.i
new file mode 100644
index 0000000..4f24293
--- /dev/null
+++ b/Examples/test-suite/cpp11_final_class.i
@@ -0,0 +1,141 @@
+%module cpp11_final_class
+
+%warnfilter(SWIGWARN_PARSE_KEYWORD) final; // 'final' is a java keyword, renaming to '_final'
+%warnfilter(SWIGWARN_PARSE_KEYWORD) override; // 'override' is a C# keyword, renaming to '_override'
+
+%ignore Space1::final::operator=;
+#if defined(SWIGPHP)
+%rename(Space1_final) Space1::final::final;
+#endif
+#if defined(SWIGOCAML)
+%rename(finale) BrokenSpace::FinalEnum1::final;
+#endif
+
+%inline %{
+struct FinalBase {
+  virtual ~FinalBase() {}
+};
+
+struct FinalClass1 final : FinalBase {
+  void method1() {}
+};
+
+class FinalClass2 final : public FinalBase {
+public:
+  void method2() {}
+};
+
+struct FinalClass3 final {
+  void method3() {}
+};
+
+struct FinalClass4 {
+  void method4() {}
+} final;
+
+struct override final {
+  void omethod() {}
+};
+%}
+
+%rename(Space1_final) Space1::final;
+
+%inline %{
+namespace Space1 {
+struct final final {
+  void finalmethod() {}
+  final() {}
+  final(const final &other) = default;
+  final& operator=(const final &other) = default;
+};
+struct FinalClass5 final {
+  void method5() {}
+  final final_member_var;
+  final get_final_member() { return final_member_var; }
+  Space1::final get_final_member2() { return final_member_var; }
+};
+struct FinalClass6 {
+  void method6() {}
+  virtual void final() final {}
+  virtual ~FinalClass6() = default;
+};
+typedef final Space1_final_typedef1;
+typedef struct final Space1_final_typedef2;
+}
+typedef Space1::final Space1_final_typedef3;
+typedef struct Space1::final Space1_final_typedef4;
+%}
+
+%inline %{
+namespace Space2 {
+class Y {
+public:
+  Y(int i=0) {}
+};
+
+struct FinalVar1 {
+    class Y notfinal;
+//  class Y final; // SWIG (C++ only) fails to parse (same for struct and union)
+};
+struct FinalVar2 {
+    class Y notfinal = {};
+//  class Y final = {}; // SWIG (C++ only) fails to parse (same for struct and union)
+};
+struct FinalVar3 {
+    class Y notfinal = Y();
+//  class Y final = Y(); // SWIG (C++ only) fails to parse (same for struct and union)
+};
+struct FinalVar4 {
+  class Y* final;
+  FinalVar4() : final() {}
+};
+struct FinalVar5 {
+  Y final;
+};
+struct FinalVar6 {
+  Y final = {};
+};
+struct FinalVar7 {
+  Y final = Y();
+};
+struct FinalVar8 {
+  Y final{};
+};
+struct FinalVar9 {
+  Y final{9};
+};
+struct FinalVar10 {
+  void b10(Y final) {}
+};
+}
+%}
+
+// Unfortunately the use of final in BrokenSpace does not work with Visual C++
+// so we limit testing to parsing these by SWIG and then ignoring it all.
+%ignore BrokenSpace::FinalVar11;
+%ignore BrokenSpace::FinalEnum1;
+%ignore BrokenSpace::FinalEnum2;
+
+namespace BrokenSpace {
+using Space2::Y;
+struct FinalVar11 {
+  void a11(class Y final) {}
+};
+struct FinalEnum1 {
+  enum Enum1 { one, two, final };
+  void enum_in(Enum1 e) {}
+};
+struct FinalEnum2 {
+  enum Enum2 { one, two, three, four };
+  enum Enum2 final;
+};
+}
+
+%rename(Space3_final) Space3::final;
+%inline %{
+namespace Space3 {
+  typedef struct final {
+    void fmethod() {}
+  } final;
+}
+%}
diff --git a/Examples/test-suite/cpp11_final_directors.i b/Examples/test-suite/cpp11_final_directors.i
index b58111a..6c9cfed 100644
--- a/Examples/test-suite/cpp11_final_directors.i
+++ b/Examples/test-suite/cpp11_final_directors.i
@@ -9,6 +9,13 @@
 %warnfilter(SWIGWARN_LANG_DIRECTOR_FINAL) BaseFinalDestructor::~BaseFinalDestructor;
 %warnfilter(SWIGWARN_LANG_DIRECTOR_FINAL) BaseFinalDestructor2::~BaseFinalDestructor2;
 
+%{
+#if defined(__clang__)
+// Suppress: class with destructor marked 'final' cannot be inherited from [-Wfinal-dtor-non-final-class]
+#pragma clang diagnostic ignored "-Wfinal-dtor-non-final-class"
+#endif
+%}
+
 %inline %{
 struct Base {
   virtual void basemeth() final {}
diff --git a/Examples/test-suite/cpp11_final_override.i b/Examples/test-suite/cpp11_final_override.i
index 8d275b3..b527a81 100644
--- a/Examples/test-suite/cpp11_final_override.i
+++ b/Examples/test-suite/cpp11_final_override.i
@@ -6,6 +6,13 @@
 %warnfilter(SWIGWARN_PARSE_KEYWORD) final; // 'final' is a java keyword, renaming to '_final'
 %warnfilter(SWIGWARN_PARSE_KEYWORD) override; // 'override' is a C# keyword, renaming to '_override'
 
+%{
+#if defined(__clang__)
+// Suppress: class with destructor marked 'final' cannot be inherited from [-Wfinal-dtor-non-final-class]
+#pragma clang diagnostic ignored "-Wfinal-dtor-non-final-class"
+#endif
+%}
+
 // throw is invalid in C++17 and later, only SWIG to use it
 #define TESTCASE_THROW1(T1) throw(T1)
 %{
@@ -27,7 +34,7 @@
   virtual ~Base() {}
 };
 
-struct Derived /*final*/ : Base {
+struct Derived final : Base {
   virtual void stuff() const noexcept override final {}
   virtual void override1() const noexcept override;
   virtual void override2() const noexcept override;
@@ -90,7 +97,7 @@
     virtual void override(int) {}
     virtual ~FinalOverrideMethods() = default;
 };
-struct FinalOverrideVariables {
+struct FinalOverrideVars {
     int final;
     double override;
 };
@@ -138,3 +145,31 @@
 DerivedNoVirtualStruct::~DerivedNoVirtualStruct() {}
 %}
 
+%inline %{
+namespace Outer {
+  namespace final {
+    template <typename T> struct smart_ptr {
+      typedef T type;
+    };
+  }
+  namespace override {
+    template <typename T> struct dumb_ptr {
+      typedef T type;
+    };
+  }
+}
+%}
+
+%template(SmartPtrBaseStruct) Outer::final::smart_ptr<DerivedStruct>;
+
+%inline %{
+class ObjectDB
+{
+public:
+  static void smart1(typename Outer::final::smart_ptr<DerivedStruct>::type *objectT) {}
+  static void smart2(Outer::final::smart_ptr<DerivedStruct>::type *objectT) {}
+  static void dumb1(typename Outer::override::dumb_ptr<DerivedStruct>::type *objectT) {}
+  static void dumb2(Outer::override::dumb_ptr<DerivedStruct>::type *objectT) {}
+  static Outer::final::smart_ptr<DerivedStruct>::type get() { return DerivedStruct(); }
+};
+%}
diff --git a/Examples/test-suite/cpp11_function_objects.i b/Examples/test-suite/cpp11_function_objects.i
index e80f60a..dffb689 100644
--- a/Examples/test-suite/cpp11_function_objects.i
+++ b/Examples/test-suite/cpp11_function_objects.i
@@ -9,15 +9,21 @@
 
 %feature("director") Test;
 
+/* We had to rename this in the C++ API being wrapped due to a collision with
+ * a value typedef in newer ocaml headers, so use %rename to avoid having to
+ * update all the runme files which use it.
+ */
+%rename(value) Test::the_value;
+
 %inline %{
 class Test {
 public:
-  int value;
+  int the_value;
   
   virtual void operator()(int x, int y) {
-    value=x+y;
+    the_value=x+y;
   }
-  Test() : value(0) {}
+  Test() : the_value(0) {}
   virtual ~Test() {}
 };
 
@@ -29,12 +35,12 @@
 int testit1(Test &new_test, int a, int b) {
   pF = std::ref(new_test);
   pF(a, b);
-  return new_test.value;
+  return new_test.the_value;
 }
 
 int testit2(int a, int b) {
   test(a, b);
-  return test.value;
+  return test.the_value;
 }
 
 %}
diff --git a/Examples/test-suite/cpp11_inheriting_constructors.i b/Examples/test-suite/cpp11_inheriting_constructors.i
index ccdf050..4c2ed3f 100644
--- a/Examples/test-suite/cpp11_inheriting_constructors.i
+++ b/Examples/test-suite/cpp11_inheriting_constructors.i
@@ -10,6 +10,7 @@
   int _val;
 public:
   BaseClass(int iValue) { _val = iValue; }
+  int retrieveValue() { return _val; }
 };
 
 // Constructor inheritance via using declaration
diff --git a/Examples/test-suite/cpp11_initializer_list.i b/Examples/test-suite/cpp11_initializer_list.i
index b309576..7e86cc0 100644
--- a/Examples/test-suite/cpp11_initializer_list.i
+++ b/Examples/test-suite/cpp11_initializer_list.i
@@ -10,7 +10,7 @@
   $1 = {"Ab", "Fab"};
 %}
 
-%begin %{
+%runtime %{
 #if __GNUC__ >= 9
 /* warning: ‘new’ of initializer_list does not extend the lifetime of the underlying array [-Winit-list-lifetime] */
 /* incorrect warning for C::C(std::initializer_list<const char *>) */
@@ -39,7 +39,7 @@
 public:
   C(std::initializer_list<const char *> init) {
     for (auto& val : init)
-      joined += val;
+      joined = joined + val;
   }
   C() {}
   const char * get_joined_string() {
diff --git a/Examples/test-suite/cpp11_lambda_functions.i b/Examples/test-suite/cpp11_lambda_functions.i
index 3d7d76d..0096eef 100644
--- a/Examples/test-suite/cpp11_lambda_functions.i
+++ b/Examples/test-suite/cpp11_lambda_functions.i
@@ -56,7 +56,7 @@
 auto lambda5 = []() { return thing; };
 #endif
 
-void fn() {
+void fn1() {
   int stuff = 0;
   auto lambdaxxxx = [=,&stuff]() { return thing; };
 }
diff --git a/Examples/test-suite/cpp11_move_only.i b/Examples/test-suite/cpp11_move_only.i
new file mode 100644
index 0000000..b7db92b
--- /dev/null
+++ b/Examples/test-suite/cpp11_move_only.i
@@ -0,0 +1,61 @@
+%module cpp11_move_only
+
+%include "cpp11_move_only_helper.i"
+
+#if defined(SWIGOCAML)
+%rename(valu) val;
+#endif
+
+%ignore MoveOnly::operator=;
+//%valuewrapper MoveOnly; // SWIG sets %valuewrapper by default for move-only types
+
+%inline %{
+#include <iostream>
+using namespace std;
+
+bool trace = false;
+
+struct MoveOnly {
+  int val;
+  MoveOnly(int i = 0) : val(i) { if (trace) cout << "MoveOnly(" << i << ")" << " " << this << endl; Counter::normal_constructor++; }
+
+  MoveOnly(const MoveOnly &other) = delete;
+  MoveOnly & operator=(const MoveOnly &other) = delete;
+
+  MoveOnly(MoveOnly &&other) noexcept : val(std::move(other.val)) { if (trace) cout << "MoveOnly(MoveOnly &&)" << " " << this << endl; Counter::move_constructor++; }
+  MoveOnly & operator=(MoveOnly &&other) noexcept { if (trace) cout << "operator=(MoveOnly &&)" << " " << this << endl; Counter::move_assignment++; if (this != &other) { val = std::move(other.val); } return *this; }
+  ~MoveOnly() { if (trace) cout << "~MoveOnly()" << " " << this << endl; Counter::destructor++; }
+
+  static MoveOnly create() { return MoveOnly(111); }
+  // static const MoveOnly createConst() { return MoveOnly(111); } // not supported by default
+
+  // compile error by default, see cpp11_move_typemaps.i
+  #if defined(WRAP_TAKE_METHOD)
+  static void take(MoveOnly mo) { if (trace) cout << "take(MoveOnly)" << " " << &mo << endl; }
+  #endif
+};
+%}
+
+%ignore MovableCopyable::operator=;
+%ignore MovableCopyable::MovableCopyable(MovableCopyable &&);
+// %valuewrapper MovableCopyable; // SWIG does not use valuewrapper by default for copyable types with a default constructor
+
+%inline %{
+// Movable and Copyable
+struct MovableCopyable {
+  int val;
+  MovableCopyable(int i = 0) : val(i) { if (trace) cout << "MovableCopyable(" << i << ")" << " " << this << endl; Counter::normal_constructor++; }
+
+  MovableCopyable(const MovableCopyable &other) : val(other.val) { if (trace) cout << "MovableCopyable(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_constructor++;}
+  MovableCopyable & operator=(const MovableCopyable &other) { if (trace) cout << "operator=(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_assignment++; if (this != &other) { val = other.val; } return *this; }
+
+  MovableCopyable(MovableCopyable &&other) noexcept : val(std::move(other.val)) { if (trace) cout << "MovableCopyable(MovableCopyable &&)" << " " << this << endl; Counter::move_constructor++; }
+  MovableCopyable & operator=(MovableCopyable &&other) noexcept { if (trace) cout << "operator=(MovableCopyable &&)" << " " << this << endl; Counter::move_assignment++; if (this != &other) { val = std::move(other.val); } return *this; }
+  ~MovableCopyable() { if (trace) cout << "~MovableCopyable()" << " " << this << endl; Counter::destructor++; }
+
+  static MovableCopyable create() { return MovableCopyable(111); }
+  static const MovableCopyable createConst() { return MovableCopyable(111); }
+
+  static void take(MovableCopyable mc) { if (trace) cout << "take(MovableCopyable)" << " " << &mc << endl; }
+};
+%}
diff --git a/Examples/test-suite/cpp11_move_only_helper.i b/Examples/test-suite/cpp11_move_only_helper.i
new file mode 100644
index 0000000..89fc150
--- /dev/null
+++ b/Examples/test-suite/cpp11_move_only_helper.i
@@ -0,0 +1,71 @@
+// Helper interface for cpp11_move_only.i and others
+
+%include <std_string.i>
+%catches(std::string) Counter::check_counts;
+
+%inline %{
+#include <sstream>
+using namespace std;
+
+
+struct Counter {
+  static int normal_constructor;
+  static int copy_constructor;
+  static int copy_assignment;
+  static int move_constructor;
+  static int move_assignment;
+  static int destructor;
+  static void reset_counts() {
+    normal_constructor = 0;
+    copy_constructor = 0;
+    copy_assignment = 0;
+    move_constructor = 0;
+    move_assignment = 0;
+    destructor = 0;
+  }
+  // Check against expected counts of constructor, assignment operators etc.
+  // Not observed during development, but compiler optimisation could change the expected values.
+  // Throws exception if not correct (use %catches to catch them)
+  static void check_counts(
+      int normal_constructor,
+      int copy_constructor,
+      int copy_assignment,
+      int move_constructor,
+      int move_assignment,
+      int destructor) {
+    bool match = (
+      normal_constructor == Counter::normal_constructor &&
+      copy_constructor == Counter::copy_constructor &&
+      copy_assignment == Counter::copy_assignment &&
+      move_constructor == Counter::move_constructor &&
+      move_assignment == Counter::move_assignment &&
+      destructor == Counter::destructor);
+    if (!match) {
+      std::stringstream ss;
+      ss << "check_counts failed" << std::endl <<
+        Counter::normal_constructor << " " <<
+        Counter::copy_constructor << " " <<
+        Counter::copy_assignment << " " <<
+        Counter::move_constructor << " " <<
+        Counter::move_assignment << " " <<
+        Counter::destructor << " " <<
+        " (actual)" << std::endl <<
+        normal_constructor << " " <<
+        copy_constructor << " " <<
+        copy_assignment << " " <<
+        move_constructor << " " <<
+        move_assignment << " " <<
+        destructor << " " <<
+        " (expected)" << std::endl;
+      throw ss.str();
+    }
+  }
+};
+
+int Counter::normal_constructor = 0;
+int Counter::copy_constructor = 0;
+int Counter::copy_assignment = 0;
+int Counter::move_constructor = 0;
+int Counter::move_assignment = 0;
+int Counter::destructor = 0;
+%}
diff --git a/Examples/test-suite/cpp11_move_only_valuewrapper.i b/Examples/test-suite/cpp11_move_only_valuewrapper.i
new file mode 100644
index 0000000..d9162bf
--- /dev/null
+++ b/Examples/test-suite/cpp11_move_only_valuewrapper.i
@@ -0,0 +1,180 @@
+%module cpp11_move_only_valuewrapper
+
+/*
+ * This test case checks SwigValueWrapper and move assignment.
+ * Although not necessary, the test case was developed testing with C++98 compatibility for comparing improvements.
+ * C++11 and later is of course required for the move assignment support.
+ * C++98 is not actually necessary now as the test-suite only runs this test with compilers that support C++11 and later.
+*/
+
+%{
+#include <iostream>
+#include <sstream>
+using std::cout;
+using std::endl;
+
+#if __cplusplus >= 201103L
+#include <memory>
+#else
+namespace std {
+  // just something that will compile and vaguely work for when c++11 is not supported
+  template <class T> class unique_ptr {
+    T *ptr;
+    public:
+      unique_ptr(T *ptr = 0) : ptr(ptr) {}
+      unique_ptr(const unique_ptr &a) : ptr(a.ptr) { /*please look away*/ const_cast<unique_ptr &>(a).ptr = 0;}
+      ~unique_ptr() { delete ptr; }
+      unique_ptr& operator=(const unique_ptr &a) {
+        if (&a != this) {
+          delete ptr;
+          ptr = a.ptr;
+          /*please look away*/ const_cast<unique_ptr &>(a).ptr = 0;
+        }
+        return *this;
+      }
+  };
+}
+#endif
+%}
+
+%include "cpp11_move_only_helper.i"
+
+%valuewrapper XXX;
+%ignore XXX::operator=;
+
+%inline %{
+bool trace = false;
+struct XXX {
+  XXX(int i = 0) { if (trace) cout << "XXX(" << i << ")" << " " << this << endl; Counter::normal_constructor++; }
+  XXX(const XXX &other) { if (trace) cout << "XXX(const XXX &)" << " " << this << " " << &other << endl; Counter::copy_constructor++;}
+  XXX & operator=(const XXX &other) { if (trace) cout << "operator=(const XXX &)" << " " << this << " " << &other << endl; Counter::copy_assignment++; return *this; }
+#if defined(__cplusplus) && __cplusplus >= 201103L
+  XXX(XXX &&other) noexcept { if (trace) cout << "XXX(XXX &&)" << " " << this << endl; Counter::move_constructor++; }
+  XXX & operator=(XXX &&other) noexcept { if (trace) cout << "operator=(XXX &&)" << " " << this << endl; Counter::move_assignment++; return *this; }
+#endif
+  ~XXX() { if (trace) cout << "~XXX()" << " " << this << endl; Counter::destructor++; }
+};
+
+bool has_cplusplus11() {
+#if __cplusplus >= 201103L
+  return true;
+#else
+  return false;
+#endif
+}
+%}
+
+std::unique_ptr<XXX> makeUniqueXXX();
+void cleanup(std::unique_ptr<XXX>* p);
+
+%{
+std::unique_ptr<XXX> makeUniqueXXX() {
+  if (trace) cout << "makeUniqueXXX()" << endl;
+  return std::unique_ptr<XXX>(new XXX(11));
+}
+void cleanup(std::unique_ptr<XXX>* p) {
+  delete p;
+}
+typedef XXX UUU;
+%}
+
+%inline %{
+XXX createXXX() {
+  if (trace) cout << "createXXX()" << endl;
+  return XXX(111);
+}
+XXX createXXX2() {
+  if (trace) cout << "createXXX2()" << endl;
+  return XXX(222);
+}
+UUU createUnknownType() {
+  if (trace) cout << "createXXX2()" << endl;
+  return XXX(222);
+}
+struct YYY {};
+void inputByValue(UUU uuu, XXX xxx, YYY yyy) {}
+%}
+
+
+%catches(std::string) test1;
+%catches(std::string) test2;
+%catches(std::string) test3;
+%catches(std::string) test4;
+%catches(std::string) test5;
+%catches(std::string) test6;
+
+%inline %{
+// 'unit tests' for SwigValueWrapper
+void test1() {
+  Counter::reset_counts();
+  {
+    SwigValueWrapper<XXX> x;
+    x = XXX();
+  }
+#if __cplusplus >= 201103L
+  Counter::check_counts(1, 0, 0, 1, 0, 2); // was same as < c++11 counts below before move assignment operator added to SwigValueWrapper
+#else
+  Counter::check_counts(1, 1, 0, 0, 0, 2);
+#endif
+}
+void test2() {
+  Counter::reset_counts();
+  {
+    SwigValueWrapper<XXX> x;
+    x = XXX();
+    x = XXX();
+  }
+#if __cplusplus >= 201103L
+  Counter::check_counts(2, 0, 0, 2, 0, 4);
+#else
+  Counter::check_counts(2, 2, 0, 0, 0, 4);
+#endif
+}
+void test3() {
+  Counter::reset_counts();
+  {
+    SwigValueWrapper<XXX> x;
+    XXX a(999);
+#if __cplusplus >= 201103L
+    x = std::move(a);
+#endif
+  }
+#if __cplusplus >= 201103L
+  Counter::check_counts(1, 0, 0, 1, 0, 2);
+#endif
+}
+void test4() {
+  Counter::reset_counts();
+  {
+    SwigValueWrapper<std::unique_ptr<XXX> > x;
+    x = std::unique_ptr<XXX>(new XXX(444));
+  }
+  Counter::check_counts(1, 0, 0, 0, 0, 1);
+}
+void test5() {
+#if __cplusplus >= 201103L
+  Counter::reset_counts();
+  {
+    SwigValueWrapper<std::unique_ptr<XXX> > x;
+    x = std::unique_ptr<XXX>(new XXX(550));
+    std::unique_ptr<XXX> x2(new XXX(555));
+    x = std::move(x2);
+  }
+  Counter::check_counts(2, 0, 0, 0, 0, 2);
+#endif
+}
+void test6() {
+#if __cplusplus >= 201103L
+  Counter::reset_counts();
+  {
+    // emulates how std::unique_ptr typemaps could be wrapped with SwigValueWrapper
+    void *ptr = 0;
+    SwigValueWrapper<std::unique_ptr<XXX> > x; // SWIG generated if std::unique_ptr<> definition not parsed
+    x = makeUniqueXXX(); // SWIG generated code wrapping function returning std::unique_ptr
+    ptr = new std::unique_ptr<XXX>(x); // 'out' typemap (move std::unique_ptr from stack to the heap)
+    delete (std::unique_ptr<XXX> *)ptr; // Final cleanup (user needs to call this)
+  }
+  Counter::check_counts(1, 0, 0, 0, 0, 1);
+#endif
+}
+%}
diff --git a/Examples/test-suite/cpp11_move_typemaps.i b/Examples/test-suite/cpp11_move_typemaps.i
new file mode 100644
index 0000000..706780a
--- /dev/null
+++ b/Examples/test-suite/cpp11_move_typemaps.i
@@ -0,0 +1,12 @@
+%module cpp11_move_typemaps
+
+%include <swigmove.i>
+%apply SWIGTYPE MOVE { MoveOnly mo }
+%valuewrapper MovableCopyable;
+%apply SWIGTYPE MOVE { MovableCopyable mc }
+
+%inline %{
+#define WRAP_TAKE_METHOD
+%}
+
+%include "cpp11_move_only.i"
diff --git a/Examples/test-suite/cpp11_noexcept.i b/Examples/test-suite/cpp11_noexcept.i
index 8aa0baa..6b05844 100644
--- a/Examples/test-suite/cpp11_noexcept.i
+++ b/Examples/test-suite/cpp11_noexcept.i
@@ -1,5 +1,7 @@
 %module cpp11_noexcept
 
+%ignore NoExceptAbstract::operator std::string;
+%ignore NoExceptAbstract::operator int;
 %ignore NoExceptClass(NoExceptClass&&);
 %rename(Assignment) NoExceptClass::operator=;
 
@@ -7,6 +9,7 @@
 extern "C" void global_noexcept(int, bool) noexcept {}
 %}
 %inline %{
+#include <string>
 
 extern "C" void global_noexcept(int, bool) noexcept;
 extern "C" void global_noexcept2(int, bool) noexcept {}
@@ -43,6 +46,9 @@
 struct NoExceptAbstract {
   virtual void noo4() const noexcept = 0;
   virtual ~NoExceptAbstract() noexcept = 0;
+  // Regression test for https://github.com/swig/swig/issues/2474
+  virtual explicit operator std::string() const noexcept = 0;
+  explicit virtual operator int() const noexcept = 0;
 };
 
 struct NoExceptDefaultDelete {
diff --git a/Examples/test-suite/cpp11_raw_string_literals.i b/Examples/test-suite/cpp11_raw_string_literals.i
index b50b768..fb86137 100644
--- a/Examples/test-suite/cpp11_raw_string_literals.i
+++ b/Examples/test-suite/cpp11_raw_string_literals.i
@@ -1,7 +1,7 @@
 /* This module tests whether SWIG correctly parses:
-   -    ordinary strings (char_t)
+   -    ordinary strings (char)
    - L  wide strings (wchar_t)
-   - u8 unicode8 strings (char_t)
+   - u8 unicode8 strings (char / char8_t since C++20)
    - u  unicode16 strings (char16_t)
    - U  unicode32 strings (char32_t)
 
@@ -21,6 +21,11 @@
 %include <std_wstring.i>
 #endif
 
+#if defined(SWIGLUA)
+// Lua uses a parameter called L in every wrapper function
+%ignore L;
+#endif
+
 %inline %{
 #include <iostream>
 #include <string>
@@ -44,7 +49,8 @@
 
 // New string literals
 wstring         aa =  L"Wide string";
-const char     *bb = u8"UTF-8 string";
+// u8"" is const char8_t[N] in C++20; const char[N] from C++11 until then.
+const char     *bb = reinterpret_cast<const char*>(u8"UTF-8 string");
 const char16_t *cc =  u"UTF-16 string";
 const char32_t *dd =  U"UTF-32 string";
 // New char literals
@@ -57,7 +63,7 @@
 const char      *xx =        ")I'm an \"ascii\" \\ string.";
 const char      *ee =   R"XXX()I'm an "ascii" \ string.)XXX";
 wstring          ff =  LR"XXX(I'm a "raw wide" \ string.)XXX";
-const char      *gg = u8R"XXX(I'm a "raw UTF-8" \ string.)XXX";
+const char      *gg = reinterpret_cast<const char*>(u8R"XXX(I'm a "raw UTF-8" \ string.)XXX");
 const char16_t  *hh =  uR"XXX(I'm a "raw UTF-16" \ string.)XXX";
 const char32_t  *ii =  UR"XXX(I'm a "raw UTF-32" \ string.)XXX";
 %}
diff --git a/Examples/test-suite/cpp11_ref_qualifiers.i b/Examples/test-suite/cpp11_ref_qualifiers.i
index e371367..23698f0 100644
--- a/Examples/test-suite/cpp11_ref_qualifiers.i
+++ b/Examples/test-suite/cpp11_ref_qualifiers.i
@@ -18,18 +18,18 @@
 public:
   string h1() & { return string(); }
   string h2() const & { return string(); }
-  string h3() && { return std::move(string()); }
-  string h4() const && { return std::move(string()); }
+  string h3() && { return string(); }
+  string h4() const && { return string(); }
   string h5() const { return string(); }
   string h6() volatile const & { return string(); }
   string h7() const volatile & { return string(); }
-  string h8() volatile const && { return std::move(string()); }
-  string h9() const volatile && { return std::move(string()); }
+  string h8() volatile const && { return string(); }
+  string h9() const volatile && { return string(); }
 
   string h() & { return string(); }
   string h() const & { return string(); }
-  string h() && { return std::move(string()); }
-  string h() const && { return std::move(string()); }
+  string h() && { return string(); }
+  string h() const && { return string(); }
 };
 %}
 
@@ -89,11 +89,11 @@
 %inline %{
 struct ConversionOperators {
   virtual operator string() & { return string(); }
-  virtual operator string() && { return std::move(string()); }
+  virtual operator string() && { return string(); }
   virtual ~ConversionOperators() {}
 };
 struct ConversionOperators2 {
-  virtual operator string() && { return std::move(string()); }
+  virtual operator string() && { return string(); }
   virtual ~ConversionOperators2() {}
 };
 %}
diff --git a/Examples/test-suite/cpp11_result_of.i b/Examples/test-suite/cpp11_result_of.i
index 8a26c5f..f377054 100644
--- a/Examples/test-suite/cpp11_result_of.i
+++ b/Examples/test-suite/cpp11_result_of.i
@@ -2,11 +2,28 @@
    and its templating capabilities introduced in C++11. */
 %module cpp11_result_of
 
+// std::result_of is deprecated in C++17
+// Replace std implementation with a simple implementation in order to continue testing with C++17 compilers and later
+
 %inline %{
-#include <functional>
 typedef double(*fn_ptr)(double);
 %}
 
+%{
+#if __cplusplus >= 201703L
+namespace std {
+  // Forward declaration of result_of
+  template<typename Func> struct result_of;
+  // Add in the required partial specialization of result_of
+  template<> struct result_of< fn_ptr(double) > {
+    typedef double type;
+  };
+}
+#else
+#include <functional>
+#endif
+%}
+
 namespace std {
   // Forward declaration of result_of
   template<typename Func> struct result_of;
@@ -34,22 +51,14 @@
 }
 %}
 
-%{
-// Another alternative approach using decltype (not very SWIG friendly)
-std::result_of< decltype(square)&(double) >::type test_result_alternative2(double(*fun)(double), double arg) {
-  return fun(arg);
-}
-%}
-
 %inline %{
 #include <iostream>
 
 void cpp_testing() {
-  std::cout << "result: " << test_result_impl(square, 3) << std::endl;
-  std::cout << "result: " << test_result_impl<double(*)(double), double>(square, 4) << std::endl;
-  std::cout << "result: " << test_result_impl< fn_ptr, double >(square, 5) << std::endl;
-  std::cout << "result: " << test_result_alternative1(square, 6) << std::endl;
-  std::cout << "result: " << test_result_alternative2(square, 7) << std::endl;
+  std::cout << "result: " << test_result_impl(square, 3.0) << std::endl;
+  std::cout << "result: " << test_result_impl<double(*)(double), double>(square, 4.0) << std::endl;
+  std::cout << "result: " << test_result_impl< fn_ptr, double >(square, 5.0) << std::endl;
+  std::cout << "result: " << test_result_alternative1(square, 6.0) << std::endl;
 }
 %}
 
diff --git a/Examples/test-suite/cpp11_rvalue_reference2.i b/Examples/test-suite/cpp11_rvalue_reference2.i
index a2a0020..a3af6da 100644
--- a/Examples/test-suite/cpp11_rvalue_reference2.i
+++ b/Examples/test-suite/cpp11_rvalue_reference2.i
@@ -20,10 +20,10 @@
 static const UserDef PublicUserDef = UserDef();
 struct Thingy {
   typedef int Integer;
-  int val;
+  int valval;
   int &lvalref;
   int &&rvalref;
-  Thingy(int v, int &&rvalv) : val(v), lvalref(val), rvalref(std::move(rvalv)) {}
+  Thingy(int v, int &&rvalv) : valval(v), lvalref(valval), rvalref(std::move(rvalv)) {}
   void refIn(long &i) {}
   void rvalueIn(long &&i) {}
   short && rvalueInOut(short &&i) { return std::move(i); }
@@ -31,10 +31,10 @@
   // test both primitive and user defined rvalue reference default arguments and compactdefaultargs
   void compactDefaultArgs(const bool &&b = (const bool &&)PublicGlobalTrue, const UserDef &&u  = (const UserDef &&)PublicUserDef) {}
   void privateDefaultArgs(const bool &&b = (const bool &&)PrivateTrue) {}
-  operator int &&() { return std::move(val); }
-  Thingy(const Thingy& rhs) : val(rhs.val), lvalref(rhs.lvalref), rvalref(std::move(rhs.rvalref)) {}
+  operator int &&() { return std::move(valval); }
+  Thingy(const Thingy& rhs) : valval(rhs.valval), lvalref(rhs.lvalref), rvalref(std::move(rhs.rvalref)) {}
   Thingy& operator=(const Thingy& rhs) {
-    val = rhs.val;
+    valval = rhs.valval;
     lvalref = rhs.lvalref;
     rvalref = rhs.rvalref;
     return *this;
diff --git a/Examples/test-suite/cpp11_rvalue_reference3.i b/Examples/test-suite/cpp11_rvalue_reference3.i
index 8ebf453..55a55ba 100644
--- a/Examples/test-suite/cpp11_rvalue_reference3.i
+++ b/Examples/test-suite/cpp11_rvalue_reference3.i
@@ -24,19 +24,19 @@
 void takeit4(Thing *const&& t) {}
 void takeit5(Thing const*const&& t) {}
 
-struct Containing {
-  Thing && member_rvalue_ref;
-  Thing *&& member_rvalue_ref_ptr1;
-  Thing const*&& member_rvalue_ref_ptr2;
-  Thing *const&& member_rvalue_ref_ptr3;
-  Thing const*const &&member_rvalue_ref_ptr4;
+struct Contain {
+  Thing && m_ref;
+  Thing *&& m_ref_ptr1;
+  Thing const*&& m_ref_ptr2;
+  Thing *const&& m_ref_ptr3;
+  Thing const*const &&m_ref_ptr4;
 
-  Containing(Thing&&r, Thing*&& r1, Thing const*&& r2, Thing *const&& r3, Thing const*const && r4) :
-    member_rvalue_ref(std::move(r)), 
-    member_rvalue_ref_ptr1(std::move(r1)),
-    member_rvalue_ref_ptr2(std::move(r2)),
-    member_rvalue_ref_ptr3(std::move(r3)),
-    member_rvalue_ref_ptr4(std::move(r4))
+  Contain(Thing&&r, Thing*&& r1, Thing const*&& r2, Thing *const&& r3, Thing const*const && r4) :
+    m_ref(std::move(r)),
+    m_ref_ptr1(std::move(r1)),
+    m_ref_ptr2(std::move(r2)),
+    m_ref_ptr3(std::move(r3)),
+    m_ref_ptr4(std::move(r4))
     {}
 };
 %}
@@ -61,19 +61,19 @@
 void int_takeit4(int *const&& t) {}
 void int_takeit5(int const*const&& t) {}
 
-struct IntContaining {
-  int && member_rvalue_ref;
-  int *&& member_rvalue_ref_ptr1;
-  int const*&& member_rvalue_ref_ptr2;
-  int *const&& member_rvalue_ref_ptr3;
-  int const*const &&member_rvalue_ref_ptr4;
+struct IContain {
+  int && m_ref;
+  int *&& m_ref_ptr1;
+  int const*&& m_ref_ptr2;
+  int *const&& m_ref_ptr3;
+  int const*const &&m_ref_ptr4;
 
-  IntContaining(int&& r, int*&& r1, int const*&& r2, int *const&& r3, int const*const && r4) :
-    member_rvalue_ref(std::move(r)),
-    member_rvalue_ref_ptr1(std::move(r1)),
-    member_rvalue_ref_ptr2(std::move(r2)),
-    member_rvalue_ref_ptr3(std::move(r3)),
-    member_rvalue_ref_ptr4(std::move(r4))
+  IContain(int&& r, int*&& r1, int const*&& r2, int *const&& r3, int const*const && r4) :
+    m_ref(std::move(r)),
+    m_ref_ptr1(std::move(r1)),
+    m_ref_ptr2(std::move(r2)),
+    m_ref_ptr3(std::move(r3)),
+    m_ref_ptr4(std::move(r4))
     {}
 };
 %}
diff --git a/Examples/test-suite/cpp11_rvalue_reference_move.i b/Examples/test-suite/cpp11_rvalue_reference_move.i
new file mode 100644
index 0000000..04cd2b8
--- /dev/null
+++ b/Examples/test-suite/cpp11_rvalue_reference_move.i
@@ -0,0 +1,52 @@
+%module cpp11_rvalue_reference_move
+
+// Testcase for testing rvalue reference input typemaps which assume the object is moved during a function call
+
+%include "cpp11_move_only_helper.i"
+
+%catches(std::string) MovableCopyable::check_numbers_match;
+
+%rename(MoveAssign) MovableCopyable::operator=(MovableCopyable &&);
+%ignore MovableCopyable::operator=(const MovableCopyable &); // ignore copy assignment operator, keep move assignment operator
+%ignore MovableCopyable::MovableCopyable(const MovableCopyable &); // ignore copy constructor, keep the move constructor
+
+%inline %{
+#include <iostream>
+using namespace std;
+
+bool trace = false;
+
+class MovableCopyable {
+  int num;
+public:
+  MovableCopyable(int i = 0) : num(i) { if (trace) cout << "MovableCopyable(" << i << ")" << " " << this << endl; Counter::normal_constructor++; }
+
+  MovableCopyable(const MovableCopyable &other) : num(other.num) { if (trace) cout << "MovableCopyable(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_constructor++;}
+  MovableCopyable & operator=(const MovableCopyable &other) { if (trace) cout << "operator=(const MovableCopyable &)" << " " << this << " " << &other << endl; Counter::copy_assignment++; num = other.num; return *this; }
+
+  MovableCopyable(MovableCopyable &&other) noexcept : num(std::move(other.num)) { if (trace) cout << "MovableCopyable(MovableCopyable &&)" << " " << this << endl; Counter::move_constructor++; }
+  MovableCopyable & operator=(MovableCopyable &&other) noexcept { if (trace) cout << "operator=(MovableCopyable &&)" << " " << this << endl; Counter::move_assignment++; num = std::move(other.num); return *this; }
+  ~MovableCopyable() { if (trace) cout << "~MovableCopyable()" << " " << this << endl; Counter::destructor++; }
+
+  int getNum() { return num; }
+
+  static void movein(MovableCopyable &&mcin) {
+    MovableCopyable mc = std::move(mcin);
+  }
+
+  static MovableCopyable && moveout(int i) {
+    static MovableCopyable instance;
+    instance = MovableCopyable(i);
+    return std::move(instance);
+  }
+
+  static bool is_nullptr(MovableCopyable *p) {
+    return p == nullptr;
+  }
+
+  static void check_numbers_match(MovableCopyable *p, int expected_num) {
+    if (p->num != expected_num)
+      throw std::string("Numbers don't match");
+  }
+};
+%}
diff --git a/Examples/test-suite/cpp11_shared_ptr_crtp_upcast.i b/Examples/test-suite/cpp11_shared_ptr_crtp_upcast.i
new file mode 100644
index 0000000..f00dc1f
--- /dev/null
+++ b/Examples/test-suite/cpp11_shared_ptr_crtp_upcast.i
@@ -0,0 +1,92 @@
+%module cpp11_shared_ptr_crtp_upcast
+
+// Cutdown testcase for assert reported in https://github.com/swig/swig/issues/2768
+// Note that this test has CRTP and %template instantiations for DiscretisedDensity template parameters not fully resolved
+
+%warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE,
+	    SWIGWARN_CSHARP_MULTIPLE_INHERITANCE,
+	    SWIGWARN_D_MULTIPLE_INHERITANCE,
+	    SWIGWARN_RUBY_MULTIPLE_INHERITANCE,
+	    SWIGWARN_PHP_MULTIPLE_INHERITANCE) stir::DiscretisedDensity<3,float>;
+
+%include <std_shared_ptr.i>
+
+%{
+#include <memory>
+namespace stir {}
+using namespace stir;
+%}
+
+%inline %{
+namespace stir {
+  // Note: CRTP
+  template <typename Derived, typename Base, typename Parent = Base>
+  class RegisteredParsingObject : public Parent {
+  };
+}
+%}
+
+%shared_ptr(stir::Array<3,float>)
+%inline %{
+namespace stir {
+  template <int num_dimensions, typename elemT>
+  class Array {
+  };
+}
+%}
+%template(FloatArray3D) stir::Array<3,float>;
+
+%shared_ptr(stir::ExamData);
+%inline %{
+namespace stir {
+  class ExamData {
+  };
+}
+%}
+
+%shared_ptr(stir::DiscretisedDensity<3,float>)
+%inline %{
+namespace stir {
+  template<int num_dimensions, typename elemT>
+  class DiscretisedDensity : public ExamData, public Array<num_dimensions,elemT> {
+  };
+}
+%}
+
+%shared_ptr(stir::DataProcessor<stir::DiscretisedDensity<3,float> >)
+%shared_ptr(stir::RegisteredParsingObject<
+            stir::ChainedDataProcessor<stir::DiscretisedDensity<3,float> >,
+            stir::DataProcessor<DiscretisedDensity<3,float> >,
+	    stir::DataProcessor<DiscretisedDensity<3,float> > >)
+%shared_ptr(stir::ChainedDataProcessor<stir::DiscretisedDensity<3,float> >)
+
+%inline %{
+namespace stir {
+  template <typename DataT>
+  class DataProcessor {
+  };
+
+  template <typename DataT>
+  class ChainedDataProcessor : public RegisteredParsingObject< ChainedDataProcessor<DataT>, DataProcessor<DataT>, DataProcessor<DataT> > {
+  };
+}
+%}
+
+// SWIG will qualify Discretised in the %template() declaration even though Discretised
+// is not in scope with the 'using namespace stir' below commented out.
+//using namespace stir;
+%template(Float3DDiscretisedDensity) stir::DiscretisedDensity<3,float>;
+%template(DataProcessor3DFloat) stir::DataProcessor<stir::DiscretisedDensity<3,float> >;
+%template(RPChainedDataProcessor3DFloat) stir::RegisteredParsingObject<
+                                         stir::ChainedDataProcessor<stir::DiscretisedDensity<3,float> >,
+                                         stir::DataProcessor<DiscretisedDensity<3,float> >,
+                                         stir::DataProcessor<DiscretisedDensity<3,float> > >;
+%template(ChainedDataProcessor3DFloat) stir::ChainedDataProcessor<stir::DiscretisedDensity<3,float> >;
+
+%inline %{
+void useobject(stir::RegisteredParsingObject<
+               stir::ChainedDataProcessor<stir::DiscretisedDensity<3,float> >,
+               stir::DataProcessor<DiscretisedDensity<3,float> >,
+               stir::DataProcessor<DiscretisedDensity<3,float> > >) {
+}
+%}
diff --git a/Examples/test-suite/cpp11_shared_ptr_template_upcast.i b/Examples/test-suite/cpp11_shared_ptr_template_upcast.i
new file mode 100644
index 0000000..38968bb
--- /dev/null
+++ b/Examples/test-suite/cpp11_shared_ptr_template_upcast.i
@@ -0,0 +1,88 @@
+%module cpp11_shared_ptr_template_upcast
+
+%{
+#include <memory>
+#include <string>
+%}
+
+%include <std_shared_ptr.i>
+%include <std_string.i>
+
+%{
+class Base {
+public:
+    Base() : value(0) {}
+    Base(int v) : value(v) {}
+    virtual ~Base() {}
+    
+    virtual int GetResult() = 0;
+    
+    int value;
+};
+
+class Derived : public Base {
+public:
+    Derived() : Base() {}
+    Derived(int v) : Base(v) {}
+    virtual ~Derived() {}
+    
+    int GetResult() { return value*2; }
+};
+
+template <class T> class Printable : virtual public T {
+public:
+    Printable(int param) : T(param) {}
+    ~Printable() {}
+
+    std::string GetFormatted() { return std::string("The formatted result is: ").append(std::to_string(this->GetResult())); }
+};
+
+std::shared_ptr<Printable<Derived> > MakePrintableDerived(int param) {
+    return std::make_shared<Printable<Derived> >(param);
+}
+
+%}
+
+%shared_ptr(Base);
+%shared_ptr(Derived);
+%shared_ptr(Printable<Derived>)
+
+class Base {
+public:
+    Base();
+    Base(int v);
+    virtual ~Base();
+    
+    virtual int GetResult() = 0;
+    
+    int value;
+};
+
+class Derived : public Base {
+public:
+    Derived();
+    Derived(int v);
+    virtual ~Derived();
+    
+    int GetResult();
+};
+
+/*
+    Virtual inheritance is contrived for this case, but exposes whether SWIGSmartPtrUpcast generated a correctly typed shared pointer of the upcasted class type -
+    if the pointer type is incorrect, this will result in a segmentation fault (on Windows, this could manifest as undefined behavior) when trying to access members 
+    inherited from T through a shared_ptr<Printable<T> >.
+*/
+template <class T> class Printable : virtual public T {
+public:
+    Printable(int param);
+    ~Printable();
+
+    std::string GetFormatted();
+};
+
+std::shared_ptr<Printable<Derived> > MakePrintableDerived(int param);
+
+
+%template(PrintableDerived) Printable<Derived>;
+
+
diff --git a/Examples/test-suite/cpp11_std_array.i b/Examples/test-suite/cpp11_std_array.i
index 3d47715..ce87db7 100644
--- a/Examples/test-suite/cpp11_std_array.i
+++ b/Examples/test-suite/cpp11_std_array.i
@@ -1,6 +1,6 @@
 %module cpp11_std_array
 
-#if defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGJAVA) || defined(SWIGCSHARP)
+#if defined(SWIGPYTHON) || defined(SWIGRUBY) || defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGGO)
 
 %{
 #include <array>
@@ -57,6 +57,16 @@
     val *= 10;
   }
 }
+
+std::array<int, 6> overloadFunc(std::array<int, 6> myarray) {
+  std::array<int, 6> newarray(myarray);
+  for (auto& val : newarray) {
+    val *= 100;
+  }
+  return newarray;
+}
+void overloadFunc(int i, int j) {
+}
 %}
 
 #endif
diff --git a/Examples/test-suite/cpp11_std_unique_ptr.i b/Examples/test-suite/cpp11_std_unique_ptr.i
new file mode 100644
index 0000000..f360d8c
--- /dev/null
+++ b/Examples/test-suite/cpp11_std_unique_ptr.i
@@ -0,0 +1,107 @@
+%module cpp11_std_unique_ptr
+
+#if !(defined(SWIGGO) || defined(SWIGOCAML) || defined(SWIGR) || defined(SWIGSCILAB))
+
+%warnfilter(509, 516) overloadTest(Klass);
+
+%include "std_string.i"
+%include "std_unique_ptr.i"
+
+%unique_ptr(Klass)
+
+%inline %{
+#include <memory>
+#include <string>
+//#include <iostream>
+#include "swig_examples_lock.h"
+
+class Klass {
+public:
+  explicit Klass(const char* label) :
+    m_label(label)
+  {
+    SwigExamples::Lock lock(critical_section);
+    total_count++;
+  }
+
+  const char* getLabel() const { return m_label.c_str(); }
+
+  virtual ~Klass()
+  {
+    SwigExamples::Lock lock(critical_section);
+    total_count--;
+  }
+
+  static int getTotal_count() { return total_count; }
+
+private:
+  static SwigExamples::CriticalSection critical_section;
+  static int total_count;
+
+  std::string m_label;
+};
+
+SwigExamples::CriticalSection Klass::critical_section;
+int Klass::total_count = 0;
+
+%}
+
+%inline %{
+
+// Virtual inheritance used as this usually results in different values for Klass* and KlassInheritance*
+// for testing class inheritance and unique_ptr
+struct KlassInheritance : virtual Klass {
+  KlassInheritance(const char* label) : Klass(label) {
+    // std::cout << "ptrs.... " << std::hex << (Klass*)this << " " << (KlassInheritance*)this << std::endl;
+  }
+};
+
+std::string useKlassRawPtr(Klass* k) {
+//  std::cout << "useKlassRawPtr " << std::hex << (Klass*)k << std::endl;
+  std::string s(k->getLabel());
+//  std::cout << "useKlassRawPtr string: " << s << std::endl;
+  return s;
+}
+
+std::string takeKlassUniquePtr(std::unique_ptr<Klass> k) {
+//  std::cout << "takeKlassUniquePtr " << std::hex << (Klass*)k.get() << std::endl;
+  std::string s(k ? k->getLabel() : "null smart pointer");
+//  std::cout << "takeKlassUniquePtr string: " << s << std::endl;
+  return s;
+}
+
+Klass *make_null() {
+  return nullptr;
+}
+
+bool is_nullptr(Klass *p) {
+  return p == nullptr;
+}
+
+Klass *get_not_owned_ptr(Klass *p) {
+  return p;
+}
+
+std::unique_ptr<Klass> makeKlassUniquePtr(const char* label) {
+  return std::unique_ptr<Klass>(new Klass(label));
+}
+
+std::unique_ptr<Klass> makeNullUniquePtr() {
+  return std::unique_ptr<Klass>();
+}
+
+int overloadTest() {
+  return 0;
+}
+
+int overloadTest(std::unique_ptr<Klass> kover) {
+  return 1;
+}
+
+int overloadTest(Klass k) {
+  return 2;
+}
+
+%}
+
+#endif
diff --git a/Examples/test-suite/cpp11_strongly_typed_enumerations.i b/Examples/test-suite/cpp11_strongly_typed_enumerations.i
index 64fdd2b..d08f077 100644
--- a/Examples/test-suite/cpp11_strongly_typed_enumerations.i
+++ b/Examples/test-suite/cpp11_strongly_typed_enumerations.i
@@ -5,12 +5,13 @@
 %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Class1::Struct1;
 %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) Class2::Struct1;
 
-/* Forward declarations (illegally accepted by SWIG - oh well!) */
-enum Enum1 : short;
+// Some illegal forward declarations (incorrectly accepted by SWIG - oh well!)
 enum Enum3;
 enum ;
 enum : unsigned short;
 
+enum Enum1 : short; // should error as mismatches Enum1 class below
+
 %inline %{
 enum class Enum1 {
   Val1,
@@ -65,7 +66,17 @@
   typedef T type_name;
 };
 
-enum class Enum10 : TType<int>::type_name {
+using EnumBase9 = unsigned short;
+enum class Enum9: EnumBase9 {
+  Val1 = 0,
+  Val2 = 0x2,
+};
+%}
+
+%template() TType<unsigned char>; // Instantiate template for underlying type used in Enum10
+
+%inline %{
+enum class Enum10 : TType<unsigned char>::type_name {
   Val1, Val2, Val3 = 103, Val4
 };
 
@@ -223,3 +234,32 @@
 };
 %}
 
+// Target language underlying enum type manipulation
+#if defined(SWIGCSHARP)
+%typemap(csbase, replace="1") Enum15 "short"
+%typemap(csbase) Enum16 "short"
+%warnfilter(SWIGWARN_CSHARP_MULTIPLE_INHERITANCE) Enum16;
+%typemap(csbase) Enum17 "ulong"
+#elif defined(SWIGD)
+%typemap(dbase, replace="1") Enum15 "short"
+%typemap(dbase) Enum16 "short"
+%warnfilter(SWIGWARN_D_MULTIPLE_INHERITANCE) Enum16;
+%typemap(dbase) Enum17 "uint"
+#endif
+%inline %{
+  enum class Enum15 : long long
+  {
+    Val1 = 1151,
+    Val2 = 1152,
+  };
+  enum class Enum16 : long long
+  {
+    Val1 = 1161,
+    Val2 = 1162,
+  };
+  enum class Enum17
+  {
+    Val1 = 1171,
+    Val2 = 1172,
+  };
+%}
diff --git a/Examples/test-suite/cpp11_template_double_brackets.i b/Examples/test-suite/cpp11_template_double_brackets.i
index ba5caa5..d7522c9 100644
--- a/Examples/test-suite/cpp11_template_double_brackets.i
+++ b/Examples/test-suite/cpp11_template_double_brackets.i
@@ -1,5 +1,5 @@
 /* This interface checks whether SWIG supports the new double angled brackets
-   in the template syntax without having a space inbetween. This feature was
+   in the template syntax without having a space in between. This feature was
    introduced in new C++11 standard.
 */
 %module cpp11_template_double_brackets
diff --git a/Examples/test-suite/cpp11_template_explicit.i b/Examples/test-suite/cpp11_template_explicit.i
index 71752f8..950f1d2 100644
--- a/Examples/test-suite/cpp11_template_explicit.i
+++ b/Examples/test-suite/cpp11_template_explicit.i
@@ -4,13 +4,15 @@
 */
 %module cpp11_template_explicit
 
+/* Suppress SWIG warnings related to explicit template instantiation and extern templates */
 #pragma SWIG nowarn=SWIGWARN_PARSE_EXPLICIT_TEMPLATE
+#pragma SWIG nowarn=SWIGWARN_PARSE_EXTERN_TEMPLATE
 
 %inline %{
 
 template<typename T> class Temper {
 public:
-  T val;
+  T valu;
 };
 
 class A {
@@ -33,6 +35,30 @@
 
 template class Temper<int>;
 extern template class Temper<short>;
+
+/* Templated function to check support for extern template functions */
+template <typename T>
+T my_templated_function(int a, double b)
+{
+  return T();
+}
+
+/* Explicit extern function template instantiation with simple type */
+extern template int my_templated_function<int>(int, double);
+template int my_templated_function<int>(int, double);
+
+/* Explicit extern function template instantiation with more complex types */
+extern template A my_templated_function<A>(int, double);
+template A my_templated_function<A>(int, double);
+
+extern template Temper<int> my_templated_function<Temper<int>>(int, double);
+template Temper<int> my_templated_function<Temper<int>>(int, double);
+
 %}
 
 %template(TemperInt) Temper<int>;
+
+/* Enable several versions of the templated function */
+%template(my_templated_function_int      ) my_templated_function<int>;
+%template(my_templated_function_A        ) my_templated_function<A>;
+%template(my_templated_function_TemperInt) my_templated_function<Temper<int>>;
diff --git a/Examples/test-suite/cpp11_template_parameters_decltype.i b/Examples/test-suite/cpp11_template_parameters_decltype.i
new file mode 100644
index 0000000..0d05bb8
--- /dev/null
+++ b/Examples/test-suite/cpp11_template_parameters_decltype.i
@@ -0,0 +1,107 @@
+%module cpp11_template_parameters_decltype
+
+%inline %{
+// Github issue #1589
+template <decltype(true) X = true>
+void A() { }
+%}
+
+// %template(A) A<>; // not working
+%template(A) A<true>; // workaround
+
+
+%include <std_string.i>
+%include <std_vector.i>
+%include <std_map.i>
+
+#pragma SWIG nowarn=SWIGWARN_CPP11_DECLTYPE
+
+%{
+// Simple implementation of helper functions required in test below
+std::string array(std::vector<std::string>::const_iterator begin, std::vector<std::string>::const_iterator end) {
+  return "not implemented";
+}
+std::string object(std::map<std::string, std::string>::const_iterator begin, std::map<std::string, std::string>::const_iterator end) {
+  return "not implemented";
+}
+%}
+
+%inline %{
+#include <iostream>
+
+// Github issue #1590
+struct Converter {
+  std::string to_json() const { return std::string(); }
+};
+struct Json {
+  int ctor;
+  Json(std::string s) : ctor(0) {}
+  template < class T, class = decltype(&T::to_json) >
+    Json(const T & t) : Json(t.to_json()) { ctor = 1; }
+
+// Github issue #1589
+  // Implicit constructor: map-like objects (std::map, std::unordered_map, etc)
+  template <class M, typename std::enable_if<
+      std::is_constructible<std::string, decltype(std::declval<M>().begin()->first)>::value,
+      int>::type = 0>
+          Json(const M & m) : Json(object(m.begin(), m.end())) { ctor = 2; }
+  // Implicit constructor: vector-like objects (std::list, std::vector, std::set, etc)
+  template <class V, typename std::enable_if<
+      std::is_constructible<Json, decltype(*std::declval<V>().begin())>::value,
+          int>::type = 0>
+  Json(const V & v) : Json(array(v.begin(), v.end())) { ctor = 3; }
+
+  // Same sort of thing as constructors above but for a member function
+  int mmm(std::string s) { return 100; }
+  template < class T, class = decltype(&T::to_json) >
+    int mmm(const T & t) { return 101; }
+  template <class M, typename std::enable_if<
+    std::is_constructible<std::string, decltype(std::declval<M>().begin()->first)>::value,
+    int>::type = 0>
+      int mmm(const M & m) { return 102; }
+  template <class V, typename std::enable_if<
+    std::is_constructible<Json, decltype(*std::declval<V>().begin())>::value,
+    int>::type = 0>
+      int mmm(const V & v) { return 103; }
+};
+
+void tester(bool show) {
+  // Example usage from c++
+  if (show) {
+    Json json0(std::string("hi"));
+    Converter converter;
+    std::cout << "json0 " << json0.ctor << std::endl;
+    Json json1 = Json(converter);
+    std::cout << "json1 " << json1.ctor << std::endl;
+    std::map<std::string, std::string> myStringStringMap;
+    Json json2 = Json(myStringStringMap);
+    std::cout << "json2 " << json2.ctor << std::endl;
+    std::vector<std::string> myVectorString;
+    Json json3 = Json(myVectorString);
+    std::cout << "json3 " << json3.ctor << std::endl;
+
+    std::cout << "json0.mmm " << json0.mmm("bye") << std::endl;
+    std::cout << "json1.mmm " << json1.mmm(converter) << std::endl;
+    std::cout << "json2.mmm " << json2.mmm(myStringStringMap) << std::endl;
+    std::cout << "json3.mmm " << json3.mmm(myVectorString) << std::endl;
+  }
+}
+%}
+
+%template(VectorString) std::vector<std::string>;
+%template(MapStringString) std::map<std::string, std::string>;
+
+// There is quite a bit of inconsistency about providing or not providing default
+// template parameters that needs investigating. Below is a combination that works.
+
+// Note that instantiating the two Json constructors (or the two mmm methods) that
+// use enable_if is ambiguous given the enable_if is not evaluated by SWIG.
+
+// %template(Json) Json::Json<Converter>; // not working
+%template(Json) Json::Json<Converter, std::string>; // workaround
+%template(Json) Json::Json<std::map<std::string, std::string>, 0>;
+%template(Json) Json::Json<std::vector<std::string>, 0>;
+
+%template(mmm) Json::mmm<Converter, std::string>;
+%template(mmm) Json::mmm<std::map<std::string, std::string>, 0>;
+%template(mmm) Json::mmm<std::vector<std::string>, 0>;
diff --git a/Examples/test-suite/cpp11_template_templated_methods.i b/Examples/test-suite/cpp11_template_templated_methods.i
new file mode 100644
index 0000000..712f85c
--- /dev/null
+++ b/Examples/test-suite/cpp11_template_templated_methods.i
@@ -0,0 +1,136 @@
+%module cpp11_template_templated_methods
+
+// Testing templated methods in a template
+// Including variadic templated method reported in https://github.com/swig/swig/issues/2794
+
+#if defined(SWIGLUA) || defined(SWIGOCAML)
+%rename(end_renamed) end;
+%rename(begin_renamed) begin;
+#endif
+
+%include <std_vector.i>
+
+%inline %{
+namespace eprosima {
+namespace fastrtps {
+
+template <
+    typename _Ty,
+    typename _Collection = std::vector<_Ty> >
+class ResourceLimitedVector
+{
+public:
+
+    using collection_type = _Collection;
+    using value_type = _Ty;
+    using pointer = typename collection_type::pointer;
+    using const_pointer = typename collection_type::const_pointer;
+    using reference = typename collection_type::reference;
+    using const_reference = typename collection_type::const_reference;
+    using size_type = typename collection_type::size_type;
+    using difference_type = typename collection_type::difference_type;
+    using iterator = typename collection_type::iterator;
+    using const_iterator = typename collection_type::const_iterator;
+    using reverse_iterator = typename collection_type::reverse_iterator;
+    using const_reverse_iterator = typename collection_type::const_reverse_iterator;
+
+    // Templated method in template
+    template <class InputIterator>
+    void assign( InputIterator first, InputIterator last)
+    {
+        size_type n = static_cast<size_type>(std::distance(first, last));
+        InputIterator value = first;
+        std::advance(value, n);
+        collection_.assign(first, value);
+    }
+
+    // Templated method in template using template parameter from the templated method (InputIterator) and the class (_Ty)
+    template <class InputIterator>
+    void assign_and_append( InputIterator first, InputIterator last, const _Ty& val)
+    {
+        assign(first, last);
+        collection_.push_back(val);
+    }
+
+    // Variadic templated method in template
+    template<typename ... Args>
+    void emplace_back( Args&& ... args )
+    {
+        collection_.emplace_back(args ...);
+    }
+
+    // Variadic templated constructor in template
+    template<typename ... Args>
+    ResourceLimitedVector( Args&& ... args )
+    {
+        collection_.emplace_back(args ...);
+    }
+
+    ResourceLimitedVector()
+    {
+    }
+
+    collection_type& getCollection() { return collection_; }
+
+private:
+    collection_type collection_;
+};
+
+namespace rtps {
+  struct octet {
+    int num;
+    octet(int i=0) : num(i) {}
+  };
+}
+}
+}
+%}
+
+class SimpleIterator {};
+
+%{
+#include <iterator>
+
+class SimpleIterator
+{
+  std::vector<eprosima::fastrtps::rtps::octet>::iterator it;
+public:
+  using iterator_category = std::forward_iterator_tag;
+  using value_type = eprosima::fastrtps::rtps::octet;
+  using difference_type = std::ptrdiff_t;
+  using pointer = eprosima::fastrtps::rtps::octet *;
+  using reference = eprosima::fastrtps::rtps::octet &;
+  SimpleIterator() : it() {}
+  SimpleIterator(std::vector<eprosima::fastrtps::rtps::octet>::iterator it) :it(it) {}
+  SimpleIterator& operator++() {++it;return *this;}
+  SimpleIterator operator++(int) {SimpleIterator tmp(*this); operator++(); return tmp;}
+  bool operator==(const SimpleIterator& rhs) const {return it==rhs.it;}
+  bool operator!=(const SimpleIterator& rhs) const {return it!=rhs.it;}
+  eprosima::fastrtps::rtps::octet& operator*() const {return *it;}
+};
+%}
+
+%inline %{
+struct SimpleContainer {
+    std::vector<eprosima::fastrtps::rtps::octet> container;
+    SimpleContainer(std::vector<eprosima::fastrtps::rtps::octet> v) : container(v) {}
+    SimpleIterator begin() { return SimpleIterator(container.begin()); }
+    SimpleIterator end() { return SimpleIterator(container.end()); }
+};
+%}
+
+%apply const int & {int &&}; // for emplace_back
+
+%template(OctetVector) std::vector<eprosima::fastrtps::rtps::octet>;
+%template(OctetResourceLimitedVector) eprosima::fastrtps::ResourceLimitedVector<eprosima::fastrtps::rtps::octet>;
+%extend eprosima::fastrtps::ResourceLimitedVector<eprosima::fastrtps::rtps::octet> {
+  %template(assign) assign<SimpleIterator>;
+  %template(assign_and_append) assign_and_append<SimpleIterator>;
+  // emplace_back template parameters need to match those in the octet constructor
+  %template(emplace_back) emplace_back<>;
+  %template(emplace_back) emplace_back<int>;
+  %template(emplace_back) emplace_back<eprosima::fastrtps::rtps::octet>;
+  // Variadic templated constructor in template
+  %template(ResourceLimitedVector) ResourceLimitedVector<int>;
+  %template(ResourceLimitedVector) ResourceLimitedVector<eprosima::fastrtps::rtps::octet>;
+}
diff --git a/Examples/test-suite/cpp11_thread_local.i b/Examples/test-suite/cpp11_thread_local.i
index 21f2185..a852891 100644
--- a/Examples/test-suite/cpp11_thread_local.i
+++ b/Examples/test-suite/cpp11_thread_local.i
@@ -16,7 +16,9 @@
 extern thread_local int etval;
 thread_local extern int teval;
 extern "C" thread_local int ectval;
+extern "C" { thread_local int ectval2 = 56; }
 extern "C++" thread_local int ecpptval;
+extern "C++" { thread_local int ecpptval2 = 67; }
 
 thread_local int ThreadLocals::stval = 11;
 thread_local int ThreadLocals::tsval = 22;
@@ -30,6 +32,10 @@
 // externs
 thread_local int etval = 33;
 thread_local int teval = 44;
+extern "C" {
 thread_local int ectval = 55;
+}
+extern "C++" {
 thread_local int ecpptval = 66;
+}
 %}
diff --git a/Examples/test-suite/cpp11_type_aliasing.i b/Examples/test-suite/cpp11_type_aliasing.i
index abc1642..7f5e705 100644
--- a/Examples/test-suite/cpp11_type_aliasing.i
+++ b/Examples/test-suite/cpp11_type_aliasing.i
@@ -63,12 +63,14 @@
 
 // Test that SWIG understands these new types
 
+%{
+Int mult2(Int x) { return x * 2; }
+%}
 %callback("%s_cb");
 Int mult2(Int x);
 %nocallback;
 
 %inline %{
-Int mult2(Int x) { return x * 2; }
 IntPtr allocate_int() { return new Int(12); }
 void free_int(int* ptr) { delete ptr; }
 void inplace_mult2(IntRef x) { x *= 2; }
@@ -110,3 +112,40 @@
 callback_t get_callback() { return mult2; }
 int call(callback_t funk, int param) { return funk(param); }
 %}
+
+
+// Template template parameters - from #1021
+%inline %{
+#include <type_traits>
+
+class Node {};
+struct AnyVal { typedef AnyVal Super; };
+
+template<template<typename D, typename O> class C, typename T, typename Super, typename Root, typename O>
+  using DeriveToBase = typename std::conditional<std::is_same<T, AnyVal>::value, Root, C<Super, O> >::type;
+
+template<class T, class Root, class RParent>
+  using ImmediateBase = typename std::conditional<std::is_same<T, AnyVal>::value, Root, RParent >::type;
+
+template<class D, typename _Super=AnyVal> class Expression {
+  typedef _Super Super;
+};
+
+void TestInstantiationsPart4() {
+  Expression<AnyVal, AnyVal::Super> express;
+  (void)express;
+  DeriveToBase<Expression, AnyVal, AnyVal, AnyVal, AnyVal> derive_to_base = AnyVal();
+}
+%}
+
+#if 0
+// TODO define and instantiate std::conditional and std::is_same
+%template(ExpressionInstantiation) Expression<AnyVal, AnyVal::Super>;
+%template(AnyTypeInstantiation) DeriveToBase<Expression, AnyVal, AnyVal, AnyVal, AnyVal>;
+
+%inline %{
+AnyVal takeAnyVal(DeriveToBase<Expression, AnyVal, AnyVal, AnyVal, AnyVal> av) {
+  return av;
+}
+%}
+#endif
diff --git a/Examples/test-suite/cpp11_type_traits.i b/Examples/test-suite/cpp11_type_traits.i
index 715ce99..fb1fae8 100644
--- a/Examples/test-suite/cpp11_type_traits.i
+++ b/Examples/test-suite/cpp11_type_traits.i
@@ -4,17 +4,19 @@
 // This doesn't really directly test functionality in type_traits as it doesn't provide
 // much for use by target languages, rather it tests usage of it.
 
+%warnfilter(509) elaborate;
+
 %inline %{
 #include <type_traits>
 
 // First way of operating.
 template< bool B > struct algorithm {
-  template< class T1, class T2 > static int do_it(T1 &, T2 &)  { /*...*/ return 1; }
+  template< class T1, class T2 > static int do_it(T1 &, T2 &) { /*...*/ return 1; }
 };
 
 // Second way of operating.
 template<> struct algorithm<true> {
-  template< class T1, class T2 > static int do_it(T1, T2)  { /*...*/ return 2; }
+  template< class T1, class T2 > static int do_it(T1, T2) { /*...*/ return 2; }
 };
 
 // Instantiating 'elaborate' will automatically instantiate the correct way to operate, depending on the types used.
diff --git a/Examples/test-suite/cpp11_userdefined_literals.i b/Examples/test-suite/cpp11_userdefined_literals.i
index 43103cc..37dc6c5 100644
--- a/Examples/test-suite/cpp11_userdefined_literals.i
+++ b/Examples/test-suite/cpp11_userdefined_literals.i
@@ -17,8 +17,8 @@
 #include <iostream>
 
 struct OutputType {
-  int val;
-  OutputType(int v) : val(v) {}
+  int valu;
+  OutputType(int v) : valu(v) {}
 };
 
 // Raw literal
@@ -30,6 +30,9 @@
 
 // Cooked string literals
 OutputType operator "" _mySuffix1(const char * string_values, size_t num_chars) { return OutputType(100); }
+#ifdef __cpp_lib_char8_t // For C++20
+OutputType operator "" _mySuffix1(const char8_t * string_values, size_t num_chars) { return OutputType(100); }
+#endif
 OutputType operator "" _mySuffix2(const wchar_t * string_values, size_t num_chars) { return OutputType(200); }
 OutputType operator "" _mySuffix3(const char16_t * string_values, size_t num_chars) { return OutputType(300); }
 OutputType operator "" _mySuffix4(const char32_t * string_values, size_t num_chars) { return OutputType(400); }
diff --git a/Examples/test-suite/cpp11_using_constructor.i b/Examples/test-suite/cpp11_using_constructor.i
new file mode 100644
index 0000000..d1dcddb
--- /dev/null
+++ b/Examples/test-suite/cpp11_using_constructor.i
@@ -0,0 +1,565 @@
+%module cpp11_using_constructor
+
+// Note: this testcase is also used by cpp11_director_using_constructor.i
+
+%inline %{
+// Public base constructors
+struct PublicBase1 {
+  virtual ~PublicBase1() {}
+  PublicBase1(int i, const char* s) {}
+  virtual void meth() {}
+};
+struct PublicDerived1 : PublicBase1 {
+  using PublicBase1::PublicBase1;
+  using PublicBase1::meth;
+};
+
+struct PublicBase2 {
+  virtual ~PublicBase2() {}
+  PublicBase2(int i, const char* s) {}
+  PublicBase2() {}
+  virtual void meth() {}
+};
+struct PublicDerived2 : PublicBase2 {
+  using PublicBase2::PublicBase2;
+  using PublicBase2::meth;
+};
+
+struct PublicBase3 {
+  virtual ~PublicBase3() {}
+  PublicBase3(int i, const char* s) {}
+  PublicBase3() = default;
+  virtual void meth() {}
+};
+struct PublicDerived3 : PublicBase3 {
+  using PublicBase3::PublicBase3;
+  using PublicBase3::meth;
+};
+
+struct PublicBase4 {
+  virtual ~PublicBase4() {}
+  PublicBase4() = default;
+  virtual void meth() {}
+};
+struct PublicDerived4 : PublicBase4 {
+  using PublicBase4::PublicBase4;
+  using PublicBase4::meth;
+};
+
+struct PublicBase5 {
+  virtual ~PublicBase5() {}
+  // implicit constructor
+  virtual void meth() {}
+};
+struct PublicDerived5 : PublicBase5 {
+  using PublicBase5::PublicBase5;
+  using PublicBase5::meth;
+};
+
+// Protected base constructors
+struct ProtectedBase1 {
+  virtual ~ProtectedBase1() {}
+protected:
+  ProtectedBase1(int i, const char* s) {}
+  virtual void meth() {}
+};
+struct ProtectedDerived1 : ProtectedBase1 {
+  using ProtectedBase1::ProtectedBase1;
+  using ProtectedBase1::meth;
+};
+
+struct ProtectedBase2 {
+  virtual ~ProtectedBase2() {}
+protected:
+  ProtectedBase2(int i, const char* s) {}
+  ProtectedBase2() {}
+  virtual void meth() {}
+};
+struct ProtectedDerived2 : ProtectedBase2 {
+  using ProtectedBase2::ProtectedBase2;
+  using ProtectedBase2::meth;
+};
+
+struct ProtectedBase3 {
+  virtual ~ProtectedBase3() {}
+protected:
+  ProtectedBase3(int i, const char* s) {}
+  ProtectedBase3() = default;
+  virtual void meth() {}
+};
+struct ProtectedDerived3 : ProtectedBase3 {
+  using ProtectedBase3::ProtectedBase3;
+  using ProtectedBase3::meth;
+};
+
+struct ProtectedBase4 {
+  virtual ~ProtectedBase4() {}
+protected:
+  ProtectedBase4() = default;
+  virtual void meth() {}
+};
+struct ProtectedDerived4 : ProtectedBase4 {
+  using ProtectedBase4::ProtectedBase4;
+  using ProtectedBase4::meth;
+};
+
+struct ProtectedBase5 {
+  virtual ~ProtectedBase5() {}
+  // implicit constructor
+protected:
+  virtual void meth() {}
+};
+struct ProtectedDerived5 : ProtectedBase5 {
+  using ProtectedBase5::ProtectedBase5;
+  using ProtectedBase5::meth;
+};
+
+// Mix of public and overloaded constructors
+struct MixedBase1 {
+  virtual ~MixedBase1() {}
+  MixedBase1(int i, const char* s) {}
+  virtual void meth() {}
+};
+struct MixedDerived1a : MixedBase1 {
+  MixedDerived1a() : MixedBase1(0, 0) {}
+  using MixedBase1::MixedBase1;
+  using MixedBase1::meth;
+};
+struct MixedDerived1b : MixedBase1 {
+  using MixedBase1::MixedBase1;
+  MixedDerived1b() : MixedBase1(0, 0) {}
+  using MixedBase1::meth;
+};
+
+struct MixedBase2 {
+  virtual ~MixedBase2() {}
+  MixedBase2(int i, const char* s) {}
+  MixedBase2() {}
+  virtual void meth() {}
+};
+struct MixedDerived2a : MixedBase2 {
+  MixedDerived2a(int i, const char* s) {}
+  using MixedBase2::MixedBase2;
+  using MixedBase2::meth;
+};
+struct MixedDerived2b : MixedBase2 {
+  using MixedBase2::MixedBase2;
+  MixedDerived2b(int i, const char* s) {}
+  using MixedBase2::meth;
+};
+struct MixedDerived2c : MixedBase2 {
+  using MixedBase2::MixedBase2;
+  MixedDerived2c(int ii) : MixedBase2(ii, 0) {}
+  using MixedBase2::meth;
+};
+struct MixedDerived2d : MixedBase2 {
+  MixedDerived2d(int ii) : MixedBase2(ii, 0) {}
+  using MixedBase2::MixedBase2;
+  using MixedBase2::meth;
+};
+
+struct MixedBase3 {
+  virtual ~MixedBase3() {}
+  MixedBase3(int i, const char* s) {}
+  MixedBase3() = default;
+  virtual void meth() {}
+};
+struct MixedDerived3a : MixedBase3 {
+  MixedDerived3a(int i, const char* s) {}
+  using MixedBase3::MixedBase3;
+  using MixedBase3::meth;
+};
+struct MixedDerived3b : MixedBase3 {
+  using MixedBase3::MixedBase3;
+  MixedDerived3b(int i, const char* s) {}
+  using MixedBase3::meth;
+};
+struct MixedDerived3c : MixedBase3 {
+  using MixedBase3::MixedBase3;
+  MixedDerived3c(int ii) : MixedBase3(ii, 0) {}
+  using MixedBase3::meth;
+};
+struct MixedDerived3d : MixedBase3 {
+  MixedDerived3d(int ii) : MixedBase3(ii, 0) {}
+  using MixedBase3::MixedBase3;
+  using MixedBase3::meth;
+};
+
+struct MixedBase4 {
+  virtual ~MixedBase4() {}
+  virtual void meth() {}
+};
+struct MixedDerived4a : MixedBase4 {
+  MixedDerived4a(int i, const char* s) {}
+  using MixedBase4::MixedBase4;
+  using MixedBase4::meth;
+};
+struct MixedDerived4b : MixedBase4 {
+  using MixedBase4::MixedBase4;
+  MixedDerived4b(int i, const char* s) {}
+  using MixedBase4::meth;
+};
+struct MixedDerived4c : MixedBase4 {
+  using MixedBase4::MixedBase4;
+  MixedDerived4c(int ii) {}
+  using MixedBase4::meth;
+};
+struct MixedDerived4d : MixedBase4 {
+  MixedDerived4d(int ii) {}
+  using MixedBase4::MixedBase4;
+  using MixedBase4::meth;
+};
+struct MixedDerived4e : MixedBase4 {
+  MixedDerived4e() {}
+  using MixedBase4::MixedBase4;
+  using MixedBase4::meth;
+};
+struct MixedDerived4f : MixedBase4 {
+  using MixedBase4::MixedBase4;
+  MixedDerived4f() {}
+  using MixedBase4::meth;
+};
+
+// Mix of protected base constructors and overloading
+struct ProotBase1 {
+  virtual ~ProotBase1() {}
+  ProotBase1() {}
+protected:
+  ProotBase1(int i, const char* s) {}
+  virtual void meth() {}
+};
+struct ProotDerived1a : ProotBase1 {
+  using ProotBase1::ProotBase1;
+  using ProotBase1::meth;
+};
+struct ProotDerived1b : ProotBase1 {
+  using ProotBase1::ProotBase1;
+  ProotDerived1b(int i, const char* s) : ProotBase1(i, s) {}
+  using ProotBase1::meth;
+};
+struct ProotDerived1c : ProotBase1 {
+  ProotDerived1c(int i, const char* s) : ProotBase1(i, s) {}
+  using ProotBase1::ProotBase1;
+  using ProotBase1::meth;
+};
+struct ProotDerived1d : ProotBase1 {
+  using ProotBase1::ProotBase1;
+  ProotDerived1d(int ii) : ProotBase1(ii, 0) {}
+  using ProotBase1::meth;
+};
+struct ProotDerived1e : ProotBase1 {
+  ProotDerived1e(int ii) : ProotBase1(ii, 0) {}
+  using ProotBase1::ProotBase1;
+  using ProotBase1::meth;
+};
+
+struct ProotBase2 {
+  virtual ~ProotBase2() {}
+protected:
+  ProotBase2(int i, const char* s) {}
+  ProotBase2() {}
+  virtual void meth() {}
+};
+struct ProotDerived2a : ProotBase2 {
+  ProotDerived2a(int i, const char* s) {}
+  using ProotBase2::ProotBase2;
+  using ProotBase2::meth;
+};
+struct ProotDerived2b : ProotBase2 {
+  using ProotBase2::ProotBase2;
+  ProotDerived2b(int i, const char* s) {}
+  using ProotBase2::meth;
+};
+struct ProotDerived2c : ProotBase2 {
+  ProotDerived2c(int i, const char* s) {}
+  ProotDerived2c() {}
+  using ProotBase2::ProotBase2;
+  using ProotBase2::meth;
+};
+struct ProotDerived2d : ProotBase2 {
+  ProotDerived2d(int i, const char* s) {}
+  using ProotBase2::ProotBase2;
+  ProotDerived2d() {}
+  using ProotBase2::meth;
+};
+struct ProotDerived2e : ProotBase2 {
+  using ProotBase2::ProotBase2;
+  ProotDerived2e(int i, const char* s) {}
+  ProotDerived2e() {}
+  using ProotBase2::meth;
+};
+struct ProotDerived2f : ProotBase2 {
+  using ProotBase2::ProotBase2;
+  ProotDerived2f(int i, const char* s) {}
+  ProotDerived2f() {}
+  ProotDerived2f(int) {}
+  using ProotBase2::meth;
+};
+
+// Deeper inheritance chain
+struct DeepBase1 {
+  virtual ~DeepBase1() {}
+  DeepBase1(int i) {}
+};
+struct DeepBase2 : DeepBase1 {
+  DeepBase2(int i, int j) : DeepBase1(i+j) {}
+  using DeepBase1::DeepBase1;
+};
+struct DeepBase3 : DeepBase2 {
+  DeepBase3(int i, int j, int k) : DeepBase2(i+j+k) {}
+  using DeepBase2::DeepBase2;
+};
+
+struct DeepProtectedBase1 {
+  virtual ~DeepProtectedBase1() {}
+protected:
+  DeepProtectedBase1(int i) {}
+};
+struct DeepProtectedBase2 : DeepProtectedBase1 {
+protected:
+  DeepProtectedBase2(int i, int j) : DeepProtectedBase1(i+j) {}
+  using DeepProtectedBase1::DeepProtectedBase1;
+};
+struct DeepProtectedBase3 : DeepProtectedBase2 {
+  DeepProtectedBase3(int i, int j, int k) : DeepProtectedBase2(i+j+k) {}
+  using DeepProtectedBase2::DeepProtectedBase2;
+};
+
+void cpptester() {
+    DeepBase3 db3 = DeepBase3(11);
+    db3 = DeepBase3(11, 22);
+    db3 = DeepBase3(11, 22, 33);
+    DeepProtectedBase3 dbp3 = DeepProtectedBase3(11, 22, 33);
+}
+
+%}
+
+// Missing base
+%warnfilter(SWIGWARN_TYPE_UNDEFINED_CLASS, SWIGWARN_PARSE_USING_UNDEF) HiddenDerived1;
+%{
+struct HiddenBase1 {
+  virtual ~HiddenBase1() {}
+  HiddenBase1(int i, const char* s) {}
+  HiddenBase1() {}
+  virtual void meth() {}
+};
+%}
+%inline %{
+struct HiddenDerived1 : HiddenBase1 {
+  using HiddenBase1::HiddenBase1;
+  using HiddenBase1::meth;
+};
+%}
+
+#if 0 // not yet working
+// Typedefs and using declarations
+%inline %{
+struct TypedefBase1 {
+  TypedefBase1(int i, const char* s) {}
+  virtual void meth() {}
+};
+struct TypedefDerived1 : TypedefBase1 {
+  typedef TypedefBase1 Superclass;
+  using Superclass::TypedefBase1;
+};
+void tester() {
+    TypedefDerived1 td(0, "hi");
+    td.meth();
+}
+%}
+#endif
+
+%inline %{
+// Templates and public base constructors (derive from non-template)
+template<typename T>
+struct TemplatePublicDerived1 : PublicBase1 {
+  using PublicBase1::PublicBase1;
+  using PublicBase1::meth;
+};
+
+template<typename T>
+struct TemplatePublicDerived2 : PublicBase2 {
+  using PublicBase2::PublicBase2;
+  using PublicBase2::meth;
+};
+
+template<typename T>
+struct TemplatePublicDerived3 : PublicBase3 {
+  using PublicBase3::PublicBase3;
+  using PublicBase3::meth;
+};
+
+template<typename T>
+struct TemplatePublicDerived4 : PublicBase4 {
+  using PublicBase4::PublicBase4;
+  using PublicBase4::meth;
+};
+
+template<typename T>
+struct TemplatePublicDerived5 : PublicBase5 {
+  using PublicBase5::PublicBase5;
+  using PublicBase5::meth;
+};
+%}
+%template(TemplatePublicDerived1Int) TemplatePublicDerived1<int>;
+%template(TemplatePublicDerived2Int) TemplatePublicDerived2<int>;
+%template(TemplatePublicDerived3Int) TemplatePublicDerived3<int>;
+%template(TemplatePublicDerived4Int) TemplatePublicDerived4<int>;
+%template(TemplatePublicDerived5Int) TemplatePublicDerived5<int>;
+
+%inline %{
+// Templates and public base constructors (derive from template)
+template<typename T>
+struct TemplPublicBase1 {
+  virtual ~TemplPublicBase1() {}
+  TemplPublicBase1(T i, const char* s) {}
+  virtual void meth() {}
+};
+
+template<typename T>
+struct TemplPublicBase2 {
+  virtual ~TemplPublicBase2() {}
+  TemplPublicBase2(T i, const char* s) {}
+  TemplPublicBase2() {}
+  virtual void meth() {}
+};
+
+template<typename T>
+struct TemplPublicBase3 {
+  virtual ~TemplPublicBase3() {}
+  TemplPublicBase3(T i, const char* s) {}
+  TemplPublicBase3() = default;
+  virtual void meth() {}
+};
+
+template<typename T>
+struct TemplPublicBase4 {
+  virtual ~TemplPublicBase4() {}
+  TemplPublicBase4() = default;
+  virtual void meth() {}
+};
+
+template<typename T>
+struct TemplPublicBase5 {
+  virtual ~TemplPublicBase5() {}
+  // implicit constructor
+  virtual void meth() {}
+};
+
+template<typename T>
+struct TemplPublicBase6 {
+#ifdef SWIG
+  // Destructor and constructor declared with template parameters (not allowed in C++20 and later though)
+  virtual ~TemplPublicBase6<T>() {}
+  TemplPublicBase6<T>(T i, const char* s) {}
+  TemplPublicBase6<T>() = default;
+#else
+  virtual ~TemplPublicBase6() {}
+  TemplPublicBase6(T i, const char* s) {}
+  TemplPublicBase6() = default;
+#endif
+  virtual void meth() {}
+};
+%}
+
+%template(TemplPublicBase1Int) TemplPublicBase1<int>;
+%template(TemplPublicBase2Int) TemplPublicBase2<int>;
+%template(TemplPublicBase3Int) TemplPublicBase3<int>;
+%template(TemplPublicBase4Int) TemplPublicBase4<int>;
+%template(TemplPublicBase5Int) TemplPublicBase5<int>;
+%template(TemplPublicBase6Int) TemplPublicBase6<int>;
+
+%inline %{
+template<typename T>
+struct TemplPublicDerived1 : TemplPublicBase1<T> {
+  using TemplPublicBase1<T>::TemplPublicBase1;
+  using TemplPublicBase1<T>::meth;
+};
+template<typename T>
+struct TemplPublicDerived2 : TemplPublicBase2<T> {
+  using TemplPublicBase2<T>::TemplPublicBase2;
+  using TemplPublicBase2<T>::meth;
+};
+template<typename T>
+struct TemplPublicDerived3 : TemplPublicBase3<T> {
+  using TemplPublicBase3<T>::TemplPublicBase3;
+  using TemplPublicBase3<T>::meth;
+};
+template<typename T>
+struct TemplPublicDerived4 : TemplPublicBase4<T> {
+  using TemplPublicBase4<T>::TemplPublicBase4;
+  using TemplPublicBase4<T>::meth;
+};
+template<typename T>
+struct TemplPublicDerived5 : TemplPublicBase5<T> {
+  using TemplPublicBase5<T>::TemplPublicBase5;
+  using TemplPublicBase5<T>::meth;
+};
+template<typename T>
+struct TemplPublicDerived6 : TemplPublicBase6<T> {
+  using TemplPublicBase6<T>::TemplPublicBase6;
+  using TemplPublicBase6<T>::meth;
+};
+%}
+
+%template(TemplPublicDerived1Int) TemplPublicDerived1<int>;
+%template(TemplPublicDerived2Int) TemplPublicDerived2<int>;
+%template(TemplPublicDerived3Int) TemplPublicDerived3<int>;
+%template(TemplPublicDerived4Int) TemplPublicDerived4<int>;
+%template(TemplPublicDerived5Int) TemplPublicDerived5<int>;
+%template(TemplPublicDerived6Int) TemplPublicDerived6<int>;
+
+
+// Templated constructors (public)
+%inline %{
+struct TemplateConstructor1Base {
+  virtual ~TemplateConstructor1Base() {}
+public:
+  // No implicit constructor
+  template <typename T> TemplateConstructor1Base(T t, const char *s) {}
+  template <typename T> void template_method(T t, const char *s) {}
+  virtual void normal_method() {}
+};
+%}
+
+%template(TemplateConstructor1Base) TemplateConstructor1Base::TemplateConstructor1Base<int>;
+%template(TemplateConstructor1Base) TemplateConstructor1Base::TemplateConstructor1Base<const char *>;
+%template(TemplateConstructor1Base) TemplateConstructor1Base::TemplateConstructor1Base<double>;
+%template(template_method) TemplateConstructor1Base::template_method<int>;
+%template(template_method) TemplateConstructor1Base::template_method<const char *>;
+
+%inline %{
+struct TemplateConstructor1Derived : TemplateConstructor1Base {
+  using TemplateConstructor1Base::normal_method;
+ // Note: The two using declarations below automatically introduce the templated names without an explicit %template(), see allocate.cxx
+  using TemplateConstructor1Base::TemplateConstructor1Base;
+  using TemplateConstructor1Base::template_method;
+};
+%}
+
+// Templated constructors (protected)
+%inline %{
+struct TemplateConstructor2Base {
+  virtual ~TemplateConstructor2Base() {}
+protected:
+  // No implicit constructor
+  template <typename T> TemplateConstructor2Base(T t, const char *s) {}
+  template <typename T> void template_method(T t, const char *s) {}
+  virtual void normal_method() {}
+};
+%}
+
+%template(TemplateConstructor2Base) TemplateConstructor2Base::TemplateConstructor2Base<int>;
+%template(TemplateConstructor2Base) TemplateConstructor2Base::TemplateConstructor2Base<const char *>;
+%template(TemplateConstructor2Base) TemplateConstructor2Base::TemplateConstructor2Base<double>;
+%template(template_method) TemplateConstructor2Base::template_method<int>;
+%template(template_method) TemplateConstructor2Base::template_method<const char *>;
+
+%inline %{
+struct TemplateConstructor2Derived : TemplateConstructor2Base {
+  using TemplateConstructor2Base::normal_method;
+  using TemplateConstructor2Base::TemplateConstructor2Base; // introduces protected constructors
+  using TemplateConstructor2Base::template_method; // introduces public templated methods
+  TemplateConstructor2Derived() : TemplateConstructor2Base(0, "") {} // provide one public constructor for testing
+};
+%}
diff --git a/Examples/test-suite/cpp11_using_typedef_struct.i b/Examples/test-suite/cpp11_using_typedef_struct.i
new file mode 100644
index 0000000..9fe59d7
--- /dev/null
+++ b/Examples/test-suite/cpp11_using_typedef_struct.i
@@ -0,0 +1,32 @@
+%module cpp11_using_typedef_struct
+
+%inline 
+%{
+namespace nspace1 {
+  typedef struct _xAffineMatrix {
+    int x, y, z;
+  } AffineMatrix;
+
+  struct xCacheView {
+    int x;
+  };
+  typedef struct xCacheView CacheView;
+
+  struct _xAbstract;
+  typedef struct _xAbstract Abstract;
+}
+
+using nspace1::AffineMatrix;
+using nspace1::CacheView;
+// Check that `typename` disambiguator parses.  Regression test for
+// https://github.com/swig/swig/issues/1032 fixed in SWIG 4.2.0.
+// Note: `typename` is not needed here, but should be accepted.
+using typename nspace1::Abstract;
+
+void _internal(const Abstract *) {}
+
+int fn1(AffineMatrix a) { return a.x; };
+int fn2(CacheView a) { return a.x; };
+int fn3(Abstract *a) { _internal(a); return 0; };
+int fn4(const Abstract *a) { _internal(a); return 0; };
+%}
diff --git a/Examples/test-suite/cpp11_variadic_function_templates.i b/Examples/test-suite/cpp11_variadic_function_templates.i
new file mode 100644
index 0000000..82836a4
--- /dev/null
+++ b/Examples/test-suite/cpp11_variadic_function_templates.i
@@ -0,0 +1,96 @@
+%module cpp11_variadic_function_templates
+
+// Some tests for variadic function templates
+%inline %{
+class A {
+public:
+  A() {
+    a = 100;
+  }
+  virtual ~A() {}
+  int a;
+};
+
+class B {
+public:
+  B() {
+    b = 200;
+  }
+  virtual ~B() {}
+  int b;
+};
+
+class C {
+public:
+  C() {
+    c = 300;
+  }
+  virtual ~C() {}
+  int c;
+};
+
+class D {
+public:
+  D() {
+    d = 400;
+  }
+  virtual ~D() {}
+  int d;
+};
+%}
+
+// #1863
+%inline %{
+class Container {
+public:
+template<typename... Args>
+  static void notifyMyTypes(void (fn)(Args...)); // unconventional function (ptr)
+template<typename... Args>
+  static void notifyMyTypesA(void (*fn)(Args...)) {} // conventional function ptr
+template<typename... Args>
+  static void notifyMyTypesB(void fn(Args...)) {}; // unconventional function (ptr)
+};
+%}
+%{
+template<typename... Args>
+  void Container::notifyMyTypes(void (fn)(Args...)) {}
+
+// Explicit template instantiations
+template void Container::notifyMyTypes<>(void (tt)());
+template void Container::notifyMyTypes<int>(void (tt)(int));
+template void Container::notifyMyTypes<int, double>(void (tt)(int, double));
+%}
+
+// Not supported (most vexing parse), see Extending.html#Extending_nn7
+//%template(ContainerNotifyMyTypes1) Container::notifyMyTypes<int>;
+%template(ContainerNotifyMyTypesA1) Container::notifyMyTypesA<int>;
+%template(ContainerNotifyMyTypesB1) Container::notifyMyTypesB<int>;
+
+// #1863
+%inline %{
+#include <type_traits>
+class EmplaceContainer {
+public:
+template<typename T, typename... Args>
+void emplace(Args &&... args) noexcept(
+    std::is_nothrow_constructible<T, Args &&...>::value) {}
+};
+%}
+
+%template(emplace) EmplaceContainer::emplace<int,A>;
+%template(emplace) EmplaceContainer::emplace<int,A,B>;
+%template(emplace) EmplaceContainer::emplace<int,A,B,C>;
+%template(emplace) EmplaceContainer::emplace<int,A,B,C,D>;
+
+
+// Overloading mix of variadic and non-variadic templates
+%inline %{
+template<typename T, typename U> int variadicmix1(T t, U u) { return 10; }
+template<typename... T> int variadicmix1(T... t) { return 20; }
+%}
+
+%template(variadicmix1) variadicmix1<>;
+%template(variadicmix1) variadicmix1<A>;
+%template(variadicmix1) variadicmix1<A,B>;
+%template(variadicmix1) variadicmix1<A,B,C>;
+%template(variadicmix1) variadicmix1<int, int>;
diff --git a/Examples/test-suite/cpp11_variadic_templates.i b/Examples/test-suite/cpp11_variadic_templates.i
index 15ab4ee..dfa8f79 100644
--- a/Examples/test-suite/cpp11_variadic_templates.i
+++ b/Examples/test-suite/cpp11_variadic_templates.i
@@ -4,9 +4,21 @@
    using variadic number of classes.
 */
 %module cpp11_variadic_templates
-%warnfilter(SWIGWARN_CPP11_VARIADIC_TEMPLATE) MultiArgs;
-%warnfilter(SWIGWARN_CPP11_VARIADIC_TEMPLATE) SizeOf;
-%warnfilter(SWIGWARN_CPP11_VARIADIC_TEMPLATE) MultiInherit;
+%warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE,
+	    SWIGWARN_CSHARP_MULTIPLE_INHERITANCE,
+	    SWIGWARN_D_MULTIPLE_INHERITANCE,
+	    SWIGWARN_PHP_MULTIPLE_INHERITANCE,
+	    SWIGWARN_RUBY_MULTIPLE_INHERITANCE) MultiInherit;
+%warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE,
+	    SWIGWARN_CSHARP_MULTIPLE_INHERITANCE,
+	    SWIGWARN_D_MULTIPLE_INHERITANCE,
+	    SWIGWARN_PHP_MULTIPLE_INHERITANCE,
+	    SWIGWARN_RUBY_MULTIPLE_INHERITANCE) NumerousInherit;
+%warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE,
+	    SWIGWARN_CSHARP_MULTIPLE_INHERITANCE,
+	    SWIGWARN_D_MULTIPLE_INHERITANCE,
+	    SWIGWARN_PHP_MULTIPLE_INHERITANCE,
+	    SWIGWARN_RUBY_MULTIPLE_INHERITANCE) LotsInherit;
 
 ////////////////////////
 // Variadic templates //
@@ -24,7 +36,6 @@
 
 %}
 
-// TODO
 %template (MultiArgs1) MultiArgs<int, std::vector<int>, std::map<std::string, std::vector<int>>>;
 
 ////////////////////////
@@ -36,7 +47,10 @@
 };
 %}
 
-%template (SizeOf1) SizeOf<int, int>;
+%template (SizeOf0) SizeOf<>;
+%template (SizeOf1) SizeOf<int>;
+%template (SizeOf2) SizeOf<int, int>;
+%template (SizeOf3) SizeOf<int, int, int>;
 
 //////////////////////////
 // Variadic inheritance //
@@ -60,18 +74,157 @@
   int b;
 };
 
+class C {
+public:
+  C() {
+    c = 300;
+  }
+  virtual ~C() {}
+  int c;
+};
+
+class D {
+public:
+  D() {
+    d = 400;
+  }
+  virtual ~D() {}
+  int d;
+};
+
 template <typename... BaseClasses> class MultiInherit : public BaseClasses... {
 public:
   MultiInherit(BaseClasses&... baseClasses) : BaseClasses(baseClasses)... {}
+  void MultiInstanceMethod(BaseClasses&... baseClasses) {}
+  static void MultiStaticMethod(BaseClasses&... baseClasses) {}
   int InstanceMethod() { return 123; }
   static int StaticMethod() { return 456; }
 };
 %}
 
-
-// TODO
-//%template (MultiInherit0) MultiInherit<>;
+%template (MultiInherit0) MultiInherit<>;
 %template (MultiInherit1) MultiInherit<A>;
-// TODO
 %template (MultiInherit2) MultiInherit<A,B>;
+%template (MultiInherit3) MultiInherit<A,B,C>;
 
+%inline %{
+template <typename... BaseClasses> class NumerousInherit : public BaseClasses... {
+public:
+  NumerousInherit(int i, BaseClasses&... baseClasses) : BaseClasses(baseClasses)... {}
+  void NumerousInstanceMethod(int i, BaseClasses&... baseClasses) {}
+  static void NumerousStaticMethod(int i, BaseClasses&... baseClasses) {}
+  int InstanceMethod() { return 123; }
+  static int StaticMethod() { return 456; }
+};
+%}
+
+%template (NumerousInherit0) NumerousInherit<>;
+%template (NumerousInherit1) NumerousInherit<A>;
+%template (NumerousInherit2) NumerousInherit<A,B>;
+%template (NumerousInherit3) NumerousInherit<A,B,C>;
+
+%inline %{
+template <typename T, typename... BaseClasses> class LotsInherit : public T, public BaseClasses... {
+public:
+  LotsInherit(T t, BaseClasses&... baseClasses) : BaseClasses(baseClasses)... {}
+  void LotsInstanceMethod(T t, BaseClasses&... baseClasses) {}
+  static void LotsStaticMethod(T t, BaseClasses&... baseClasses) {}
+  int InstanceMethod() { return 123; }
+  static int StaticMethod() { return 456; }
+};
+%}
+
+%template (LotsInherit1) LotsInherit<A>;
+%template (LotsInherit2) LotsInherit<A,B>;
+%template (LotsInherit3) LotsInherit<A,B,C>;
+%template (LotsInherit4) LotsInherit<A,B,C,D>;
+
+%inline %{
+struct KlassMemFuncs {
+  int memfunc0() { return 0; }
+  int memfunc1() { return 1; }
+  int memfunc2() { return 2; }
+  int memfunc3() { return 3; }
+};
+template <typename... V> struct VariadicParms {
+  void ParmsVal(V... vparms_v) {}
+  void ParmsPtr(V*... vparms_p) {}
+  void ParmsPtrRef(V*&... vparms_pr) {}
+  void ParmsPtrRValueRef(V*&&... vparms_rvr) {}
+  void ParmsRef(V&... vparms_r) {}
+  void ParmsRValueRef(V&&... vparms_r) {}
+  void ParmsConstRef(const V&... vparms_cr) {}
+
+  // Conventional unnamed parameter function ptr
+  void ParmsFuncPtrVal(int (*)(V...)) {}
+  void ParmsFuncPtrPtr(int (*)(V*...)) {}
+  void ParmsFuncPtrPtrRef(int (*)(V*&...)) {}
+  void ParmsFuncPtrPtrRValueRef(int (*)(V*&&...)) {}
+  void ParmsFuncPtrRef(int (*)(V&...)) {}
+  void ParmsFuncPtrRValueRef(int (*)(V&&...)) {}
+  void ParmsFuncPtrConstRef(int (*)(const V&...)) {}
+
+  // Unconventional unnamed parameter function ptr
+  void ParmsFuncUnnamedVal(int (V...)) {}
+  void ParmsFuncUnnamedPtr(int (V*...)) {}
+  void ParmsFuncUnnamedPtrRef(int (V*&...)) {}
+  void ParmsFuncUnnamedPtrRValueRef(int (V*&&...)) {}
+  void ParmsFuncUnnamedRef(int (V&...)) {}
+  void ParmsFuncUnnamedRValueRef(int (V&&...)) {}
+  void ParmsFuncUnnamedConstRef(int (const V&...)) {}
+
+  // Unconventional named parameter function ptr
+  void ParmsFuncNamedVal(int fn(V...)) {}
+  void ParmsFuncNamedPtr(int fn(V*...)) {}
+  void ParmsFuncNamedPtrRef(int fn(V*&...)) {}
+  void ParmsFuncNamedPtrRValueRef(int fn(V*&&...)) {}
+  void ParmsFuncNamedRef(int fn(V&...)) {}
+  void ParmsFuncNamedRValueRef(int fn(V&&...)) {}
+  void ParmsFuncNamedConstRef(int fn(const V&...)) {}
+
+  // Conventional unnamed parameter member function ptr
+  void ParmsMemFuncPtrVal(int (KlassMemFuncs::*)(V...)) {}
+  void ParmsMemFuncPtrPtr(int (KlassMemFuncs::*)(V*...)) {}
+  void ParmsMemFuncPtrPtrRef(int (KlassMemFuncs::*)(V*&...)) {}
+  void ParmsMemFuncPtrPtrRValueRef(int (KlassMemFuncs::*)(V*&&...)) {}
+  void ParmsMemFuncPtrRef(int (KlassMemFuncs::*)(V&...)) {}
+  void ParmsMemFuncPtrRValueRef(int (KlassMemFuncs::*)(V&&...)) {}
+  void ParmsMemFuncPtrConstRef(int (KlassMemFuncs::*)(const V&...)) {}
+};
+%}
+
+%template(VariadicParms0) VariadicParms<>;
+%template(VariadicParms1) VariadicParms<A>;
+%template(VariadicParms2) VariadicParms<A,B>;
+%template(VariadicParms3) VariadicParms<A,B,C>;
+
+%inline %{
+template <typename... V> struct FixedAndVariadicParms {
+public:
+  void ParmsVal(short samename1, V... samename) {}
+  void ParmsPtr(short shortvar, V*... vparms_p) {}
+  void ParmsPtrRef(short shortvar, V*&... vparms_pr) {}
+  void ParmsPtrRValueRef(short shortvar, V*&&... vparms_rvr) {}
+  void ParmsRef(short shortvar, V&... vparms_r) {}
+  void ParmsRValueRef(short shortvar, V&&... vparms_r) {}
+  void ParmsConstRef(short shortvar, const V&... vparms_cr) {}
+
+  void ParmsFuncPtrVal(short shortvar, int (*)(short, V...)) {}
+  void ParmsMemFuncPtrVal(int (KlassMemFuncs::*)(V...)) {}
+};
+%}
+
+%template(FixedAndVariadicParms0) FixedAndVariadicParms<>;
+%template(FixedAndVariadicParms1) FixedAndVariadicParms<A>;
+%template(FixedAndVariadicParms2) FixedAndVariadicParms<A,B>;
+%template(FixedAndVariadicParms3) FixedAndVariadicParms<A,B,C>;
+
+%inline %{
+struct PlainStruct {
+    template<typename ... VVV> void ParmsPlainStructVariadic(const VVV& ... args) {}
+};
+%}
+%template(PlainStructParms0) PlainStruct::ParmsPlainStructVariadic<>;
+%template(PlainStructParms1) PlainStruct::ParmsPlainStructVariadic<A>;
+%template(PlainStructParms2) PlainStruct::ParmsPlainStructVariadic<A,B>;
+%template(PlainStructParms3) PlainStruct::ParmsPlainStructVariadic<A,B,C>;
diff --git a/Examples/test-suite/cpp14_auto_return_type.i b/Examples/test-suite/cpp14_auto_return_type.i
new file mode 100644
index 0000000..2158e7a
--- /dev/null
+++ b/Examples/test-suite/cpp14_auto_return_type.i
@@ -0,0 +1,45 @@
+// This testcase checks SWIG's support for `auto` as the return type of a
+// function with no trailing return type, introduced in C++14.
+%module cpp14_auto_return_type
+
+// SWIG can't deduce the return type, so we ignore the `auto`-using declaration
+// (which would typically be in a header being wrapped) and provide a
+// declaration with an explicit return type in the interface file.
+
+namespace teca_variant_array_util {
+// Workaround to wrap a global function containing an auto return type with no trailing return type
+int va_static_cast();
+%ignore va_static_cast();
+
+// Workaround to wrap a class method containing an auto return type with no trailing return type
+%extend X {
+  const char * a() const { return $self->a(); }
+}
+%ignore X::a() const;
+
+// SWIGWARN_CPP14_AUTO warning can be suppressed using either %ignore or %warnfilter...
+%ignore X::s();
+%warnfilter(SWIGWARN_CPP14_AUTO) X::e() const;
+}
+
+%inline %{
+namespace teca_variant_array_util
+{
+// Parse error in SWIG < 4.2.0.
+auto va_static_cast()
+{
+  return 42;
+}
+struct X {
+  auto a() const {
+    return "a string";
+  }
+  auto e() const {
+    return 2.71828;
+  }
+  static auto s() {
+    return true;
+  }
+};
+}
+%}
diff --git a/Examples/test-suite/cpp14_binary_integer_literals.i b/Examples/test-suite/cpp14_binary_integer_literals.i
index 9c696b5..0cabb1c 100644
--- a/Examples/test-suite/cpp14_binary_integer_literals.i
+++ b/Examples/test-suite/cpp14_binary_integer_literals.i
@@ -1,31 +1,17 @@
 %module cpp14_binary_integer_literals
 
-// Tests are designed so that code compiles with C++98 compilers
-
-%{
-#if __cplusplus >= 201402L
-#define CPP14 1
+#if 0b100 < 4
+# error binary constant in preprocessor expression failed
 #endif
-%}
 
+%inline %{
 int b1 = 0b1;
 int b2 = 0b10;
 long b3 = 0b11l;
 unsigned long b4 = 0b100ul;
 unsigned long b5 = 0B101UL;
-
-%{
-#if defined(CPP14)
-int b1 = 0b1;
-int b2 = 0b10;
-long b3 = 0b11l;
-unsigned long b4 = 0b100ul;
-unsigned long b5 = 0B101UL;
-#else
-int b1 = 1;
-int b2 = 2;
-long b3 = 3;
-unsigned long b4 = 4;
-unsigned long b5 = 5;
-#endif
+#define b6 0b110
+const int b7 = 0b111;
 %}
+
+%constant int b8 = 0b1000;
diff --git a/Examples/test-suite/cpp17_director_string_view.i b/Examples/test-suite/cpp17_director_string_view.i
new file mode 100644
index 0000000..ef17661
--- /dev/null
+++ b/Examples/test-suite/cpp17_director_string_view.i
@@ -0,0 +1,56 @@
+%module(directors="1") cpp17_director_string_view;
+
+#if defined SWIGCSHARP || defined SWIGJAVA || defined SWIGLUA || defined SWIGPERL || defined SWIGPHP || defined SWIGPYTHON || defined SWIGRUBY
+
+%include std_string.i
+%include std_string_view.i
+
+// Using thread unsafe wrapping
+%warnfilter(SWIGWARN_TYPEMAP_THREAD_UNSAFE,SWIGWARN_TYPEMAP_DIRECTOROUT_PTR) A;
+
+%{
+#include <vector>
+#include <string>
+#include <string_view>
+%}
+
+%feature("director") A;
+%inline %{
+
+struct A
+{
+  A(const std::string& first)
+    : m_strings(1, first)
+  {}
+
+  virtual ~A() {}
+
+  virtual std::string_view get_first() const
+  { return get(0); }
+
+  virtual std::string_view get(int n) const
+  { return m_strings[n]; }
+
+  virtual std::string_view call_get_first() const
+  { return get_first(); }
+
+  virtual std::string_view call_get(int n) const
+  { return get(n); }
+
+  virtual int string_length(std::string_view s) const
+  { return (int)s.size(); }
+
+
+  virtual void process_text(const char *text) const
+  {
+  }
+
+  void call_process_func() const { process_text("hello"); }
+
+private:
+  std::vector<std::string> m_strings;
+};
+
+%}
+
+#endif
diff --git a/Examples/test-suite/cpp17_enable_if_t.i b/Examples/test-suite/cpp17_enable_if_t.i
new file mode 100644
index 0000000..a6695bc
--- /dev/null
+++ b/Examples/test-suite/cpp17_enable_if_t.i
@@ -0,0 +1,89 @@
+%module cpp17_enable_if_t
+
+// test use of enable_if_t but without full %template instantiation, that is no enable_if_t definition is parsed
+
+%inline %{
+#if defined(_MSC_VER) && _MSC_VER < 1920
+#define or ||
+#define and &&
+#endif
+
+#include <type_traits>
+typedef int node_t;
+typedef int position_t;
+
+template <typename A, typename B, std::enable_if_t<std::is_integral_v<A>, bool> = true>
+  void enableif1(const A a, const B b) {}
+
+// tests non-type template parameters within () brackets - was causing an infinite loop, issue #2418
+template <typename A, typename B, std::enable_if_t<(std::is_integral_v<A>), bool> = true>
+  void enableif2(const A a, const B b) {}
+
+template <typename A, typename B, std::enable_if_t<(std::is_integral_v<A> || std::is_same_v<A, node_t>), bool> = true>
+  void enableif3(const A a, const B b) {}
+
+template <typename A, typename B, std::enable_if_t<(std::is_integral_v<A> or std::is_same_v<A, node_t>) and (std::is_integral_v<B> or std::is_same_v<B, position_t>), bool> = true>
+  void enableif4(const A a, const B b) {}
+
+template <typename A, typename B, std::enable_if_t<(std::is_integral_v<A> and std::is_integral_v<B>), bool> = true>
+  int enableif5(const A a, const B b) {
+    return a + b;
+  }
+
+void tester() {
+  enableif5<int, int>(10, 20);
+  enableif5(10, 20);
+}
+%}
+
+// non-type template parameters working well in SWIG, below is a simple workaround as the 3rd parameter is defaulted for enable_if_t (which is just SFINAE to give a nice C++ compiler error)
+%template(enableif5) enableif5<int, int, true>; // workaround (overriding default)
+
+
+%inline %{
+// #1037 infinite loop
+template <typename T, std::enable_if_t<sizeof(T) <= 4>>
+void destId(T el) {}
+
+template <typename T, std::enable_if_t<sizeof(T) >= 3>>
+void destId(const T& el) {}
+%}
+
+%inline %{
+// #961 no name for defaulted template parameter
+template<typename T, typename = std::enable_if_t<std::is_enum<T>::value>>
+void uuu() {}
+template<typename T, typename E = std::enable_if_t<std::is_enum<T>::value>>
+void uuuE() {}
+
+template<typename T, typename = typename std::enable_if<std::is_floating_point<T>::value>::type>
+void vvv() {}
+template<typename T, typename E = typename std::enable_if<std::is_floating_point<T>::value>::type>
+void vvvE() {}
+
+// More variations of enable_if and enable_if_t
+template<typename T, typename std::enable_if<std::is_floating_point<T>::value>::type* = nullptr>
+void www() {}
+
+template<typename T, typename std::enable_if_t<std::is_enum<T>::value, int> = 0>
+void xxx() {}
+
+enum TestEnum { Enum1 = 1, Enum2 };
+struct TestStruct {};
+
+void tester2() {
+  uuu<TestEnum>();
+//  uuu<TestStruct>(); // compilation error
+  uuuE<TestEnum>();
+//  uuuE<TestStruct>(); // compilation error
+  vvv<double>();
+//  vvv<TestStruct>(); // compilation error
+  vvvE<double>();
+//  vvvE<TestStruct>(); // compilation error
+
+  www<double>();
+//  www<TestStruct>(); // compilation error
+  xxx<TestEnum>();
+//  xxx<TestStruct>(); // compilation error
+}
+%}
diff --git a/Examples/test-suite/cpp17_hex_floating_literals.i b/Examples/test-suite/cpp17_hex_floating_literals.i
index dfc1dc0..dd8e099 100644
--- a/Examples/test-suite/cpp17_hex_floating_literals.i
+++ b/Examples/test-suite/cpp17_hex_floating_literals.i
@@ -1,13 +1,6 @@
 %module cpp17_hex_floating_literals
 
-// Tests are designed so that code compiles with C++98 compilers
-
-%{
-#if __cplusplus >= 201703L
-#define CPP17 1
-#endif
-%}
-
+%inline %{
 double f1 = 0x.0p1;
 double f2 = 0x0.p1;
 double f3 = 0x0.0p-1;
@@ -17,27 +10,4 @@
 double f7 = 0xb2F.p2;
 float f8 = 0x1234AP1F;
 float f9 = 0x45A1.D1A2p+10f;
-
-%{
-#if defined(CPP17)
-double f1 = 0x.0p1;
-double f2 = 0x0.p1;
-double f3 = 0x0.0p-1;
-double f4 = 0xf.p-1;
-double f5 = 0xA.0p1;
-double f6 = 0x0.10P+10;
-double f7 = 0xb2F.p2;
-float f8 = 0x1234AP1F;
-float f9 = 0x45A1.D1A2p+10f;
-#else
-double f1 = 0.;
-double f2 = 0.;
-double f3 = 0.;
-double f4 = 7.5;
-double f5 = 20.;
-double f6 = 64.;
-double f7 = 11452.;
-float f8 = 149140.f;
-float f9 = 18253638.f;
-#endif
 %}
diff --git a/Examples/test-suite/cpp17_map_no_default_ctor.i b/Examples/test-suite/cpp17_map_no_default_ctor.i
new file mode 100644
index 0000000..2d9a9f5
--- /dev/null
+++ b/Examples/test-suite/cpp17_map_no_default_ctor.i
@@ -0,0 +1,18 @@
+%module cpp17_map_no_default_ctor
+// Tests c++17 insert_or_assign for std::map with no default constructor
+
+%include <std_map.i>
+
+%ignore NoDefaultConstructorStruct::operator<;
+%inline %{
+struct NoDefaultConstructorStruct final
+{
+	int value{0};
+	NoDefaultConstructorStruct(int v) : value(v) {}
+        bool operator<(const NoDefaultConstructorStruct& other) const { return value < other.value; }
+};
+using NoDefaultConstructorStructMap = std::map<int, NoDefaultConstructorStruct>;
+%}
+
+//%template(PairIntNoDefaultConstructorStruct) std::pair<const int, NoDefaultConstructorStruct>;
+%template(NoDefaultConstructorStructMap) std::map<int, NoDefaultConstructorStruct>;
diff --git a/Examples/test-suite/cpp17_nested_namespaces.i b/Examples/test-suite/cpp17_nested_namespaces.i
index b9ec9bd..fcbf24c 100644
--- a/Examples/test-suite/cpp17_nested_namespaces.i
+++ b/Examples/test-suite/cpp17_nested_namespaces.i
@@ -1,13 +1,5 @@
 %module cpp17_nested_namespaces
 // Tests c++17 style nested namespaces
-// Tests are designed so that code compiles with C++98 compilers
-
-#define CPP17 1
-%{
-#if __cplusplus >= 201703L
-#define CPP17 1
-#endif
-%}
 
 %inline %{
 // Tests with namespaces already defined using C++98 style (non-nested) namespaces
@@ -21,20 +13,10 @@
     };
   }
 }
-#if defined(CPP17)
 namespace A1::B1 {
-#else
-namespace A1 {
- namespace B1 {
-#endif
   A1Struct createA1Struct() { return ::A1::A1Struct(); }
   B1Struct createB1Struct() { return ::A1::B1::B1Struct(); }
-#if !defined(CPP17)
- }
 }
-#else
-}
-#endif
 
 namespace A1 {
   namespace B1 {
@@ -46,154 +28,54 @@
   }
 }
 
-#if defined(CPP17)
 namespace A1::B1::C1 {
-#else
-namespace A1 {
- namespace B1 {
-  namespace C1 {
-#endif
   C1Struct createC1Struct() { return ::A1::B1::C1::C1Struct(); }
-#if !defined(CPP17)
-  }
- }
 }
-#else
-}
-#endif
 %}
 
 %inline %{
 // Tests with namespaces already defined using C++17 style (nested) namespaces
-#if defined(CPP17)
 namespace A2::B2 {
-#else
-namespace A2 {
- namespace B2 {
-#endif
   struct B2Struct {
     void B2Method() {}
   };
-#if !defined(CPP17)
- }
 }
-#else
-}
-#endif
 
-#if defined(CPP17)
 namespace A2::B2 {
-#else
-namespace A2 {
- namespace B2 {
-#endif
   B2Struct createB2Struct() { return ::A2::B2::B2Struct(); }
-#if !defined(CPP17)
- }
 }
-#else
-}
-#endif
 
-#if defined(CPP17)
 namespace A2::B2::C2 {
-#else
-namespace A2 {
- namespace B2 {
-  namespace C2 {
-#endif
     struct C2Struct {
       void C2Method() {}
     };
-#if !defined(CPP17)
-  }
- }
 }
-#else
-}
-#endif
 
-#if defined(CPP17)
 namespace A2::B2::C2 {
-#else
-namespace A2 {
- namespace B2 {
-  namespace C2 {
-#endif
   C2Struct createC2Struct() { return ::A2::B2::C2::C2Struct(); }
-#if !defined(CPP17)
-  }
- }
 }
-#else
-}
-#endif
 %}
 
 
 %inline %{
 // Tests with namespaces already defined using C++17 style (nested) namespaces to 3 levels
-#if defined(CPP17)
 namespace A3::B3::C3 {
-#else
-namespace A3 {
- namespace B3 {
-  namespace C3 {
-#endif
     struct C3Struct {
       void C3Method() {}
     };
-#if !defined(CPP17)
-  }
- }
 }
-#else
-}
-#endif
 
-#if defined(CPP17)
 namespace A3::B3::C3 {
-#else
-namespace A3 {
- namespace B3 {
-  namespace C3 {
-#endif
   C3Struct createC3Struct() { return ::A3::B3::C3::C3Struct(); }
-#if !defined(CPP17)
-  }
- }
 }
-#else
-}
-#endif
 
-#if defined(CPP17)
 namespace A3::B3 {
-#else
-namespace A3 {
- namespace B3 {
-#endif
   struct B3Struct {
     void B3Method() {}
   };
-#if !defined(CPP17)
- }
 }
-#else
-}
-#endif
 
-#if defined(CPP17)
 namespace A3::B3 {
-#else
-namespace A3 {
- namespace B3 {
-#endif
   B3Struct createB3Struct() { return ::A3::B3::B3Struct(); }
-#if !defined(CPP17)
- }
 }
-#else
-}
-#endif
 %}
diff --git a/Examples/test-suite/cpp17_std_filesystem.i b/Examples/test-suite/cpp17_std_filesystem.i
new file mode 100644
index 0000000..c84f3fa
--- /dev/null
+++ b/Examples/test-suite/cpp17_std_filesystem.i
@@ -0,0 +1,64 @@
+%module cpp17_std_filesystem
+
+%include <std_string.i>
+%include <std_filesystem.i>
+
+%{
+#include <filesystem>
+%}
+
+%inline %{
+/* Test the "out" typemap for std::filesystem::path */
+std::filesystem::path makePath(const std::string& s) {
+    return std::filesystem::path(s);
+}
+
+/**
+ * There is no "out" typemap for a pointer to a path, so
+ * this should return a wrapped instance of a path
+ * instead of the native path type for the target language.
+ */
+std::filesystem::path * makePathPtr(const std::string& s) {
+    static std::filesystem::path p(s);
+    return &p;
+}
+
+/**
+ * There is no "out" typemap for a non-const reference to a path, so
+ * this should return a wrapped instance of a std::filesystem::path instead of
+ * the native path type for the target language.
+ */
+std::filesystem::path& makePathRef(const std::string& s) {
+    static std::filesystem::path p(s);
+    return p;
+}
+
+/**
+ * There is no "out" typemap for a const reference to a path, so
+ * this should return a wrapped instance of a std::filesystem::path
+ * instead of the native path type for the target language.
+ */
+const std::filesystem::path & makePathConstRef(const std::string & s) {
+    static std::filesystem::path p(s);
+    return p;
+}
+
+/* Test the "in" typemap for std::filesystem::path */
+std::string pathToStr(std::filesystem::path p) {
+    return p.string();
+}
+
+/* Test the "in" typemap for const std::filesystem::path & */
+std::string pathConstRefToStr(const std::filesystem::path & p) {
+    return p.string();
+}
+
+/* Test the "in" typemap for const std::filesystem::path * */
+std::string pathPtrToStr(const std::filesystem::path * p) {
+    return p->string();
+}
+
+std::filesystem::path roundTrip(const std::filesystem::path& p) {
+    return p;
+}
+%}
diff --git a/Examples/test-suite/cpp17_string_view.i b/Examples/test-suite/cpp17_string_view.i
new file mode 100644
index 0000000..ae10837
--- /dev/null
+++ b/Examples/test-suite/cpp17_string_view.i
@@ -0,0 +1,112 @@
+%module cpp17_string_view
+#if defined SWIGCSHARP || defined SWIGJAVA || defined SWIGLUA || defined SWIGPERL || defined SWIGPHP || defined SWIGPYTHON || defined SWIGRUBY || defined SWIGTCL
+%include <std_string_view.i>
+
+// throw is invalid in C++17 and later, only SWIG to use it
+#define TESTCASE_THROW1(T1) throw(T1)
+%{
+#define TESTCASE_THROW1(T1)
+%}
+
+%inline %{
+
+std::string_view test_value(std::string_view x) {
+   return x;
+}
+
+const std::string_view& test_const_reference(const std::string_view &x) {
+   return x;
+}
+
+void test_const_reference_returning_void(const std::string_view &) {
+}
+
+void test_const_reference_returning_void(const std::string_view &, int) {
+}
+
+void test_pointer(std::string_view *x) {
+}
+
+std::string_view *test_pointer_out() {
+   static std::string_view x = "x";
+   return &x;
+}
+
+void test_const_pointer(const std::string_view *x) {
+}
+
+const std::string_view *test_const_pointer_out() {
+   static std::string_view x = "x";
+   return &x;
+}
+
+void test_reference(std::string_view &x) {
+}
+
+std::string_view& test_reference_out() {
+   static std::string_view x = "test_reference_out message";
+   return x;
+}
+
+std::string_view test_reference_input(std::string_view &input) {
+  return input;
+}
+
+void test_throw() TESTCASE_THROW1(std::string_view){
+  static std::string_view x = "test_throw message";
+  throw x;
+}
+
+void test_const_reference_throw() TESTCASE_THROW1(const std::string_view &){
+  static const std::string_view x = "test_const_reference_throw message";
+  throw x;
+}
+
+void test_pointer_throw() TESTCASE_THROW1(std::string_view *) {
+  throw new std::string_view("foo");
+}
+
+void test_const_pointer_throw() TESTCASE_THROW1(const std::string_view *) {
+  throw static_cast<const std::string_view*>(new std::string_view("foo"));
+}
+%}
+
+#ifdef SWIGSCILAB
+%rename(ConstStr) ConstMemberString;
+%rename(ConstStaticStr) ConstStaticMemberString;
+#endif
+
+%inline %{
+const std::string_view ConstGlobalString = "const global string";
+
+struct Structure {
+  const std::string_view ConstMemberString;
+  static const std::string_view ConstStaticMemberString;
+
+  Structure() : ConstMemberString("const member string") {}
+};
+%}
+
+%{
+  const std::string_view Structure::ConstStaticMemberString = "const static member string";
+%}
+
+
+%inline %{
+  std::string_view stdstringview_empty() {
+    return std::string_view();
+  }
+
+  char *c_empty() {
+    return (char *)"";
+  }
+
+  char *c_null() {
+    return 0;
+  }
+
+  const char *get_null(const char *a) {
+    return a == 0 ? a : "non-null";
+  }
+%}
+#endif
diff --git a/Examples/test-suite/cpp17_u8_char_literals.i b/Examples/test-suite/cpp17_u8_char_literals.i
index 1aae1b2..e2e8e0d 100644
--- a/Examples/test-suite/cpp17_u8_char_literals.i
+++ b/Examples/test-suite/cpp17_u8_char_literals.i
@@ -1,26 +1,9 @@
 %module cpp17_u8_char_literals
 
-// Tests are designed so that code compiles with C++98 compilers
-
-%{
-#if __cplusplus >= 201703L
-#define CPP17 1
-#endif
-%}
-
-// UTF-8 character literals will (apparently) have type char8_t in C++20.
+// UTF-8 character literals are type `char` in C++17 but `char8_t` in C++20,
+// but the latter can be assigned to `char`.
+%inline %{
 char a = u8'a';
 char u = u8'u';
 char u8 = u8'8';
-
-%{
-#if defined(CPP17)
-char a = u8'a';
-char u = u8'u';
-char u8 = u8'8';
-#else
-char a = 'a';
-char u = 'u';
-char u8 = '8';
-#endif
 %}
diff --git a/Examples/test-suite/cpp20_constexpr_destructor.i b/Examples/test-suite/cpp20_constexpr_destructor.i
new file mode 100644
index 0000000..56c51e3
--- /dev/null
+++ b/Examples/test-suite/cpp20_constexpr_destructor.i
@@ -0,0 +1,50 @@
+%module cpp20_constexpr_destructor
+
+// Test constexpr destructors introduced in C++20
+
+%inline %{
+class DtorA {
+public:
+    constexpr ~DtorA() {}
+};
+
+class DtorB {
+public:
+    constexpr ~DtorB();
+};
+
+constexpr DtorB::~DtorB() {}
+
+class DtorC {
+public:
+    virtual constexpr ~DtorC() {}
+};
+
+class DtorD {
+public:
+    constexpr virtual ~DtorD() {}
+};
+
+class DtorE {
+public:
+    inline virtual constexpr ~DtorE() {}
+};
+
+class DtorF {
+public:
+    virtual constexpr ~DtorF() = 0;
+};
+
+class DtorG {
+public:
+    virtual constexpr ~DtorG() = default;
+};
+
+template<typename T>
+struct DtorTemplate {
+    virtual constexpr ~DtorTemplate();
+};
+
+template<typename T>
+constexpr DtorTemplate<T>::~DtorTemplate() {}
+%}
diff --git a/Examples/test-suite/cpp20_lambda_template.i b/Examples/test-suite/cpp20_lambda_template.i
new file mode 100644
index 0000000..61b59df
--- /dev/null
+++ b/Examples/test-suite/cpp20_lambda_template.i
@@ -0,0 +1,16 @@
+%module cpp20_lambda_template
+
+// We just want to test that SWIG doesn't choke parsing this so suppress:
+// Warning 340: Lambda expressions and closures are not fully supported yet.
+%warnfilter(SWIGWARN_CPP11_LAMBDA);
+
+%include <std_vector.i>
+
+%inline %{
+#include <vector>
+auto templated_lambda = []<typename T>(std::vector<T> t){};
+
+// Regression test for parsing bug fixed in SWIG 4.2.0 (#2630)
+auto y = []<bool X = 1>=2> { return 1; };
+auto z = []<bool X = 1<=2> { return 1; };
+%}
diff --git a/Examples/test-suite/cpp20_spaceship_operator.i b/Examples/test-suite/cpp20_spaceship_operator.i
new file mode 100644
index 0000000..ddece13
--- /dev/null
+++ b/Examples/test-suite/cpp20_spaceship_operator.i
@@ -0,0 +1,28 @@
+%module cpp20_spaceship_operator
+
+%rename(spaceship) operator<=>;
+
+%inline %{
+#include <compare>
+
+int v = (-1 <=> 1 > 0) ? 7 : 42;
+
+// We use !(a >= b) here due to limited support for (a < b) in SWIG's parser.
+#define ALIEN !(0 <=> 1 >= 0)
+
+const int SPACE = 3 <=> 3 == 0;
+
+struct A {
+  int v;
+
+  explicit A(int v_) : v(v_) { }
+};
+
+int operator<=>(const A& a, const A& b) {
+  return a.v - b.v;
+}
+
+int f(int v = (-1 <=> 1 > 0) ? 7 : 42) { return v; }
+%}
+
+%constant int COMET = (4 <=> 2 > 0);
diff --git a/Examples/test-suite/cpp_basic.i b/Examples/test-suite/cpp_basic.i
index a228af2..4c7dfae 100644
--- a/Examples/test-suite/cpp_basic.i
+++ b/Examples/test-suite/cpp_basic.i
@@ -1,9 +1,12 @@
-/* This is a basic test of proxy classes, used by chicken */
+/* This is a basic test of proxy classes */
 
 %warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK);                   /* memory leak when setting a ptr/ref variable */
 
 %warnfilter(SWIGWARN_RUBY_WRONG_NAME) global_cint;       /* Ruby, wrong constant name */
 
+%feature("php:allowdynamicproperties", 1) Foo; /* Allow PHP-specific custom property testing in _runme.php */
+%feature("php:allowdynamicproperties", 0) Bar; /* and that this doesn't allow custom properties. */
+
 %module cpp_basic
 
 %newobject Bar::testFoo;
@@ -45,6 +48,9 @@
     const char* __str__() const { return "FooSubSub"; }
 };
 
+Foo& get_reference(Foo& other) { return other; }
+const Foo& get_const_reference(const Foo& other) { return other; }
+
 %}
 
 %{
@@ -74,10 +80,17 @@
     Foo *testFoo(int a, Foo *f) {
       return new Foo(2 * a + (f ? f->num : 0) + fval.num);
     }
+/* Const member data and references mean this class can't be assigned. */
 private:
     Bar& operator=(const Bar&);
 };
 
+// This class is valid C++ but cannot be assigned to because it has const member data.
+struct JustConst {
+explicit JustConst(int i_inp) : i(i_inp) {}
+const int i;
+};
+
 %}
 
 %{
diff --git a/Examples/test-suite/cpp_enum.i b/Examples/test-suite/cpp_enum.i
index 548c65d..83b22a5 100644
--- a/Examples/test-suite/cpp_enum.i
+++ b/Examples/test-suite/cpp_enum.i
@@ -58,3 +58,36 @@
 typedef enum { PLAY = true, STOP = false } play_state;
 %}
 
+// Regression test for https://github.com/swig/swig/issues/2796
+// Skip for C# as this enum can't be wrapper as a C# proper enum.
+#if defined SWIGCSHARP || defined SWIGD
+%ignore Enum2796;
+#endif
+%inline %{
+typedef int mytype0;
+typedef mytype0 mytype1;
+#ifndef SWIG
+typedef int unknown_to_swig_type;
+#endif
+typedef unknown_to_swig_type mytype2;
+
+enum Enum2796
+{
+   CASE0A = (mytype0)10,
+   CASE0B = mytype0(10),
+   CASE0C = static_cast<mytype0>(10),
+   CASE1A = (mytype1)10, // Used to fail
+   CASE1B = mytype1(10),
+   CASE1C = static_cast<mytype1>(10),
+   CASE2A = (mytype2)10, // Used to fail
+   CASE2B = mytype2(10),
+   CASE2C = static_cast<mytype2>(10),
+   CASE3A = (unknown_to_swig_type)10,
+   CASE3B = unknown_to_swig_type(10),
+   CASE3C = static_cast<unknown_to_swig_type>(10),
+   CASE4A = (5)*2,
+   CASE4B = (14)&11,
+   CASE4C = (3)+7,
+   CASE4D = (42)-32,
+};
+%}
diff --git a/Examples/test-suite/cpp_parameters.i b/Examples/test-suite/cpp_parameters.i
new file mode 100644
index 0000000..e8a4c94
--- /dev/null
+++ b/Examples/test-suite/cpp_parameters.i
@@ -0,0 +1,46 @@
+%module cpp_parameters
+
+%{
+// For Perl
+#ifdef Zero
+#undef Zero
+#endif
+%}
+%inline %{
+
+// Zero arguments
+struct Zero {
+  Zero() {}
+  int zero() { return 0; }
+  static int stat_zero() { return 0; }
+};
+// One mandatory argument
+struct One {
+  One(int a) {}
+  int one(int a) { return a; }
+  static int stat_one(int a) { return a; }
+};
+// Two mandatory arguments
+struct Two {
+  Two(int a, int b) {}
+  int two(int a, int b) { return a + b; }
+  static int stat_two(int a, int b) { return a + b; }
+};
+// Single optional argument
+struct Single {
+  Single(int a=0) {}
+  int single(int a=0) { return a; }
+  static int stat_single(int a=0) { return a; }
+};
+
+int global_zero() { return 0; }
+int global_one(int a) { return a; }
+int global_two(int a, int b) { return a + b; }
+int global_single(int a=0) { return a; }
+
+#ifdef SWIGPYTHON_BUILTIN
+bool is_python_builtin() { return true; }
+#else
+bool is_python_builtin() { return false; }
+#endif
+%}
diff --git a/Examples/test-suite/cpp_typedef.i b/Examples/test-suite/cpp_typedef.i
index b782a3b..140df34 100644
--- a/Examples/test-suite/cpp_typedef.i
+++ b/Examples/test-suite/cpp_typedef.i
@@ -3,6 +3,9 @@
 %module cpp_typedef
 
 %{
+#if defined(_MSC_VER) && _MSC_VER >= 1900
+  #pragma warning( disable : 5208) // warning C5208: unnamed class used in typedef name cannot declare members other than non-static data members, member enumerations, or member classes
+#endif
 
 class Bar {
 public:
@@ -27,7 +30,6 @@
 // Test that the correct types are used for typedef struct declarations
 typedef struct {
   int something;
-  void m() {}
 } UnnamedStruct;
 
 typedef struct NamedStruct {
diff --git a/Examples/test-suite/csharp/Makefile.in b/Examples/test-suite/csharp/Makefile.in
index 8272864..6bda2ab 100644
--- a/Examples/test-suite/csharp/Makefile.in
+++ b/Examples/test-suite/csharp/Makefile.in
@@ -8,14 +8,20 @@
 CSHARPCILINTERPRETER_FLAGS = @CSHARPCILINTERPRETER_FLAGS@
 CSHARPCONVERTPATH     = @top_srcdir@/@CSHARPCONVERTPATH@
 
+HAVE_CXX11   = @HAVE_CXX11@
+HAVE_CXX14   = @HAVE_CXX14@
+HAVE_CXX17   = @HAVE_CXX17@
+HAVE_CXX20   = @HAVE_CXX20@
 srcdir       = @srcdir@
 top_srcdir   = ../@top_srcdir@
 top_builddir = ../@top_builddir@
 
 CPP_TEST_CASES = \
 	complextest \
+	csharp_argument_defaults_feature \
 	csharp_attributes \
 	csharp_swig2_compatibility \
+	csharp_director_typemaps \
 	csharp_exceptions \
 	csharp_features \
 	csharp_lib_arrays \
@@ -23,18 +29,25 @@
 	csharp_namespace_system_collision \
 	csharp_prepost \
 	csharp_typemaps \
+	director_wstring \
 	enum_thorough_simple \
 	enum_thorough_typesafe \
 	exception_partial_info \
 	intermediary_classname \
+	nested_scope \
 	li_boost_intrusive_ptr \
 	li_std_list \
 
+
 CPP11_TEST_CASES = \
 	cpp11_shared_ptr_const \
+	cpp11_shared_ptr_crtp_upcast \
 	cpp11_shared_ptr_nullptr_in_containers \
 	cpp11_shared_ptr_overload \
+	cpp11_shared_ptr_template_upcast \
 	cpp11_shared_ptr_upcast \
+	cpp11_std_unordered_map \
+	cpp11_std_unordered_set \
 	cpp11_strongly_typed_enumerations_simple \
 
 include $(srcdir)/../common.mk
diff --git a/Examples/test-suite/csharp/allprotected_runme.cs b/Examples/test-suite/csharp/allprotected_runme.cs
index 6b04feb..2da8f8f 100644
--- a/Examples/test-suite/csharp/allprotected_runme.cs
+++ b/Examples/test-suite/csharp/allprotected_runme.cs
@@ -27,6 +27,9 @@
     ProtectedBase pb = new ProtectedDerived("ProtectedDerived");
     // ProtectedDerived's destructor should be called via the Dispose(disposing) virtual call
     pb.Dispose();
+
+    MyAllProtectedBottom mapb = new MyAllProtectedBottom();
+    mapb.callProtectedMethods();
   }
 }
 
@@ -83,3 +86,14 @@
       throw new Exception("Failed");
   }
 }
+
+class MyAllProtectedBottom : AllProtectedBottom
+{
+  public void callProtectedMethods() {
+    usingOverloaded();
+    usingOverloaded(99);
+    usingSingle();
+    doSomething();
+    doSomething(99);
+  }
+}
diff --git a/Examples/test-suite/csharp/argcargvtest_runme.cs b/Examples/test-suite/csharp/argcargvtest_runme.cs
new file mode 100644
index 0000000..5b7f7c3
--- /dev/null
+++ b/Examples/test-suite/csharp/argcargvtest_runme.cs
@@ -0,0 +1,46 @@
+using System;
+using argcargvtestNamespace;
+
+public class argcargvtest_runme {
+
+  public static void Main() {
+    string[] largs = {"hi", "hola", "hello"};
+    if (argcargvtest.mainc(largs) != 3)
+      throw new Exception("bad main typemap");
+
+    string[] targs = {"hi", "hola"};
+    if (!argcargvtest.mainv(targs, 0).Equals("hi"))
+      throw new Exception("bad main typemap");
+    if (!argcargvtest.mainv(targs, 1).Equals("hola"))
+      throw new Exception("bad main typemap");
+    if (!argcargvtest.mainv(targs, 2).Equals("<<NULL>>"))
+      throw new Exception("bad main typemap");
+
+// For dynamically typed languages we test this throws an exception or similar
+// at runtime, but for C# this doesn't even compile (but we can't easily
+// test for that here).
+//  argcargvtest.mainv("hello", 1);
+
+    argcargvtest.initializeApp(largs);
+
+    // Check that an empty array works.
+    string[] empty_args = {};
+    if (argcargvtest.mainc(empty_args) != 0)
+      throw new Exception("bad main typemap");
+    if (!argcargvtest.mainv(empty_args, 0).Equals("<<NULL>>"))
+      throw new Exception("bad main typemap");
+
+    // Check that empty strings are handled.
+    string[] empty_string = {"hello", "", "world"};
+    if (argcargvtest.mainc(empty_string) != 3)
+      throw new Exception("bad main typemap");
+    if (argcargvtest.mainv(empty_string, 0) != "hello")
+      throw new Exception("bad main typemap");
+    if (argcargvtest.mainv(empty_string, 1) != "")
+      throw new Exception("bad main typemap");
+    if (argcargvtest.mainv(empty_string, 2) != "world")
+      throw new Exception("bad main typemap");
+    if (argcargvtest.mainv(empty_string, 3) != "<<NULL>>")
+      throw new Exception("bad main typemap");
+  }
+}
diff --git a/Examples/test-suite/csharp/catches_strings_runme.cs b/Examples/test-suite/csharp/catches_strings_runme.cs
new file mode 100644
index 0000000..e2e3364
--- /dev/null
+++ b/Examples/test-suite/csharp/catches_strings_runme.cs
@@ -0,0 +1,32 @@
+using System;
+using catches_stringsNamespace;
+
+public class catches_strings_runme {
+  public static void Main()
+  {
+    {
+      bool exception_thrown = false;
+      try {
+        StringsThrower.charstring();
+      } catch (ApplicationException e) {
+        if (!e.Message.Contains("charstring message"))
+          throw new ApplicationException("incorrect exception message:" + e);
+        exception_thrown = true;
+      }
+      if (!exception_thrown)
+        throw new ApplicationException("Should have thrown an exception");
+    }
+    {
+      bool exception_thrown = false;
+      try {
+        StringsThrower.stdstring();
+      } catch (ApplicationException e) {
+        if (!e.Message.Contains("stdstring message"))
+          throw new ApplicationException("incorrect exception message:" + e);
+        exception_thrown = true;
+      }
+      if (!exception_thrown)
+        throw new ApplicationException("Should have thrown an exception");
+    }
+  }
+}
diff --git a/Examples/test-suite/csharp/cpp11_move_only_runme.cs b/Examples/test-suite/csharp/cpp11_move_only_runme.cs
new file mode 100644
index 0000000..f2d1c4c
--- /dev/null
+++ b/Examples/test-suite/csharp/cpp11_move_only_runme.cs
@@ -0,0 +1,34 @@
+using System;
+using cpp11_move_onlyNamespace;
+
+public class cpp11_move_only_runme {
+
+  public static void Main() {
+
+    // Output
+    Counter.reset_counts();
+    using (MoveOnly mo = MoveOnly.create()) {
+    }
+    Counter.check_counts(1, 0, 0, 2, 0, 3);
+
+    Counter.reset_counts();
+    using (MovableCopyable mo = MovableCopyable.create()) {
+    }
+    Counter.check_counts(2, 1, 0, 0, 1, 3);
+
+    // Move semantics not used
+    Counter.reset_counts();
+    using (MovableCopyable mo = MovableCopyable.createConst()) {
+    }
+    Counter.check_counts(2, 1, 1, 0, 0, 3);
+
+    // Input
+    Counter.reset_counts();
+    using (MovableCopyable mo = new MovableCopyable(222)) {
+      Counter.check_counts(1, 0, 0, 0, 0, 0);
+      MovableCopyable.take(mo);
+      Counter.check_counts(2, 0, 1, 1, 0, 2);
+    }
+    Counter.check_counts(2, 0, 1, 1, 0, 3);
+  }
+}
diff --git a/Examples/test-suite/csharp/cpp11_move_only_valuewrapper_runme.cs b/Examples/test-suite/csharp/cpp11_move_only_valuewrapper_runme.cs
new file mode 100644
index 0000000..d6a42a3
--- /dev/null
+++ b/Examples/test-suite/csharp/cpp11_move_only_valuewrapper_runme.cs
@@ -0,0 +1,33 @@
+using System;
+using cpp11_move_only_valuewrapperNamespace;
+
+public class cpp11_move_only_valuewrapper_runme {
+
+  public static void Main() {
+    Counter.reset_counts();
+    using (XXX xxx = cpp11_move_only_valuewrapper.createXXX()) {
+    }
+    if (cpp11_move_only_valuewrapper.has_cplusplus11())
+      // Was (1, 2, 0, 0, 0, 3) before SwigValueWrapper::operator=(T &&) was added.
+      // Was (1, 1, 0, 1, 0, 3) before SwigValueWrapper::operator T&&() was added with new "out" typemaps
+      Counter.check_counts(1, 0, 0, 2, 0, 3);
+    Counter.reset_counts();
+    using (XXX xxx = cpp11_move_only_valuewrapper.createXXX2()) {
+    }
+    if (cpp11_move_only_valuewrapper.has_cplusplus11())
+      Counter.check_counts(1, 0, 0, 2, 0, 3);
+    cpp11_move_only_valuewrapper.test1();
+    cpp11_move_only_valuewrapper.test2();
+    cpp11_move_only_valuewrapper.test3();
+    cpp11_move_only_valuewrapper.test4();
+    cpp11_move_only_valuewrapper.test5();
+    cpp11_move_only_valuewrapper.test6();
+
+    // Tests SwigValueWrapper, std::unique_ptr (SWIG not parsing a type that is move-only)
+    Counter.reset_counts();
+    SWIGTYPE_p_std__unique_ptrT_XXX_t ptr = cpp11_move_only_valuewrapper.makeUniqueXXX();
+    cpp11_move_only_valuewrapper.cleanup(ptr);
+    Counter.check_counts(1, 0, 0, 0, 0, 1);
+  }
+
+}
diff --git a/Examples/test-suite/csharp/cpp11_move_typemaps_runme.cs b/Examples/test-suite/csharp/cpp11_move_typemaps_runme.cs
new file mode 100644
index 0000000..96849c4
--- /dev/null
+++ b/Examples/test-suite/csharp/cpp11_move_typemaps_runme.cs
@@ -0,0 +1,37 @@
+using System;
+using cpp11_move_typemapsNamespace;
+
+public class cpp11_move_typemaps_runme {
+
+  public static void Main() {
+    Counter.reset_counts();
+    using (MoveOnly mo = new MoveOnly(111)) {
+      Counter.check_counts(1, 0, 0, 0, 0, 0);
+      MoveOnly.take(mo);
+      Counter.check_counts(1, 0, 0, 1, 0, 2);
+    }
+    Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+    Counter.reset_counts();
+    using (MovableCopyable mo = new MovableCopyable(111)) {
+      Counter.check_counts(1, 0, 0, 0, 0, 0);
+      MovableCopyable.take(mo);
+      Counter.check_counts(1, 0, 0, 1, 0, 2);
+    }
+    Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+    using (MoveOnly mo = new MoveOnly(222)) {
+      MoveOnly.take(mo);
+      bool exception_thrown = false;
+      try {
+        MoveOnly.take(mo);
+      } catch (ApplicationException e) {
+        if (!e.Message.Contains("Cannot release ownership as memory is not owned"))
+          throw new ApplicationException("incorrect exception message");
+        exception_thrown = true;
+      }
+      if (!exception_thrown)
+        throw new ApplicationException("double usage of take should have been an error");
+    }
+  }
+}
diff --git a/Examples/test-suite/csharp/cpp11_rvalue_reference_move_runme.cs b/Examples/test-suite/csharp/cpp11_rvalue_reference_move_runme.cs
new file mode 100644
index 0000000..9b26606
--- /dev/null
+++ b/Examples/test-suite/csharp/cpp11_rvalue_reference_move_runme.cs
@@ -0,0 +1,86 @@
+using System;
+using cpp11_rvalue_reference_moveNamespace;
+
+public class cpp11_rvalue_reference_move_runme {
+  public static void Main() {
+    {
+      // Function containing rvalue reference parameter
+      Counter.reset_counts();
+      MovableCopyable mo = new MovableCopyable(222);
+      Counter.check_counts(1, 0, 0, 0, 0, 0);
+      MovableCopyable.movein(mo);
+      Counter.check_counts(1, 0, 0, 1, 0, 2);
+      if (!MovableCopyable.is_nullptr(mo))
+        throw new ApplicationException("is_nullptr failed");
+      mo.Dispose();
+      Counter.check_counts(1, 0, 0, 1, 0, 2);
+    }
+
+    {
+      // Move constructor test
+      Counter.reset_counts();
+      MovableCopyable mo = new MovableCopyable(222);
+      Counter.check_counts(1, 0, 0, 0, 0, 0);
+      MovableCopyable mo_moved = new MovableCopyable(mo);
+      Counter.check_counts(1, 0, 0, 1, 0, 1);
+      if (!MovableCopyable.is_nullptr(mo))
+        throw new ApplicationException("is_nullptr failed");
+      mo.Dispose();
+      Counter.check_counts(1, 0, 0, 1, 0, 1);
+      mo_moved.Dispose();
+      Counter.check_counts(1, 0, 0, 1, 0, 2);
+    }
+
+    {
+      // Move assignment operator test
+      Counter.reset_counts();
+      MovableCopyable mo111 = new MovableCopyable(111);
+      MovableCopyable mo222 = new MovableCopyable(222);
+      Counter.check_counts(2, 0, 0, 0, 0, 0);
+      mo111.MoveAssign(mo222);
+      Counter.check_counts(2, 0, 0, 0, 1, 1);
+      if (!MovableCopyable.is_nullptr(mo222))
+        throw new ApplicationException("is_nullptr failed");
+      mo222.Dispose();
+      Counter.check_counts(2, 0, 0, 0, 1, 1);
+      mo111.Dispose();
+      Counter.check_counts(2, 0, 0, 0, 1, 2);
+    }
+
+    {
+      // null check
+      Counter.reset_counts();
+      bool exception_thrown = false;
+      try {
+        MovableCopyable.movein(null);
+      } catch (ArgumentNullException e) {
+        if (!e.Message.Contains("MovableCopyable && is null"))
+          throw new ApplicationException("incorrect exception message:" + e);
+        exception_thrown = true;
+      }
+      if (!exception_thrown)
+        throw new ApplicationException("Should have thrown null error");
+      Counter.check_counts(0, 0, 0, 0, 0, 0);
+    }
+
+    {
+      // output
+      Counter.reset_counts();
+      MovableCopyable mc = MovableCopyable.moveout(1234);
+      Counter.check_counts(2, 0, 0, 0, 1, 1);
+      MovableCopyable.check_numbers_match(mc, 1234);
+
+      bool exception_thrown = false;
+      try {
+        MovableCopyable.movein(mc);
+      } catch (ApplicationException e) {
+        if (!e.Message.Contains("Cannot release ownership as memory is not owned"))
+          throw new ApplicationException("incorrect exception message");
+        exception_thrown = true;
+      }
+      if (!exception_thrown)
+        throw new ApplicationException("Should have thrown 'Cannot release ownership as memory is not owned' error");
+      Counter.check_counts(2, 0, 0, 0, 1, 1);
+    }
+  }
+}
diff --git a/Examples/test-suite/csharp/cpp11_shared_ptr_template_upcast_runme.cs b/Examples/test-suite/csharp/cpp11_shared_ptr_template_upcast_runme.cs
new file mode 100644
index 0000000..e76d2ba
--- /dev/null
+++ b/Examples/test-suite/csharp/cpp11_shared_ptr_template_upcast_runme.cs
@@ -0,0 +1,15 @@
+// This is the cpp11_shared_ptr_template_upcast runtime testcase. It checks that SWIG generates the appropriate upcasted shared_ptr type for a template instantiation deriving from a base class.
+// For this case, the expected behavior is: given a cptr with underlying type shared_ptr<Printable<Derived> >, PrintableDerived_SWIGSmartPtrUpcast returns a cptr with 
+// underlying type std::shared_ptr< Derived >, where Printable<Derived> inherits from Derived.
+using System;
+using cpp11_shared_ptr_template_upcastNamespace;
+
+public class cpp11_shared_ptr_template_upcast_runme
+{
+    static void Main()
+    {
+        PrintableDerived pd = cpp11_shared_ptr_template_upcast.MakePrintableDerived(20);
+        pd.GetResult();
+        pd.GetFormatted();
+    }
+}
diff --git a/Examples/test-suite/csharp/cpp11_std_array_runme.cs b/Examples/test-suite/csharp/cpp11_std_array_runme.cs
index ee7c5ee..649e062 100644
--- a/Examples/test-suite/csharp/cpp11_std_array_runme.cs
+++ b/Examples/test-suite/csharp/cpp11_std_array_runme.cs
@@ -78,5 +78,20 @@
         catch (ArgumentOutOfRangeException)
         {
         }
+
+        // ICollection constructor, differently sized
+        ai = new ArrayInt6(new int[] {1, 2, 3});
+        compareContainers(ai, new int[] { 1, 2, 3, 0, 0, 0});
+        ai = new ArrayInt6(new int[] {1, 2, 3, 4, 5, 6, 7, 8});
+        compareContainers(ai, new int[] { 1, 2, 3, 4, 5, 6});
+
+        // ToArray test
+        int[] aiArray = ai.ToArray();
+        for (int i=0; i<ai.Count; i++) {
+          if (aiArray[i] != ai[i])
+            throw new Exception("ToArray failed, index:" + i);
+        }
+        if (ai.Count != aiArray.Length)
+          throw new Exception("ToArray lengths mismatch");
     }
 }
diff --git a/Examples/test-suite/csharp/cpp11_std_unique_ptr_runme.cs b/Examples/test-suite/csharp/cpp11_std_unique_ptr_runme.cs
new file mode 100644
index 0000000..7d905e0
--- /dev/null
+++ b/Examples/test-suite/csharp/cpp11_std_unique_ptr_runme.cs
@@ -0,0 +1,131 @@
+using System;
+using cpp11_std_unique_ptrNamespace;
+
+public class cpp11_std_unique_ptr_runme {
+    private static void WaitForGC()
+    {
+        System.GC.Collect(); 
+        System.GC.WaitForPendingFinalizers();
+        System.Threading.Thread.Sleep(10);
+    }
+
+    private static void checkCount(int expected_count)
+    {
+      int actual_count = Klass.getTotal_count();
+      if (actual_count != expected_count)
+        throw new ApplicationException("Counts incorrect, expected:" + expected_count + " actual:" + actual_count);
+    }
+
+    public static void Main()
+    {
+        // Test raw pointer handling involving virtual inheritance
+        using (KlassInheritance kini = new KlassInheritance("KlassInheritanceInput")) {
+          checkCount(1);
+          string s = cpp11_std_unique_ptr.useKlassRawPtr(kini);
+          if (s != "KlassInheritanceInput")
+            throw new ApplicationException("Incorrect string: " + s);
+        }
+        checkCount(0);
+
+        // unique_ptr as input
+        using (Klass kin = new Klass("KlassInput")) {
+          checkCount(1);
+          string s = cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+          checkCount(0);
+          if (s != "KlassInput")
+            throw new ApplicationException("Incorrect string: " + s);
+          if (!cpp11_std_unique_ptr.is_nullptr(kin))
+            throw new ApplicationException("is_nullptr failed");
+        } // Dispose should not fail, even though already deleted
+        checkCount(0);
+
+        using (Klass kin = new Klass("KlassInput")) {
+          checkCount(1);
+          string s = cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+          checkCount(0);
+          if (s != "KlassInput")
+            throw new ApplicationException("Incorrect string: " + s);
+          if (!cpp11_std_unique_ptr.is_nullptr(kin))
+            throw new ApplicationException("is_nullptr failed");
+          bool exception_thrown = false;
+          try {
+            cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+          } catch (ApplicationException e) {
+            if (!e.Message.Contains("Cannot release ownership as memory is not owned"))
+              throw new ApplicationException("incorrect exception message");
+            exception_thrown = true;
+          }
+          if (!exception_thrown)
+              throw new ApplicationException("double usage of takeKlassUniquePtr should have been an error");
+        } // Dispose should not fail, even though already deleted
+        checkCount(0);
+
+        using (Klass kin = new Klass("KlassInput")) {
+            bool exception_thrown = false;
+            Klass notowned = cpp11_std_unique_ptr.get_not_owned_ptr(kin);
+            try {
+              cpp11_std_unique_ptr.takeKlassUniquePtr(notowned);
+            } catch (ApplicationException e) {
+              if (!e.Message.Contains("Cannot release ownership as memory is not owned"))
+                throw new ApplicationException("incorrect exception message");
+              exception_thrown = true;
+            }
+            if (!exception_thrown)
+                throw new ApplicationException("Should have thrown 'Cannot release ownership as memory is not owned' error");
+            checkCount(1);
+        }
+        checkCount(0);
+
+        using (KlassInheritance kini = new KlassInheritance("KlassInheritanceInput")) {
+          checkCount(1);
+          string s = cpp11_std_unique_ptr.takeKlassUniquePtr(kini);
+          checkCount(0);
+          if (s != "KlassInheritanceInput")
+            throw new ApplicationException("Incorrect string: " + s);
+          if (!cpp11_std_unique_ptr.is_nullptr(kini))
+            throw new ApplicationException("is_nullptr failed");
+        } // Dispose should not fail, even though already deleted
+        checkCount(0);
+
+        cpp11_std_unique_ptr.takeKlassUniquePtr(null);
+        cpp11_std_unique_ptr.takeKlassUniquePtr(cpp11_std_unique_ptr.make_null());
+        checkCount(0);
+
+        // overloaded parameters
+        if (cpp11_std_unique_ptr.overloadTest() != 0)
+          throw new ApplicationException("overloadTest failed");
+        if (cpp11_std_unique_ptr.overloadTest(null) != 1)
+          throw new ApplicationException("overloadTest failed");
+        if (cpp11_std_unique_ptr.overloadTest(new Klass("over")) != 1)
+          throw new ApplicationException("overloadTest failed");
+        checkCount(0);
+
+
+        // unique_ptr as output
+        Klass k1 = cpp11_std_unique_ptr.makeKlassUniquePtr("first");
+        if (k1.getLabel() != "first")
+            throw new Exception("wrong object label");
+
+        Klass k2 = cpp11_std_unique_ptr.makeKlassUniquePtr("second");
+        checkCount(2);
+
+        using (Klass k3 = cpp11_std_unique_ptr.makeKlassUniquePtr("second")) {
+          checkCount(3);
+        }
+        checkCount(2);
+
+        k1.Dispose();
+        k1 = null;
+        checkCount(1);
+
+        if (k2.getLabel() != "second")
+            throw new Exception("wrong object label");
+
+        k2.Dispose();
+        k2 = null;
+        checkCount(0);
+
+        if (cpp11_std_unique_ptr.makeNullUniquePtr() != null)
+          throw new Exception("null failure");
+    }
+}
diff --git a/Examples/test-suite/csharp/cpp11_std_unordered_map_runme.cs b/Examples/test-suite/csharp/cpp11_std_unordered_map_runme.cs
new file mode 100644
index 0000000..2b9e31e
--- /dev/null
+++ b/Examples/test-suite/csharp/cpp11_std_unordered_map_runme.cs
@@ -0,0 +1,126 @@
+using System;
+using System.Collections.Generic;
+using cpp11_std_unordered_mapNamespace;
+
+public class runme
+{
+  static void checkThat(bool mustBeTrue)
+  {
+    if (!mustBeTrue)
+    {
+      throw new Exception("checkThat failed");
+    }
+  }
+
+  static void Main()
+  {
+    global::System.Collections.Generic.IDictionary<string, int> sim = new UnorderedMapStringInt();
+    global::System.Collections.Generic.IDictionary<int, int> iim = new UnorderedMapIntInt();
+
+    checkThat(((UnorderedMapStringInt)sim).IsEmpty);
+    checkThat(((UnorderedMapIntInt)iim).IsEmpty);
+
+    checkThat(sim.Count == 0);
+    checkThat(iim.Count == 0);
+
+    int myInt;
+    checkThat(!sim.TryGetValue("key", out myInt));
+    checkThat(!iim.TryGetValue(1, out myInt));
+
+    checkThat(!sim.ContainsKey("key"));
+    checkThat(!iim.ContainsKey(1));
+
+    sim.Add("key", 2);
+    iim.Add(1, 2);
+
+    checkThat(sim.Count == 1);
+    checkThat(iim.Count == 1);
+
+    checkThat(sim["key"] == 2);
+    checkThat(iim[1] == 2);
+
+    checkThat(sim.Remove("key"));
+    checkThat(iim.Remove(1));
+
+    checkThat(sim.Count == 0);
+    checkThat(iim.Count == 0);
+
+    checkThat(!sim.TryGetValue("key", out myInt));
+    checkThat(!iim.TryGetValue(1, out myInt));
+
+    checkThat(!sim.Remove("key"));
+    checkThat(!iim.Remove(1));
+
+    sim["key"] = 2;
+    iim[1] = 2;
+
+    sim.Clear();
+    iim.Clear();
+    checkThat(sim.Count == 0);
+    checkThat(iim.Count == 0);
+
+    sim["key1"] = 1;
+    iim[1] = 1;
+    sim["key2"] = 2;
+    iim[2] = 2;
+
+    checkThat(sim.Count == 2);
+    checkThat(iim.Count == 2);
+    checkThat(sim["key1"] == 1);
+    checkThat(iim[1] == 1);
+    checkThat(sim["key2"] == 2);
+    checkThat(iim[2] == 2);
+
+    sim["key1"] = 3;
+    iim[1] = 3;
+
+    checkThat(sim.Count == 2);
+    checkThat(iim.Count == 2);
+    checkThat(sim["key1"] == 3);
+    checkThat(iim[1] == 3);
+
+    {
+      int collectionSize = 20;
+      UnorderedMapStringInt simap = new UnorderedMapStringInt();
+      for (int i = 0; i < collectionSize; i++)
+      {
+          int val = i * 18;
+          simap.Add(i.ToString(), val);
+      }
+
+      // Keys and Values test
+      IList<string> keys = new List<string>(simap.Keys);
+      IList<int> values = new List<int>(simap.Values);
+      Dictionary<string, int> check = new Dictionary<string, int>();
+      if (keys.Count != collectionSize)
+        throw new Exception("Keys count test failed");
+
+      if (values.Count != collectionSize)
+        throw new Exception("Values count test failed");
+
+      for (int i = 0; i < keys.Count; i++)
+      {
+        if (simap[keys[i]] != values[i])
+          throw new Exception("Keys and values test failed for index " + i);
+        check.Add(keys[i], values[i]);
+      }
+
+      for (int i = 0; i < collectionSize; i++)
+      {
+        if (!check.ContainsKey(i.ToString()))
+          throw new Exception("Keys and Values ContainsKey test " + i + " failed");
+      }
+
+      // CopyTo() test
+      {
+        KeyValuePair<string, int>[] outputarray = new KeyValuePair<string, int>[collectionSize];
+        simap.CopyTo(outputarray);
+        foreach (KeyValuePair<string, int> val in outputarray)
+        {
+          if (simap[val.Key] != val.Value)
+            throw new Exception("CopyTo (1) test failed, index:" + val.Key);
+        }
+      }
+    }
+  }
+}
diff --git a/Examples/test-suite/csharp/cpp11_std_unordered_set_runme.cs b/Examples/test-suite/csharp/cpp11_std_unordered_set_runme.cs
new file mode 100644
index 0000000..ff0ec56
--- /dev/null
+++ b/Examples/test-suite/csharp/cpp11_std_unordered_set_runme.cs
@@ -0,0 +1,203 @@
+using System;
+using System.Collections.Generic;
+using cpp11_std_unordered_setNamespace;
+
+public class runme
+{
+    static void checkThat(bool mustBeTrue, string message)
+    {
+        if (!mustBeTrue)
+            throw new Exception("Test that the set " + message + " failed");
+    }
+
+    static void Main()
+    {
+        UnorderedSetString ss = new UnorderedSetString();
+
+        // Check the interface methods first.
+        ISet<string> s = ss;
+
+        checkThat(((UnorderedSetString)s).IsEmpty, "is empty");
+        checkThat(s.Count == 0, "is initially empty");
+        checkThat(!s.Contains("key"), "doesn't contain inexistent element");
+        checkThat(!s.Remove("key"), "returns false when removing inexistent element");
+
+        checkThat(s.Add("key"), "returns true when adding a new element");
+        checkThat(!s.Add("key"), "returns false when adding an existing element");
+        checkThat(s.Contains("key"), "contains the just added element");
+        checkThat(s.Remove("key"), "returns true when removing an existing element");
+        checkThat(s.Count == 0, "is empty again");
+
+        checkThat(s.Add("key1"), "Add(key1) returns true");
+        checkThat(s.Add("key2"), "Add(key2) returns true");
+        checkThat(s.Add("key3"), "Add(key3) returns true");
+
+        // Also check a different interface, providing a different Add() (sic!).
+        ICollection<string> coll = ss;
+        coll.Add("key");
+        checkThat(ss.Count == 4, "contains 4 elements");
+
+        // Now use object-specific methods, mimicking HashSet<>.
+        string val;
+        checkThat(ss.TryGetValue("key1", out val), "could retrieve existing item");
+        checkThat(val.Equals("key1"), "value was returned correctly by TryGetValue()");
+        checkThat(!ss.TryGetValue("no-such-key", out val), "couldn't retrieve inexistent item");
+        checkThat(val == null, "value was reset after failed TryGetValue()");
+
+        IList<string> list = new List<string>();
+        foreach (string str in ss) {
+            list.Add(str);
+        }
+        checkThat(list.Count == 4, "copy contains 4 elements");
+
+        ss.Clear();
+        checkThat(ss.Count == 0, "is empty after Clear()");
+
+        // Check set-theoretic methods.
+        checkThat(new UnorderedSetString().SetEquals(new UnorderedSetString()), "SetEquals() works for empty sets");
+        checkThat(new UnorderedSetString{"foo"}.SetEquals(new UnorderedSetString{"foo"}), "SetEquals() works for non-empty sets");
+        checkThat(!new UnorderedSetString{"foo"}.SetEquals(new[] {"bar"}), "SetEquals() doesn't always return true");
+
+        ss = new UnorderedSetString{"foo", "bar", "baz"};
+        ss.ExceptWith(new[] {"baz", "quux"});
+        checkThat(ss.SetEquals(new[] {"foo", "bar"}), "ExceptWith works");
+
+        ss = new UnorderedSetString{"foo", "bar", "baz"};
+        ss.IntersectWith(new[] {"baz", "quux"});
+        checkThat(ss.SetEquals(new[] {"baz"}), "IntersectWith works");
+
+        checkThat(ss.IsProperSubsetOf(new[] {"bar", "baz"}), "IsProperSubsetOf works");
+        checkThat(!ss.IsProperSubsetOf(new[] {"baz"}), "!IsProperSubsetOf works");
+        checkThat(ss.IsSubsetOf(new[] {"bar", "baz"}), "IsSubsetOf works");
+        checkThat(!ss.IsSubsetOf(new[] {"bar"}), "!IsSubsetOf works");
+
+        ss = new UnorderedSetString{"foo", "bar", "baz"};
+        checkThat(ss.IsProperSupersetOf(new[] {"bar"}), "IsProperSupersetOf works");
+        checkThat(!ss.IsProperSupersetOf(new[] {"quux"}), "IsProperSupersetOf works");
+        checkThat(ss.IsSupersetOf(new[] {"foo", "bar", "baz"}), "IsProperSupersetOf works");
+        checkThat(!ss.IsSupersetOf(new[] {"foo", "bar", "baz", "quux"}), "IsProperSupersetOf works");
+
+        checkThat(ss.Overlaps(new[] {"foo"}), "Overlaps works");
+        checkThat(!ss.Overlaps(new[] {"moo"}), "!Overlaps works");
+
+        ss.SymmetricExceptWith(new[] {"baz", "quux"});
+        checkThat(ss.SetEquals(new[] {"foo", "bar", "quux"}), "SymmetricExceptWith works");
+
+        ss = new UnorderedSetString{"foo", "bar", "baz"};
+        ss.UnionWith(new[] {"baz", "quux"});
+        checkThat(ss.SetEquals(new[] {"foo", "bar", "baz", "quux"}), "UnionWith works");
+
+        // And a set of primitive type.
+        UnorderedSetInt intSet = new UnorderedSetInt();
+        checkThat(intSet.Count == 0, "is initially empty");
+        checkThat(intSet.Add(17), "17 added successfully");
+        checkThat(!intSet.Add(17), "17 not added again");
+        checkThat(intSet.Count == 1, "not empty any more");
+        checkThat(intSet.Add(289), "289 added successfully");
+        checkThat(intSet.Count == 2, "even less empty now");
+
+        // Test IsProperSubsetOf
+        UnorderedSetInt intSet2 = new UnorderedSetInt();
+        checkThat(intSet2.IsProperSubsetOf(intSet), "empty set is proper subset of non-empty set");
+        checkThat(!intSet.IsProperSubsetOf(intSet2), "non-empty set is not proper subset of empty set");
+        intSet2.Add(17);
+        checkThat(intSet2.IsProperSubsetOf(intSet), "subset is proper subset of superset");
+        checkThat(!intSet.IsProperSubsetOf(intSet2), "superset is not proper subset of subset");
+        intSet2.Add(289);
+        checkThat(!intSet2.IsProperSubsetOf(intSet), "superset is not proper subset of itself");
+        checkThat(!intSet.IsProperSubsetOf(intSet2), "subset is not proper subset of itself");
+
+        // Test IsProperSupersetOf
+        intSet2 = new UnorderedSetInt();
+        checkThat(intSet.IsProperSupersetOf(intSet2), "superset is proper superset of subset");
+        checkThat(!intSet2.IsProperSupersetOf(intSet), "subset is not proper superset of superset");
+        checkThat(!intSet.IsProperSupersetOf(intSet), "set is not proper superset of itself");
+        checkThat(!intSet2.IsProperSupersetOf(intSet2), "subset is not proper superset of itself");
+        intSet2.Add(17);
+        checkThat(intSet.IsProperSupersetOf(intSet2), "superset is not proper superset of subset");
+        intSet2.Add(289);
+        checkThat(!intSet.IsProperSupersetOf(intSet2), "superset is not proper superset of itself");
+        checkThat(!intSet2.IsProperSupersetOf(intSet), "subset is not proper superset of itself");
+
+        // Test IsSubsetOf
+        intSet2 = new UnorderedSetInt();
+        checkThat(intSet2.IsSubsetOf(intSet), "empty set is subset of non-empty set");
+        checkThat(!intSet.IsSubsetOf(intSet2), "non-empty set is not subset of empty set");
+        intSet2.Add(17);
+        checkThat(intSet2.IsSubsetOf(intSet), "subset is subset of superset");
+        checkThat(!intSet.IsSubsetOf(intSet2), "superset is not subset of subset");
+        intSet2.Add(289);
+        checkThat(intSet2.IsSubsetOf(intSet), "superset is subset of itself");
+        checkThat(intSet.IsSubsetOf(intSet2), "subset is subset of itself");
+
+        // Test IsSupersetOf
+        intSet2 = new UnorderedSetInt();
+        checkThat(intSet.IsSupersetOf(intSet2), "superset is superset of subset");
+        checkThat(!intSet2.IsSupersetOf(intSet), "subset is not superset of superset");
+        checkThat(intSet.IsSupersetOf(intSet), "set is superset of itself");
+        checkThat(intSet2.IsSupersetOf(intSet2), "subset is superset of itself");
+        intSet2.Add(17);
+        checkThat(intSet.IsSupersetOf(intSet2), "superset is not superset of subset");
+        intSet2.Add(289);
+        checkThat(intSet.IsSupersetOf(intSet2), "superset is superset of itself");
+        checkThat(intSet2.IsSupersetOf(intSet), "subset is superset of itself");
+
+        // Test Overlaps
+        intSet2 = new UnorderedSetInt();
+        checkThat(!intSet2.Overlaps(intSet), "empty set does not overlap non-empty set");
+        checkThat(!intSet.Overlaps(intSet2), "non-empty set does not overlap empty set");
+        intSet2.Add(17);
+        checkThat(intSet2.Overlaps(intSet), "subset overlaps superset");
+        checkThat(intSet.Overlaps(intSet2), "superset overlaps subset");
+        intSet2.Add(289);
+        checkThat(intSet2.Overlaps(intSet), "superset overlaps itself");
+        checkThat(intSet.Overlaps(intSet2), "subset overlaps itself");
+
+        // Test SymmetricExceptWith
+        intSet2 = new UnorderedSetInt();
+        intSet2.SymmetricExceptWith(intSet);
+        checkThat(intSet2.SetEquals(intSet), "SymmetricExceptWith empty set works");
+        intSet2.SymmetricExceptWith(intSet);
+        checkThat(intSet2.Count == 0, "SymmetricExceptWith empty set twice works");
+        intSet2.Add(17);
+        intSet2.SymmetricExceptWith(intSet);
+        checkThat(intSet2.SetEquals(new[] {289}), "SymmetricExceptWith non-empty set works");
+        intSet2.SymmetricExceptWith(intSet);
+
+        // Test UnionWith
+        intSet2 = new UnorderedSetInt();
+        intSet2.UnionWith(intSet); // empty set union non-empty set
+        checkThat(intSet2.SetEquals(intSet), "UnionWith empty set works");
+        intSet2.UnionWith(intSet); // empty set union non-empty set
+        checkThat(intSet2.SetEquals(intSet), "UnionWith empty set twice works");
+        intSet2.Add(17);
+        intSet2.UnionWith(intSet);
+        checkThat(intSet2.SetEquals(intSet), "UnionWith non-empty set works");
+        intSet2.UnionWith(intSet);
+        checkThat(intSet2.SetEquals(intSet), "UnionWith non-empty set twice works");
+
+        // Test IntersectWith
+        intSet2 = new UnorderedSetInt();
+        intSet2.IntersectWith(intSet); // empty set intersect non-empty set
+        checkThat(intSet2.Count == 0, "IntersectWith empty set works");
+        intSet2.IntersectWith(intSet); // empty set intersect non-empty set
+        checkThat(intSet2.Count == 0, "IntersectWith empty set twice works");
+        intSet2.Add(17);
+        intSet2.IntersectWith(intSet);
+        checkThat(intSet2.SetEquals(new[] {17}), "IntersectWith non-empty set works");
+        intSet2.IntersectWith(intSet);
+        checkThat(intSet2.SetEquals(new[] {17}), "IntersectWith non-empty set twice works");
+
+        // Test ExceptWith
+        intSet2 = new UnorderedSetInt();
+        intSet2.ExceptWith(intSet); // empty set except non-empty set
+        checkThat(intSet2.Count == 0, "ExceptWith empty set works");
+        intSet2.ExceptWith(intSet); // empty set except non-empty set
+        checkThat(intSet2.Count == 0, "ExceptWith empty set twice works");
+        intSet2.Add(17);
+        intSet2.ExceptWith(intSet);
+        checkThat(intSet2.Count == 0, "ExceptWith non-empty set works");
+        intSet2.ExceptWith(intSet);
+        checkThat(intSet2.Count == 0, "ExceptWith non-empty set twice works");
+    }
+}
diff --git a/Examples/test-suite/csharp/cpp11_strongly_typed_enumerations_runme.cs b/Examples/test-suite/csharp/cpp11_strongly_typed_enumerations_runme.cs
index f2c25e7..dd74e27 100644
--- a/Examples/test-suite/csharp/cpp11_strongly_typed_enumerations_runme.cs
+++ b/Examples/test-suite/csharp/cpp11_strongly_typed_enumerations_runme.cs
@@ -9,6 +9,11 @@
     return expected + 1;
   }
 
+  public static void enumTypeCheck(Type actual, Type expected) {
+    if (actual != expected)
+      throw new ApplicationException("Enum type incorrect. Expected " + expected + " Actual: " + actual);
+  }
+
   public static void Main() {
     int val = 0;
     val = enumCheck((int)Enum1.Val1, val);
@@ -164,6 +169,18 @@
     enumCheck((int)cpp11_strongly_typed_enumerations.globalTest1(Enum1.Val5a), 13);
     enumCheck((int)cpp11_strongly_typed_enumerations.globalTest2(Class1.Enum12.Val5c), 1121);
     enumCheck((int)cpp11_strongly_typed_enumerations.globalTest3(Class1.Struct1.Enum12.Val5f), 3121);
+
+    // Check underlying enum type
+    enumTypeCheck(Enum.GetUnderlyingType(Enum2.Val1.GetType()), ((short)0).GetType());
+    enumTypeCheck(Enum.GetUnderlyingType(Enum4.Val1.GetType()), ((uint)0).GetType());
+    enumTypeCheck(Enum.GetUnderlyingType(Enum5.Val1.GetType()), ((int)0).GetType());
+    enumTypeCheck(Enum.GetUnderlyingType(Enum9.Val1.GetType()), ((ushort)0).GetType());
+    enumTypeCheck(Enum.GetUnderlyingType(Enum7td.Val1.GetType()), ((uint)0).GetType());
+    enumTypeCheck(Enum.GetUnderlyingType(Enum10.Val1.GetType()), ((byte)0).GetType());
+
+    enumTypeCheck(Enum.GetUnderlyingType(Enum15.Val1.GetType()), ((short)0).GetType());
+    enumTypeCheck(Enum.GetUnderlyingType(Enum16.Val1.GetType()), ((long)0).GetType());
+    enumTypeCheck(Enum.GetUnderlyingType(Enum17.Val1.GetType()), ((ulong)0).GetType());
   }
 }
 
diff --git a/Examples/test-suite/csharp/cpp17_director_string_view_runme.cs b/Examples/test-suite/csharp/cpp17_director_string_view_runme.cs
new file mode 100644
index 0000000..470d45b
--- /dev/null
+++ b/Examples/test-suite/csharp/cpp17_director_string_view_runme.cs
@@ -0,0 +1,55 @@
+using System;
+using cpp17_director_string_viewNamespace;
+
+public class runme
+{
+  static void Main()
+  {
+    runme r = new runme();
+    r.run();
+  }
+
+  void run()
+  {
+    String s;
+
+    cpp17_director_string_view_A c = new cpp17_director_string_view_A("hi");
+    for (int i=0; i<3; i++) {
+      s = c.call_get(i);
+      Object ii = i;
+      if (s != ii.ToString()) throw new Exception("cpp17_director_string_view_A.get(" + i + ") failed. Got:" + s);
+    }
+
+    cpp17_director_string_view_B b = new cpp17_director_string_view_B("hello");
+
+    s = b.get_first();
+    if (s != "cpp17_director_string_view_B.get_first") throw new Exception("get_first() failed");
+
+    s = b.call_get_first();
+    if (s != "cpp17_director_string_view_B.get_first") throw new Exception("call_get_first() failed");
+
+    s = b.call_get(0);
+    if (s != "cpp17_director_string_view_B.get: hello") throw new Exception("get(0) failed");
+  }
+}
+
+class cpp17_director_string_view_B : A {
+    public cpp17_director_string_view_B(String first) : base(first) {
+    }
+    public override String get_first() {
+      return "cpp17_director_string_view_B.get_first";
+    }
+
+    public override String get(int n) {
+      return "cpp17_director_string_view_B.get: " + base.get(n);
+    }
+}
+
+class cpp17_director_string_view_A : A {
+    public cpp17_director_string_view_A(String first) : base(first) {
+    }
+    public override String get(int n) {
+      Object nn = n;
+      return nn.ToString();
+    }
+}
diff --git a/Examples/test-suite/csharp/cpp17_string_view_runme.cs b/Examples/test-suite/csharp/cpp17_string_view_runme.cs
new file mode 100644
index 0000000..a7b54b7
--- /dev/null
+++ b/Examples/test-suite/csharp/cpp17_string_view_runme.cs
@@ -0,0 +1,97 @@
+using System;
+using cpp17_string_viewNamespace;
+
+public class runme
+{
+    static void Main()
+    {
+        // Checking expected use of %typemap(in) std::string_view {}
+        cpp17_string_view.test_value("Fee");
+
+        // Checking expected result of %typemap(out) std::string_view {}
+        if (cpp17_string_view.test_value("Fi") != "Fi")
+            throw new Exception("Test 1 failed");
+
+        // Verify type-checking for %typemap(in) std::string_view {}
+        try {
+            cpp17_string_view.test_value(null);
+            throw new Exception("Test 2 failed");
+        } catch (ArgumentNullException) {
+        }
+
+        // Checking expected use of %typemap(in) const std::string_view & {}
+        cpp17_string_view.test_const_reference("Fo");
+
+        // Checking expected result of %typemap(out) const std::string_view& {}
+        if (cpp17_string_view.test_const_reference("Fum") != "Fum")
+            throw new Exception("Test 3 failed");
+
+        // Verify type-checking for %typemap(in) const std::string_view & {}
+        try {
+            cpp17_string_view.test_const_reference(null);
+            throw new Exception("Test 4 failed");
+        } catch (ArgumentNullException) {
+        }
+
+        //
+        // Input and output typemaps for pointers and non-const references to
+        // std::string_view are *not* supported; the following tests confirm
+        // that none of these cases are slipping through.
+        //
+
+        SWIGTYPE_p_std__string_view stringPtr = null;
+
+        stringPtr = cpp17_string_view.test_pointer_out();
+
+        cpp17_string_view.test_pointer(stringPtr);
+
+        stringPtr = cpp17_string_view.test_const_pointer_out();
+
+        cpp17_string_view.test_const_pointer(stringPtr);
+
+        stringPtr = cpp17_string_view.test_reference_out();
+
+        cpp17_string_view.test_reference(stringPtr);
+
+        // Check throw exception specification
+        try {
+            cpp17_string_view.test_throw();
+            throw new Exception("Test 5 failed");
+        } catch (ApplicationException e) {
+          if (e.Message != "test_throw message")
+            throw new Exception("Test 5 string check: " + e.Message);
+        }
+        try {
+            cpp17_string_view.test_const_reference_throw();
+            throw new Exception("Test 6 failed");
+        } catch (ApplicationException e) {
+          if (e.Message != "test_const_reference_throw message")
+            throw new Exception("Test 6 string check: " + e.Message);
+        }
+
+        // Global variables
+        if (cpp17_string_view.ConstGlobalString != "const global string")
+          throw new Exception("ConstGlobalString test");
+
+        // Member variables
+        Structure myStructure = new Structure();
+        if (myStructure.ConstMemberString != "const member string")
+          throw new Exception("ConstMemberString test");
+
+        if (Structure.ConstStaticMemberString != "const static member string")
+          throw new Exception("ConstStaticMemberString test");
+
+        if (cpp17_string_view.stdstringview_empty() != "")
+          throw new Exception("stdstringview_empty test");
+        if (cpp17_string_view.c_empty() != "")
+          throw new Exception("c_empty test");
+        if (cpp17_string_view.c_null() != null)
+          throw new Exception("c_null test");
+        if (cpp17_string_view.get_null(cpp17_string_view.c_null()) != null)
+          throw new Exception("get_null c_null test");
+        if (cpp17_string_view.get_null(cpp17_string_view.c_empty()) != "non-null")
+          throw new Exception("get_null c_empty test");
+        if (cpp17_string_view.get_null(cpp17_string_view.stdstringview_empty()) != "non-null")
+          throw new Exception("get_null stdstringview_empty test");
+    }
+}
diff --git a/Examples/test-suite/csharp/csharp_argument_defaults_feature_runme.cs b/Examples/test-suite/csharp/csharp_argument_defaults_feature_runme.cs
new file mode 100644
index 0000000..3acd1ea
--- /dev/null
+++ b/Examples/test-suite/csharp/csharp_argument_defaults_feature_runme.cs
@@ -0,0 +1,65 @@
+using System;
+using csharp_argument_defaults_featureNamespace;
+
+public class runme {
+    static void Main() {
+        Foo foo = new Foo(1);
+        foo.bar(1); //shutup compiler warning
+        Foo bar = new Foo(1, c:3);
+
+        if(bar.bar(1) != 7)
+            throw new ApplicationException("bar.bar(1) != 7");
+        if(bar.bar(1, 4, 4) != 9)
+            throw new ApplicationException("bar.bar(1, 4, 4) != 9");
+        if(bar.bar(1, y:3) != 8)
+            throw new ApplicationException("bar.bar(1, y:3) != 8");
+        if(bar.bat() != 6)
+            throw new ApplicationException("bar.bat() != 6");
+        if(bar.bat(3,3) != 9)
+            throw new ApplicationException("bar.bat(3,3) != 9");
+        if(bar.zoo() != 5)
+            throw new ApplicationException("bar.zoo() != 5");
+        if(bar.lengthOfString() != 5)
+            throw new ApplicationException("bar.lengthOfString() != 5");
+        if(bar.zoo(x:"to") != 2)
+            throw new ApplicationException("bar.zoo(x:\"to\" != 2");
+        if(bar.pi() != System.Math.PI)
+            throw new ApplicationException("bar.pi() != Math.PI");
+        if(bar.valueofenum(t:EnumerationType.three) != 3)
+            throw new ApplicationException("bar.valueofenum(t:EnumerationType.three) != 3");
+        if(bar.valueofenum() != 2)
+            throw new ApplicationException("bar.valueofenum() != 2");
+        if(bar.valueofchar() != 99)
+            throw new ApplicationException("bar.valueofchar() != 99");
+        if(bar.valueofchar(c:'d') != 100)
+            throw new ApplicationException("bar.valueofchar(c:'d') != 100");
+
+        if(Foo.sbar(1) != 7)
+            throw new ApplicationException("Foo.sbar(1) != 7");
+        if(Foo.sbar(1, 4, 4) != 9)
+            throw new ApplicationException("Foo.sbar(1, 4, 4) != 9");
+        if(Foo.sbar(1, y:3) != 8)
+            throw new ApplicationException("Foo.sbar(1, y:3) != 8");
+        if(Foo.sbat() != 6)
+            throw new ApplicationException("Foo.sbat() != 6");
+        if(Foo.sbat(3,3) != 9)
+            throw new ApplicationException("Foo.sbat(3,3) != 9");
+
+        if(csharp_argument_defaults_feature.gbar(1) != 7)
+            throw new ApplicationException("gbar(1) != 7");
+        if(csharp_argument_defaults_feature.gbar(1, 4, 4) != 9)
+            throw new ApplicationException("gbar(1, 4, 4) != 9");
+        if(csharp_argument_defaults_feature.gbar(1, y:3) != 8)
+            throw new ApplicationException("gbar(1, y:3) != 8");
+        if(csharp_argument_defaults_feature.gbat() != 6)
+            throw new ApplicationException("gbat() != 6");
+        if(csharp_argument_defaults_feature.gbat(3,3) != 9)
+            throw new ApplicationException("gbat(3,3) != 9");
+
+        var iface = new AnImplementation();
+        if(iface.foo() != 6)
+            throw new ApplicationException("AnImplementation::foo() != 6");
+        if(iface.foo(z:5) != 7)
+            throw new ApplicationException("AnImplementation::foo(z:4) != 7");
+    }
+}
diff --git a/Examples/test-suite/csharp/csharp_director_typemaps_runme.cs b/Examples/test-suite/csharp/csharp_director_typemaps_runme.cs
new file mode 100644
index 0000000..6143332
--- /dev/null
+++ b/Examples/test-suite/csharp/csharp_director_typemaps_runme.cs
@@ -0,0 +1,53 @@
+
+using System;
+using System.Reflection;
+using csharp_director_typemapsNamespace;
+
+public class csharp_director_typemaps_runme {
+
+  class CSharpDirectorTypemaps_InStreamDerived : InStream
+  {
+    private int constant;
+    public CSharpDirectorTypemaps_InStreamDerived(int constant) { this.constant = constant; }
+    public override int Read(global::System.IntPtr buf, int len, out int readLen) {
+      readLen = (buf == global::System.IntPtr.Zero) ? -len - constant : len + constant;
+      return readLen;
+    }
+    public override int Write(global::System.IntPtr buf, int len, out int writeLen) {
+      writeLen = (buf == global::System.IntPtr.Zero) ? -len - constant : len + constant;
+      return writeLen;
+    }
+  }
+  public static void Main() {
+    int outLen = -1;
+    int k = 100;
+    int j = 23;
+    InStream instream = new CSharpDirectorTypemaps_InStreamDerived(k);
+
+    {
+      int ret = csharp_director_typemaps.callRead(instream, InStream.getCPtr(instream).Handle, j, out outLen);
+      Assert(outLen, j + k);
+      Assert(ret, j + k);
+    }
+    {
+      int ret = csharp_director_typemaps.callRead(instream, global::System.IntPtr.Zero, j, out outLen);
+      Assert(outLen, -j - k);
+      Assert(ret, -j - k);
+    }
+
+    {
+      int ret = csharp_director_typemaps.callWrite(instream, InStream.getCPtr(instream).Handle, j, out outLen);
+      Assert(outLen, j + k);
+      Assert(ret, j + k);
+    }
+    {
+      int ret = csharp_director_typemaps.callWrite(instream, global::System.IntPtr.Zero, j, out outLen);
+      Assert(outLen, -j - k);
+      Assert(ret, -j - k);
+    }
+  }
+  private static void Assert(int i1, int i2) {
+    if (i1 != i2)
+      throw new Exception("assertion failure. " + i1 + " != " + i2);
+  }
+}
diff --git a/Examples/test-suite/csharp/csharp_typemaps_runme.cs b/Examples/test-suite/csharp/csharp_typemaps_runme.cs
index 846644f..a9119a0 100644
--- a/Examples/test-suite/csharp/csharp_typemaps_runme.cs
+++ b/Examples/test-suite/csharp/csharp_typemaps_runme.cs
@@ -107,6 +107,22 @@
        Console.Error.WriteLine("Test failed (thread " + threadId + "): " + e.Message);
        Failed = true;
      }
+
+    // $imfuncname substitution
+    ProxyA pa = new ProxyA();
+    if (pa.imfuncname_test() != 123)
+      throw new ApplicationException("imfuncname_test is not 123");
+    if (ProxyA.imfuncname_static_test() != 234)
+      throw new ApplicationException("imfuncname_test is not 234");
+    if (csharp_typemaps.imfuncname_global_test() != 345)
+      throw new ApplicationException("imfuncname_test is not 345");
+
+    pa.variab = 1000;
+    if (pa.variab != 1000 + 111 + 222)
+      throw new ApplicationException("pa.variab is not 1333");
+    csharp_typemaps.global_variab = 1000;
+    if (csharp_typemaps.global_variab != 1000 + 333 + 444)
+      throw new ApplicationException("csharp_typemaps.variab is not 1777");
    }
 }
 
diff --git a/Examples/test-suite/csharp/director_basic_runme.cs b/Examples/test-suite/csharp/director_basic_runme.cs
index de299b1..a81f27e 100644
--- a/Examples/test-suite/csharp/director_basic_runme.cs
+++ b/Examples/test-suite/csharp/director_basic_runme.cs
@@ -50,7 +50,7 @@
       myNewBar.x = 10;
 
       // Low level implementation check
-//      my.testSwigDerivedClassHasMethod();
+      my.testSwigDerivedClassHasMethod();
 
       // These should not call the C# implementations as they are not overridden
       int v;
diff --git a/Examples/test-suite/csharp/director_classes_runme.cs b/Examples/test-suite/csharp/director_classes_runme.cs
index 700492f..25bb359 100644
--- a/Examples/test-suite/csharp/director_classes_runme.cs
+++ b/Examples/test-suite/csharp/director_classes_runme.cs
@@ -21,8 +21,8 @@
 Base - FullyOverloaded(bool 1)
 Base - SemiOverloaded(int -678)
 Base - SemiOverloaded(bool 1)
-Base - DefaultParms(10, 2.2)
-Base - DefaultParms(10, 1.1)
+Base - DefaultParms(10, 2.25)
+Base - DefaultParms(10, 1.125)
 --------------------------------
 Derived - Val(444.555)
 Derived - Ref(444.555)
@@ -32,8 +32,8 @@
 Derived - FullyOverloaded(bool 1)
 Derived - SemiOverloaded(int -678)
 Base - SemiOverloaded(bool 1)
-Derived - DefaultParms(10, 2.2)
-Derived - DefaultParms(10, 1.1)
+Derived - DefaultParms(10, 2.25)
+Derived - DefaultParms(10, 1.125)
 --------------------------------
 CSharpDerived - Val(444.555)
 CSharpDerived - Ref(444.555)
@@ -43,8 +43,8 @@
 CSharpDerived - FullyOverloaded(bool True)
 CSharpDerived - SemiOverloaded(-678)
 Base - SemiOverloaded(bool 1)
-CSharpDerived - DefaultParms(10, 2.2)
-CSharpDerived - DefaultParms(10, 1.1)
+CSharpDerived - DefaultParms(10, 2.25)
+CSharpDerived - DefaultParms(10, 1.125)
 ------------ Finish ------------
 */
 
@@ -113,7 +113,7 @@
     if (myCaller.SemiOverloadedCall(true) != "Base" + "::SemiOverloaded(bool)") throw new Exception("failed");
 
     // Default parameters methods test
-    if (NAMESPACE + myCaller.DefaultParmsCall(10, 2.2) != myBase.GetType() + "::DefaultParms(int, double)") throw new Exception("failed");
+    if (NAMESPACE + myCaller.DefaultParmsCall(10, 2.25) != myBase.GetType() + "::DefaultParms(int, double)") throw new Exception("failed");
     if (myBase.GetType() == typeof(CSharpDerived)) { // special handling for C# derived classes, there is no way to do this any other way
       if (NAMESPACE + myCaller.DefaultParmsCall(10) != myBase.GetType() + "::DefaultParms(int, double)") throw new Exception("failed");
     } else {
@@ -177,12 +177,12 @@
   // Note the following method can never be called from unmanaged code.
   // It is here only for code that calls it directly from managed code.
   // But should always be defined to ensure behaviour is consistent
-  // independent of where DefaultParsms is called from (managed or unmanaged code).
+  // independent of where DefaultParams is called from (managed or unmanaged code).
   // Note this method can never be called from unmanaged code
   public override String DefaultParms(int x)
   {
     if (director_classes.PrintDebug) Console.WriteLine("CSharpDerived - DefaultParms({0})", x);
-    return DefaultParms(x, 1.1/*use C++ default here*/);
+    return DefaultParms(x, 1.125/*use C++ default here*/);
   }
 }
 
diff --git a/Examples/test-suite/csharp/director_default_runme.cs b/Examples/test-suite/csharp/director_default_runme.cs
new file mode 100644
index 0000000..af14c1e
--- /dev/null
+++ b/Examples/test-suite/csharp/director_default_runme.cs
@@ -0,0 +1,58 @@
+using System;
+
+namespace director_defaultNamespace {
+
+public class runme
+{
+  static void Main()
+  {
+    {
+      MyFoo a = new MyFoo();
+      a = new MyFoo(10);
+      a.Dispose();
+    }
+
+    {
+      MyFoo a = new MyFoo();
+      if (a.GetMsg() != "MyFoo-default") {
+        throw new Exception( "Test 1 failed" );
+      }
+      if (a.GetMsg("boo") != "MyFoo-boo") {
+        throw new Exception( "Test 2 failed" );
+      }
+      a.Dispose();
+    }
+
+    {
+      Foo b = new Foo();
+      if (b.GetMsg() != "Foo-default") {
+        throw new Exception( "Test 1 failed" );
+      }
+      if (b.GetMsg("boo") != "Foo-boo") {
+        throw new Exception( "Test 2 failed" );
+      }
+      b.Dispose();
+    }
+  }
+}
+
+public class MyFoo : Foo
+{
+  public MyFoo()
+    : base()
+  {
+  }
+
+  public MyFoo(int i)
+    : base(i)
+  {
+  }
+
+  public override string Msg(string msg)
+  {
+    return "MyFoo-" + msg;
+  }
+}
+
+}
+
diff --git a/Examples/test-suite/csharp/director_pass_by_value_runme.cs b/Examples/test-suite/csharp/director_pass_by_value_runme.cs
index ba63715..1f64f6d 100644
--- a/Examples/test-suite/csharp/director_pass_by_value_runme.cs
+++ b/Examples/test-suite/csharp/director_pass_by_value_runme.cs
@@ -28,6 +28,8 @@
           break;
       };
     }
+    if (director_pass_by_value.has_cplusplus11())
+      Counter.check_counts(1, 0, 0, 1, 0, 1); // check move constructor called and just one destructor
     // bug was the passByVal 'global' object was destroyed after the call to virtualMethod had finished.
     int ret = runme.passByVal.getVal();
     if (ret != 0x12345678)
diff --git a/Examples/test-suite/csharp/director_property_runme.cs b/Examples/test-suite/csharp/director_property_runme.cs
new file mode 100644
index 0000000..b93e8e2
--- /dev/null
+++ b/Examples/test-suite/csharp/director_property_runme.cs
@@ -0,0 +1,64 @@
+using System;
+
+namespace director_propertyNamespace {
+
+public class runme
+{
+  static void Main()
+  {
+    {
+      Foo a = new MyFoo();
+      if (a.getA() != "") {
+        throw new Exception( "Test failed" );
+      }
+      a.setA("Hello");
+      if (a.getA() != "Hello set from MyFoo") {
+        throw new Exception( "Test failed" );
+      }
+      a.setAByRef("Hello");
+      if (a.getA() != "Hello setAByRef from MyFoo") {
+        throw new Exception( "Test failed" );
+      }
+      a.Dispose();
+    }
+
+    {
+      Foo a_original = new MyFoo();
+      Foo a = Foo.get_self(a_original);
+      if (a.getA() != "") {
+        throw new Exception( "Test failed" );
+      }
+      a.setA("Hello");
+      if (a.getA() != "Hello set from MyFoo") {
+        throw new Exception( "Test failed" );
+      }
+      a.setAByRef("Hello");
+      if (a.getA() != "Hello setAByRef from MyFoo") {
+        throw new Exception( "Test failed" );
+      }
+      a.Dispose();
+    }
+  }
+}
+
+public class MyFoo : Foo
+{
+  public MyFoo()
+    : base()
+  {
+  }
+
+  public override void setA(string a)
+  {
+    base.setA(a + " set from MyFoo");
+  }
+
+  public override void setAByRef(string a)
+  {
+    base.setA(a + " setAByRef from MyFoo");
+  }
+}
+
+}
+
+
diff --git a/Examples/test-suite/csharp/director_string_runme.cs b/Examples/test-suite/csharp/director_string_runme.cs
index 0b1b04f..759ca6d 100644
--- a/Examples/test-suite/csharp/director_string_runme.cs
+++ b/Examples/test-suite/csharp/director_string_runme.cs
@@ -3,7 +3,7 @@
 
 public class runme
 {
-  static void Main() 
+  static void Main()
   {
     runme r = new runme();
     r.run();
@@ -22,6 +22,9 @@
 
     director_string_B b = new director_string_B("hello");
 
+    s = b.get_first();
+    if (s != "director_string_B.get_first") throw new Exception("get_first() failed");
+
     s = b.call_get_first();
     if (s != "director_string_B.get_first") throw new Exception("call_get_first() failed");
 
@@ -36,7 +39,7 @@
     public override String get_first() {
       return "director_string_B.get_first";
     }
-  
+
     public override String get(int n) {
       return "director_string_B.get: " + base.get(n);
     }
@@ -50,4 +53,3 @@
       return nn.ToString();
     }
 }
-
diff --git a/Examples/test-suite/csharp/director_using_member_scopes_runme.cs b/Examples/test-suite/csharp/director_using_member_scopes_runme.cs
new file mode 100644
index 0000000..8b97990
--- /dev/null
+++ b/Examples/test-suite/csharp/director_using_member_scopes_runme.cs
@@ -0,0 +1,70 @@
+using System;
+
+namespace director_using_member_scopesNamespace {
+
+public class runme
+{
+  static void Main()
+  {
+    runme r = new runme();
+    r.run();
+  }
+
+  void run()
+  {
+    NativeWindowType nwt = new NativeWindowType();
+    {
+      MyApplicationContextSDL a = new MyApplicationContextSDL();
+
+      if (ApplicationContextBase.call_setWindowGrab(a, nwt, true) != 100)
+        throw new Exception("failed");
+
+      if (ApplicationContextSDL.call_setWindowGrab(a, nwt, true) != 100)
+        throw new Exception("failed");
+    }
+
+    {
+      MyACSDL a = new MyACSDL();
+
+      if (ACB.call_setWindowGrab(a, nwt, true) != 100)
+        throw new Exception("failed");
+      if (ACB.call_setWindowGrab(a, "hi", 0) != 200)
+        throw new Exception("failed");
+
+      if (ACSDL.call_setWindowGrab(a, nwt, true) != 100)
+        throw new Exception("failed");
+      if (ACSDL.call_setWindowGrab(a, "hi", 0) != 200)
+        throw new Exception("failed");
+    }
+  }
+}
+
+class MyApplicationContextSDL: ApplicationContextSDL
+{
+  public MyApplicationContextSDL() : base()
+  {
+  }
+
+  public override int setWindowGrab(NativeWindowType win, bool grab)
+  {
+    return 100;
+  }
+}
+
+class MyACSDL: ACSDL
+{
+  public MyACSDL() : base()
+  {
+  }
+
+  public override int setWindowGrab(NativeWindowType win, bool grab)
+  {
+    return 100;
+  }
+  public override int setWindowGrab(string s, int val)
+  {
+    return 200;
+  }
+}
+
+}
diff --git a/Examples/test-suite/csharp/director_void_runme.cs b/Examples/test-suite/csharp/director_void_runme.cs
index 24b470f..ef440a7 100644
--- a/Examples/test-suite/csharp/director_void_runme.cs
+++ b/Examples/test-suite/csharp/director_void_runme.cs
@@ -67,6 +67,12 @@
       if (x != 1334)
         throw new Exception("Bad4 should be 1334, got " + x);
     }
+    {
+      MemberVoid mv = new MemberVoid();
+      global::System.IntPtr zero = global::System.IntPtr.Zero;
+      mv.memberVariable = zero;
+      zero = mv.memberVariable;
+    }
   }
 }
 
diff --git a/Examples/test-suite/csharp/director_wstring_runme.cs b/Examples/test-suite/csharp/director_wstring_runme.cs
new file mode 100644
index 0000000..7258e7f
--- /dev/null
+++ b/Examples/test-suite/csharp/director_wstring_runme.cs
@@ -0,0 +1,56 @@
+using System;
+using director_wstringNamespace;
+
+public class runme
+{
+    static void Main()
+    {
+        runme r = new runme();
+        r.run();
+    }
+
+    void run()
+    {
+        director_wstring_B b = new director_wstring_B("hello");
+
+        b.get(0);
+        if (b.get_first() != "hello world!")
+            throw new ApplicationException("Incorrect get_first:" + b.get_first());
+
+        b.call_process_func();
+        if (b.smem != "hello")
+            throw new ApplicationException("Incorrect smem:" + b.smem);
+
+        b.call_process_wstring_func();
+        if (b.smem != "hello (wstring)")
+            throw new ApplicationException("Incorrect smem:" + b.smem);
+
+        b.call_process_wstring_ref_func();
+        if (b.smem != "hello (wstring ref)")
+            throw new ApplicationException("Incorrect smem:" + b.smem);
+    }
+}
+
+class director_wstring_B : A
+{
+    public String smem;
+    public director_wstring_B(String first) : base(first)
+    {
+    }
+    public override String get_first()
+    {
+        return base.get_first() + " world!";
+    }
+    public override void process_text(String s)
+    {
+        this.smem = s;
+    }
+    public override void process_wstring_text(String s)
+    {
+        this.smem = s + " (wstring)";
+    }
+    public override void process_wstring_ref_text(String s)
+    {
+        this.smem = s + " (wstring ref)";
+    }
+}
diff --git a/Examples/test-suite/csharp/friends_runme.cs b/Examples/test-suite/csharp/friends_runme.cs
index ae3ffb6..b2a2041 100644
--- a/Examples/test-suite/csharp/friends_runme.cs
+++ b/Examples/test-suite/csharp/friends_runme.cs
@@ -2,6 +2,11 @@
 using friendsNamespace;
 
 public class friends_runme {
+  private static void check_equal(int a, int b) {
+    if (a != b)
+      throw new Exception("Not equal " + a + " != " + b);
+  }
+
   public static void Main() {
     A a = new A(2);
 
@@ -22,7 +27,7 @@
     if (friends.mix(a,b) != 5)
       throw new Exception("failed");
 
-    D_d di = new D_d(2);
+    D_i di = new D_i(2);
     D_d dd = new D_d(3.3);
 
     // incredible template overloading working just fine
@@ -38,6 +43,22 @@
       throw new Exception("failed");
     if (friends.get_val1(dd) != 1.3)
       throw new Exception("failed");
+
+    if (friends.chum_blah() != 1234)
+      throw new Exception("failed");
+    if (friends.mate_blah() != 4321)
+      throw new Exception("failed");
+
+    Foe foe = new Foe(111);
+    check_equal(friends.friend_definition(), 10);
+    check_equal(friends.friend_declaration(), 11);
+    check_equal(friends.friend_args_definition(foe), 111);
+    check_equal(friends.friend_args_declaration(foe), 111);
+
+    check_equal(friends.friend_definition_compiler(), 20);
+    check_equal(friends.friend_declaration_compiler(), 21);
+    check_equal(friends.friend_args_definition_compiler(foe), 111);
+    check_equal(friends.friend_args_declaration_compiler(foe), 111);
   }
 }
 
diff --git a/Examples/test-suite/csharp/li_boost_shared_ptr_runme.cs b/Examples/test-suite/csharp/li_boost_shared_ptr_runme.cs
index 445c4d7..e383d40 100644
--- a/Examples/test-suite/csharp/li_boost_shared_ptr_runme.cs
+++ b/Examples/test-suite/csharp/li_boost_shared_ptr_runme.cs
@@ -591,7 +591,7 @@
       throw new Exception("verify value failed. Expected: " + expected + " Got: " + got);
   }
   private void verifyCount(int expected, Klass k) {
-    int got = li_boost_shared_ptr.use_count(k); 
+    int got = (int)li_boost_shared_ptr.use_count(k); 
     if (expected != got)
       throw new Exception("verify use_count failed. Expected: " + expected + " Got: " + got);
   }
diff --git a/Examples/test-suite/csharp/li_constraints_runme.cs b/Examples/test-suite/csharp/li_constraints_runme.cs
new file mode 100644
index 0000000..d66a998
--- /dev/null
+++ b/Examples/test-suite/csharp/li_constraints_runme.cs
@@ -0,0 +1,57 @@
+using System;
+using li_constraintsNamespace;
+
+public class runme {
+    static void check_double(bool except, Action<double> f, double val, string ex) {
+      bool actual = true;
+      bool proper = false;
+      try {
+        f(val);
+      } catch(Exception e) {
+        actual = false;
+        proper = e.Message.Equals(string.Join(" ", "Expected", "a", ex, "value."));
+      }
+      if (actual) {
+        if (!except)
+          throw new Exception(string.Join("", "function '", ex, "' with ", val.ToString(), " should perform an exception"));
+      } else {
+        if (except)
+          throw new Exception(string.Join("", "function '", ex, "' with ", val.ToString(), " should not perform an exception"));
+        else if (!proper)
+          throw new Exception(string.Join("", "function '", ex, "' with ", val.ToString(), " should perform a proper exception"));
+      }
+    }
+
+    static void Main() {
+      check_double(true, li_constraints.test_nonnegative, 10, "non-negative");
+      check_double(true, li_constraints.test_nonnegative, 0, "non-negative");
+      check_double(false, li_constraints.test_nonnegative, -10, "non-negative");
+
+      check_double(false, li_constraints.test_nonpositive, 10, "non-positive");
+      check_double(true, li_constraints.test_nonpositive, 0, "non-positive");
+      check_double(true, li_constraints.test_nonpositive, -10, "non-positive");
+
+      check_double(true, li_constraints.test_positive, 10, "positive");
+      check_double(false, li_constraints.test_positive, 0, "positive");
+      check_double(false, li_constraints.test_positive, -10, "positive");
+
+      check_double(false, li_constraints.test_negative, 10, "negative");
+      check_double(false, li_constraints.test_negative, 0, "negative");
+      check_double(true, li_constraints.test_negative, -10, "negative");
+
+      check_double(true, li_constraints.test_nonzero, 10, "nonzero");
+      check_double(false, li_constraints.test_nonzero, 0, "nonzero");
+      check_double(true, li_constraints.test_nonzero, -10, "nonzero");
+
+      bool have_exception = false;
+      try {
+        li_constraints.test_nonnull(null);
+      } catch(Exception e) {
+        have_exception = e.Message.Equals("Received a NULL pointer.");
+      }
+      if (!have_exception)
+          throw new Exception("test_nonnull should perform proper exception with 'null' value");
+      SWIGTYPE_p_void nonnull = li_constraints.get_nonnull();
+      li_constraints.test_nonnull(nonnull);
+    }
+}
diff --git a/Examples/test-suite/csharp/li_std_auto_ptr_runme.cs b/Examples/test-suite/csharp/li_std_auto_ptr_runme.cs
index 863b867..bc5c776 100644
--- a/Examples/test-suite/csharp/li_std_auto_ptr_runme.cs
+++ b/Examples/test-suite/csharp/li_std_auto_ptr_runme.cs
@@ -9,56 +9,123 @@
         System.Threading.Thread.Sleep(10);
     }
 
+    private static void checkCount(int expected_count)
+    {
+      int actual_count = Klass.getTotal_count();
+      if (actual_count != expected_count)
+        throw new ApplicationException("Counts incorrect, expected:" + expected_count + " actual:" + actual_count);
+    }
+
     public static void Main()
     {
+        // Test raw pointer handling involving virtual inheritance
+        using (KlassInheritance kini = new KlassInheritance("KlassInheritanceInput")) {
+          checkCount(1);
+          string s = li_std_auto_ptr.useKlassRawPtr(kini);
+          if (s != "KlassInheritanceInput")
+            throw new ApplicationException("Incorrect string: " + s);
+        }
+        checkCount(0);
+
+        // auto_ptr as input
+        using (Klass kin = new Klass("KlassInput")) {
+          checkCount(1);
+          string s = li_std_auto_ptr.takeKlassAutoPtr(kin);
+          checkCount(0);
+          if (s != "KlassInput")
+            throw new ApplicationException("Incorrect string: " + s);
+          if (!li_std_auto_ptr.is_nullptr(kin))
+            throw new ApplicationException("is_nullptr failed");
+        } // Dispose should not fail, even though already deleted
+        checkCount(0);
+
+        using (Klass kin = new Klass("KlassInput")) {
+          checkCount(1);
+          string s = li_std_auto_ptr.takeKlassAutoPtr(kin);
+          checkCount(0);
+          if (s != "KlassInput")
+            throw new ApplicationException("Incorrect string: " + s);
+          if (!li_std_auto_ptr.is_nullptr(kin))
+            throw new ApplicationException("is_nullptr failed");
+          bool exception_thrown = false;
+          try {
+            li_std_auto_ptr.takeKlassAutoPtr(kin);
+          } catch (ApplicationException e) {
+            if (!e.Message.Contains("Cannot release ownership as memory is not owned"))
+              throw new ApplicationException("incorrect exception message");
+            exception_thrown = true;
+          }
+          if (!exception_thrown)
+              throw new ApplicationException("double usage of takeKlassAutoPtr should have been an error");
+        } // Dispose should not fail, even though already deleted
+        checkCount(0);
+
+        using (Klass kin = new Klass("KlassInput")) {
+            bool exception_thrown = false;
+            Klass notowned = li_std_auto_ptr.get_not_owned_ptr(kin);
+            try {
+              li_std_auto_ptr.takeKlassAutoPtr(notowned);
+            } catch (ApplicationException e) {
+              if (!e.Message.Contains("Cannot release ownership as memory is not owned"))
+                throw new ApplicationException("incorrect exception message");
+              exception_thrown = true;
+            }
+            if (!exception_thrown)
+                throw new ApplicationException("Should have thrown 'Cannot release ownership as memory is not owned' error");
+            checkCount(1);
+        }
+        checkCount(0);
+
+        using (KlassInheritance kini = new KlassInheritance("KlassInheritanceInput")) {
+          checkCount(1);
+          string s = li_std_auto_ptr.takeKlassAutoPtr(kini);
+          checkCount(0);
+          if (s != "KlassInheritanceInput")
+            throw new ApplicationException("Incorrect string: " + s);
+          if (!li_std_auto_ptr.is_nullptr(kini))
+            throw new ApplicationException("is_nullptr failed");
+        } // Dispose should not fail, even though already deleted
+        checkCount(0);
+
+        li_std_auto_ptr.takeKlassAutoPtr(null);
+        li_std_auto_ptr.takeKlassAutoPtr(li_std_auto_ptr.make_null());
+        checkCount(0);
+
+        // overloaded parameters
+        if (li_std_auto_ptr.overloadTest() != 0)
+          throw new ApplicationException("overloadTest failed");
+        if (li_std_auto_ptr.overloadTest(null) != 1)
+          throw new ApplicationException("overloadTest failed");
+        if (li_std_auto_ptr.overloadTest(new Klass("over")) != 1)
+          throw new ApplicationException("overloadTest failed");
+        checkCount(0);
+
+
+        // auto_ptr as output
         Klass k1 = li_std_auto_ptr.makeKlassAutoPtr("first");
         if (k1.getLabel() != "first")
             throw new Exception("wrong object label");
 
         Klass k2 = li_std_auto_ptr.makeKlassAutoPtr("second");
-        if (Klass.getTotal_count() != 2)
-            throw new Exception("number of objects should be 2");
+        checkCount(2);
 
         using (Klass k3 = li_std_auto_ptr.makeKlassAutoPtr("second")) {
-          if (Klass.getTotal_count() != 3)
-            throw new Exception("number of objects should be 3");
+          checkCount(3);
         }
-        if (Klass.getTotal_count() != 2)
-            throw new Exception("number of objects should be 2");
+        checkCount(2);
 
+        k1.Dispose();
         k1 = null;
-        {
-          int countdown = 500;
-          int expectedCount = 1;
-          while (true) {
-            WaitForGC();
-            if (--countdown == 0)
-              break;
-            if (Klass.getTotal_count() == expectedCount)
-              break;
-          };
-          int actualCount = Klass.getTotal_count();
-          if (actualCount != expectedCount)
-            Console.Error.WriteLine("Expected count: " + expectedCount + " Actual count: " + actualCount); // Finalizers are not guaranteed to be run and sometimes they just don't
-        }
+        checkCount(1);
 
         if (k2.getLabel() != "second")
             throw new Exception("wrong object label");
 
+        k2.Dispose();
         k2 = null;
-        {
-          int countdown = 500;
-          int expectedCount = 0;
-          while (true) {
-            WaitForGC();
-            if (--countdown == 0)
-              break;
-            if (Klass.getTotal_count() == expectedCount)
-              break;
-          }
-          int actualCount = Klass.getTotal_count();
-          if (actualCount != expectedCount)
-            Console.Error.WriteLine("Expected count: " + expectedCount + " Actual count: " + actualCount); // Finalizers are not guaranteed to be run and sometimes they just don't
-        }
+        checkCount(0);
+
+        if (li_std_auto_ptr.makeNullAutoPtr() != null)
+          throw new Exception("null failure");
     }
 }
diff --git a/Examples/test-suite/csharp/li_std_map_runme.cs b/Examples/test-suite/csharp/li_std_map_runme.cs
index 51510c9..e2b0920 100644
--- a/Examples/test-suite/csharp/li_std_map_runme.cs
+++ b/Examples/test-suite/csharp/li_std_map_runme.cs
@@ -158,6 +158,8 @@
         simap.Clear();
         if (simap.Count != 0)
             throw new Exception("Clear test failed");
+        if (!simap.IsEmpty)
+            throw new Exception("Empty test failed");
 
         // Test wrapped methods
         for (int i = 1; i <= 5; i++)
diff --git a/Examples/test-suite/csharp/li_std_set_runme.cs b/Examples/test-suite/csharp/li_std_set_runme.cs
index e9cd2c2..34939d7 100644
--- a/Examples/test-suite/csharp/li_std_set_runme.cs
+++ b/Examples/test-suite/csharp/li_std_set_runme.cs
@@ -17,6 +17,7 @@
         // Check the interface methods first.
         ISet<string> s = ss;
 
+        checkThat(((StringSet)s).IsEmpty, "is empty");
         checkThat(s.Count == 0, "is initially empty");
         checkThat(!s.Contains("key"), "doesn't contain inexistent element");
         checkThat(!s.Remove("key"), "returns false when removing inexistent element");
diff --git a/Examples/test-suite/csharp/li_std_string_runme.cs b/Examples/test-suite/csharp/li_std_string_runme.cs
index 4c9d713..b4bdcfe 100644
--- a/Examples/test-suite/csharp/li_std_string_runme.cs
+++ b/Examples/test-suite/csharp/li_std_string_runme.cs
@@ -94,7 +94,20 @@
         Structure.StaticMemberString2 = s;
         if (Structure.StaticMemberString2 != s)
           throw new Exception("StaticMemberString2 test 2");
-      if (Structure.ConstStaticMemberString != "const static member string")
-        throw new Exception("ConstStaticMemberString test");
+        if (Structure.ConstStaticMemberString != "const static member string")
+          throw new Exception("ConstStaticMemberString test");
+
+        if (li_std_string.stdstring_empty() != "")
+          throw new Exception("stdstring_empty test");
+        if (li_std_string.c_empty() != "")
+          throw new Exception("c_empty test");
+        if (li_std_string.c_null() != null)
+          throw new Exception("c_null test");
+        if (li_std_string.get_null(li_std_string.c_null()) != null)
+          throw new Exception("get_null c_null test");
+        if (li_std_string.get_null(li_std_string.c_empty()) != "non-null")
+          throw new Exception("get_null c_empty test");
+        if (li_std_string.get_null(li_std_string.stdstring_empty()) != "non-null")
+          throw new Exception("get_null stdstring_empty test");
     }
 }
diff --git a/Examples/test-suite/csharp/li_std_vector_runme.cs b/Examples/test-suite/csharp/li_std_vector_runme.cs
index 0c6211c..33c84b2 100644
--- a/Examples/test-suite/csharp/li_std_vector_runme.cs
+++ b/Examples/test-suite/csharp/li_std_vector_runme.cs
@@ -520,6 +520,8 @@
     vect.Clear();
     if (vect.Count != 0)
       throw new Exception("Clear failed");
+    if (!vect.IsEmpty)
+      throw new Exception("Empty failed");
 
     // Finally test the methods being wrapped
     {
diff --git a/Examples/test-suite/csharp/li_std_wstring_runme.cs b/Examples/test-suite/csharp/li_std_wstring_runme.cs
index 8b7ba1b..97dfedb 100644
--- a/Examples/test-suite/csharp/li_std_wstring_runme.cs
+++ b/Examples/test-suite/csharp/li_std_wstring_runme.cs
@@ -1,3 +1,6 @@
+// This file has a BOM for UTF-8
+// Notes for displaying UTF-8 properly in Windows: https://stackoverflow.com/questions/49476326/displaying-unicode-in-powershell
+
 using System;
 using li_std_wstringNamespace;
 
@@ -5,17 +8,38 @@
 {
     static private void check_equal(char a, char b)
     {
-      if (a != b)
-        throw new Exception("char failed '" + a + "' != '" + b + "'");
+        if (a != b)
+            throw new Exception("char failed '" + a + "' != '" + b + "'");
+    }
+
+    static private void display_bytes(string s)
+    {
+        Console.Write("[");
+        if (s != null)
+        {
+            foreach (char x in s)
+            {
+                int n = Convert.ToInt32(x);
+                Console.Write(n.ToString("X") + " ");
+            }
+        }
+        else
+            Console.Write("null");
+        Console.WriteLine("]");
     }
 
     static private void check_equal(string a, string b)
     {
-      if (a != b)
-        throw new Exception("string failed '" + a + "' != '" + b + "'");
+        if (li_std_wstring.trace) {
+            Console.WriteLine("check_equal {0} {1}", a, b);
+            display_bytes(a);
+            display_bytes(b);
+        }
+        if (a != b)
+          throw new Exception("string failed '" + a + "' != '" + b + "'");
     }
 
-    static void Main() 
+    static void Main()
     {
         char h = 'h';
         check_equal(li_std_wstring.test_wcvalue(h), h);
@@ -30,6 +54,8 @@
         li_std_wstring.test_pointer(null);
         li_std_wstring.test_const_pointer(null);
 
+        check_equal(li_std_wstring.test_ccvalue(null), null);
+
         try {
             li_std_wstring.test_value(null);
             throw new Exception("NULL check failed");
@@ -37,10 +63,10 @@
         }
 
         try {
-              li_std_wstring.test_reference(null);
-              throw new Exception("NULL check failed");
+            li_std_wstring.test_reference(null);
+            throw new Exception("NULL check failed");
         } catch (ArgumentNullException e) {
-            if (!e.Message.Contains("type is null"))
+            if (!e.Message.Contains("is null"))
                 throw new Exception("Missing text " + e);
         }
         try {
@@ -54,13 +80,24 @@
         x = "hello";
         check_equal(li_std_wstring.test_const_reference(x), x);
 
-        /* Postpone, tricky, std::wstring portability problem.
+        /* Tricky, std::wstring portability problem.
          * std::wstring is 2 bytes on Windows, 4 bytes on Linux, LPWSTR is 2 bytes.
-         * .NET marshalling should work on Windows but not Linux.
-        string s = "abc";
-        if (!li_std_wstring.test_equal_abc(s))
-            throw new Exception("Not equal " + s);
-        */
+         */
+        string ss = "abc";
+        if (!li_std_wstring.test_equal_abc(ss))
+            throw new Exception("Not equal " + ss);
+
+        ss = "JP: 日本語";
+        if (!li_std_wstring.test_equal_jp(ss))
+            throw new Exception("Not equal " + ss);
+
+        ss = "DE: Kröpeliner Straße";
+        if (!li_std_wstring.test_equal_de(ss))
+            throw new Exception("Not equal " + ss);
+
+        ss = "RU: Война и мир";
+        if (!li_std_wstring.test_equal_ru(ss))
+            throw new Exception("Not equal " + ss);
 
         try {
             li_std_wstring.test_throw();
@@ -68,6 +105,24 @@
             check_equal(e.Message, "throwing test_throw");
         }
 
+        try {
+            li_std_wstring.test_throw_jp();
+        } catch (Exception e) {
+            check_equal(e.Message, "JP: 日本語");
+        }
+
+        try {
+            li_std_wstring.test_throw_ref_jp();
+        } catch (Exception e) {
+            check_equal(e.Message, "JP: 日本語");
+        }
+
+        try {
+            li_std_wstring.test_throw_wchar_t_ptr();
+        } catch (Exception e) {
+            check_equal(e.Message, "JP: 日本語");
+        }
+
         x = "abc\0def";
         // Unlike other languages, embedded NULL in std::string not supported
         // check_equal(li_std_wstring.test_value(x), x);
@@ -75,14 +130,28 @@
         check_equal(li_std_wstring.test_ccvalue(x), "abc");
         check_equal(li_std_wstring.test_wchar_overload(x), "abc");
 
+        // Member variables
+        var s = new wchar_test_struct();
+        s.wchar_t_member = h;
+        check_equal(s.wchar_t_member, h);
+        s.wchar_t_ptr_member = x;
+        check_equal(s.wchar_t_ptr_member, "abc");
+        s.wchar_t_ptr_member = ss;
+        check_equal(s.wchar_t_ptr_member, ss);
+
         {
             // Unicode strings
+            // Strings below are UTF8 in this file, but .NET holds them internally as UTF16
+            // DE: https://www.utf8-chartable.de/
+            // RU: https://www.utf8-chartable.de/unicode-utf8-table.pl?start=1024
             string[] test_strings = {
                 "JP: 日本語", "DE: Kröpeliner Straße" , "RU: Война и мир", "EN: War and Peace"
             };
 
             foreach (string expected in test_strings)
             {
+                if (li_std_wstring.trace)
+                    Console.WriteLine("expected (C#): " + expected);
                 string received = li_std_wstring.test_value(expected);
                 check_equal(received, expected);
             }
@@ -99,6 +168,13 @@
                 check_equal(received, expected);
             }
 
+            foreach (string expected in test_strings)
+            {
+                s.wchar_t_ptr_member = expected;
+                string received = s.wchar_t_ptr_member;
+                check_equal(received, expected);
+            }
+
             /* Not working for Japanese and Russian characters on Windows, okay on Linux
              * Is fixed by adding CharSet=CharSet.Unicode to the DllImport, so change to:
              * [global::System.Runtime.InteropServices.DllImport("li_std_wstring", CharSet=global::System.Runtime.InteropServices.CharSet.Unicode, EntryPoint="CSharp_li_std_wstringNamespace_test_wcvalue")]
diff --git a/Examples/test-suite/csharp/multiple_inheritance_abstract_runme.cs b/Examples/test-suite/csharp/multiple_inheritance_abstract_runme.cs
index 4584be3..512fbf2 100644
--- a/Examples/test-suite/csharp/multiple_inheritance_abstract_runme.cs
+++ b/Examples/test-suite/csharp/multiple_inheritance_abstract_runme.cs
@@ -216,6 +216,7 @@
     check(multiple_inheritance_abstract.InputCPtrRefBottom1(b1)!=103+104, "InputCPtrRefBottom1() failed");
     check(multiple_inheritance_abstract.InputCPtrRefBottom2(b2)!=206+205, "InputCPtrRefBottom2() failed");
     check(multiple_inheritance_abstract.InputCPtrRefBottom3(b3)!=307+308+309, "InputCPtrRefBottom3() failed");
+
     // Return pointers
     check(multiple_inheritance_abstract.MakePtrDerived1_CBase1().cbase1y()!=3, "MakePtrDerived1_CBase1 failed");
     check(multiple_inheritance_abstract.MakePtrDerived1_CBase2().cbase2()!=4, "MakePtrDerived1_CBase2 failed");
@@ -234,6 +235,15 @@
     check(multiple_inheritance_abstract.MakeRefDerived3_CBase1().cbase1y()!=7, "MakeRefDerived3_CBase1 failed");
     check(multiple_inheritance_abstract.MakeRefDerived3_CBase2().cbase2()!=8, "MakeRefDerived3_CBase2 failed");
 
+    // Return const pointer references
+    check(multiple_inheritance_abstract.MakeConstPtrRefDerived1_CBase1().cbase1y()!=3, "MakeConstPtrRefDerived1_CBase1 failed");
+    check(multiple_inheritance_abstract.MakeConstPtrRefDerived1_CBase2().cbase2()!=4, "MakeConstPtrRefDerived1_CBase2 failed");
+    check(multiple_inheritance_abstract.MakeConstPtrRefDerived2_CBase1().cbase1y()!=6, "MakeConstPtrRefDerived2_CBase1 failed");
+    check(multiple_inheritance_abstract.MakeConstPtrRefDerived2_ABase1().abase1()!=5, "MakeConstPtrRefDerived2_ABase1 failed");
+    check(multiple_inheritance_abstract.MakeConstPtrRefDerived3_ABase1().abase1()!=9, "MakeConstPtrRefDerived3_ABase1 failed");
+    check(multiple_inheritance_abstract.MakeConstPtrRefDerived3_CBase1().cbase1y()!=7, "MakeConstPtrRefDerived3_CBase1 failed");
+    check(multiple_inheritance_abstract.MakeConstPtrRefDerived3_CBase2().cbase2()!=8, "MakeConstPtrRefDerived3_CBase2 failed");
+
     // Return by value (sliced objects)
     check(multiple_inheritance_abstract.MakeValDerived1_CBase1().cbase1y()!=1, "MakeValDerived1_CBase1 failed");
     check(multiple_inheritance_abstract.MakeValDerived1_CBase2().cbase2()!=2, "MakeValDerived1_CBase2 failed");
diff --git a/Examples/test-suite/csharp/multiple_inheritance_interfaces_runme.cs b/Examples/test-suite/csharp/multiple_inheritance_interfaces_runme.cs
index c786ff9..96b74bc 100644
--- a/Examples/test-suite/csharp/multiple_inheritance_interfaces_runme.cs
+++ b/Examples/test-suite/csharp/multiple_inheritance_interfaces_runme.cs
@@ -83,5 +83,7 @@
     d.ia(10);
     d.ia("bye");
     d.ia("bye", false);
+
+    UndesirablesSwigImpl.UndesiredStaticMethod(UndesirablesSwigImpl.UndesiredEnum.UndesiredEnum1);
   }
 }
diff --git a/Examples/test-suite/csharp/multiple_inheritance_nspace_runme.cs b/Examples/test-suite/csharp/multiple_inheritance_nspace_runme.cs
index 6ed13a6..c279251 100644
--- a/Examples/test-suite/csharp/multiple_inheritance_nspace_runme.cs
+++ b/Examples/test-suite/csharp/multiple_inheritance_nspace_runme.cs
@@ -217,6 +217,7 @@
     check(multiple_inheritance_nspace.InputCPtrRefBottom1(b1)!=103+104, "InputCPtrRefBottom1() failed");
     check(multiple_inheritance_nspace.InputCPtrRefBottom2(b2)!=206+205, "InputCPtrRefBottom2() failed");
     check(multiple_inheritance_nspace.InputCPtrRefBottom3(b3)!=307+308+309, "InputCPtrRefBottom3() failed");
+
     // Return pointers
     check(multiple_inheritance_nspace.MakePtrDerived1_CBase1().cbase1y()!=3, "MakePtrDerived1_CBase1 failed");
     check(multiple_inheritance_nspace.MakePtrDerived1_CBase2().cbase2()!=4, "MakePtrDerived1_CBase2 failed");
@@ -235,6 +236,15 @@
     check(multiple_inheritance_nspace.MakeRefDerived3_CBase1().cbase1y()!=7, "MakeRefDerived3_CBase1 failed");
     check(multiple_inheritance_nspace.MakeRefDerived3_CBase2().cbase2()!=8, "MakeRefDerived3_CBase2 failed");
 
+    // Return const pointer references
+    check(multiple_inheritance_nspace.MakeConstPtrRefDerived1_CBase1().cbase1y()!=3, "MakeConstPtrRefDerived1_CBase1 failed");
+    check(multiple_inheritance_nspace.MakeConstPtrRefDerived1_CBase2().cbase2()!=4, "MakeConstPtrRefDerived1_CBase2 failed");
+    check(multiple_inheritance_nspace.MakeConstPtrRefDerived2_CBase1().cbase1y()!=6, "MakeConstPtrRefDerived2_CBase1 failed");
+    check(multiple_inheritance_nspace.MakeConstPtrRefDerived2_ABase1().abase1()!=5, "MakeConstPtrRefDerived2_ABase1 failed");
+    check(multiple_inheritance_nspace.MakeConstPtrRefDerived3_ABase1().abase1()!=9, "MakeConstPtrRefDerived3_ABase1 failed");
+    check(multiple_inheritance_nspace.MakeConstPtrRefDerived3_CBase1().cbase1y()!=7, "MakeConstPtrRefDerived3_CBase1 failed");
+    check(multiple_inheritance_nspace.MakeConstPtrRefDerived3_CBase2().cbase2()!=8, "MakeConstPtrRefDerived3_CBase2 failed");
+
     // Return by value (sliced objects)
     check(multiple_inheritance_nspace.MakeValDerived1_CBase1().cbase1y()!=1, "MakeValDerived1_CBase1 failed");
     check(multiple_inheritance_nspace.MakeValDerived1_CBase2().cbase2()!=2, "MakeValDerived1_CBase2 failed");
diff --git a/Examples/test-suite/csharp/multiple_inheritance_overload_runme.cs b/Examples/test-suite/csharp/multiple_inheritance_overload_runme.cs
new file mode 100644
index 0000000..24a2849
--- /dev/null
+++ b/Examples/test-suite/csharp/multiple_inheritance_overload_runme.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using multiple_inheritance_overloadNamespace;
+
+public class multiple_inheritance_overload_runme {
+
+  public static void check(bool fail, String msg) {
+    if (fail)
+      throw new Exception(msg);
+  }
+
+  public static void Main() {
+    int i = 0;
+    Base b1 = new Derived();
+    check(b1.Method(i) != 0, "b1.Method failed");
+    check(b1.MethodForRenaming(i) != 0, "b1.MethodForRenaming failed");
+    check(b1.MethodForRenamingConst(i) != 1, "b1.MethodForRenamingConst failed");
+    check(b1.MethodWarningSuppressed(i) != 0, "b1.MethodWarningSuppressed failed");
+    check(b1.NotVirtualMethod(i) != 0, "b1.NotVirtualMethod failed");
+    check(b1.SimilarOverloadedMethod(i) != 0, "b1.NotVirtualMethod failed");
+
+    Derived d1 = new Derived();
+    check(d1.Method(i) != 0, "d1.Method failed");
+    check(d1.MethodForRenaming(i) != 0, "d1.MethodForRenaming failed");
+    check(d1.MethodForRenamingConst(i) != 1, "d1.MethodForRenamingConst failed");
+    check(d1.MethodWarningSuppressed(i) != 0, "d1.MethodWarningSuppressed failed");
+    check(d1.NotVirtualMethod(i) != 0, "d1.NotVirtualMethod failed");
+    check(d1.SimilarOverloadedMethod(i) != 0, "d1.NotVirtualMethod failed");
+
+    check(d1.AnotherMethod(i) != 0, "d1.AnotherMethod failed");
+
+    Base db1 = BaseSwigImpl.in_out(d1);
+    check(db1.Method(i) != 0, "db1.Method failed");
+    check(db1.MethodForRenaming(i) != 0, "db1.MethodForRenaming failed");
+    check(db1.MethodForRenamingConst(i) != 1, "db1.MethodForRenamingConst failed");
+    check(db1.MethodWarningSuppressed(i) != 0, "db1.MethodWarningSuppressed failed");
+    check(db1.NotVirtualMethod(i) != 0, "db1.NotVirtualMethod failed");
+    check(db1.SimilarOverloadedMethod(i) != 0, "db1.NotVirtualMethod failed");
+
+    MoreDerived m1 = new MoreDerived();
+    check(m1.Method(i) != 0, "m1.Method failed");
+    check(m1.MethodForRenaming(i) != 0, "m1.MethodForRenaming failed");
+    check(m1.MethodForRenamingConst(i) != 1, "m1.MethodForRenamingConst failed");
+    check(m1.MethodWarningSuppressed(i) != 0, "m1.MethodWarningSuppressed failed");
+    check(m1.NotVirtualMethod(i) != 0, "m1.NotVirtualMethod failed");
+    check(m1.SimilarOverloadedMethod(i) != 0, "m1.NotVirtualMethod failed");
+
+    check(m1.AnotherMethod(i) != 0, "m1.AnotherMethod failed");
+
+    Base mb2 = BaseSwigImpl.in_out(m1);
+    check(mb2.Method(i) != 0, "mb2.Method failed");
+    check(mb2.MethodForRenaming(i) != 0, "mb2.MethodForRenaming failed");
+    check(mb2.MethodForRenamingConst(i) != 1, "mb2.MethodForRenamingConst failed");
+    check(mb2.MethodWarningSuppressed(i) != 0, "mb2.MethodWarningSuppressed failed");
+    check(mb2.NotVirtualMethod(i) != 0, "mb2.NotVirtualMethod failed");
+    check(mb2.SimilarOverloadedMethod(i) != 0, "mb2.NotVirtualMethod failed");
+  }
+}
diff --git a/Examples/test-suite/csharp/multiple_inheritance_shared_ptr_runme.cs b/Examples/test-suite/csharp/multiple_inheritance_shared_ptr_runme.cs
index 13ffc62..fc2263e 100644
--- a/Examples/test-suite/csharp/multiple_inheritance_shared_ptr_runme.cs
+++ b/Examples/test-suite/csharp/multiple_inheritance_shared_ptr_runme.cs
@@ -301,6 +301,15 @@
     check(multiple_inheritance_shared_ptr.MakeRefDerived3_CBase1().cbase1y()!=7, "MakeRefDerived3_CBase1 failed");
     check(multiple_inheritance_shared_ptr.MakeRefDerived3_CBase2().cbase2()!=8, "MakeRefDerived3_CBase2 failed");
 
+    // Return const pointer references
+    check(multiple_inheritance_shared_ptr.MakeConstPtrRefDerived1_CBase1().cbase1y()!=3, "MakeConstPtrRefDerived1_CBase1 failed");
+    check(multiple_inheritance_shared_ptr.MakeConstPtrRefDerived1_CBase2().cbase2()!=4, "MakeConstPtrRefDerived1_CBase2 failed");
+    check(multiple_inheritance_shared_ptr.MakeConstPtrRefDerived2_CBase1().cbase1y()!=6, "MakeConstPtrRefDerived2_CBase1 failed");
+    check(multiple_inheritance_shared_ptr.MakeConstPtrRefDerived2_ABase1().abase1()!=5, "MakeConstPtrRefDerived2_ABase1 failed");
+    check(multiple_inheritance_shared_ptr.MakeConstPtrRefDerived3_ABase1().abase1()!=9, "MakeConstPtrRefDerived3_ABase1 failed");
+    check(multiple_inheritance_shared_ptr.MakeConstPtrRefDerived3_CBase1().cbase1y()!=7, "MakeConstPtrRefDerived3_CBase1 failed");
+    check(multiple_inheritance_shared_ptr.MakeConstPtrRefDerived3_CBase2().cbase2()!=8, "MakeConstPtrRefDerived3_CBase2 failed");
+
     // Return by value (sliced objects)
     check(multiple_inheritance_shared_ptr.MakeValDerived1_CBase1().cbase1y()!=1, "MakeValDerived1_CBase1 failed");
     check(multiple_inheritance_shared_ptr.MakeValDerived1_CBase2().cbase2()!=2, "MakeValDerived1_CBase2 failed");
diff --git a/Examples/test-suite/csharp/preproc_constants_c_runme.cs b/Examples/test-suite/csharp/preproc_constants_c_runme.cs
index 5966d52..7125512 100644
--- a/Examples/test-suite/csharp/preproc_constants_c_runme.cs
+++ b/Examples/test-suite/csharp/preproc_constants_c_runme.cs
@@ -5,16 +5,22 @@
 // Same as preproc_constants_c.i testcase, but bool types are int instead
 public class runme {
   static void Main() {
+    System.Type typeof_long = typeof(int);
+    System.Type typeof_ulong = typeof(uint);
+    if (preproc_constants_c.SWIGWORDSIZE64_enabled == 1) {
+      typeof_long = typeof(long);
+      typeof_ulong = typeof(ulong);
+    }
     assert( typeof(int) == preproc_constants_c.CONST_INT1.GetType() );
     assert( typeof(int) == preproc_constants_c.CONST_INT2.GetType() );
     assert( typeof(uint) == preproc_constants_c.CONST_UINT1.GetType() );
     assert( typeof(uint) == preproc_constants_c.CONST_UINT2.GetType() );
     assert( typeof(uint) == preproc_constants_c.CONST_UINT3.GetType() );
     assert( typeof(uint) == preproc_constants_c.CONST_UINT4.GetType() );
-    assert( typeof(int) == preproc_constants_c.CONST_LONG1.GetType() );
-    assert( typeof(int) == preproc_constants_c.CONST_LONG2.GetType() );
-    assert( typeof(int) == preproc_constants_c.CONST_LONG3.GetType() );
-    assert( typeof(int) == preproc_constants_c.CONST_LONG4.GetType() );
+    assert( typeof_long == preproc_constants_c.CONST_LONG1.GetType() );
+    assert( typeof_long == preproc_constants_c.CONST_LONG2.GetType() );
+    assert( typeof_long == preproc_constants_c.CONST_LONG3.GetType() );
+    assert( typeof_long == preproc_constants_c.CONST_LONG4.GetType() );
     assert( typeof(long) == preproc_constants_c.CONST_LLONG1.GetType() );
     assert( typeof(long) == preproc_constants_c.CONST_LLONG2.GetType() );
     assert( typeof(long) == preproc_constants_c.CONST_LLONG3.GetType() );
@@ -27,8 +33,8 @@
     assert( typeof(double) == preproc_constants_c.CONST_DOUBLE2.GetType() );
     assert( typeof(double) == preproc_constants_c.CONST_DOUBLE3.GetType() );
     assert( typeof(double) == preproc_constants_c.CONST_DOUBLE4.GetType() );
-    assert( typeof(double) == preproc_constants_c.CONST_DOUBLE5.GetType() );
-    assert( typeof(double) == preproc_constants_c.CONST_DOUBLE6.GetType() );
+    assert( typeof(float) == preproc_constants_c.CONST_FLOAT1.GetType() );
+    assert( typeof(float) == preproc_constants_c.CONST_FLOAT2.GetType() );
     assert( typeof(int) == preproc_constants_c.CONST_BOOL1.GetType() );
     assert( typeof(int) == preproc_constants_c.CONST_BOOL2.GetType() );
     assert( typeof(char) == preproc_constants_c.CONST_CHAR.GetType() );
@@ -39,8 +45,8 @@
     assert( typeof(int) == preproc_constants_c.INT_AND_CHAR.GetType() );
     assert( typeof(int) == preproc_constants_c.INT_AND_INT.GetType() );
     assert( typeof(uint) == preproc_constants_c.INT_AND_UINT.GetType() );
-    assert( typeof(int) == preproc_constants_c.INT_AND_LONG.GetType() );
-    assert( typeof(uint) == preproc_constants_c.INT_AND_ULONG.GetType() );
+    assert( typeof_long == preproc_constants_c.INT_AND_LONG.GetType() );
+    assert( typeof_ulong == preproc_constants_c.INT_AND_ULONG.GetType() );
     assert( typeof(long) == preproc_constants_c.INT_AND_LLONG.GetType() );
     assert( typeof(ulong) == preproc_constants_c.INT_AND_ULLONG.GetType() );
     assert( typeof(int ) == preproc_constants_c.BOOL_AND_BOOL.GetType() );
@@ -51,6 +57,8 @@
     assert( typeof(int) == preproc_constants_c.EXPR_MINUS.GetType() );
     assert( typeof(int) == preproc_constants_c.EXPR_LSHIFT.GetType() );
     assert( typeof(int) == preproc_constants_c.EXPR_RSHIFT.GetType() );
+    assert( typeof(int) == preproc_constants_c.EXPR_LT.GetType() );
+    assert( typeof(int) == preproc_constants_c.EXPR_GT.GetType() );
     assert( typeof(int) == preproc_constants_c.EXPR_LTE.GetType() );
     assert( typeof(int) == preproc_constants_c.EXPR_GTE.GetType() );
     assert( typeof(int) == preproc_constants_c.EXPR_INEQUALITY.GetType() );
diff --git a/Examples/test-suite/csharp/preproc_constants_runme.cs b/Examples/test-suite/csharp/preproc_constants_runme.cs
index 6af8f20..cfe9fd4 100644
--- a/Examples/test-suite/csharp/preproc_constants_runme.cs
+++ b/Examples/test-suite/csharp/preproc_constants_runme.cs
@@ -4,16 +4,22 @@
 
 public class runme {
   static void Main() {
+    System.Type typeof_long = typeof(int);
+    System.Type typeof_ulong = typeof(uint);
+    if (preproc_constants.SWIGWORDSIZE64_enabled == 1) {
+      typeof_long = typeof(long);
+      typeof_ulong = typeof(ulong);
+    }
     assert( typeof(int) == preproc_constants.CONST_INT1.GetType() );
     assert( typeof(int) == preproc_constants.CONST_INT2.GetType() );
     assert( typeof(uint) == preproc_constants.CONST_UINT1.GetType() );
     assert( typeof(uint) == preproc_constants.CONST_UINT2.GetType() );
     assert( typeof(uint) == preproc_constants.CONST_UINT3.GetType() );
     assert( typeof(uint) == preproc_constants.CONST_UINT4.GetType() );
-    assert( typeof(int) == preproc_constants.CONST_LONG1.GetType() );
-    assert( typeof(int) == preproc_constants.CONST_LONG2.GetType() );
-    assert( typeof(int) == preproc_constants.CONST_LONG3.GetType() );
-    assert( typeof(int) == preproc_constants.CONST_LONG4.GetType() );
+    assert( typeof_long == preproc_constants.CONST_LONG1.GetType() );
+    assert( typeof_long == preproc_constants.CONST_LONG2.GetType() );
+    assert( typeof_long == preproc_constants.CONST_LONG3.GetType() );
+    assert( typeof_long == preproc_constants.CONST_LONG4.GetType() );
     assert( typeof(long) == preproc_constants.CONST_LLONG1.GetType() );
     assert( typeof(long) == preproc_constants.CONST_LLONG2.GetType() );
     assert( typeof(long) == preproc_constants.CONST_LLONG3.GetType() );
@@ -26,8 +32,8 @@
     assert( typeof(double) == preproc_constants.CONST_DOUBLE2.GetType() );
     assert( typeof(double) == preproc_constants.CONST_DOUBLE3.GetType() );
     assert( typeof(double) == preproc_constants.CONST_DOUBLE4.GetType() );
-    assert( typeof(double) == preproc_constants.CONST_DOUBLE5.GetType() );
-    assert( typeof(double) == preproc_constants.CONST_DOUBLE6.GetType() );
+    assert( typeof(float) == preproc_constants.CONST_FLOAT1.GetType() );
+    assert( typeof(float) == preproc_constants.CONST_FLOAT2.GetType() );
     assert( typeof(bool) == preproc_constants.CONST_BOOL1.GetType() );
     assert( typeof(bool) == preproc_constants.CONST_BOOL2.GetType() );
     assert( typeof(char) == preproc_constants.CONST_CHAR.GetType() );
@@ -38,8 +44,8 @@
     assert( typeof(int) == preproc_constants.INT_AND_CHAR.GetType() );
     assert( typeof(int) == preproc_constants.INT_AND_INT.GetType() );
     assert( typeof(uint) == preproc_constants.INT_AND_UINT.GetType() );
-    assert( typeof(int) == preproc_constants.INT_AND_LONG.GetType() );
-    assert( typeof(uint) == preproc_constants.INT_AND_ULONG.GetType() );
+    assert( typeof_long == preproc_constants.INT_AND_LONG.GetType() );
+    assert( typeof_ulong == preproc_constants.INT_AND_ULONG.GetType() );
     assert( typeof(long) == preproc_constants.INT_AND_LLONG.GetType() );
     assert( typeof(ulong) == preproc_constants.INT_AND_ULLONG.GetType() );
     assert( typeof(int ) == preproc_constants.BOOL_AND_BOOL.GetType() );
@@ -50,6 +56,8 @@
     assert( typeof(int) == preproc_constants.EXPR_MINUS.GetType() );
     assert( typeof(int) == preproc_constants.EXPR_LSHIFT.GetType() );
     assert( typeof(int) == preproc_constants.EXPR_RSHIFT.GetType() );
+    assert( typeof(bool) == preproc_constants.EXPR_LT.GetType() );
+    assert( typeof(bool) == preproc_constants.EXPR_GT.GetType() );
     assert( typeof(bool) == preproc_constants.EXPR_LTE.GetType() );
     assert( typeof(bool) == preproc_constants.EXPR_GTE.GetType() );
     assert( typeof(bool) == preproc_constants.EXPR_INEQUALITY.GetType() );
diff --git a/Examples/test-suite/csharp/special_variable_macros_runme.cs b/Examples/test-suite/csharp/special_variable_macros_runme.cs
index 1845cd0..432b90f 100644
--- a/Examples/test-suite/csharp/special_variable_macros_runme.cs
+++ b/Examples/test-suite/csharp/special_variable_macros_runme.cs
@@ -20,5 +20,9 @@
       throw new Exception("test failed");
     NewName newName = NewName.factory("factoryname");
     name = newName.getStoredName();
+    if (special_variable_macros.makeStringInt("stringint", 999) != "stringint")
+      throw new Exception("test failed");
+    if (special_variable_macros.provideStringInt(999) != "1000")
+      throw new Exception("test failed");
   }
 }
diff --git a/Examples/test-suite/csharp/template_nested_flat_runme.cs b/Examples/test-suite/csharp/template_nested_flat_runme.cs
new file mode 100644
index 0000000..afdbe5f
--- /dev/null
+++ b/Examples/test-suite/csharp/template_nested_flat_runme.cs
@@ -0,0 +1,25 @@
+using System;
+using template_nested_flatNamespace;
+#pragma warning disable 219
+
+public class runme {
+  static void Main() {
+    new T_NormalTemplateNormalClass().tmethod(new NormalClass());
+    new OuterClass().T_OuterTMethodNormalClass(new NormalClass());
+
+    TemplateFuncs tf = new TemplateFuncs();
+    if (tf.T_TemplateFuncs1Int(-10) != -10)
+      throw new Exception("it failed");
+    if (tf.T_TemplateFuncs2Double(-12.3) != -12.3)
+      throw new Exception("it failed");
+
+    T_NestedOuterTemplateDouble tn = new T_NestedOuterTemplateDouble();
+    if (tn.hohum(-12.3) != -12.3)
+      throw new Exception("it failed");
+    T_OuterClassInner1Int inner1 = new OuterClass().useInner1(new T_OuterClassInner1Int());
+    T_OuterClassInner2NormalClass inner2 = new T_OuterClassInner2NormalClass();
+    inner2.embeddedVar = 2;
+    T_OuterClassInner2NormalClass inner22 = new OuterClass().useInner2Again(inner2);
+  }
+}
+
diff --git a/Examples/test-suite/csharp/typemap_out_optimal_runme.cs b/Examples/test-suite/csharp/typemap_out_optimal_runme.cs
index 5bc1d14..0d4254e 100644
--- a/Examples/test-suite/csharp/typemap_out_optimal_runme.cs
+++ b/Examples/test-suite/csharp/typemap_out_optimal_runme.cs
@@ -3,10 +3,14 @@
 
 public class typemap_out_optimal_runme {
 
-  public static XX x = null;
   public static void Main() {
-    XX.debug = false;
-    x = XX.create();
+    XX.trace = false;
+    if (XX.trace)
+      Console.WriteLine("calling create()");
+    using (XX x = XX.create()) { }
+    if (XX.trace)
+      Console.WriteLine("calling createConst()");
+    using (XX x = XX.createConst()) { }
   }
 
 }
diff --git a/Examples/test-suite/csharp_argument_defaults_feature.i b/Examples/test-suite/csharp_argument_defaults_feature.i
new file mode 100644
index 0000000..3640296
--- /dev/null
+++ b/Examples/test-suite/csharp_argument_defaults_feature.i
@@ -0,0 +1,99 @@
+%module csharp_argument_defaults_feature
+%include "std_string.i"
+%include <swiginterface.i>
+
+%feature("cs:defaultargs") Foo::Foo;
+%feature("cs:defaultargs", z=4) Foo::bar;
+%feature("cs:defaultargs", x="\"fives\"") Foo::zoo;
+%feature("cs:defaultargs", value="System.Math.PI") Foo::pi;
+%feature("cs:defaultargs", s=R"--("fives")--") Foo::lengthOfString;
+%feature("cs:defaultargs", z=4) ::gbar;
+%feature("cs:defaultargs", z=4) Foo::sbar;
+%feature("cs:defaultargs", z=4) AnInterface::foo;
+%interface(AnInterface)
+
+//intentionally don't touch bat, leave it to normal handling
+
+%inline %{
+#include <string>
+
+enum EnumerationType {
+    one=1,
+    two,
+    three
+};
+
+int gbar(int x, int y=2, int z=3)
+{
+    return x+y+z;
+}
+int gbat(int x=1, int y=2, int z=3)
+{
+    return x+y+z;
+}
+
+class Foo {
+public:
+    virtual ~Foo() {}
+    Foo(int a, int b=1, int c=2)
+    {
+    }
+    int bar(int x, int y=2, int z=3)
+    {
+        return x+y+z;
+    }
+    int bat(int x=1, int y=2, int z=3)
+    {
+        return x+y+z;
+    }
+    int zoo(std::string x="four")
+    {
+        return (int)x.size();
+    }
+    double pi(double value=3.14)
+    {
+        return value;
+    }
+    int lengthOfString(const std::string& s="four")
+    {
+        return (int)s.size();
+    }
+    int valueofenum(EnumerationType t=two)
+    {
+        return (int)t;
+    }
+    int valueofchar(char c='c')
+    {
+        return (int)c;
+    }
+
+    static int sbar(int x, int y=2, int z=3)
+    {
+        return x+y+z;
+    }
+    static int sbat(int x=1, int y=2, int z=3)
+    {
+        return x+y+z;
+    }
+};
+
+class AnInterface
+{
+public:
+    AnInterface() {}
+    virtual int foo(int x=1, int y=2, int z=3) = 0;
+    virtual ~AnInterface() {}
+};
+
+class AnImplementation: public AnInterface
+{
+public:
+    int foo(int x=1, int y=2, int z=3)
+    {
+        return x*y+z;
+    }
+};
+%}
+
+
+
diff --git a/Examples/test-suite/csharp_director_typemaps.i b/Examples/test-suite/csharp_director_typemaps.i
new file mode 100644
index 0000000..614bdbf
--- /dev/null
+++ b/Examples/test-suite/csharp_director_typemaps.i
@@ -0,0 +1,37 @@
+%module (directors="1") csharp_director_typemaps
+
+// This tests that the csout typemap is handled correctly in the director code.
+// The 'out' needs stripping in some parts of the generated director code.
+
+%feature("director") InStream;
+
+%apply void *VOID_INT_PTR { void * }
+
+%typemap(ctype)         int* readLen, int* writeLen "/*ctype*/ int*"
+%typemap(imtype)        int* readLen, int* writeLen "/*imtype*/ out int"
+%typemap(cstype)        int* readLen                "/*cstype*/ out int"
+// Note for below: 'out' used in typemap comment
+%typemap(cstype)                      int* writeLen "/*out cstype out*/ out int"
+%typemap(csin)          int* readLen, int* writeLen "/*csin*/ out $csinput"
+%typemap(in)            int* readLen, int* writeLen %{/*in*/  $1 = ($1_ltype)$input; %}
+%typemap(out)           int* readLen, int* writeLen %{/*out*/ $result = (void *)$1; %}
+%typemap(csdirectorin)  int* readLen, int* writeLen "/*csdirectorin*/ out $iminput"
+%typemap(csdirectorout) int* readLen, int* writeLen "/*csdirectorout*/ $cscall"
+%typemap(directorin)    int* readLen, int* writeLen "/*directorin*/ $input = $1;"
+%typemap(directorout)   int* readLen, int* writeLen %{/*directorout*/  $result = ($1_ltype)$input; %}
+
+%inline %{
+class InStream
+{
+public:
+    virtual int Read(void* buf, int len, int* readLen) = 0;
+    virtual int Write(void* buf, int len, int* writeLen) = 0;
+    virtual ~InStream() {}
+};
+int callRead(InStream* stream, void* buf, int len, int* readLen) {
+  return stream->Read(buf, len, readLen);
+}
+int callWrite(InStream* stream, void* buf, int len, int* writeLen) {
+  return stream->Write(buf, len, writeLen);
+}
+%}
diff --git a/Examples/test-suite/csharp_lib_arrays.i b/Examples/test-suite/csharp_lib_arrays.i
index d07d437..d427dca 100644
--- a/Examples/test-suite/csharp_lib_arrays.i
+++ b/Examples/test-suite/csharp_lib_arrays.i
@@ -1,5 +1,8 @@
 %module csharp_lib_arrays
 
+// TODO: also test long type for INPUT[], OUTPUT[], INOUT[], FIXED[].
+// Will require something clever like detecting sizeof(long) at configure time.
+
 %include "arrays_csharp.i"
 
 %apply int INPUT[]  { int* sourceArray }
@@ -57,5 +60,3 @@
   myArraySwap(array1, array2, nitems);
 }
 %}
-
-  
diff --git a/Examples/test-suite/csharp_typemaps.i b/Examples/test-suite/csharp_typemaps.i
index dc5b40c..a73f01c 100644
--- a/Examples/test-suite/csharp_typemaps.i
+++ b/Examples/test-suite/csharp_typemaps.i
@@ -136,3 +136,42 @@
 bool MVar::svar = false;
 %}
 
+// $imfuncname substitution
+%typemap(csout) int imfuncname_test {
+    return $modulePINVOKE.$imfuncname(swigCPtr) + 123;
+  }
+%typemap(csout) int imfuncname_static_test {
+    return $modulePINVOKE.$imfuncname() + 234;
+  }
+%typemap(csout) int imfuncname_global_test {
+    return $modulePINVOKE.$imfuncname() + 345;
+  }
+
+%typemap(csvarout, excode=SWIGEXCODE2) int variab %{
+    get {
+      int ret = $modulePINVOKE.$imfuncname(swigCPtr) + 222;$excode
+      return ret;
+    } %}
+%typemap(csvarin, excode=SWIGEXCODE2) int variab %{
+    set {
+      $modulePINVOKE.$imfuncname(swigCPtr, value + 111);$excode
+    } %}
+
+%typemap(csvarout, excode=SWIGEXCODE2) int global_variab %{
+    get {
+      int ret = $modulePINVOKE.$imfuncname() + 333;$excode
+      return ret;
+    } %}
+%typemap(csvarin, excode=SWIGEXCODE2) int global_variab %{
+    set {
+      $modulePINVOKE.$imfuncname(value + 444);$excode
+    } %}
+%inline %{
+struct ProxyA {
+  int imfuncname_test() { return 0; }
+  static int imfuncname_static_test() { return 0; }
+  int variab;
+};
+int imfuncname_global_test() { return 0; }
+int global_variab;
+%}
diff --git a/Examples/test-suite/d/Makefile.in b/Examples/test-suite/d/Makefile.in
index a20cfb4..10eddf1 100644
--- a/Examples/test-suite/d/Makefile.in
+++ b/Examples/test-suite/d/Makefile.in
@@ -4,32 +4,51 @@
 
 LANGUAGE     = d
 
+HAVE_CXX11   = @HAVE_CXX11@
+HAVE_CXX14   = @HAVE_CXX14@
+HAVE_CXX17   = @HAVE_CXX17@
+HAVE_CXX20   = @HAVE_CXX20@
 srcdir       = @srcdir@
 top_srcdir   = ../@top_srcdir@
 top_builddir = ../@top_builddir@
 
-ifeq (,$(D_VERSION))
-  D_VERSION = @DDEFAULTVERSION@
-endif
-
-ifeq (2,$(D_VERSION))
-  VERSIONSUFFIX = .2
-else
-  VERSIONSUFFIX = .1
-endif
-
-SCRIPTSUFFIX = _runme$(VERSIONSUFFIX).d
-
 CPP_TEST_CASES = \
 	d_nativepointers \
 	exception_partial_info
 
 CPP11_TEST_CASES = \
 	cpp11_shared_ptr_const \
+	cpp11_shared_ptr_crtp_upcast \
 	cpp11_shared_ptr_nullptr_in_containers \
 	cpp11_shared_ptr_overload \
 	cpp11_shared_ptr_upcast \
 
+# "D classes support the single inheritance paradigm" https://dlang.org/spec/class.html
+FAILING_CPP_TESTS += \
+	using_composition \
+	using_extend \
+
+# Build error due to 2 classes with same name.
+FAILING_CPP_TESTS += \
+	director_nspace_director_name_collision \
+
+# Swig D do not forward 'override' of functions through multiple swig run.
+# You should compile your files at once.
+FAILING_MULTI_CPP_TESTS += \
+	imports \
+	packageoption \
+
+# TODO: probably a bug
+# This test uses a struct extended property for a struct size.
+# Using the same name for the struct and the struct type confuse the Swig D.
+# It create a wrong property function in the C wrap code.
+# Using different name for struct or struct type remove the function completly,
+# which also implies on a bug.
+# We should use proper testing with a run me script.
+# To verify, the extended property actually works in run-time.
+FAILING_C_TESTS += \
+	nested_extend_c \
+
 include $(srcdir)/../common.mk
 
 # Overridden variables here
@@ -40,44 +59,44 @@
 # Rules for the different types of tests
 %.cpptest:
 	$(setup)
-	+(cd $*$(VERSIONSUFFIX) && $(swig_and_compile_cpp))
+	+(cd $*.2 && $(swig_and_compile_cpp))
 	+$(run_testcase)
 
 %.ctest:
 	$(setup)
-	+(cd $*$(VERSIONSUFFIX) && $(swig_and_compile_c))
+	+(cd $*.2 && $(swig_and_compile_c))
 	+$(run_testcase)
 
 %.multicpptest:
 	$(setup)
-	+(cd $*$(VERSIONSUFFIX) && $(swig_and_compile_multi_cpp))
+	+(cd $*.2 && $(swig_and_compile_multi_cpp))
 	+$(run_testcase)
 
 # Makes a directory for the testcase if it does not exist
 setup = \
-	if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then			\
+	if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*_runme.2.d ]; then			\
 	  echo "$(ACTION)ing $(LANGUAGE) testcase $* (with run test)" ;	\
 	else									\
 	  echo "$(ACTION)ing $(LANGUAGE) testcase $*" ;			\
 	fi;									\
-	if [ ! -d $*$(VERSIONSUFFIX) ]; then					\
-	  mkdir $*$(VERSIONSUFFIX);						\
+	if [ ! -d $*.2 ]; then					\
+	  mkdir $*.2;						\
 	fi;									\
-	if [ ! -d $*$(VERSIONSUFFIX)/$* ]; then					\
-	  mkdir $*$(VERSIONSUFFIX)/$*;						\
+	if [ ! -d $*.2/$* ]; then					\
+	  mkdir $*.2/$*;						\
 	fi
 
 # Compiles D files then runs the testcase. A testcase is only run if
 # a file is found which has _runme.d appended after the testcase name.
 run_testcase = \
-	if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
-	  cd $*$(VERSIONSUFFIX) && \
+	if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*_runme.2.d ]; then \
+	  cd $*.2 && \
 	  $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile \
 	  DFLAGS='-of$*_runme' \
-	  DSRCS='../$(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) `find $* -name *.d`' d_compile && \
+	  DSRCS='../$(SCRIPTDIR)/$(SCRIPTPREFIX)$*_runme.2.d `find $* -name *.d`' d_compile && \
 	  env LD_LIBRARY_PATH=".:$$LD_LIBRARY_PATH" $(RUNTOOL) ./$*_runme; \
 	else \
-	  cd $*$(VERSIONSUFFIX) && \
+	  cd $*.2 && \
 	  $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile \
 	  DFLAGS='-c' \
 	  DSRCS='`find $* -name *.d`' d_compile && cd .. ; \
@@ -85,6 +104,6 @@
 
 # Clean: remove testcase directories
 %.clean:
-	@if [ -d $*$(VERSIONSUFFIX) ]; then \
-	  rm -rf $*$(VERSIONSUFFIX); \
+	@if [ -d $*.2 ]; then \
+	  rm -rf $*.2; \
 	fi
diff --git a/Examples/test-suite/d/README b/Examples/test-suite/d/README
index bb53728..2e7aa6e 100644
--- a/Examples/test-suite/d/README
+++ b/Examples/test-suite/d/README
@@ -2,6 +2,3 @@
 ---------------------------
 
 Please see ../README for the common readme file.
-
-By default the D1 version is built, set D_VERSION=2 (in the environment or at
-the make command line) to run it for D2 instead.
diff --git a/Examples/test-suite/d/aggregate_runme.1.d b/Examples/test-suite/d/aggregate_runme.1.d
deleted file mode 100644
index a00d34c..0000000
--- a/Examples/test-suite/d/aggregate_runme.1.d
+++ /dev/null
@@ -1,25 +0,0 @@
-module aggregate_runme;
-
-import aggregate.aggregate;
-
-void main() {
-  // Confirm that move() returns correct results under normal use.
-  int result = move(UP);
-  if (result != UP) throw new Exception("UP failed");
-
-  result = move(DOWN);
-  if (result != DOWN) throw new Exception("DOWN failed");
-
-  result = move(LEFT);
-  if (result != LEFT) throw new Exception("LEFT failed");
-
-  result = move(RIGHT);
-  if (result != RIGHT) throw new Exception("RIGHT failed");
-
-  // Confirm that move() raises an exception when the contract is violated.
-  try {
-    move(0);
-    throw new Exception("0 test failed");
-  }
-  catch (Exception e) {}
-}
diff --git a/Examples/test-suite/d/allprotected_runme.1.d b/Examples/test-suite/d/allprotected_runme.1.d
deleted file mode 100644
index 82a180e..0000000
--- a/Examples/test-suite/d/allprotected_runme.1.d
+++ /dev/null
@@ -1,65 +0,0 @@
-module allprotected_runme;
-
-import allprotected.Klass;
-import allprotected.ProtectedBase;
-
-void main() {
-  auto mpb = new MyProtectedBase("MyProtectedBase");
-  mpb.accessProtected();
-}
-
-class MyProtectedBase : ProtectedBase {
-public:
-  this(char[] name) {
-    super(name);
-  }
-
-  void accessProtected() {
-    char[] s = virtualMethod();
-    if (s != "ProtectedBase")
-      throw new Exception("Failed");
-
-    Klass k = instanceMethod(new Klass("xyz"));
-    if (k.getName() != "xyz") 
-      throw new Exception("Failed");
-
-    k = instanceOverloaded(new Klass("xyz"));
-    if (k.getName() != "xyz") 
-      throw new Exception("Failed");
-
-    k = instanceOverloaded(new Klass("xyz"), "abc");
-    if (k.getName() != "abc") 
-      throw new Exception("Failed");
-
-    k = staticMethod(new Klass("abc"));
-    if (k.getName() != "abc") 
-      throw new Exception("Failed");
-
-    k = staticOverloaded(new Klass("xyz"));
-    if (k.getName() != "xyz") 
-      throw new Exception("Failed");
-
-    k = staticOverloaded(new Klass("xyz"), "abc");
-    if (k.getName() != "abc") 
-      throw new Exception("Failed");
-
-    instanceMemberVariable = 30;
-    int i = instanceMemberVariable;
-    if (i != 30)
-      throw new Exception("Failed");
-
-    staticMemberVariable = 40;
-    i = staticMemberVariable;
-    if (i != 40)
-      throw new Exception("Failed");
-
-    i = staticConstMemberVariable;
-    if (i != 20)
-      throw new Exception("Failed");
-
-    anEnum = ProtectedBase.AnEnum.EnumVal1;
-    ProtectedBase.AnEnum ae = anEnum;
-    if (ae != ProtectedBase.AnEnum.EnumVal1)
-      throw new Exception("Failed");
-  }
-}
diff --git a/Examples/test-suite/d/allprotected_runme.2.d b/Examples/test-suite/d/allprotected_runme.2.d
index f7c396d..9f762c5 100644
--- a/Examples/test-suite/d/allprotected_runme.2.d
+++ b/Examples/test-suite/d/allprotected_runme.2.d
@@ -2,12 +2,16 @@
 
 import allprotected.Klass;
 import allprotected.ProtectedBase;
+import allprotected.AllProtectedBottom;
 import std.conv : text;
 import std.exception : enforce;
 
 void main() {
   auto mpb = new MyProtectedBase("MyProtectedBase");
   mpb.accessProtected();
+
+  MyAllProtectedBottom mapb = new MyAllProtectedBottom();
+  mapb.callProtectedMethods();
 }
 
 class MyProtectedBase : ProtectedBase {
@@ -61,3 +65,15 @@
     enforce(ae == ProtectedBase.AnEnum.EnumVal1);
   }
 }
+
+class MyAllProtectedBottom : AllProtectedBottom
+{
+public:
+  void callProtectedMethods() {
+    usingOverloaded();
+    usingOverloaded(99);
+    usingSingle();
+    doSomething();
+    doSomething(99);
+  }
+}
diff --git a/Examples/test-suite/d/apply_strings_runme.1.d b/Examples/test-suite/d/apply_strings_runme.1.d
deleted file mode 100644
index 960caa4..0000000
--- a/Examples/test-suite/d/apply_strings_runme.1.d
+++ /dev/null
@@ -1,12 +0,0 @@
-module apply_strings_runme;
-
-import apply_strings.apply_strings;
-
-const char[] TEST_MESSAGE = "A message from target language to the C++ world and back again.";
-
-void main() {
-  if (UCharFunction(TEST_MESSAGE) != TEST_MESSAGE) throw new Exception("UCharFunction failed");
-  if (SCharFunction(TEST_MESSAGE) != TEST_MESSAGE) throw new Exception("SCharFunction failed");
-  auto pChar = CharFunction(null);
-  if (pChar !is null) throw new Exception("CharFunction failed");
-}
diff --git a/Examples/test-suite/d/argcargvtest_runme.2.d b/Examples/test-suite/d/argcargvtest_runme.2.d
new file mode 100644
index 0000000..466f19e
--- /dev/null
+++ b/Examples/test-suite/d/argcargvtest_runme.2.d
@@ -0,0 +1,44 @@
+module argcargvtest_runme;
+
+import std.exception;
+import argcargvtest.argcargvtest;
+
+void main() {
+  auto largs = ["hi", "hola", "hello"];
+  enforce(mainc(largs) == 3, "calling mainc failed");
+
+  auto targs = ["hi", "hola"];
+  enforce(mainv(targs, 0) == "hi", "calling mainv failed");
+  enforce(mainv(targs, 1) == "hola", "calling mainv failed");
+  enforce(mainv(targs, 2) == "<<NULL>>", "calling mainv failed");
+
+// For dynamically typed languages we test this throws an exception or similar
+// at runtime, but for D language this doesn't even compile (but we can't easily
+// test for that here).
+// mainv("hello", 1);
+
+  initializeApp(largs);
+
+  // Check that an empty array works.
+  string[] empty_args;
+  enforce(mainc(empty_args) == 0, "calling mainc failed");
+  enforce(mainv(empty_args, 0) == "<<NULL>>", "calling mainv failed");
+  // In D, an empty array created like empty_args is identical to null.
+  enforce(mainc(null) == 0, "calling mainc failed");
+  // However an empty array created like this has a non-null .array so test
+  // this case is handled too.
+  string[] empty_args_array_set = targs;
+  empty_args_array_set.length = 0;
+  enforce(mainc(empty_args_array_set) == 0, "calling mainc failed");
+  // Check creating via slicing too.
+  string[] empty_args_array_set2 = targs[0..0];
+  enforce(mainc(empty_args_array_set2) == 0, "calling mainc failed");
+
+  // Check that empty strings are handled.
+  auto empty_string = ["hello", "", "world"];
+  enforce(mainc(empty_string) == 3, "calling mainc failed");
+  enforce(mainv(empty_string, 0) == "hello", "calling mainv failed");
+  enforce(mainv(empty_string, 1) == "", "calling mainv failed");
+  enforce(mainv(empty_string, 2) == "world", "calling mainv failed");
+  enforce(mainv(empty_string, 3) == "<<NULL>>", "calling mainv failed");
+}
diff --git a/Examples/test-suite/d/bools_runme.1.d b/Examples/test-suite/d/bools_runme.1.d
deleted file mode 100644
index f501b07..0000000
--- a/Examples/test-suite/d/bools_runme.1.d
+++ /dev/null
@@ -1,20 +0,0 @@
-/// This is the bool runtime testcase. It checks that the C++ bool type works.
-module bools_runme;
-
-import bools.bools;
-
-void main() {
-  bool t = true;
-  bool f = false;
-
-  check_bo(f);
-  check_bo(t);
-}
-
-void check_bo(bool input) {
-  for (int i = 0; i < 1000; ++i) {
-    if (bo(input) != input) {
-      throw new Exception("Runtime test check_bo failed.");
-    }
-  }
-}
diff --git a/Examples/test-suite/d/catches_runme.1.d b/Examples/test-suite/d/catches_runme.1.d
deleted file mode 100644
index 55b1813..0000000
--- a/Examples/test-suite/d/catches_runme.1.d
+++ /dev/null
@@ -1,33 +0,0 @@
-module catches_runme;
-
-import catches.catches;
-
-void main() {
-  test({ test_catches(1); }, "C++ int exception thrown, value: 1");
-  test({ test_catches(2); }, "two");
-  test({ test_catches(3); }, "C++ ThreeException const & exception thrown");
-
-  test({ test_exception_specification(1); }, "C++ int exception thrown, value: 1");
-  test({ test_exception_specification(2); }, "unknown exception");
-  test({ test_exception_specification(3); }, "unknown exception");
-
-  test({ test_catches_all(1); }, "unknown exception");
-}
-
-void test(void delegate() command, char[] expectedMessage) {
-  bool didntThrow;
-  try {
-    command();
-    didntThrow = true;
-  } catch (Exception e) {
-    if (e.msg != expectedMessage) {
-      throw new Exception("Failed to propagate C++ exception. Expected '" ~
-	expectedMessage ~ "', but received '" ~ e.msg ~ "'.");
-    }
-  }
-
-  if (didntThrow) {
-    throw new Exception("Failed to propagate C++ exception. Expected '" ~
-      expectedMessage ~ "', but no exception was thrown.");
-  }
-}
diff --git a/Examples/test-suite/d/catches_strings_runme.2.d b/Examples/test-suite/d/catches_strings_runme.2.d
new file mode 100644
index 0000000..8910835
--- /dev/null
+++ b/Examples/test-suite/d/catches_strings_runme.2.d
@@ -0,0 +1,32 @@
+module catches_strings_runme;
+
+import catches_strings.catches_strings;
+import catches_strings.StringsThrower;
+import std.algorithm;
+
+void main() {
+  {
+    bool exception_thrown = false;
+    try {
+      StringsThrower.charstring();
+    } catch (Exception e) {
+      if (!canFind(e.msg, "charstring message"))
+        throw new Exception("incorrect exception message:" ~ e.msg);
+      exception_thrown = true;
+    }
+    if (!exception_thrown)
+      throw new Exception("Should have thrown an exception");
+  }
+  {
+    bool exception_thrown = false;
+    try {
+      StringsThrower.stdstring();
+    } catch (Exception e) {
+      if (!canFind(e.msg, "stdstring message"))
+        throw new Exception("incorrect exception message:" ~ e.msg);
+      exception_thrown = true;
+    }
+    if (!exception_thrown)
+      throw new Exception("Should have thrown an exception");
+  }
+}
diff --git a/Examples/test-suite/d/char_binary_runme.2.d b/Examples/test-suite/d/char_binary_runme.2.d
new file mode 100644
index 0000000..1cf6c2e
--- /dev/null
+++ b/Examples/test-suite/d/char_binary_runme.2.d
@@ -0,0 +1,27 @@
+module char_binary_runme;
+
+import char_binary.char_binary;
+import char_binary.Test;
+import std.stdio;
+
+void main() {
+   Test t = new Test();
+   string str = "hile";
+   if (t.strlen(str) != 4) {
+      writeln(t.strlen(str));
+      throw new Exception("bad multi-arg typemap");
+   }
+
+   if (t.strlen("hil\000") != 4) {
+      throw new Exception("bad multi-arg typemap");
+   }
+
+   // creating a raw char*
+   auto pc = new_pchar(5);
+   pchar_setitem(pc, 0, 'h');
+   pchar_setitem(pc, 1, 'o');
+   pchar_setitem(pc, 2, 'l');
+   pchar_setitem(pc, 3, 'a');
+   pchar_setitem(pc, 4, 0);
+   delete_pchar(pc);
+}
diff --git a/Examples/test-suite/d/char_strings_runme.1.d b/Examples/test-suite/d/char_strings_runme.1.d
deleted file mode 100644
index cde6fe0..0000000
--- a/Examples/test-suite/d/char_strings_runme.1.d
+++ /dev/null
@@ -1,151 +0,0 @@
-module char_strings_runme;
-
-import tango.text.convert.Integer;
-import char_strings.char_strings;
-
-const char[] CPLUSPLUS_MSG = "A message from the deep dark world of C++, where anything is possible.";
-const char[] OTHERLAND_MSG = "Little message from the safe world.";
-
-void main() {
-  const uint count = 10000;
-  uint i = 0;
-
-  // get functions
-  for (i=0; i<count; i++) {
-    char[] str = GetCharHeapString();
-    if (str != CPLUSPLUS_MSG)
-      throw new Exception("Test char get 1 failed, iteration " ~ toString(i));
-    DeleteCharHeapString();
-  }
-
-  for (i=0; i<count; i++) {
-    char[] str = GetConstCharProgramCodeString();
-    if (str != CPLUSPLUS_MSG)
-      throw new Exception("Test char get 2 failed, iteration " ~ toString(i));
-    DeleteCharHeapString();
-  }
-
-  for (i=0; i<count; i++) {
-    char[] str = GetCharStaticString();
-    if (str != CPLUSPLUS_MSG)
-      throw new Exception("Test char get 3 failed, iteration " ~ toString(i));
-  }
-
-  for (i=0; i<count; i++) {
-    char[] str = GetCharStaticStringFixed();
-    if (str != CPLUSPLUS_MSG)
-      throw new Exception("Test char get 4 failed, iteration " ~ toString(i));
-  }
-
-  for (i=0; i<count; i++) {
-    char[] str = GetConstCharStaticStringFixed();
-    if (str != CPLUSPLUS_MSG)
-      throw new Exception("Test char get 5 failed, iteration " ~ toString(i));
-  }
-
-  // set functions
-  for (i=0; i<count; i++) {
-    if (!SetCharHeapString(OTHERLAND_MSG ~ toString(i), i))
-      throw new Exception("Test char set 1 failed, iteration " ~ toString(i));
-  }
-
-  for (i=0; i<count; i++) {
-    if (!SetCharStaticString(OTHERLAND_MSG ~ toString(i), i))
-      throw new Exception("Test char set 2 failed, iteration " ~ toString(i));
-  }
-
-  for (i=0; i<count; i++) {
-    if (!SetCharArrayStaticString(OTHERLAND_MSG ~ toString(i), i))
-      throw new Exception("Test char set 3 failed, iteration " ~ toString(i));
-  }
-
-  for (i=0; i<count; i++) {
-    if (!SetConstCharHeapString(OTHERLAND_MSG ~ toString(i), i))
-      throw new Exception("Test char set 4 failed, iteration " ~ toString(i));
-  }
-
-  for (i=0; i<count; i++) {
-    if (!SetConstCharStaticString(OTHERLAND_MSG ~ toString(i), i))
-      throw new Exception("Test char set 5 failed, iteration " ~ toString(i));
-  }
-
-  for (i=0; i<count; i++) {
-    if (!SetConstCharArrayStaticString(OTHERLAND_MSG ~ toString(i), i))
-      throw new Exception("Test char set 6 failed, iteration " ~ toString(i));
-  }
-
-  for (i=0; i<count; i++) {
-    if (!SetCharConstStaticString(OTHERLAND_MSG ~ toString(i), i))
-      throw new Exception("Test char set 7 failed, iteration " ~ toString(i));
-  }
-
-  for (i=0; i<count; i++) {
-    if (!SetConstCharConstStaticString(OTHERLAND_MSG ~ toString(i), i))
-      throw new Exception("Test char set 8 failed, iteration " ~ toString(i));
-  }
-
-  // get set function
-  for (i=0; i<count*10; i++) {
-    char[] ping = OTHERLAND_MSG ~ toString(i);
-    char[] pong = CharPingPong(ping);
-    if (ping != pong)
-      throw new Exception("Test PingPong 1 failed.\nExpected:" ~ ping ~ "\nReceived:" ~ pong);
-  }
-
-  // variables
-  for (i=0; i<count; i++) {
-    global_char = OTHERLAND_MSG ~ toString(i);
-    if (global_char != OTHERLAND_MSG ~ toString(i))
-      throw new Exception("Test variables 1 failed, iteration " ~ toString(i));
-  }
-
-  for (i=0; i<count; i++) {
-    global_char_array1 = OTHERLAND_MSG ~ toString(i);
-    if (global_char_array1 != OTHERLAND_MSG ~ toString(i))
-      throw new Exception("Test variables 2 failed, iteration " ~ toString(i));
-  }
-
-  for (i=0; i<count; i++) {
-    global_char_array2 = OTHERLAND_MSG ~ toString(i);
-    if (global_char_array2 != OTHERLAND_MSG ~ toString(i))
-      throw new Exception("Test variables 3 failed, iteration " ~ toString(i));
-  }
-
-  for (i=0; i<count; i++) {
-    if (global_const_char != CPLUSPLUS_MSG)
-      throw new Exception("Test variables 4 failed, iteration " ~ toString(i));
-  }
-
-  for (i=0; i<count; i++) {
-    if (global_const_char_array1 != CPLUSPLUS_MSG)
-      throw new Exception("Test variables 5 failed, iteration " ~ toString(i));
-  }
-
-  for (i=0; i<count; i++) {
-    if (global_const_char_array2 != CPLUSPLUS_MSG)
-      throw new Exception("Test variables 6 failed, iteration " ~ toString(i));
-  }
-
-  // char *& tests
-  for (i=0; i<count; i++) {
-    char[] str = GetCharPointerRef();
-    if (str != CPLUSPLUS_MSG)
-      throw new Exception("Test char pointer ref get failed, iteration " ~ toString(i));
-  }
-
-  for (i=0; i<count; i++) {
-    if (!SetCharPointerRef(OTHERLAND_MSG ~ toString(i), i))
-      throw new Exception("Test char pointer ref set failed, iteration " ~ toString(i));
-  }
-
-  for (i=0; i<count; i++) {
-    char[] str = GetConstCharPointerRef();
-    if (str != CPLUSPLUS_MSG)
-      throw new Exception("Test const char pointer ref get failed, iteration " ~ toString(i));
-  }
-
-  for (i=0; i<count; i++) {
-    if (!SetConstCharPointerRef(OTHERLAND_MSG ~ toString(i), i))
-      throw new Exception("Test const char pointer ref set failed, iteration " ~ toString(i));
-  }
-}
diff --git a/Examples/test-suite/d/constover_runme.1.d b/Examples/test-suite/d/constover_runme.1.d
deleted file mode 100644
index ead6731..0000000
--- a/Examples/test-suite/d/constover_runme.1.d
+++ /dev/null
@@ -1,31 +0,0 @@
-module constover_runme;
-
-import constover.constover;
-import constover.Foo;
-
-void main() {
-  char[] p = test("test");
-  if (p != "test")
-    throw new Exception("test failed!");
-
-  p = test_pconst("test");
-  if (p != "test_pconst")
-    throw new Exception("test_pconst failed!");
-
-  auto f = new Foo();
-  p = f.test("test");
-  if (p != "test")
-    throw new Exception("member-test failed!");
-
-  p = f.test_pconst("test");
-  if (p != "test_pconst")
-    throw new Exception("member-test_pconst failed!");
-
-  p = f.test_constm("test");
-  if (p != "test_constmethod")
-    throw new Exception("member-test_constm failed!");
-
-  p = f.test_pconstm("test");
-  if (p != "test_pconstmethod")
-    throw new Exception("member-test_pconstm failed!");
-}
diff --git a/Examples/test-suite/d/cpp11_move_typemaps_runme.2.d b/Examples/test-suite/d/cpp11_move_typemaps_runme.2.d
new file mode 100644
index 0000000..29561cd
--- /dev/null
+++ b/Examples/test-suite/d/cpp11_move_typemaps_runme.2.d
@@ -0,0 +1,42 @@
+module cpp11_move_typemaps_runme;
+
+import cpp11_move_typemaps.Counter;
+import cpp11_move_typemaps.MoveOnly;
+import cpp11_move_typemaps.MovableCopyable;
+import std.conv;
+import std.algorithm;
+
+void main() {
+  {
+    Counter.reset_counts();
+    scope MoveOnly mo = new MoveOnly(111);
+    Counter.check_counts(1, 0, 0, 0, 0, 0);
+    MoveOnly.take(mo);
+    Counter.check_counts(1, 0, 0, 1, 0, 2);
+  }
+  Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+  {
+    Counter.reset_counts();
+    scope MovableCopyable mo = new MovableCopyable(111);
+    Counter.check_counts(1, 0, 0, 0, 0, 0);
+    MovableCopyable.take(mo);
+    Counter.check_counts(1, 0, 0, 1, 0, 2);
+  }
+  Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+  {
+    scope MoveOnly mo = new MoveOnly(222);
+    MoveOnly.take(mo);
+    bool exception_thrown = false;
+    try {
+      MoveOnly.take(mo);
+    } catch (Exception e) {
+      if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
+        throw new Exception("incorrect exception message: " ~ e.msg);
+      exception_thrown = true;
+    }
+    if (!exception_thrown)
+      throw new Exception("double usage of take should have been an error");
+  }
+}
diff --git a/Examples/test-suite/d/cpp11_rvalue_reference_move_runme.2.d b/Examples/test-suite/d/cpp11_rvalue_reference_move_runme.2.d
new file mode 100644
index 0000000..342f34f
--- /dev/null
+++ b/Examples/test-suite/d/cpp11_rvalue_reference_move_runme.2.d
@@ -0,0 +1,87 @@
+module cpp11_rvalue_reference_move_runme;
+
+import cpp11_rvalue_reference_move.Counter;
+import cpp11_rvalue_reference_move.MovableCopyable;
+import std.algorithm;
+
+void main() {
+  {
+    // Function containing rvalue reference parameter
+    Counter.reset_counts();
+    scope MovableCopyable mo = new MovableCopyable(222);
+    Counter.check_counts(1, 0, 0, 0, 0, 0);
+    MovableCopyable.movein(mo);
+    Counter.check_counts(1, 0, 0, 1, 0, 2);
+    if (!MovableCopyable.is_nullptr(mo))
+      throw new Exception("is_nullptr failed");
+    mo.dispose();
+    Counter.check_counts(1, 0, 0, 1, 0, 2);
+  }
+
+  {
+    // Move constructor test
+    Counter.reset_counts();
+    scope MovableCopyable mo = new MovableCopyable(222);
+    Counter.check_counts(1, 0, 0, 0, 0, 0);
+    MovableCopyable mo_moved = new MovableCopyable(mo);
+    Counter.check_counts(1, 0, 0, 1, 0, 1);
+    if (!MovableCopyable.is_nullptr(mo))
+      throw new Exception("is_nullptr failed");
+    mo.dispose();
+    Counter.check_counts(1, 0, 0, 1, 0, 1);
+    mo_moved.dispose();
+    Counter.check_counts(1, 0, 0, 1, 0, 2);
+  }
+
+  {
+    // Move assignment operator test
+    Counter.reset_counts();
+    scope MovableCopyable mo111 = new MovableCopyable(111);
+    scope MovableCopyable mo222 = new MovableCopyable(222);
+    Counter.check_counts(2, 0, 0, 0, 0, 0);
+    mo111.MoveAssign(mo222);
+    Counter.check_counts(2, 0, 0, 0, 1, 1);
+    if (!MovableCopyable.is_nullptr(mo222))
+      throw new Exception("is_nullptr failed");
+    mo222.dispose();
+    Counter.check_counts(2, 0, 0, 0, 1, 1);
+    mo111.dispose();
+    Counter.check_counts(2, 0, 0, 0, 1, 2);
+  }
+
+  {
+    // null check
+    Counter.reset_counts();
+    bool exception_thrown = false;
+    try {
+      MovableCopyable.movein(null);
+    } catch (Exception e) {
+      if (!canFind(e.msg, "MovableCopyable && is null"))
+        throw new Exception("incorrect exception message:" ~ e.msg);
+      exception_thrown = true;
+    }
+    if (!exception_thrown)
+      throw new Exception("Should have thrown null error");
+    Counter.check_counts(0, 0, 0, 0, 0, 0);
+  }
+
+  {
+    // output
+    Counter.reset_counts();
+    MovableCopyable mc = MovableCopyable.moveout(1234);
+    Counter.check_counts(2, 0, 0, 0, 1, 1);
+    MovableCopyable.check_numbers_match(mc, 1234);
+
+    bool exception_thrown = false;
+    try {
+      MovableCopyable.movein(mc);
+    } catch (Exception e) {
+      if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
+        throw new Exception("incorrect exception message: " ~ e.msg);
+      exception_thrown = true;
+    }
+    if (!exception_thrown)
+      throw new Exception("Should have thrown 'Cannot release ownership as memory is not owned' error");
+    Counter.check_counts(2, 0, 0, 0, 1, 1);
+  }
+}
diff --git a/Examples/test-suite/d/cpp11_std_unique_ptr_runme.2.d b/Examples/test-suite/d/cpp11_std_unique_ptr_runme.2.d
new file mode 100644
index 0000000..b8e4664
--- /dev/null
+++ b/Examples/test-suite/d/cpp11_std_unique_ptr_runme.2.d
@@ -0,0 +1,123 @@
+module cpp11_std_unique_ptr_runme;
+
+import cpp11_std_unique_ptr.cpp11_std_unique_ptr;
+import cpp11_std_unique_ptr.Klass;
+import cpp11_std_unique_ptr.KlassInheritance;
+import std.conv;
+import std.algorithm;
+
+void checkCount(int expected_count) {
+  int actual_count = Klass.getTotal_count();
+  if (actual_count != expected_count)
+    throw new Exception("Counts incorrect, expected:" ~ to!string(expected_count) ~ " actual:" ~ to!string(actual_count));
+}
+
+void main() {
+  // Test raw pointer handling involving virtual inheritance
+  {
+    scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+    checkCount(1);
+    string s = useKlassRawPtr(kini);
+    if (s != "KlassInheritanceInput")
+      throw new Exception("Incorrect string: " ~ s);
+  }
+  checkCount(0);
+
+  // unique_ptr as input
+  {
+    scope Klass kin = new Klass("KlassInput");
+    checkCount(1);
+    string s = takeKlassUniquePtr(kin);
+    checkCount(0);
+    if (s != "KlassInput")
+      throw new Exception("Incorrect string: " ~ s);
+    if (!is_nullptr(kin))
+      throw new Exception("is_nullptr failed");
+  } // dispose should not fail, even though already deleted
+  checkCount(0);
+
+  {
+    scope Klass kin = new Klass("KlassInput");
+    checkCount(1);
+    string s = takeKlassUniquePtr(kin);
+    checkCount(0);
+    if (s != "KlassInput")
+      throw new Exception("Incorrect string: " ~ s);
+    if (!is_nullptr(kin))
+      throw new Exception("is_nullptr failed");
+    bool exception_thrown = false;
+    try {
+      takeKlassUniquePtr(kin);
+    } catch (Exception e) {
+      if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
+        throw new Exception("incorrect exception message: " ~ e.msg);
+      exception_thrown = true;
+    }
+    if (!exception_thrown)
+      throw new Exception("double usage of takeKlassUniquePtr should have been an error");
+  } // dispose should not fail, even though already deleted
+  checkCount(0);
+
+  {
+    scope Klass kin = new Klass("KlassInput");
+    bool exception_thrown = false;
+    Klass notowned = get_not_owned_ptr(kin);
+    try {
+      takeKlassUniquePtr(notowned);
+    } catch (Exception e) {
+      if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
+        throw new Exception("incorrect exception message: " ~ e.msg);
+      exception_thrown = true;
+    }
+    if (!exception_thrown)
+      throw new Exception("Should have thrown 'Cannot release ownership as memory is not owned' error");
+    checkCount(1);
+  }
+  checkCount(0);
+
+  {
+    scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+    checkCount(1);
+    string s = takeKlassUniquePtr(kini);
+    checkCount(0);
+    if (s != "KlassInheritanceInput")
+      throw new Exception("Incorrect string: " ~ s);
+    if (!is_nullptr(kini))
+      throw new Exception("is_nullptr failed");
+  } // dispose should not fail, even though already deleted
+  checkCount(0);
+
+  takeKlassUniquePtr(null);
+  takeKlassUniquePtr(make_null());
+  checkCount(0);
+
+  // overloaded parameters
+  if (overloadTest() != 0)
+    throw new Exception("overloadTest failed");
+  if (overloadTest(null) != 1)
+    throw new Exception("overloadTest failed");
+  if (overloadTest(new Klass("over")) != 1)
+    throw new Exception("overloadTest failed");
+  checkCount(0);
+
+
+  // unique_ptr as output
+  Klass k1 = makeKlassUniquePtr("first");
+  if (k1.getLabel() != "first")
+    throw new Exception("wrong object label");
+
+  Klass k2 = makeKlassUniquePtr("second");
+  checkCount(2);
+
+  k1.dispose();
+  checkCount(1);
+
+  if (k2.getLabel() != "second")
+      throw new Exception("wrong object label");
+
+  k2.dispose();
+  checkCount(0);
+
+  if (makeNullUniquePtr() !is null)
+    throw new Exception("null failure");
+}
diff --git a/Examples/test-suite/d/cpp11_strongly_typed_enumerations_runme.2.d b/Examples/test-suite/d/cpp11_strongly_typed_enumerations_runme.2.d
new file mode 100644
index 0000000..658c45c
--- /dev/null
+++ b/Examples/test-suite/d/cpp11_strongly_typed_enumerations_runme.2.d
@@ -0,0 +1,203 @@
+module cpp11_strongly_typed_enumerations_runme;
+
+import cpp11_strongly_typed_enumerations.cpp11_strongly_typed_enumerations;
+import cpp11_strongly_typed_enumerations.Enum1;
+import cpp11_strongly_typed_enumerations.Enum2;
+import cpp11_strongly_typed_enumerations.Enum3;
+import cpp11_strongly_typed_enumerations.Enum4;
+import cpp11_strongly_typed_enumerations.Enum5;
+import cpp11_strongly_typed_enumerations.Enum6;
+import cpp11_strongly_typed_enumerations.Enum7td;
+import cpp11_strongly_typed_enumerations.Enum8;
+import cpp11_strongly_typed_enumerations.Enum9;
+import cpp11_strongly_typed_enumerations.Enum10;
+import cpp11_strongly_typed_enumerations.Enum11;
+import cpp11_strongly_typed_enumerations.Enum15;
+import cpp11_strongly_typed_enumerations.Enum16;
+import cpp11_strongly_typed_enumerations.Enum17;
+import cpp11_strongly_typed_enumerations.Class1;
+import cpp11_strongly_typed_enumerations.Class2;
+import std.conv;
+
+int enumCheck(int actual, int expected) {
+  if (actual != expected)
+    throw new Exception("Enum value mismatch. Expected " ~ to!string(expected) ~ " Actual: " ~ to!string(actual));
+  return expected + 1;
+}
+
+void main() {
+  int val = 0;
+  val = enumCheck(cast(int)Enum1.Val1, val);
+  val = enumCheck(cast(int)Enum1.Val2, val);
+  val = enumCheck(cast(int)Enum1.Val3, 13);
+  val = enumCheck(cast(int)Enum1.Val4, val);
+  val = enumCheck(cast(int)Enum1.Val5a, 13);
+  val = enumCheck(cast(int)Enum1.Val6a, val);
+
+  val = 0;
+  val = enumCheck(cast(int)Enum2.Val1, val);
+  val = enumCheck(cast(int)Enum2.Val2, val);
+  val = enumCheck(cast(int)Enum2.Val3, 23);
+  val = enumCheck(cast(int)Enum2.Val4, val);
+  val = enumCheck(cast(int)Enum2.Val5b, 23);
+  val = enumCheck(cast(int)Enum2.Val6b, val);
+
+  val = 0;
+  val = enumCheck(cast(int)Enum4.Val1, val);
+  val = enumCheck(cast(int)Enum4.Val2, val);
+  val = enumCheck(cast(int)Enum4.Val3, 43);
+  val = enumCheck(cast(int)Enum4.Val4, val);
+
+  val = 0;
+  val = enumCheck(cast(int)Enum5.Val1, val);
+  val = enumCheck(cast(int)Enum5.Val2, val);
+  val = enumCheck(cast(int)Enum5.Val3, 53);
+  val = enumCheck(cast(int)Enum5.Val4, val);
+
+  val = 0;
+  val = enumCheck(cast(int)Enum6.Val1, val);
+  val = enumCheck(cast(int)Enum6.Val2, val);
+  val = enumCheck(cast(int)Enum6.Val3, 63);
+  val = enumCheck(cast(int)Enum6.Val4, val);
+
+  val = 0;
+  val = enumCheck(cast(int)Enum7td.Val1, val);
+  val = enumCheck(cast(int)Enum7td.Val2, val);
+  val = enumCheck(cast(int)Enum7td.Val3, 73);
+  val = enumCheck(cast(int)Enum7td.Val4, val);
+
+  val = 0;
+  val = enumCheck(cast(int)Enum8.Val1, val);
+  val = enumCheck(cast(int)Enum8.Val2, val);
+  val = enumCheck(cast(int)Enum8.Val3, 83);
+  val = enumCheck(cast(int)Enum8.Val4, val);
+
+  val = 0;
+  val = enumCheck(cast(int)Enum10.Val1, val);
+  val = enumCheck(cast(int)Enum10.Val2, val);
+  val = enumCheck(cast(int)Enum10.Val3, 103);
+  val = enumCheck(cast(int)Enum10.Val4, val);
+
+  val = 0;
+  val = enumCheck(cast(int)Class1.Enum12.Val1, 1121);
+  val = enumCheck(cast(int)Class1.Enum12.Val2, 1122);
+  val = enumCheck(cast(int)Class1.Enum12.Val3, val);
+  val = enumCheck(cast(int)Class1.Enum12.Val4, val);
+  val = enumCheck(cast(int)Class1.Enum12.Val5c, 1121);
+  val = enumCheck(cast(int)Class1.Enum12.Val6c, val);
+
+  val = 0;
+  val = enumCheck(cast(int)Class1.Enum13.Val1, 1131);
+  val = enumCheck(cast(int)Class1.Enum13.Val2, 1132);
+  val = enumCheck(cast(int)Class1.Enum13.Val3, val);
+  val = enumCheck(cast(int)Class1.Enum13.Val4, val);
+  val = enumCheck(cast(int)Class1.Enum13.Val5d, 1131);
+  val = enumCheck(cast(int)Class1.Enum13.Val6d, val);
+
+  val = 0;
+  val = enumCheck(cast(int)Class1.Enum14.Val1, 1141);
+  val = enumCheck(cast(int)Class1.Enum14.Val2, 1142);
+  val = enumCheck(cast(int)Class1.Enum14.Val3, val);
+  val = enumCheck(cast(int)Class1.Enum14.Val4, val);
+  val = enumCheck(cast(int)Class1.Enum14.Val5e, 1141);
+  val = enumCheck(cast(int)Class1.Enum14.Val6e, val);
+
+  /* Nested struct not supported for D
+  val = 0;
+  val = enumCheck(cast(int)Class1.Struct1.Enum12.Val1, 3121);
+  val = enumCheck(cast(int)Class1.Struct1.Enum12.Val2, 3122);
+  val = enumCheck(cast(int)Class1.Struct1.Enum12.Val3, val);
+  val = enumCheck(cast(int)Class1.Struct1.Enum12.Val4, val);
+  val = enumCheck(cast(int)Class1.Struct1.Enum12.Val5f, 3121);
+  val = enumCheck(cast(int)Class1.Struct1.Enum12.Val6f, val);
+
+  val = 0;
+  val = enumCheck(cast(int)Class1.Struct1.Enum13.Val1, 3131);
+  val = enumCheck(cast(int)Class1.Struct1.Enum13.Val2, 3132);
+  val = enumCheck(cast(int)Class1.Struct1.Enum13.Val3, val);
+  val = enumCheck(cast(int)Class1.Struct1.Enum13.Val4, val);
+
+  val = 0;
+  val = enumCheck(cast(int)Class1.Struct1.Enum14.Val1, 3141);
+  val = enumCheck(cast(int)Class1.Struct1.Enum14.Val2, 3142);
+  val = enumCheck(cast(int)Class1.Struct1.Enum14.Val3, val);
+  val = enumCheck(cast(int)Class1.Struct1.Enum14.Val4, val);
+  val = enumCheck(cast(int)Class1.Struct1.Enum14.Val5g, 3141);
+  val = enumCheck(cast(int)Class1.Struct1.Enum14.Val6g, val);
+  */
+
+  val = 0;
+  val = enumCheck(cast(int)Class2.Enum12.Val1, 2121);
+  val = enumCheck(cast(int)Class2.Enum12.Val2, 2122);
+  val = enumCheck(cast(int)Class2.Enum12.Val3, val);
+  val = enumCheck(cast(int)Class2.Enum12.Val4, val);
+  val = enumCheck(cast(int)Class2.Enum12.Val5h, 2121);
+  val = enumCheck(cast(int)Class2.Enum12.Val6h, val);
+
+  val = 0;
+  val = enumCheck(cast(int)Class2.Enum13.Val1, 2131);
+  val = enumCheck(cast(int)Class2.Enum13.Val2, 2132);
+  val = enumCheck(cast(int)Class2.Enum13.Val3, val);
+  val = enumCheck(cast(int)Class2.Enum13.Val4, val);
+  val = enumCheck(cast(int)Class2.Enum13.Val5i, 2131);
+  val = enumCheck(cast(int)Class2.Enum13.Val6i, val);
+
+  val = 0;
+  val = enumCheck(cast(int)Class2.Enum14.Val1, 2141);
+  val = enumCheck(cast(int)Class2.Enum14.Val2, 2142);
+  val = enumCheck(cast(int)Class2.Enum14.Val3, val);
+  val = enumCheck(cast(int)Class2.Enum14.Val4, val);
+  val = enumCheck(cast(int)Class2.Enum14.Val5j, 2141);
+  val = enumCheck(cast(int)Class2.Enum14.Val6j, val);
+
+  /* Nested struct not supported for D
+  val = 0;
+  val = enumCheck(cast(int)Class2.Struct1.Enum12.Val1, 4121);
+  val = enumCheck(cast(int)Class2.Struct1.Enum12.Val2, 4122);
+  val = enumCheck(cast(int)Class2.Struct1.Enum12.Val3, val);
+  val = enumCheck(cast(int)Class2.Struct1.Enum12.Val4, val);
+  val = enumCheck(cast(int)Class2.Struct1.Enum12.Val5k, 4121);
+  val = enumCheck(cast(int)Class2.Struct1.Enum12.Val6k, val);
+
+  val = 0;
+  val = enumCheck(cast(int)Class2.Struct1.Enum13.Val1, 4131);
+  val = enumCheck(cast(int)Class2.Struct1.Enum13.Val2, 4132);
+  val = enumCheck(cast(int)Class2.Struct1.Enum13.Val3, val);
+  val = enumCheck(cast(int)Class2.Struct1.Enum13.Val4, val);
+  val = enumCheck(cast(int)Class2.Struct1.Enum13.Val5l, 4131);
+  val = enumCheck(cast(int)Class2.Struct1.Enum13.Val6l, val);
+
+  val = 0;
+  val = enumCheck(cast(int)Class2.Struct1.Enum14.Val1, 4141);
+  val = enumCheck(cast(int)Class2.Struct1.Enum14.Val2, 4142);
+  val = enumCheck(cast(int)Class2.Struct1.Enum14.Val3, val);
+  val = enumCheck(cast(int)Class2.Struct1.Enum14.Val4, val);
+  val = enumCheck(cast(int)Class2.Struct1.Enum14.Val5m, 4141);
+  val = enumCheck(cast(int)Class2.Struct1.Enum14.Val6m, val);
+  */
+
+  Class1 class1 = new Class1();
+  enumCheck(cast(int)class1.class1Test1(Enum1.Val5a), 13);
+  enumCheck(cast(int)class1.class1Test2(Class1.Enum12.Val5c), 1121);
+  /* Nested struct not supported for D
+  enumCheck(cast(int)class1.class1Test3(Class1.Struct1.Enum12.Val5f), 3121);
+  */
+
+  enumCheck(cast(int)globalTest1(Enum1.Val5a), 13);
+  enumCheck(cast(int)globalTest2(Class1.Enum12.Val5c), 1121);
+  /* Nested struct not supported for D
+  enumCheck(cast(int)globalTest3(Class1.Struct1.Enum12.Val5f), 3121);
+  */
+
+  // Check underlying enum type
+  assert(is(typeof(Enum2.Val1.asOriginalType) == short));
+  assert(is(typeof(Enum4.Val1.asOriginalType) == uint));
+  assert(is(typeof(Enum5.Val1.asOriginalType) == int));
+  assert(is(typeof(Enum9.Val1.asOriginalType) == ushort));
+  assert(is(typeof(Enum7td.Val1.asOriginalType) == uint));
+  assert(is(typeof(Enum10.Val1.asOriginalType) == ubyte));
+
+  assert(is(typeof(Enum15.Val1.asOriginalType) == short));
+  assert(is(typeof(Enum16.Val1.asOriginalType) == long));
+  assert(is(typeof(Enum17.Val1.asOriginalType) == uint));
+}
diff --git a/Examples/test-suite/d/d_nativepointers_runme.1.d b/Examples/test-suite/d/d_nativepointers_runme.1.d
deleted file mode 100644
index dfafacc..0000000
--- a/Examples/test-suite/d/d_nativepointers_runme.1.d
+++ /dev/null
@@ -1,38 +0,0 @@
-module d_nativepointers_runnme;
-
-import d_nativepointers.d_nativepointers;
-import d_nativepointers.SomeClass;
-import d_nativepointers.SWIGTYPE_p_OpaqueClass;
-import d_nativepointers.SWIGTYPE_p_p_SomeClass;
-import d_nativepointers.SWIGTYPE_p_p_f_p_p_int_p_SomeClass__void;
-
-extern(C) alias void function(int**, char***) GType;
-
-void main() {
-  check!(a, int*);
-  check!(b, float**);
-  check!(c, char***);
-  check!(d, SomeClass);
-  check!(e, SWIGTYPE_p_p_SomeClass);
-  check!(f, SWIGTYPE_p_OpaqueClass);
-  check!(g, GType);
-  check!(h, SWIGTYPE_p_p_f_p_p_int_p_SomeClass__void);
-
-  {
-    static assert(is(int* function(int*) == typeof(&refA)));
-    int v = 2;
-    assert(*refA(&v) == 2);
-  }
-
-  {
-    static assert(is(float** function(float**) == typeof(&refB)));
-    float v = 1.0;
-    float* p = &v;
-    assert(**refB(&p) == 1.0);
-  }
-}
-
-void check(alias F, T)() {
-  static assert(is(T function(T) == typeof(&F)));
-  assert(F(null) is null);
-}
diff --git a/Examples/test-suite/d/default_args_runme.1.d b/Examples/test-suite/d/default_args_runme.1.d
deleted file mode 100644
index 0ad63b7..0000000
--- a/Examples/test-suite/d/default_args_runme.1.d
+++ /dev/null
@@ -1,127 +0,0 @@
-module default_args_runme;
-
-import default_args.default_args;
-import default_args.ConstMethods;
-import default_args.EnumClass;
-import default_args.Except;
-import default_args.Foo;
-import default_args.Klass;
-import default_args.Statics;
-import default_args.Tricky;
-
-void main() {
-  if (anonymous() != 7771)
-    throw new Exception("anonymous (1) failed");
-  if (anonymous(1234) != 1234)
-    throw new Exception("anonymous (2) failed");
-
-  if (booltest() != true)
-    throw new Exception("booltest (1) failed");
-  if (booltest(true) != true)
-    throw new Exception("booltest (2) failed");
-  if (booltest(false) != false)
-    throw new Exception("booltest (3) failed");
-
-  auto ec = new EnumClass();
-  if (ec.blah() != true)
-    throw new Exception("EnumClass failed");
-
-  if (casts1() != null)
-    throw new Exception("casts1 failed");
-
-  if (casts2() != "Hello")
-    throw new Exception("casts2 failed");
-
-  if (casts1("Ciao") != "Ciao")
-    throw new Exception("casts1 not default failed");
-
-  if (chartest1() != 'x')
-    throw new Exception("chartest1 failed");
-
-  if (chartest2() != '\0')
-    throw new Exception("chartest2 failed");
-
-  if (chartest1('y') != 'y')
-    throw new Exception("chartest1 not default failed");
-
-  if (chartest1('y') != 'y')
-    throw new Exception("chartest1 not default failed");
-
-  if (reftest1() != 42)
-    throw new Exception("reftest1 failed");
-
-  if (reftest1(400) != 400)
-    throw new Exception("reftest1 not default failed");
-
-  if (reftest2() != "hello")
-    throw new Exception("reftest2 failed");
-
-  // rename
-  auto foo = new Foo();
-  foo.newname();
-  foo.newname(10);
-  foo.renamed3arg(10, 10.0);
-  foo.renamed2arg(10);
-  foo.renamed1arg();
-
-  // exception specifications
-  testException( { exceptionspec(); }, "exceptionspec 1" );
-  testException( { exceptionspec(-1); }, "exceptionspec 2" );
-  testException( { exceptionspec(100); }, "exceptionspec 3" );
-
-  auto ex = new Except(false);
-  testException( { ex.exspec(); }, "exspec 1" );
-  testException( { ex.exspec(-1); }, "exspec 2" );
-  testException( { ex.exspec(100); }, "exspec 3" );
-  testException( { ex = new Except(true); }, "Except constructor 1" );
-  testException( { ex = new Except(true, -2); }, "Except constructor 2" );
-
-  // Default parameters in static class methods
-  if (Statics.staticmethod() != 10+20+30)
-    throw new Exception("staticmethod 1 failed");
-  if (Statics.staticmethod(100) != 100+20+30)
-    throw new Exception("staticmethod 2 failed");
-  if (Statics.staticmethod(100,200,300) != 100+200+300)
-    throw new Exception("staticmethod 3 failed");
-
-
-  auto tricky = new Tricky();
-  if (tricky.privatedefault() != 200)
-    throw new Exception("privatedefault failed");
-  if (tricky.protectedint() != 2000)
-    throw new Exception("protectedint failed");
-  if (tricky.protecteddouble() != 987.654)
-    throw new Exception("protecteddouble failed");
-  if (tricky.functiondefault() != 500)
-    throw new Exception("functiondefault failed");
-  if (tricky.contrived() != 'X')
-    throw new Exception("contrived failed");
-
-  if (constructorcall().val != -1)
-    throw new Exception("constructorcall test 1 failed");
-
-  if (constructorcall(new Klass(2222)).val != 2222)
-    throw new Exception("constructorcall test 2 failed");
-
-  if (constructorcall(new Klass()).val != -1)
-    throw new Exception("constructorcall test 3 failed");
-
-  // const methods
-  auto cm = new ConstMethods();
-  if (cm.coo() != 20)
-    throw new Exception("coo test 1 failed");
-  if (cm.coo(1.0) != 20)
-    throw new Exception("coo test 2 failed");
-}
-
-void testException(void delegate() command, char[] testName) {
-  bool didntThrow;
-  try {
-    command();
-    didntThrow = true;
-  } catch (Exception e) {}
-
-  if (didntThrow) {
-    throw new Exception(testName ~ " failed");
-  }
-}
diff --git a/Examples/test-suite/d/default_constructor_runme.1.d b/Examples/test-suite/d/default_constructor_runme.1.d
deleted file mode 100644
index bd79cdf..0000000
--- a/Examples/test-suite/d/default_constructor_runme.1.d
+++ /dev/null
@@ -1,17 +0,0 @@
-module default_constructor_runme;
-
-import default_constructor.G;
-
-void main() {
-  // Protected destructor test.
-  try {
-    {
-      scope g = new G();
-    }
-    throw new Exception("Protected destructor exception should have been thrown");
-  } catch (Exception e) {
-    if (e.msg != "C++ destructor does not have public access") {
-      throw e;
-    }
-  }
-}
diff --git a/Examples/test-suite/d/director_alternating_runme.1.d b/Examples/test-suite/d/director_alternating_runme.1.d
deleted file mode 100644
index 27bd262..0000000
--- a/Examples/test-suite/d/director_alternating_runme.1.d
+++ /dev/null
@@ -1,7 +0,0 @@
-module director_alternating_runme;
-
-import director_alternating.director_alternating;
-
-void main() {
-   assert(getBar().id() == idFromGetBar());
-}
diff --git a/Examples/test-suite/d/director_basic_runme.1.d b/Examples/test-suite/d/director_basic_runme.1.d
deleted file mode 100644
index 58a5483..0000000
--- a/Examples/test-suite/d/director_basic_runme.1.d
+++ /dev/null
@@ -1,59 +0,0 @@
-module director_basic_runme;
-
-import director_basic.A1;
-import director_basic.Bar;
-import director_basic.Foo;
-import director_basic.MyClass;
-
-void main() {
-  auto a = new director_basic_MyFoo();
-  if (a.ping() != "director_basic_MyFoo::ping()") {
-    throw new Exception("a.ping()");
-  }
-  if (a.pong() != "Foo::pong();director_basic_MyFoo::ping()") {
-    throw new Exception("a.pong()");
-  }
-
-  auto b = new Foo();
-  if (b.ping() != "Foo::ping()") {
-    throw new Exception("b.ping()");
-  }
-  if (b.pong() != "Foo::pong();Foo::ping()") {
-    throw new Exception("b.pong()");
-  }
-
-  {
-    scope a1 = new A1(1, false);
-  }
-
-  {
-    auto my = new MyOverriddenClass();
-
-    my.expectNull = true;
-    if (MyClass.call_pmethod(my, null) !is null)
-      throw new Exception("null pointer conversion problem");
-
-    auto myBar = new Bar();
-    my.expectNull = false;
-    auto myNewBar = MyClass.call_pmethod(my, myBar);
-    if (myNewBar is null)
-      throw new Exception("non-null pointer conversion problem");
-    myNewBar.x = 10;
-  }
-}
-
-class director_basic_MyFoo : Foo {
-  public override char[] ping() {
-    return "director_basic_MyFoo::ping()";
-  }
-}
-
-class MyOverriddenClass : MyClass {
-  public bool expectNull = false;
-  public bool nonNullReceived = false;
-  public override Bar pmethod(Bar b) {
-    if (expectNull && (b !is null))
-      throw new Exception("null not received as expected");
-    return b;
-  }
-}
diff --git a/Examples/test-suite/d/director_classes_runme.1.d b/Examples/test-suite/d/director_classes_runme.1.d
deleted file mode 100644
index e753f5f..0000000
--- a/Examples/test-suite/d/director_classes_runme.1.d
+++ /dev/null
@@ -1,177 +0,0 @@
-/**
- * This test demonstrates director classes when the types are classes. Shown are
- * virtual function calls which use classes passed by
- *  - Value
- *  - Reference
- *  - Pointer
- * as both parameters and return values
- *
- * The test also demonstrates directors used with:
- *  - method overloading
- *  - default parameters
- *
- * Note: Methods with default parameters that call up from C++ cannot call the
- * overloaded D methods, see DefaultParms method.
-
- * Expected output if PrintDebug enabled:
- * ------------ Start ------------
- * Base - Val(444.555)
- * Base - Ref(444.555)
- * Base - Ptr(444.555)
- * Base - ConstPtrRef(444.555)
- * Base - FullyOverloaded(int 10)
- * Base - FullyOverloaded(bool 1)
- * Base - SemiOverloaded(int -678)
- * Base - SemiOverloaded(bool 1)
- * Base - DefaultParms(10, 2.2)
- * Base - DefaultParms(10, 1.1)
- * --------------------------------
- * Derived - Val(444.555)
- * Derived - Ref(444.555)
- * Derived - Ptr(444.555)
- * Derived - ConstPtrRef(444.555)
- * Derived - FullyOverloaded(int 10)
- * Derived - FullyOverloaded(bool 1)
- * Derived - SemiOverloaded(int -678)
- * Base - SemiOverloaded(bool 1)
- * Derived - DefaultParms(10, 2.2)
- * Derived - DefaultParms(10, 1.1)
- * --------------------------------
- * DDerived - Val(444.555)
- * DDerived - Ref(444.555)
- * DDerived - Ptr(444.555)
- * DDerived - ConstPtrRef(444.555)
- * DDerived - FullyOverloaded(int 10)
- * DDerived - FullyOverloaded(bool True)
- * DDerived - SemiOverloaded(-678)
- * Base - SemiOverloaded(bool 1)
- * DDerived - DefaultParms(10, 2.2)
- * DDerived - DefaultParms(10, 1.1)
- * ------------ Finish ------------
- */
-module director_classes_runme;
-
-import tango.io.Stdout;
-import tango.text.Util;
-import director_classes.director_classes;
-import director_classes.Caller;
-import director_classes.Base;
-import director_classes.Derived;
-import director_classes.DoubleHolder;
-
-void main() {
-  if (PrintDebug) Stdout.formatln("------------ Start ------------");
-
-  auto myCaller = new Caller();
-
-  // Test C++ base class.
-  {
-    scope myBase = new Base(100.0);
-    makeCalls(myCaller, myBase);
-  }
-
-  if (PrintDebug) Stdout.formatln("--------------------------------");
-
-  // Test vanilla C++ wrapped derived class.
-  {
-    scope myBase = new Derived(200.0);
-    makeCalls(myCaller, myBase);
-  }
-
-  if (PrintDebug) Stdout.formatln("--------------------------------");
-
-  // Test director / D derived class.
-  {
-    scope myBase = new DDerived(300.0);
-    makeCalls(myCaller, myBase);
-  }
-
-  if (PrintDebug) Stdout.formatln("------------ Finish ------------");
-}
-
-void makeCalls(Caller myCaller, Base myBase) {
-  char[] myBaseType = myBase.classinfo.name.split(".")[$-1];
-  myCaller.set(myBase);
-
-  DoubleHolder dh = new DoubleHolder(444.555);
-
-  // Class pointer, reference and pass by value tests
-  if (myCaller.ValCall(dh).val != dh.val) throw new Exception("[1] failed");
-  if (myCaller.RefCall(dh).val != dh.val) throw new Exception("[2] failed");
-  if (myCaller.PtrCall(dh).val != dh.val) throw new Exception("[3] failed");
-  if (myCaller.ConstPtrRefCall(dh).val != dh.val) throw new Exception("[3] failed");
-
-  // Fully overloaded method test (all methods in base class are overloaded)
-  if (myCaller.FullyOverloadedCall(10) != myBaseType ~ "::FullyOverloaded(int)") throw new Exception("[4] failed");
-  if (myCaller.FullyOverloadedCall(true) != myBaseType ~ "::FullyOverloaded(bool)") throw new Exception("[5] failed");
-
-  // Semi overloaded method test (some methods in base class are overloaded)
-  if (myCaller.SemiOverloadedCall(-678) != myBaseType ~ "::SemiOverloaded(int)") throw new Exception("[6] failed");
-  if (myCaller.SemiOverloadedCall(true) != "Base" ~ "::SemiOverloaded(bool)") throw new Exception("[7] failed");
-
-  // Default parameters methods test
-  if (myCaller.DefaultParmsCall(10, 2.2) != myBaseType ~ "::DefaultParms(int, double)") throw new Exception("[8] failed");
-  if (myBase.classinfo == DDerived.classinfo) { // special handling for D derived classes, there is no way to do this any other way
-    if (myCaller.DefaultParmsCall(10) != myBaseType ~ "::DefaultParms(int, double)") throw new Exception("[9] failed");
-  } else {
-    if (myCaller.DefaultParmsCall(10) != myBaseType ~ "::DefaultParms(int)") throw new Exception("[10] failed");
-  }
-
-  myCaller.reset();
-}
-
-public class DDerived : Base {
-  public this(double dd) {
-    super(dd);
-  }
-
-  public override DoubleHolder Val(DoubleHolder x) {
-    if (PrintDebug) Stdout.formatln("DDerived - Val({0:d3})", x.val);
-    return x;
-  }
-
-  public override DoubleHolder Ref(DoubleHolder x) {
-    if (PrintDebug) Stdout.formatln("DDerived - Ref({0:d3})", x.val);
-    return x;
-  }
-
-  public override DoubleHolder Ptr(DoubleHolder x) {
-    if (PrintDebug) Stdout.formatln("DDerived - Ptr({0:d3})", x.val);
-    return x;
-  }
-
-  public override DoubleHolder ConstPtrRef(DoubleHolder x) {
-    if (PrintDebug) Stdout.formatln("DDerived - ConstPtrRef({0:d3})", x.val);
-    return x;
-  }
-
-  public override char[] FullyOverloaded(int x) {
-    if (PrintDebug) Stdout.formatln("DDerived - FullyOverloaded(int {0})", x);
-    return "DDerived::FullyOverloaded(int)";
-  }
-
-  public override char[] FullyOverloaded(bool x) {
-    if (PrintDebug) Stdout.formatln("DDerived - FullyOverloaded(bool {0})", x);
-    return "DDerived::FullyOverloaded(bool)";
-  }
-
-  public override char[] SemiOverloaded(int x) {
-    char[] ret = "DDerived::SemiOverloaded(int)";
-    if (PrintDebug) Stdout.formatln("DDerived - SemiOverloaded({0})", x);
-    return ret;
-  }
-  alias Base.SemiOverloaded SemiOverloaded; // Alias in SemiOverloaded(bool x).
-
-  public override char[] DefaultParms(int x, double y) {
-    char[] ret = "DDerived::DefaultParms(int, double)";
-    if (PrintDebug) Stdout.formatln("DDerived - DefaultParms({0}, {1:d1})", x, y);
-    return ret;
-  }
-  // This method will never be called from C++ code because the two-parameter
-  // DefaultParams() has a default value for the second parameter there. It is
-  // only here to ensure consistent behavior for calls from C++ and D code.
-  public override char[] DefaultParms(int x) {
-    if (PrintDebug) Stdout.formatln("DDerived - DefaultParms({0})", x);
-    return DefaultParms(x, 1.1/*use C++ default here*/);
-  }
-}
diff --git a/Examples/test-suite/d/director_classes_runme.2.d b/Examples/test-suite/d/director_classes_runme.2.d
index b16fa54..5e9588b 100644
--- a/Examples/test-suite/d/director_classes_runme.2.d
+++ b/Examples/test-suite/d/director_classes_runme.2.d
@@ -23,8 +23,8 @@
  * Base - FullyOverloaded(bool 1)
  * Base - SemiOverloaded(int -678)
  * Base - SemiOverloaded(bool 1)
- * Base - DefaultParms(10, 2.2)
- * Base - DefaultParms(10, 1.1)
+ * Base - DefaultParms(10, 2.25)
+ * Base - DefaultParms(10, 1.125)
  * --------------------------------
  * Derived - Val(444.555)
  * Derived - Ref(444.555)
@@ -34,8 +34,8 @@
  * Derived - FullyOverloaded(bool 1)
  * Derived - SemiOverloaded(int -678)
  * Base - SemiOverloaded(bool 1)
- * Derived - DefaultParms(10, 2.2)
- * Derived - DefaultParms(10, 1.1)
+ * Derived - DefaultParms(10, 2.25)
+ * Derived - DefaultParms(10, 1.125)
  * --------------------------------
  * DDerived - Val(444.555)
  * DDerived - Ref(444.555)
@@ -45,8 +45,8 @@
  * DDerived - FullyOverloaded(bool true)
  * DDerived - SemiOverloaded(-678)
  * Base - SemiOverloaded(bool 1)
- * DDerived - DefaultParms(10, 2.2)
- * DDerived - DefaultParms(10, 1.1)
+ * DDerived - DefaultParms(10, 2.25)
+ * DDerived - DefaultParms(10, 1.125)
  * ------------ Finish ------------
  */
 module director_classes_runme;
@@ -111,7 +111,7 @@
   enforce(myCaller.SemiOverloadedCall(true) == "Base" ~ "::SemiOverloaded(bool)", "[7] failed");
 
   // Default parameters methods test
-  enforce(myCaller.DefaultParmsCall(10, 2.2) == myBaseType ~ "::DefaultParms(int, double)", "[8] failed");
+  enforce(myCaller.DefaultParmsCall(10, 2.25) == myBaseType ~ "::DefaultParms(int, double)", "[8] failed");
   if (myBase.classinfo == DDerived.classinfo) { // special handling for D derived classes, there is no other way to do this
     enforce(myCaller.DefaultParmsCall(10) == myBaseType ~ "::DefaultParms(int, double)", "[9] failed");
   } else {
@@ -173,6 +173,6 @@
   // only here to ensure consistent behavior for calls from C++ and D code.
   public override string DefaultParms(int x) {
     if (PrintDebug) writefln("DDerived - DefaultParms(%s)", x);
-    return DefaultParms(x, 1.1/*use C++ default here*/);
+    return DefaultParms(x, 1.125/*use C++ default here*/);
   }
 }
diff --git a/Examples/test-suite/d/director_classic_runme.1.d b/Examples/test-suite/d/director_classic_runme.1.d
deleted file mode 100644
index 33be806..0000000
--- a/Examples/test-suite/d/director_classic_runme.1.d
+++ /dev/null
@@ -1,207 +0,0 @@
-module director_classic_runme;
-
-import tango.io.Stdout;
-import director_classic.Caller;
-import director_classic.Person;
-import director_classic.Child;
-import director_classic.GrandChild;
-import director_classic.OrphanPerson;
-import director_classic.OrphanChild;
-
-const bool TRACE = false;
-
-void main() {
-  {
-    scope person = new Person();
-    check(person, "Person");
-  }
-  {
-    scope person = new Child();
-    check(person, "Child");
-  }
-  {
-    scope person = new GrandChild();
-    check(person, "GrandChild");
-  }
-  {
-    scope person = new TargetLangPerson();
-    check(person, "TargetLangPerson");
-  }
-  {
-    scope person = new TargetLangChild();
-    check(person, "TargetLangChild");
-  }
-  {
-    scope person = new TargetLangGrandChild();
-    check(person, "TargetLangGrandChild");
-  }
-
-  // Semis - don't override id() in target language
-  {
-    scope person = new TargetLangSemiPerson();
-    check(person, "Person");
-  }
-  {
-    scope person = new TargetLangSemiChild();
-    check(person, "Child");
-  }
-  {
-    scope person = new TargetLangSemiGrandChild();
-    check(person, "GrandChild");
-  }
-
-  // Orphans - don't override id() in C++
-  {
-    scope person = new OrphanPerson();
-    check(person, "Person");
-  }
-  {
-    scope person = new OrphanChild();
-    check(person, "Child");
-  }
-  {
-    scope person = new TargetLangOrphanPerson();
-    check(person, "TargetLangOrphanPerson");
-  }
-  {
-    scope person = new TargetLangOrphanChild();
-    check(person, "TargetLangOrphanChild");
-  }
-
-  // Duals - id() makes an upcall to the base id()
-  {
-    scope person = new TargetLangDualPerson();
-    check(person, "TargetLangDualPerson + Person");
-  }
-  {
-    scope person = new TargetLangDualChild();
-    check(person, "TargetLangDualChild + Child");
-  }
-  {
-    scope person = new TargetLangDualGrandChild();
-    check(person, "TargetLangDualGrandChild + GrandChild");
-  }
-
-  // Mix Orphans and Duals
-  {
-    scope person = new TargetLangDualOrphanPerson();
-    check(person, "TargetLangDualOrphanPerson + Person");
-  }
-  {
-    scope person = new TargetLangDualOrphanChild();
-    check(person, "TargetLangDualOrphanChild + Child");
-  }
-}
-
-void check(Person person, char[] expected) {
-  char[] ret;
-  // Normal D polymorphic call.
-  ret = person.id();
-  if (TRACE)
-    Stdout(ret).newline;
-  if (ret != expected)
-    throw new Exception("Failed. Received: " ~ ret ~ " Expected: " ~ expected);
-
-  // Polymorphic call from C++.
-  Caller caller = new Caller();
-  caller.setCallback(person);
-  ret = caller.call();
-  if (TRACE)
-    Stdout(ret).newline;
-  if (ret != expected)
-    throw new Exception("Failed. Received: " ~ ret ~ " Expected: " ~ expected);
-
-  // Polymorphic call of object created in D and passed to C++ and back again.
-  Person baseclass = caller.baseClass();
-  ret = baseclass.id();
-  if (TRACE)
-    Stdout(ret).newline;
-  if (ret != expected)
-    throw new Exception("Failed. Received: " ~ ret ~ " Expected: " ~ expected);
-
-  caller.resetCallback();
-  if (TRACE)
-    Stdout("----------------------------------------").newline;
-}
-
-
-// »Full« target language persons.
-class TargetLangPerson : Person {
-  public override char[] id() {
-    return "TargetLangPerson";
-  }
-}
-
-class TargetLangChild : Child {
-  public override char[] id() {
-    return "TargetLangChild";
-  }
-}
-
-class TargetLangGrandChild : GrandChild {
-  public override char[] id() {
-    return "TargetLangGrandChild";
-  }
-}
-
-
-// Semis - don't override id() in target language
-class TargetLangSemiPerson : Person {
-  // No id() override
-}
-
-class TargetLangSemiChild : Child {
-  // No id() override
-}
-
-class TargetLangSemiGrandChild : GrandChild {
-  // No id() override
-}
-
-
-// Orphans - don't override id() in C++
-class TargetLangOrphanPerson : OrphanPerson {
-  public override char[] id() {
-    return "TargetLangOrphanPerson";
-  }
-}
-
-class TargetLangOrphanChild : OrphanChild {
-  public override char[] id() {
-    return "TargetLangOrphanChild";
-  }
-}
-
-
-// Duals - id() makes an upcall to the base id()
-class TargetLangDualPerson : Person {
-  public override char[] id() {
-    return "TargetLangDualPerson + " ~ super.id();
-  }
-}
-
-class TargetLangDualChild : Child {
-  public override char[] id() {
-    return "TargetLangDualChild + " ~ super.id();
-  }
-}
-
-class TargetLangDualGrandChild : GrandChild {
-  public override char[] id() {
-    return "TargetLangDualGrandChild + " ~ super.id();
-  }
-}
-
-
-// Mix Orphans and Duals
-class TargetLangDualOrphanPerson : OrphanPerson {
-  public override char[] id() {
-    return "TargetLangDualOrphanPerson + " ~ super.id();
-  }
-}
-
-class TargetLangDualOrphanChild : OrphanChild {
-  public override char[] id() {
-    return "TargetLangDualOrphanChild + " ~ super.id();
-  }
-}
diff --git a/Examples/test-suite/d/director_ignore_runme.1.d b/Examples/test-suite/d/director_ignore_runme.1.d
deleted file mode 100644
index 797d2fd..0000000
--- a/Examples/test-suite/d/director_ignore_runme.1.d
+++ /dev/null
@@ -1,39 +0,0 @@
-module director_ignore_runme;
-
-import director_ignore.DIgnores;
-import director_ignore.DAbstractIgnores;
-
-void main() {
-  // Just check the classes can be instantiated and other methods work as expected
-  auto a = new DIgnoresDerived();
-  if (a.Triple(5) != 15)
-    throw new Exception("Triple failed");
-
-  auto b = new DAbstractIgnoresDerived();
-  if (b.Quadruple(5) != 20)
-    throw new Exception("Quadruple failed");
-}
-
-class DIgnoresDerived : DIgnores {
-public:
-  // These will give a warning if the %ignore is not working
-  int OverloadedMethod(int n, int xoffset, int yoffset) { return 0; }
-  int OverloadedMethod(int n, int xoffset) { return 0; }
-  int OverloadedMethod(int n) { return 0; }
-
-  int OverloadedProtectedMethod(int n, int xoffset, int yoffset) { return 0; }
-  int OverloadedProtectedMethod(int n, int xoffset) { return 0; }
-  int OverloadedProtectedMethod(int n) { return 0; }
-}
-
-class DAbstractIgnoresDerived : DAbstractIgnores {
-public:
-  // These will give a warning if the %ignore is not working
-  int OverloadedMethod(int n, int xoffset, int yoffset) { return 0; }
-  int OverloadedMethod(int n, int xoffset) { return 0; }
-  int OverloadedMethod(int n) { return 0; }
-
-  int OverloadedProtectedMethod(int n, int xoffset, int yoffset) { return 0; }
-  int OverloadedProtectedMethod(int n, int xoffset) { return 0; }
-  int OverloadedProtectedMethod(int n) { return 0; }
-}
diff --git a/Examples/test-suite/d/director_ignore_runme.2.d b/Examples/test-suite/d/director_ignore_runme.2.d
index 0d9f7f7..0e9e393 100644
--- a/Examples/test-suite/d/director_ignore_runme.2.d
+++ b/Examples/test-suite/d/director_ignore_runme.2.d
@@ -19,7 +19,7 @@
   int OverloadedMethod(int n, int xoffset, int yoffset) { return 0; }
   int OverloadedMethod(int n, int xoffset) { return 0; }
   int OverloadedMethod(int n) { return 0; }
-  alias super.OverloadedMethod OverloadedMethod;
+  alias OverloadedMethod = DIgnores.OverloadedMethod;
 
 protected:
   int OverloadedProtectedMethod(int n, int xoffset, int yoffset) { return 0; }
@@ -33,7 +33,7 @@
   int OverloadedMethod(int n, int xoffset, int yoffset) { return 0; }
   int OverloadedMethod(int n, int xoffset) { return 0; }
   int OverloadedMethod(int n) { return 0; }
-  alias super.OverloadedMethod OverloadedMethod;
+  alias OverloadedMethod = DAbstractIgnores.OverloadedMethod;
 
 protected:
   int OverloadedProtectedMethod(int n, int xoffset, int yoffset) { return 0; }
diff --git a/Examples/test-suite/d/director_primitives_runme.1.d b/Examples/test-suite/d/director_primitives_runme.1.d
deleted file mode 100644
index f19e86f..0000000
--- a/Examples/test-suite/d/director_primitives_runme.1.d
+++ /dev/null
@@ -1,122 +0,0 @@
-/**
- * This test program shows a D class DDerived inheriting from Base.
- *
- * Three types of classes are created and the virtual methods called to
- * demonstrate:
- *  - Wide variety of primitive types
- *  - Calling methods with zero, one or more parameters
- *  - Director methods that are not overridden in D
- *  - Director classes that are not overridden at all in D, i.e. non-director
- *    behaviour is as expected for director classes
- *  - Inheritance hierarchy using director methods
- *  - Return types working as well as parameters
- *
- * The Caller class is a tester class which calls the virtual functions from C++.
- */
-module director_primitives_runme;
-
-import tango.io.Stdout;
-import director_primitives.director_primitives;
-import director_primitives.Base;
-import director_primitives.Caller;
-import director_primitives.Derived;
-import director_primitives.HShadowMode;
-
-void main() {
-  PrintDebug = false;
-  if (PrintDebug) Stdout("------------ Start ------------ ").newline;
-
-  Caller myCaller = new Caller();
-
-  // Test C++ base class.
-  {
-    scope myBase = new Base(100.0);
-    makeCalls(myCaller, myBase);
-  }
-
-  if (PrintDebug) Stdout("--------------------------------").newline;
-
-  // Test vanilla C++ wrapped derived class.
-  {
-    scope Base myBase = new Derived(100.0);
-    makeCalls(myCaller, myBase);
-  }
-
-  if (PrintDebug) Stdout("--------------------------------").newline;
-
-  // Test director/D derived class.
-  {
-    scope Base myBase = new DDerived(300.0);
-    makeCalls(myCaller, myBase);
-  }
-
-  if (PrintDebug) Stdout("------------ Finish ------------ ").newline;
-}
-
-void makeCalls(Caller myCaller, Base myBase) {
-  myCaller.set(myBase);
-
-  myCaller.NoParmsMethodCall();
-  if (myCaller.BoolMethodCall(true) != true) throw new Exception("failed");
-  if (myCaller.BoolMethodCall(false) != false) throw new Exception("failed");
-  if (myCaller.IntMethodCall(-123) != -123) throw new Exception("failed");
-  if (myCaller.UIntMethodCall(123) != 123) throw new Exception("failed");
-  if (myCaller.FloatMethodCall(-123.456f) != -123.456f) throw new Exception("failed");
-  if (myCaller.CharPtrMethodCall("test string") != "test string") throw new Exception("failed");
-  if (myCaller.ConstCharPtrMethodCall("another string") != "another string") throw new Exception("failed");
-  if (myCaller.EnumMethodCall(HShadowMode.HShadowHard) != HShadowMode.HShadowHard) throw new Exception("failed");
-  myCaller.ManyParmsMethodCall(true, -123, 123, 123.456f, "test string", "another string", HShadowMode.HShadowHard);
-  myCaller.NotOverriddenMethodCall();
-
-  myCaller.reset();
-}
-
-class DDerived : Base {
-public:
-  this(double dd) {
-    super(dd);
-  }
-
-  override void NoParmsMethod() {
-    if (PrintDebug) Stdout("DDerived - NoParmsMethod()").newline;
-  }
-
-  override bool BoolMethod(bool x) {
-    if (PrintDebug) Stdout.formatln("DDerived - BoolMethod({0})", x);
-    return x;
-  }
-
-  override int IntMethod(int x) {
-    if (PrintDebug) Stdout.formatln("DDerived - IntMethod({0})", x);
-    return x;
-  }
-
-  override uint UIntMethod(uint x) {
-    if (PrintDebug) Stdout.formatln("DDerived - UIntMethod({0})", x);
-    return x;
-  }
-
-  override float FloatMethod(float x) {
-    if (PrintDebug) Stdout.formatln("DDerived - FloatMethod({0})", x);
-    return x;
-  }
-
-  override char[] CharPtrMethod(char[] x) {
-    if (PrintDebug) Stdout.formatln("DDerived - CharPtrMethod({0})", x);
-    return x;
-  }
-
-  override char[] ConstCharPtrMethod(char[] x) {
-    if (PrintDebug) Stdout.formatln("DDerived - ConstCharPtrMethod({0})", x);
-    return x;
-  }
-
-  override HShadowMode EnumMethod(HShadowMode x) {
-    if (PrintDebug) Stdout.formatln("DDerived - EnumMethod({0})", x);
-    return x;
-  }
-
-  override void ManyParmsMethod(bool b, int i, uint u, float f, char[] c, char[] cc, HShadowMode h) {
-    if (PrintDebug) Stdout.formatln("DDerived - ManyParmsMethod({0}, {1}, {2}, {3:d3}, {4}, {5}, {6})", b, i, u, f, c, cc, h);
-  }
-}
diff --git a/Examples/test-suite/d/director_protected_runme.1.d b/Examples/test-suite/d/director_protected_runme.1.d
deleted file mode 100644
index 81447b7..0000000
--- a/Examples/test-suite/d/director_protected_runme.1.d
+++ /dev/null
@@ -1,50 +0,0 @@
-module director_protected_runme;
-
-import director_protected.Foo;
-import director_protected.Bar;
-
-void main() {
-  Bar b = new Bar();
-  Foo f = b.create();
-  auto fb = new FooBar();
-  auto fb2 = new FooBar2();
-
-  char[] s;
-  s = fb.used();
-  if ( s != ("Foo::pang();Bar::pong();Foo::pong();FooBar::ping();"))
-    throw new Exception("bad FooBar::used" ~ " - " ~ s);
-
-  s = fb2.used();
-  if ( s != ("FooBar2::pang();Bar::pong();Foo::pong();FooBar2::ping();"))
-    throw new Exception("bad FooBar2::used");
-
-  s = b.pong();
-  if ( s != ("Bar::pong();Foo::pong();Bar::ping();"))
-    throw new Exception("bad Bar::pong");
-
-  s = f.pong();
-  if ( s != ("Bar::pong();Foo::pong();Bar::ping();"))
-    throw new Exception("bad Foo::pong");
-
-  s = fb.pong();
-  if ( s != ("Bar::pong();Foo::pong();FooBar::ping();"))
-    throw new Exception("bad FooBar::pong");
-}
-
-class FooBar : Bar {
-protected:
-  override char[] ping() {
-    return "FooBar::ping();";
-  }
-}
-
-class FooBar2 : Bar{
-protected:
-  override char[] ping() {
-    return "FooBar2::ping();";
-  }
-
-  override char[] pang() {
-    return "FooBar2::pang();";
-  }
-}
diff --git a/Examples/test-suite/d/director_string_runme.1.d b/Examples/test-suite/d/director_string_runme.1.d
deleted file mode 100644
index 4e75079..0000000
--- a/Examples/test-suite/d/director_string_runme.1.d
+++ /dev/null
@@ -1,46 +0,0 @@
-module director_string_runme;
-
-import Integer = tango.text.convert.Integer;
-import director_string.A;
-
-void main() {
-  char[] s;
-
-  auto c = new director_string_A("hi");
-  for (int i=0; i<3; ++i) {
-    s = c.call_get(i);
-    if (s != Integer.toString(i)) throw new Exception("director_string_A.get(" ~ Integer.toString(i) ~ ") failed. Got:" ~ s);
-  }
-
-  auto b = new director_string_B("hello");
-
-  s = b.call_get_first();
-  if (s != "director_string_B.get_first") throw new Exception("call_get_first() failed");
-
-  s = b.call_get(0);
-  if (s != "director_string_B.get: hello") throw new Exception("get(0) failed");
-}
-
-class director_string_B : A {
-public:
-  this(char[] first) {
-    super(first);
-  }
-  override char[] get_first() {
-    return "director_string_B.get_first";
-  }
-
-  override char[] get(int n) {
-    return "director_string_B.get: " ~ super.get(n);
-  }
-}
-
-class director_string_A : A {
-public:
-  this(char[] first) {
-    super(first);
-  }
-  override char[] get(int n) {
-    return Integer.toString(n);
-  }
-}
diff --git a/Examples/test-suite/d/enum_thorough_runme.1.d b/Examples/test-suite/d/enum_thorough_runme.1.d
deleted file mode 100644
index b318bc0..0000000
--- a/Examples/test-suite/d/enum_thorough_runme.1.d
+++ /dev/null
@@ -1,447 +0,0 @@
-module enum_thorough_runme;
-
-import enum_thorough.enum_thorough;
-import enum_thorough.AnonStruct;
-import enum_thorough.colour;
-import enum_thorough.DifferentTypes;
-import enum_thorough.FirStruct;
-import enum_thorough.HairStruct;
-import enum_thorough.IgnoreTest;
-import enum_thorough.Instances;
-import enum_thorough.namedanon;
-import enum_thorough.namedanonspace;
-import enum_thorough.newname;
-import enum_thorough.NewNameStruct;
-import enum_thorough.repeat;
-import enum_thorough.SpeedClass;
-import enum_thorough.TClassInt;
-import enum_thorough.TemplateClassInt;
-import enum_thorough.TreesClass;
-import enum_thorough.twonames;
-import enum_thorough.TwoNamesStruct;
-
-void main() {
-  {
-    // Anonymous enums
-    int i = AnonEnum1;
-    if (ReallyAnInteger != 200) throw new Exception("Test Anon 1 failed");
-    i += AnonSpaceEnum1;
-    i += AnonStruct.AnonStructEnum1;
-  }
-  {
-    auto red = colour.red;
-    colourTest1(red);
-    colourTest2(red);
-    colourTest3(red);
-    colourTest4(red);
-    myColour = red;
-  }
-  {
-    auto s = new SpeedClass();
-    auto speed = SpeedClass.speed.slow;
-    if (s.speedTest1(speed) != speed) throw new Exception("speedTest 1 failed");
-    if (s.speedTest2(speed) != speed) throw new Exception("speedTest 2 failed");
-    if (s.speedTest3(speed) != speed) throw new Exception("speedTest 3 failed");
-    if (s.speedTest4(speed) != speed) throw new Exception("speedTest 4 failed");
-    if (s.speedTest5(speed) != speed) throw new Exception("speedTest 5 failed");
-    if (s.speedTest6(speed) != speed) throw new Exception("speedTest 6 failed");
-    if (s.speedTest7(speed) != speed) throw new Exception("speedTest 7 failed");
-    if (s.speedTest8(speed) != speed) throw new Exception("speedTest 8 failed");
-
-    if (speedTest1(speed) != speed) throw new Exception("speedTest Global 1 failed");
-    if (speedTest2(speed) != speed) throw new Exception("speedTest Global 2 failed");
-    if (speedTest3(speed) != speed) throw new Exception("speedTest Global 3 failed");
-    if (speedTest4(speed) != speed) throw new Exception("speedTest Global 4 failed");
-    if (speedTest5(speed) != speed) throw new Exception("speedTest Global 5 failed");
-  }
-  {
-    auto s = new SpeedClass();
-    auto slow = SpeedClass.speed.slow;
-    auto lightning = SpeedClass.speed.lightning;
-
-    if (s.mySpeedtd1 != slow) throw new Exception("mySpeedtd1 1 failed");
-    if (cast(int)s.mySpeedtd1 != 10) throw new Exception("mySpeedtd1 2 failed");
-
-    s.mySpeedtd1 = lightning;
-    if (s.mySpeedtd1 != lightning) throw new Exception("mySpeedtd1 3 failed");
-    if (cast(int)s.mySpeedtd1 != 31) throw new Exception("mySpeedtd1 4 failed");
-  }
-  {
-    if (namedanonTest1(namedanon.NamedAnon2) != namedanon.NamedAnon2) throw new Exception("namedanonTest 1 failed");
-  }
-  {
-    auto val = twonames.TwoNames2;
-    if (twonamesTest1(val) != val) throw new Exception("twonamesTest 1 failed");
-    if (twonamesTest2(val) != val) throw new Exception("twonamesTest 2 failed");
-    if (twonamesTest3(val) != val) throw new Exception("twonamesTest 3 failed");
-  }
-  {
-    auto t = new TwoNamesStruct();
-    auto val = TwoNamesStruct.twonames.TwoNamesStruct1;
-    if (t.twonamesTest1(val) != val) throw new Exception("twonamesTest 1 failed");
-    if (t.twonamesTest2(val) != val) throw new Exception("twonamesTest 2 failed");
-    if (t.twonamesTest3(val) != val) throw new Exception("twonamesTest 3 failed");
-  }
-  {
-    auto val = namedanonspace.NamedAnonSpace2;
-    if (namedanonspaceTest1(val) != val) throw new Exception("namedanonspaceTest 1 failed");
-    if (namedanonspaceTest2(val) != val) throw new Exception("namedanonspaceTest 2 failed");
-    if (namedanonspaceTest3(val) != val) throw new Exception("namedanonspaceTest 3 failed");
-    if (namedanonspaceTest4(val) != val) throw new Exception("namedanonspaceTest 4 failed");
-  }
-  {
-    auto t = new TemplateClassInt();
-    auto galileo = TemplateClassInt.scientists.galileo;
-    if (t.scientistsTest1(galileo) != galileo) throw new Exception("scientistsTest 1 failed");
-    if (t.scientistsTest2(galileo) != galileo) throw new Exception("scientistsTest 2 failed");
-    if (t.scientistsTest3(galileo) != galileo) throw new Exception("scientistsTest 3 failed");
-    if (t.scientistsTest4(galileo) != galileo) throw new Exception("scientistsTest 4 failed");
-    if (t.scientistsTest5(galileo) != galileo) throw new Exception("scientistsTest 5 failed");
-    if (t.scientistsTest6(galileo) != galileo) throw new Exception("scientistsTest 6 failed");
-    if (t.scientistsTest7(galileo) != galileo) throw new Exception("scientistsTest 7 failed");
-    if (t.scientistsTest8(galileo) != galileo) throw new Exception("scientistsTest 8 failed");
-    if (t.scientistsTest9(galileo) != galileo) throw new Exception("scientistsTest 9 failed");
-//      if (t.scientistsTestA(galileo) != galileo) throw new Exception("scientistsTest A failed");
-    if (t.scientistsTestB(galileo) != galileo) throw new Exception("scientistsTest B failed");
-//      if (t.scientistsTestC(galileo) != galileo) throw new Exception("scientistsTest C failed");
-    if (t.scientistsTestD(galileo) != galileo) throw new Exception("scientistsTest D failed");
-    if (t.scientistsTestE(galileo) != galileo) throw new Exception("scientistsTest E failed");
-    if (t.scientistsTestF(galileo) != galileo) throw new Exception("scientistsTest F failed");
-    if (t.scientistsTestG(galileo) != galileo) throw new Exception("scientistsTest G failed");
-    if (t.scientistsTestH(galileo) != galileo) throw new Exception("scientistsTest H failed");
-    if (t.scientistsTestI(galileo) != galileo) throw new Exception("scientistsTest I failed");
-    if (t.scientistsTestJ(galileo) != galileo) throw new Exception("scientistsTest J failed");
-
-    if (scientistsTest1(galileo) != galileo) throw new Exception("scientistsTest Global 1 failed");
-    if (scientistsTest2(galileo) != galileo) throw new Exception("scientistsTest Global 2 failed");
-    if (scientistsTest3(galileo) != galileo) throw new Exception("scientistsTest Global 3 failed");
-    if (scientistsTest4(galileo) != galileo) throw new Exception("scientistsTest Global 4 failed");
-    if (scientistsTest5(galileo) != galileo) throw new Exception("scientistsTest Global 5 failed");
-    if (scientistsTest6(galileo) != galileo) throw new Exception("scientistsTest Global 6 failed");
-    if (scientistsTest7(galileo) != galileo) throw new Exception("scientistsTest Global 7 failed");
-    if (scientistsTest8(galileo) != galileo) throw new Exception("scientistsTest Global 8 failed");
-  }
-  {
-    auto t = new TClassInt();
-    auto bell = TClassInt.scientists.bell;
-    auto galileo = TemplateClassInt.scientists.galileo;
-    if (t.scientistsNameTest1(bell) != bell) throw new Exception("scientistsNameTest 1 failed");
-    if (t.scientistsNameTest2(bell) != bell) throw new Exception("scientistsNameTest 2 failed");
-    if (t.scientistsNameTest3(bell) != bell) throw new Exception("scientistsNameTest 3 failed");
-    if (t.scientistsNameTest4(bell) != bell) throw new Exception("scientistsNameTest 4 failed");
-    if (t.scientistsNameTest5(bell) != bell) throw new Exception("scientistsNameTest 5 failed");
-    if (t.scientistsNameTest6(bell) != bell) throw new Exception("scientistsNameTest 6 failed");
-    if (t.scientistsNameTest7(bell) != bell) throw new Exception("scientistsNameTest 7 failed");
-    if (t.scientistsNameTest8(bell) != bell) throw new Exception("scientistsNameTest 8 failed");
-    if (t.scientistsNameTest9(bell) != bell) throw new Exception("scientistsNameTest 9 failed");
-//      if (t.scientistsNameTestA(bell) != bell) throw new Exception("scientistsNameTest A failed");
-    if (t.scientistsNameTestB(bell) != bell) throw new Exception("scientistsNameTest B failed");
-//      if (t.scientistsNameTestC(bell) != bell) throw new Exception("scientistsNameTest C failed");
-    if (t.scientistsNameTestD(bell) != bell) throw new Exception("scientistsNameTest D failed");
-    if (t.scientistsNameTestE(bell) != bell) throw new Exception("scientistsNameTest E failed");
-    if (t.scientistsNameTestF(bell) != bell) throw new Exception("scientistsNameTest F failed");
-    if (t.scientistsNameTestG(bell) != bell) throw new Exception("scientistsNameTest G failed");
-    if (t.scientistsNameTestH(bell) != bell) throw new Exception("scientistsNameTest H failed");
-    if (t.scientistsNameTestI(bell) != bell) throw new Exception("scientistsNameTest I failed");
-
-    if (t.scientistsNameSpaceTest1(bell) != bell) throw new Exception("scientistsNameSpaceTest 1 failed");
-    if (t.scientistsNameSpaceTest2(bell) != bell) throw new Exception("scientistsNameSpaceTest 2 failed");
-    if (t.scientistsNameSpaceTest3(bell) != bell) throw new Exception("scientistsNameSpaceTest 3 failed");
-    if (t.scientistsNameSpaceTest4(bell) != bell) throw new Exception("scientistsNameSpaceTest 4 failed");
-    if (t.scientistsNameSpaceTest5(bell) != bell) throw new Exception("scientistsNameSpaceTest 5 failed");
-    if (t.scientistsNameSpaceTest6(bell) != bell) throw new Exception("scientistsNameSpaceTest 6 failed");
-    if (t.scientistsNameSpaceTest7(bell) != bell) throw new Exception("scientistsNameSpaceTest 7 failed");
-
-    if (t.scientistsOtherTest1(galileo) != galileo) throw new Exception("scientistsOtherTest 1 failed");
-    if (t.scientistsOtherTest2(galileo) != galileo) throw new Exception("scientistsOtherTest 2 failed");
-    if (t.scientistsOtherTest3(galileo) != galileo) throw new Exception("scientistsOtherTest 3 failed");
-    if (t.scientistsOtherTest4(galileo) != galileo) throw new Exception("scientistsOtherTest 4 failed");
-    if (t.scientistsOtherTest5(galileo) != galileo) throw new Exception("scientistsOtherTest 5 failed");
-    if (t.scientistsOtherTest6(galileo) != galileo) throw new Exception("scientistsOtherTest 6 failed");
-    if (t.scientistsOtherTest7(galileo) != galileo) throw new Exception("scientistsOtherTest 7 failed");
-
-    if (scientistsNameTest1(bell) != bell) throw new Exception("scientistsNameTest Global 1 failed");
-    if (scientistsNameTest2(bell) != bell) throw new Exception("scientistsNameTest Global 2 failed");
-    if (scientistsNameTest3(bell) != bell) throw new Exception("scientistsNameTest Global 3 failed");
-    if (scientistsNameTest4(bell) != bell) throw new Exception("scientistsNameTest Global 4 failed");
-    if (scientistsNameTest5(bell) != bell) throw new Exception("scientistsNameTest Global 5 failed");
-    if (scientistsNameTest6(bell) != bell) throw new Exception("scientistsNameTest Global 6 failed");
-    if (scientistsNameTest7(bell) != bell) throw new Exception("scientistsNameTest Global 7 failed");
-
-    if (scientistsNameSpaceTest1(bell) != bell) throw new Exception("scientistsNameSpaceTest Global 1 failed");
-    if (scientistsNameSpaceTest2(bell) != bell) throw new Exception("scientistsNameSpaceTest Global 2 failed");
-    if (scientistsNameSpaceTest3(bell) != bell) throw new Exception("scientistsNameSpaceTest Global 3 failed");
-    if (scientistsNameSpaceTest4(bell) != bell) throw new Exception("scientistsNameSpaceTest Global 4 failed");
-    if (scientistsNameSpaceTest5(bell) != bell) throw new Exception("scientistsNameSpaceTest Global 5 failed");
-    if (scientistsNameSpaceTest6(bell) != bell) throw new Exception("scientistsNameSpaceTest Global 6 failed");
-    if (scientistsNameSpaceTest7(bell) != bell) throw new Exception("scientistsNameSpaceTest Global 7 failed");
-
-    if (scientistsNameSpaceTest8(bell) != bell) throw new Exception("scientistsNameSpaceTest Global 8 failed");
-    if (scientistsNameSpaceTest9(bell) != bell) throw new Exception("scientistsNameSpaceTest Global 9 failed");
-    if (scientistsNameSpaceTestA(bell) != bell) throw new Exception("scientistsNameSpaceTest Global A failed");
-    if (scientistsNameSpaceTestB(bell) != bell) throw new Exception("scientistsNameSpaceTest Global B failed");
-    if (scientistsNameSpaceTestC(bell) != bell) throw new Exception("scientistsNameSpaceTest Global C failed");
-    if (scientistsNameSpaceTestD(bell) != bell) throw new Exception("scientistsNameSpaceTest Global D failed");
-    if (scientistsNameSpaceTestE(bell) != bell) throw new Exception("scientistsNameSpaceTest Global E failed");
-
-    if (scientistsNameSpaceTestF(bell) != bell) throw new Exception("scientistsNameSpaceTest Global F failed");
-    if (scientistsNameSpaceTestG(bell) != bell) throw new Exception("scientistsNameSpaceTest Global G failed");
-    if (scientistsNameSpaceTestH(bell) != bell) throw new Exception("scientistsNameSpaceTest Global H failed");
-    if (scientistsNameSpaceTestI(bell) != bell) throw new Exception("scientistsNameSpaceTest Global I failed");
-    if (scientistsNameSpaceTestJ(bell) != bell) throw new Exception("scientistsNameSpaceTest Global J failed");
-    if (scientistsNameSpaceTestK(bell) != bell) throw new Exception("scientistsNameSpaceTest Global K failed");
-    if (scientistsNameSpaceTestL(bell) != bell) throw new Exception("scientistsNameSpaceTest Global L failed");
-  }
-  {
-    auto val = newname.argh;
-    if (renameTest1(val) != val) throw new Exception("renameTest Global 1 failed");
-    if (renameTest2(val) != val) throw new Exception("renameTest Global 2 failed");
-  }
-  {
-    auto n = new NewNameStruct();
-    if (n.renameTest1(NewNameStruct.enumeration.bang) != NewNameStruct.enumeration.bang) throw new Exception("renameTest 1 failed");
-    if (n.renameTest2(NewNameStruct.enumeration.bang) != NewNameStruct.enumeration.bang) throw new Exception("renameTest 2 failed");
-    if (n.renameTest3(NewNameStruct.simplerenamed.simple1) != NewNameStruct.simplerenamed.simple1) throw new Exception("renameTest 3 failed");
-    if (n.renameTest4(NewNameStruct.doublenamerenamed.doublename1) != NewNameStruct.doublenamerenamed.doublename1) throw new Exception("renameTest 4 failed");
-    if (n.renameTest5(NewNameStruct.doublenamerenamed.doublename1) != NewNameStruct.doublenamerenamed.doublename1) throw new Exception("renameTest 5 failed");
-    if (n.renameTest6(NewNameStruct.singlenamerenamed.singlename1) != NewNameStruct.singlenamerenamed.singlename1) throw new Exception("renameTest 6 failed");
-  }
-  {
-    if (renameTest3(NewNameStruct.enumeration.bang) != NewNameStruct.enumeration.bang) throw new Exception("renameTest Global 3 failed");
-    if (renameTest4(NewNameStruct.simplerenamed.simple1) != NewNameStruct.simplerenamed.simple1) throw new Exception("renameTest Global 4 failed");
-    if (renameTest5(NewNameStruct.doublenamerenamed.doublename1) != NewNameStruct.doublenamerenamed.doublename1) throw new Exception("renameTest Global 5 failed");
-    if (renameTest6(NewNameStruct.doublenamerenamed.doublename1) != NewNameStruct.doublenamerenamed.doublename1) throw new Exception("renameTest Global 6 failed");
-    if (renameTest7(NewNameStruct.singlenamerenamed.singlename1) != NewNameStruct.singlenamerenamed.singlename1) throw new Exception("renameTest Global 7 failed");
-  }
-  {
-    auto t = new TreesClass();
-    auto pine = TreesClass.trees.pine;
-
-    if (t.treesTest1(pine) != pine) throw new Exception("treesTest 1 failed");
-    if (t.treesTest2(pine) != pine) throw new Exception("treesTest 2 failed");
-    if (t.treesTest3(pine) != pine) throw new Exception("treesTest 3 failed");
-    if (t.treesTest4(pine) != pine) throw new Exception("treesTest 4 failed");
-    if (t.treesTest5(pine) != pine) throw new Exception("treesTest 5 failed");
-    if (t.treesTest6(pine) != pine) throw new Exception("treesTest 6 failed");
-    if (t.treesTest7(pine) != pine) throw new Exception("treesTest 7 failed");
-    if (t.treesTest8(pine) != pine) throw new Exception("treesTest 8 failed");
-    if (t.treesTest9(pine) != pine) throw new Exception("treesTest 9 failed");
-    if (t.treesTestA(pine) != pine) throw new Exception("treesTest A failed");
-    if (t.treesTestB(pine) != pine) throw new Exception("treesTest B failed");
-    if (t.treesTestC(pine) != pine) throw new Exception("treesTest C failed");
-    if (t.treesTestD(pine) != pine) throw new Exception("treesTest D failed");
-    if (t.treesTestE(pine) != pine) throw new Exception("treesTest E failed");
-    if (t.treesTestF(pine) != pine) throw new Exception("treesTest F failed");
-    if (t.treesTestG(pine) != pine) throw new Exception("treesTest G failed");
-    if (t.treesTestH(pine) != pine) throw new Exception("treesTest H failed");
-    if (t.treesTestI(pine) != pine) throw new Exception("treesTest I failed");
-    if (t.treesTestJ(pine) != pine) throw new Exception("treesTest J failed");
-    if (t.treesTestK(pine) != pine) throw new Exception("treesTest K failed");
-    if (t.treesTestL(pine) != pine) throw new Exception("treesTest L failed");
-    if (t.treesTestM(pine) != pine) throw new Exception("treesTest M failed");
-    if (t.treesTestN(pine) != pine) throw new Exception("treesTest N failed");
-    if (t.treesTestO(pine) != pine) throw new Exception("treesTest O failed");
-
-    if (treesTest1(pine) != pine) throw new Exception("treesTest Global 1 failed");
-    if (treesTest2(pine) != pine) throw new Exception("treesTest Global 2 failed");
-    if (treesTest3(pine) != pine) throw new Exception("treesTest Global 3 failed");
-    if (treesTest4(pine) != pine) throw new Exception("treesTest Global 4 failed");
-    if (treesTest5(pine) != pine) throw new Exception("treesTest Global 5 failed");
-    if (treesTest6(pine) != pine) throw new Exception("treesTest Global 6 failed");
-    if (treesTest7(pine) != pine) throw new Exception("treesTest Global 7 failed");
-    if (treesTest8(pine) != pine) throw new Exception("treesTest Global 8 failed");
-    if (treesTest9(pine) != pine) throw new Exception("treesTest Global 9 failed");
-    if (treesTestA(pine) != pine) throw new Exception("treesTest Global A failed");
-    if (treesTestB(pine) != pine) throw new Exception("treesTest Global B failed");
-    if (treesTestC(pine) != pine) throw new Exception("treesTest Global C failed");
-    if (treesTestD(pine) != pine) throw new Exception("treesTest Global D failed");
-    if (treesTestE(pine) != pine) throw new Exception("treesTest Global E failed");
-    if (treesTestF(pine) != pine) throw new Exception("treesTest Global F failed");
-    if (treesTestG(pine) != pine) throw new Exception("treesTest Global G failed");
-    if (treesTestH(pine) != pine) throw new Exception("treesTest Global H failed");
-    if (treesTestI(pine) != pine) throw new Exception("treesTest Global I failed");
-    if (treesTestJ(pine) != pine) throw new Exception("treesTest Global J failed");
-    if (treesTestK(pine) != pine) throw new Exception("treesTest Global K failed");
-    if (treesTestL(pine) != pine) throw new Exception("treesTest Global L failed");
-    if (treesTestM(pine) != pine) throw new Exception("treesTest Global M failed");
-//      if (treesTestN(pine) != pine) throw new Exception("treesTest Global N failed");
-    if (treesTestO(pine) != pine) throw new Exception("treesTest Global O failed");
-    if (treesTestP(pine) != pine) throw new Exception("treesTest Global P failed");
-    if (treesTestQ(pine) != pine) throw new Exception("treesTest Global Q failed");
-    if (treesTestR(pine) != pine) throw new Exception("treesTest Global R failed");
-  }
-  {
-    auto h = new HairStruct();
-    auto ginger = HairStruct.hair.ginger;
-
-    if (h.hairTest1(ginger) != ginger) throw new Exception("hairTest 1 failed");
-    if (h.hairTest2(ginger) != ginger) throw new Exception("hairTest 2 failed");
-    if (h.hairTest3(ginger) != ginger) throw new Exception("hairTest 3 failed");
-    if (h.hairTest4(ginger) != ginger) throw new Exception("hairTest 4 failed");
-    if (h.hairTest5(ginger) != ginger) throw new Exception("hairTest 5 failed");
-    if (h.hairTest6(ginger) != ginger) throw new Exception("hairTest 6 failed");
-    if (h.hairTest7(ginger) != ginger) throw new Exception("hairTest 7 failed");
-    if (h.hairTest8(ginger) != ginger) throw new Exception("hairTest 8 failed");
-    if (h.hairTest9(ginger) != ginger) throw new Exception("hairTest 9 failed");
-    if (h.hairTestA(ginger) != ginger) throw new Exception("hairTest A failed");
-    if (h.hairTestB(ginger) != ginger) throw new Exception("hairTest B failed");
-
-    auto red = colour.red;
-    if (h.colourTest1(red) != red) throw new Exception("colourTest HairStruct 1 failed");
-    if (h.colourTest2(red) != red) throw new Exception("colourTest HairStruct 2 failed");
-    if (h.namedanonTest1(namedanon.NamedAnon2) != namedanon.NamedAnon2) throw new Exception("namedanonTest HairStruct 1 failed");
-    if (h.namedanonspaceTest1(namedanonspace.NamedAnonSpace2) != namedanonspace.NamedAnonSpace2) throw new Exception("namedanonspaceTest HairStruct 1 failed");
-
-    auto fir = TreesClass.trees.fir;
-    if (h.treesGlobalTest1(fir) != fir) throw new Exception("treesGlobalTest1 HairStruct 1 failed");
-    if (h.treesGlobalTest2(fir) != fir) throw new Exception("treesGlobalTest1 HairStruct 2 failed");
-    if (h.treesGlobalTest3(fir) != fir) throw new Exception("treesGlobalTest1 HairStruct 3 failed");
-    if (h.treesGlobalTest4(fir) != fir) throw new Exception("treesGlobalTest1 HairStruct 4 failed");
-  }
-  {
-    auto blonde = HairStruct.hair.blonde;
-    if (hairTest1(blonde) != blonde) throw new Exception("hairTest Global 1 failed");
-    if (hairTest2(blonde) != blonde) throw new Exception("hairTest Global 2 failed");
-    if (hairTest3(blonde) != blonde) throw new Exception("hairTest Global 3 failed");
-    if (hairTest4(blonde) != blonde) throw new Exception("hairTest Global 4 failed");
-    if (hairTest5(blonde) != blonde) throw new Exception("hairTest Global 5 failed");
-    if (hairTest6(blonde) != blonde) throw new Exception("hairTest Global 6 failed");
-    if (hairTest7(blonde) != blonde) throw new Exception("hairTest Global 7 failed");
-    if (hairTest8(blonde) != blonde) throw new Exception("hairTest Global 8 failed");
-    if (hairTest9(blonde) != blonde) throw new Exception("hairTest Global 9 failed");
-    if (hairTestA(blonde) != blonde) throw new Exception("hairTest Global A failed");
-    if (hairTestB(blonde) != blonde) throw new Exception("hairTest Global B failed");
-    if (hairTestC(blonde) != blonde) throw new Exception("hairTest Global C failed");
-
-    if (hairTestA1(blonde) != blonde) throw new Exception("hairTest Global A1 failed");
-    if (hairTestA2(blonde) != blonde) throw new Exception("hairTest Global A2 failed");
-    if (hairTestA3(blonde) != blonde) throw new Exception("hairTest Global A3 failed");
-    if (hairTestA4(blonde) != blonde) throw new Exception("hairTest Global A4 failed");
-    if (hairTestA5(blonde) != blonde) throw new Exception("hairTest Global A5 failed");
-    if (hairTestA6(blonde) != blonde) throw new Exception("hairTest Global A6 failed");
-    if (hairTestA7(blonde) != blonde) throw new Exception("hairTest Global A7 failed");
-    if (hairTestA8(blonde) != blonde) throw new Exception("hairTest Global A8 failed");
-    if (hairTestA9(blonde) != blonde) throw new Exception("hairTest Global A9 failed");
-    if (hairTestAA(blonde) != blonde) throw new Exception("hairTest Global AA failed");
-    if (hairTestAB(blonde) != blonde) throw new Exception("hairTest Global AB failed");
-    if (hairTestAC(blonde) != blonde) throw new Exception("hairTest Global AC failed");
-
-    if (hairTestB1(blonde) != blonde) throw new Exception("hairTest Global B1 failed");
-    if (hairTestB2(blonde) != blonde) throw new Exception("hairTest Global B2 failed");
-    if (hairTestB3(blonde) != blonde) throw new Exception("hairTest Global B3 failed");
-    if (hairTestB4(blonde) != blonde) throw new Exception("hairTest Global B4 failed");
-    if (hairTestB5(blonde) != blonde) throw new Exception("hairTest Global B5 failed");
-    if (hairTestB6(blonde) != blonde) throw new Exception("hairTest Global B6 failed");
-    if (hairTestB7(blonde) != blonde) throw new Exception("hairTest Global B7 failed");
-    if (hairTestB8(blonde) != blonde) throw new Exception("hairTest Global B8 failed");
-    if (hairTestB9(blonde) != blonde) throw new Exception("hairTest Global B9 failed");
-    if (hairTestBA(blonde) != blonde) throw new Exception("hairTest Global BA failed");
-    if (hairTestBB(blonde) != blonde) throw new Exception("hairTest Global BB failed");
-    if (hairTestBC(blonde) != blonde) throw new Exception("hairTest Global BC failed");
-
-    if (hairTestC1(blonde) != blonde) throw new Exception("hairTest Global C1 failed");
-    if (hairTestC2(blonde) != blonde) throw new Exception("hairTest Global C2 failed");
-    if (hairTestC3(blonde) != blonde) throw new Exception("hairTest Global C3 failed");
-    if (hairTestC4(blonde) != blonde) throw new Exception("hairTest Global C4 failed");
-    if (hairTestC5(blonde) != blonde) throw new Exception("hairTest Global C5 failed");
-    if (hairTestC6(blonde) != blonde) throw new Exception("hairTest Global C6 failed");
-    if (hairTestC7(blonde) != blonde) throw new Exception("hairTest Global C7 failed");
-    if (hairTestC8(blonde) != blonde) throw new Exception("hairTest Global C8 failed");
-    if (hairTestC9(blonde) != blonde) throw new Exception("hairTest Global C9 failed");
-    if (hairTestCA(blonde) != blonde) throw new Exception("hairTest Global CA failed");
-    if (hairTestCB(blonde) != blonde) throw new Exception("hairTest Global CB failed");
-    if (hairTestCC(blonde) != blonde) throw new Exception("hairTest Global CC failed");
-  }
-  {
-    auto f = new FirStruct();
-    auto blonde = HairStruct.hair.blonde;
-
-    if (f.hairTestFir1(blonde) != blonde) throw new Exception("hairTestFir 1 failed");
-    if (f.hairTestFir2(blonde) != blonde) throw new Exception("hairTestFir 2 failed");
-    if (f.hairTestFir3(blonde) != blonde) throw new Exception("hairTestFir 3 failed");
-    if (f.hairTestFir4(blonde) != blonde) throw new Exception("hairTestFir 4 failed");
-    if (f.hairTestFir5(blonde) != blonde) throw new Exception("hairTestFir 5 failed");
-    if (f.hairTestFir6(blonde) != blonde) throw new Exception("hairTestFir 6 failed");
-    if (f.hairTestFir7(blonde) != blonde) throw new Exception("hairTestFir 7 failed");
-    if (f.hairTestFir8(blonde) != blonde) throw new Exception("hairTestFir 8 failed");
-    if (f.hairTestFir9(blonde) != blonde) throw new Exception("hairTestFir 9 failed");
-    if (f.hairTestFirA(blonde) != blonde) throw new Exception("hairTestFir A failed");
-  }
-  {
-    GlobalInstance = globalinstance2;
-    if (GlobalInstance != globalinstance2) throw new Exception("GlobalInstance 1 failed");
-
-    auto i = new Instances();
-    i.MemberInstance = Instances.memberinstance3;
-    if (i.MemberInstance != Instances.memberinstance3) throw new Exception("MemberInstance 1 failed");
-  }
-  // ignore enum item tests start
-  {
-    if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_zero) != 0) throw new Exception("ignoreATest 0 failed");
-    if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_three) != 3) throw new Exception("ignoreATest 3 failed");
-    if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_ten) != 10) throw new Exception("ignoreATest 10 failed");
-    if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_eleven) != 11) throw new Exception("ignoreATest 11 failed");
-    if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirteen) != 13) throw new Exception("ignoreATest 13 failed");
-    if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_fourteen) != 14) throw new Exception("ignoreATest 14 failed");
-    if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_twenty) != 20) throw new Exception("ignoreATest 20 failed");
-    if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirty) != 30) throw new Exception("ignoreATest 30 failed");
-    if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirty_two) != 32) throw new Exception("ignoreATest 32 failed");
-    if (cast(int)ignoreATest(IgnoreTest.IgnoreA.ignoreA_thirty_three) != 33) throw new Exception("ignoreATest 33 failed");
-  }
-  {
-    if (cast(int)ignoreBTest(IgnoreTest.IgnoreB.ignoreB_eleven) != 11) throw new Exception("ignoreBTest 11 failed");
-    if (cast(int)ignoreBTest(IgnoreTest.IgnoreB.ignoreB_twelve) != 12) throw new Exception("ignoreBTest 12 failed");
-    if (cast(int)ignoreBTest(IgnoreTest.IgnoreB.ignoreB_thirty_one) != 31) throw new Exception("ignoreBTest 31 failed");
-    if (cast(int)ignoreBTest(IgnoreTest.IgnoreB.ignoreB_thirty_two) != 32) throw new Exception("ignoreBTest 32 failed");
-    if (cast(int)ignoreBTest(IgnoreTest.IgnoreB.ignoreB_forty_one) != 41) throw new Exception("ignoreBTest 41 failed");
-    if (cast(int)ignoreBTest(IgnoreTest.IgnoreB.ignoreB_forty_two) != 42) throw new Exception("ignoreBTest 42 failed");
-  }
-  {
-    if (cast(int)ignoreCTest(IgnoreTest.IgnoreC.ignoreC_ten) != 10) throw new Exception("ignoreCTest 10 failed");
-    if (cast(int)ignoreCTest(IgnoreTest.IgnoreC.ignoreC_twelve) != 12) throw new Exception("ignoreCTest 12 failed");
-    if (cast(int)ignoreCTest(IgnoreTest.IgnoreC.ignoreC_thirty) != 30) throw new Exception("ignoreCTest 30 failed");
-    if (cast(int)ignoreCTest(IgnoreTest.IgnoreC.ignoreC_thirty_two) != 32) throw new Exception("ignoreCTest 32 failed");
-    if (cast(int)ignoreCTest(IgnoreTest.IgnoreC.ignoreC_forty) != 40) throw new Exception("ignoreCTest 40 failed");
-    if (cast(int)ignoreCTest(IgnoreTest.IgnoreC.ignoreC_forty_two) != 42) throw new Exception("ignoreCTest 42 failed");
-  }
-  {
-    if (cast(int)ignoreDTest(IgnoreTest.IgnoreD.ignoreD_twenty_one) != 21) throw new Exception("ignoreDTest 21 failed");
-    if (cast(int)ignoreDTest(IgnoreTest.IgnoreD.ignoreD_twenty_two) != 22) throw new Exception("ignoreDTest 22 failed");
-  }
-  {
-    if (cast(int)ignoreETest(IgnoreTest.IgnoreE.ignoreE_zero) != 0) throw new Exception("ignoreETest 0 failed");
-    if (cast(int)ignoreETest(IgnoreTest.IgnoreE.ignoreE_twenty_one) != 21) throw new Exception("ignoreETest 21 failed");
-    if (cast(int)ignoreETest(IgnoreTest.IgnoreE.ignoreE_twenty_two) != 22) throw new Exception("ignoreETest 22 failed");
-  }
-  // ignore enum item tests end
-  {
-    if (cast(int)repeatTest(repeat.one) != 1) throw new Exception("repeatTest 1 failed");
-    if (cast(int)repeatTest(repeat.initial) != 1) throw new Exception("repeatTest 2 failed");
-    if (cast(int)repeatTest(repeat.two) != 2) throw new Exception("repeatTest 3 failed");
-    if (cast(int)repeatTest(repeat.three) != 3) throw new Exception("repeatTest 4 failed");
-    if (cast(int)repeatTest(repeat.llast) != 3) throw new Exception("repeatTest 5 failed");
-    if (cast(int)repeatTest(repeat.end) != 3) throw new Exception("repeatTest 6 failed");
-  }
-  // different types
-  {
-    if (cast(int)differentTypesTest(DifferentTypes.typeint) != 10) throw new Exception("differentTypes 1 failed");
-    if (cast(int)differentTypesTest(DifferentTypes.typeboolfalse) != 0) throw new Exception("differentTypes 2 failed");
-    if (cast(int)differentTypesTest(DifferentTypes.typebooltrue) != 1) throw new Exception("differentTypes 3 failed");
-    if (cast(int)differentTypesTest(DifferentTypes.typebooltwo) != 2) throw new Exception("differentTypes 4 failed");
-    if (cast(int)differentTypesTest(DifferentTypes.typechar) != 'C') throw new Exception("differentTypes 5 failed");
-    if (cast(int)differentTypesTest(DifferentTypes.typedefaultint) != 'D') throw new Exception("differentTypes 6 failed");
-
-    int global_enum = global_typeint;
-    if (cast(int)globalDifferentTypesTest(global_enum) != 10) throw new Exception("global differentTypes 1 failed");
-    global_enum = global_typeboolfalse;
-    if (cast(int)globalDifferentTypesTest(global_enum) != 0) throw new Exception("global differentTypes 2 failed");
-    global_enum = global_typebooltrue;
-    if (cast(int)globalDifferentTypesTest(global_enum) != 1) throw new Exception("global differentTypes 3 failed");
-    global_enum = global_typebooltwo;
-    if (cast(int)globalDifferentTypesTest(global_enum) != 2) throw new Exception("global differentTypes 4 failed");
-    global_enum = global_typechar;
-    if (cast(int)globalDifferentTypesTest(global_enum) != 'C') throw new Exception("global differentTypes 5 failed");
-    global_enum = global_typedefaultint;
-    if (cast(int)globalDifferentTypesTest(global_enum) != 'D') throw new Exception("global differentTypes 6 failed");
-  }
-}
diff --git a/Examples/test-suite/d/inherit_target_language_runme.1.d b/Examples/test-suite/d/inherit_target_language_runme.1.d
deleted file mode 100644
index 8a13cac..0000000
--- a/Examples/test-suite/d/inherit_target_language_runme.1.d
+++ /dev/null
@@ -1,29 +0,0 @@
-module inherit_target_language_runme;
-
-import inherit_target_language.BaseX;
-import inherit_target_language.Derived1;
-import inherit_target_language.Derived2;
-import inherit_target_language.DerivedX;
-import inherit_target_language.MultipleDerived1;
-import inherit_target_language.MultipleDerived2;
-import inherit_target_language.MultipleDerived3;
-import inherit_target_language.MultipleDerived4;
-
-void main() {
-  (new Derived1()).targetLanguageBaseMethod();
-  (new Derived2()).targetLanguageBaseMethod();
-
-  (new MultipleDerived1()).targetLanguageBaseMethod();
-  (new MultipleDerived2()).targetLanguageBaseMethod();
-  (new MultipleDerived3()).f();
-  (new MultipleDerived4()).g();
-
-  auto baseX = new BaseX();
-  baseX.basex();
-  baseX.targetLanguageBase2Method();
-
-  auto derivedX = new DerivedX();
-  derivedX.basex();
-  derivedX.derivedx();
-  derivedX.targetLanguageBase2Method();
-}
diff --git a/Examples/test-suite/d/li_attribute_runme.1.d b/Examples/test-suite/d/li_attribute_runme.1.d
deleted file mode 100644
index ada3ed8..0000000
--- a/Examples/test-suite/d/li_attribute_runme.1.d
+++ /dev/null
@@ -1,75 +0,0 @@
-module li_attribute_runme;
-
-import li_attribute.A;
-import li_attribute.B;
-import li_attribute.MyClass;
-import li_attribute.MyClassVal;
-import li_attribute.MyStringyClass;
-import li_attribute.MyFoo;
-import li_attribute.Param_i;
-
-void main() {
-  auto aa = new A(1,2,3);
-
-  if (aa.a != 1)
-    throw new Exception("error");
-  aa.a = 3;
-  if (aa.a != 3)
-    throw new Exception("error");
-
-  if (aa.b != 2)
-    throw new Exception("error");
-  aa.b = 5;
-  if (aa.b != 5)
-    throw new Exception("error");
-
-  if (aa.d != aa.b)
-    throw new Exception("error");
-
-  if (aa.c != 3)
-    throw new Exception("error");
-
-  auto pi = new Param_i(7);
-  if (pi.value != 7)
-    throw new Exception("error");
-
-  pi.value=3;
-  if (pi.value != 3)
-    throw new Exception("error");
-
-  auto b = new B(aa);
-  if (b.a.c != 3)
-    throw new Exception("error");
-
-  // class/struct attribute with get/set methods using return/pass by reference
-  auto myFoo = new MyFoo();
-  myFoo.x = 8;
-  auto myClass = new MyClass();
-  myClass.Foo = myFoo;
-  if (myClass.Foo.x != 8)
-    throw new Exception("error");
-
-  // class/struct attribute with get/set methods using return/pass by value
-  auto myClassVal = new MyClassVal();
-  if (myClassVal.ReadWriteFoo.x != -1)
-    throw new Exception("error");
-  if (myClassVal.ReadOnlyFoo.x != -1)
-    throw new Exception("error");
-  myClassVal.ReadWriteFoo = myFoo;
-  if (myClassVal.ReadWriteFoo.x != 8)
-    throw new Exception("error");
-  if (myClassVal.ReadOnlyFoo.x != 8)
-    throw new Exception("error");
-
-  // string attribute with get/set methods using return/pass by value
-  auto myStringClass = new MyStringyClass("initial string");
-  if (myStringClass.ReadWriteString != "initial string")
-    throw new Exception("error");
-  if (myStringClass.ReadOnlyString != "initial string")
-    throw new Exception("error");
-  myStringClass.ReadWriteString = "changed string";
-  if (myStringClass.ReadWriteString != "changed string")
-    throw new Exception("error");
-  if (myStringClass.ReadOnlyString != "changed string")
-    throw new Exception("error");
-}
diff --git a/Examples/test-suite/d/li_boost_shared_ptr_bits_runme.1.d b/Examples/test-suite/d/li_boost_shared_ptr_bits_runme.1.d
deleted file mode 100644
index 098570b..0000000
--- a/Examples/test-suite/d/li_boost_shared_ptr_bits_runme.1.d
+++ /dev/null
@@ -1,21 +0,0 @@
-module li_boost_shared_ptr_runme_bits;
-
-import li_boost_shared_ptr_bits.li_boost_shared_ptr_bits;
-import li_boost_shared_ptr_bits.HiddenDestructor;
-import li_boost_shared_ptr_bits.IntHolder;
-import li_boost_shared_ptr_bits.VectorIntHolder;
-
-void main() {
-  auto v = new VectorIntHolder();
-  v ~= new IntHolder(11);
-  v ~= new IntHolder(22);
-  v ~= new IntHolder(33);
-
-  if (sum(v) != 66) {
-    throw new Exception("sum is wrong");
-  }
-
-  {
-    scope hidden = HiddenDestructor.create();
-  }
-}
diff --git a/Examples/test-suite/d/li_boost_shared_ptr_runme.1.d b/Examples/test-suite/d/li_boost_shared_ptr_runme.1.d
deleted file mode 100644
index ed55cd3..0000000
--- a/Examples/test-suite/d/li_boost_shared_ptr_runme.1.d
+++ /dev/null
@@ -1,604 +0,0 @@
-module li_boost_shared_ptr_runme;
-
-import tango.io.Stdout;
-import tango.core.Exception;
-import tango.core.Memory;
-import tango.core.Thread;
-import tango.text.convert.Integer;
-import li_boost_shared_ptr.li_boost_shared_ptr;
-import li_boost_shared_ptr.Klass;
-import li_boost_shared_ptr.KlassDerived;
-import li_boost_shared_ptr.Klass3rdDerived;
-import li_boost_shared_ptr.MemberVariables;
-import li_boost_shared_ptr.PairIntDouble;
-
-// Debugging flag
-const bool TRACE = false;
-
-void main() {
-  if (TRACE)
-    Stdout("---> STARTED <---").newline;
-
-  debug_shared=TRACE;
-
-  // Change loop count to run for a long time to monitor memory
-  const int LOOP_COUNT = 1; // 50000;
-  for (int i = 0; i < LOOP_COUNT; ++i) {
-    runTest();
-    GC.collect();
-  }
-
-  if (TRACE)
-    Stdout("---> NEARLY FINISHED <---").newline;
-
-  // Try to get the GC to collect everything not referenced anymore.
-  int countdown = 100;
-  while (--countdown) {
-    GC.collect();
-    if (Klass.getTotal_count() == 1)
-      break;
-    Thread.sleep(0.01);
-  }
-
-  // A single remaining instance expected: the global variable (GlobalValue).
-  if (Klass.getTotal_count() != 1)
-    throw new Exception("Klass.total_count=" ~ toString(Klass.getTotal_count()));
-
-  // A single remaining instance expected: the global variable (GlobalSmartValue).
-  int wrapper_count = shared_ptr_wrapper_count();
-  if (wrapper_count != NOT_COUNTING)
-    if (wrapper_count != 1)
-      throw new Exception("shared_ptr wrapper count=" ~ toString(wrapper_count));
-
-  if (TRACE)
-    Stdout("---> FINISHED <---").newline;
-}
-
-void runTest() {
-  // simple shared_ptr usage - created in C++
-  {
-    auto k = new Klass("me oh my");
-    char[] val = k.getValue();
-    verifyValue("me oh my", val);
-    verifyCount(1, k);
-  }
-
-  // simple shared_ptr usage - not created in C++
-  {
-    auto k = factorycreate();
-    char[] val = k.getValue();
-    verifyValue("factorycreate", val);
-    verifyCount(1, k);
-  }
-
-  // pass by shared_ptr
-  {
-    auto k = new Klass("me oh my");
-    auto kret = smartpointertest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my smartpointertest", val);
-    verifyCount(2, k);
-    verifyCount(2, kret);
-  }
-
-  // pass by shared_ptr pointer
-  {
-    auto k = new Klass("me oh my");
-    auto kret = smartpointerpointertest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my smartpointerpointertest", val);
-    verifyCount(2, k);
-    verifyCount(2, kret);
-  }
-
-  // pass by shared_ptr reference
-  {
-    auto k = new Klass("me oh my");
-    auto kret = smartpointerreftest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my smartpointerreftest", val);
-    verifyCount(2, k);
-    verifyCount(2, kret);
-  }
-
-  // pass by shared_ptr pointer reference
-  {
-    auto k = new Klass("me oh my");
-    auto kret = smartpointerpointerreftest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my smartpointerpointerreftest", val);
-    verifyCount(2, k);
-    verifyCount(2, kret);
-  }
-
-  // const pass by shared_ptr
-  {
-    auto k = new Klass("me oh my");
-    auto kret = constsmartpointertest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my", val);
-    verifyCount(2, k);
-    verifyCount(2, kret);
-  }
-
-  // const pass by shared_ptr pointer
-  {
-    auto k = new Klass("me oh my");
-    auto kret = constsmartpointerpointertest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my", val);
-    verifyCount(2, k);
-    verifyCount(2, kret);
-  }
-
-  // const pass by shared_ptr reference
-  {
-    auto k = new Klass("me oh my");
-    auto kret = constsmartpointerreftest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my", val);
-    verifyCount(2, k);
-    verifyCount(2, kret);
-  }
-
-  // pass by value
-  {
-    auto k = new Klass("me oh my");
-    auto kret = valuetest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my valuetest", val);
-    verifyCount(1, k);
-    verifyCount(1, kret);
-  }
-
-  // pass by pointer
-  {
-    auto k = new Klass("me oh my");
-    auto kret = pointertest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my pointertest", val);
-    verifyCount(1, k);
-    verifyCount(1, kret);
-  }
-
-  // pass by reference
-  {
-    auto k = new Klass("me oh my");
-    auto kret = reftest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my reftest", val);
-    verifyCount(1, k);
-    verifyCount(1, kret);
-  }
-
-  // pass by pointer reference
-  {
-    auto k = new Klass("me oh my");
-    auto kret = pointerreftest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my pointerreftest", val);
-    verifyCount(1, k);
-    verifyCount(1, kret);
-  }
-
-  // null tests
-  {
-    Klass k = null;
-
-    // TODO: add in const versions too
-    if (smartpointertest(k) !is null)
-      throw new Exception("return was not null");
-
-    if (smartpointerpointertest(k) !is null)
-      throw new Exception("return was not null");
-
-    if (smartpointerreftest(k) !is null)
-      throw new Exception("return was not null");
-
-    if (smartpointerpointerreftest(k) !is null)
-      throw new Exception("return was not null");
-
-    if (nullsmartpointerpointertest(null) != "null pointer")
-      throw new Exception("not null smartpointer pointer");
-
-    try { valuetest(k); throw new Exception("Failed to catch null pointer"); } catch (IllegalArgumentException) {}
-
-    if (pointertest(k) !is null)
-      throw new Exception("return was not null");
-
-    try { reftest(k); throw new Exception("Failed to catch null pointer"); } catch (IllegalArgumentException) {}
-  }
-
-  // $owner
-  {
-    auto k = pointerownertest();
-    char[] val = k.getValue();
-    verifyValue("pointerownertest", val);
-    verifyCount(1, k);
-  }
-  {
-    auto k = smartpointerpointerownertest();
-    char[] val = k.getValue();
-    verifyValue("smartpointerpointerownertest", val);
-    verifyCount(1, k);
-  }
-
-  ////////////////////////////////// Derived classes ////////////////////////////////////////
-  // derived pass by shared_ptr
-  {
-    auto k = new KlassDerived("me oh my");
-    auto kret = derivedsmartptrtest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my derivedsmartptrtest-Derived", val);
-    verifyCount(4, k); // includes two extra references for upcasts in the proxy classes
-    verifyCount(4, kret);
-  }
-  // derived pass by shared_ptr pointer
-  {
-    auto k = new KlassDerived("me oh my");
-    auto kret = derivedsmartptrpointertest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my derivedsmartptrpointertest-Derived", val);
-    verifyCount(4, k); // includes two extra references for upcasts in the proxy classes
-    verifyCount(4, kret);
-  }
-  // derived pass by shared_ptr ref
-  {
-    auto k = new KlassDerived("me oh my");
-    auto kret = derivedsmartptrreftest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my derivedsmartptrreftest-Derived", val);
-    verifyCount(4, k); // includes two extra references for upcasts in the proxy classes
-    verifyCount(4, kret);
-  }
-  // derived pass by shared_ptr pointer ref
-  {
-    auto k = new KlassDerived("me oh my");
-    auto kret = derivedsmartptrpointerreftest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my derivedsmartptrpointerreftest-Derived", val);
-    verifyCount(4, k); // includes two extra references for upcasts in the proxy classes
-    verifyCount(4, kret);
-  }
-  // derived pass by pointer
-  {
-    auto k = new KlassDerived("me oh my");
-    auto kret = derivedpointertest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my derivedpointertest-Derived", val);
-    verifyCount(2, k); // includes an extra reference for the upcast in the proxy class
-    verifyCount(2, kret);
-  }
-  // derived pass by ref
-  {
-    auto k = new KlassDerived("me oh my");
-    auto kret = derivedreftest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my derivedreftest-Derived", val);
-    verifyCount(2, k); // includes an extra reference for the upcast in the proxy class
-    verifyCount(2, kret);
-  }
-
-  ////////////////////////////////// Derived and base class mixed ////////////////////////////////////////
-  // pass by shared_ptr (mixed)
-  {
-    auto k = new KlassDerived("me oh my");
-    auto kret = smartpointertest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my smartpointertest-Derived", val);
-    verifyCount(3, k); // an extra reference for the upcast in the proxy class
-    verifyCount(3, kret);
-  }
-
-  // pass by shared_ptr pointer (mixed)
-  {
-    auto k = new KlassDerived("me oh my");
-    auto kret = smartpointerpointertest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my smartpointerpointertest-Derived", val);
-    verifyCount(3, k); // an extra reference for the upcast in the proxy class
-    verifyCount(3, kret);
-  }
-
-  // pass by shared_ptr reference (mixed)
-  {
-    auto k = new KlassDerived("me oh my");
-    auto kret = smartpointerreftest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my smartpointerreftest-Derived", val);
-    verifyCount(3, k); // an extra reference for the upcast in the proxy class
-    verifyCount(3, kret);
-  }
-
-  // pass by shared_ptr pointer reference (mixed)
-  {
-    auto k = new KlassDerived("me oh my");
-    auto kret = smartpointerpointerreftest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my smartpointerpointerreftest-Derived", val);
-    verifyCount(3, k); // an extra reference for the upcast in the proxy class
-    verifyCount(3, kret);
-  }
-
-  // pass by value (mixed)
-  {
-    auto k = new KlassDerived("me oh my");
-    auto kret = valuetest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my valuetest", val); // note slicing
-    verifyCount(2, k); // an extra reference for the upcast in the proxy class
-    verifyCount(1, kret);
-  }
-
-  // pass by pointer (mixed)
-  {
-    auto k = new KlassDerived("me oh my");
-    auto kret = pointertest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my pointertest-Derived", val);
-    verifyCount(2, k); // an extra reference for the upcast in the proxy class
-    verifyCount(1, kret);
-  }
-
-  // pass by ref (mixed)
-  {
-    auto k = new KlassDerived("me oh my");
-    auto kret = reftest(k);
-    char[] val = kret.getValue();
-    verifyValue("me oh my reftest-Derived", val);
-    verifyCount(2, k); // an extra reference for the upcast in the proxy class
-    verifyCount(1, kret);
-  }
-
-  // 3rd derived class
-  {
-    auto k = new Klass3rdDerived("me oh my");
-    char[] val = k.getValue();
-    verifyValue("me oh my-3rdDerived", val);
-    verifyCount(3, k); // 3 classes in inheritance chain == 3 swigCPtr values
-    val = test3rdupcast(k);
-    verifyValue("me oh my-3rdDerived", val);
-    verifyCount(3, k);
-  }
-
-  ////////////////////////////////// Member variables ////////////////////////////////////////
-  // smart pointer by value
-  {
-    auto m = new MemberVariables();
-    auto k = new Klass("smart member value");
-    m.SmartMemberValue = k;
-    char[] val = k.getValue();
-    verifyValue("smart member value", val);
-    verifyCount(2, k);
-
-    auto kmember = m.SmartMemberValue;
-    val = kmember.getValue();
-    verifyValue("smart member value", val);
-    verifyCount(3, kmember);
-    verifyCount(3, k);
-
-    delete m;
-
-    verifyCount(2, kmember);
-    verifyCount(2, k);
-  }
-  // smart pointer by pointer
-  {
-    auto m = new MemberVariables();
-    auto k = new Klass("smart member pointer");
-    m.SmartMemberPointer = k;
-    char[] val = k.getValue();
-    verifyValue("smart member pointer", val);
-    verifyCount(1, k);
-
-    auto kmember = m.SmartMemberPointer;
-    val = kmember.getValue();
-    verifyValue("smart member pointer", val);
-    verifyCount(2, kmember);
-    verifyCount(2, k);
-
-    delete m;
-
-    verifyCount(2, kmember);
-    verifyCount(2, k);
-  }
-  // smart pointer by reference
-  {
-    auto m = new MemberVariables();
-    auto k = new Klass("smart member reference");
-    m.SmartMemberReference = k;
-    char[] val = k.getValue();
-    verifyValue("smart member reference", val);
-    verifyCount(2, k);
-
-    auto kmember = m.SmartMemberReference;
-    val = kmember.getValue();
-    verifyValue("smart member reference", val);
-    verifyCount(3, kmember);
-    verifyCount(3, k);
-
-    // The C++ reference refers to SmartMemberValue...
-    auto kmemberVal = m.SmartMemberValue;
-    val = kmember.getValue();
-    verifyValue("smart member reference", val);
-    verifyCount(4, kmemberVal);
-    verifyCount(4, kmember);
-    verifyCount(4, k);
-
-    delete m;
-
-    verifyCount(3, kmember);
-    verifyCount(3, k);
-  }
-  // plain by value
-  {
-    auto m = new MemberVariables();
-    auto k = new Klass("plain member value");
-    m.MemberValue = k;
-    char[] val = k.getValue();
-    verifyValue("plain member value", val);
-    verifyCount(1, k);
-
-    auto kmember = m.MemberValue;
-    val = kmember.getValue();
-    verifyValue("plain member value", val);
-    verifyCount(1, kmember);
-    verifyCount(1, k);
-
-    delete m;
-
-    verifyCount(1, kmember);
-    verifyCount(1, k);
-  }
-  // plain by pointer
-  {
-    auto m = new MemberVariables();
-    auto k = new Klass("plain member pointer");
-    m.MemberPointer = k;
-    char[] val = k.getValue();
-    verifyValue("plain member pointer", val);
-    verifyCount(1, k);
-
-    auto kmember = m.MemberPointer;
-    val = kmember.getValue();
-    verifyValue("plain member pointer", val);
-    verifyCount(1, kmember);
-    verifyCount(1, k);
-
-    delete m;
-
-    verifyCount(1, kmember);
-    verifyCount(1, k);
-  }
-  // plain by reference
-  {
-    auto m = new MemberVariables();
-    auto k = new Klass("plain member reference");
-    m.MemberReference = k;
-    char[] val = k.getValue();
-    verifyValue("plain member reference", val);
-    verifyCount(1, k);
-
-    auto kmember = m.MemberReference;
-    val = kmember.getValue();
-    verifyValue("plain member reference", val);
-    verifyCount(1, kmember);
-    verifyCount(1, k);
-
-    delete m;
-
-    verifyCount(1, kmember);
-    verifyCount(1, k);
-  }
-
-  // null member variables
-  {
-    auto m = new MemberVariables();
-
-    // shared_ptr by value
-    auto k = m.SmartMemberValue;
-    if (k !is null)
-      throw new Exception("expected null");
-    m.SmartMemberValue = null;
-    k = m.SmartMemberValue;
-    if (k !is null)
-      throw new Exception("expected null");
-    verifyCount(0, k);
-
-    // plain by value
-    try { m.MemberValue = null; throw new Exception("Failed to catch null pointer"); } catch (IllegalArgumentException) {}
-  }
-
-  ////////////////////////////////// Global variables ////////////////////////////////////////
-  // smart pointer
-  {
-    auto kglobal = GlobalSmartValue;
-    if (kglobal !is null)
-      throw new Exception("expected null");
-
-    auto k = new Klass("smart global value");
-    GlobalSmartValue = k;
-    verifyCount(2, k);
-
-    kglobal = GlobalSmartValue;
-    char[] val = kglobal.getValue();
-    verifyValue("smart global value", val);
-    verifyCount(3, kglobal);
-    verifyCount(3, k);
-    verifyValue("smart global value", GlobalSmartValue.getValue());
-    GlobalSmartValue = null;
-  }
-  // plain value
-  {
-    Klass kglobal;
-
-    auto k = new Klass("global value");
-    GlobalValue = k;
-    verifyCount(1, k);
-
-    kglobal = GlobalValue;
-    char[] val = kglobal.getValue();
-    verifyValue("global value", val);
-    verifyCount(1, kglobal);
-    verifyCount(1, k);
-    verifyValue("global value", GlobalValue.getValue());
-
-    try { GlobalValue = null; throw new Exception("Failed to catch null pointer"); } catch (IllegalArgumentException) {}
-  }
-  // plain pointer
-  {
-    auto kglobal = GlobalPointer;
-    if (kglobal !is null)
-      throw new Exception("expected null");
-
-    auto k = new Klass("global pointer");
-    GlobalPointer = k;
-    verifyCount(1, k);
-
-    kglobal = GlobalPointer;
-    char[] val = kglobal.getValue();
-    verifyValue("global pointer", val);
-    verifyCount(1, kglobal);
-    verifyCount(1, k);
-    GlobalPointer = null;
-  }
-  // plain reference
-  {
-    Klass kglobal;
-
-    auto k = new Klass("global reference");
-    GlobalReference = k;
-    verifyCount(1, k);
-
-    kglobal = GlobalReference;
-    char[] val = kglobal.getValue();
-    verifyValue("global reference", val);
-    verifyCount(1, kglobal);
-    verifyCount(1, k);
-
-    try { GlobalReference = null; throw new Exception("Failed to catch null pointer"); } catch (IllegalArgumentException) {}
-  }
-
-  ////////////////////////////////// Templates ////////////////////////////////////////
-  {
-    PairIntDouble pid = new PairIntDouble(10, 20.2);
-    if (pid.baseVal1 != 20 || pid.baseVal2 != 40.4)
-      throw new Exception("Base values wrong");
-    if (pid.val1 != 10 || pid.val2 != 20.2)
-      throw new Exception("Derived Values wrong");
-  }
-}
-
-private void verifyValue(char[] expected, char[] got) {
-  if (expected != got)
-    throw new Exception("verify value failed. Expected: " ~ expected ~ " Got: " ~ got);
-}
-
-private void verifyCount(int expected, Klass k) {
-  // We deliberately call the use_count(Klass) overload also for objects which
-  // are instances of a subclass of Klass (due to static dispatch); things still
-  // have to work.
-  int got = use_count(k);
-  if (expected != got)
-    throw new Exception("verify use_count failed. Expected: " ~ toString(expected) ~ " Got: " ~ toString(got));
-}
diff --git a/Examples/test-suite/d/li_boost_shared_ptr_runme.2.d b/Examples/test-suite/d/li_boost_shared_ptr_runme.2.d
index 0289295..baae905 100644
--- a/Examples/test-suite/d/li_boost_shared_ptr_runme.2.d
+++ b/Examples/test-suite/d/li_boost_shared_ptr_runme.2.d
@@ -32,9 +32,22 @@
   if (TRACE)
     writeln("---> NEARLY FINISHED <---");
 
-  // A single remaining instance expected: the global variable (GlobalValue).
-  if (Klass.getTotal_count() != 1)
-    throw new Exception("Klass.total_count=" ~ to!string(Klass.getTotal_count()));
+  static if (is(typeof(GC.inFinalizer))) {
+    version(LDC) {
+      /* LDC on Ubuntu have a bug with `GC.inFinalizer`.
+       * So simply skip it. */
+    } else {
+      while(GC.inFinalizer) {
+        GC.collect();
+        // sleep for 50 milliseconds
+        Thread.sleep( dur!("msecs")( 50 ) );
+      }
+
+      // A single remaining instance expected: the global variable (GlobalValue).
+      if (Klass.getTotal_count() != 1)
+        throw new Exception("Klass.total_count=" ~ to!string(Klass.getTotal_count()));
+    }
+  }
 
   // A single remaining instance expected: the global variable (GlobalSmartValue).
   int wrapper_count = shared_ptr_wrapper_count();
diff --git a/Examples/test-suite/d/li_constraints_runme.2.d b/Examples/test-suite/d/li_constraints_runme.2.d
new file mode 100644
index 0000000..2a2bf65
--- /dev/null
+++ b/Examples/test-suite/d/li_constraints_runme.2.d
@@ -0,0 +1,56 @@
+module li_constraints_runme;
+
+import std.array;
+import std.algorithm;
+import std.exception;
+import li_constraints.li_constraints;
+
+void check_double(bool except, void function(double) f, double val, string name) {
+  bool actual = true;
+  bool proper = true;
+  try {
+    f(val);
+  } catch(Exception e) {
+    actual = false;
+    proper = e.msg.equal(join(["Expected a ", name, " value."]));
+  }
+  enforce(actual == except);
+  enforce(proper);
+}
+void check_pointer(bool except, void function(void*) f, void* val) {
+  bool actual = true;
+  bool proper = true;
+  try {
+    f(val);
+  } catch(Exception e) {
+    actual = false;
+    proper = e.msg.equal("Received a NULL pointer.");
+  }
+  enforce(actual == except);
+  enforce(proper);
+}
+
+void main() {
+  check_double(true, &test_nonnegative, 10, "non-negative");
+  check_double(true, &test_nonnegative, 0, "non-negative");
+  check_double(false, &test_nonnegative, -10, "non-negative");
+
+  check_double(false, &test_nonpositive, 10, "non-positive");
+  check_double(true, &test_nonpositive, 0, "non-positive");
+  check_double(true, &test_nonpositive, -10, "non-positive");
+
+  check_double(true, &test_positive, 10, "positive");
+  check_double(false, &test_positive, 0, "positive");
+  check_double(false, &test_positive, -10, "positive");
+
+  check_double(false, &test_negative, 10, "negative");
+  check_double(false, &test_negative, 0, "negative");
+  check_double(true, &test_negative, -10, "negative");
+
+  check_double(true, &test_nonzero, 10, "nonzero");
+  check_double(false, &test_nonzero, 0, "nonzero");
+  check_double(true, &test_nonzero, -10, "nonzero");
+
+  check_pointer(false, &test_nonnull, null);
+  check_pointer(true, &test_nonnull, get_nonnull());
+}
diff --git a/Examples/test-suite/d/li_std_auto_ptr_runme.2.d b/Examples/test-suite/d/li_std_auto_ptr_runme.2.d
new file mode 100644
index 0000000..86fac68
--- /dev/null
+++ b/Examples/test-suite/d/li_std_auto_ptr_runme.2.d
@@ -0,0 +1,123 @@
+module li_std_auto_ptr_runme;
+
+import li_std_auto_ptr.li_std_auto_ptr;
+import li_std_auto_ptr.Klass;
+import li_std_auto_ptr.KlassInheritance;
+import std.conv;
+import std.algorithm;
+
+void checkCount(int expected_count) {
+  int actual_count = Klass.getTotal_count();
+  if (actual_count != expected_count)
+    throw new Exception("Counts incorrect, expected:" ~ to!string(expected_count) ~ " actual:" ~ to!string(actual_count));
+}
+
+void main() {
+  // Test raw pointer handling involving virtual inheritance
+  {
+    scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+    checkCount(1);
+    string s = useKlassRawPtr(kini);
+    if (s != "KlassInheritanceInput")
+      throw new Exception("Incorrect string: " ~ s);
+  }
+  checkCount(0);
+
+  // auto_ptr as input
+  {
+    scope Klass kin = new Klass("KlassInput");
+    checkCount(1);
+    string s = takeKlassAutoPtr(kin);
+    checkCount(0);
+    if (s != "KlassInput")
+      throw new Exception("Incorrect string: " ~ s);
+    if (!is_nullptr(kin))
+      throw new Exception("is_nullptr failed");
+  } // dispose should not fail, even though already deleted
+  checkCount(0);
+
+  {
+    scope Klass kin = new Klass("KlassInput");
+    checkCount(1);
+    string s = takeKlassAutoPtr(kin);
+    checkCount(0);
+    if (s != "KlassInput")
+      throw new Exception("Incorrect string: " ~ s);
+    if (!is_nullptr(kin))
+      throw new Exception("is_nullptr failed");
+    bool exception_thrown = false;
+    try {
+      takeKlassAutoPtr(kin);
+    } catch (Exception e) {
+      if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
+        throw new Exception("incorrect exception message: " ~ e.msg);
+      exception_thrown = true;
+    }
+    if (!exception_thrown)
+      throw new Exception("double usage of takeKlassAutoPtr should have been an error");
+  } // dispose should not fail, even though already deleted
+  checkCount(0);
+
+  {
+    scope Klass kin = new Klass("KlassInput");
+    bool exception_thrown = false;
+    Klass notowned = get_not_owned_ptr(kin);
+    try {
+      takeKlassAutoPtr(notowned);
+    } catch (Exception e) {
+      if (!canFind(e.msg, "Cannot release ownership as memory is not owned"))
+        throw new Exception("incorrect exception message: " ~ e.msg);
+      exception_thrown = true;
+    }
+    if (!exception_thrown)
+      throw new Exception("Should have thrown 'Cannot release ownership as memory is not owned' error");
+    checkCount(1);
+  }
+  checkCount(0);
+
+  {
+    scope KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+    checkCount(1);
+    string s = takeKlassAutoPtr(kini);
+    checkCount(0);
+    if (s != "KlassInheritanceInput")
+      throw new Exception("Incorrect string: " ~ s);
+    if (!is_nullptr(kini))
+      throw new Exception("is_nullptr failed");
+  } // dispose should not fail, even though already deleted
+  checkCount(0);
+
+  takeKlassAutoPtr(null);
+  takeKlassAutoPtr(make_null());
+  checkCount(0);
+
+  // overloaded parameters
+  if (overloadTest() != 0)
+    throw new Exception("overloadTest failed");
+  if (overloadTest(null) != 1)
+    throw new Exception("overloadTest failed");
+  if (overloadTest(new Klass("over")) != 1)
+    throw new Exception("overloadTest failed");
+  checkCount(0);
+
+
+  // auto_ptr as output
+  Klass k1 = makeKlassAutoPtr("first");
+  if (k1.getLabel() != "first")
+    throw new Exception("wrong object label");
+
+  Klass k2 = makeKlassAutoPtr("second");
+  checkCount(2);
+
+  k1.dispose();
+  checkCount(1);
+
+  if (k2.getLabel() != "second")
+      throw new Exception("wrong object label");
+
+  k2.dispose();
+  checkCount(0);
+
+  if (makeNullAutoPtr() !is null)
+    throw new Exception("null failure");
+}
diff --git a/Examples/test-suite/d/li_std_except_runme.1.d b/Examples/test-suite/d/li_std_except_runme.1.d
deleted file mode 100644
index 39f3bb2..0000000
--- a/Examples/test-suite/d/li_std_except_runme.1.d
+++ /dev/null
@@ -1,40 +0,0 @@
-module li_std_except_runme;
-
-import tango.core.Exception;
-import tango.io.Console;
-import li_std_except.Test;
-
-void main() {
-  with (new Test()) {
-    mixin(test("Exception", "throw_bad_exception"));
-    mixin(test("Exception", "throw_domain_error"));
-    mixin(test("Exception", "throw_exception"));
-    mixin(test("IllegalArgumentException", "throw_invalid_argument"));
-    mixin(test("NoSuchElementException", "throw_length_error"));
-    mixin(test("Exception", "throw_logic_error"));
-    mixin(test("NoSuchElementException", "throw_out_of_range"));
-    mixin(test("Exception", "throw_overflow_error"));
-    mixin(test("Exception", "throw_range_error"));
-    mixin(test("Exception", "throw_runtime_error"));
-    mixin(test("Exception", "throw_underflow_error"));
-  }
-}
-
-char[] test(char[] e, char[] f) {
-  return "if (!works!(" ~ e ~ ")(&" ~ f ~ ")) {\n" ~
-    "throw new Exception(\"" ~ f ~ " failed\");\n" ~
-  "}";
-}
-
-bool works(alias E, F)(F f) {
-  try {
-    try {
-      f();
-    } catch(E) {
-      return true;
-    }
-  } catch(Exception e) {
-    Cerr( "Received wrong exception: " ~ e.classinfo.name ).newline;
-  }
-  return false;
-}
diff --git a/Examples/test-suite/d/li_std_string_runme.1.d b/Examples/test-suite/d/li_std_string_runme.1.d
deleted file mode 100644
index b5bbb51..0000000
--- a/Examples/test-suite/d/li_std_string_runme.1.d
+++ /dev/null
@@ -1,97 +0,0 @@
-module li_std_string_runme;
-
-import tango.core.Exception;
-import li_std_string.li_std_string;
-import li_std_string.Structure;
-import li_std_string.SWIGTYPE_p_std__string;
-
-
-void main() {
-  // Checking expected use of %typemap(in) std::string {}
-  test_value("Fee");
-
-  // Checking expected result of %typemap(out) std::string {}
-  if (test_value("Fi") != "Fi")
-      throw new Exception("Test 1 failed");
-
-  // Verify type-checking for %typemap(in) std::string {}
-  try {
-      test_value(null);
-      throw new Exception("Test 2 failed");
-  } catch (IllegalArgumentException) {
-  }
-
-  // Checking expected use of %typemap(in) const std::string & {}
-  test_const_reference("Fo");
-
-  // Checking expected result of %typemap(out) const std::string& {}
-  if (test_const_reference("Fum") != "Fum")
-      throw new Exception("Test 3 failed");
-
-  // Verify type-checking for %typemap(in) const std::string & {}
-  try {
-      test_const_reference(null);
-      throw new Exception("Test 4 failed");
-  } catch (IllegalArgumentException) {
-  }
-
-  // Input and output typemaps for pointers and non-const references to
-  // std::string are *not* supported; the following tests confirm
-  // that none of these cases are slipping through.
-
-  SWIGTYPE_p_std__string stringPtr = null;
-
-  stringPtr = test_pointer_out();
-  test_pointer(stringPtr);
-
-  stringPtr = test_const_pointer_out();
-  test_const_pointer(stringPtr);
-
-  stringPtr = test_reference_out();
-  test_reference(stringPtr);
-
-  // Check throw exception specification
-  try {
-      test_throw();
-      throw new Exception("test 5 failed!");
-  } catch (Exception e) {
-    if (e.msg != "test_throw message")
-      throw new Exception("Test 5 string check: " ~ e.msg);
-  }
-  try {
-      test_const_reference_throw();
-      throw new Exception("test 6 failed!");
-  } catch (Exception e) {
-    if (e.msg != "test_const_reference_throw message")
-      throw new Exception("Test 6 string check: " ~ e.msg);
-  }
-
-  // Global variables.
-  const char[] s = "initial string";
-  if (GlobalString2 != "global string 2")
-    throw new Exception("GlobalString2 test 1");
-  GlobalString2 = s;
-  if (GlobalString2 != s)
-    throw new Exception("GlobalString2 test 2");
-  if (ConstGlobalString != "const global string")
-    throw new Exception("ConstGlobalString test");
-
-  // Member variables.
-  auto myStructure = new Structure();
-  if (myStructure.MemberString2 != "member string 2")
-    throw new Exception("MemberString2 test 1");
-  myStructure.MemberString2 = s;
-  if (myStructure.MemberString2 != s)
-    throw new Exception("MemberString2 test 2");
-  if (myStructure.ConstMemberString != "const member string")
-    throw new Exception("ConstMemberString test");
-
-  // Static member variables.
-  if (Structure.StaticMemberString2 != "static member string 2")
-    throw new Exception("StaticMemberString2 test 1");
-  Structure.StaticMemberString2 = s;
-  if (Structure.StaticMemberString2 != s)
-    throw new Exception("StaticMemberString2 test 2");
-  if (Structure.ConstStaticMemberString != "const static member string")
-    throw new Exception("ConstStaticMemberString test");
-}
diff --git a/Examples/test-suite/d/li_std_string_runme.2.d b/Examples/test-suite/d/li_std_string_runme.2.d
index 395c2f7..f0d0fa8 100644
--- a/Examples/test-suite/d/li_std_string_runme.2.d
+++ b/Examples/test-suite/d/li_std_string_runme.2.d
@@ -72,6 +72,13 @@
   Structure.StaticMemberString2 = s;
   enforce(Structure.StaticMemberString2 == s, "StaticMemberString2 test 2");
   enforce(Structure.ConstStaticMemberString == "const static member string", "ConstStaticMemberString test");
+
+  enforce(stdstring_empty() == "", "stdstring_empty test");
+  enforce(c_empty() == "", "c_empty test");
+  enforce(c_null() == null, "c_null test");
+  enforce(get_null(c_null()) == null, "get_null c_null test");
+  enforce(get_null(c_empty()) == null, "get_null c_empty test");
+  enforce(get_null(stdstring_empty()) == null, "get_null stdstring_empty test");
 }
 
 private void enforceThrows(void delegate() dg, string errorMessage) {
diff --git a/Examples/test-suite/d/li_std_vector_runme.1.d b/Examples/test-suite/d/li_std_vector_runme.1.d
deleted file mode 100644
index 895fb45..0000000
--- a/Examples/test-suite/d/li_std_vector_runme.1.d
+++ /dev/null
@@ -1,219 +0,0 @@
-module li_std_vector_runme;
-
-import tango.core.Exception;
-import tango.io.Stdout;
-import Integer = tango.text.convert.Integer;
-import li_std_vector.li_std_vector;
-import li_std_vector.DoubleVector;
-import li_std_vector.IntVector;
-import li_std_vector.IntPtrVector;
-import li_std_vector.IntConstPtrVector;
-import li_std_vector.RealVector;
-import li_std_vector.Struct;
-import li_std_vector.StructVector;
-import li_std_vector.StructPtrVector;
-import li_std_vector.StructConstPtrVector;
-
-const size_t SIZE = 20;
-
-void main() {
-  // Basic functionality tests.
-  {
-    auto vector = new IntVector();
-    for (size_t i = 0; i < SIZE; ++i) {
-      vector ~= i * 10;
-    }
-
-    if (vector.length != SIZE) {
-      throw new Exception("length test failed.");
-    }
-
-    vector[0] = 200;
-    if (vector[0] != 200) {
-      throw new Exception("indexing test failed");
-    }
-    vector[0] = 0 * 10;
-
-    try {
-      vector[vector.length] = 777;
-      throw new Exception("out of range test failed");
-    } catch (NoSuchElementException) {
-    }
-
-    foreach (i, value; vector) {
-      if (value != (i * 10)) {
-	throw new Exception("foreach test failed, i: " ~ Integer.toString(i));
-      }
-    }
-
-    vector.clear();
-    if (vector.size != 0) {
-      throw new Exception("clear test failed");
-    }
-  }
-
-  // Slice tests.
-  {
-    auto dVector = new DoubleVector();
-    for (size_t i = 0; i < SIZE; ++i) {
-      dVector ~= i * 10.1f;
-    }
-
-    double[] dArray = dVector[];
-    foreach (i, value; dArray) {
-      if (dVector[i] != value) {
-	throw new Exception("slice test 1 failed, i: " ~ Integer.toString(i));
-      }
-    }
-
-
-    auto sVector = new StructVector();
-    for (size_t i = 0; i < SIZE; i++) {
-      sVector ~= new Struct(i / 10.0);
-    }
-
-    Struct[] array = sVector[];
-
-    for (size_t i = 0; i < SIZE; i++) {
-      // Make sure that a shallow copy has been made.
-      void* aPtr = Struct.swigGetCPtr(array[i]);
-      void* vPtr = Struct.swigGetCPtr(sVector[i]);
-      if (aPtr != vPtr) {
-	throw new Exception("slice test 2 failed, i: " ~
-	  Integer.toString(i));
-      }
-    }
-  }
-
-  // remove() tests.
-  {
-    auto iVector = new IntVector();
-    for (int i = 0; i < SIZE; i++) {
-      iVector ~= i;
-    }
-
-    iVector.remove(iVector.length - 1);
-    iVector.remove(SIZE / 2);
-    iVector.remove(0);
-
-    try {
-      iVector.remove(iVector.size);
-      throw new Exception("remove test failed");
-    } catch (NoSuchElementException) {
-    }
-  }
-
-  // Capacity tests.
-  {
-    auto dv = new DoubleVector(10);
-    if ((dv.capacity != 10) || (dv.length != 0)) {
-      throw new Exception("constructor setting capacity test failed");
-    }
-
-    // TODO: Is this really required (and spec'ed) behavior?
-    dv.capacity = 20;
-    if (dv.capacity != 20) {
-      throw new Exception("capacity test 1 failed");
-    }
-
-    dv ~= 1.11;
-    try {
-      dv.capacity = dv.length - 1;
-      throw new Exception("capacity test 2 failed");
-    } catch (IllegalArgumentException) {
-    }
-  }
-
-  // Test the methods being wrapped.
-  {
-    auto iv = new IntVector();
-    for (int i=0; i<4; i++) {
-      iv ~= i;
-    }
-
-    double x = average(iv);
-    x += average(new IntVector([1, 2, 3, 4]));
-    RealVector rv = half(new RealVector([10.0f, 10.5f, 11.0f, 11.5f]));
-
-    auto dv = new DoubleVector();
-    for (size_t i = 0; i < SIZE; i++) {
-      dv ~= i / 2.0;
-    }
-    halve_in_place(dv);
-
-    RealVector v0 = vecreal(new RealVector());
-    float flo = 123.456f;
-    v0 ~= flo;
-    flo = v0[0];
-
-    IntVector v1 = vecintptr(new IntVector());
-    IntPtrVector v2 = vecintptr(new IntPtrVector());
-    IntConstPtrVector v3 = vecintconstptr(new IntConstPtrVector());
-
-    v1 ~= 123;
-    v2.clear();
-    v3.clear();
-
-    StructVector v4 = vecstruct(new StructVector());
-    StructPtrVector v5 = vecstructptr(new StructPtrVector());
-    StructConstPtrVector v6 = vecstructconstptr(new StructConstPtrVector());
-
-    v4 ~= new Struct(123);
-    v5 ~= new Struct(123);
-    v6 ~= new Struct(123);
-  }
-
-  // Test vectors of pointers.
-  {
-    auto vector = new StructPtrVector();
-    for (size_t i = 0; i < SIZE; i++) {
-      vector ~= new Struct(i / 10.0);
-    }
-
-    Struct[] array = vector[];
-
-    for (size_t i = 0; i < SIZE; i++) {
-      // Make sure that a shallow copy has been made.
-      void* aPtr = Struct.swigGetCPtr(array[i]);
-      void* vPtr = Struct.swigGetCPtr(vector[i]);
-      if (aPtr != vPtr) {
-	throw new Exception("StructPtrVector test 1 failed, i: " ~
-	  Integer.toString(i));
-      }
-    }
-  }
-
-  // Test vectors of const pointers.
-  {
-    auto vector = new StructConstPtrVector();
-    for (size_t i = 0; i < SIZE; i++) {
-      vector ~= new Struct(i / 10.0);
-    }
-
-    Struct[] array = vector[];
-
-    for (size_t i = 0; i < SIZE; i++) {
-      // Make sure that a shallow copy has been made.
-      void* aPtr = Struct.swigGetCPtr(array[i]);
-      void* vPtr = Struct.swigGetCPtr(vector[i]);
-      if (aPtr != vPtr) {
-	throw new Exception("StructConstPtrVector test 1 failed, i: " ~
-	  Integer.toString(i));
-      }
-    }
-  }
-
-  // Test vectors destroyed via dispose().
-  {
-    {
-      scope vector = new StructVector();
-      vector ~= new Struct(0.0);
-      vector ~= new Struct(11.1);
-    }
-    {
-      scope vector = new DoubleVector();
-      vector ~= 0.0;
-      vector ~= 11.1;
-    }
-  }
-}
diff --git a/Examples/test-suite/d/li_std_vector_runme.2.d b/Examples/test-suite/d/li_std_vector_runme.2.d
index f4a6667..3f97062 100644
--- a/Examples/test-suite/d/li_std_vector_runme.2.d
+++ b/Examples/test-suite/d/li_std_vector_runme.2.d
@@ -47,7 +47,7 @@
       enforce(countUntil(vector[], i * 10) == i, "indexOf test failed, i: " ~ to!string(i));
     }
 
-    enforce(countUntil(vector[], 42) == -1, "non-existant item indexOf test failed");
+    enforce(countUntil(vector[], 42) == -1, "non-existent item indexOf test failed");
 
     vector.clear();
     enforce(vector.length == 0, "clear test failed");
diff --git a/Examples/test-suite/d/li_typemaps_runme.1.d b/Examples/test-suite/d/li_typemaps_runme.1.d
deleted file mode 100644
index e37b12b..0000000
--- a/Examples/test-suite/d/li_typemaps_runme.1.d
+++ /dev/null
@@ -1,94 +0,0 @@
-/// Tests correct handling of a few INPUT/OUTPUT/INOUT-typemapped functions.
-module li_typemaps_runme;
-
-import li_typemaps.li_typemaps;
-
-void main() {
-  // Check double INPUT typemaps
-  if (in_double(22.22) != 22.22) raiseError("in_double");
-  if (inr_double(22.22) != 22.22) raiseError("inr_double");
-
-  // Check double OUTPUT typemaps
-  {
-    double var = 44.44;
-    out_double(22.22, var);
-    if (var != 22.22) raiseError("out_double");
-  }
-  {
-    double var = 44.44;
-    outr_double(22.22, var);
-    if (var != 22.22) raiseError("outr_double");
-  }
-
-  // Check double INOUT typemaps
-  {
-    double var = 44.44;
-    inout_double(var);
-    if (var != 44.44) raiseError("inout_double");
-  }
-  {
-    double var = 44.44;
-    inoutr_double(var);
-    if (var != 44.44) raiseError("inoutr_double");
-  }
-
-  // Check unsigned long long INPUT typemaps
-  if (in_ulonglong(20) != 20) raiseError("in_ulonglong");
-  if (inr_ulonglong(20) != 20) raiseError("inr_ulonglong");
-
-  // Check unsigned long long OUTPUT typemaps
-  {
-    ulong var = 40;
-    out_ulonglong(20, var);
-    if (var != 20) raiseError("out_ulonglong");
-  }
-  {
-    ulong var = 40;
-    outr_ulonglong(20, var);
-    if (var != 20) raiseError("outr_ulonglong");
-  }
-
-  // Check unsigned long long INOUT typemaps
-  {
-    ulong var = 40;
-    inout_ulonglong(var);
-    if (var != 40) raiseError("inout_ulonglong");
-  }
-  {
-    ulong var = 40;
-    inoutr_ulonglong(var);
-    if (var != 40) raiseError("inoutr_ulonglong");
-  }
-
-  // Check unsigned bool INPUT typemaps
-  if (in_bool(false) != false) raiseError("in_bool");
-  if (inr_bool(false) != false) raiseError("inr_bool");
-
-  // Check unsigned bool OUTPUT typemaps
-  {
-    bool var = false;
-    out_bool(true, var);
-    if (var != true) raiseError("out_bool");
-  }
-  {
-    bool var = false;
-    outr_bool(true, var);
-    if (var != true) raiseError("outr_bool");
-  }
-
-  // Check unsigned bool INOUT typemaps
-  {
-    bool var = false;
-    inout_bool(var);
-    if (var != false) raiseError("inout_bool");
-  }
-  {
-    bool var = false;
-    inoutr_bool(var);
-    if (var != false) raiseError("inoutr_bool");
-  }
-}
-
-void raiseError(char[] funcName) {
-  throw new Exception("Test FAILED for function " ~ funcName);
-}
diff --git a/Examples/test-suite/d/long_long_runme.1.d b/Examples/test-suite/d/long_long_runme.1.d
deleted file mode 100644
index a6d5448..0000000
--- a/Examples/test-suite/d/long_long_runme.1.d
+++ /dev/null
@@ -1,35 +0,0 @@
-// Checks if the long long and unsigned long long types work.
-module long_long_runme;
-
-import Integer = tango.text.convert.Integer;
-import long_long.long_long;
-
-void main() {
-  check_ll(0L);
-  check_ll(0x7FFFFFFFFFFFFFFFL);
-  check_ll(-10L);
-
-  check_ull(0u);
-  check_ull(127u);
-  check_ull(128u);
-  check_ull(9223372036854775807u); //0x7FFFFFFFFFFFFFFFL
-  check_ull(18446744073709551615u); //0xFFFFFFFFFFFFFFFFL
-}
-
-void check_ll(long value) {
-  ll = value;
-  long value_check = ll;
-  if (value != value_check) {
-    throw new Exception("Runtime test using long long failed: expected: " ~
-      Integer.toString(value) ~ ", got: " ~ Integer.toString(value_check));
-  }
-}
-
-void check_ull(ulong value) {
-  ull = value;
-  ulong value_check = ull;
-  if (value != value_check) {
-    throw new Exception( "Runtime test using unsigned long long failed: expected: " ~
-      Integer.toString(value) ~ ", ll_check=" ~ Integer.toString(value_check));
-  }
-}
diff --git a/Examples/test-suite/d/member_pointer_runme.1.d b/Examples/test-suite/d/member_pointer_runme.1.d
deleted file mode 100644
index c1f8d33..0000000
--- a/Examples/test-suite/d/member_pointer_runme.1.d
+++ /dev/null
@@ -1,43 +0,0 @@
-module member_pointer_runme;
-
-import Float = tango.text.convert.Float;
-import member_pointer.member_pointer;
-import member_pointer.Square;
-import member_pointer.SWIGTYPE_m_Shape__f_void__double;
-
-void main() {
-  auto s = new Square(10);
-
-  // Do some calculations
-  auto area_pt = areapt();
-  auto perim_pt = perimeterpt();
-  check("Square area ", 100.0, do_op(s, area_pt));
-  check("Square perim", 40.0, do_op(s, perim_pt));
-
-  SWIGTYPE_m_Shape__f_void__double memberPtr = null;
-  memberPtr = areavar;
-  memberPtr = perimetervar;
-
-  // Try the variables
-  check("Square area ", 100.0, do_op(s, areavar));
-  check("Square perim", 40.0, do_op(s, perimetervar));
-
-  // Modify one of the variables
-  areavar = perim_pt;
-  check("Square perimeter", 40.0, do_op(s,areavar));
-
-  // Try the constants
-  memberPtr = AREAPT;
-  memberPtr = PERIMPT;
-  memberPtr = NULLPT;
-
-  check("Square area", 100.0, do_op(s, AREAPT));
-  check("Square perim", 40.0, do_op(s, PERIMPT));
-}
-
-void check(char[] what, double expected, double actual) {
-  if (expected != actual) {
-    throw new Exception("Failed: " ~ what ~ ": expected "
-      ~ Float.toString(expected) ~ ", but got " ~ Float.toString(actual));
-  }
-}
diff --git a/Examples/test-suite/d/nspace_extend_runme.1.d b/Examples/test-suite/d/nspace_extend_runme.1.d
deleted file mode 100644
index 82ccfec..0000000
--- a/Examples/test-suite/d/nspace_extend_runme.1.d
+++ /dev/null
@@ -1,32 +0,0 @@
-module nspace_extend_runme;
-
-static import oi1c = nspace_extend.Outer.Inner1.Color;
-static import oi2c = nspace_extend.Outer.Inner2.Color;
-
-void main() {
-  {
-    // constructors and destructors
-    scope color1 = new oi1c.Color();
-    scope color = new oi1c.Color(color1);
-
-    // class methods
-    color.colorInstanceMethod(20.0);
-    oi1c.Color.colorStaticMethod(20.0);
-    auto created = oi1c.Color.create();
-  }
-  {
-    // constructors and destructors
-    scope color2 = new oi2c.Color();
-    scope color = new oi2c.Color(color2);
-
-    // class methods
-    color.colorInstanceMethod(20.0);
-    oi2c.Color.colorStaticMethod(20.0);
-    auto created = oi2c.Color.create();
-
-    // Same class different namespaces
-    auto col1 = new oi1c.Color();
-    auto col2 = oi2c.Color.create();
-    col2.colors(col1, col1, col2, col2, col2);
-  }
-}
diff --git a/Examples/test-suite/d/nspace_runme.1.d b/Examples/test-suite/d/nspace_runme.1.d
deleted file mode 100644
index 8d3b81f..0000000
--- a/Examples/test-suite/d/nspace_runme.1.d
+++ /dev/null
@@ -1,87 +0,0 @@
-module nspace_runme;
-
-import nspace.nspace;
-static import nspace.NoNSpacePlease;
-static import nspace.Outer.namespce;
-static import nspace.Outer.Inner1.Channel;
-static import oi1c = nspace.Outer.Inner1.Color;
-static import nspace.Outer.Inner2.Channel;
-static import nspace.Outer.Inner2.Color;
-static import nspace.Outer.Inner3.Blue;
-static import nspace.Outer.Inner4.Blue;
-static import nspace.Outer.SomeClass;
-
-void main() {
-  // constructors and destructors
-  auto color1 = new oi1c.Color();
-  auto color = new oi1c.Color(color1);
-
-  // class methods
-  color.colorInstanceMethod(20.0);
-  oi1c.Color.colorStaticMethod(20.0);
-  auto created = oi1c.Color.create();
-
-  // class enums
-  auto someClass = new nspace.Outer.SomeClass.SomeClass();
-  auto channel = someClass.GetInner1ColorChannel();
-  if (channel != oi1c.Color.Channel.Transmission) {
-    throw new Exception("Transmission wrong");
-  }
-
-  // class anonymous enums
-  int val1 = oi1c.Color.ColorEnumVal1;
-  int val2 = oi1c.Color.ColorEnumVal2;
-  if (val1 != 0 || val2 != 0x22) {
-    throw new Exception("ColorEnumVal wrong");
-  }
-
-  // instance member variables
-  color.instanceMemberVariable = 123;
-  if (color.instanceMemberVariable != 123) {
-    throw new Exception("instance member variable failed");
-  }
-
-  // static member variables
-  oi1c.Color.staticMemberVariable = 789;
-  if (oi1c.Color.staticMemberVariable != 789) {
-    throw new Exception("static member variable failed");
-  }
-  if (oi1c.Color.staticConstMemberVariable != 222) {
-    throw new Exception("static const member variable failed");
-  }
-  if (oi1c.Color.staticConstEnumMemberVariable != oi1c.Color.Channel.Transmission) {
-    throw new Exception("static const enum member variable failed");
-  }
-
-  // check globals in a namespace don't get mangled with the nspace option
-  nspace.nspace.namespaceFunction(color);
-  nspace.nspace.namespaceVar = 111;
-  if (nspace.nspace.namespaceVar != 111) {
-    throw new Exception("global var failed");
-  }
-
-  // Same class different namespaces
-  auto col1 = new oi1c.Color();
-  auto col2 = nspace.Outer.Inner2.Color.Color.create();
-  col2.colors(col1, col1, col2, col2, col2);
-
-  // global enums
-  auto outerChannel1 = someClass.GetInner1Channel();
-  if (outerChannel1 != nspace.Outer.Inner1.Channel.Channel.Transmission1) {
-    throw new Exception("Transmission1 wrong");
-  }
-  auto outerChannel2 = someClass.GetInner2Channel();
-  if (outerChannel2 != nspace.Outer.Inner2.Channel.Channel.Transmission2) {
-    throw new Exception("Transmission2 wrong");
-  }
-
-  // turn feature off / ignoring
-  auto ns = new nspace.Outer.namespce.namespce();
-  auto nons = new nspace.NoNSpacePlease.NoNSpacePlease();
-
-  // Derived class
-  auto blue3 = new nspace.Outer.Inner3.Blue.Blue();
-  blue3.blueInstanceMethod();
-  auto blue4 = new nspace.Outer.Inner4.Blue.Blue();
-  blue4.blueInstanceMethod();
-}
diff --git a/Examples/test-suite/d/operator_overload_runme.1.d b/Examples/test-suite/d/operator_overload_runme.1.d
deleted file mode 100644
index 18a24b9..0000000
--- a/Examples/test-suite/d/operator_overload_runme.1.d
+++ /dev/null
@@ -1,89 +0,0 @@
-module operator_overload_runme;
-
-import operator_overload.Op;
-
-void main() {
-  // Invoke the C++ sanity check first.
-  Op.sanity_check();
-
-  auto a = new Op();
-  auto b = new Op(5);
-  auto c = b;
-  auto d = new Op(2);
-  auto dd = d;
-  
-  // test equality
-  assert(a != b);
-  assert(b == c);
-  assert(a != d);
-  assert(d == dd);
-  
-  // test <
-  assert(a < b);
-  assert(a <= b);
-  assert(b <= c);
-  assert(b >= c);
-  assert(b > d);
-  assert(b >= d);
-  
-  // test +=
-  auto e = new Op(3);
-  e += d;
-  assert(e == b);
-  e -= c;
-  assert(e == a);
-  e = new Op(1);
-  e *= b;
-  assert(e == c);
-  e /= d;
-  assert(e == d);
-  e %= c;
-  assert(e == d);
-  
-  // test +
-  auto f = new Op(1);
-  auto g = new Op(1);
-  assert(f + g == new Op(2));
-  assert(f - g == new Op(0));
-  assert(f * g == new Op(1));
-  assert(f / g == new Op(1));
-  assert(f % g == new Op(0));
-  
-  // test unary operators
-  assert(-a == a);
-  assert(-b == new Op(-5));
-  // The unary ! operator is not overloadable in D1.
-  
-  // test []
-  auto h = new Op(3);
-  assert(h[0]==3);
-  assert(h[1]==0);
-  // Generation of opIndexAssign is not supported yet.
-  
-  // test ()
-  auto i = new Op(3);
-  assert(i()==3);
-  assert(i(1)==4);
-  assert(i(1,2)==6);
-  
-  // test ++ and --
-  auto j = new Op(100);
-  int original = j.i;
-  {
-    Op newOp = j++;
-    int newInt = original++;
-    assert(j.i == original);
-    assert(newOp.i == newInt);
-  }
-  {
-    Op newOp = j--;
-    int newInt = original--;
-    assert(j.i == original);
-    assert(newOp.i == newInt);
-  }
-  // Prefix increment/decrement operators are lowered to (foo +=/-= 1) in D1,
-  // but the test case does not define an integer overload for operator +=
-  // respectively -=.
-  
-  // Implicit casting is not overloadable in D1.
-}
\ No newline at end of file
diff --git a/Examples/test-suite/d/overload_complicated_runme.1.d b/Examples/test-suite/d/overload_complicated_runme.1.d
deleted file mode 100644
index 03d1bf1..0000000
--- a/Examples/test-suite/d/overload_complicated_runme.1.d
+++ /dev/null
@@ -1,50 +0,0 @@
-module overload_complicated_runme;
-
-import overload_complicated;
-
-void main() {
-  SWIGTYPE_p_int pInt = null;
-
-  // Check the correct constructors are available
-  Pop p = new Pop(pInt);
-
-  p = new Pop(pInt, false);
-
-  // Check overloaded in const only and pointers/references which target languages cannot disambiguate
-  if (p.hip(false) != 701)
-    throw new Exception("Test 1 failed");
-
-  if (p.hip(pInt) != 702)
-    throw new Exception("Test 2 failed");
-
-  // Reverse the order for the above
-  if (p.hop(pInt) != 805)
-    throw new Exception("Test 3 failed");
-
-  if (p.hop(false) != 801)
-    throw new Exception("Test 4 failed");
-
-  // Few more variations and order shuffled
-  if (p.pop(false) != 901)
-    throw new Exception("Test 5 failed");
-
-  if (p.pop(pInt) != 902)
-    throw new Exception("Test 6 failed");
-
-  if (p.pop() != 905)
-    throw new Exception("Test 7 failed");
-
-  // Overload on const only
-  if (p.bop(pInt) != 1001)
-    throw new Exception("Test 8 failed");
-
-  if (p.bip(pInt) != 2001)
-    throw new Exception("Test 9 failed");
-
-  // Globals
-  if (muzak(false) != 3001)
-    throw new Exception("Test 10 failed");
-
-  if (muzak(pInt) != 3002)
-    throw new Exception("Test 11 failed");
-}
diff --git a/Examples/test-suite/d/overload_template_runme.1.d b/Examples/test-suite/d/overload_template_runme.1.d
deleted file mode 100644
index a1fe801..0000000
--- a/Examples/test-suite/d/overload_template_runme.1.d
+++ /dev/null
@@ -1,146 +0,0 @@
-module overload_template_runme;
-
-import overload_template.overload_template;
-import overload_template.Klass;
-
-void main() {
-  int f = foo();
-
-  f += maximum(3,4);
-  double b = maximum(3.4,5.2);
-  b++; // warning suppression
-
-  // mix 1
-  if (mix1("hi") != 101)
-    throw new Exception ("mix1(const char*)");
-
-  if (mix1(1.0, 1.0) != 102)
-    throw new Exception ("mix1(double, const double &)");
-
-  if (mix1(1.0) != 103)
-    throw new Exception ("mix1(double)");
-
-  // mix 2
-  if (mix2("hi") != 101)
-    throw new Exception ("mix2(const char*)");
-
-  if (mix2(1.0, 1.0) != 102)
-    throw new Exception ("mix2(double, const double &)");
-
-  if (mix2(1.0) != 103)
-    throw new Exception ("mix2(double)");
-
-  // mix 3
-  if (mix3("hi") != 101)
-    throw new Exception ("mix3(const char*)");
-
-  if (mix3(1.0, 1.0) != 102)
-    throw new Exception ("mix3(double, const double &)");
-
-  if (mix3(1.0) != 103)
-    throw new Exception ("mix3(double)");
-
-  // Combination 1
-  if (overtparams1(100) != 10)
-    throw new Exception ("overtparams1(int)");
-
-  if (overtparams1(100.0, 100) != 20)
-    throw new Exception ("overtparams1(double, int)");
-
-  // Combination 2
-  if (overtparams2(100.0, 100) != 40)
-    throw new Exception ("overtparams2(double, int)");
-
-  // Combination 3
-  if (overloaded() != 60)
-    throw new Exception ("overloaded()");
-
-  if (overloaded(100.0, 100) != 70)
-    throw new Exception ("overloaded(double, int)");
-
-  // Combination 4
-  if (overloadedagain("hello") != 80)
-    throw new Exception ("overloadedagain(const char *)");
-
-  if (overloadedagain() != 90)
-    throw new Exception ("overloadedagain(double)");
-
-  // specializations
-  if (specialization(10) != 202)
-    throw new Exception ("specialization(int)");
-
-  if (specialization(10.0) != 203)
-    throw new Exception ("specialization(double)");
-
-  if (specialization(10, 10) != 204)
-    throw new Exception ("specialization(int, int)");
-
-  if (specialization(10.0, 10.0) != 205)
-    throw new Exception ("specialization(double, double)");
-
-  if (specialization("hi", "hi") != 201)
-    throw new Exception ("specialization(const char *, const char *)");
-
-  // simple specialization
-  xyz();
-  xyz_int();
-  xyz_double();
-
-  // a bit of everything
-  if (overload("hi") != 0)
-    throw new Exception ("overload()");
-
-  if (overload(1) != 10)
-    throw new Exception ("overload(int t)");
-
-  if (overload(1, 1) != 20)
-    throw new Exception ("overload(int t, const int &)");
-
-  if (overload(1, "hello") != 30)
-    throw new Exception ("overload(int t, const char *)");
-
-  auto k = new Klass();
-  if (overload(k) != 10)
-    throw new Exception ("overload(Klass t)");
-
-  if (overload(k, k) != 20)
-    throw new Exception ("overload(Klass t, const Klass &)");
-
-  if (overload(k, "hello") != 30)
-    throw new Exception ("overload(Klass t, const char *)");
-
-  if (overload(10.0, "hi") != 40)
-    throw new Exception ("overload(double t, const char *)");
-
-  if (overload() != 50)
-    throw new Exception ("overload(const char *)");
-
-
-  // everything put in a namespace
-  if (nsoverload("hi") != 1000)
-    throw new Exception ("nsoverload()");
-
-  if (nsoverload(1) != 1010)
-    throw new Exception ("nsoverload(int t)");
-
-  if (nsoverload(1, 1) != 1020)
-    throw new Exception ("nsoverload(int t, const int &)");
-
-  if (nsoverload(1, "hello") != 1030)
-    throw new Exception ("nsoverload(int t, const char *)");
-
-  if (nsoverload(k) != 1010)
-    throw new Exception ("nsoverload(Klass t)");
-
-  if (nsoverload(k, k) != 1020)
-    throw new Exception ("nsoverload(Klass t, const Klass &)");
-
-  if (nsoverload(k, "hello") != 1030)
-    throw new Exception ("nsoverload(Klass t, const char *)");
-
-  if (nsoverload(10.0, "hi") != 1040)
-    throw new Exception ("nsoverload(double t, const char *)");
-
-  if (nsoverload() != 1050)
-    throw new Exception ("nsoverload(const char *)");
-}
diff --git a/Examples/test-suite/d/pointer_reference_runme.1.d b/Examples/test-suite/d/pointer_reference_runme.1.d
deleted file mode 100644
index c593b93..0000000
--- a/Examples/test-suite/d/pointer_reference_runme.1.d
+++ /dev/null
@@ -1,13 +0,0 @@
-module pointer_reference_runme;
-
-import pointer_reference.pointer_reference;
-import pointer_reference.Struct;
-
-void main() {
-  Struct s  = get();
-  if (s.value != 10) throw new Exception("get test failed");
-
-  Struct ss = new Struct(20);
-  set(ss);
-  if (Struct.instance.value != 20) throw new Exception("set test failed");
-}
diff --git a/Examples/test-suite/d/preproc_constants_c_runme.1.d b/Examples/test-suite/d/preproc_constants_c_runme.1.d
deleted file mode 100644
index a6c2f3d..0000000
--- a/Examples/test-suite/d/preproc_constants_c_runme.1.d
+++ /dev/null
@@ -1,67 +0,0 @@
-module preproc_constants_c_runme;
-
-import tango.stdc.config;
-import preproc_constants_c.preproc_constants_c;
-
-// Same as preproc_constants.i testcase, but bool types are int instead.
-void main() {
-  static assert(is(int == typeof(CONST_INT1())));
-  static assert(is(int == typeof(CONST_INT2())));
-  static assert(is(uint == typeof(CONST_UINT1())));
-  static assert(is(uint == typeof(CONST_UINT2())));
-  static assert(is(uint == typeof(CONST_UINT3())));
-  static assert(is(uint == typeof(CONST_UINT4())));
-  static assert(is(c_long == typeof(CONST_LONG1())));
-  static assert(is(c_long == typeof(CONST_LONG2())));
-  static assert(is(c_long == typeof(CONST_LONG3())));
-  static assert(is(c_long == typeof(CONST_LONG4())));
-  static assert(is(long == typeof(CONST_LLONG1())));
-  static assert(is(long == typeof(CONST_LLONG2())));
-  static assert(is(long == typeof(CONST_LLONG3())));
-  static assert(is(long == typeof(CONST_LLONG4())));
-  static assert(is(ulong == typeof(CONST_ULLONG1())));
-  static assert(is(ulong == typeof(CONST_ULLONG2())));
-  static assert(is(ulong == typeof(CONST_ULLONG3())));
-  static assert(is(ulong == typeof(CONST_ULLONG4())));
-  static assert(is(double == typeof(CONST_DOUBLE1())));
-  static assert(is(double == typeof(CONST_DOUBLE2())));
-  static assert(is(double == typeof(CONST_DOUBLE3())));
-  static assert(is(double == typeof(CONST_DOUBLE4())));
-  static assert(is(double == typeof(CONST_DOUBLE5())));
-  static assert(is(double == typeof(CONST_DOUBLE6())));
-  static assert(is(int == typeof(CONST_BOOL1())));
-  static assert(is(int == typeof(CONST_BOOL2())));
-  static assert(is(char == typeof(CONST_CHAR())));
-  static assert(is(char[] == typeof(CONST_STRING1())));
-  static assert(is(char[] == typeof(CONST_STRING2())));
-
-  static assert(is(int == typeof(INT_AND_BOOL())));
-  static assert(is(int == typeof(INT_AND_CHAR())));
-  static assert(is(int == typeof(INT_AND_INT())));
-  static assert(is(uint == typeof(INT_AND_UINT())));
-  static assert(is(c_long == typeof(INT_AND_LONG())));
-  static assert(is(c_ulong == typeof(INT_AND_ULONG())));
-  static assert(is(long == typeof(INT_AND_LLONG())));
-  static assert(is(ulong == typeof(INT_AND_ULLONG())));
-  static assert(is(int == typeof(BOOL_AND_BOOL())));
-
-  static assert(is(int == typeof(EXPR_MULTIPLY())));
-  static assert(is(int == typeof(EXPR_DIVIDE())));
-  static assert(is(int == typeof(EXPR_PLUS())));
-  static assert(is(int == typeof(EXPR_MINUS())));
-  static assert(is(int == typeof(EXPR_LSHIFT())));
-  static assert(is(int == typeof(EXPR_RSHIFT())));
-  static assert(is(int == typeof(EXPR_LTE())));
-  static assert(is(int == typeof(EXPR_GTE())));
-  static assert(is(int == typeof(EXPR_INEQUALITY())));
-  static assert(is(int == typeof(EXPR_EQUALITY())));
-  static assert(is(int == typeof(EXPR_AND())));
-  static assert(is(int == typeof(EXPR_XOR())));
-  static assert(is(int == typeof(EXPR_OR())));
-  static assert(is(int == typeof(EXPR_LAND())));
-  static assert(is(int == typeof(EXPR_LOR())));
-  static assert(is(double == typeof(EXPR_CONDITIONAL())));
-  static assert(is(double == typeof(EXPR_MIXED1())));
-  static assert(is(int == typeof(EXPR_WCHAR_MAX())));
-  static assert(is(int == typeof(EXPR_WCHAR_MIN())));
-}
diff --git a/Examples/test-suite/d/preproc_constants_c_runme.2.d b/Examples/test-suite/d/preproc_constants_c_runme.2.d
index 786cb48..136a897 100644
--- a/Examples/test-suite/d/preproc_constants_c_runme.2.d
+++ b/Examples/test-suite/d/preproc_constants_c_runme.2.d
@@ -27,8 +27,8 @@
   static assert(is(double == typeof(CONST_DOUBLE2())));
   static assert(is(double == typeof(CONST_DOUBLE3())));
   static assert(is(double == typeof(CONST_DOUBLE4())));
-  static assert(is(double == typeof(CONST_DOUBLE5())));
-  static assert(is(double == typeof(CONST_DOUBLE6())));
+  static assert(is(float == typeof(CONST_FLOAT1())));
+  static assert(is(float == typeof(CONST_FLOAT2())));
   static assert(is(int == typeof(CONST_BOOL1())));
   static assert(is(int == typeof(CONST_BOOL2())));
   static assert(is(char == typeof(CONST_CHAR())));
@@ -51,6 +51,8 @@
   static assert(is(int == typeof(EXPR_MINUS())));
   static assert(is(int == typeof(EXPR_LSHIFT())));
   static assert(is(int == typeof(EXPR_RSHIFT())));
+  static assert(is(int == typeof(EXPR_LT())));
+  static assert(is(int == typeof(EXPR_GT())));
   static assert(is(int == typeof(EXPR_LTE())));
   static assert(is(int == typeof(EXPR_GTE())));
   static assert(is(int == typeof(EXPR_INEQUALITY())));
diff --git a/Examples/test-suite/d/preproc_constants_runme.1.d b/Examples/test-suite/d/preproc_constants_runme.1.d
deleted file mode 100644
index 85fa918..0000000
--- a/Examples/test-suite/d/preproc_constants_runme.1.d
+++ /dev/null
@@ -1,66 +0,0 @@
-module preproc_constants_runme;
-
-import tango.stdc.config;
-import preproc_constants.preproc_constants;
-
-void main() {
-  static assert(is(int == typeof(CONST_INT1())));
-  static assert(is(int == typeof(CONST_INT2())));
-  static assert(is(uint == typeof(CONST_UINT1())));
-  static assert(is(uint == typeof(CONST_UINT2())));
-  static assert(is(uint == typeof(CONST_UINT3())));
-  static assert(is(uint == typeof(CONST_UINT4())));
-  static assert(is(c_long == typeof(CONST_LONG1())));
-  static assert(is(c_long == typeof(CONST_LONG2())));
-  static assert(is(c_long == typeof(CONST_LONG3())));
-  static assert(is(c_long == typeof(CONST_LONG4())));
-  static assert(is(long == typeof(CONST_LLONG1())));
-  static assert(is(long == typeof(CONST_LLONG2())));
-  static assert(is(long == typeof(CONST_LLONG3())));
-  static assert(is(long == typeof(CONST_LLONG4())));
-  static assert(is(ulong == typeof(CONST_ULLONG1())));
-  static assert(is(ulong == typeof(CONST_ULLONG2())));
-  static assert(is(ulong == typeof(CONST_ULLONG3())));
-  static assert(is(ulong == typeof(CONST_ULLONG4())));
-  static assert(is(double == typeof(CONST_DOUBLE1())));
-  static assert(is(double == typeof(CONST_DOUBLE2())));
-  static assert(is(double == typeof(CONST_DOUBLE3())));
-  static assert(is(double == typeof(CONST_DOUBLE4())));
-  static assert(is(double == typeof(CONST_DOUBLE5())));
-  static assert(is(double == typeof(CONST_DOUBLE6())));
-  static assert(is(bool == typeof(CONST_BOOL1())));
-  static assert(is(bool == typeof(CONST_BOOL2())));
-  static assert(is(char == typeof(CONST_CHAR())));
-  static assert(is(char[] == typeof(CONST_STRING1())));
-  static assert(is(char[] == typeof(CONST_STRING2())));
-
-  static assert(is(int == typeof(INT_AND_BOOL())));
-  static assert(is(int == typeof(INT_AND_CHAR())));
-  static assert(is(int == typeof(INT_AND_INT())));
-  static assert(is(uint == typeof(INT_AND_UINT())));
-  static assert(is(c_long == typeof(INT_AND_LONG())));
-  static assert(is(c_ulong == typeof(INT_AND_ULONG())));
-  static assert(is(long == typeof(INT_AND_LLONG())));
-  static assert(is(ulong == typeof(INT_AND_ULLONG())));
-  static assert(is(int == typeof(BOOL_AND_BOOL())));
-
-  static assert(is(int == typeof(EXPR_MULTIPLY())));
-  static assert(is(int == typeof(EXPR_DIVIDE())));
-  static assert(is(int == typeof(EXPR_PLUS())));
-  static assert(is(int == typeof(EXPR_MINUS())));
-  static assert(is(int == typeof(EXPR_LSHIFT())));
-  static assert(is(int == typeof(EXPR_RSHIFT())));
-  static assert(is(bool == typeof(EXPR_LTE())));
-  static assert(is(bool == typeof(EXPR_GTE())));
-  static assert(is(bool == typeof(EXPR_INEQUALITY())));
-  static assert(is(bool == typeof(EXPR_EQUALITY())));
-  static assert(is(int == typeof(EXPR_AND())));
-  static assert(is(int == typeof(EXPR_XOR())));
-  static assert(is(int == typeof(EXPR_OR())));
-  static assert(is(bool == typeof(EXPR_LAND())));
-  static assert(is(bool == typeof(EXPR_LOR())));
-  static assert(is(double == typeof(EXPR_CONDITIONAL())));
-  static assert(is(double == typeof(EXPR_MIXED1())));
-  static assert(is(int == typeof(EXPR_WCHAR_MAX())));
-  static assert(is(int == typeof(EXPR_WCHAR_MIN())));
-}
diff --git a/Examples/test-suite/d/preproc_constants_runme.2.d b/Examples/test-suite/d/preproc_constants_runme.2.d
index c81e531..b4ccef2 100644
--- a/Examples/test-suite/d/preproc_constants_runme.2.d
+++ b/Examples/test-suite/d/preproc_constants_runme.2.d
@@ -26,8 +26,8 @@
   static assert(is(double == typeof(CONST_DOUBLE2())));
   static assert(is(double == typeof(CONST_DOUBLE3())));
   static assert(is(double == typeof(CONST_DOUBLE4())));
-  static assert(is(double == typeof(CONST_DOUBLE5())));
-  static assert(is(double == typeof(CONST_DOUBLE6())));
+  static assert(is(float == typeof(CONST_FLOAT1())));
+  static assert(is(float == typeof(CONST_FLOAT2())));
   static assert(is(bool == typeof(CONST_BOOL1())));
   static assert(is(bool == typeof(CONST_BOOL2())));
   static assert(is(char == typeof(CONST_CHAR())));
@@ -50,6 +50,8 @@
   static assert(is(int == typeof(EXPR_MINUS())));
   static assert(is(int == typeof(EXPR_LSHIFT())));
   static assert(is(int == typeof(EXPR_RSHIFT())));
+  static assert(is(bool == typeof(EXPR_LT())));
+  static assert(is(bool == typeof(EXPR_GT())));
   static assert(is(bool == typeof(EXPR_LTE())));
   static assert(is(bool == typeof(EXPR_GTE())));
   static assert(is(bool == typeof(EXPR_INEQUALITY())));
diff --git a/Examples/test-suite/d/sizet_runme.1.d b/Examples/test-suite/d/sizet_runme.1.d
deleted file mode 100644
index ae42e20..0000000
--- a/Examples/test-suite/d/sizet_runme.1.d
+++ /dev/null
@@ -1,15 +0,0 @@
-module sizet_runme;
-
-import sizet.sizet;
-
-void main() {
-  size_t s = 2000;
-  s = test1(s+1);
-  s = test2(s+1);
-  s = test3(s+1);
-  s = test4(s+1);
-
-  if (s != 2004) {
-    throw new Exception("failed");
-  }
-}
diff --git a/Examples/test-suite/d/sneaky1_runme.1.d b/Examples/test-suite/d/sneaky1_runme.1.d
deleted file mode 100644
index b293b49..0000000
--- a/Examples/test-suite/d/sneaky1_runme.1.d
+++ /dev/null
@@ -1,21 +0,0 @@
-module sneaky1_runme;
-
-import sneaky1.sneaky1;
-
-void main() {
-  if (add(30, 2) != 32) {
-    throw new Exception("add test failed");
-  }
-
-  if (subtract(20, 2) != 18) {
-    throw new Exception("subtract test failed");
-  }
-
-  if (mul(20, 2) != 40) {
-    throw new Exception("mul test failed");
-  }
-
-  if (divide(20, 2) != 10) {
-    throw new Exception("div test failed");
-  }
-}
diff --git a/Examples/test-suite/d/special_variable_macros_runme.1.d b/Examples/test-suite/d/special_variable_macros_runme.1.d
deleted file mode 100644
index eab0331..0000000
--- a/Examples/test-suite/d/special_variable_macros_runme.1.d
+++ /dev/null
@@ -1,43 +0,0 @@
-module special_variable_macros_runme;
-
-import special_variable_macros.special_variable_macros;
-import special_variable_macros.Name;
-import special_variable_macros.NewName;
-import special_variable_macros.PairIntBool;
-
-void main() {
-  auto name = new Name();
-
-  if (testFred(name) != "none") {
-    throw new Exception("test failed");
-  }
-
-  if (testJack(name) != "$specialname") {
-    throw new Exception("test failed");
-  }
-
-  if (testJill(name) != "jilly") {
-    throw new Exception("test failed");
-  }
-
-  if (testMary(name) != "SWIGTYPE_p_NameWrap") {
-    throw new Exception("test failed");
-  }
-
-  if (testJames(name) != "SWIGTYPE_Name") {
-    throw new Exception("test failed");
-  }
-
-  if (testJim(name) != "multiname num") {
-    throw new Exception("test failed");
-  }
-
-  if (testJohn(new PairIntBool(10, false)) != 123) {
-    throw new Exception("test failed");
-  }
-
-  auto newName = NewName.factory("factoryname");
-  if (newName.getStoredName().getName() != "factoryname") {
-    throw new Exception("test failed");
-  }
-}
diff --git a/Examples/test-suite/d/special_variable_macros_runme.2.d b/Examples/test-suite/d/special_variable_macros_runme.2.d
index 0bc4c0c..6287dc5 100644
--- a/Examples/test-suite/d/special_variable_macros_runme.2.d
+++ b/Examples/test-suite/d/special_variable_macros_runme.2.d
@@ -19,4 +19,6 @@
 
   auto newName = NewName.factory("factoryname");
   enforce(newName.getStoredName().getName() == "factoryname");
+  enforce(makeStringInt("stringint", 999) == "stringint");
+  enforce(provideStringInt(999) == "1000");
 }
diff --git a/Examples/test-suite/d/threads_runme.1.d b/Examples/test-suite/d/threads_runme.1.d
deleted file mode 100644
index 2068758..0000000
--- a/Examples/test-suite/d/threads_runme.1.d
+++ /dev/null
@@ -1,70 +0,0 @@
-module threads_runme;
-
-import tango.core.Thread;
-import tango.io.Console;
-import Integer = tango.text.convert.Integer;
-import threads.Kerfuffle;
-
-// Spawn 8 threads.
-const uint NUM_THREADS = 8;
-
-// Run test for a few seconds on a 1GHz machine.
-const uint WORKER_LOOP_PASSES = 30000;
-
-void main() {
-  auto kerf = new Kerfuffle();
-  TestThread[] threads;
-
-  // Invoke the threads.
-  for (uint i = 0; i < NUM_THREADS; i++) {
-    auto thread = new TestThread(kerf);
-    threads ~= thread;
-    thread.name = Integer.toString(i);
-    thread.start();
-  }
-
-  // Wait for the threads to finish.
-  foreach(thread; threads) {
-    thread.join();
-  }
-
-  // Check if any thread has failed.
-  foreach(thread; threads) {
-    if (thread.failed) throw new Exception("Test failed.");
-  }
-}
-
-class TestThread : Thread {
-public:
-  this(Kerfuffle kerf) {
-    super(&run);
-    m_kerf = kerf;
-  }
-
-  void run() {
-    failed = false;
-    try {
-      for (uint i = 0; i < WORKER_LOOP_PASSES; i++) {
-	char[] given = "This is the test char[] that should come back. A number: " ~ Integer.toString(i);
-	char[] received = m_kerf.StdString(given);
-	if (received != given) {
-	  throw new Exception("StdString char[] does not match. Received: '" ~ received ~ "'. Expected: '" ~ given ~ "'.");
-	}
-      }
-      for (uint i = 0; i < WORKER_LOOP_PASSES; i++) {
-	char[] given = "This is the test char[] that should come back. A number: " ~ Integer.toString(i);
-	char[] received = m_kerf.CharString(given);
-	if (received != given) {
-	  throw new Exception("StdString char[] does not match. Received: '" ~ received ~ "'. Expected: '" ~ given ~ "'.");
-	}
-      }
-    } catch (Exception e) {
-      Cerr("Test failed (thread " ~ name() ~ "): " ~ e.msg).newline;
-      failed = true;
-    }
-  }
-
-  bool failed;
-private:
-  Kerfuffle m_kerf;
-}
diff --git a/Examples/test-suite/d/throw_exception_runme.1.d b/Examples/test-suite/d/throw_exception_runme.1.d
deleted file mode 100644
index f2397a2..0000000
--- a/Examples/test-suite/d/throw_exception_runme.1.d
+++ /dev/null
@@ -1,30 +0,0 @@
-module throw_exception_runme;
-
-import throw_exception.Foo;
-
-void main() {
-  test!("test_int");
-  test!("test_msg");
-  test!("test_cls");
-  test!("test_cls_ptr");
-  test!("test_cls_ref");
-  test!("test_cls_td");
-  test!("test_cls_ptr_td");
-  test!("test_cls_ref_td");
-  test!("test_array");
-  test!("test_enum");
-}
-
-void test(char[] methodName)() {
-  auto foo = new Foo();
-
-  bool didntThrow;
-  try {
-    mixin("foo." ~ methodName ~ "();");
-    didntThrow = true;
-  } catch (Exception) {}
-
-  if (didntThrow) {
-    throw new Exception(methodName ~ " failed");
-  }
-}
diff --git a/Examples/test-suite/d/typemap_namespace_runme.1.d b/Examples/test-suite/d/typemap_namespace_runme.1.d
deleted file mode 100644
index 3a5ca1a..0000000
--- a/Examples/test-suite/d/typemap_namespace_runme.1.d
+++ /dev/null
@@ -1,13 +0,0 @@
-module typemap_namespace_runme;
-
-import typemap_namespace.typemap_namespace;
-
-void main() {
-  if (test1("hello") != "hello") {
-    throw new Exception("test1 failed");
-  }
-
-  if (test2("hello") != "hello") {
-    throw new Exception("test2 failed");
-  }
-}
diff --git a/Examples/test-suite/d/typemap_out_optimal_runme.1.d b/Examples/test-suite/d/typemap_out_optimal_runme.1.d
deleted file mode 100644
index 16aab3c..0000000
--- a/Examples/test-suite/d/typemap_out_optimal_runme.1.d
+++ /dev/null
@@ -1,9 +0,0 @@
-module typemap_out_optimal_runme;
-
-import typemap_out_optimal.XX;
-
-void main() {
-  XX x;
-  XX.trace = false;
-  x = XX.create();
-}
diff --git a/Examples/test-suite/d/typemap_out_optimal_runme.2.d b/Examples/test-suite/d/typemap_out_optimal_runme.2.d
index 16aab3c..1267197 100644
--- a/Examples/test-suite/d/typemap_out_optimal_runme.2.d
+++ b/Examples/test-suite/d/typemap_out_optimal_runme.2.d
@@ -6,4 +6,5 @@
   XX x;
   XX.trace = false;
   x = XX.create();
+  x = XX.createConst();
 }
diff --git a/Examples/test-suite/d/varargs_runme.1.d b/Examples/test-suite/d/varargs_runme.1.d
deleted file mode 100644
index 53f76d0..0000000
--- a/Examples/test-suite/d/varargs_runme.1.d
+++ /dev/null
@@ -1,20 +0,0 @@
-module varargs_runme;
-
-import varargs.varargs;
-import varargs.Foo;
-
-void main() {
-  if (test("Hello") != "Hello") {
-    throw new Exception("Test 1 failed");
-  }
-
-  auto f = new Foo("Greetings");
-
-  if (f.str != "Greetings") {
-    throw new Exception("Test 2 failed");
-  }
-
-  if (f.test("Hello") != "Hello") {
-    throw new Exception("Test 3 failed");
-  }
-}
diff --git a/Examples/test-suite/d/virtual_poly_runme.1.d b/Examples/test-suite/d/virtual_poly_runme.1.d
deleted file mode 100644
index fb2e781..0000000
--- a/Examples/test-suite/d/virtual_poly_runme.1.d
+++ /dev/null
@@ -1,27 +0,0 @@
-module virtual_poly_runme;
-
-import virtual_poly.NDouble;
-import virtual_poly.NInt;
-import virtual_poly.NNumber;
-
-void main() {
-  // D supports covariant (polymorphic) return types, so this should work like
-  // in C++.
-  auto d = new NDouble(3.5);
-  NDouble dc = d.copy();
-  if (d.get() != dc.get()) {
-    throw new Exception("Test 1 failed.");
-  }
-
-  auto i = new NInt(2);
-  NInt ic = i.copy();
-  if (i.get() != ic.get()) {
-    throw new Exception("Test 2 failed.");
-  }
-
-  NNumber n = d;
-  auto nd = cast(NDouble) n.copy();
-  if (nd.get() != d.get()) {
-    throw new Exception("Test 3 failed.");
-  }
-}
diff --git a/Examples/test-suite/default_arg_expressions.i b/Examples/test-suite/default_arg_expressions.i
index d83dc05..ce4d3f4 100644
--- a/Examples/test-suite/default_arg_expressions.i
+++ b/Examples/test-suite/default_arg_expressions.i
@@ -8,20 +8,29 @@
 %warnfilter(SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG) UsdGeomTokensPtr;
 %immutable UsdGeomTokens;
 
+// Don't call our getters get_xxx() as that collides with generated getters in
+// some languages (e.g. csharp).
+
 %inline %{
 struct Numbers {
   int val;
   int *ptr;
+  const int& g_val() const { return val; }
+  const int* g_ptr() const { return ptr; }
   Numbers() : val(), ptr(&val) {}
 };
 struct TfToken {
   Numbers val;
   Numbers *ptr;
+  const Numbers& g_val() const { return val; }
+  const Numbers* g_ptr() const { return ptr; }
   TfToken() : val(), ptr(&val) {}
 };
 struct Tokens {
   const TfToken face;
   const TfToken *pface;
+  const TfToken& g_face(int = 0, int = 0) const { return face; }
+  const TfToken* g_pface() const { return pface; }
   Tokens() : face(), pface(&face) {}
 };
 static Tokens UsdGeomTokens;
@@ -30,5 +39,35 @@
 void CreateMaterialBindSubset2(int num = UsdGeomTokensPtr->pface->val.val) {}
 void CreateMaterialBindSubset3(int num = UsdGeomTokensPtr->pface->ptr->val) {}
 void CreateMaterialBindSubset4(int num = UsdGeomTokensPtr->face.val.val) {}
-//void CreateMaterialBindSubset5(int num = UsdGeomTokens.face.val.val) {}
+void CreateMaterialBindSubset5(int num = UsdGeomTokens.face.val.val) {}
+void CreateMaterialBindSubset6(int num = UsdGeomTokensPtr->pface->val.g_val()) {}
+void CreateMaterialBindSubset7(int num = UsdGeomTokensPtr->pface->ptr->g_val()) {}
+void CreateMaterialBindSubset8(int num = UsdGeomTokensPtr->face.val.g_val()) {}
+void CreateMaterialBindSubset9(int num = UsdGeomTokens.face.val.g_val()) {}
+void CreateMaterialBindSubseta(int num = UsdGeomTokensPtr->pface->g_val().val) {}
+void CreateMaterialBindSubsetb(int num = UsdGeomTokensPtr->pface->g_ptr()->val) {}
+void CreateMaterialBindSubsetc(int num = UsdGeomTokensPtr->face.g_val().val) {}
+void CreateMaterialBindSubsetd(int num = UsdGeomTokens.face.g_val().val) {}
+void CreateMaterialBindSubsete(int num = UsdGeomTokensPtr->pface->g_val().g_val()) {}
+void CreateMaterialBindSubsetf(int num = UsdGeomTokensPtr->pface->g_ptr()->g_val()) {}
+void CreateMaterialBindSubsetg(int num = UsdGeomTokensPtr->face.g_val().g_val()) {}
+void CreateMaterialBindSubseth(int num = UsdGeomTokens.face.g_val().g_val()) {}
+void CreateMaterialBindSubseti(int num = UsdGeomTokensPtr->g_pface()->val.val) {}
+void CreateMaterialBindSubsetj(int num = UsdGeomTokensPtr->g_pface()->ptr->val) {}
+void CreateMaterialBindSubsetk(int num = UsdGeomTokensPtr->g_face().val.val) {}
+void CreateMaterialBindSubsetl(int num = UsdGeomTokens.g_face().val.val) {}
+void CreateMaterialBindSubsetm(int num = UsdGeomTokensPtr->g_pface()->val.g_val()) {}
+void CreateMaterialBindSubsetn(int num = UsdGeomTokensPtr->g_pface()->ptr->g_val()) {}
+void CreateMaterialBindSubseto(int num = UsdGeomTokensPtr->g_face().val.g_val()) {}
+void CreateMaterialBindSubsetp(int num = UsdGeomTokens.g_face().val.g_val()) {}
+void CreateMaterialBindSubsetq(int num = UsdGeomTokensPtr->g_pface()->g_val().val) {}
+void CreateMaterialBindSubsetr(int num = UsdGeomTokensPtr->g_pface()->g_ptr()->val) {}
+void CreateMaterialBindSubsets(int num = UsdGeomTokensPtr->g_face().g_val().val) {}
+void CreateMaterialBindSubsett(int num = UsdGeomTokens.g_face().g_val().val) {}
+void CreateMaterialBindSubsetu(int num = UsdGeomTokensPtr->g_pface()->g_val().g_val()) {}
+void CreateMaterialBindSubsetv(int num = UsdGeomTokensPtr->g_pface()->g_ptr()->g_val()) {}
+void CreateMaterialBindSubsetw(int num = UsdGeomTokensPtr->g_face().g_val().g_val()) {}
+void CreateMaterialBindSubsetx(int num = UsdGeomTokens.g_face().g_val().g_val()) {}
+void CreateMaterialBindSubsety(int num = UsdGeomTokens.g_face(1).g_val().g_val()) {}
+void CreateMaterialBindSubsetz(int num = UsdGeomTokens.g_face(1,2).g_val().g_val()) {}
 %}
diff --git a/Examples/test-suite/default_args.i b/Examples/test-suite/default_args.i
index 6b680f5..fd09152 100644
--- a/Examples/test-suite/default_args.i
+++ b/Examples/test-suite/default_args.i
@@ -18,6 +18,7 @@
 %{
 #define TESTCASE_THROW1(T1)
 #define TESTCASE_THROW2(T1, T2)
+#include <string.h>
 %}
 
 %include <std_string.i>
@@ -71,7 +72,7 @@
   class EnumClass {
     public:
       enum speed { FAST, SLOW };
-      // Note: default values should be EnumClass::FAST and SWEET 
+      // Note: default values should be EnumClass::FAST and SWEET
       bool blah(speed s = FAST, flavor f = SWEET) { return (s == FAST && f == SWEET); };
   };
 
@@ -83,16 +84,16 @@
 
   // casts
   const char * casts1(const char *m = (const char *) NULL) {
-    char *ret = NULL; 
-    if (m) { 
+    char *ret = NULL;
+    if (m) {
       ret = new char[strlen(m)+1];
       strcpy(ret, m);
     }
     return ret;
   }
   const char * casts2(const char *m = (const char *) "Hello") {
-    char *ret = NULL; 
-    if (m) { 
+    char *ret = NULL;
+    if (m) {
       ret = new char[strlen(m)+1];
       strcpy(ret, m);
     }
@@ -108,16 +109,16 @@
   char chartest6(char c = '\x43') { return c; } // 'C'
 
   // namespaces
-  namespace AType { 
-    enum AType { NoType }; 
-  } 
+  namespace AType {
+    enum AType { NoType };
+  }
   void dummy(AType::AType aType = AType::NoType) {}
-  namespace A { 
-    namespace B { 
-      int CONST_NUM = 10; 
-    } 
+  namespace A {
+    namespace B {
+      int CONST_NUM = 10;
+    }
     int afunction(int i = B::CONST_NUM) { return i; }
-  } 
+  }
 
   // references
   int reftest1(const int &x = 42) { return x; }
@@ -131,7 +132,7 @@
       void test(int x = Oak + Fir + Cedar) {}
   };
   enum Tree::types chops(enum Tree::types type) { return type; }
- 
+
 %}
 
 // Rename a class member
@@ -143,7 +144,7 @@
 %rename(renamed2arg) Foo::renameme(int x) const;
 %rename(renamed1arg) Foo::renameme() const;
 
-%typemap(default) double* null_by_default "$1=0;";
+%typemap(default) double* null_by_default "$1=0;"
 
 %inline %{
   typedef void* MyHandle;
@@ -155,11 +156,11 @@
       static int spam;
 
       Foo(){}
-     
+
       Foo(int x, int y = 0, int z = 0){}
 
       void meth(int x, int y = 0, int z = 0){}
-    
+
       // Use a renamed member as a default argument.  SWIG has to resolve
       // bar to Foo::bar and not Foo::spam.  SWIG-1.3.11 got this wrong.
       // (Different default parameter wrapping in SWIG-1.3.23 ensures SWIG doesn't have to resolve these symbols).
@@ -189,20 +190,20 @@
 // tests valuewrapper
 %feature("compactdefaultargs") MyClass2::set;
 %inline %{
-  enum MyType { Val1, Val2 }; 
+  enum MyType { Val1, Val2 };
 
-  class MyClass1 
-  { 
-    public: 
+  class MyClass1
+  {
+    public:
       MyClass1(MyType myType) {}
-  }; 
+  };
 
-  class MyClass2 
-  { 
-    public : 
+  class MyClass2
+  {
+    public :
       void set(MyClass1 cl1 = Val1) {}
-      // This could have been written : set(MyClass1 cl1 = MyClass1(Val1)) 
-      // But it works in C++ since there is a "conversion" constructor in  MyClass1. 
+      // This could have been written : set(MyClass1 cl1 = MyClass1(Val1))
+      // But it works in C++ since there is a "conversion" constructor in  MyClass1.
       void set2(MyClass1 cl1 = Val1) {}
   };
 %}
@@ -228,7 +229,7 @@
 %}
 
 // Default parameters in static class methods
-#ifdef SWIGPYTHON
+#if defined(SWIGPYTHON) || defined(SWIGJAVASCRIPT)
 %rename(staticMethod) staticmethod;
 #endif
 
@@ -281,7 +282,7 @@
 };
 %}
 
-// const methods 
+// const methods
 // runtime test needed to check that the const method is called
 struct ConstMethods {
   int coo(double d = 0.0) const;
@@ -305,8 +306,8 @@
       return(x+p);
     }
 
-    typedef struct Pointf { 
-      double		x,y; 
+    typedef struct Pointf {
+      double		x,y;
     } Pointf;
   }
 %}
diff --git a/Examples/test-suite/derived_byvalue.i b/Examples/test-suite/derived_byvalue.i
index 21de809..34aedaa 100644
--- a/Examples/test-suite/derived_byvalue.i
+++ b/Examples/test-suite/derived_byvalue.i
@@ -83,7 +83,7 @@
   and by checking the typemaps.
   The typemap code also calls SwigType_remember(), if your typemaps
   defined an object type, it will be added into the SwigType table.
-  its normally a 
+  it's normally a
     SWIG_ConvertPtr(....$descriptor...)
   when it should have been a $&descriptor or $*descriptor
     
diff --git a/Examples/test-suite/director_basic.i b/Examples/test-suite/director_basic.i
index 07d6275..6c97695 100644
--- a/Examples/test-suite/director_basic.i
+++ b/Examples/test-suite/director_basic.i
@@ -5,6 +5,7 @@
 #endif
 
 %warnfilter(SWIGWARN_TYPEMAP_THREAD_UNSAFE,SWIGWARN_TYPEMAP_DIRECTOROUT_PTR) MyClass::pmethod;
+%warnfilter(SWIGWARN_TYPEMAP_DIRECTOROUT_PTR) ConstPtrClass::getConstPtr;
 
  %{
  #include <string>
@@ -48,7 +49,7 @@
  %inline %{
 
  struct A{
-     A(std::complex<int> i, double d=0.0) {}
+     A(std::complex<double> i, double d=0.0) {}
      A(int i, bool j=false) {}
      virtual ~A() {}
 
@@ -59,7 +60,7 @@
  namespace hi  {
 
    struct A1 : public A {
-     A1(std::complex<int> i, double d=0.0) : A(i, d) {}
+     A1(std::complex<double> i, double d=0.0) : A(i, d) {}
      A1(int i, bool j=false) : A(i, j) {}
 
      virtual int ff(int i = 0) {return i;}  
@@ -70,11 +71,12 @@
  %}
 
  %typemap(cscode) MyClass %{
+   // low level implementation check for checking MyOverriddenClass
    public void testSwigDerivedClassHasMethod() {
      if (SwigDerivedClassHasMethod("nonVirtual", swigMethodTypes3))
-       throw new global::System.Exception("non-overriding non-virtual method would be when connecting director");
+       throw new global::System.Exception("SwigDerivedClassHasMethod failed checking a non-overriding non-virtual method (nonVirtual)");
      if (SwigDerivedClassHasMethod("nonOverride", swigMethodTypes4))
-       throw new global::System.Exception("non-overriding virtual method would be when connecting director");
+       throw new global::System.Exception("SwigDerivedClassHasMethod failed checking a non-overriding method (nonOverride)");
    }
  %}
 
@@ -174,7 +176,19 @@
   }
   
 };
-
-%}
+ %}
 
 %template(MyClassT_i) MyClassT<int>;
+
+ %feature("director") ConstPtrClass;
+
+ %inline %{
+
+class ConstPtrClass {
+public:
+  virtual ~ConstPtrClass() {}
+  virtual int *const getConstPtr() = 0;
+};
+
+ %}
+
diff --git a/Examples/test-suite/director_binary_string.i b/Examples/test-suite/director_binary_string.i
index 17bdc1b..784f2be 100644
--- a/Examples/test-suite/director_binary_string.i
+++ b/Examples/test-suite/director_binary_string.i
@@ -4,10 +4,15 @@
 
 %apply (char *STRING, size_t LENGTH) { (char *dataBufferAA, int sizeAA) };
 %apply (char *STRING, size_t LENGTH) { (char *dataBufferBB, int sizeBB) };
+#ifdef SWIGD
+%apply (const char* STRING, size_t LENGTH) { (const char* data, size_t datalen) };
+#else
 %apply (char* STRING, size_t LENGTH) { (const void* data, size_t datalen) };
+#endif
 
 %inline %{
 #include <stdlib.h>
+#include <string.h>
 
 #define BUFFER_SIZE_AA 8
 #define BUFFER_SIZE_BB 5
@@ -21,7 +26,11 @@
     if (dataBufferBB)
       memset(dataBufferBB, -1, sizeBB);
   }
+  #ifdef SWIGD
+  virtual void writeData(const char* data, size_t datalen) = 0;
+  #else
   virtual void writeData(const void* data, size_t datalen) = 0;
+  #endif
 };
 
 class Caller {
diff --git a/Examples/test-suite/director_classes.i b/Examples/test-suite/director_classes.i
index 52342bf..f8c4e68 100644
--- a/Examples/test-suite/director_classes.i
+++ b/Examples/test-suite/director_classes.i
@@ -56,10 +56,10 @@
   virtual std::string SemiOverloaded(int x) { if (PrintDebug) std::cout << "Base - SemiOverloaded(int " << x << ")" << std::endl; return "Base::SemiOverloaded(int)"; }
   virtual std::string SemiOverloaded(bool x) { if (PrintDebug) std::cout << "Base - SemiOverloaded(bool " << x << ")" << std::endl; return "Base::SemiOverloaded(bool)"; }
 
-  virtual std::string DefaultParms(int x, double y = 1.1) {
+  virtual std::string DefaultParms(int x, double y = 1.125) {
     if (PrintDebug) std::cout << "Base - DefaultParms(" << x << ", " << y << ")" << std::endl;
     std::string ret("Base::DefaultParms(int");
-    if (y!=1.1)
+    if (y!=1.125)
       ret = ret + std::string(", double");
     ret = ret + std::string(")");
     return ret;
@@ -82,10 +82,10 @@
   virtual std::string SemiOverloaded(int x) { if (PrintDebug) std::cout << "Derived - SemiOverloaded(int " << x << ")" << std::endl; return "Derived::SemiOverloaded(int)"; }
   // No SemiOverloaded(bool x)
 
-  virtual std::string DefaultParms(int x, double y = 1.1) { 
+  virtual std::string DefaultParms(int x, double y = 1.125) {
     if (PrintDebug) std::cout << "Derived - DefaultParms(" << x << ", " << y << ")" << std::endl;
     std::string ret("Derived::DefaultParms(int");
-    if (y!=1.1)
+    if (y!=1.125)
       ret = ret + std::string(", double");
     ret = ret + std::string(")");
     return ret;
diff --git a/Examples/test-suite/director_comparison_operators.i b/Examples/test-suite/director_comparison_operators.i
new file mode 100644
index 0000000..f2251ed
--- /dev/null
+++ b/Examples/test-suite/director_comparison_operators.i
@@ -0,0 +1,23 @@
+%module(directors="1") director_comparison_operators
+
+%include "std_string.i"
+%feature("director");
+
+#if !defined(SWIGLUA) && !defined(SWIGR)
+%rename(EqualEqual) operator ==;
+%rename(NotEqual) operator !=;
+%rename(LessThanEqual) operator <=;
+%rename(GreaterThanEqual) operator >=;
+#endif
+
+%inline %{
+class Foo {
+public:
+  virtual ~Foo() { }
+  virtual bool operator==(const Foo&) const = 0;
+  virtual bool operator>=(const Foo&) const = 0;
+  virtual bool operator<=(const Foo&) const = 0;
+  virtual bool operator!=(const Foo&) const = 0;
+  virtual std::string test(const char *foo="a=1,b=2") { return foo; }
+};
+%}
diff --git a/Examples/test-suite/director_conversion_operators.i b/Examples/test-suite/director_conversion_operators.i
new file mode 100644
index 0000000..afcd49d
--- /dev/null
+++ b/Examples/test-suite/director_conversion_operators.i
@@ -0,0 +1,35 @@
+%module(directors="1") director_conversion_operators
+
+%feature("director");
+
+%warnfilter(SWIGWARN_TYPEMAP_DIRECTOROUT_PTR) Bar;
+
+%rename(toFoo) Bar::operator Foo();
+%rename(toFooPtr) Bar::operator Foo *();
+%rename(toFooRef) Bar::operator Foo &();
+%rename(toFooPtrRef) Bar::operator Foo *&();
+
+%rename(toOtherFoo) Bar::operator OtherFoo();
+%rename(toOtherFooPtr) Bar::operator OtherFoo *();
+%rename(toOtherFooRef) Bar::operator OtherFoo &();
+%rename(toOtherFooPtrRef) Bar::operator OtherFoo *&();
+
+%inline %{
+   struct Foo {
+   };
+   struct OtherFoo {
+   };
+   struct Bar {
+      Foo myFoo;
+      Foo *myFooPtr;
+      virtual ~Bar() { }
+      virtual operator Foo () { return Foo(); }
+      virtual operator Foo *() { return &myFoo; }
+      virtual operator Foo &() { return myFoo; }
+      virtual operator Foo *&() { return myFooPtr; }
+      virtual operator OtherFoo () = 0;
+      virtual operator OtherFoo *() = 0;
+      virtual operator OtherFoo &() = 0;
+      virtual operator OtherFoo *&() = 0;
+   };
+%}
diff --git a/Examples/test-suite/director_exception.i b/Examples/test-suite/director_exception.i
index 71366be..8e76c07 100644
--- a/Examples/test-suite/director_exception.i
+++ b/Examples/test-suite/director_exception.i
@@ -18,22 +18,7 @@
 
 %include "std_string.i"
 
-#ifdef SWIGPHP
-
-%feature("director:except") {
-  if ($error == FAILURE) {
-    Swig::DirectorMethodException::raise("$symname");
-  }
-}
-
-%exception {
-  try { $action }
-  catch (Swig::DirectorException &) { SWIG_fail; }
-}
-
-#endif
-
-#ifdef SWIGPYTHON
+#if defined SWIGPHP || defined SWIGPYTHON
 
 %feature("director:except") {
   if ($error != NULL) {
@@ -63,7 +48,7 @@
 %feature("director:except") {
   jthrowable $error = jenv->ExceptionOccurred();
   if ($error) {
-    // Dont clear exception, still be active when return to java execution
+    // Don't clear exception, still be active when return to java execution
     // Essentially ignore exception occurred -- old behavior.
     return $null;
   }
diff --git a/Examples/test-suite/director_multiple_inheritance.i b/Examples/test-suite/director_multiple_inheritance.i
new file mode 100644
index 0000000..ff50cfe
--- /dev/null
+++ b/Examples/test-suite/director_multiple_inheritance.i
@@ -0,0 +1,71 @@
+//%module(ruby_minherit="1") multiple_inheritance
+%module(directors="1") director_multiple_inheritance
+
+%feature("director") A;
+%feature("director") B;
+%feature("director") C;
+%feature("director") D;
+
+%inline %{
+
+class A {
+public:
+    virtual ~A() { }
+    virtual int testA();
+};
+
+class B: virtual public A {
+public:
+    virtual ~B() { }
+    virtual int testB();
+};
+
+class C: virtual public A {
+public:
+    virtual ~C() { }
+    virtual int testC();
+};
+
+class D: virtual public A {
+public:
+    virtual ~D() { }
+    virtual int testD();
+};
+
+class E {
+public:
+    virtual ~E() { }
+    virtual int testE(B*);
+};
+
+class F {
+public:
+    virtual ~F() { }
+    virtual int testF(C*);
+};
+
+class T {
+public:
+    virtual ~T() { }
+    virtual int testT(D*);
+};
+
+%}
+
+%{
+
+int A::testA() { return 1; }
+
+int B::testB() { return 2; }
+
+int C::testC() { return 3; }
+
+int D::testD() { return 4; }
+
+int E::testE(B*) { return 5; }
+
+int F::testF(C*) { return 6; }
+
+int T::testT(D*) { return 20; }
+
+%}
diff --git a/Examples/test-suite/director_nspace.i b/Examples/test-suite/director_nspace.i
index f24227c..016f61d 100644
--- a/Examples/test-suite/director_nspace.i
+++ b/Examples/test-suite/director_nspace.i
@@ -15,7 +15,6 @@
     class FooBar {
     public:
       FooBar() {}
-      FooBar(const FooBar&) {}
       virtual ~FooBar() {}
       
       std::string FooBarDo() { return "Bar::Foo2::Foo2Bar()"; }
@@ -56,7 +55,6 @@
     class FooBar {
     public:
       FooBar();
-      FooBar(const FooBar&);
       virtual ~FooBar();
       
       std::string FooBarDo();
diff --git a/Examples/test-suite/director_overload.i b/Examples/test-suite/director_overload.i
index 604ffe5..d6feb12 100644
--- a/Examples/test-suite/director_overload.i
+++ b/Examples/test-suite/director_overload.i
@@ -47,5 +47,14 @@
   virtual void notover(int *p) const {}
 };
 
-%}
+class OverloadedGetSet
+{
+  int v;
+public:
+  OverloadedGetSet() : v(42) { }
+  virtual ~OverloadedGetSet() { }
+  virtual int rw() const { return v; }
+  virtual void rw(int new_v) { v = new_v; }
+};
 
+%}
diff --git a/Examples/test-suite/director_overload2.i b/Examples/test-suite/director_overload2.i
index e467c18..9d020e1 100644
--- a/Examples/test-suite/director_overload2.i
+++ b/Examples/test-suite/director_overload2.i
@@ -23,4 +23,3 @@
   virtual void nnn() {}
 };
 %}
-
diff --git a/Examples/test-suite/director_pass_by_value.i b/Examples/test-suite/director_pass_by_value.i
index 31d8ce2..6eb62f0 100644
--- a/Examples/test-suite/director_pass_by_value.i
+++ b/Examples/test-suite/director_pass_by_value.i
@@ -1,14 +1,34 @@
 %module(directors="1") director_pass_by_value
+
 %director DirectorPassByValueAbstractBase;
 
+%include "cpp11_move_only_helper.i"
+
+%ignore PassedByValue::operator=;
+%ignore PassedByValue::PassedByValue(PassedByValue &&);
+
 %inline %{
-class PassedByValue {
-  int val;
-public:
-  PassedByValue() { val = 0x12345678; }
+#include <iostream>
+using namespace std;
+int trace = false;
+struct PassedByValue {
+  PassedByValue(int v = 0x12345678) { val = v; if (trace) cout << "PassedByValue(0x" << hex << val << ")" << " " << this << endl; Counter::normal_constructor++; }
+
+  PassedByValue(const PassedByValue &other) { val = other.val; if (trace) cout << "PassedByValue(const PassedByValue &)" << " " << this << " " << &other << endl; Counter::copy_constructor++;}
+  PassedByValue & operator=(const PassedByValue &other) { val = other.val; if (trace) cout << "operator=(const PassedByValue &)" << " " << this << " " << &other << endl; Counter::copy_assignment++; return *this; }
+
+#if __cplusplus >= 201103L
+  PassedByValue(PassedByValue &&other) noexcept { val = other.val; if (trace) cout << "PassedByValue(PassedByValue &&)" << " " << this << endl; Counter::move_constructor++; }
+  PassedByValue & operator=(PassedByValue &&other) noexcept { val = other.val; if (trace) cout << "operator=(PassedByValue &&)" << " " << this << endl; Counter::move_assignment++; return *this; }
+  ~PassedByValue() { if (trace) cout << "~PassedByValue()" << " " << this << endl; Counter::destructor++; }
+#endif
+
   int getVal() { return val; }
+private:
+  int val;
 };
 
+
 int doSomething(int x) {
   int yy[256];
   yy[0] =0x9876;
@@ -18,6 +38,7 @@
 class DirectorPassByValueAbstractBase {
 public:
   virtual void virtualMethod(PassedByValue pbv) = 0;
+  virtual void virtualConstMethod(const PassedByValue pbv) {}
   virtual ~DirectorPassByValueAbstractBase () {}
 };
 
@@ -27,4 +48,12 @@
     f.virtualMethod(PassedByValue());
   }
 };
+
+bool has_cplusplus11() {
+#if __cplusplus >= 201103L
+  return true;
+#else
+  return false;
+#endif
+}
 %}
diff --git a/Examples/test-suite/director_property.i b/Examples/test-suite/director_property.i
index d64e0c4..ef0f2ff 100644
--- a/Examples/test-suite/director_property.i
+++ b/Examples/test-suite/director_property.i
@@ -18,9 +18,9 @@
    virtual std::string pong() { return "Foo::pong();" + ping(); }
    virtual std::string getA() { return this->a_; }
    virtual void setA(std::string a) { this->a_ = a; }
+   virtual void setAByRef(const std::string &a) { this->a_ = a; }
 
    static Foo* get_self(Foo *slf) {return slf;}
-   
  };
 
  %}
@@ -37,9 +37,9 @@
    virtual std::string pong();
    virtual std::string getA();
    virtual void setA(std::string a);
+   virtual void setAByRef(const std::string &a);
    
    static Foo* get_self(Foo *slf);
-   
  };
 
  %{
@@ -54,7 +54,7 @@
  %inline %{
 
  struct A{
-     A(std::complex<int> i, double d=0.0) {}
+     A(std::complex<double> i, double d=0.0) {}
      A(int i, bool j=false) {}
      virtual ~A() {}
 
@@ -65,7 +65,7 @@
  namespace hi  {
 
    struct A1 : public A {
-     A1(std::complex<int> i, double d=0.0) : A(i, d) {}
+     A1(std::complex<double> i, double d=0.0) : A(i, d) {}
      A1(int i, bool j=false) : A(i, j) {}
 
      virtual int ff(int i = 0) {return i;}  
diff --git a/Examples/test-suite/director_protected.i b/Examples/test-suite/director_protected.i
index 0299b23..122addb 100644
--- a/Examples/test-suite/director_protected.i
+++ b/Examples/test-suite/director_protected.i
@@ -11,13 +11,6 @@
 
 %newobject *::create();
 
-#ifdef SWIGPHP
-// TODO: Currently we do not track the dynamic type of returned objects
-// in PHP, so we need the factory helper.
-%include factory.i
-%factory(Foo *Bar::create, Bar);
-#endif
-
 %rename(a) Bar::hello;
 %rename(s) Foo::p;
 %rename(q) Foo::r;
diff --git a/Examples/test-suite/director_simple.i b/Examples/test-suite/director_simple.i
new file mode 100644
index 0000000..0883cae
--- /dev/null
+++ b/Examples/test-suite/director_simple.i
@@ -0,0 +1,42 @@
+%module(directors="1") director_simple
+
+%feature("director") IntBase;
+%feature("director") BoolBase;
+
+%inline %{
+class IntBase {
+ public:
+  virtual ~IntBase() {}
+  IntBase(int i = 3) { (void)i; }
+  virtual int apply(int x) const { return x * 2; }
+};
+
+class IntDerived : public IntBase {
+ public:
+  virtual int apply(int x) const { return x * 3; }
+};
+
+int apply(const IntBase& b, int x)
+{
+  return b.apply(x);
+}
+
+class BoolBase {
+ public:
+  virtual ~BoolBase() {}
+  BoolBase() {}
+  virtual bool apply(bool a, bool b) const = 0;
+};
+
+class BoolDerived : public BoolBase {
+ public:
+  virtual bool apply(bool a, bool b) const { return a != b; }
+};
+
+bool apply(const BoolBase& base, bool a, bool b)
+{
+  return base.apply(a, b);
+}
+
+%}
+
diff --git a/Examples/test-suite/director_stl.i b/Examples/test-suite/director_stl.i
index 46946e5..cbcb4ba 100644
--- a/Examples/test-suite/director_stl.i
+++ b/Examples/test-suite/director_stl.i
@@ -17,11 +17,7 @@
 %feature("director") Foo;
 
 %feature("director:except") {
-#ifndef SWIGPHP
   if ($error != NULL) {
-#else
-  if ($error == FAILURE) {
-#endif
     throw Swig::DirectorMethodException();
   }
 }
diff --git a/Examples/test-suite/director_template.i b/Examples/test-suite/director_template.i
new file mode 100644
index 0000000..fdc5bfb
--- /dev/null
+++ b/Examples/test-suite/director_template.i
@@ -0,0 +1,28 @@
+%module(directors="1") director_template
+
+%{
+#include <vector>
+%}
+
+%include <std_vector.i>
+
+%feature("director") HandleBytes;
+
+%inline %{
+  template <typename X, typename Y> class TwoTemplateParms {};
+%}
+
+%template(TT_int_double) TwoTemplateParms<int, double>;
+
+%inline %{
+  class HandleBytes {
+  public:
+    virtual void handle(const std::vector<unsigned char> data) = 0; // Note: not instantiated with %template
+    virtual void handle2(TwoTemplateParms<int, double> data) = 0;
+    virtual ~HandleBytes() {}
+  };
+
+  void bytes_wrapper(const std::vector<unsigned char> data, HandleBytes *handler) {
+    handler->handle(data);
+  }
+%}
diff --git a/Examples/test-suite/director_thread.i b/Examples/test-suite/director_thread.i
index c456473..845f8e0 100644
--- a/Examples/test-suite/director_thread.i
+++ b/Examples/test-suite/director_thread.i
@@ -20,7 +20,6 @@
 #ifdef _WIN32
 #include <windows.h>
 #include <process.h>
-#include <stdio.h>
 #else
 #include <pthread.h>
 #include <errno.h>
@@ -30,6 +29,7 @@
 #endif
 
 #include <assert.h>
+#include <stdio.h>
 #include "swig_examples_lock.h"
 
 class Foo;  
@@ -42,15 +42,15 @@
   static pthread_t thread;
 #endif
 
-  static int thread_terminate = 0;
+  static int swig_thread_terminate = 0;
   static SwigExamples::CriticalSection critical_section;
   int get_thread_terminate() {
     SwigExamples::Lock lock(critical_section);
-    return thread_terminate;
+    return swig_thread_terminate;
   }
   void set_thread_terminate(int value) {
     SwigExamples::Lock lock(critical_section);
-    thread_terminate = value;
+    swig_thread_terminate = value;
   }
 }
 %}
@@ -73,7 +73,7 @@
     Foo() : val(0) {
     }
     
-    virtual ~Foo()  {
+    virtual ~Foo() {
     }
 
     void stop() {
diff --git a/Examples/test-suite/director_unwrap_result.i b/Examples/test-suite/director_unwrap_result.i
new file mode 100644
index 0000000..1acc614
--- /dev/null
+++ b/Examples/test-suite/director_unwrap_result.i
@@ -0,0 +1,93 @@
+%module(directors="1") director_unwrap_result
+
+%warnfilter(SWIGWARN_TYPEMAP_DIRECTOROUT_PTR) Storage;
+%warnfilter(SWIGWARN_TYPEMAP_DIRECTOROUT_PTR) StorageTmpl;
+
+%feature("director") Element;
+%feature("director") Storage;
+%feature("director") StorageTmpl;
+
+%inline %{
+
+class Element {
+  Element* self;
+  Element** selfptr;
+  public:
+    Element() {
+      self = this;
+      selfptr = &self;
+    }
+    virtual ~Element() {}
+    Element **getPtrPtr() {
+      return &self;
+    }
+    Element ***getPtrPtrPtr() {
+      return &selfptr;
+    }
+};
+typedef Element * element_ptr_t;
+typedef Element & element_ref_t;
+
+class Storage {
+  public:
+    virtual ~Storage() {}
+    virtual Element **getIt() = 0;
+    Element getElement() {
+      return **getIt();
+    }
+    Element* const getElementPtr() {
+      return *getIt();
+    }
+    Element& getElementRef() {
+      return **getIt();
+    }
+    Element* const *getElementPtrPtr() {
+      return getIt();
+    }
+    Element *&getElementPtrRef() {
+      return *getIt();
+    }
+    element_ref_t getElementRefTypedef() {
+      return **getIt();
+    }
+    element_ptr_t getElementPtrTypedef() {
+      return *getIt();
+    }
+    element_ptr_t &getElementPtrRefTypedef() {
+      return *getIt();
+    }
+};
+
+template<class T> class StorageTmpl {
+  public:
+    virtual ~StorageTmpl() {}
+    virtual T &getIt() = 0;
+    T getVal() {
+      return getIt();
+    }
+    T *getPtr() {
+      return &getIt();
+    }
+    T &getRef() {
+      return getIt();
+    }
+};
+
+%}
+
+%template(ElementStorage) StorageTmpl<Element>;
+%template(ElementPtrStorage) StorageTmpl<Element *>;
+%template(ElementPtrPtrStorage) StorageTmpl<Element *const *>;
+
+%inline %{
+
+template<class T> T getParam(T t) {
+  return t;
+}
+
+%}
+
+%template(getIntParam) getParam<int>;
+%template(getIntPtrParam) getParam<int*>;
+%template(getElementPtrParam) getParam<Element *>;
+
diff --git a/Examples/test-suite/director_using.i b/Examples/test-suite/director_using.i
index d86546e..1eec373 100644
--- a/Examples/test-suite/director_using.i
+++ b/Examples/test-suite/director_using.i
@@ -1,7 +1,5 @@
 %module(directors="1",dirprot="1") director_using
 
-%warnfilter(SWIGWARN_PHP_PUBLIC_BASE) FooBar;
-
 %{
 #include <string>
 #include <iostream>
diff --git a/Examples/test-suite/director_using_member_scopes.i b/Examples/test-suite/director_using_member_scopes.i
new file mode 100644
index 0000000..d2776ea
--- /dev/null
+++ b/Examples/test-suite/director_using_member_scopes.i
@@ -0,0 +1,55 @@
+%module(directors="1") director_using_member_scopes
+
+// Similar to using_member_scopes but for directors
+
+#if !defined(SWIGGO) // TODO: fix Go crash
+
+%feature("director");
+// Python,Java,C# no diffs in generated code when adding in nodirector. Go not happy even without %nodirector.
+// Fully qualifying parameter types in a method declared after the using declaration caused
+// a method being incorrectly added by the using declaration even though the declaration already existed
+
+// Github issue #1441 - segfault in Go and C#
+
+%inline %{
+namespace OgreBites
+{
+    struct NativeWindowType {};
+    class ApplicationContextBase {
+    public:
+        virtual ~ApplicationContextBase() {}
+        virtual int setWindowGrab(NativeWindowType* win, bool grab = true) { return 0; }
+        int setWindowGrab(bool grab = true) { return 5; }
+
+        static int call_setWindowGrab(ApplicationContextBase* ptr, NativeWindowType* win, bool grab) { return ptr->setWindowGrab(win, grab); }
+    };
+    class ApplicationContextSDL : public ApplicationContextBase {
+    public:
+        using ApplicationContextBase::setWindowGrab;
+        int setWindowGrab(NativeWindowType* win, bool grab = true) { return 10; } // This should not be added again as it exists in base class
+
+        static int call_setWindowGrab(ApplicationContextSDL* ptr, NativeWindowType* win, bool grab) { return ptr->setWindowGrab(win, grab); }
+    };
+
+    class ACB {
+    public:
+        virtual ~ACB() {}
+        virtual int setWindowGrab(NativeWindowType* win, bool grab = true) { return 0; }
+        virtual int setWindowGrab(const char *s, int val) { return 1; } // Additional method compared to ApplicationContextBase
+        int setWindowGrab(bool grab = true) { return 5; }
+
+        static int call_setWindowGrab(ACB* ptr, NativeWindowType* win, bool grab) { return ptr->setWindowGrab(win, grab); }
+        static int call_setWindowGrab(ACB* ptr, const char *s, int val) { return ptr->setWindowGrab(s, val); }
+    };
+    class ACSDL : public ACB {
+    public:
+        using ACB::setWindowGrab; // This introduces two methods, not one method like ApplicationContextSDL
+        int setWindowGrab(NativeWindowType* win, bool grab = true) { return 10; } // This should not be added again as it exists in base class
+
+        static int call_setWindowGrab(ACSDL* ptr, NativeWindowType* win, bool grab) { return ptr->setWindowGrab(win, grab); }
+        static int call_setWindowGrab(ACSDL* ptr, const char *s, int val) { return ptr->setWindowGrab(s, val); }
+    };
+}
+%}
+
+#endif
diff --git a/Examples/test-suite/director_void.i b/Examples/test-suite/director_void.i
index 40f53b6..d9d99aa 100644
--- a/Examples/test-suite/director_void.i
+++ b/Examples/test-suite/director_void.i
@@ -43,5 +43,9 @@
     return *(int *)p;
   }
 };
+
+struct MemberVoid {
+  void *memberVariable;
+};
 %}
 
diff --git a/Examples/test-suite/director_wstring.i b/Examples/test-suite/director_wstring.i
index 17761ea..02df9d6 100644
--- a/Examples/test-suite/director_wstring.i
+++ b/Examples/test-suite/director_wstring.i
@@ -39,10 +39,11 @@
 
   std::vector<std::wstring> m_strings;
 
+  virtual const wchar_t * wchar_out() { return L"ciao"; }
 
-  virtual void process_text(const wchar_t *text) 
-  {
-  }
+  virtual void process_text(const wchar_t *text) {}
+  virtual void process_wstring_text(std::wstring text) {}
+  virtual void process_wstring_ref_text(const std::wstring& text) {}
 
   virtual std::wstring multiple_params_val(const std::wstring& p1, const std::wstring& p2, std::wstring p3, std::wstring p4) const
   { return get_first(); }
@@ -51,6 +52,8 @@
   { return get_first(); }
   
   void call_process_func() { process_text(L"hello"); }
+  void call_process_wstring_func() { process_wstring_text(L"hello"); }
+  void call_process_wstring_ref_func() { process_wstring_ref_text(L"hello"); }
  };
  
  %}
diff --git a/Examples/test-suite/doxygen_autodoc_docstring.i b/Examples/test-suite/doxygen_autodoc_docstring.i
new file mode 100644
index 0000000..e590d7f
--- /dev/null
+++ b/Examples/test-suite/doxygen_autodoc_docstring.i
@@ -0,0 +1,75 @@
+%module doxygen_autodoc_docstring
+
+%feature("autodoc", 1);
+
+%feature("docstring") ClassWithDocString "Class doc from docstring";
+%feature("docstring") functionWithDocString "Function doc from docstring";
+%feature("docstring") ClassWithDocStringAndDoxygenComment "Class doc from docstring overriding doxycomment";
+%feature("docstring") functionWithDocStringAndDoxygenComment "Function doc from docstring overriding doxycomment";
+
+%inline %{
+class ClassWithoutDoxygenComment {};
+
+void functionWithoutDoxygenComment(int number) {}
+
+/**
+ * Class doxygen comment
+ */
+class ClassWithDoxygenComment {};
+
+/**
+ * Function doxygen comment
+ */
+void functionWithDoxygenComment(int number) {}
+
+class ClassWithDocString {};
+
+void functionWithDocString(int number) {}
+
+/**
+ * Class doxygen comment
+ */
+class ClassWithDocStringAndDoxygenComment {};
+
+/**
+ * Function doxygen comment
+ */
+void functionWithDocStringAndDoxygenComment(int number) {}
+%}
+
+
+%feature("autodoc", ""); // clear autodoc
+
+%feature("docstring") ClassWithDocStringAndDoxygenCommentNoAutodoc "Class doc from docstring overriding doxycomment (no autodoc)";
+%feature("docstring") functionWithDocStringAndDoxygenCommentNoAutodoc "Function doc from docstring overriding doxycomment (no autodoc)";
+
+%inline %{
+/**
+ * Class doxygen comment
+ */
+class ClassWithDocStringAndDoxygenCommentNoAutodoc {};
+
+/**
+ * Function doxygen comment
+ */
+void functionWithDocStringAndDoxygenCommentNoAutodoc(int number) {}
+
+/**
+ * Class doxygen comment 2
+ */
+class ClassWithDoxygenComment2 {};
+
+/**
+ * Function doxygen comment 2
+ */
+void functionWithDoxygenComment2(int number) {}
+%}
+
+%inline %{
+#ifdef SWIGPYTHON_BUILTIN
+bool is_python_builtin() { return true; }
+#else
+bool is_python_builtin() { return false; }
+#endif
+%}
+
diff --git a/Examples/test-suite/doxygen_basic_translate.i b/Examples/test-suite/doxygen_basic_translate.i
index da4d809..4e543fe 100644
--- a/Examples/test-suite/doxygen_basic_translate.i
+++ b/Examples/test-suite/doxygen_basic_translate.i
@@ -107,6 +107,23 @@
     return 0;
 }
 
+/* Regression test for crash with empty comment: */
+/**/ 
+
+/**
+ * @brief Test variadic function
+ * @param ... extra args
+ */
+void function8(...) {
+}
+
+/**
+ * @brief Test unnamed argument
+ * @param baz Description of baz
+ */
+void function9(int) {
+} 
+
 /**
  * Comment at the end of file should be ignored.
  */
diff --git a/Examples/test-suite/doxygen_basic_translate_style3.i b/Examples/test-suite/doxygen_basic_translate_style3.i
new file mode 100644
index 0000000..e364b16
--- /dev/null
+++ b/Examples/test-suite/doxygen_basic_translate_style3.i
@@ -0,0 +1,102 @@
+%module doxygen_basic_translate_style3
+
+%include "doxygen_basic_translate.h"
+
+%inline %{
+
+/// \brief
+/// Brief description.
+///
+/// The comment text.
+///
+/// \author Some author
+///
+/// \return Some number
+///
+/// \sa function2
+int function()
+{
+    return 0;
+}
+
+/// A test of a very very very very very very very very very very very very very very very very
+/// very very very very very long comment string.
+void function2()
+{
+}
+
+/// A test for overloaded functions
+/// This is function \b one
+void function3(int a)
+{
+}
+
+/// A test for overloaded functions
+/// This is function \b two
+void function3(int a, int b)
+{
+}
+
+/// A test of some mixed tag usage
+/// \if CONDITION
+/// This \a code fragment shows us something \.
+/// \par Minuses:
+/// \arg it's senseless
+/// \arg it's stupid
+/// \arg it's null
+///
+/// \warning This may not work as expected
+/// \code
+/// int main() { while(true); }
+///
+/// int testBlankLine() {}
+/// \endcode
+/// \endif
+void function4()
+{
+  // Note: a comment in the above code block will not get processed
+  // correctly with this doxygen comment style, because
+  // DoxygenParser::tokenizeDoxygenComment strips out the leading
+  // comment characters.  Whereas it works in the other doxygen
+  // comment styles (as shown in the other variations of
+  // doxygen_basic_translate), this test is modified to remove the
+  // comment within the code block.
+}
+
+
+void function5(int a)
+{
+}
+///< This is a post comment.
+
+/// Test for default args
+/// @param a Some parameter, default is 42
+void function6(int a=42)
+{
+}
+
+class Shape
+{
+public:
+  typedef Shape* superType;
+};
+
+/// Test for a parameter with difficult type
+/// (mostly for python)
+/// @param a Very strange param
+void function7(Shape::superType *a[10])
+{
+}
+
+/// Multiple parameters test.
+///
+/// @param y Vertical coordinate.
+/// @param x Horizontal coordinate.
+/// @return Arc tangent of @c y/x.
+double Atan2(double y, double x)
+{
+    return 0;
+}
+
+/// Comment at the end of file should be ignored.
+%}
diff --git a/Examples/test-suite/doxygen_code_blocks.i b/Examples/test-suite/doxygen_code_blocks.i
new file mode 100644
index 0000000..900e8f9
--- /dev/null
+++ b/Examples/test-suite/doxygen_code_blocks.i
@@ -0,0 +1,62 @@
+%module doxygen_code_blocks
+
+// This test is only used with Python
+
+%inline %{
+
+/**
+ * \brief Test for code blocks
+ *
+ * \code
+ * simple code block
+ * \endcode
+ *
+ * More advanced usage with C++ characters:
+ * \code
+ * std::vector<int> first;                                // empty vector of ints
+ * std::vector<int> second (4,100);                       // four ints with value 100
+ * std::vector<int> third (second.begin(),second.end());  // iterating through second
+ * std::vector<int> fourth (third);                       // a copy of third
+ *  // the iterator constructor can also be used to construct from arrays:
+ * int myints[] = {16,2,77,29};
+ * std::vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );
+ *
+ * std::cout << "The contents of fifth are:";
+ * for (std::vector<int>::iterator it = fifth.begin(); it != fifth.end(); ++it)
+ *   std::cout << ' ' << *it;
+ * std::cout << '\n'; 
+ * \endcode
+ *
+ * A code block for C:
+ * \code{.c}
+ * printf("hello world");
+ * \endcode
+ *
+ * A code block for Java:
+ * \code{.java}
+ * public class HelloWorld {
+ *     public static void main(String[] args) {
+ *         // Prints "Hello, World" to the terminal window.
+ *         System.out.println("Hello, World");
+ *     }
+ * }
+ * \endcode
+ * 
+ * A code block for python:
+ * \code{.py}
+ * print('hello world')
+ * \endcode
+ *
+ * A python doctest example:
+ * \code{.py}
+ * >>> 1 + 1
+ * 2
+ * \endcode
+ */
+int function()
+{
+    return 0;
+}  
+
+
+%}
diff --git a/Examples/test-suite/doxygen_misc_constructs.h b/Examples/test-suite/doxygen_misc_constructs.h
index d677dc3..9e81aaf 100644
--- a/Examples/test-suite/doxygen_misc_constructs.h
+++ b/Examples/test-suite/doxygen_misc_constructs.h
@@ -91,4 +91,12 @@
 void cycle(int id, char *fileName)
 {}
 
+/// This doc comment ends with a quote: "and that's ok"
+void doc_ends_with_quote() {}
 
+/**
+    This comment contains embedded triple-quoted string:
+
+        """How quaint"""
+ */
+void doc_with_triple_quotes() {}
diff --git a/Examples/test-suite/doxygen_misc_constructs.i b/Examples/test-suite/doxygen_misc_constructs.i
index c1b3eea..395d735 100644
--- a/Examples/test-suite/doxygen_misc_constructs.i
+++ b/Examples/test-suite/doxygen_misc_constructs.i
@@ -36,7 +36,7 @@
      * @param line line number
      * @param isGetSize if set, for every object location both address and size are returned
      *
-     * @link Connection::getId() @endlink <br>
+     * @link Connection::getId() @endlink<br>
      */
     void getAddress(int &fileName,
                     int line,
@@ -62,7 +62,7 @@
      * used for unspecified parameters.
      * <p>
      *
-     * @link advancedWinIDEALaunching.py Python example.@endlink <br>
+     * @link advancedWinIDEALaunching.py Python example.@endlink<br>
      */
     class CConnectionConfig
     {
@@ -95,13 +95,68 @@
     class ClassWithNestedEnum {
     public:
         /**
-         * Enum description.
+         * ENested description.
          */
         typedef enum {ONE,  ///< desc of one
                       TWO,  ///< desc of two
                       THREE ///< desc of three
         } ENested;
 
+        /**
+         * ENestedOdd description.
+         */
+        typedef enum {ODD_ONE   ///< desc of odd_one
+                     ,ODD_TWO   ///< desc of odd_two
+                     ,ODD_THREE ///< desc of odd_three
+        } ENestedOdd;
+
+        /**
+         * ENestedOddPartial1 description.
+         */
+        typedef enum {ODD_PARTIAL1_ONE
+                     ,ODD_PARTIAL1_TWO   ///< desc of odd_partial1_two
+                     ,ODD_PARTIAL1_THREE ///< desc of odd_partial1_three
+        } ENestedOddPartial1;
+
+        /**
+         * ENestedOddPartial3 description.
+         */
+        typedef enum {ODD_PARTIAL3_ONE   ///< desc of odd_partial3_one
+                     ,ODD_PARTIAL3_TWO   ///< desc of odd_partial3_two
+                     ,ODD_PARTIAL3_THREE
+        } ENestedOddPartial3;
+
+        /** Description for TESTENUM. */
+        enum TESTENUM
+        {
+          /** something for none */
+          TEST_NONE = 0,
+          /** something for one */
+          TEST_ONE,
+          /** something for two */
+          TEST_TWO  /** something more for two */
+        };
+    };
+
+    /// SIOBeam struct description
+    struct SIOBeam {
+
+      /** testfunction - testing extra trailing doc comment */
+      void testfunction(
+          /** testfunction aaa parm */
+          int testf_aaa,
+          /** testfunction bbb parm */
+          double testf_bbb,
+          /** testfunction ccc parm */
+          bool testf_ccc /** testfunction more for two parm */
+          ) {}
+
+      /// Constructor for input from an existing SIO file
+      explicit SIOBeam(
+          const char * filename,   ///< Name of input SIO file.
+          int elevationOrder=1, ///< Interpolation order (0-3) in elevation
+          int bearingOrder=1   ///< Interpolation order (0-3) in bearing
+          ) {}
     };
 
     /// @return This is a bad place for this tag, but it should be ignored.
@@ -121,6 +176,13 @@
      */
     void showList() { }
 
+    /** Incorrectly documented members, these should be post document comments, Github issue #1636 */
+    struct IncorrectlyDocumentedMembers
+    {
+      int aaaa; //! really for bbbb value
+      int bbbb; //! not for bbbb value, is quietly ignored by Doxygen and SWIG
+    };
+
     #include "doxygen_misc_constructs.h"
 
 %}
diff --git a/Examples/test-suite/doxygen_parsing.i b/Examples/test-suite/doxygen_parsing.i
index 40f37a4..ddb9961 100644
--- a/Examples/test-suite/doxygen_parsing.i
+++ b/Examples/test-suite/doxygen_parsing.i
@@ -29,6 +29,7 @@
  */
 struct SomeStruct
 {
+   int width; ///< \**immutable** image width in pixels
 };
 
 /**
@@ -132,6 +133,25 @@
 	}
 };
 
+struct Foo1636
+{
+  ///@{
+  /// groupmember1 description
+  int groupmember1;
+  /// groupmember2 description
+  int groupmember2;
+  ///@}
+};
+
+struct Foo1750
+{
+  /// @name Group name
+  /// @{
+  int a;
+  /// @}
+  int b;
+};
+
 #ifdef SWIGPYTHON_BUILTIN
 bool is_python_builtin() { return true; }
 #else
diff --git a/Examples/test-suite/doxygen_translate.i b/Examples/test-suite/doxygen_translate.i
index bb0af1c..0d11a21 100644
--- a/Examples/test-suite/doxygen_translate.i
+++ b/Examples/test-suite/doxygen_translate.i
@@ -59,6 +59,7 @@
  * \endif
  * 
  * \image html testImage.bmp "Hello, world!" width=10cm
+ * \image html "test image.jpg" "Test jpeg" width=10cm
  * 
  * <ul>
  * 
diff --git a/Examples/test-suite/doxygen_translate_all_tags.i b/Examples/test-suite/doxygen_translate_all_tags.i
index 8da683d..b54203d 100644
--- a/Examples/test-suite/doxygen_translate_all_tags.i
+++ b/Examples/test-suite/doxygen_translate_all_tags.i
@@ -210,7 +210,7 @@
  * 
  * \line example
  *
- * \link someMember Some description follows \endlink
+ * \link someMember Some description follows\endlink with text after
  * 
  * \mainpage Some title
  *
@@ -262,6 +262,9 @@
  * \paragraph someParagraph Paragraph title
  *
  * \param a the first param
+ * \param[in] b parameter with intent(in)
+ * \param[out] c parameter with intent(out)
+ * \param[in,out] d parameter with intent(in,out)
  * 
  * \post Some description
  *
@@ -273,7 +276,7 @@
  *
  * \property someVar
  */
-void func07(int a)
+void func07(int a, int b, int c, int d)
 {
 }
 
diff --git a/Examples/test-suite/duplicate_class_name_in_ns.i b/Examples/test-suite/duplicate_class_name_in_ns.i
new file mode 100644
index 0000000..8071f08
--- /dev/null
+++ b/Examples/test-suite/duplicate_class_name_in_ns.i
@@ -0,0 +1,88 @@
+%module duplicate_class_name_in_ns
+
+%rename(XA) A::X;
+%rename(XB) B::X;
+
+%inline %{
+
+namespace A
+{
+    class X
+    {
+    public:
+        X(){};
+    };
+
+    template<typename T>
+    class Foo
+    {
+    public:
+        Foo(){};
+    };
+
+    class Bar
+    {
+    public:
+        Bar(){};
+    };
+
+    template<typename T>
+    class Baz
+    {
+    public:
+        Baz(){};
+    };
+}
+
+namespace B
+{
+    // non-template derived from non-template
+    class X : public A::X
+    {
+    public:
+        X(){};
+        A::X do_x(){return A::X();}
+    };
+
+    // template derived from template with different template args
+    template<typename T, typename U>
+    class Foo : public A::Foo<U>
+    {
+    public:
+        Foo(){};
+        A::Foo<U> do_foo(){return A::Foo<U>();}
+    };
+
+    // template derived from non-template
+    template<typename T, typename U>
+    class Bar : public A::Bar
+    {
+    public:
+        Bar(){};
+        A::Bar do_bar(){return A::Bar();}
+    };
+
+    // template derived from template with same template args
+    template<typename T>
+    class Baz : public A::Baz<T>
+    {
+    public:
+        Baz(){};
+        A::Baz<T> do_baz(){return A::Baz<T>();}
+    };
+}
+
+%}
+
+%template(AFoo) A::Foo<double>;
+%template(ABaz) A::Baz<double>;
+%template(BFoo) B::Foo<int, double>;
+%template(BBar) B::Bar<int, double>;
+%template(BBaz) B::Baz<double>;
+
+%inline %{
+    A::X get_a_x() {B::X x; return x.do_x();}
+    A::Foo<double> get_a_foo() {B::Foo<int, double> x; return x.do_foo();}
+    A::Bar get_a_bar() {B::Bar<int, double> x; return x.do_bar();}
+    A::Baz<double> get_a_baz() {B::Baz<double> x; return x.do_baz();}
+%}
diff --git a/Examples/test-suite/duplicate_parm_names.i b/Examples/test-suite/duplicate_parm_names.i
new file mode 100644
index 0000000..b6c369c
--- /dev/null
+++ b/Examples/test-suite/duplicate_parm_names.i
@@ -0,0 +1,21 @@
+%module duplicate_parm_names
+
+// Testing duplicate argument name handling
+
+%{
+void fn_2parms(int, int) {}
+void fn_3parms(int, int, double) {}
+void fn_4parms(int, short, double, const char *) {}
+
+struct SameParmNameCheck {
+  void metho(int, short, double, const char *) {}
+};
+%}
+
+void fn_2parms(int argx, int argx) {}
+void fn_3parms(int p_a, int p_a, double p_c) {}
+void fn_4parms(int duplicate, short duplicate, double duplicate, const char *duplicate) {}
+
+struct SameParmNameCheck {
+  void metho(int dup, short dup, double uniq, const char *dup) {}
+};
diff --git a/Examples/test-suite/enum_forward.i b/Examples/test-suite/enum_forward.i
index 784f4fb..5593e02 100644
--- a/Examples/test-suite/enum_forward.i
+++ b/Examples/test-suite/enum_forward.i
@@ -1,7 +1,7 @@
 %module enum_forward
 
 /* This contains C code that is not valid C++03 and Octave, and Javascript(v8) wrappers are always compiled as C++ */
-#if !defined(SWIGOCTAVE) && !defined(SWIG_JAVASCRIPT_V8)
+#if !defined(SWIGOCTAVE) && !defined(SWIG_JAVASCRIPT_V8) && !defined(SWIG_JAVASCRIPT_NAPI)
 %{
 enum ForwardEnum1 { AAA, BBB };
 enum ForwardEnum2 { CCC, DDD };
diff --git a/Examples/test-suite/enum_thorough.i b/Examples/test-suite/enum_thorough.i
index 3beefcc..b8eb3df 100644
--- a/Examples/test-suite/enum_thorough.i
+++ b/Examples/test-suite/enum_thorough.i
@@ -89,8 +89,6 @@
   const colour myColour2;
   speedtd1 mySpeedtd1;
   SpeedClass() : myColour2(red), mySpeedtd1(slow) { }
-private:
-  SpeedClass& operator=(const SpeedClass&);
 };
 
 int                            speedTest0(int s) { return s; }
diff --git a/Examples/test-suite/equality.i b/Examples/test-suite/equality.i
index cdabc48..344cb9f 100644
--- a/Examples/test-suite/equality.i
+++ b/Examples/test-suite/equality.i
@@ -57,8 +57,7 @@
 %}
 
 /* 
-  in order to wrapper this correctly
-  we need to extend the class
+  in order to wrap this correctly we need to extend the class
   to make the friends & non members part of the class
 */
 %extend EqualOpDefined {
diff --git a/Examples/test-suite/errors/Makefile.in b/Examples/test-suite/errors/Makefile.in
index 7137a68..347bf38 100644
--- a/Examples/test-suite/errors/Makefile.in
+++ b/Examples/test-suite/errors/Makefile.in
@@ -16,6 +16,10 @@
 LANGUAGE     = errors
 ERROR_EXT    = newerr
 
+HAVE_CXX11   = @HAVE_CXX11@
+HAVE_CXX14   = @HAVE_CXX14@
+HAVE_CXX17   = @HAVE_CXX17@
+HAVE_CXX20   = @HAVE_CXX20@
 srcdir       = @srcdir@
 top_srcdir   = @top_srcdir@
 top_builddir = @top_builddir@
diff --git a/Examples/test-suite/errors/c_bad_name.i b/Examples/test-suite/errors/c_bad_name.i
deleted file mode 100644
index 43ccb4d..0000000
--- a/Examples/test-suite/errors/c_bad_name.i
+++ /dev/null
@@ -1,4 +0,0 @@
-%module xxx
-
-%name() int foo;
-
diff --git a/Examples/test-suite/errors/c_bad_name.stderr b/Examples/test-suite/errors/c_bad_name.stderr
deleted file mode 100644
index 6c1f706..0000000
--- a/Examples/test-suite/errors/c_bad_name.stderr
+++ /dev/null
@@ -1,2 +0,0 @@
-c_bad_name.i:3: Warning 121: %name is deprecated.  Use %rename instead.
-c_bad_name.i:3: Error: Missing argument to %name directive.
diff --git a/Examples/test-suite/errors/c_deprecated.i b/Examples/test-suite/errors/c_deprecated.i
deleted file mode 100644
index 27e7439..0000000
--- a/Examples/test-suite/errors/c_deprecated.i
+++ /dev/null
@@ -1,8 +0,0 @@
-%module xxx
-
-int foo(%val int *x, %out int *y);
-
-
-
-
-
diff --git a/Examples/test-suite/errors/c_deprecated.stderr b/Examples/test-suite/errors/c_deprecated.stderr
deleted file mode 100644
index 9e77c9a..0000000
--- a/Examples/test-suite/errors/c_deprecated.stderr
+++ /dev/null
@@ -1,2 +0,0 @@
-c_deprecated.i:3: Warning 102: %val directive deprecated (ignored).
-c_deprecated.i:3: Warning 103: %out directive deprecated (ignored).
diff --git a/Examples/test-suite/errors/c_extra_rbrace.stderr b/Examples/test-suite/errors/c_extra_rbrace.stderr
index 23bd41f..a7b1938 100644
--- a/Examples/test-suite/errors/c_extra_rbrace.stderr
+++ b/Examples/test-suite/errors/c_extra_rbrace.stderr
@@ -1 +1 @@
-c_extra_rbrace.i:5: Error: Syntax error. Extraneous '}'
+c_extra_rbrace.i:5: Error: Syntax error. Extraneous closing brace ('}')
diff --git a/Examples/test-suite/errors/c_missing_rbrace.stderr b/Examples/test-suite/errors/c_missing_rbrace.stderr
index 28fdd26..7cadc07 100644
--- a/Examples/test-suite/errors/c_missing_rbrace.stderr
+++ b/Examples/test-suite/errors/c_missing_rbrace.stderr
@@ -1,2 +1 @@
 c_missing_rbrace.i:3: Error: Missing '}'. Reached end of input.
-c_missing_rbrace.i:3: Error: Syntax error in input(1).
diff --git a/Examples/test-suite/errors/c_missing_semi.stderr b/Examples/test-suite/errors/c_missing_semi.stderr
index 18befaa..9b35037 100644
--- a/Examples/test-suite/errors/c_missing_semi.stderr
+++ b/Examples/test-suite/errors/c_missing_semi.stderr
@@ -1 +1 @@
-c_missing_semi.i:3: Error: Syntax error - possibly a missing semicolon.
+c_missing_semi.i:3: Error: Syntax error - possibly a missing semicolon (';').
diff --git a/Examples/test-suite/errors/c_redefine.stderr b/Examples/test-suite/errors/c_redefine.stderr
index 4fccf14..a5996d1 100644
--- a/Examples/test-suite/errors/c_redefine.stderr
+++ b/Examples/test-suite/errors/c_redefine.stderr
@@ -1,6 +1,6 @@
-c_redefine.i:4: Warning 302: Identifier 'foo' redefined (ignored),
-c_redefine.i:3: Warning 302: previous definition of 'foo'.
-c_redefine.i:8: Warning 302: Identifier 'bar' redefined (ignored),
-c_redefine.i:6: Warning 302: previous definition of 'bar'.
-c_redefine.i:14: Warning 322: Redundant redeclaration of 'bar' (Renamed from 'spam'),
-c_redefine.i:6: Warning 322: previous declaration of 'bar'.
+c_redefine.i:4: Warning 302: Redefinition of identifier 'foo' ignored,
+c_redefine.i:3: Warning 302: previous definition of 'foo' as foo(int,int).
+c_redefine.i:8: Warning 302: Redefinition of identifier 'bar' ignored,
+c_redefine.i:6: Warning 302: previous definition of 'bar' as bar(int).
+c_redefine.i:14: Warning 322: Redundant redeclaration of identifier 'bar' (Renamed from 'spam') as spam(int) ignored,
+c_redefine.i:6: Warning 322: previous declaration of 'bar' as bar(int).
diff --git a/Examples/test-suite/errors/c_redefine_typedef.i b/Examples/test-suite/errors/c_redefine_typedef.i
new file mode 100644
index 0000000..0829ead
--- /dev/null
+++ b/Examples/test-suite/errors/c_redefine_typedef.i
@@ -0,0 +1,15 @@
+%module xxx
+
+
+struct Hello;
+struct Hello;
+
+struct MyStruct {
+  int x;
+};
+struct MyStruct {
+  int x;
+};
+
+typedef int Int;
+typedef int Int;
diff --git a/Examples/test-suite/errors/c_redefine_typedef.stderr b/Examples/test-suite/errors/c_redefine_typedef.stderr
new file mode 100644
index 0000000..60b63f0
--- /dev/null
+++ b/Examples/test-suite/errors/c_redefine_typedef.stderr
@@ -0,0 +1,4 @@
+c_redefine_typedef.i:10: Warning 302: Redefinition of identifier 'MyStruct' ignored,
+c_redefine_typedef.i:7: Warning 302: previous definition of 'MyStruct'.
+c_redefine_typedef.i:15: Warning 322: Redundant redeclaration of identifier 'Int' ignored,
+c_redefine_typedef.i:14: Warning 322: previous declaration of 'Int'.
diff --git a/Examples/test-suite/errors/c_spaceship.i b/Examples/test-suite/errors/c_spaceship.i
new file mode 100644
index 0000000..da0d6c7
--- /dev/null
+++ b/Examples/test-suite/errors/c_spaceship.i
@@ -0,0 +1,3 @@
+%module xxx
+/* Test that the spaceship operator gives an error in C mode. */
+int a[(1<=>2>1)];
diff --git a/Examples/test-suite/errors/c_spaceship.stderr b/Examples/test-suite/errors/c_spaceship.stderr
new file mode 100644
index 0000000..bc18d45
--- /dev/null
+++ b/Examples/test-suite/errors/c_spaceship.stderr
@@ -0,0 +1 @@
+c_spaceship.i:3: Error: Syntax error in input(1).
diff --git a/Examples/test-suite/errors/cpp_class_definition.i b/Examples/test-suite/errors/cpp_class_definition.i
index 8381e75..d6842ee 100644
--- a/Examples/test-suite/errors/cpp_class_definition.i
+++ b/Examples/test-suite/errors/cpp_class_definition.i
@@ -1,7 +1,7 @@
 %module xxx
 
-// This should error but doesn't
-#if 0
+
+
 namespace OtherSpace {
   struct L;
 }
@@ -13,7 +13,7 @@
     };
   }
 }
-#endif
+
 
 namespace Space1 {
   struct A;
@@ -24,3 +24,17 @@
   };
 }
 
+namespace Space2 {
+    struct B;
+}
+
+struct ::Space2::B {
+    int val;
+    B() : val() {}
+};
+
+struct XX;
+// g++: error: global qualification of class name is invalid before ‘{’ token
+struct ::XX {
+  int vvv;
+};
diff --git a/Examples/test-suite/errors/cpp_class_definition.stderr b/Examples/test-suite/errors/cpp_class_definition.stderr
index 2c41028..744ae70 100644
--- a/Examples/test-suite/errors/cpp_class_definition.stderr
+++ b/Examples/test-suite/errors/cpp_class_definition.stderr
@@ -1 +1,5 @@
+cpp_class_definition.i:11: Warning 302: Redefinition of identifier 'L' as Space11::SubSpace11::L ignored,
+cpp_class_definition.i:10: Warning 302: previous definition of 'L' as Space11::SubSpace11::L.
 cpp_class_definition.i:22: Error: 'Space1::A' resolves to 'Space1::A' and was incorrectly instantiated in scope 'Space2' instead of within scope 'Space1'.
+cpp_class_definition.i:31: Error: Using the unary scope operator :: in class definition '::Space2::B' is invalid.
+cpp_class_definition.i:38: Error: Using the unary scope operator :: in class definition '::XX' is invalid.
diff --git a/Examples/test-suite/errors/cpp_decltype_unsupported.i b/Examples/test-suite/errors/cpp_decltype_unsupported.i
new file mode 100644
index 0000000..9b01f56
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_decltype_unsupported.i
@@ -0,0 +1,58 @@
+#ifdef SWIG
+%module xxx
+#endif
+
+// Test that decltype cases where SWIG doesn't yet support deducing the type
+// are handled gracefully.
+//
+// To check testcases are valid C++:
+// g++ -std=c++20 -Wall -W -xc++ -c cpp_decltype_unsupported.i
+
+// Function return type
+static int func_returning_int(int x = 0) { return x; }
+static int global_int = 42;
+decltype(func_returning_int()) func_return;
+decltype(func_returning_int(0)) func_return2;
+
+// Address of (other than char or wchar_t)
+decltype(&global_int) address_of;
+
+// Pointer dereference (other than of char* or wchar_t*).
+#ifdef SWIG
+%ignore pointer_to_int;
+#endif
+int* pointer_to_int;
+decltype(*pointer_to_int) pointer_dereference = *pointer_to_int;
+
+// Variable SWIG doesn't know about.
+#ifndef SWIG
+static int undeclared_variable = 1;
+#endif
+decltype(undeclared_variable) unknown_to_swig;
+
+// Constructed object.
+struct A {};
+decltype(A()) constructed_object;
+
+// Spaceship operator.
+#include <compare>
+decltype(1 <=> 2) spaceship = (1 <=> 2);
+
+// Array dereference.
+decltype(("abc"[1])) array_deref = 0;
+constexpr auto array_deref2{"abc"[1]};
+// FIXME: SWIG fails to parse these cases:
+#ifndef SWIG
+decltype("abc"[1]) array_deref3 = 0;
+constexpr auto array_deref4 = ("abc"[1]);
+constexpr auto array_deref5("abc"[1]);
+#endif
+
+// Comparisons.
+// FIXME SWIG fails to parse both these with `Error: Missing ')'. Reached end of input.`
+//decltype(1 < 2) lt_test = 0;
+//decltype(1 > 2) gt_test = 0;
+
+// Assignment.
+bool a;
+decltype((a = true) + 1) assignment = true;
diff --git a/Examples/test-suite/errors/cpp_decltype_unsupported.stderr b/Examples/test-suite/errors/cpp_decltype_unsupported.stderr
new file mode 100644
index 0000000..d688d25
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_decltype_unsupported.stderr
@@ -0,0 +1,10 @@
+cpp_decltype_unsupported.i:14: Warning 344: Unable to deduce decltype for 'func_returning_int()'.
+cpp_decltype_unsupported.i:15: Warning 344: Unable to deduce decltype for 'func_returning_int(0)'.
+cpp_decltype_unsupported.i:18: Warning 344: Unable to deduce decltype for '&global_int'.
+cpp_decltype_unsupported.i:25: Warning 344: Unable to deduce decltype for '*pointer_to_int'.
+cpp_decltype_unsupported.i:31: Warning 344: Unable to deduce decltype for 'undeclared_variable'.
+cpp_decltype_unsupported.i:35: Warning 344: Unable to deduce decltype for 'A()'.
+cpp_decltype_unsupported.i:39: Warning 344: Unable to deduce decltype for '1 <=> 2'.
+cpp_decltype_unsupported.i:42: Warning 344: Unable to deduce decltype for '("abc"[1])'.
+cpp_decltype_unsupported.i:43: Warning 346: Unable to deduce auto type for variable 'array_deref2' (ignored).
+cpp_decltype_unsupported.i:58: Warning 344: Unable to deduce decltype for '(a = true) + 1'.
diff --git a/Examples/test-suite/errors/cpp_destructor_storage.i b/Examples/test-suite/errors/cpp_destructor_storage.i
new file mode 100644
index 0000000..985f3b6
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_destructor_storage.i
@@ -0,0 +1,13 @@
+%module xxx
+
+struct BadDestructor1 {
+    virtual ~BadDestructor1() = 1;
+};
+
+struct BadDestructor2 {
+    ~BadDestructor2() = 0;
+};
+
+struct BadDestructor3 {
+    ~BadDestructor3() const;
+};
diff --git a/Examples/test-suite/errors/cpp_destructor_storage.stderr b/Examples/test-suite/errors/cpp_destructor_storage.stderr
new file mode 100644
index 0000000..642a345
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_destructor_storage.stderr
@@ -0,0 +1,3 @@
+cpp_destructor_storage.i:4: Error: Destructor ~BadDestructor1() has an invalid pure specifier, only = 0 is allowed.
+cpp_destructor_storage.i:8: Error: Destructor ~BadDestructor2() uses a pure specifier but is not virtual.
+cpp_destructor_storage.i:12: Error: Destructor ~BadDestructor3() const cannot have a qualifier.
diff --git a/Examples/test-suite/errors/cpp_extend_destructors.stderr b/Examples/test-suite/errors/cpp_extend_destructors.stderr
index 1eef277..b5de8cc 100644
--- a/Examples/test-suite/errors/cpp_extend_destructors.stderr
+++ b/Examples/test-suite/errors/cpp_extend_destructors.stderr
@@ -1,11 +1,11 @@
-cpp_extend_destructors.i:8: Warning 302: Identifier '~AStruct' redefined by %extend (ignored),
+cpp_extend_destructors.i:8: Warning 302: Redefinition of identifier '~AStruct' by %extend ignored,
 cpp_extend_destructors.i:5: Warning 302: %extend definition of '~AStruct'.
-cpp_extend_destructors.i:14: Warning 302: Identifier '~BStruct' redefined (ignored),
-cpp_extend_destructors.i:13: Warning 302: previous definition of '~BStruct'.
-cpp_extend_destructors.i:87: Warning 302: Identifier '~JStruct' redefined (ignored),
-cpp_extend_destructors.i:85: Warning 302: previous definition of '~JStruct'.
-cpp_extend_destructors.i:100: Warning 302: Identifier '~LStruct' redefined (ignored),
-cpp_extend_destructors.i:98: Warning 302: previous definition of '~LStruct'.
+cpp_extend_destructors.i:14: Warning 302: Redefinition of identifier '~BStruct' as BStruct::~BStruct() ignored,
+cpp_extend_destructors.i:13: Warning 302: previous definition of '~BStruct' as BStruct::~BStruct().
+cpp_extend_destructors.i:87: Warning 302: Redefinition of identifier '~JStruct' as JStruct::~JStruct() ignored,
+cpp_extend_destructors.i:85: Warning 302: previous definition of '~JStruct' as JStruct::~JStruct().
+cpp_extend_destructors.i:100: Warning 302: Redefinition of identifier '~LStruct' as LStruct::~LStruct() ignored,
+cpp_extend_destructors.i:98: Warning 302: previous definition of '~LStruct' as LStruct::~LStruct().
 cpp_extend_destructors.i:24: Warning 521: Illegal destructor name CStruct::~NOT_CStruct(). Ignored.
 cpp_extend_destructors.i:30: Warning 521: Illegal destructor name DStruct::~NOT_DStruct(). Ignored.
 cpp_extend_destructors.i:44: Warning 521: Illegal destructor name EStruct::~NOT_EStruct(). Ignored.
diff --git a/Examples/test-suite/errors/cpp_extend_redefine.i b/Examples/test-suite/errors/cpp_extend_redefine.i
index dfe8fe4..f13d497 100644
--- a/Examples/test-suite/errors/cpp_extend_redefine.i
+++ b/Examples/test-suite/errors/cpp_extend_redefine.i
@@ -13,11 +13,3 @@
 %extend foo {
     int spam();
 };
-
-
-   
-
-
-
-
-
diff --git a/Examples/test-suite/errors/cpp_extend_redefine.stderr b/Examples/test-suite/errors/cpp_extend_redefine.stderr
index 94770f5..2e46a33 100644
--- a/Examples/test-suite/errors/cpp_extend_redefine.stderr
+++ b/Examples/test-suite/errors/cpp_extend_redefine.stderr
@@ -1,4 +1,4 @@
-cpp_extend_redefine.i:9: Warning 302: Identifier 'bar' redefined by %extend (ignored),
+cpp_extend_redefine.i:9: Warning 302: Redefinition of identifier 'bar' by %extend ignored,
 cpp_extend_redefine.i:5: Warning 302: %extend definition of 'bar'.
-cpp_extend_redefine.i:14: Warning 322: Redundant redeclaration of 'spam',
-cpp_extend_redefine.i:10: Warning 322: previous declaration of 'spam'.
+cpp_extend_redefine.i:14: Warning 322: Redundant redeclaration of identifier 'spam' as foo::spam() ignored,
+cpp_extend_redefine.i:10: Warning 322: previous declaration of 'spam' as foo::spam().
diff --git a/Examples/test-suite/errors/cpp_extend_redefine_template.i b/Examples/test-suite/errors/cpp_extend_redefine_template.i
new file mode 100644
index 0000000..edc6d7c
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_extend_redefine_template.i
@@ -0,0 +1,54 @@
+%module xxx
+
+%extend FooT<int> {
+  FooT(int a) { return new FooT<T>(); }
+  ~FooT() { delete $self;}
+  int spam(const char *) { return x; }
+  int spam(int x) { return x; }
+  int spam(int x, int y) { return x + y ; }
+  int spam(int x, int y,int z) { return x + y ; }
+  int spam(Foo f, double d = 10.0) { return 0; }
+};
+
+%inline %{
+template<class T>
+class FooT {
+public:
+  FooT(){}
+
+#ifdef SWIG
+%extend { FooT(int a, int b) { return new FooT<T>(); } }  
+#endif
+
+  int spam() { return 1; }
+  int spam(const char* c) { return 2; }
+};
+%}
+
+%template(FooTi) FooT<int>;
+
+
+// After the class
+
+%inline %{
+template<class T>
+class BarT {
+public:
+  BarT() { }
+  int spam() { return 1; }
+  int spam(const char* c) { return 2; }
+};
+%}
+
+
+%extend BarT<int> {
+  BarT(int a) { return new BarT<T>(); }
+  ~BarT() { delete $self;}
+  int spam(const char *) { return 1}
+  int spam(int x) { return x; }
+  int spam(int x, int y) { return x + y ; }
+  int spam(int x, int y,int z) { return x + y ; }
+  int spam(Bar b, double d = 10.0) { return 0; }
+};
+
+%template(BarTi) BarT<int>;
diff --git a/Examples/test-suite/errors/cpp_extend_redefine_template.stderr b/Examples/test-suite/errors/cpp_extend_redefine_template.stderr
new file mode 100644
index 0000000..88454c4
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_extend_redefine_template.stderr
@@ -0,0 +1,4 @@
+cpp_extend_redefine_template.i:24: Warning 302: Redefinition of identifier 'spam' by %extend ignored,
+cpp_extend_redefine_template.i:6: Warning 302: %extend definition of 'spam'.
+cpp_extend_redefine_template.i:39: Warning 302: Redefinition of identifier 'spam' by %extend ignored,
+cpp_extend_redefine_template.i:47: Warning 302: %extend definition of 'spam'.
diff --git a/Examples/test-suite/errors/cpp_extra_brackets.stderr b/Examples/test-suite/errors/cpp_extra_brackets.stderr
index f1fabc7..901bed6 100644
--- a/Examples/test-suite/errors/cpp_extra_brackets.stderr
+++ b/Examples/test-suite/errors/cpp_extra_brackets.stderr
@@ -1 +1 @@
-cpp_extra_brackets.i:5: Error: Unexpected ')'.
+cpp_extra_brackets.i:5: Error: Unexpected closing parenthesis (')').
diff --git a/Examples/test-suite/errors/cpp_invalid_template.stderr b/Examples/test-suite/errors/cpp_invalid_template.stderr
index f6bfaaf..f394649 100644
--- a/Examples/test-suite/errors/cpp_invalid_template.stderr
+++ b/Examples/test-suite/errors/cpp_invalid_template.stderr
@@ -1,3 +1,2 @@
-cpp_invalid_template.i:3: Error: Undefined scope 'SSS'
 cpp_invalid_template.i:3: Error: Template 'SSS::AAA' undefined.
 cpp_invalid_template.i:9: Error: 'JJJ' is not defined as a template. (classforward)
diff --git a/Examples/test-suite/errors/cpp_missing_rparenthesis.stderr b/Examples/test-suite/errors/cpp_missing_rparenthesis.stderr
index cc97f5c..5b826aa 100644
--- a/Examples/test-suite/errors/cpp_missing_rparenthesis.stderr
+++ b/Examples/test-suite/errors/cpp_missing_rparenthesis.stderr
@@ -1,2 +1 @@
 cpp_missing_rparenthesis.i:5: Error: Missing ')'. Reached end of input.
-cpp_missing_rparenthesis.i:5: Error: Syntax error in input(3).
diff --git a/Examples/test-suite/errors/cpp_namespace_template_bad.i b/Examples/test-suite/errors/cpp_namespace_template_bad.i
index f41918f..d8a3309 100644
--- a/Examples/test-suite/errors/cpp_namespace_template_bad.i
+++ b/Examples/test-suite/errors/cpp_namespace_template_bad.i
@@ -9,6 +9,11 @@
   }; 
 }
 
+namespace test1 {
+  %template(maxchar) ::test::max<char>;
+  %template(vectorchar) ::test::vector<char>;
+}
+
 namespace test2 {
   using namespace test;
   %template(maxshort) max<short>;
@@ -32,9 +37,18 @@
   %template(vectorInteger) vector<Integer>;
 }
 
-using namespace test;
 namespace test5 {
+// Empty namespace
+}
+template<typename T> struct GlobalVector {
+  void gook(T i) {}
+  void geeko(double d) {}
+  void geeky(int d) {}
+};
+%template(GlobalVectorIntPtr) test5::GlobalVector<int *>; // should fail as GlobalVector is in global namespace
+
+using namespace test;
+namespace test6 {
   %template(maxdouble) max<double>;
   %template(vectordouble) vector<double>;
 }
-
diff --git a/Examples/test-suite/errors/cpp_namespace_template_bad.stderr b/Examples/test-suite/errors/cpp_namespace_template_bad.stderr
index 5965d52..d6ee15d 100644
--- a/Examples/test-suite/errors/cpp_namespace_template_bad.stderr
+++ b/Examples/test-suite/errors/cpp_namespace_template_bad.stderr
@@ -1,9 +1,11 @@
-cpp_namespace_template_bad.i:14: Error: 'max' resolves to 'test::max' and was incorrectly instantiated in scope 'test2' instead of within scope 'test'.
-cpp_namespace_template_bad.i:15: Error: 'vector' resolves to 'test::vector' and was incorrectly instantiated in scope 'test2' instead of within scope 'test'.
-cpp_namespace_template_bad.i:21: Error: 'max' resolves to 'test::max' and was incorrectly instantiated in scope 'test3' instead of within scope 'test'.
-cpp_namespace_template_bad.i:22: Error: 'vector' resolves to 'test::vector' and was incorrectly instantiated in scope 'test3' instead of within scope 'test'.
-cpp_namespace_template_bad.i:31: Error: 'max' resolves to 'test::max' and was incorrectly instantiated in scope 'test4' instead of within scope 'test'.
-cpp_namespace_template_bad.i:32: Error: 'vector' resolves to 'test::vector' and was incorrectly instantiated in scope 'test4' instead of within scope 'test'.
-cpp_namespace_template_bad.i:37: Error: 'max' resolves to 'test::max' and was incorrectly instantiated in scope 'test5' instead of within scope 'test'.
-cpp_namespace_template_bad.i:37: Error: Template 'max' undefined.
-cpp_namespace_template_bad.i:38: Error: 'vector' resolves to 'test::vector' and was incorrectly instantiated in scope 'test5' instead of within scope 'test'.
+cpp_namespace_template_bad.i:13: Error: '::test::max' resolves to 'test::max' and was incorrectly instantiated in scope 'test1' instead of within scope 'test'.
+cpp_namespace_template_bad.i:14: Error: '::test::vector' resolves to 'test::vector' and was incorrectly instantiated in scope 'test1' instead of within scope 'test'.
+cpp_namespace_template_bad.i:19: Error: 'max' resolves to 'test::max' and was incorrectly instantiated in scope 'test2' instead of within scope 'test'.
+cpp_namespace_template_bad.i:20: Error: 'vector' resolves to 'test::vector' and was incorrectly instantiated in scope 'test2' instead of within scope 'test'.
+cpp_namespace_template_bad.i:26: Error: 'max' resolves to 'test::max' and was incorrectly instantiated in scope 'test3' instead of within scope 'test'.
+cpp_namespace_template_bad.i:27: Error: 'vector' resolves to 'test::vector' and was incorrectly instantiated in scope 'test3' instead of within scope 'test'.
+cpp_namespace_template_bad.i:36: Error: 'max' resolves to 'test::max' and was incorrectly instantiated in scope 'test4' instead of within scope 'test'.
+cpp_namespace_template_bad.i:37: Error: 'vector' resolves to 'test::vector' and was incorrectly instantiated in scope 'test4' instead of within scope 'test'.
+cpp_namespace_template_bad.i:48: Error: Template 'test5::GlobalVector' undefined.
+cpp_namespace_template_bad.i:52: Error: 'max' resolves to 'test::max' and was incorrectly instantiated in scope 'test6' instead of within scope 'test'.
+cpp_namespace_template_bad.i:53: Error: 'vector' resolves to 'test::vector' and was incorrectly instantiated in scope 'test6' instead of within scope 'test'.
diff --git a/Examples/test-suite/errors/cpp_namewarn.i b/Examples/test-suite/errors/cpp_namewarn.i
index c0edc4b..5c62ceb 100644
--- a/Examples/test-suite/errors/cpp_namewarn.i
+++ b/Examples/test-suite/errors/cpp_namewarn.i
@@ -1,10 +1,10 @@
 %module xxx
 
-%namewarn("314:'key1' is a keyword, renaming to '_key1'", rename="_%s") "key1";
-%namewarn("314:'key2' is a keyword, renaming to '_key2'", rename="_%s") "key2";
-%namewarn("314:'key3' is a keyword, renaming to '_key3'", rename="_%s") "key3";
-%namewarn("314:'key4' is a keyword, renaming to '_key4'", rename="_%s") "key4";
-%namewarn("314:'key5' is a keyword, renaming to '_key5'", rename="_%s") "key5";
+%namewarn("314:'key1' is a keyword", rename="_%s") "key1";
+%namewarn("314:'key2' is a keyword", rename="_%s") "key2";
+%namewarn("314:'key3' is a keyword", rename="_%s") "key3";
+%namewarn("314:'key4' is a keyword", rename="_%s") "key4";
+%namewarn("314:'key5' is a keyword", rename="_%s") "key5";
 
 // Non-templated
 %ignore KlassA::key1;
diff --git a/Examples/test-suite/errors/cpp_namewarn.stderr b/Examples/test-suite/errors/cpp_namewarn.stderr
index e5b8932..7cc640e 100644
--- a/Examples/test-suite/errors/cpp_namewarn.stderr
+++ b/Examples/test-suite/errors/cpp_namewarn.stderr
@@ -7,4 +7,4 @@
 cpp_namewarn.i:72: Warning 314: 'key1' is a keyword, renaming to '_key1'
 cpp_namewarn.i:73: Warning 314: 'key2' is a keyword, renaming to '_key2'
 cpp_namewarn.i:74: Warning 314: 'key3' is a keyword, renaming to '_key3'
-cpp_namewarn.i:80: Warning 314: 'key5' is a keyword, renaming to '_key5'
+cpp_namewarn.i:80: Warning 314: 'key5' is a keyword
diff --git a/Examples/test-suite/errors/cpp_nested_template.stderr b/Examples/test-suite/errors/cpp_nested_template.stderr
index 363a260..5b107ca 100644
--- a/Examples/test-suite/errors/cpp_nested_template.stderr
+++ b/Examples/test-suite/errors/cpp_nested_template.stderr
@@ -1,4 +1,2 @@
 cpp_nested_template.i:9: Error: 'Temply' resolves to '::Temply' and was incorrectly instantiated in scope 'A' instead of within scope ''.
-cpp_nested_template.i:9: Warning 324: Named nested template instantiations not supported. Processing as if no name was given to %template().
 cpp_nested_template.i:18: Error: 'Temply' resolves to '::Temply' and was incorrectly instantiated in scope 'B' instead of within scope ''.
-cpp_nested_template.i:18: Warning 324: Named nested template instantiations not supported. Processing as if no name was given to %template().
diff --git a/Examples/test-suite/errors/cpp_pp_expressions_bad.i b/Examples/test-suite/errors/cpp_pp_expressions_bad.i
new file mode 100644
index 0000000..2f71232
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_pp_expressions_bad.i
@@ -0,0 +1,6 @@
+%module xxx
+
+
+/* Spaceship operator doesn't seem to be allowed in preprocessor expressions. */
+#if (4 <=> 2) < 0
+#endif
diff --git a/Examples/test-suite/errors/cpp_pp_expressions_bad.stderr b/Examples/test-suite/errors/cpp_pp_expressions_bad.stderr
new file mode 100644
index 0000000..d95d416
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_pp_expressions_bad.stderr
@@ -0,0 +1,2 @@
+cpp_pp_expressions_bad.i:5: Warning 202: Could not evaluate expression '(4 <=> 2) < 0'
+cpp_pp_expressions_bad.i:5: Warning 202: Spaceship operator (<=>) not allowed in preprocessor expression
diff --git a/Examples/test-suite/errors/cpp_recursive_typedef.stderr b/Examples/test-suite/errors/cpp_recursive_typedef.stderr
index d9135aa..b5a5923 100644
--- a/Examples/test-suite/errors/cpp_recursive_typedef.stderr
+++ b/Examples/test-suite/errors/cpp_recursive_typedef.stderr
@@ -1 +1 @@
-:1: Error: Recursive typedef detected resolving 'pds *' to 'std::set< pds > *' to 'std::set< std::set< pds > > *' and so on...
+cpp_recursive_typedef.i:3: Error: Recursive typedef detected resolving 'pds *' to 'std::set< pds > *' to 'std::set< std::set< pds > > *' and so on...
diff --git a/Examples/test-suite/errors/cpp_redefine_class.i b/Examples/test-suite/errors/cpp_redefine_class.i
new file mode 100644
index 0000000..ffffc15
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_redefine_class.i
@@ -0,0 +1,38 @@
+%module xxx
+
+namespace Space {
+struct MyStruct {
+  int b;
+};
+}
+
+namespace Space {
+struct MyStruct {
+  int b;
+};
+}
+
+namespace Space {
+class MyClass {
+public:
+  int a;
+};
+}
+
+class Space::MyClass {
+public:
+  int a;
+};
+
+namespace Space {
+template<typename T>
+class MyTemplateClass {
+public:
+  int a;
+};
+template<typename T>
+class MyTemplateClass {
+public:
+  int a;
+};
+}
diff --git a/Examples/test-suite/errors/cpp_redefine_class.stderr b/Examples/test-suite/errors/cpp_redefine_class.stderr
new file mode 100644
index 0000000..95d2ff7
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_redefine_class.stderr
@@ -0,0 +1,8 @@
+cpp_redefine_class.i:10: Warning 302: Redefinition of identifier 'MyStruct' as Space::MyStruct ignored,
+cpp_redefine_class.i:4: Warning 302: previous definition of 'MyStruct' as Space::MyStruct.
+cpp_redefine_class.i:22: Warning 302: Redefinition of identifier 'MyClass' as Space::MyClass ignored,
+cpp_redefine_class.i:16: Warning 302: previous definition of 'MyClass' as Space::MyClass.
+cpp_redefine_class.i:34: Warning 302: Redefinition of identifier 'MyTemplateClass' as Space::MyTemplateClass ignored,
+cpp_redefine_class.i:29: Warning 302: previous definition of 'MyTemplateClass' as Space::MyTemplateClass.
+cpp_redefine_class.i:34: Warning 302: Redefinition of identifier 'MyTemplateClass' as Space::MyTemplateClass ignored,
+cpp_redefine_class.i:29: Warning 302: previous definition of 'MyTemplateClass' as Space::MyTemplateClass.
diff --git a/Examples/test-suite/errors/cpp_scope_bad.i b/Examples/test-suite/errors/cpp_scope_bad.i
new file mode 100644
index 0000000..0396c40
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_scope_bad.i
@@ -0,0 +1,37 @@
+%module xxx
+
+template <typename Tnum>
+class Space::A<Tnum>::Anest {
+public:
+    Anest();
+};
+
+namespace N {
+  template<typename T> class C {};
+}
+namespace unrelated {
+  %template(cin) N::C<int>;
+  template class N::C<int>;
+}
+struct Outer {
+    struct Unrelated<X>  {
+      %template(cin) N::C<int>;
+      template class N::C<int>;
+    };
+};
+
+struct ::X::Y<int> {
+};
+
+using namespace Nope<double>;
+
+template<typename T>
+struct NotANamespace {
+};
+%template(NotANamespaceInt) NotANamespace<int>;
+%template() NotANamespace<double>;
+
+using namespace NotANamespace<double>;
+
+namespace BadEquivalent = NotANamespace<int>;
+namespace AwfulEquivalent = Nope<double>;
diff --git a/Examples/test-suite/errors/cpp_scope_bad.stderr b/Examples/test-suite/errors/cpp_scope_bad.stderr
new file mode 100644
index 0000000..d2387fe
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_scope_bad.stderr
@@ -0,0 +1,13 @@
+cpp_scope_bad.i:4: Error: Undefined scope 'Space::A< Tnum >'
+cpp_scope_bad.i:4: Warning 317: Specialization of non-template 'Space::A'.
+cpp_scope_bad.i:13: Error: 'N::C' resolves to 'N::C' and was incorrectly instantiated in scope 'unrelated' instead of within scope 'N'.
+cpp_scope_bad.i:14: Warning 320: Explicit template instantiation ignored.
+cpp_scope_bad.i:18: Error: 'N::C' resolves to 'N::C' and was incorrectly instantiated in scope 'Outer::Unrelated< X >' instead of within scope 'N'.
+cpp_scope_bad.i:19: Warning 320: Explicit template instantiation ignored.
+cpp_scope_bad.i:20: Warning 325: Nested struct not currently supported (Unrelated< X > ignored)
+cpp_scope_bad.i:23: Error: Using the unary scope operator :: in class definition '::X::Y< int >' is invalid.
+cpp_scope_bad.i:26: Error: Nothing known about namespace 'Nope< double >'
+cpp_scope_bad.i:34: Error: 'NotANamespace< double >' is not a namespace.
+cpp_scope_bad.i:36: Error: 'NotANamespace< int >' is not a namespace
+cpp_scope_bad.i:37: Error: Unknown namespace 'Nope< double >'
+cpp_scope_bad.i:23: Warning 503: Can't wrap class Y< int > unless renamed to a valid identifier.
diff --git a/Examples/test-suite/errors/cpp_smartptr_feature.i b/Examples/test-suite/errors/cpp_smartptr_feature.i
new file mode 100644
index 0000000..4a0d510
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_smartptr_feature.i
@@ -0,0 +1,14 @@
+%module xxx
+
+%feature("smartptr", noblock=1) AA { std::shared_ptr< AA > }
+%feature("smartptr", noblock=1) DD { std::shared_ptr< }
+
+
+struct AA {};
+struct BB : AA {};
+struct CC : AA {};
+struct DD : AA {};
+
+%feature("smartptr", noblock=1) YY { std::shared_ptr< YY > }
+struct XX {};
+struct YY : XX {};
diff --git a/Examples/test-suite/errors/cpp_smartptr_feature.stderr b/Examples/test-suite/errors/cpp_smartptr_feature.stderr
new file mode 100644
index 0000000..442f795
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_smartptr_feature.stderr
@@ -0,0 +1,5 @@
+cpp_smartptr_feature.i:8: Warning 520: Derived class 'BB' of 'AA' is not similarly marked as a smart pointer.
+cpp_smartptr_feature.i:9: Warning 520: Derived class 'CC' of 'AA' is not similarly marked as a smart pointer.
+cpp_smartptr_feature.i:10: Error: Invalid type (std::shared_ptr<) in 'smartptr' feature for class DD.
+cpp_smartptr_feature.i:10: Warning 520: Derived class 'DD' of 'AA' is not similarly marked as a smart pointer.
+cpp_smartptr_feature.i:14: Warning 520: Base class 'XX' of 'YY' is not similarly marked as a smart pointer.
diff --git a/Examples/test-suite/errors/cpp_template_class_repeat.i b/Examples/test-suite/errors/cpp_template_class_repeat.i
new file mode 100644
index 0000000..c8bffd4
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_template_class_repeat.i
@@ -0,0 +1,34 @@
+%module xxx
+
+template<typename T> struct A {};
+%template(Aint) A<int>;
+%template(Aint2) A<int>; // Now ignored and issues a warning
+
+template<typename T> struct B {};
+%template() B<int>;
+%template(Bint) B<int>; // OK
+
+template<typename T> struct C {};
+%template() C<int>;
+%template() C<int>; // Quietly ignored now
+%template(Cint) C<int>; // OK
+
+template <typename T, typename U = short> struct D {};
+%template(Dint) D<int>;
+%template(Dintshort) D<int, short>;
+
+template<typename T> struct E {};
+%template(Eint) E<int>;
+%template(Eint) E<int>; // Always has been ignored as a redefined identifier
+
+
+template<typename T> struct F {};
+%template(Fint) F<int>;
+%template() F<int>; // Quietly ignored
+%template() F<int>; // Quietly ignored
+
+template<typename T> struct G {};
+%template() G<int>;
+%template() G<int>; // Quietly ignored
+%template(Gint) G<int>;
+%template() G<int>; // Quietly ignored
diff --git a/Examples/test-suite/errors/cpp_template_class_repeat.stderr b/Examples/test-suite/errors/cpp_template_class_repeat.stderr
new file mode 100644
index 0000000..db283dc
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_template_class_repeat.stderr
@@ -0,0 +1,6 @@
+cpp_template_class_repeat.i:5: Warning 404: Duplicate template instantiation of 'A< int >' with name 'Aint2' ignored,
+cpp_template_class_repeat.i:4: Warning 404: previous instantiation of 'A< int >' with name 'Aint'.
+cpp_template_class_repeat.i:18: Warning 404: Duplicate template instantiation of 'D< int,short >' with name 'Dintshort' ignored,
+cpp_template_class_repeat.i:17: Warning 404: previous instantiation of 'D< int >' with name 'Dint'.
+cpp_template_class_repeat.i:22: Warning 404: Duplicate template instantiation of 'E< int >' with name 'Eint' ignored,
+cpp_template_class_repeat.i:21: Warning 404: previous instantiation of 'E< int >' with name 'Eint'.
diff --git a/Examples/test-suite/errors/cpp_template_duplicate.i b/Examples/test-suite/errors/cpp_template_duplicate.i
new file mode 100644
index 0000000..672c988
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_template_duplicate.i
@@ -0,0 +1,20 @@
+%module xxx
+
+%include <std_vector.i>
+
+// Note these 404 warnings come from two different places in the SWIG code base
+
+%inline %{
+typedef unsigned char uint8_T;
+typedef unsigned char boolean_T;
+%}
+
+%template(std_vector_boolean_type) std::vector<boolean_T>;
+%template(std_vector_boolean_type_duplicate) std::vector<boolean_T>;
+%template(std_vector_uint8_type) std::vector<uint8_T>;
+
+namespace std {
+%template(std_vector_boolean_type_again) vector<boolean_T>;
+%template(std_vector_uint8_type_again) vector<uint8_T>;
+%template(std_vector_unsigned_char) vector<unsigned char>;
+}
diff --git a/Examples/test-suite/errors/cpp_template_duplicate.stderr b/Examples/test-suite/errors/cpp_template_duplicate.stderr
new file mode 100644
index 0000000..b23e64d
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_template_duplicate.stderr
@@ -0,0 +1,10 @@
+cpp_template_duplicate.i:13: Warning 404: Duplicate template instantiation of 'vector< boolean_T >' with name 'std_vector_boolean_type_duplicate' ignored,
+cpp_template_duplicate.i:12: Warning 404: previous instantiation of 'vector< boolean_T >' with name 'std_vector_boolean_type'.
+cpp_template_duplicate.i:17: Warning 404: Duplicate template instantiation of 'vector< boolean_T >' with name 'std_vector_boolean_type_again' ignored,
+cpp_template_duplicate.i:12: Warning 404: previous instantiation of 'vector< boolean_T >' with name 'std_vector_boolean_type'.
+cpp_template_duplicate.i:18: Warning 404: Duplicate template instantiation of 'vector< uint8_T >' with name 'std_vector_uint8_type_again' ignored,
+cpp_template_duplicate.i:14: Warning 404: previous instantiation of 'vector< uint8_T >' with name 'std_vector_uint8_type'.
+cpp_template_duplicate.i:12: Warning 404: Duplicate template instantiation of 'vector< boolean_T >' with name 'std_vector_boolean_type' ignored,
+cpp_template_duplicate.i:19: Warning 404: previous instantiation of 'vector< unsigned char >' with name 'std_vector_unsigned_char'.
+cpp_template_duplicate.i:14: Warning 404: Duplicate template instantiation of 'vector< uint8_T >' with name 'std_vector_uint8_type' ignored,
+cpp_template_duplicate.i:19: Warning 404: previous instantiation of 'vector< unsigned char >' with name 'std_vector_unsigned_char'.
diff --git a/Examples/test-suite/errors/cpp_template_duplicate_names.stderr b/Examples/test-suite/errors/cpp_template_duplicate_names.stderr
index 9856ff5..f1acbc2 100644
--- a/Examples/test-suite/errors/cpp_template_duplicate_names.stderr
+++ b/Examples/test-suite/errors/cpp_template_duplicate_names.stderr
@@ -1,14 +1,14 @@
-cpp_template_duplicate_names.i:14: Warning 302: Identifier 'Duplicate1' redefined (ignored),
-cpp_template_duplicate_names.i:13: Warning 302: previous definition of 'Duplicate1'.
-cpp_template_duplicate_names.i:14: Warning 302: Identifier 'Duplicate1' redefined (ignored),
-cpp_template_duplicate_names.i:13: Warning 302: previous definition of 'Duplicate1'.
-cpp_template_duplicate_names.i:25: Warning 302: Identifier 'Duplicate2_0' redefined (ignored) (Renamed from 'Duplicate2< 0 >'),
-cpp_template_duplicate_names.i:24: Warning 302: previous definition of 'Duplicate2_0' (Renamed from 'Duplicate2< 0 >').
-cpp_template_duplicate_names.i:35: Warning 302: Identifier 'Duplicate3' redefined (ignored) (Renamed from 'Duplicate3< 0 >'),
-cpp_template_duplicate_names.i:31: Warning 302: previous definition of 'Duplicate3'.
-cpp_template_duplicate_names.i:47: Warning 302: Identifier 'Duplicate4' redefined (ignored),
-cpp_template_duplicate_names.i:46: Warning 302: previous definition of 'Duplicate4'.
-cpp_template_duplicate_names.i:47: Warning 302: Identifier 'Duplicate4' redefined (ignored),
-cpp_template_duplicate_names.i:46: Warning 302: previous definition of 'Duplicate4'.
-cpp_template_duplicate_names.i:50: Warning 302: Identifier 'Duplicate4' redefined (ignored) (Renamed from 'Duplicate4< 0 >'),
-cpp_template_duplicate_names.i:46: Warning 302: previous definition of 'Duplicate4'.
+cpp_template_duplicate_names.i:14: Warning 302: Redefinition of identifier 'Duplicate1' as Space::Duplicate1 ignored,
+cpp_template_duplicate_names.i:13: Warning 302: previous definition of 'Duplicate1' as Space::Duplicate1.
+cpp_template_duplicate_names.i:14: Warning 302: Redefinition of identifier 'Duplicate1' as Space::Duplicate1 ignored,
+cpp_template_duplicate_names.i:13: Warning 302: previous definition of 'Duplicate1' as Space::Duplicate1.
+cpp_template_duplicate_names.i:25: Warning 404: Duplicate template instantiation of 'Duplicate2< 0 >' with name 'Duplicate2_0' ignored,
+cpp_template_duplicate_names.i:24: Warning 404: previous instantiation of 'Duplicate2< 0 >' with name 'Duplicate2_0'.
+cpp_template_duplicate_names.i:35: Warning 404: Duplicate template instantiation of 'Duplicate3< 0 >' with name 'Duplicate3' ignored,
+cpp_template_duplicate_names.i:34: Warning 404: previous instantiation of 'Duplicate3< 0 >' with name 'Duplicate3'.
+cpp_template_duplicate_names.i:47: Warning 302: Redefinition of identifier 'Duplicate4' as Space::Duplicate4 ignored,
+cpp_template_duplicate_names.i:46: Warning 302: previous definition of 'Duplicate4' as Space::Duplicate4.
+cpp_template_duplicate_names.i:47: Warning 302: Redefinition of identifier 'Duplicate4' as Space::Duplicate4 ignored,
+cpp_template_duplicate_names.i:46: Warning 302: previous definition of 'Duplicate4' as Space::Duplicate4.
+cpp_template_duplicate_names.i:50: Warning 404: Duplicate template instantiation of 'Duplicate4< 0 >' with name 'Duplicate4' ignored,
+cpp_template_duplicate_names.i:49: Warning 404: previous instantiation of 'Duplicate4< 0 >' with name 'Duplicate4'.
diff --git a/Examples/test-suite/errors/cpp_template_explicit_instantiation.i b/Examples/test-suite/errors/cpp_template_explicit_instantiation.i
new file mode 100644
index 0000000..9751372
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_template_explicit_instantiation.i
@@ -0,0 +1,24 @@
+%module xxx
+
+%inline %{
+namespace std {
+  template<typename T> class vector {};
+}
+template<typename T> void Func() {}
+%}
+
+%inline %{
+// Class template
+template class std::vector<int>;        // C++03 template explicit instantiation definition in C++
+extern template class std::vector<int>; // C++11 template explicit instantiation declaration (extern template)
+%}
+%template(VectorInt) std::vector<int>;  // SWIG template instantiation
+
+%inline %{
+// Function template
+template void Func<int>();             // C++03 template explicit instantiation definition in C++
+extern template void Func<int>();      // C++11 template explicit instantiation declaration (extern template)
+%}
+%template(FuncInt) Func<int>;          // SWIG template instantiation
+
+
diff --git a/Examples/test-suite/errors/cpp_template_explicit_instantiation.stderr b/Examples/test-suite/errors/cpp_template_explicit_instantiation.stderr
new file mode 100644
index 0000000..052d3de
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_template_explicit_instantiation.stderr
@@ -0,0 +1,4 @@
+cpp_template_explicit_instantiation.i:12: Warning 320: Explicit template instantiation ignored.
+cpp_template_explicit_instantiation.i:13: Warning 327: Extern template ignored.
+cpp_template_explicit_instantiation.i:19: Warning 320: Explicit template instantiation ignored.
+cpp_template_explicit_instantiation.i:20: Warning 327: Extern template ignored.
diff --git a/Examples/test-suite/errors/cpp_template_friend.stderr b/Examples/test-suite/errors/cpp_template_friend.stderr
index 8dea195..04ecc86 100644
--- a/Examples/test-suite/errors/cpp_template_friend.stderr
+++ b/Examples/test-suite/errors/cpp_template_friend.stderr
@@ -1,8 +1,8 @@
-cpp_template_friend.i:4: Warning 302: Identifier 'template_friend1' redefined (ignored),
+cpp_template_friend.i:4: Warning 302: Redefinition of identifier 'template_friend1' ignored,
 cpp_template_friend.i:3: Warning 302: previous definition of 'template_friend1'.
-cpp_template_friend.i:13: Warning 302: Identifier 'template_friend2' redefined (ignored),
+cpp_template_friend.i:13: Warning 302: Redefinition of identifier 'template_friend2' ignored,
 cpp_template_friend.i:9: Warning 302: previous definition of 'template_friend2'.
-cpp_template_friend.i:17: Warning 322: Redundant redeclaration of 'normal_friend1',
-cpp_template_friend.i:16: Warning 322: previous declaration of 'normal_friend1'.
-cpp_template_friend.i:26: Warning 322: Redundant redeclaration of 'normal_friend2',
-cpp_template_friend.i:22: Warning 322: previous declaration of 'normal_friend2'.
+cpp_template_friend.i:17: Warning 322: Redundant redeclaration of identifier 'normal_friend1' as normal_friend1(int) ignored,
+cpp_template_friend.i:16: Warning 322: previous declaration of 'normal_friend1' as normal_friend1(int).
+cpp_template_friend.i:26: Warning 322: Redundant redeclaration of identifier 'normal_friend2' as normal_friend2(int) ignored,
+cpp_template_friend.i:22: Warning 322: previous declaration of 'normal_friend2' as normal_friend2(int).
diff --git a/Examples/test-suite/errors/cpp_template_missing_base.i b/Examples/test-suite/errors/cpp_template_missing_base.i
new file mode 100644
index 0000000..56d44ea
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_template_missing_base.i
@@ -0,0 +1,35 @@
+%module xx
+
+struct Low : High {
+};
+
+struct Small;
+
+struct Big : Small {
+};
+
+%inline %{
+namespace A {
+  class XYZ {};
+  template<typename T> struct ABC :
+                                    public B::ABC<T> {
+};
+}
+namespace B {
+  template<typename T> struct ABC {
+    void aaa(T t) {}
+  };
+}
+%}
+%template(ABCXYZ) A::ABC<A::XYZ>;
+
+%template() B::ABC<int>;
+%template(ABCint) A::ABC<int>;
+
+template<typename T>
+struct Another : WrongOrderBase<int> {
+};
+%template(AnotherBool) Another<bool>;
+
+template<typename T> class WrongOrderBase {};
+%template(ForAnotherInt) WrongOrderBase<int>;
diff --git a/Examples/test-suite/errors/cpp_template_missing_base.stderr b/Examples/test-suite/errors/cpp_template_missing_base.stderr
new file mode 100644
index 0000000..c769803
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_template_missing_base.stderr
@@ -0,0 +1,9 @@
+cpp_template_missing_base.i:3: Warning 401: Nothing known about base class 'High'. Ignored.
+cpp_template_missing_base.i:8: Warning 402: Base class 'Small' is incomplete.
+cpp_template_missing_base.i:6: Warning 402: Only forward declaration 'Small' was found.
+cpp_template_missing_base.i:15: Warning 401: Nothing known about base class 'B::ABC< A::XYZ >'. Ignored.
+cpp_template_missing_base.i:15: Warning 401: Maybe you forgot to instantiate 'B::ABC< A::XYZ >' using %template.
+cpp_template_missing_base.i:15: Warning 401: Base class 'B::ABC< int >' has no name as it is an empty template instantiated with '%template()'. Ignored.
+cpp_template_missing_base.i:26: Warning 401: The %template directive must be written before 'B::ABC< int >' is used as a base class and be declared with a name.
+cpp_template_missing_base.i:30: Warning 401: Base class 'WrongOrderBase< int >' undefined.
+cpp_template_missing_base.i:35: Warning 401: 'WrongOrderBase< int >' must be defined before it is used as a base class.
diff --git a/Examples/test-suite/errors/cpp_template_nargs.stderr b/Examples/test-suite/errors/cpp_template_nargs.stderr
index 4ced28e..ef94e63 100644
--- a/Examples/test-suite/errors/cpp_template_nargs.stderr
+++ b/Examples/test-suite/errors/cpp_template_nargs.stderr
@@ -1,2 +1,2 @@
-cpp_template_nargs.i:5: Error: Template 'blah' undefined.
-cpp_template_nargs.i:6: Error: Template 'blah' undefined.
+cpp_template_nargs.i:5: Error: No matching function template 'blah' found.
+cpp_template_nargs.i:6: Error: No matching function template 'blah' found.
diff --git a/Examples/test-suite/errors/cpp_template_partial_specialization_defaults.i b/Examples/test-suite/errors/cpp_template_partial_specialization_defaults.i
new file mode 100644
index 0000000..25b2c5c
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_template_partial_specialization_defaults.i
@@ -0,0 +1,9 @@
+%module xxx
+
+template<class Y, class T=int> struct X { void primary() {} };
+template<class YY> struct X<YY*> { void special(YY*) {} };
+
+%template(Xbad1) X<>;
+%template(Xokay1) X<const char *>;
+%template(Xokay2) X<const short *, int>;
+%template(Xbad2) X<const char *, int, double>;
diff --git a/Examples/test-suite/errors/cpp_template_partial_specialization_defaults.stderr b/Examples/test-suite/errors/cpp_template_partial_specialization_defaults.stderr
new file mode 100644
index 0000000..1968624
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_template_partial_specialization_defaults.stderr
@@ -0,0 +1,2 @@
+cpp_template_partial_specialization_defaults.i:6: Error: Not enough template parameters specified. Minimum of 1 required.
+cpp_template_partial_specialization_defaults.i:9: Error: Too many template parameters. Maximum of 2.
diff --git a/Examples/test-suite/errors/cpp_template_redefine.i b/Examples/test-suite/errors/cpp_template_redefine.i
new file mode 100644
index 0000000..3bd015e
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_template_redefine.i
@@ -0,0 +1,107 @@
+%module xxx
+// This is a copy of Examples/test-suite/cpp11_template_parameters_decltype
+%inline %{
+// Github issue #1589
+template <decltype(true) X = true>
+void A() { }
+%}
+
+// %template(A) A<>; // not working
+%template(A) A<true>; // workaround
+
+
+%include <std_string.i>
+%include <std_vector.i>
+%include <std_map.i>
+
+//#pragma SWIG nowarn=SWIGWARN_CPP11_DECLTYPE
+
+%{
+// Simple implementation of helper functions required in test below
+std::string array(std::vector<std::string>::const_iterator begin, std::vector<std::string>::const_iterator end) {
+  return "not implemented";
+}
+std::string object(std::map<std::string, std::string>::const_iterator begin, std::map<std::string, std::string>::const_iterator end) {
+  return "not implemented";
+}
+%}
+
+%inline %{
+#include <iostream>
+
+// Github issue #1590
+struct Converter {
+  std::string to_json() const { return std::string(); }
+};
+struct Json {
+  int ctor;
+  Json(std::string s) : ctor(0) {}
+  template < class T, class = decltype(&T::to_json) >
+    Json(const T & t) : Json(t.to_json()) { ctor = 1; }
+
+// Github issue #1589
+  // Implicit constructor: map-like objects (std::map, std::unordered_map, etc)
+  template <class M, typename std::enable_if<
+      std::is_constructible<std::string, decltype(std::declval<M>().begin()->first)>::value,
+      int>::type = 0>
+          Json(const M & m) : Json(object(m.begin(), m.end())) { ctor = 2; }
+  // Implicit constructor: vector-like objects (std::list, std::vector, std::set, etc)
+  template <class V, typename std::enable_if<
+      std::is_constructible<Json, decltype(*std::declval<V>().begin())>::value,
+          int>::type = 0>
+  Json(const V & v) : Json(array(v.begin(), v.end())) { ctor = 3; }
+
+  // Same sort of thing as constructors above but for a member function
+  int mmm(std::string s) { return 100; }
+  template < class T, class = decltype(&T::to_json) >
+    int mmm(const T & t) { return 101; }
+  template <class M, typename std::enable_if<
+    std::is_constructible<std::string, decltype(std::declval<M>().begin()->first)>::value,
+    int>::type = 0>
+      int mmm(const M & m) { return 102; }
+  template <class V, typename std::enable_if<
+    std::is_constructible<Json, decltype(*std::declval<V>().begin())>::value,
+    int>::type = 0>
+      int mmm(const V & v) { return 103; }
+};
+
+void tester(bool show) {
+  // Example usage from c++
+  if (show) {
+    Json json0(std::string("hi"));
+    Converter converter;
+    std::cout << "json0 " << json0.ctor << std::endl;
+    Json json1 = Json(converter);
+    std::cout << "json1 " << json1.ctor << std::endl;
+    std::map<std::string, std::string> myStringStringMap;
+    Json json2 = Json(myStringStringMap);
+    std::cout << "json2 " << json2.ctor << std::endl;
+    std::vector<std::string> myVectorString;
+    Json json3 = Json(myVectorString);
+    std::cout << "json3 " << json3.ctor << std::endl;
+
+    std::cout << "json0.mmm " << json0.mmm("bye") << std::endl;
+    std::cout << "json1.mmm " << json1.mmm(converter) << std::endl;
+    std::cout << "json2.mmm " << json2.mmm(myStringStringMap) << std::endl;
+    std::cout << "json3.mmm " << json3.mmm(myVectorString) << std::endl;
+  }
+}
+%}
+
+%template(VectorString) std::vector<std::string>;
+%template(MapStringString) std::map<std::string, std::string>;
+
+// There is quite a bit of inconsistency about providing or not providing default
+// template parameters that needs investigating. Below is a combination that works.
+
+// Note that instantiating the two Json constructors (or the two mmm methods) that
+// use enable_if is ambiguous given the enable_if is not evaluated by SWIG.
+
+// %template(Json) Json::Json<Converter>; // not working
+%template(Json) Json::Json<Converter, std::string>; // workaround
+%template(Json) Json::Json<std::map<std::string, std::string>, 0>;
+%template(Json) Json::Json<std::vector<std::string>, 0>;
+
+%template(mmm) Json::mmm<Converter, std::string>;
+%template(mmm) Json::mmm<std::map<std::string, std::string>, 0>;
+%template(mmm) Json::mmm<std::vector<std::string>, 0>;
diff --git a/Examples/test-suite/errors/cpp_template_redefine.stderr b/Examples/test-suite/errors/cpp_template_redefine.stderr
new file mode 100644
index 0000000..4b15c2f
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_template_redefine.stderr
@@ -0,0 +1,30 @@
+cpp_template_redefine.i:39: Warning 344: Unable to deduce decltype for '&T::to_json'.
+cpp_template_redefine.i:45: Warning 344: Unable to deduce decltype for 'std::declval<M>().begin()->first'.
+cpp_template_redefine.i:50: Warning 344: Unable to deduce decltype for '*std::declval<V>().begin()'.
+cpp_template_redefine.i:56: Warning 344: Unable to deduce decltype for '&T::to_json'.
+cpp_template_redefine.i:59: Warning 344: Unable to deduce decltype for 'std::declval<M>().begin()->first'.
+cpp_template_redefine.i:63: Warning 344: Unable to deduce decltype for '*std::declval<V>().begin()'.
+cpp_template_redefine.i:101: Warning 322: Redundant redeclaration of identifier 'Json' as Json::Json(Converter const &) ignored,
+cpp_template_redefine.i:101: Warning 322: previous declaration of 'Json' as Json::Json(Converter const &).
+cpp_template_redefine.i:101: Warning 322: Redundant redeclaration of identifier 'Json' as Json::Json(Converter const &) ignored,
+cpp_template_redefine.i:101: Warning 322: previous declaration of 'Json' as Json::Json(Converter const &).
+cpp_template_redefine.i:102: Warning 322: Redundant redeclaration of identifier 'Json' as Json::Json(std::map< std::string,std::string,std::less< std::string >,std::allocator< std::pair< std::string const,std::string > > > const &) ignored,
+cpp_template_redefine.i:102: Warning 322: previous declaration of 'Json' as Json::Json(std::map< std::string,std::string,std::less< std::string >,std::allocator< std::pair< std::string const,std::string > > > const &).
+cpp_template_redefine.i:102: Warning 322: Redundant redeclaration of identifier 'Json' as Json::Json(std::map< std::string,std::string,std::less< std::string >,std::allocator< std::pair< std::string const,std::string > > > const &) ignored,
+cpp_template_redefine.i:102: Warning 322: previous declaration of 'Json' as Json::Json(std::map< std::string,std::string,std::less< std::string >,std::allocator< std::pair< std::string const,std::string > > > const &).
+cpp_template_redefine.i:103: Warning 322: Redundant redeclaration of identifier 'Json' as Json::Json(std::vector< std::string,std::allocator< std::string > > const &) ignored,
+cpp_template_redefine.i:103: Warning 322: previous declaration of 'Json' as Json::Json(std::vector< std::string,std::allocator< std::string > > const &).
+cpp_template_redefine.i:103: Warning 322: Redundant redeclaration of identifier 'Json' as Json::Json(std::vector< std::string,std::allocator< std::string > > const &) ignored,
+cpp_template_redefine.i:103: Warning 322: previous declaration of 'Json' as Json::Json(std::vector< std::string,std::allocator< std::string > > const &).
+cpp_template_redefine.i:105: Warning 322: Redundant redeclaration of identifier 'mmm' as Json::mmm< Converter,std::string >(Converter const &) ignored,
+cpp_template_redefine.i:105: Warning 322: previous declaration of 'mmm' as Json::mmm< Converter,std::string >(Converter const &).
+cpp_template_redefine.i:105: Warning 322: Redundant redeclaration of identifier 'mmm' as Json::mmm< Converter,std::string >(Converter const &) ignored,
+cpp_template_redefine.i:105: Warning 322: previous declaration of 'mmm' as Json::mmm< Converter,std::string >(Converter const &).
+cpp_template_redefine.i:106: Warning 322: Redundant redeclaration of identifier 'mmm' as Json::mmm< std::map< std::string,std::string >,0 >(std::map< std::string,std::string,std::less< std::string >,std::allocator< std::pair< std::string const,std::string > > > const &) ignored,
+cpp_template_redefine.i:106: Warning 322: previous declaration of 'mmm' as Json::mmm< std::map< std::string,std::string >,0 >(std::map< std::string,std::string,std::less< std::string >,std::allocator< std::pair< std::string const,std::string > > > const &).
+cpp_template_redefine.i:106: Warning 322: Redundant redeclaration of identifier 'mmm' as Json::mmm< std::map< std::string,std::string >,0 >(std::map< std::string,std::string,std::less< std::string >,std::allocator< std::pair< std::string const,std::string > > > const &) ignored,
+cpp_template_redefine.i:106: Warning 322: previous declaration of 'mmm' as Json::mmm< std::map< std::string,std::string >,0 >(std::map< std::string,std::string,std::less< std::string >,std::allocator< std::pair< std::string const,std::string > > > const &).
+cpp_template_redefine.i:107: Warning 322: Redundant redeclaration of identifier 'mmm' as Json::mmm< std::vector< std::string >,0 >(std::vector< std::string,std::allocator< std::string > > const &) ignored,
+cpp_template_redefine.i:107: Warning 322: previous declaration of 'mmm' as Json::mmm< std::vector< std::string >,0 >(std::vector< std::string,std::allocator< std::string > > const &).
+cpp_template_redefine.i:107: Warning 322: Redundant redeclaration of identifier 'mmm' as Json::mmm< std::vector< std::string >,0 >(std::vector< std::string,std::allocator< std::string > > const &) ignored,
+cpp_template_redefine.i:107: Warning 322: previous declaration of 'mmm' as Json::mmm< std::vector< std::string >,0 >(std::vector< std::string,std::allocator< std::string > > const &).
diff --git a/Examples/test-suite/errors/cpp_template_repeat.i b/Examples/test-suite/errors/cpp_template_repeat.i
index f170080..08d3782 100644
--- a/Examples/test-suite/errors/cpp_template_repeat.i
+++ b/Examples/test-suite/errors/cpp_template_repeat.i
@@ -4,4 +4,15 @@
 
 %template(iblah) blah<int>;
 %template(iiblah) blah<int>;
-// The second %template instantiation above should surely be ignored with a warning, but doesn't atm
+
+// empty template instantiations for template functions warn (unlike for template classes)
+%template() blah<double>;
+%template() blah<double>;
+%template() blah<double>;
+
+%template(sblah) blah<short>;
+%template(sblah) blah<short>;
+
+%template() blah<const char *>;
+%template() blah<const char *>;
+%template(sblah) blah<const char *>;
diff --git a/Examples/test-suite/errors/cpp_template_repeat.stderr b/Examples/test-suite/errors/cpp_template_repeat.stderr
index e69de29..7ab04f2 100644
--- a/Examples/test-suite/errors/cpp_template_repeat.stderr
+++ b/Examples/test-suite/errors/cpp_template_repeat.stderr
@@ -0,0 +1,6 @@
+cpp_template_repeat.i:6: Warning 404: Duplicate template instantiation of 'blah< int >' with name 'iiblah' ignored,
+cpp_template_repeat.i:5: Warning 404: previous instantiation of 'blah< int >' with name 'iblah'.
+cpp_template_repeat.i:14: Warning 404: Duplicate template instantiation of 'blah< short >' with name 'sblah' ignored,
+cpp_template_repeat.i:13: Warning 404: previous instantiation of 'blah< short >' with name 'sblah'.
+cpp_template_repeat.i:9: Warning 519: %template() contains no name. Template method ignored: blah< double >(double)
+cpp_template_repeat.i:16: Warning 519: %template() contains no name. Template method ignored: blah< char const * >(char const *)
diff --git a/Examples/test-suite/errors/cpp_typemap_out_optimal_bug.i b/Examples/test-suite/errors/cpp_typemap_out_optimal_bug.i
new file mode 100644
index 0000000..e8168ec
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_typemap_out_optimal_bug.i
@@ -0,0 +1,45 @@
+%module x
+
+// Just the following languages tested
+#if defined (SWIGCSHARP) || defined (SWIGD)
+%typemap(out, optimal="1") SWIGTYPE %{
+  $result = new $1_ltype((const $1_ltype &)$1);
+%}
+#elif defined (SWIGJAVA)
+%typemap(out, optimal="1") SWIGTYPE %{
+  *($&1_ltype*)&$result = new $1_ltype((const $1_ltype &)$1);
+%}
+#elif defined (SWIGUTL)
+%typemap(out,noblock="1", optimal="1") SWIGTYPE {
+  %set_output(SWIG_NewPointerObj(%new_copy($1, $ltype), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags));
+}
+#endif
+
+// This results in an action which SWIG should disable "optimal" for, but
+// it was failing to.  Fixed in SWIG 4.1.0.
+%exception XX::create() "$action\n{while(sleep(1)){}}"
+
+%ignore XX::operator=;
+
+#ifdef SWIGD
+%rename(trace) XX::debug;
+#endif
+
+%inline %{
+#include <iostream>
+using namespace std;
+
+struct XX {
+  XX() { if (debug) cout << "XX()" << endl; }
+  XX(int i) { if (debug) cout << "XX(" << i << ")" << endl; }
+  XX(const XX &other) { if (debug) cout << "XX(const XX &)" << endl; }
+  XX& operator =(const XX &other) { if (debug) cout << "operator=(const XX &)" << endl; return *this; }
+  ~XX() { if (debug) cout << "~XX()" << endl; }
+  static XX create() {
+    return XX(123);
+  }
+  static bool debug;
+};
+bool XX::debug = true;
+%}
+
diff --git a/Examples/test-suite/errors/cpp_typemap_out_optimal_bug.stderr b/Examples/test-suite/errors/cpp_typemap_out_optimal_bug.stderr
new file mode 100644
index 0000000..15bf64f
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_typemap_out_optimal_bug.stderr
@@ -0,0 +1,4 @@
+cpp_typemap_out_optimal_bug.i:40: Warning 474: Method XX::create() usage of the optimal attribute ignored
+cpp_typemap_out_optimal_bug.i:15: Warning 474: in the out typemap as the following cannot be used to generate optimal code: result = XX::create();
+{while(sleep(1)){}}
+
diff --git a/Examples/test-suite/errors/cpp_using_constructor_bad.i b/Examples/test-suite/errors/cpp_using_constructor_bad.i
new file mode 100644
index 0000000..19b7eaa
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_using_constructor_bad.i
@@ -0,0 +1,22 @@
+%module xxx
+
+struct NotConnected {};
+struct Base {};
+struct Derived : Base {};
+struct MoreDerived : Derived {
+  using Base::Base;
+  using NotConnected::NotConnected;
+};
+
+template<typename T>
+struct TemplateBase {};
+template<typename T>
+struct TemplateDerived : TemplateBase<T> {};
+template<typename T>
+struct TemplateMoreDerived : TemplateDerived<T> {
+  using TemplateBase<T>::TemplateBase;
+};
+
+%template(TemplateBaseInt) TemplateBase<int>;
+%template(TempDerivedInt) TemplateDerived<int>;
+%template(TempMoreDerivedInt) TemplateMoreDerived<int>;
diff --git a/Examples/test-suite/errors/cpp_using_constructor_bad.stderr b/Examples/test-suite/errors/cpp_using_constructor_bad.stderr
new file mode 100644
index 0000000..e635d20
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_using_constructor_bad.stderr
@@ -0,0 +1,3 @@
+cpp_using_constructor_bad.i:7: Warning 329: Using declaration 'Base::Base' for inheriting constructors uses base 'Base' which is not an immediate base of 'MoreDerived'.
+cpp_using_constructor_bad.i:8: Warning 329: Using declaration 'NotConnected::NotConnected' for inheriting constructors uses base 'NotConnected' which is not an immediate base of 'MoreDerived'.
+cpp_using_constructor_bad.i:17: Warning 329: Using declaration 'TemplateBase< int >::TemplateBase' for inheriting constructors uses base 'TemplateBase' which is not an immediate base of 'TemplateMoreDerived< int >'.
diff --git a/Examples/test-suite/errors/cpp_using_declaration_overload.i b/Examples/test-suite/errors/cpp_using_declaration_overload.i
new file mode 100644
index 0000000..9ec633f
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_using_declaration_overload.i
@@ -0,0 +1,9 @@
+%module xxx
+
+struct Base {
+  void m(bool) {}
+};
+struct Derived : Base { 
+  void m(bool) const {}
+  using Base::m;
+};
diff --git a/Examples/test-suite/errors/cpp_using_declaration_overload.stderr b/Examples/test-suite/errors/cpp_using_declaration_overload.stderr
new file mode 100644
index 0000000..a5118a7
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_using_declaration_overload.stderr
@@ -0,0 +1,2 @@
+cpp_using_declaration_overload.i:7: Warning 512: Overloaded method Derived::m(bool) const ignored,
+cpp_using_declaration_overload.i:8: Warning 512: using non-const method Derived::m(bool) instead.
diff --git a/Examples/test-suite/errors/cpp_using_rename.i b/Examples/test-suite/errors/cpp_using_rename.i
new file mode 100644
index 0000000..4b6453c
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_using_rename.i
@@ -0,0 +1,22 @@
+%module xxx
+
+%rename(UseMe) use_me(int i);
+%rename(UseMeToo) Derived::use_me_too;
+
+class Base
+{
+public:
+    void use_me(Base *);
+    void use_me(int i);
+    bool use_me_too(double d) const;
+    bool use_me_too(bool b) const;
+};
+
+class Derived : public Base
+{
+public:
+    using Base::use_me;
+    using Base::use_me_too;
+    using Base::does_not_exist;
+};
+
diff --git a/Examples/test-suite/errors/cpp_using_rename.stderr b/Examples/test-suite/errors/cpp_using_rename.stderr
new file mode 100644
index 0000000..5464896
--- /dev/null
+++ b/Examples/test-suite/errors/cpp_using_rename.stderr
@@ -0,0 +1,7 @@
+cpp_using_rename.i:18: Warning 526: Using declaration Base::use_me, with name 'use_me', is not actually using
+cpp_using_rename.i:10: Warning 526: the method from Base::use_me(int), with name 'UseMe', as the names are different.
+cpp_using_rename.i:19: Warning 526: Using declaration Base::use_me_too, with name 'UseMeToo', is not actually using
+cpp_using_rename.i:11: Warning 526: the method from Base::use_me_too(double) const, with name 'use_me_too', as the names are different.
+cpp_using_rename.i:19: Warning 526: Using declaration Base::use_me_too, with name 'UseMeToo', is not actually using
+cpp_using_rename.i:12: Warning 526: the method from Base::use_me_too(bool) const, with name 'use_me_too', as the names are different.
+cpp_using_rename.i:20: Warning 315: Nothing known about 'Base::does_not_exist'.
diff --git a/Examples/test-suite/errors/doxygen_unclosed_tag.i b/Examples/test-suite/errors/doxygen_unclosed_tag.i
new file mode 100644
index 0000000..fbc3596
--- /dev/null
+++ b/Examples/test-suite/errors/doxygen_unclosed_tag.i
@@ -0,0 +1,6 @@
+%module xxx
+
+/**
+ * Return a random variate with uniform distribution in the range [a,b), where a<b
+ */
+double uniform(double a, double b);
diff --git a/Examples/test-suite/errors/doxygen_unclosed_tag.stderr b/Examples/test-suite/errors/doxygen_unclosed_tag.stderr
new file mode 100644
index 0000000..9fcdbbb
--- /dev/null
+++ b/Examples/test-suite/errors/doxygen_unclosed_tag.stderr
@@ -0,0 +1 @@
+doxygen_unclosed_tag.i:4: Warning 563: Doxygen HTML error for tag b: HTML tag without greater-than ('>') found.
diff --git a/Examples/test-suite/errors/pp_badeval.stderr b/Examples/test-suite/errors/pp_badeval.stderr
index 80f5037..bfaa17f 100644
--- a/Examples/test-suite/errors/pp_badeval.stderr
+++ b/Examples/test-suite/errors/pp_badeval.stderr
@@ -1,2 +1,2 @@
 pp_badeval.i:4: Warning 202: Could not evaluate expression 'FOO==4+'
-pp_badeval.i:4: Warning 202: Error: 'Expected an expression'
+pp_badeval.i:4: Warning 202: Expected an expression
diff --git a/Examples/test-suite/errors/pp_deprecated.i b/Examples/test-suite/errors/pp_deprecated.i
deleted file mode 100644
index 68f8131..0000000
--- a/Examples/test-suite/errors/pp_deprecated.i
+++ /dev/null
@@ -1,9 +0,0 @@
-%module xxx
-
-
-%extern ext;
-
-#warning Print this warning
-
-#error This is an error
-
diff --git a/Examples/test-suite/errors/pp_deprecated.stderr b/Examples/test-suite/errors/pp_deprecated.stderr
deleted file mode 100644
index 6eff001..0000000
--- a/Examples/test-suite/errors/pp_deprecated.stderr
+++ /dev/null
@@ -1,4 +0,0 @@
-pp_deprecated.i:4: Warning 101: %extern is deprecated. Use %import instead.
-pp_deprecated.i:4: Error: Unable to find 'ext;'
-pp_deprecated.i:6: Warning 204: CPP #warning, "Print this warning".
-pp_deprecated.i:8: Error: CPP #error "This is an error". Use the -cpperraswarn option to continue swig processing.
diff --git a/Examples/test-suite/errors/pp_error_directive.i b/Examples/test-suite/errors/pp_error_directive.i
new file mode 100644
index 0000000..8515284
--- /dev/null
+++ b/Examples/test-suite/errors/pp_error_directive.i
@@ -0,0 +1,9 @@
+%module xxx
+
+#warning Print this warning
+
+#error This is an error
+
+#error Another error
+
+#warning Another warning
diff --git a/Examples/test-suite/errors/pp_error_directive.stderr b/Examples/test-suite/errors/pp_error_directive.stderr
new file mode 100644
index 0000000..9e3523a
--- /dev/null
+++ b/Examples/test-suite/errors/pp_error_directive.stderr
@@ -0,0 +1,4 @@
+pp_error_directive.i:3: Warning 204: CPP #warning, "Print this warning".
+pp_error_directive.i:5: Error: CPP #error "This is an error". Use the -cpperraswarn option to continue swig processing.
+pp_error_directive.i:7: Error: CPP #error "Another error". Use the -cpperraswarn option to continue swig processing.
+pp_error_directive.i:9: Warning 204: CPP #warning, "Another warning".
diff --git a/Examples/test-suite/errors/pp_expressions_bad.i b/Examples/test-suite/errors/pp_expressions_bad.i
index 454437f..8f1929e 100644
--- a/Examples/test-suite/errors/pp_expressions_bad.i
+++ b/Examples/test-suite/errors/pp_expressions_bad.i
@@ -1,5 +1,5 @@
 %module xxx
-/* Note: needs -Wextra to see these warnings */
+
 
 /* Divide by zero */
 #define ZERO 0
@@ -41,3 +41,39 @@
 #if(1)
 #warning Warning okay: #if(1)
 #endif
+
+/* The SWIG preprocessor support strings with equality/inequality tests.
+ * Check error cases.
+ */
+#if "TWO" == 1
+#endif
+
+/* This didn't fail prior with SWIG < 4.1.  Github #1384. */
+#if 1 == ("TWO")
+#endif
+
+/* These should all give errors. */
+#if "1"
+#endif
+#if -"1"
+#endif
+#if "1" == -"-1"
+#endif
+#if "1" == !"-1"
+#endif
+#if "1" == ~"1"
+#endif
+/* Unary + was a no-op and so this didn't give an error in SWIG < 4.1.0. */
+#if "1" == +"1"
+#endif
+
+/* Spaceship operator doesn't seem to be allowed in preprocessor expressions,
+ * and isn't valid in C at all.
+ */
+#if (4 <=> 2) < 0
+#endif
+
+/* Check handling of use of an undefined function-like macro. */
+#if MY_VERSION_AT_LEAST(1,2,3)
+#warning This should not warn
+#endif
diff --git a/Examples/test-suite/errors/pp_expressions_bad.stderr b/Examples/test-suite/errors/pp_expressions_bad.stderr
index 84104c6..23c6416 100644
--- a/Examples/test-suite/errors/pp_expressions_bad.stderr
+++ b/Examples/test-suite/errors/pp_expressions_bad.stderr
@@ -1,19 +1,37 @@
 pp_expressions_bad.i:7: Warning 202: Could not evaluate expression '1%ZERO'
-pp_expressions_bad.i:7: Warning 202: Error: 'Modulo by zero in expression'
+pp_expressions_bad.i:7: Warning 202: Modulo by zero in expression
 pp_expressions_bad.i:9: Warning 202: Could not evaluate expression '2/ZERO'
-pp_expressions_bad.i:9: Warning 202: Error: 'Division by zero in expression'
+pp_expressions_bad.i:9: Warning 202: Division by zero in expression
 pp_expressions_bad.i:12: Warning 202: Could not evaluate expression '1%(5-5)'
-pp_expressions_bad.i:12: Warning 202: Error: 'Modulo by zero in expression'
+pp_expressions_bad.i:12: Warning 202: Modulo by zero in expression
 pp_expressions_bad.i:14: Warning 202: Could not evaluate expression '2/(55-55)'
-pp_expressions_bad.i:14: Warning 202: Error: 'Division by zero in expression'
+pp_expressions_bad.i:14: Warning 202: Division by zero in expression
 pp_expressions_bad.i:18: Warning 202: Could not evaluate expression '1.2'
-pp_expressions_bad.i:18: Warning 202: Error: 'Floating point constant in preprocessor expression'
+pp_expressions_bad.i:18: Warning 202: Floating point constant in preprocessor expression
 pp_expressions_bad.i:21: Warning 202: Could not evaluate expression '2e3'
-pp_expressions_bad.i:21: Warning 202: Error: 'Floating point constant in preprocessor expression'
+pp_expressions_bad.i:21: Warning 202: Floating point constant in preprocessor expression
 pp_expressions_bad.i:25: Warning 202: Could not evaluate expression '8.8'
-pp_expressions_bad.i:25: Warning 202: Error: 'Floating point constant in preprocessor expression'
+pp_expressions_bad.i:25: Warning 202: Floating point constant in preprocessor expression
 pp_expressions_bad.i:29: Error: Unknown SWIG preprocessor directive: if123 (if this is a block of target language code, delimit it with %{ and %})
 pp_expressions_bad.i:30: Error: Extraneous #endif.
 pp_expressions_bad.i:32: Error: Unknown SWIG preprocessor directive: if456e (if this is a block of target language code, delimit it with %{ and %})
 pp_expressions_bad.i:33: Error: Extraneous #endif.
 pp_expressions_bad.i:42: Warning 204: CPP #warning, "Warning okay: #if(1)".
+pp_expressions_bad.i:48: Warning 202: Could not evaluate expression '"TWO" == 1'
+pp_expressions_bad.i:48: Warning 202: Can't mix strings and integers in expression
+pp_expressions_bad.i:52: Warning 202: Could not evaluate expression '1 == ("TWO")'
+pp_expressions_bad.i:52: Warning 202: Can't mix strings and integers in expression
+pp_expressions_bad.i:58: Warning 202: Could not evaluate expression '-"1"'
+pp_expressions_bad.i:58: Warning 202: Syntax error: attempt to apply unary operator to string
+pp_expressions_bad.i:60: Warning 202: Could not evaluate expression '"1" == -"-1"'
+pp_expressions_bad.i:60: Warning 202: Syntax error: attempt to apply unary operator to string
+pp_expressions_bad.i:62: Warning 202: Could not evaluate expression '"1" == !"-1"'
+pp_expressions_bad.i:62: Warning 202: Syntax error: attempt to apply unary operator to string
+pp_expressions_bad.i:64: Warning 202: Could not evaluate expression '"1" == ~"1"'
+pp_expressions_bad.i:64: Warning 202: Syntax error: attempt to apply unary operator to string
+pp_expressions_bad.i:67: Warning 202: Could not evaluate expression '"1" == +"1"'
+pp_expressions_bad.i:67: Warning 202: Syntax error: attempt to apply unary operator to string
+pp_expressions_bad.i:73: Warning 202: Could not evaluate expression '(4 <=> 2) < 0'
+pp_expressions_bad.i:73: Warning 202: Syntax error
+pp_expressions_bad.i:77: Warning 202: Could not evaluate expression 'MY_VERSION_AT_LEAST(1,2,3)'
+pp_expressions_bad.i:77: Warning 202: Use of undefined function-like macro
diff --git a/Examples/test-suite/errors/pp_invalid_exponents.stderr b/Examples/test-suite/errors/pp_invalid_exponents.stderr
index 735a31c..2ad1b5c 100644
--- a/Examples/test-suite/errors/pp_invalid_exponents.stderr
+++ b/Examples/test-suite/errors/pp_invalid_exponents.stderr
@@ -1,6 +1,6 @@
 :EOF: Error: Exponent does not have any digits
 pp_invalid_exponents.i:3: Warning 202: Could not evaluate expression '123e'
-pp_invalid_exponents.i:3: Warning 202: Error: 'Syntax error'
+pp_invalid_exponents.i:3: Warning 202: Syntax error
 :EOF: Error: Exponent does not have any digits
 pp_invalid_exponents.i:6: Warning 202: Could not evaluate expression '456.e'
-pp_invalid_exponents.i:6: Warning 202: Error: 'Syntax error'
+pp_invalid_exponents.i:6: Warning 202: Syntax error
diff --git a/Examples/test-suite/errors/pp_unknowndirective.i b/Examples/test-suite/errors/pp_unknowndirective.i
index b4e608b..659a997 100644
--- a/Examples/test-suite/errors/pp_unknowndirective.i
+++ b/Examples/test-suite/errors/pp_unknowndirective.i
@@ -1,10 +1,5 @@
 %module xxx
 
-/* Regression test for bug introduced in 3.0.4 and fixed in 3.0.6 - the '%std'
- * here led to SWIG calling abort().
- */
-%typemap(jstype) std::vector<std::string>, const %std::vector<std::string>&, std::vector<std::string>&  "List<String>"
-
 /* This used to give the rather cryptic "Syntax error in input(1)." prior to
  * SWIG 3.0.4.  This testcase checks that the improved message is actually
  * issued.
diff --git a/Examples/test-suite/errors/pp_unknowndirective.stderr b/Examples/test-suite/errors/pp_unknowndirective.stderr
index 2cc2377..d0d5e24 100644
--- a/Examples/test-suite/errors/pp_unknowndirective.stderr
+++ b/Examples/test-suite/errors/pp_unknowndirective.stderr
@@ -1 +1 @@
-pp_unknowndirective.i:12: Error: Unknown directive '%remane'.
+pp_unknowndirective.i:7: Error: Unknown directive '%remane'.
diff --git a/Examples/test-suite/errors/pp_unknowndirective4.i b/Examples/test-suite/errors/pp_unknowndirective4.i
new file mode 100644
index 0000000..c9d95e1
--- /dev/null
+++ b/Examples/test-suite/errors/pp_unknowndirective4.i
@@ -0,0 +1,7 @@
+%module xxx
+
+/* Regression test for bug #368 introduced in 3.0.4 and fully fixed in 4.1.0.
+ * The `%std` here led to SWIG calling abort() before 3.0.6, and was quietly
+ * ignored in from 3.0.6 until 4.1.0.
+ */
+%typemap(jstype) std::vector<std::string>, const %std::vector<std::string>&, std::vector<std::string>&  "List<String>"
diff --git a/Examples/test-suite/errors/pp_unknowndirective4.stderr b/Examples/test-suite/errors/pp_unknowndirective4.stderr
new file mode 100644
index 0000000..efb6afe
--- /dev/null
+++ b/Examples/test-suite/errors/pp_unknowndirective4.stderr
@@ -0,0 +1 @@
+pp_unknowndirective4.i:7: Error: Unknown directive '%std'.
diff --git a/Examples/test-suite/errors/pp_unknowndirective5.i b/Examples/test-suite/errors/pp_unknowndirective5.i
new file mode 100644
index 0000000..f5fb0f5
--- /dev/null
+++ b/Examples/test-suite/errors/pp_unknowndirective5.i
@@ -0,0 +1,20 @@
+%module xxx
+
+/* Before SWIG 4.1.0 the `9%a` expression triggered:
+ *
+ * Error: Unknown directive '%a'
+ *
+ * The fix for that works by handling an apparent directive that isn't a
+ * recognised directive by noting down its name, emitting MODULO and then
+ * rescanning what follows, and if the parser then gives a syntax error we
+ * report it as an unknown directive.
+ *
+ * However the initial version of this failed to reset the noted down apparent
+ * directive often enough, so a later syntax error could get incorrectly
+ * reported.  Here the syntax error in the declaration of `c` was confusingly
+ * reported as `Error: Unknown directive '%a'`.  This was found and fixed prior
+ * to 4.1.0.
+ */
+int a;
+int test2(int b = 9%a) { return b; }
+void int c;
diff --git a/Examples/test-suite/errors/pp_unknowndirective5.stderr b/Examples/test-suite/errors/pp_unknowndirective5.stderr
new file mode 100644
index 0000000..b61c3ad
--- /dev/null
+++ b/Examples/test-suite/errors/pp_unknowndirective5.stderr
@@ -0,0 +1 @@
+pp_unknowndirective5.i:20: Error: Syntax error in input(1).
diff --git a/Examples/test-suite/errors/swig_command_encoder.i b/Examples/test-suite/errors/swig_command_encoder.i
new file mode 100644
index 0000000..aaae82b
--- /dev/null
+++ b/Examples/test-suite/errors/swig_command_encoder.i
@@ -0,0 +1,6 @@
+%module xxx
+
+// This feature was removed in SWIG 4.1.0 so check it gives an error.
+%define SedCmd "%(command:sed -e 's/\([a-z]\)/\U\\1/' -e 's/\(_\)\([a-z]\)/\U\\2/g' <<<)s" %enddef
+%rename(SedCmd) "";
+int x;
diff --git a/Examples/test-suite/errors/swig_command_encoder.stderr b/Examples/test-suite/errors/swig_command_encoder.stderr
new file mode 100644
index 0000000..2479246
--- /dev/null
+++ b/Examples/test-suite/errors/swig_command_encoder.stderr
@@ -0,0 +1 @@
+SWIG:EOF: Error: Command encoder no longer supported - use regex encoder instead, command:sed -e 's//([a-z]/)//U/1/' -e 's//(_/)/([a-z]/)//U/2/g' <<<x
diff --git a/Examples/test-suite/errors/swig_constant_missing_semi.i b/Examples/test-suite/errors/swig_constant_missing_semi.i
new file mode 100644
index 0000000..3fa1f3b
--- /dev/null
+++ b/Examples/test-suite/errors/swig_constant_missing_semi.i
@@ -0,0 +1,3 @@
+%module xxx
+%constant int BAR=0
+int foo(int);
diff --git a/Examples/test-suite/errors/swig_constant_missing_semi.stderr b/Examples/test-suite/errors/swig_constant_missing_semi.stderr
new file mode 100644
index 0000000..f86d373
--- /dev/null
+++ b/Examples/test-suite/errors/swig_constant_missing_semi.stderr
@@ -0,0 +1 @@
+swig_constant_missing_semi.i:3: Warning 305: Bad constant value (ignored).
diff --git a/Examples/test-suite/errors/swig_typemap_missing_value.i b/Examples/test-suite/errors/swig_typemap_missing_value.i
new file mode 100644
index 0000000..b9937af
--- /dev/null
+++ b/Examples/test-suite/errors/swig_typemap_missing_value.i
@@ -0,0 +1,7 @@
+%module xxx
+
+%typemap(in, numinputs=1, foo) int ""
+%typemap(argout=123) char* ""
+
+/* SWIG segfaulted trying to use the above in typemap in SWIG < 4.1.0. */
+void func(int arg);
diff --git a/Examples/test-suite/errors/swig_typemap_missing_value.stderr b/Examples/test-suite/errors/swig_typemap_missing_value.stderr
new file mode 100644
index 0000000..26bc8cd
--- /dev/null
+++ b/Examples/test-suite/errors/swig_typemap_missing_value.stderr
@@ -0,0 +1,2 @@
+swig_typemap_missing_value.i:3: Error: %typemap attribute 'foo' is missing its value.  If this is specifying the target language, that's no longer supported: use #ifdef SWIG<LANG> instead.
+swig_typemap_missing_value.i:4: Error: %typemap method shouldn't have a value specified.
diff --git a/Examples/test-suite/errors/swig_typemap_old.stderr b/Examples/test-suite/errors/swig_typemap_old.stderr
index 2374116..91bf115 100644
--- a/Examples/test-suite/errors/swig_typemap_old.stderr
+++ b/Examples/test-suite/errors/swig_typemap_old.stderr
@@ -1,5 +1,5 @@
-swig_typemap_old.i:6: Warning 450: Deprecated typemap feature ($source/$target).
-swig_typemap_old.i:6: Warning 450: The use of $source and $target in a typemap declaration is deprecated.
+swig_typemap_old.i:6: Error: Obsolete typemap feature ($source/$target).
+swig_typemap_old.i:6: Error: The use of $source and $target in a typemap declaration is no longer supported.
 For typemaps related to argument input (in,ignore,default,arginit,check), replace
 $source by $input and $target by $1.   For typemaps related to return values (out,
 argout,ret,except), replace $source by $1 and $target by $result.  See the file
diff --git a/Examples/test-suite/exception_memory_leak.i b/Examples/test-suite/exception_memory_leak.i
new file mode 100644
index 0000000..5875d9c
--- /dev/null
+++ b/Examples/test-suite/exception_memory_leak.i
@@ -0,0 +1,70 @@
+%module exception_memory_leak
+
+%include <std_string.i>
+%include <exception.i>
+
+#ifdef SWIGCSHARP
+#define TYPEMAP_OUT_INIT $result = 0;
+#else
+#define TYPEMAP_OUT_INIT
+#endif
+
+%typemap(in) Foo* foo
+{
+  $1 = new Foo;
+}
+%typemap(freearg) Foo* foo
+{
+  Foo::inc_freearg_count();
+  delete $1;
+}
+%typemap(out) Foo* trigger_internal_swig_exception
+{
+  TYPEMAP_OUT_INIT
+  if ($1 == NULL) {
+    SWIG_exception(SWIG_RuntimeError, "Let's see how the bindings manage this exception!");
+#ifdef SWIG_fail
+    SWIG_fail;
+#endif
+  }
+  $1 = NULL;
+}
+%typemap(out) Foo trigger_internal_swig_exception
+{
+  TYPEMAP_OUT_INIT
+  SWIG_exception(SWIG_RuntimeError, "Let's see how the bindings manage this exception!");
+#ifdef SWIG_fail
+  SWIG_fail;
+#endif
+}
+
+%inline %{
+  #include <string>
+
+  class Foo {
+      static unsigned count;
+      static unsigned freearg_count;
+    public:
+      Foo() { ++count; }
+      ~Foo() { --count; }
+      static unsigned get_count() { return count; }
+      static unsigned get_freearg_count() { return freearg_count; }
+#ifndef SWIG
+      static void inc_freearg_count() { ++freearg_count; }
+#endif
+  };
+
+  unsigned Foo::count = 0;
+  unsigned Foo::freearg_count = 0;
+
+  static Foo* trigger_internal_swig_exception(const std::string& message, Foo* foo)
+  {
+    return (message == "null") ? NULL : foo;
+  }
+
+  static Foo trigger_internal_swig_exception(const std::string& message)
+  {
+    return Foo();
+  }
+
+%}
diff --git a/Examples/test-suite/exception_order.i b/Examples/test-suite/exception_order.i
index e241163..523f5c4 100644
--- a/Examples/test-suite/exception_order.i
+++ b/Examples/test-suite/exception_order.i
@@ -128,7 +128,7 @@
 	throw ep;
       } else if (i == 3) {
 	throw ET<int>();
-      } else  {
+      } else {
 	throw ET<double>();
       }
       return 0;
diff --git a/Examples/test-suite/exception_partial_info.i b/Examples/test-suite/exception_partial_info.i
index 3ac465c..1044620 100644
--- a/Examples/test-suite/exception_partial_info.i
+++ b/Examples/test-suite/exception_partial_info.i
@@ -24,14 +24,12 @@
 class ex2 : public myException
 {
    public:
-      virtual const char *name()  { return "ex2"; }
+      virtual const char *name() { return "ex2"; }
 };
 %}
 
 #if !defined(SWIGUTL)
 
-#if !defined(SWIGCHICKEN)
-
 %inline %{
 class Impl
 {
@@ -42,10 +40,6 @@
 %}
 
 #else
-#warning "Chicken needs fixing for partial exception information"
-#endif
-
-#else
 #warning "UTL needs fixing for partial exception information"
 #endif
 
diff --git a/Examples/test-suite/expressions.i b/Examples/test-suite/expressions.i
index 7b907ec..e38e650 100644
--- a/Examples/test-suite/expressions.i
+++ b/Examples/test-suite/expressions.i
@@ -6,5 +6,8 @@
     A() : k( 20/(5-1) ) {}
     A(int i) : k( 20/(5-1)*i /* comment */ ) {}
     int k;
+    // Regression test for preprocessor bug with handling a slash immediately
+    // followed by a single quote, fixed in 4.2.0.  (#2630)
+    int f(int i = 64/' ') { return i; }
 };
 %}
diff --git a/Examples/test-suite/extend_placement.i b/Examples/test-suite/extend_placement.i
index b95e821..4ec0d481 100644
--- a/Examples/test-suite/extend_placement.i
+++ b/Examples/test-suite/extend_placement.i
@@ -83,6 +83,8 @@
 
 // After the class
 
+%warnfilter(SWIGWARN_PARSE_REDEFINED) BarT<int>::spam();
+
 %inline %{
 template<class T>
 class BarT {
diff --git a/Examples/test-suite/extend_template_ns.i b/Examples/test-suite/extend_template_ns.i
index 3712f2c..e4ab3ce 100644
--- a/Examples/test-suite/extend_template_ns.i
+++ b/Examples/test-suite/extend_template_ns.i
@@ -7,7 +7,7 @@
 %} 
  
 namespace oss { 
-   %extend Foo<One> {           //************ this doesn't  work 
+   %extend Foo<One> {           //************ this doesn't work
      int test1(int x) { return x; } 
    };
 } 
diff --git a/Examples/test-suite/extern_c.i b/Examples/test-suite/extern_c.i
index e56d9f12..78c9d10 100644
--- a/Examples/test-suite/extern_c.i
+++ b/Examples/test-suite/extern_c.i
@@ -5,6 +5,7 @@
 void RealFunction(int value);
 typedef void Function1(int value); // Fails
 typedef int Integer1;
+int Integer3;
 }
 typedef void Function2(int value); // Works
 typedef int Integer2;
@@ -27,5 +28,14 @@
 
 extern "C" typedef int Integer;
 Integer int1;
+extern "C" int int2;
+extern "C" { extern int int3; }
+extern "C" { int int4 = 789; }
 %}
 
+%{
+extern "C" {
+  int int2 = 123;
+  int int3 = 456;
+}
+%}
diff --git a/Examples/test-suite/features.i b/Examples/test-suite/features.i
index a8b5652..3ce77f0 100644
--- a/Examples/test-suite/features.i
+++ b/Examples/test-suite/features.i
@@ -68,7 +68,7 @@
 
 // Test 4: Test templates with user supplied constructors and destructor
 %exception Template<int>::Template() "$action /*Template<int>::Template<int>*/";
-%exception Template<int>::Template(const Template&) "$action /*Template<int>::Template<int>(const Template&)*/";
+%exception Template<int>::Template(const Template<int>&) "$action /*Template<int>::Template(const Template&)*/";
 %exception Template<int>::~Template() "$action /*Template<int>::~Template*/";
 // method tests
 %exception Template<int>::foo "$action /*Template<int>::foo*/";
@@ -76,6 +76,7 @@
 %exception Template<int>::set(const int &t) "$action /*Template<int>::set(const int &t)*/";
 %exception Template<int>::bar(const int &t)       "_failed_ /*Template<int>::bar(const int &t) const*/";
 %exception Template<int>::bar(const int &t) const "$action /*Template<int>::bar(const int &t) const*/";
+%exception Template<int>::spam(const Template<int> &)       "$action /*Template<int>::spam(const Template&)*/";
 
 %inline %{
 template<class T> class Template {
@@ -86,6 +87,7 @@
   ~Template(){}
   void foo(){}
   void bar(const int &t) const {}
+  void spam(const Template &){}
 #ifdef SWIG
     %extend {
       T& get(int i) const {
diff --git a/Examples/test-suite/final_c.i b/Examples/test-suite/final_c.i
new file mode 100644
index 0000000..42cac11
--- /dev/null
+++ b/Examples/test-suite/final_c.i
@@ -0,0 +1,13 @@
+%module final_c
+
+%warnfilter(SWIGWARN_PARSE_KEYWORD) final; // 'final' is a java keyword, renaming to '_final'
+
+%inline %{
+struct Y {
+  int yval;
+};
+struct Y final;
+void init() {
+  final.yval = 123;
+}
+%}
diff --git a/Examples/test-suite/fragments.i b/Examples/test-suite/fragments.i
index 4bf399a..e7bcae2 100644
--- a/Examples/test-suite/fragments.i
+++ b/Examples/test-suite/fragments.i
@@ -21,7 +21,7 @@
 }  
 %}
 
-%typemap(in,fragment="Hi") int hola "$1 = 123;";
+%typemap(in,fragment="Hi") int hola "$1 = 123;"
 
 
 %inline %{
@@ -34,3 +34,107 @@
 }
 
 %}
+
+/* Instantiate multiple fragments at once using fragments in comma separated list */
+typedef int comma_frag3;
+
+%fragment("comma_frag1","header", noblock=1) {
+typedef int comma_frag1;
+}
+
+%fragment("comma_frag2","header", noblock=1, noblock=1) {
+typedef comma_frag1 comma_frag2;
+}
+
+%fragment("comma_frag3","header",
+          fragment="comma_frag1,comma_frag2")
+%{typedef comma_frag2 comma_frag3;%}
+
+%fragment("comma_frag3");
+%inline %{
+comma_frag3 my_comma_frag_int = 0;
+%}
+
+
+/* Instantiate multiple fragments at once using multiple keywords */
+typedef int explicit_frag3;
+
+%fragment("explicit_frag1","header", noblock=1) {
+typedef int explicit_frag1;
+}
+
+%fragment("explicit_frag2","header", noblock=1) {
+typedef explicit_frag1 explicit_frag2;
+}
+
+%fragment("explicit_frag3","header",
+          fragment="explicit_frag1", fragment="explicit_frag2")
+%{typedef explicit_frag2 explicit_frag3;%}
+
+%fragment("explicit_frag3");
+%inline %{
+explicit_frag3 my_int = 0;
+%}
+
+/* Test typemap's ability to instantiate multiple fragments on demand */
+typedef int int_infrag1;
+typedef int int_infrag2;
+typedef int int_outfrag1;
+typedef int int_outfrag2;
+typedef int int_outfrag3;
+
+%fragment("infrag2","runtime") %{
+typedef int_infrag1 int_infrag2;
+%}
+
+%fragment("infrag1","runtime") %{
+typedef int int_infrag1;
+%}
+%fragment("infrag2","runtime") %{
+__second_infrag2_fragment_is_ignored_this_will_not_compile_if_emitted_
+typedef int_infrag1 int_infrag2;
+%}
+
+%fragment("outfrag1","runtime") %{
+typedef int int_outfrag1;
+%}
+%fragment("outfrag2","runtime") %{
+typedef int_outfrag1 int_outfrag2;
+%}
+
+%fragment("tcfrag1","runtime") %{
+typedef int int_tcfrag1;
+%}
+%fragment("tcfrag2","runtime") %{
+typedef int_tcfrag1 int_tcfrag2;
+%}
+
+%fragment("outspecial"{bool},"runtime") %{
+typedef int int_outfrag3_temp;
+%}
+%fragment("outfrag3","runtime") %{
+typedef int_outfrag3_temp int_outfrag3;
+%}
+
+%typemap(in, fragment="infrag1", fragment="infrag2") int_infrag2
+%{$typemap(in,int)%}
+
+%typemap(check, fragment="tcfrag1", noblock=1, fragment="tcfrag2") int_infrag2
+{(void)sizeof(int_tcfrag2);}
+
+%typemap(out, fragment="outfrag1", fragment="outfrag2", noblock=1) int_outfrag2
+{$typemap(out,int)}
+
+/* Test another permutation of keyword order */
+%typemap(out, noblock=1, fragment="outfrag1", fragment="outfrag2") int_outfrag1
+{$typemap(out,int)}
+
+/* Test fragment specialization */
+%typemap(out, noblock=1, fragment="outspecial"{bool}, fragment="outfrag3") int_outfrag3
+{$typemap(out,int)}
+
+%inline %{
+int identity_in(int_infrag2 inp) { return inp; }
+int_outfrag2 identity_out(int inp) { return inp; }
+int_outfrag3 identity_out_2(int inp) { return inp; }
+%}
diff --git a/Examples/test-suite/friends.i b/Examples/test-suite/friends.i
index 1ba1e5e..0efffd1 100644
--- a/Examples/test-suite/friends.i
+++ b/Examples/test-suite/friends.i
@@ -3,7 +3,8 @@
 #include <iostream>
 %}
 
-%warnfilter(SWIGWARN_LANG_IDENTIFIER);
+%warnfilter(SWIGWARN_LANG_IDENTIFIER) operator<<;
+%warnfilter(SWIGWARN_LANG_IDENTIFIER) operator>>;
 
 #if defined(SWIGOCTAVE)
 %warnfilter(SWIGWARN_IGNORE_OPERATOR_LSHIFT_MSG) operator<<;
@@ -139,45 +140,114 @@
     };
 
   namespace ns1 {
-
     void bas() {}
-
     void baz() {}
   }
 }
 
-// Use this version with extra qualifiers to test SWIG as some compilers accept this
-  namespace ns1 {
-    namespace ns2 {
-      class Foo {
-      public:
-	Foo::Foo() {};
-	friend void bar();
-	friend void ns1::baz();	
-	void Foo::member() { }
-	
-      };
-      void bar() {}    
-    }
-  }
+%inline %{
+  class CModelParameterSpecies;
+  class CModelParameterCompartment {
+    CModelParameterSpecies *species;
+  public:
+    int getSpeciesVal();
+    CModelParameterCompartment();
+    ~CModelParameterCompartment();
+  };
+  class CModelParameterSpecies
+  {
+    int private_val;
+  public:
+    // Friend function-declarations are silently ignored (including constructor and destructor declarations)
+    friend CModelParameterCompartment::~CModelParameterCompartment();
+    friend CModelParameterCompartment::CModelParameterCompartment();
+    friend int CModelParameterCompartment::getSpeciesVal();
+  };
+%}
 
-// Remove extra qualifiers for the compiler as some compilers won't compile the extra qaulification (eg gcc-4.1 onwards) 
 %{
+CModelParameterCompartment::CModelParameterCompartment() {
+  species = new CModelParameterSpecies();
+  species->private_val = 1;
+}
+CModelParameterCompartment::~CModelParameterCompartment() {
+  species->private_val = 0;
+  delete species;
+}
+int CModelParameterCompartment::getSpeciesVal() {
+  return species->private_val;
+}
+%}
+
+
+// Unqualified friend function definition and declaration example from SWIG docs
+%inline %{
+class Chum {
+  int val;
+  friend int chum_blah() { Chum c; c.private_function(); return c.val; }
+  void private_function();
+};
+
+class Mate {
+  int val;
+  friend int mate_blah(); // Unqualified friend function declaration
+  void private_function();
+};
+%}
+
+%{
+// Only seen by the compiler, not seen by SWIG
+int chum_blah();
+int mate_blah() { Mate m; m.private_function(); return m.val; }
+
+void Chum::private_function() { this->val = 1234; }
+void Mate::private_function() { this->val = 4321; }
+%}
+
+
+// Foe class tests friend definitions/declarations in a namespace
+%inline %{
   namespace ns1 {
     namespace ns2 {
-      class Foo {
+      class Foe {
+        int val;
       public:
-	Foo() {};
-	friend void bar();
-	friend void ns1::baz();	
-	void member() { }
-	
+	Foe() : val() {}
+	Foe(int val) : val(val) {}
+        // Unqualified friends visible to SWIG in outer scope
+	friend int friend_definition() { return Foe(10).val; }
+	friend int friend_declaration();
+	friend int friend_args_definition(Foe &foe) { return foe.val; }
+	friend int friend_args_declaration(Foe &foe);
+
+        // Unqualified friends only visible to C++ compiler in outer scope
+	friend int friend_definition_compiler() { return Foe(20).val; }
+	friend int friend_declaration_compiler();
+	friend int friend_args_definition_compiler(Foe &foe) { return foe.val; }
+	friend int friend_args_declaration_compiler(Foe &foe);
+
+        // Qualified friend (silently ignored)
+	friend void ns1::baz();
       };
-      void bar() {}    
+      int friend_definition();
+      int friend_declaration() { return Foe(11).val; }
+      int friend_args_definition(Foe &foe);
+      int friend_args_declaration(Foe &foe) { return foe.val; }
     }
   }
 %}
-    
+
+%{
+  namespace ns1 {
+    namespace ns2 {
+      int friend_definition_compiler();
+      int friend_declaration_compiler() { return Foe(21).val; }
+   // int friend_args_definition_compiler(Foe &foe); // ADL is used to find this, so no declaration is needed
+      int friend_args_declaration_compiler(Foe &foe) { return foe.val; }
+    }
+  }
+%}
+
 
 %template(D_i) D<int>;
 %template(D_d) D<double>;
diff --git a/Examples/test-suite/friends_operator_overloading.i b/Examples/test-suite/friends_operator_overloading.i
new file mode 100644
index 0000000..bbf5033
--- /dev/null
+++ b/Examples/test-suite/friends_operator_overloading.i
@@ -0,0 +1,114 @@
+%module friends_operator_overloading
+
+// Tests friend operators within a namespace
+// Demonstrates how to turn friend operators into member functions (required for some languages - tests includes a Python runtime test)
+// Note that by default the friend functions result in global function wrappers (overloaded as there are friends from two different classes)
+// Testcase highlighted a compilation problem with Python builtin wrappers
+// Tests only the languages that don't ignore operator<<
+
+%warnfilter(SWIGWARN_LANG_IDENTIFIER,                    // Warning 503: Can't wrap 'operator <<' unless renamed to a valid identifier.
+            SWIGWARN_IGNORE_OPERATOR_LSHIFT) operator<<; // Warning 373: operator<< ignored
+
+%inline %{
+// Remove this define to test the equivalent implementation using member methods instead of friends
+#define FRIENDS
+
+// Debugging/tracing using printf
+#include <cstdio>
+//#define myprintf(a, b) printf(a, b)
+#define myprintf(a, b)
+
+namespace shifting {
+
+class ShiftA {
+  int val;
+public:
+  ShiftA(int val = 0) : val(val) {}
+#if !defined(FRIENDS)
+  ShiftA operator<<(const ShiftA& gd) {
+    ShiftA ret(val - gd.getVal());
+    myprintf("member operator << (GeoData) %d\n", ret.getVal());
+    return ret;
+  }
+  ShiftA operator<<(int amount) {
+    ShiftA ret(val - amount);
+    myprintf("member operator << (int) %d\n", ret.getVal());
+    return ret;
+  }
+#else
+  friend ShiftA operator<<(const ShiftA& this_, const ShiftA& gd) {
+    ShiftA ret(this_.val - gd.getVal());
+    myprintf("friend operator << (GeoData) %d\n", ret.getVal());
+    return ret;
+  }
+  friend ShiftA operator<<(const ShiftA& this_, int amount) {
+    ShiftA ret(this_.val - amount);
+    myprintf("friend operator << (int) %d\n", ret.getVal());
+    return ret;
+  }
+#if defined(SWIG)
+%extend {
+  ShiftA operator<<(const ShiftA& gd) { return *$self << gd; }
+  ShiftA operator<<(int amount) { return *$self << amount; }
+}
+#endif
+#endif
+  int getVal() const { return val; }
+};
+
+class ShiftB {
+  int val;
+public:
+  ShiftB(int val = 0) : val(val) {}
+#if !defined(FRIENDS)
+  ShiftB operator<<(const ShiftB& gd) {
+    ShiftB ret(val - gd.getVal());
+    myprintf("member operator << (GeoData) %d\n", ret.getVal());
+    return ret;
+  }
+  ShiftB operator<<(int amount) {
+    ShiftB ret(val - amount);
+    myprintf("member operator << (int) %d\n", ret.getVal());
+    return ret;
+  }
+#else
+  friend ShiftB operator<<(const ShiftB& this_, const ShiftB& gd) {
+    ShiftB ret(this_.val - gd.getVal());
+    myprintf("friend operator << (GeoData) %d\n", ret.getVal());
+    return ret;
+  }
+  friend ShiftB operator<<(const ShiftB& this_, int amount) {
+    ShiftB ret(this_.val - amount);
+    myprintf("friend operator << (int) %d\n", ret.getVal());
+    return ret;
+  }
+#if defined(SWIG)
+%extend {
+  ShiftB operator<<(const ShiftB& gd) { return *$self << gd; }
+  ShiftB operator<<(int amount) { return *$self << amount; }
+}
+#endif
+#endif
+  int getVal() const { return val; }
+};
+
+void sanity_checker_ShiftA() {
+  ShiftA gd1(20);
+  ShiftA gd2(100);
+  ShiftA gd3(gd2 << gd1);
+  myprintf("gd3 %d\n", gd3.getVal());
+  ShiftA gd4(gd2 << 30);
+  myprintf("gd4 %d\n", gd4.getVal());
+
+}
+void sanity_checker_ShiftB() {
+  ShiftB gd1(20);
+  ShiftB gd2(100);
+  ShiftB gd3(gd2 << gd1);
+  myprintf("gd3 %d\n", gd3.getVal());
+  ShiftB gd4(gd2 << 30);
+  myprintf("gd4 %d\n", gd4.getVal());
+}
+
+}
+%}
diff --git a/Examples/test-suite/global_immutable_vars.i b/Examples/test-suite/global_immutable_vars.i
new file mode 100644
index 0000000..9545b29
--- /dev/null
+++ b/Examples/test-suite/global_immutable_vars.i
@@ -0,0 +1,33 @@
+%module global_immutable_vars
+
+// Test immutable and mutable global variables,
+// see https://www.swig.org/Doc4.0/SWIGDocumentation.html#SWIG_readonly_variables
+
+%inline %{
+  int default_mutable_var = 40;
+%}
+
+%immutable;
+%feature("immutable", "0") specific_mutable_var;
+
+%inline %{
+  int global_immutable_var = 41;
+  int specific_mutable_var = 42;
+%}
+
+%mutable;
+%immutable specific_immutable_var;
+%inline %{
+  int global_mutable_var = 43;
+  int specific_immutable_var = 44;
+
+  int check_values(int default_mutable, int global_immutable, int specific_mutable, int global_mutable, int specific_immutable) {
+    return
+      default_mutable    == default_mutable_var &&
+      global_immutable   == global_immutable_var &&
+      specific_mutable   == specific_mutable_var &&
+      global_mutable     == global_mutable_var &&
+      specific_immutable == specific_immutable_var;
+  }
+%}
+
diff --git a/Examples/test-suite/global_immutable_vars_cpp.i b/Examples/test-suite/global_immutable_vars_cpp.i
new file mode 100644
index 0000000..b5d5e0f
--- /dev/null
+++ b/Examples/test-suite/global_immutable_vars_cpp.i
@@ -0,0 +1,33 @@
+%module global_immutable_vars_cpp
+
+// Test immutable and mutable global variables,
+// see https://www.swig.org/Doc4.0/SWIGDocumentation.html#SWIG_readonly_variables
+
+%inline %{
+  int default_mutable_var = 40;
+%}
+
+%immutable;
+%feature("immutable", "0") specific_mutable_var;
+
+%inline %{
+  int global_immutable_var = 41;
+  int specific_mutable_var = 42;
+%}
+
+%mutable;
+%immutable specific_immutable_var;
+%inline %{
+  int global_mutable_var = 43;
+  int specific_immutable_var = 44;
+
+  int check_values(int default_mutable, int global_immutable, int specific_mutable, int global_mutable, int specific_immutable) {
+    return
+      default_mutable    == default_mutable_var &&
+      global_immutable   == global_immutable_var &&
+      specific_mutable   == specific_mutable_var &&
+      global_mutable     == global_mutable_var &&
+      specific_immutable == specific_immutable_var;
+  }
+%}
+
diff --git a/Examples/test-suite/global_vars.i b/Examples/test-suite/global_vars.i
index d562d1e..46133fe 100644
--- a/Examples/test-suite/global_vars.i
+++ b/Examples/test-suite/global_vars.i
@@ -33,4 +33,8 @@
     b = "string b";
     x = 1234;
   }
+
+  int read_x() { return x; }
+
+  std::string read_b() { return b; }
 %}
diff --git a/Examples/test-suite/go/Makefile.in b/Examples/test-suite/go/Makefile.in
index 8283327..b2ac7262 100644
--- a/Examples/test-suite/go/Makefile.in
+++ b/Examples/test-suite/go/Makefile.in
@@ -12,6 +12,10 @@
 
 SO = @SO@
 
+HAVE_CXX11   = @HAVE_CXX11@
+HAVE_CXX14   = @HAVE_CXX14@
+HAVE_CXX17   = @HAVE_CXX17@
+HAVE_CXX20   = @HAVE_CXX20@
 srcdir         = @srcdir@
 top_srcdir     = @top_srcdir@
 top_builddir   = @top_builddir@
@@ -43,17 +47,9 @@
 
 %.multicpptest:
 	$(setup)
-	mkdir -p gopath/$*/src 2>/dev/null || true
-	if ! test -d gopath/$*/src/swigtests; then \
-	  (cd gopath/$*/src && ln -s . swigtests); \
-	fi
+	$(go_multicpp_setup)
 	+for f in `cat $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list` ; do \
-	  $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
-	  SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	  LIBS='$(LIBS)' INCLUDES='$(INCLUDES)' SWIGOPT='$(SWIGOPT)' NOLINK=true \
-	  TARGET="$(TARGETPREFIX)$${f}$(TARGETSUFFIX)" INTERFACEDIR='$(INTERFACEDIR)' INTERFACE="$$f.i" \
-	  GOMOD="$*" \
-	  $(LANGUAGE)$(VARIANT)_cpp; \
+	  $(call swig_and_compile_cpp_helper,$${f},'$(SWIGOPT)') GOMOD="$*"; \
 	done
 	$(run_multi_testcase)
 
@@ -61,28 +57,9 @@
 	# Does not work because go build won't build li_windows.go,
 	# because file names with "windows" are only built on Windows.
 
-multi_import.multicpptest:
-	$(setup)
-	mkdir -p gopath/multi_import/src 2>/dev/null || true
-	if ! test -d gopath/multi_import/src/swigtests; then \
-	  (cd gopath/multi_import/src && ln -s . swigtests); \
-	fi
-	for f in multi_import_b multi_import_a; do \
-	  $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
-	  SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	  LIBS='$(LIBS)' INCLUDES='$(INCLUDES)' SWIGOPT='$(SWIGOPT)' NOLINK=true \
-	  TARGET="$(TARGETPREFIX)$${f}$(TARGETSUFFIX)" INTERFACEDIR='$(INTERFACEDIR)' INTERFACE="$$f.i" \
-	  GOMOD="multi_import" \
-	  $(LANGUAGE)$(VARIANT)_cpp; \
-	done
-	$(run_multi_testcase)
-
 go_subdir_import.multicpptest:
 	$(setup)
-	mkdir -p gopath/go_subdir_import/src 2>/dev/null || true
-	if ! test -d gopath/go_subdir_import/src/swigtests; then \
-	  (cd gopath/go_subdir_import/src && ln -s . swigtests); \
-	fi
+	$(go_multicpp_setup)
 	mkdir -p testdir/go_subdir_import 2>/dev/null || true
 	mkdir -p gopath/go_subdir_import/src/testdir/go_subdir_import 2>/dev/null || true
 	$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
@@ -93,16 +70,17 @@
 	INTERFACE='testdir/go_subdir_import/go_subdir_import_b.i' \
 	GOMOD="go_subdir_import" \
 	$(LANGUAGE)$(VARIANT)_cpp;
-	for f in testdir/go_subdir_import/go_subdir_import_c go_subdir_import_a ; do \
-	  $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' CXXSRCS='$(CXXSRCS)' \
-	  SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
-	  LIBS='$(LIBS)' INCLUDES='$(INCLUDES)' SWIGOPT='$(SWIGOPT)' NOLINK=true \
-	  TARGET="$(TARGETPREFIX)$${f}$(TARGETSUFFIX)" INTERFACEDIR='$(INTERFACEDIR)' INTERFACE="$$f.i" \
-	  GOMOD="go_subdir_import" \
-	  $(LANGUAGE)$(VARIANT)_cpp; \
+	+for f in testdir/go_subdir_import/go_subdir_import_c go_subdir_import_a ; do \
+	  $(call swig_and_compile_cpp_helper,$${f},'$(SWIGOPT)') GOMOD="go_subdir_import"; \
 	done
 	$(run_multi_testcase)
 
+go_multicpp_setup = \
+	mkdir -p gopath/$*/src 2>/dev/null || true; \
+	if ! test -d gopath/$*/src/swigtests; then \
+	  (cd gopath/$*/src && ln -s . swigtests); \
+	fi
+
 # Runs the testcase.
 run_testcase = \
 	if test -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); then \
@@ -121,8 +99,7 @@
 	  cp gopath/src/$*/* gopath/src/swigtests/$*/; \
 	  mkdir gopath/src/$*/runme 2>/dev/null || true; \
 	  cp $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) gopath/src/$*/runme/runme.go; \
-	  (cd gopath/src/$*/runme && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o runme runme.go); \
-	  cp gopath/src/$*/runme/runme $*_runme; \
+	  (cd gopath/src/$*/runme && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o ../../../../$*_runme runme.go); \
 	  env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) ./$*_runme; \
 	fi
 
@@ -143,8 +120,7 @@
 	  cp gopath/src/$*/* gopath/src/swigtests/$*/; \
 	  mkdir gopath/src/$*/runme 2>/dev/null || true; \
 	  cp $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) gopath/src/$*/runme/runme.go; \
-	  (cd gopath/src/$*/runme && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o runme runme.go); \
-	  cp gopath/src/$*/runme/runme $*_runme; \
+	  (cd gopath/src/$*/runme && $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o ../../../../$*_runme runme.go); \
 	  env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) ./$*_runme; \
 	fi
 
@@ -164,7 +140,7 @@
 	  CGO_LDFLAGS="$(LDFLAGS) -lm"; \
 	  export CGO_LDFLAGS; \
 	  (cd gopath/$*/src/$* && \
-	    $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o ../../../../$*_runme) && \
+	    $(COMPILETOOL) $(GO) build `if $(GOGCC); then echo -compiler=gccgo; fi` -o ../../../../$*_runme) && \
 	  env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) ./$*_runme; \
 	fi
 
@@ -173,16 +149,18 @@
 
 clean:
 	$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' go_clean
-	rm -f mod_a.go mod_a.gox mod_b.go mod_b.gox
-	rm -f imports_a.go imports_a.gox imports_b.go imports_b.gox
 	rm -f clientdata_prop_a.go clientdata_prop_a.gox
 	rm -f clientdata_prop_b.go clientdata_prop_b.gox
+	rm -f import_stl_a.go import_stl_a.gox
+	rm -f import_stl_b.go import_stl_b.gox
+	rm -f imports_a.go imports_a.gox imports_b.go imports_b.gox
+	rm -f mod_a.go mod_a.gox mod_b.go mod_b.gox
 	rm -f multi_import_a.go multi_import_a.gox
 	rm -f multi_import_b.go multi_import_b.gox
-	rm -rf go_subdir_import_a.go go_subdir_import_a.gox testdir
+	rm -f multi_import_d.go multi_import_d.gox
 	rm -f packageoption_a.go packageoption_a.gox
 	rm -f packageoption_b.go packageoption_b.gox
 	rm -f packageoption_c.go packageoption_c.gox
-	rm -f import_stl_a.go import_stl_a.gox
-	rm -f import_stl_b.go import_stl_b.gox
+	rm -f template_typedef_cplx2.go template_typedef_cplx2.gox
+	rm -rf go_subdir_import_a.go go_subdir_import_a.gox testdir
 	rm -rf gopath
diff --git a/Examples/test-suite/go/argcargvtest_runme.go b/Examples/test-suite/go/argcargvtest_runme.go
new file mode 100644
index 0000000..1bb1feb
--- /dev/null
+++ b/Examples/test-suite/go/argcargvtest_runme.go
@@ -0,0 +1,55 @@
+package main
+
+import wrap "swigtests/argcargvtest"
+
+func main() {
+	largs := []string{"hi", "hola", "hello"}
+	if ri := wrap.Mainc(largs); ri != 3 {
+		panic(ri)
+	}
+
+	targs := []string{"hi", "hola"}
+	if rs := wrap.Mainv(targs, 0); rs != "hi" {
+		panic(rs)
+	}
+	if rs := wrap.Mainv(targs, 1); rs != "hola" {
+		panic(rs)
+	}
+	if rs := wrap.Mainv(targs, 2); rs != "<<NULL>>" {
+		panic(rs)
+	}
+
+// For dynamically typed languages we test this throws an exception or similar
+// at runtime, but for Go this doesn't even compile (but we can't easily
+// test for that here).
+//	wrap.Mainv("hello", 1)
+
+	wrap.InitializeApp(largs)
+
+	// Check that an empty array works.
+	empty_args := []string{};
+	if ri := wrap.Mainc(empty_args); ri != 0 {
+		panic(ri)
+	}
+	if rs := wrap.Mainv(empty_args, 0); rs != "<<NULL>>" {
+		panic(rs)
+	}
+
+	// Check that empty strings are handled.
+	empty_string := []string{"hello", "", "world"};
+	if ri := wrap.Mainc(empty_string); ri != 3 {
+		panic(ri)
+	}
+	if rs := wrap.Mainv(empty_string, 0); rs != "hello" {
+		panic(rs)
+	}
+	if rs := wrap.Mainv(empty_string, 1); rs != "" {
+		panic(rs)
+	}
+	if rs := wrap.Mainv(empty_string, 2); rs != "world" {
+		panic(rs)
+	}
+	if rs := wrap.Mainv(empty_string, 3); rs != "<<NULL>>" {
+		panic(rs)
+	}
+}
diff --git a/Examples/test-suite/go/catches_strings_runme.go b/Examples/test-suite/go/catches_strings_runme.go
new file mode 100644
index 0000000..b31565c
--- /dev/null
+++ b/Examples/test-suite/go/catches_strings_runme.go
@@ -0,0 +1,32 @@
+package main
+
+import "strings"
+import . "swigtests/catches_strings"
+
+func main() {
+  {
+    exception_thrown := false
+    func() {
+      defer func() {
+        exception_thrown = strings.Index(recover().(string), "charstring message") == 0
+      }()
+      StringsThrowerCharstring()
+    }()
+    if !exception_thrown {
+      panic(0)
+    }
+  }
+
+  {
+    exception_thrown := false
+    func() {
+      defer func() {
+        exception_thrown = strings.Index(recover().(string), "stdstring message") == 0
+      }()
+      StringsThrowerStdstring()
+    }()
+    if !exception_thrown {
+      panic(0)
+    }
+  }
+}
diff --git a/Examples/test-suite/go/class_case_runme.go b/Examples/test-suite/go/class_case_runme.go
new file mode 100644
index 0000000..7d0870b
--- /dev/null
+++ b/Examples/test-suite/go/class_case_runme.go
@@ -0,0 +1,12 @@
+package main
+
+import . "swigtests/class_case"
+
+func main() {
+	b2 := NewClassB2()
+	// This used to fail with:
+	// panic: interface conversion: interface {} is class_case.SwigcptrClassB2, not int
+	if Test2(b2) != 1 {
+		panic("Unexpected overload used")
+	}
+}
diff --git a/Examples/test-suite/go/cpp11_std_array_runme.go b/Examples/test-suite/go/cpp11_std_array_runme.go
new file mode 100644
index 0000000..97b5df2
--- /dev/null
+++ b/Examples/test-suite/go/cpp11_std_array_runme.go
@@ -0,0 +1,68 @@
+package main
+
+import (
+  "fmt"
+  "swigtests/cpp11_std_array"
+)
+
+func CompareContainers(actual cpp11_std_array.ArrayInt6, expected [6]int) error {
+  if int(actual.Size()) != len(expected) {
+    return fmt.Errorf("Sizes are different: %d %d", actual.Size(), len(expected))
+  }
+  for i := 0; i < int(actual.Size()); i++ {
+    actualValue := actual.Get(i)
+    expectedValue := expected[i]
+    if actualValue != expectedValue {
+      return fmt.Errorf("Value is wrong for element %d. Expected %d got: %d", i, expectedValue, actualValue)
+    }
+  }
+  if actual.IsEmpty() {
+	  return fmt.Errorf("ai should not be empty")
+  }
+  return nil
+}
+
+func main() {
+  ai := cpp11_std_array.NewArrayInt6()
+  ps := [6]int{0, 0, 0, 0, 0, 0}
+  CompareContainers(ai, ps)
+
+  vals := [6]int{10, 20, 30, 40, 50, 60}
+  for i := 0; i < len(vals); i++ {
+    ai.Set(i, vals[i])
+  }
+  CompareContainers(ai, vals);
+
+  // Check return
+  vals = [6]int{-2, -1, 0, 0, 1, 2}
+  CompareContainers(cpp11_std_array.ArrayOutVal(), vals);
+  CompareContainers(cpp11_std_array.ArrayOutConstRef(), vals);
+  CompareContainers(cpp11_std_array.ArrayOutRef(), vals);
+  CompareContainers(cpp11_std_array.ArrayOutPtr(), vals);
+
+  // Check passing arguments
+  vals = [6]int{9, 8, 7, 6, 5, 4}
+  valsArrayInt6 := cpp11_std_array.NewArrayInt6()
+  for i := 0; i < len(vals); i++ {
+    valsArrayInt6.Set(i, vals[i])
+  }
+
+  ai = cpp11_std_array.ArrayInVal(valsArrayInt6);
+  CompareContainers(ai, vals);
+
+  ai = cpp11_std_array.ArrayInConstRef(valsArrayInt6);
+  CompareContainers(ai, vals);
+
+  ai = cpp11_std_array.NewArrayInt6(valsArrayInt6);
+  cpp11_std_array.ArrayInRef(ai);
+  CompareContainers(ai, vals);
+
+  ai = cpp11_std_array.NewArrayInt6(valsArrayInt6);
+  cpp11_std_array.ArrayInPtr(ai);
+  CompareContainers(ai, vals);
+
+  // Fill
+  ai.Fill(111)
+  vals = [6]int{111, 111, 111, 111, 111, 111}
+  CompareContainers(ai, vals);
+}
diff --git a/Examples/test-suite/go/friends_runme.go b/Examples/test-suite/go/friends_runme.go
index b6b9e93..393d6f6 100644
--- a/Examples/test-suite/go/friends_runme.go
+++ b/Examples/test-suite/go/friends_runme.go
@@ -27,24 +27,31 @@
 		panic(0)
 	}
 
-	di := friends.NewD_d(2)
+	di := friends.NewD_i(2)
 	dd := friends.NewD_d(3.3)
 
 	// incredible template overloading working just fine
-	if friends.Get_val1(di).(float64) != 2 {
+	if friends.Get_val1(di).(int) != 2 {
 		panic(0)
 	}
 	if friends.Get_val1(dd).(float64) != 3.3 {
 		panic(0)
 	}
 
-	friends.Set(di, 4.0)
+	friends.Set(di, 4)
 	friends.Set(dd, 1.3)
 
-	if friends.Get_val1(di).(float64) != 4 {
+	if friends.Get_val1(di).(int) != 4 {
 		panic(0)
 	}
 	if friends.Get_val1(dd).(float64) != 1.3 {
 		panic(0)
 	}
+
+        if friends.Chum_blah() != 1234 {
+		panic(0)
+        }
+        if friends.Mate_blah() != 4321 {
+		panic(0)
+        }
 }
diff --git a/Examples/test-suite/go/go_director_inout_runme.go b/Examples/test-suite/go/go_director_inout_runme.go
index 171b3c2..6b68543 100644
--- a/Examples/test-suite/go/go_director_inout_runme.go
+++ b/Examples/test-suite/go/go_director_inout_runme.go
@@ -14,6 +14,35 @@
 	return wrap.GoRetStruct{s}
 }
 
+func (p *GoMyClass) S1(s string) {
+	if s != "S1" {
+		panic(s)
+	}
+}
+
+func (p *GoMyClass) S2(s *string) {
+	if *s != "S2" {
+		panic(s)
+	}
+	*s = "R2"
+}
+
+func (p *GoMyClass) S3(s *string) {
+	if *s != "S3" {
+		panic(s)
+	}
+	*s = "R3"
+}
+
+func (p *GoMyClass) S4(s []string) {
+	if s[0] != "T1" {
+		panic(s)
+	}
+	if s[1] != "T2" {
+		panic(s)
+	}
+}
+
 func main() {
 	a := wrap.NewDirectorMyClass(&GoMyClass{})
 	m := map[string]interface{}{
@@ -24,6 +53,23 @@
 		panic(s)
 	}
 
+	a.S1("S1")
+	str := "S2"
+	a.S2(&str)
+	if str != "R2" {
+		panic(str)
+	}
+	str = "S3"
+	a.S3(&str)
+	if str != "R3" {
+		panic(str)
+	}
+
+	a.CallS4([]string{ "T1", "T2" })
+
+	a.S5(&str)
+	a.S5(nil)
+
 	a = wrap.NewDirectorMyClass(nil)
 	s = a.Adjust(m)
 	if s.Str != `{"first":"second"}` {
diff --git a/Examples/test-suite/go/go_inout_runme.go b/Examples/test-suite/go/go_inout_runme.go
index 2dc5b99..981b7f2 100644
--- a/Examples/test-suite/go/go_inout_runme.go
+++ b/Examples/test-suite/go/go_inout_runme.go
@@ -50,4 +50,12 @@
 		fmt.Println("for c2.M got", pm, "want", want)
 		panic(pm)
 	}
+
+	c1 := go_inout.NewC1()
+	c2.M2(c1)
+	c2.M2(nil)
+
+	if !go_inout.Strings([]string{"1", "2"}) {
+		panic("Strings failed")
+	}
 }
diff --git a/Examples/test-suite/go/li_constraints_runme.go b/Examples/test-suite/go/li_constraints_runme.go
new file mode 100644
index 0000000..6dda260
--- /dev/null
+++ b/Examples/test-suite/go/li_constraints_runme.go
@@ -0,0 +1,70 @@
+package main
+
+import wrap "swigtests/li_constraints"
+import "fmt";
+
+func check_double(except bool, f func (float64), val float64, name string) {
+    actual := true
+    proper := false
+	func() {
+		defer func() {
+            r := recover();
+			if r != nil {
+                actual = false
+                proper = fmt.Sprintf("%s", r) == fmt.Sprintf("Expected a %s value.", name)
+			}
+		}()
+        f(val);
+	}()
+    if actual {
+      if !except {
+        panic(fmt.Sprintf("function '%s' with %d should perform an exception", name, val));
+      }
+    } else {
+      if except {
+        panic(fmt.Sprintf("function '%s' with %d should not perform an exception", name, val));
+      } else if !proper {
+        panic(fmt.Sprintf("function '%s' with %d should perform a proper exception", name, val));
+      }
+    }
+}
+
+func main() {
+    check_double(true, wrap.Test_nonnegative, 10, "non-negative");
+    check_double(true, wrap.Test_nonnegative, 0, "non-negative");
+    check_double(false, wrap.Test_nonnegative, -10, "non-negative");
+
+    check_double(false, wrap.Test_nonpositive, 10, "non-positive");
+    check_double(true, wrap.Test_nonpositive, 0, "non-positive");
+    check_double(true, wrap.Test_nonpositive, -10, "non-positive");
+
+    check_double(true, wrap.Test_positive, 10, "positive");
+    check_double(false, wrap.Test_positive, 0, "positive");
+    check_double(false, wrap.Test_positive, -10, "positive");
+
+    check_double(false, wrap.Test_negative, 10, "negative");
+    check_double(false, wrap.Test_negative, 0, "negative");
+    check_double(true, wrap.Test_negative, -10, "negative");
+
+    check_double(true, wrap.Test_nonzero, 10, "nonzero");
+    check_double(false, wrap.Test_nonzero, 0, "nonzero");
+    check_double(true, wrap.Test_nonzero, -10, "nonzero");
+
+    have_exception := false
+	func() {
+		defer func() {
+            r := recover()
+			if r != nil {
+                have_exception = "Received a NULL pointer." == fmt.Sprintf("%s", r)
+			}
+		}()
+        // The NULL value
+        // We can not use Go `nil` as is it can not be convert to a uintptr value.
+        wrap.Test_nonnull(uintptr(0));
+	}()
+    if !have_exception {
+        panic("test_nonnull should perform exception with 'null' value")
+    }
+    nonnull := wrap.Get_nonnull();
+    wrap.Test_nonnull(nonnull);
+}
diff --git a/Examples/test-suite/go/smart_pointer_extend_runme.go b/Examples/test-suite/go/smart_pointer_extend_runme.go
index f91c9ac..e349be1 100644
--- a/Examples/test-suite/go/smart_pointer_extend_runme.go
+++ b/Examples/test-suite/go/smart_pointer_extend_runme.go
@@ -22,6 +22,10 @@
 		panic(0)
 	}
 
+	if d.Bar() != p.Bar() {
+		panic(0)
+	}
+
 	if CBaseHello() != p.Hello() {
 		panic(0)
 	}
diff --git a/Examples/test-suite/go/special_variable_macros_runme.go b/Examples/test-suite/go/special_variable_macros_runme.go
index 597c487..13b4518 100644
--- a/Examples/test-suite/go/special_variable_macros_runme.go
+++ b/Examples/test-suite/go/special_variable_macros_runme.go
@@ -25,4 +25,10 @@
 	if special_variable_macros.TestJohn(special_variable_macros.NewPairIntBool(10, false)) != 123 {
 		panic("test failed")
 	}
+	if special_variable_macros.MakeStringInt("stringint", 999) != "stringint" {
+		panic("test failed")
+	}
+	if special_variable_macros.ProvideStringInt(999) != "1000" {
+		panic("test failed")
+	}
 }
diff --git a/Examples/test-suite/go/typedef_inherit_runme.go b/Examples/test-suite/go/typedef_inherit_runme.go
index f2dbb32..eef3ef4 100644
--- a/Examples/test-suite/go/typedef_inherit_runme.go
+++ b/Examples/test-suite/go/typedef_inherit_runme.go
@@ -28,4 +28,9 @@
 	if x != "Grok::blah" {
 		panic(x)
 	}
+
+	x = d.Far()
+	if x != "Spam::far" {
+		panic(x)
+	}
 }
diff --git a/Examples/test-suite/go/typemap_out_optimal_runme.go b/Examples/test-suite/go/typemap_out_optimal_runme.go
index 0cccd97..646aa8e 100644
--- a/Examples/test-suite/go/typemap_out_optimal_runme.go
+++ b/Examples/test-suite/go/typemap_out_optimal_runme.go
@@ -3,6 +3,7 @@
 import . "swigtests/typemap_out_optimal"
 
 func main() {
-	SetXXDebug(false)
+	SetXXTrace(false)
 	_ = XXCreate()
+	_ = XXCreateConst()
 }
diff --git a/Examples/test-suite/go_director_inout.i b/Examples/test-suite/go_director_inout.i
index 5a7fbdf..0be3ca1 100644
--- a/Examples/test-suite/go_director_inout.i
+++ b/Examples/test-suite/go_director_inout.i
@@ -2,6 +2,8 @@
 
 %module(directors="1") go_director_inout
 
+%include <std_string.i>
+
 %{
 #include <string>
 %}
@@ -108,6 +110,102 @@
   $1.str.assign($input.p, $input.n);
 %}
 
+%typemap(directorin) std::string & (_gostring_ temp) {
+    $input = &temp;
+    temp.p = (char *) $1.data();
+    temp.n = $1.size();
+}
+%typemap(directorargout) std::string & {
+    _gostring_ *tmp = $input;
+    $1.assign(tmp->p, tmp->p + tmp->n);
+}
+
+%inline %{
+// Helper functions for converting string arrays
+#include <stdlib.h>
+void *alloc_ptr_array(unsigned int len)
+{
+    return calloc(len, sizeof(void *));
+}
+void set_ptr_array(void *ain, unsigned int pos, void *val)
+{
+    void **a = (void **) ain;
+    a[pos] = val;
+}
+void *get_ptr_array(void *ain, unsigned int pos)
+{
+    void **a = (void **) ain;
+    return a[pos];
+}
+void free_ptr_array(void *ain)
+{
+    void **a = (void **) ain;
+    unsigned int i;
+
+    if (!a)
+        return;
+    for (i = 0; a[i]; i++) {
+        free(a[i]);
+    }
+    free(a);
+}
+char *uintptr_to_string(void *in)
+{
+    return (char *) in;
+}
+void *string_to_uintptr(char *in)
+{
+    return strdup(in);
+}
+%}
+
+// These typemaps convert between an array of strings in Go and a
+// const char** that is NULL terminated in C++.
+%typemap(gotype) (const char * const *) "[]string"
+%typemap(imtype) (const char * const *) "uintptr"
+%typemap(goin) (const char * const *) {
+	if $input == nil || len($input) == 0 {
+		$result = 0
+	} else {
+		$result = Alloc_ptr_array(uint(len($input) + 1))
+		defer func() {
+			Free_ptr_array($result)
+		}()
+		var i uint
+		for i = 0; i < uint(len($input)); i++ {
+			Set_ptr_array($result, i, String_to_uintptr($input[i]))
+		}
+	}
+}
+%typemap(in) (const char * const *) {
+    $1 = (char **) $input;
+}
+%typemap(godirectorin) (const char * const *) {
+	if ($input == 0) {
+		$result = nil
+	} else {
+		var i uint
+		for i = 0; ; i++ {
+			var v uintptr = Get_ptr_array($input, i)
+			if v == 0 {
+				break
+			}
+		}
+		if i == 0 {
+			$result = nil
+		} else {
+			$result = make([]string, i)
+			for i = 0; ; i++ {
+				var v uintptr = Get_ptr_array($input, i)
+				if v == 0 {
+					break
+				}
+				$result[i] = Uintptr_to_string(v)
+			}
+		}
+	}
+}
+
 %feature("director") MyClass;
 
 %inline
@@ -121,6 +219,33 @@
     r.str = s.str;
     return r;
   }
+
+  void CallS4(const char * const *strarray);
+  virtual void S1(std::string s);
+  virtual void S2(std::string& s) = 0;
+  virtual void S3(std::string* s) = 0;
+  virtual void S4(const char * const *strarray);
+  virtual int S5(const std::string* s);
 };
 
+void MyClass::S1(std::string s) {
+    throw "Base S1 called!";
+}
+
+void MyClass::S4(const char * const *strarray) {
+    throw "Base S4 called!";
+}
+
+void MyClass::CallS4(const char * const *strarray) {
+    this->S4(strarray);
+}
+
+int MyClass::S5(const std::string* s) {
+    if (s) {
+        return (*s)[0];
+    } else {
+        return 0;
+    }
+}
+
 %}
diff --git a/Examples/test-suite/go_inout.i b/Examples/test-suite/go_inout.i
index 0bcb979..ae68178 100644
--- a/Examples/test-suite/go_inout.i
+++ b/Examples/test-suite/go_inout.i
@@ -239,5 +239,47 @@
 };
 
 class C2 : public C1 {
+ public:
+  void M2(C1*) {}
 };
 %}
+
+%typemap(gotype) (char *ps[], int cs) "[]string"
+
+%typemap(in) (char *ps[], int cs)
+%{
+  {
+    int i;
+    _gostring_* a;
+
+    $2 = $input.len;
+    a = (_gostring_*) $input.array;
+    $1 = (char **) malloc (($2 + 1) * sizeof (char *));
+    for (i = 0; i < $2; i++) {
+      _gostring_ *ps = &a[i];
+      $1[i] = (char *) malloc(ps->n + 1);
+      memcpy($1[i], ps->p, ps->n);
+      $1[i][ps->n] = '\0';
+    }
+    $1[i] = NULL;
+  }
+%}
+
+%typemap(freearg) (char *ps[], int cs)
+%{
+  {
+    int i;
+
+    for (i = 0; i < $2; i++) {
+      free($1[i]);
+    }
+    free($1);
+  }
+%}
+
+%inline
+%{
+bool Strings(char *ps[], int cs) {
+  return cs == 2 && strcmp(ps[0], "1") == 0 && strcmp(ps[1], "2") == 0 & ps[2] == NULL;
+}
+%}
diff --git a/Examples/test-suite/go_subdir_import_a.i b/Examples/test-suite/go_subdir_import_a.i
index 3fc36e6..5a35c8f 100644
--- a/Examples/test-suite/go_subdir_import_a.i
+++ b/Examples/test-suite/go_subdir_import_a.i
@@ -6,7 +6,7 @@
  * This case might happen for two different reasons:
  * 1) Importing a module for which the .i file is in a subdirectory relatively
  *    to this file (this is tested here with go_subdir_import_c).
- * 2) Importing a module whos module name is a path (this is tested here with
+ * 2) Importing a module whose module name is a path (this is tested here with
  *    go_subdir_import_b).
  *
  * This file is the "root" file that imports the two modules which will be
diff --git a/Examples/test-suite/grouping.i b/Examples/test-suite/grouping.i
index 5632231..24acf69 100644
--- a/Examples/test-suite/grouping.i
+++ b/Examples/test-suite/grouping.i
@@ -14,7 +14,7 @@
     return &y;
 }
 
-int (test3) = 37;
+int test3 = 37;
 
 typedef Integer (UnaryOp)(Integer);
 
diff --git a/Examples/test-suite/guile/Makefile.in b/Examples/test-suite/guile/Makefile.in
index 55885fc..2efa6ad 100644
--- a/Examples/test-suite/guile/Makefile.in
+++ b/Examples/test-suite/guile/Makefile.in
@@ -8,6 +8,10 @@
 VARIANT      =
 SCRIPTSUFFIX = _runme.scm
 
+HAVE_CXX11   = @HAVE_CXX11@
+HAVE_CXX14   = @HAVE_CXX14@
+HAVE_CXX17   = @HAVE_CXX17@
+HAVE_CXX20   = @HAVE_CXX20@
 srcdir       = @srcdir@
 top_srcdir   = @top_srcdir@
 top_builddir = @top_builddir@
diff --git a/Examples/test-suite/guile/argcargvtest_runme.scm b/Examples/test-suite/guile/argcargvtest_runme.scm
new file mode 100644
index 0000000..5e9ec48
--- /dev/null
+++ b/Examples/test-suite/guile/argcargvtest_runme.scm
@@ -0,0 +1,6 @@
+;; The SWIG modules have "passive" Linkage, i.e., they don't generate
+;; Guile modules (namespaces) but simply put all the bindings into the
+;; current module.  That's enough for such a simple test.
+(dynamic-call "scm_init_argcargvtest_module" (dynamic-link "./libargcargvtest"))
+(load "testsuite.scm")
+(load "../schemerunme/argcargvtest.scm")
diff --git a/Examples/test-suite/guile/catches_strings_runme.scm b/Examples/test-suite/guile/catches_strings_runme.scm
new file mode 100644
index 0000000..376f235
--- /dev/null
+++ b/Examples/test-suite/guile/catches_strings_runme.scm
@@ -0,0 +1,3 @@
+(dynamic-call "scm_init_catches_strings_module" (dynamic-link "./libcatches_strings"))
+(load "testsuite.scm")
+(load "../schemerunme/catches_strings.scm")
diff --git a/Examples/test-suite/guile/cpp11_move_typemaps_runme.scm b/Examples/test-suite/guile/cpp11_move_typemaps_runme.scm
new file mode 100644
index 0000000..43f78e6
--- /dev/null
+++ b/Examples/test-suite/guile/cpp11_move_typemaps_runme.scm
@@ -0,0 +1,3 @@
+(dynamic-call "scm_init_cpp11_move_typemaps_module" (dynamic-link "./libcpp11_move_typemaps"))
+(load "testsuite.scm")
+(load "../schemerunme/cpp11_move_typemaps.scm")
diff --git a/Examples/test-suite/guile/cpp11_rvalue_reference_move_runme.scm b/Examples/test-suite/guile/cpp11_rvalue_reference_move_runme.scm
new file mode 100644
index 0000000..30ddff7
--- /dev/null
+++ b/Examples/test-suite/guile/cpp11_rvalue_reference_move_runme.scm
@@ -0,0 +1,3 @@
+(dynamic-call "scm_init_cpp11_rvalue_reference_move_module" (dynamic-link "./libcpp11_rvalue_reference_move"))
+(load "testsuite.scm")
+(load "../schemerunme/cpp11_rvalue_reference_move.scm")
diff --git a/Examples/test-suite/guile/cpp11_std_unique_ptr_runme.scm b/Examples/test-suite/guile/cpp11_std_unique_ptr_runme.scm
new file mode 100644
index 0000000..9ba124a
--- /dev/null
+++ b/Examples/test-suite/guile/cpp11_std_unique_ptr_runme.scm
@@ -0,0 +1,3 @@
+(dynamic-call "scm_init_cpp11_std_unique_ptr_module" (dynamic-link "./libcpp11_std_unique_ptr"))
+(load "testsuite.scm")
+(load "../schemerunme/cpp11_std_unique_ptr.scm")
diff --git a/Examples/test-suite/guile/guile_ext_test_external.cxx b/Examples/test-suite/guile/guile_ext_test_external.cxx
index c4f906a..2729537 100644
--- a/Examples/test-suite/guile/guile_ext_test_external.cxx
+++ b/Examples/test-suite/guile/guile_ext_test_external.cxx
@@ -19,6 +19,6 @@
 SCM test_is_pointer(SCM val)
 {
 #define FUNC_NAME "test-is-pointer"
-  return SCM_BOOL(SWIG_IsPointer(val));
+  return scm_from_bool(SWIG_IsPointer(val));
 #undef FUNC_NAME
 }
diff --git a/Examples/test-suite/guile/li_std_auto_ptr_runme.scm b/Examples/test-suite/guile/li_std_auto_ptr_runme.scm
new file mode 100644
index 0000000..04d3d65
--- /dev/null
+++ b/Examples/test-suite/guile/li_std_auto_ptr_runme.scm
@@ -0,0 +1,3 @@
+(dynamic-call "scm_init_li_std_auto_ptr_module" (dynamic-link "./libli_std_auto_ptr"))
+(load "testsuite.scm")
+(load "../schemerunme/li_std_auto_ptr.scm")
diff --git a/Examples/test-suite/guile/newobject1_runme.scm b/Examples/test-suite/guile/newobject1_runme.scm
new file mode 100644
index 0000000..21f6d86
--- /dev/null
+++ b/Examples/test-suite/guile/newobject1_runme.scm
@@ -0,0 +1,3 @@
+(dynamic-call "scm_init_newobject1_module" (dynamic-link "./libnewobject1"))
+(load "../schemerunme/newobject1.scm")
+
diff --git a/Examples/test-suite/guile/null_pointer_runme.scm b/Examples/test-suite/guile/null_pointer_runme.scm
new file mode 100644
index 0000000..cad65e8
--- /dev/null
+++ b/Examples/test-suite/guile/null_pointer_runme.scm
@@ -0,0 +1,3 @@
+(dynamic-call "scm_init_null_pointer_module" (dynamic-link "./libnull_pointer"))
+(load "testsuite.scm")
+(load "../schemerunme/null_pointer.scm")
diff --git a/Examples/test-suite/guile/overload_null_runme.scm b/Examples/test-suite/guile/overload_null_runme.scm
index f764d9c..6824707 100644
--- a/Examples/test-suite/guile/overload_null_runme.scm
+++ b/Examples/test-suite/guile/overload_null_runme.scm
@@ -39,15 +39,15 @@
 ;(check (=~ 15 (Overload-byval2cpr o #nil)))
 ;(check (=~ 16 (Overload-byval2cpr o x)))
 
-; forward class declaration
-(check (=~ 17 (Overload-byval1forwardptr o x)))
-(check (=~ 18 (Overload-byval1forwardptr o #nil)))
+; fwd class declaration
+(check (=~ 17 (Overload-byval1fwdptr o x)))
+(check (=~ 18 (Overload-byval1fwdptr o #nil)))
 
-(check (=~ 19 (Overload-byval2forwardptr o #nil)))
-(check (=~ 20 (Overload-byval2forwardptr o x)))
+(check (=~ 19 (Overload-byval2fwdptr o #nil)))
+(check (=~ 20 (Overload-byval2fwdptr o x)))
 
-(check (=~ 21 (Overload-byval1forwardref o x)))
+(check (=~ 21 (Overload-byval1fwdref o x)))
 
-(check (=~ 22 (Overload-byval2forwardref o x)))
+(check (=~ 22 (Overload-byval2fwdref o x)))
 
 (exit 0)
diff --git a/Examples/test-suite/iadd.i b/Examples/test-suite/iadd.i
index 514bd3e..a3e6645 100644
--- a/Examples/test-suite/iadd.i
+++ b/Examples/test-suite/iadd.i
@@ -1,9 +1,13 @@
 %module iadd
 
+#if defined(SWIGJAVASCRIPT)
+%rename(addto) operator+=;
+#endif
+
 %include attribute.i
 class Foo; 
-%attribute_ref(test::Foo, test::A& , AsA);
-%attribute_ref(test::Foo, long, AsLong);
+%attributeref(test::Foo, test::A&, AsA);
+%attributeref(test::Foo, long, AsLong);
 
 
 %inline %{
diff --git a/Examples/test-suite/ignore_parameter.i b/Examples/test-suite/ignore_parameter.i
index 604ee3b..72db2ff 100644
--- a/Examples/test-suite/ignore_parameter.i
+++ b/Examples/test-suite/ignore_parameter.i
@@ -2,15 +2,32 @@
 
 %module ignore_parameter
 
-%typemap(in,numinputs=0) char* a "static const char* hi = \"hello\"; $1 = const_cast<char *>(hi);";
-%typemap(in,numinputs=0) int bb "$1 = 101;";
-%typemap(in,numinputs=0) double ccc "$1 = 8.8;";
+%typemap(in,numinputs=0) char* a %{
+  /* Catch if a target language substitutes this typemap more than once in
+   * the same wrapper method - this will lead to an error due to this label
+   * being redefined.
+   */
+  goto redefinition_error_means_in_typemap_substituted_more_than_once;
+  redefinition_error_means_in_typemap_substituted_more_than_once:
+  $1 = const_cast<char *>("hello");
+%}
+%typemap(in,numinputs=0) int bb "$1 = 101; called_argout = 0;"
+%typemap(in,numinputs=0) double ccc "$1 = 8.8;"
 
-%typemap(freearg) char* a ""; // ensure freearg is not generated (needed for Java at least)
+%typemap(freearg) char* a "" // ensure freearg is not generated (needed for Java at least)
+
+%typemap(argout) int bb "called_argout = 1;"
 
 %ignore unignorable;
+// Don't let SWIG expand this function with its default parameter: instead,
+// always "require" the version of the function with a single argument, but
+// then ignore it using `numinputs=0`.
+%ignore audi();
 
 %inline %{
+// constant for detecting correct "argout" call
+int called_argout = 0;
+
 // global function tests
 char* jaguar(char* a, int b, double c) { return a; }
 int lotus(char* aa, int bb, double cc) { return bb; }
@@ -25,6 +42,7 @@
   double bugatti(char* aaa, int bbb, double ccc) { return ccc; }
   int lamborghini(int bb) { return bb; }
   int maseratti(int unignorable) { return unignorable; }
+  double audi(double ccc=9.5) { return ccc; }
 };
 
 // constructor tests
diff --git a/Examples/test-suite/import_nomodule.i b/Examples/test-suite/import_nomodule.i
index 60ef7e0..2794ad5 100644
--- a/Examples/test-suite/import_nomodule.i
+++ b/Examples/test-suite/import_nomodule.i
@@ -6,9 +6,11 @@
 // For Python
 %warnfilter(SWIGWARN_TYPE_UNDEFINED_CLASS) Bar; // Base class 'Foo' ignored - unknown module name for base. Either import the appropriate module interface file or specify the name of the module in the %import directive. 
 
-%import "import_nomodule.h"
+// The "dummy=" attribute is a regression test for #1006, fixed in SWIG 4.1.0.
+// SWIG didn't used to take quoting into account when finding the closing `)`.
+%import(dummy=")foo\"") "import_nomodule.h"
 
-#if !defined(SWIGJAVA) && !defined(SWIGRUBY) && !defined(SWIGCSHARP) && !defined(SWIGD) && !defined(SWIGPYTHON_BUILTIN)
+#if !defined(SWIGJAVA) && !defined(SWIGRUBY) && !defined(SWIGCSHARP) && !defined(SWIGD) && !defined(SWIGPYTHON_BUILTIN) && !defined(SWIGPHP)
 
 /**
  * The proxy class does not have Bar derived from Foo, yet an instance of Bar
@@ -16,8 +18,8 @@
  * language modules).
  * 
  * This violation of the type system is not possible in Java, C# and D due to
- * static type checking. It's also not (currently) possible in Ruby, but this may
- * be fixable (needs more investigation).
+ * static type checking. It's also not (currently) possible in PHP or Ruby, but
+ * this may be fixable (needs more investigation).
  */
 
 %newobject create_Foo;
diff --git a/Examples/test-suite/inout.i b/Examples/test-suite/inout.i
index dc6db0e..315ee91 100644
--- a/Examples/test-suite/inout.i
+++ b/Examples/test-suite/inout.i
@@ -46,3 +46,13 @@
 void AddOne2p(std::pair<double, double>* INOUT, double* INOUT);
 void AddOne3p(double* INOUT, std::pair<double, double>* INOUT, double* INOUT);
 void AddOne1r(double& INOUT);
+
+%inline %{
+  inline void StringNot(char** INOUT) {
+    if ((*INOUT)[0]) { *INOUT = NULL; } else { *INOUT = (char*)"empty"; }
+  }
+
+  inline void CharNot(char* INOUT) {
+    if (*INOUT) { *INOUT = '\0'; } else { *INOUT = '\xff'; }
+  }
+%}
diff --git a/Examples/test-suite/inplaceadd.i b/Examples/test-suite/inplaceadd.i
index 91ef84b..c84603c 100644
--- a/Examples/test-suite/inplaceadd.i
+++ b/Examples/test-suite/inplaceadd.i
@@ -3,6 +3,11 @@
 #include <iostream>
 %}
 
+#if defined(SWIGJAVASCRIPT)
+%rename(addTo) operator +=;
+%rename(subFrom) operator -=;
+%rename(mulTo) operator *=;
+#endif
 
 %inline %{
   struct A 
diff --git a/Examples/test-suite/input.i b/Examples/test-suite/input.i
index 6cef3f9..7614494 100644
--- a/Examples/test-suite/input.i
+++ b/Examples/test-suite/input.i
@@ -6,7 +6,7 @@
   if ($1) {
     $result = SWIG_From(int)(*$1);
   } else {
-    $result = SWIG_Py_Void();
+    $result = VOID_Object;
   }
 }
 
@@ -29,7 +29,7 @@
   if ($1) {
     $result = SWIG_From(std::string)(*$1);
   } else {
-    $result = SWIG_Py_Void();
+    $result = VOID_Object;
   }
 }
 
diff --git a/Examples/test-suite/integers.i b/Examples/test-suite/integers.i
index 6a9ede4..9569df7 100644
--- a/Examples/test-suite/integers.i
+++ b/Examples/test-suite/integers.i
@@ -17,6 +17,41 @@
   signed long long signed_long_long_identity(signed long long x) { return x; }
   unsigned long long unsigned_long_long_identity(unsigned long long x) { return x; }
 
+#ifdef __cplusplus
+  signed char        & signed_char_ref_identity(       signed char        & x) { return x; }
+  unsigned char      & unsigned_char_ref_identity(     unsigned char      & x) { return x; }
+  signed short       & signed_short_ref_identity(      signed short       & x) { return x; }
+  unsigned short     & unsigned_short_ref_identity(    unsigned short     & x) { return x; }
+  signed int         & signed_int_ref_identity(        signed int         & x) { return x; }
+  unsigned int       & unsigned_int_ref_identity(      unsigned int       & x) { return x; }
+  signed long        & signed_long_ref_identity(       signed long        & x) { return x; }
+  unsigned long      & unsigned_long_ref_identity(     unsigned long      & x) { return x; }
+  signed long long   & signed_long_long_ref_identity(  signed long long   & x) { return x; }
+  unsigned long long & unsigned_long_long_ref_identity(unsigned long long & x) { return x; }
+
+  const signed char        & const_signed_char_ref_identity(       const signed char        & x) { return x; }
+  const unsigned char      & const_unsigned_char_ref_identity(     const unsigned char      & x) { return x; }
+  const signed short       & const_signed_short_ref_identity(      const signed short       & x) { return x; }
+  const unsigned short     & const_unsigned_short_ref_identity(    const unsigned short     & x) { return x; }
+  const signed int         & const_signed_int_ref_identity(        const signed int         & x) { return x; }
+  const unsigned int       & const_unsigned_int_ref_identity(      const unsigned int       & x) { return x; }
+  const signed long        & const_signed_long_ref_identity(       const signed long        & x) { return x; }
+  const unsigned long      & const_unsigned_long_ref_identity(     const unsigned long      & x) { return x; }
+  const signed long long   & const_signed_long_long_ref_identity(  const signed long long   & x) { return x; }
+  const unsigned long long & const_unsigned_long_long_ref_identity(const unsigned long long & x) { return x; }
+#endif
+
+  signed char        * signed_char_ptr() { return NULL; }
+  unsigned char      * unsigned_char_ptr() { return NULL; }
+  signed short       * signed_short_ptr() { return NULL; }
+  unsigned short     * unsigned_short_ptr() { return NULL; }
+  signed int         * signed_int_ptr() { return NULL; }
+  unsigned int       * unsigned_int_ptr() { return NULL; }
+  signed long        * signed_long_ptr() { return NULL; }
+  unsigned long      * unsigned_long_ptr() { return NULL; }
+  signed long long   * signed_long_long_ptr() { return NULL; }
+  unsigned long long * unsigned_long_long_ptr() { return NULL; }
+
   size_t signed_char_size() { return sizeof (signed char); }
   size_t unsigned_char_size() { return sizeof (unsigned char); }
   size_t signed_short_size() { return sizeof (signed short); }
diff --git a/Examples/test-suite/java/CommentParser.java b/Examples/test-suite/java/CommentParser.java
index 7dc6d59..1974059 100644
--- a/Examples/test-suite/java/CommentParser.java
+++ b/Examples/test-suite/java/CommentParser.java
@@ -1,5 +1,6 @@
 
-import com.sun.javadoc.*;
+import com.sun.source.doctree.*;
+import com.sun.source.util.DocTrees;
 import java.util.HashMap;
 import java.util.Map.Entry;
 import java.util.Map;
@@ -9,45 +10,120 @@
 import java.io.OutputStreamWriter;
 import java.io.FileOutputStream;
 import java.io.IOException;
+import java.util.*;
+import java.util.spi.ToolProvider;
+import javax.lang.model.*;
+import javax.lang.model.element.*;
+import javax.lang.model.util.*;
+import jdk.javadoc.doclet.*;
 
 
-public class CommentParser {
+public class CommentParser implements Doclet {
     private static Map<String, String> m_parsedComments = new HashMap<String, String>();
 
-    public static boolean start(RootDoc root) {
+    // We need to implement these base class pure virtual methods.
 
+    @Override
+    public void init(Locale locale, Reporter reporter) {
+    }
+
+    @Override
+    public Set<? extends Option> getSupportedOptions() {
+        return new HashSet<>();
+    }
+
+    @Override
+    public SourceVersion getSupportedSourceVersion() {
+        return SourceVersion.latest();
+    }
+
+    @Override
+    public String getName() {
+        return "CommentParser";
+    }
+
+    // Element name must be the fully qualified name of the element.
+    //
+    // If there is no comment associated with this element, simply do nothing.
+    private void storeCommentFor(DocTrees docTrees, String fullName, Element e) {
+        DocCommentTree docCommentTree = docTrees.getDocCommentTree(e);
+        if (docCommentTree == null)
+            return;
+
+        StringBuilder name = new StringBuilder(fullName);
+
+        // We must use signature in the key for methods for compatibility with
+        // the existing tests and to allow distinguishing between overloaded
+        // methods.
+        if (e instanceof ExecutableElement) {
+            ExecutableElement ex = (ExecutableElement)e;
+            name.append("(");
+
+            boolean firstParam = true;
+            for (VariableElement p : ex.getParameters()) {
+                if (firstParam) {
+                    firstParam = false;
+                } else {
+                    name.append(", ");
+                }
+
+                name.append(p.asType().toString());
+            }
+
+            name.append(")");
+        }
+
+        // For some reason the comment in the source is split into "body" and
+        // "block tags" parts, so we need to concatenate them back together.
+        StringBuilder comment = new StringBuilder();
+        for (DocTree d : docCommentTree.getFullBody()) {
+            comment.append(d.toString());
+            comment.append("\n");
+        }
+
+        boolean firstBlockTag = true;
+        for (DocTree d : docCommentTree.getBlockTags()) {
+            if (firstBlockTag) {
+                firstBlockTag = false;
+                comment.append("\n");
+            }
+
+            comment.append(d.toString());
+            comment.append("\n");
+        }
+
+        m_parsedComments.put(name.toString(), comment.toString());
+    }
+
+    @Override
+    public boolean run(DocletEnvironment docEnv) {
         /*
          * This method is called by 'javadoc' and gets the whole parsed java
          * file, we get comments and store them
          */
+        DocTrees docTrees = docEnv.getDocTrees();
+        for (TypeElement t : ElementFilter.typesIn(docEnv.getIncludedElements())) {
+            String typeName = t.getQualifiedName().toString();
 
-        for (ClassDoc classDoc : root.classes()) {
+            storeCommentFor(docTrees, typeName, t);
 
-            if (classDoc.getRawCommentText().length() > 0)
-                m_parsedComments.put(classDoc.qualifiedName(), classDoc.getRawCommentText());
+            for (Element e : t.getEnclosedElements()) {
+                // Omit the method name for ctors: this is a bit weird, but
+                // this is what the existing tests expect.
+                String fullName = typeName;
+                if (e.getKind() != ElementKind.CONSTRUCTOR) {
+                    fullName = fullName + "." + e.getSimpleName();
+                }
 
-            for (FieldDoc f : classDoc.enumConstants()) {
-                if (f.getRawCommentText().length() > 0)
-                    m_parsedComments.put(f.qualifiedName(), f.getRawCommentText());
-            }
-            for (FieldDoc f : classDoc.fields()) {
-                if (f.getRawCommentText().length() > 0)
-                    m_parsedComments.put(f.qualifiedName(), f.getRawCommentText());
-            }
-            for (ConstructorDoc c : classDoc.constructors()) {
-                if (c.getRawCommentText().length() > 0)
-                    m_parsedComments.put(c.toString(), c.getRawCommentText());
-            }
-            for (MethodDoc m : classDoc.methods()) {
-                if (m.getRawCommentText().length() > 0)
-                    m_parsedComments.put(m.toString(), m.getRawCommentText());
+                storeCommentFor(docTrees, fullName, e);
             }
         }
+
         return true;
     }
 
     
-    public int check(Map<String, String> wantedComments) {
+    public static int check(Map<String, String> wantedComments) {
         int errorCount=0;
         Iterator<Entry<String, String>> it = m_parsedComments.entrySet().iterator();
 
@@ -93,13 +169,14 @@
                 System.out.println("Output is also saved to files '" + expectedFileName +
                                    "' and '" + gotFileName + "'");
                 // here we print original strings, for nicer output
-                System.out.println("\n\n---\nexpected:\n" + wantedComments.get(e.getKey()));
+                System.out.println("\n\n---\nexpected:\n" + wantedStr);
                 System.out.println("\n\n---\ngot:\n" + e.getValue());
 
                 try {
                     // write expected string to file
                     BufferedWriter expectedFile = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(expectedFileName)));
-                    expectedFile.write(wantedComments.get(e.getKey()));
+                    if (wantedStr != null)
+                        expectedFile.write(wantedStr);
                     expectedFile.close();
 
                     // write translated string to file
@@ -130,7 +207,7 @@
     }
 
     
-    private void printKeys(Map<String, String> map) {
+    private static void printKeys(Map<String, String> map) {
         
         Set<String> keys = map.keySet();
         for (String key : keys) {
@@ -143,7 +220,7 @@
 
         Iterator< Entry<String, String> > it = m_parsedComments.entrySet().iterator();
         
-        while (it.hasNext())  {
+        while (it.hasNext()) {
             
             Entry<String, String> e = (Entry<String, String>) it.next();
             String commentText = e.getValue();
@@ -154,6 +231,15 @@
         }
     }
 
+    public static void parse(String sourcefile) {
+        ToolProvider javadoc = ToolProvider.findFirst("javadoc").orElseThrow();
+        int result = javadoc.run(System.out, System.err, new String[]{"-quiet", "-doclet", "CommentParser", sourcefile});
+        if (result != 0) {
+          System.err.println("Executing javadoc failed.");
+          System.exit(result);
+        }
+    }
+
     
     public static void main(String argv[]) {
 		
@@ -162,8 +248,7 @@
             System.exit(1);
         }
 		
-        com.sun.tools.javadoc.Main.execute("The comment parser program",
-                                           "CommentParser", new String[]{"-quiet", argv[0]});
+        parse(argv[0]);
 		
         // if we are run as standalone app, print the list of found comments as it would appear in java source
 		
diff --git a/Examples/test-suite/java/Makefile.in b/Examples/test-suite/java/Makefile.in
index 2e788fa..83335d4 100644
--- a/Examples/test-suite/java/Makefile.in
+++ b/Examples/test-suite/java/Makefile.in
@@ -9,7 +9,12 @@
 JAVA_CLASSPATH_SEP = @JAVA_CLASSPATH_SEP@
 JAVA_TOOLS_JAR     = @JAVA_TOOLS_JAR@
 SCRIPTSUFFIX = _runme.java
+SKIP_DOXYGEN_TEST_CASES = @JAVA_SKIP_DOXYGEN_TEST_CASES@
 
+HAVE_CXX11   = @HAVE_CXX11@
+HAVE_CXX14   = @HAVE_CXX14@
+HAVE_CXX17   = @HAVE_CXX17@
+HAVE_CXX20   = @HAVE_CXX20@
 srcdir       = @srcdir@
 top_srcdir   = ../@top_srcdir@
 top_builddir = ../@top_builddir@
@@ -43,15 +48,17 @@
 	java_throws \
 	java_typemaps_proxy \
 	java_typemaps_typewrapper \
+	nested_scope \
 	li_std_list \
-	li_std_map \
 	li_std_set \
 #	li_boost_intrusive_ptr
 
 CPP11_TEST_CASES = \
 	cpp11_shared_ptr_const \
+	cpp11_shared_ptr_crtp_upcast \
 	cpp11_shared_ptr_nullptr_in_containers \
 	cpp11_shared_ptr_overload \
+	cpp11_shared_ptr_template_upcast \
 	cpp11_shared_ptr_upcast \
 	cpp11_std_unordered_map \
 	cpp11_std_unordered_set \
@@ -108,13 +115,11 @@
 	  mkdir $(JAVA_PACKAGE);							  \
 	fi
 
-# Doxygen test cases need to be compiled together with the CommentParser class
-# which depends on com.sun.javadoc package which is located in this JAR.
+# Doxygen test cases need to be compiled together with the CommentParser class.
 CommentParser.class:
 	$(COMPILETOOL) $(JAVAC) -classpath $(JAVA_CLASSPATH) -d . $(srcdir)/CommentParser.java
 
 JAVA_CLASSPATH := .
-$(DOXYGEN_TEST_CASES:=.cpptest): JAVA_CLASSPATH := "$(JAVA_TOOLS_JAR)$(JAVA_CLASSPATH_SEP)."
 $(DOXYGEN_TEST_CASES:=.cpptest): CommentParser.class
 
 # Compiles java files then runs the testcase. A testcase is only run if
@@ -132,6 +137,7 @@
 	@if [ -d $(JAVA_PACKAGE) ]; then \
 	  rm -rf $(JAVA_PACKAGE); \
 	fi
+	@rm -f $*_runme.class
 
 clean:
 	@rm -f *.class hs_err*.log
diff --git a/Examples/test-suite/java/abstract_inherit_using_runme.java b/Examples/test-suite/java/abstract_inherit_using_runme.java
new file mode 100644
index 0000000..e4ec0bc
--- /dev/null
+++ b/Examples/test-suite/java/abstract_inherit_using_runme.java
@@ -0,0 +1,24 @@
+
+import abstract_inherit_using.*;
+
+public class abstract_inherit_using_runme {
+
+  static {
+    try {
+        System.loadLibrary("abstract_inherit_using");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[])
+  {
+    ConcreteDerived1 cd1 = new ConcreteDerived1();
+    cd1.f(1234);
+    cd1.f("one");
+    ConcreteDerived2 cd2 = new ConcreteDerived2();
+    cd2.f(1234);
+    cd2.f("one");
+  }
+}
diff --git a/Examples/test-suite/java/allprotected_runme.java b/Examples/test-suite/java/allprotected_runme.java
index aa5413a..864feb4 100644
--- a/Examples/test-suite/java/allprotected_runme.java
+++ b/Examples/test-suite/java/allprotected_runme.java
@@ -14,6 +14,9 @@
   {
     MyProtectedBase mpb = new MyProtectedBase("MyProtectedBase");
     mpb.accessProtected();
+
+    MyAllProtectedBottom mapb = new MyAllProtectedBottom();
+    mapb.callProtectedMethods();
   }
 }
 
@@ -72,3 +75,13 @@
   }
 }
 
+class MyAllProtectedBottom extends AllProtectedBottom
+{
+  void callProtectedMethods() {
+    usingOverloaded();
+    usingOverloaded(99);
+    usingSingle();
+    doSomething();
+    doSomething(99);
+  }
+}
diff --git a/Examples/test-suite/java/argcargvtest_runme.java b/Examples/test-suite/java/argcargvtest_runme.java
new file mode 100644
index 0000000..376b368
--- /dev/null
+++ b/Examples/test-suite/java/argcargvtest_runme.java
@@ -0,0 +1,56 @@
+import argcargvtest.*;
+
+public class argcargvtest_runme {
+
+  static {
+    try {
+      System.loadLibrary("argcargvtest");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    argcargvtest test = new argcargvtest();
+
+    String[] largs = {"hi", "hola", "hello"};
+    if (test.mainc(largs) != 3)
+        throw new RuntimeException("bad main typemap");
+
+    String[] targs = {"hi", "hola"};
+    if (!test.mainv(targs, 0).equals("hi"))
+        throw new RuntimeException("bad main typemap");
+    if (!test.mainv(targs, 1).equals("hola"))
+        throw new RuntimeException("bad main typemap");
+    if (!test.mainv(targs, 2).equals("<<NULL>>"))
+        throw new RuntimeException("bad main typemap");
+
+// For dynamically typed languages we test this throws an exception or similar
+// at runtime, but for Java this doesn't even compile (but we can't easily
+// test for that here).
+//  test.mainv("hello", 1);
+
+    test.initializeApp(largs);
+
+    // Check that an empty array works.
+    String[] empty_args = {};
+    if (test.mainc(empty_args) != 0)
+      throw new RuntimeException("bad main typemap");
+    if (!test.mainv(empty_args, 0).equals("<<NULL>>"))
+        throw new RuntimeException("bad main typemap");
+
+    // Check that empty strings are handled.
+    String[] empty_string = {"hello", "", "world"};
+    if (test.mainc(empty_string) != 3)
+      throw new RuntimeException("bad main typemap");
+    if (!test.mainv(empty_string, 0).equals("hello"))
+      throw new RuntimeException("bad main typemap");
+    if (!test.mainv(empty_string, 1).equals(""))
+      throw new RuntimeException("bad main typemap");
+    if (!test.mainv(empty_string, 2).equals("world"))
+      throw new RuntimeException("bad main typemap");
+    if (!test.mainv(empty_string, 3).equals("<<NULL>>"))
+      throw new RuntimeException("bad main typemap");
+  }
+}
diff --git a/Examples/test-suite/java/assign_const_runme.java b/Examples/test-suite/java/assign_const_runme.java
new file mode 100644
index 0000000..6035af7
--- /dev/null
+++ b/Examples/test-suite/java/assign_const_runme.java
@@ -0,0 +1,98 @@
+
+import assign_const.*;
+
+public class assign_const_runme {
+
+  static {
+    try {
+	System.loadLibrary("assign_const");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    MemberVars mv = new MemberVars();
+
+    // (1) Test directly non-assignable member variables
+    // These will only have getters
+    AssignValue a1 = mv.getMemberValue();
+    AssignArray a2 = mv.getMemberArray();
+    AssignPtr a3 = mv.getMemberPtr();
+    AssignMatrix a4 = mv.getMemberMatrix();
+
+    // (2) Test indirectly non-assignable member variables via inheritance
+    InheritedMemberVars imv = new InheritedMemberVars();
+    // These will only have getters
+    AssignValueDerived aa4 = imv.getMemberValueDerived();
+    AssignArrayDerived aa5 = imv.getMemberArrayDerived();
+    AssignPtrDerived aa6 = imv.getMemberPtrDerived();
+    AssignMatrixDerived aa7 = imv.getMemberMatrixDerived();
+
+    AssignValueDerived sa4 = InheritedMemberVars.getStaticMemberValueDerived();
+    AssignArrayDerived sa5 = InheritedMemberVars.getStaticMemberArrayDerived();
+    AssignPtrDerived sa6 = InheritedMemberVars.getStaticMemberPtrDerived();
+    AssignMatrixDerived sa7 = InheritedMemberVars.getStaticMemberMatrixDerived();
+
+    AssignValueDerived ga4 = assign_const.getGlobalValueDerived();
+    AssignArrayDerived ga5 = assign_const.getGlobalArrayDerived();
+    AssignPtrDerived ga6 = assign_const.getGlobalPtrDerived();
+    AssignMatrixDerived ga7 = assign_const.getGlobalMatrixDerived();
+
+    // These will have getters and setters
+    AssignValueDerivedSettable a7 = imv.getMemberValueDerivedSettable();
+    imv.setMemberValueDerivedSettable(a7);
+    AssignArrayDerivedSettable a8 = imv.getMemberArrayDerivedSettable();
+    imv.setMemberArrayDerivedSettable(a8);
+    AssignPtrDerivedSettable a9 = imv.getMemberPtrDerivedSettable();
+    imv.setMemberPtrDerivedSettable(a9);
+    AssignMatrixDerivedSettable a10 = imv.getMemberMatrixDerivedSettable();
+    imv.setMemberMatrixDerivedSettable(a10);
+
+    AssignValueDerivedSettable saa7 = InheritedMemberVars.getStaticMemberValueDerivedSettable();
+    InheritedMemberVars.setStaticMemberValueDerivedSettable(saa7);
+    AssignArrayDerivedSettable saa8 = InheritedMemberVars.getStaticMemberArrayDerivedSettable();
+    InheritedMemberVars.setStaticMemberArrayDerivedSettable(saa8);
+    AssignPtrDerivedSettable saa9 = InheritedMemberVars.getStaticMemberPtrDerivedSettable();
+    InheritedMemberVars.setStaticMemberPtrDerivedSettable(saa9);
+    AssignMatrixDerivedSettable saa10 = InheritedMemberVars.getStaticMemberMatrixDerivedSettable();
+    InheritedMemberVars.setStaticMemberMatrixDerivedSettable(saa10);
+
+    AssignValueDerivedSettable gaa7 = assign_const.getGlobalValueDerivedSettable();
+    assign_const.setGlobalValueDerivedSettable(gaa7);
+    AssignArrayDerivedSettable gaa8 = assign_const.getGlobalArrayDerivedSettable();
+    assign_const.setGlobalArrayDerivedSettable(gaa8);
+    AssignPtrDerivedSettable gaa9 = assign_const.getGlobalPtrDerivedSettable();
+    assign_const.setGlobalPtrDerivedSettable(gaa9);
+    AssignMatrixDerivedSettable gaa10 = assign_const.getGlobalMatrixDerivedSettable();
+    assign_const.setGlobalMatrixDerivedSettable(gaa10);
+
+    // (3) Test indirectly non-assignable member variables via classes that themselves have non-assignable member variables
+    MembersMemberVars m = new MembersMemberVars();
+
+    // These will only have getters
+    MemberValueVar mpv1 = m.getMemberValue();
+    MemberArrayVar mpv2 = m.getMemberArray();
+    MemberPtrVar mpv3 = m.getMemberPtr();
+    MemberMatrixVar mpv4 = m.getMemberMatrix();
+
+    MemberValueVar smpv1 = StaticMembersMemberVars.getStaticMemberValue();
+    MemberArrayVar smpv2 = StaticMembersMemberVars.getStaticMemberArray();
+    MemberPtrVar smpv3 = StaticMembersMemberVars.getStaticMemberPtr();
+    MemberMatrixVar smpv4 = StaticMembersMemberVars.getStaticMemberMatrix();
+
+    MemberValueVar gmpv1 = assign_const.getGlobalMemberValue();
+    MemberArrayVar gmpv2 = assign_const.getGlobalMemberArray();
+    MemberPtrVar gmpv3 = assign_const.getGlobalMemberPtr();
+    MemberMatrixVar gmpv4 = assign_const.getGlobalMemberMatrix();
+
+    // Setters and getters available
+    StaticMembersMemberVarsHolder smmvh = new StaticMembersMemberVarsHolder();
+    StaticMembersMemberVars member = smmvh.getMember();
+    smmvh.setMember(member);
+
+    StaticMembersMemberVars smmv = assign_const.getGlobalStaticMembersMemberVars();
+    assign_const.setGlobalStaticMembersMemberVars(smmv);
+  }
+}
diff --git a/Examples/test-suite/java/assign_reference_runme.java b/Examples/test-suite/java/assign_reference_runme.java
new file mode 100644
index 0000000..113250a
--- /dev/null
+++ b/Examples/test-suite/java/assign_reference_runme.java
@@ -0,0 +1,89 @@
+
+import assign_reference.*;
+
+public class assign_reference_runme {
+
+  static {
+    try {
+	System.loadLibrary("assign_reference");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    AssignPublic ap = new AssignPublic();
+    SWIGTYPE_p_int pint = ap.getPublicMember();
+    ap.setPublicMember(assign_reference.getGlobalIntRef());
+
+    MemberVars mv = new MemberVars();
+
+    // (1) Test directly non-assignable member variables
+    // These will only have getters
+    AssignPublic a1 = mv.getMemberPublic();
+    AssignProtected a2 = mv.getMemberProtected();
+    AssignPrivate a3 = mv.getMemberPrivate();
+
+    // (2) Test indirectly non-assignable member variables via inheritance
+    InheritedMemberVars imv = new InheritedMemberVars();
+    // These will only have getters
+    AssignPublicDerived a4 = imv.getMemberPublicDerived();
+    AssignProtectedDerived a5 = imv.getMemberProtectedDerived();
+    AssignPrivateDerived a6 = imv.getMemberPrivateDerived();
+
+    AssignPublicDerived sa4 = InheritedMemberVars.getStaticMemberPublicDerived();
+    AssignProtectedDerived sa5 = InheritedMemberVars.getStaticMemberProtectedDerived();
+    AssignPrivateDerived sa6 = InheritedMemberVars.getStaticMemberPrivateDerived();
+
+    AssignPublicDerived ga4 = assign_reference.getGlobalPublicDerived();
+    AssignProtectedDerived ga5 = assign_reference.getGlobalProtectedDerived();
+    AssignPrivateDerived ga6 = assign_reference.getGlobalPrivateDerived();
+
+    // These will have getters and setters
+    AssignPublicDerivedSettable a7 = imv.getMemberPublicDerivedSettable();
+    imv.setMemberPublicDerivedSettable(a7);
+    AssignProtectedDerivedSettable a8 = imv.getMemberProtectedDerivedSettable();
+    imv.setMemberProtectedDerivedSettable(a8);
+    AssignPrivateDerivedSettable a9 = imv.getMemberPrivateDerivedSettable();
+    imv.setMemberPrivateDerivedSettable(a9);
+
+    AssignPublicDerivedSettable sa7 = InheritedMemberVars.getStaticMemberPublicDerivedSettable();
+    InheritedMemberVars.setStaticMemberPublicDerivedSettable(sa7);
+    AssignProtectedDerivedSettable sa8 = InheritedMemberVars.getStaticMemberProtectedDerivedSettable();
+    InheritedMemberVars.setStaticMemberProtectedDerivedSettable(sa8);
+    AssignPrivateDerivedSettable sa9 = InheritedMemberVars.getStaticMemberPrivateDerivedSettable();
+    InheritedMemberVars.setStaticMemberPrivateDerivedSettable(sa9);
+
+    AssignPublicDerivedSettable ga7 = assign_reference.getGlobalPublicDerivedSettable();
+    assign_reference.setGlobalPublicDerivedSettable(ga7);
+    AssignProtectedDerivedSettable ga8 = assign_reference.getGlobalProtectedDerivedSettable();
+    assign_reference.setGlobalProtectedDerivedSettable(ga8);
+    AssignPrivateDerivedSettable ga9 = assign_reference.getGlobalPrivateDerivedSettable();
+    assign_reference.setGlobalPrivateDerivedSettable(ga9);
+
+    // (3) Test indirectly non-assignable member variables via classes that themselves have non-assignable member variables
+    MembersMemberVars m = new MembersMemberVars();
+
+    // These will only have getters
+    MemberPublicVar mpv1 = m.getMemberPublic();
+    MemberProtectedVar mpv2 = m.getMemberProtected();
+    MemberPrivateVar mpv3 = m.getMemberPrivate();
+
+    MemberPublicVar smpv1 = StaticMembersMemberVars.getStaticMemberPublic();
+    MemberProtectedVar smpv2 = StaticMembersMemberVars.getStaticMemberProtected();
+    MemberPrivateVar smpv3 = StaticMembersMemberVars.getStaticMemberPrivate();
+
+    MemberPublicVar gmpv1 = assign_reference.getGlobalMemberPublic();
+    MemberProtectedVar gmpv2 = assign_reference.getGlobalMemberProtected();
+    MemberPrivateVar gmpv3 = assign_reference.getGlobalMemberPrivate();
+
+    // Setters and getters available
+    StaticMembersMemberVarsHolder smmvh = new StaticMembersMemberVarsHolder();
+    StaticMembersMemberVars member = smmvh.getMember();
+    smmvh.setMember(member);
+
+    StaticMembersMemberVars smmv = assign_reference.getGlobalStaticMembersMemberVars();
+    assign_reference.setGlobalStaticMembersMemberVars(smmv);
+  }
+}
diff --git a/Examples/test-suite/java/catches_strings_runme.java b/Examples/test-suite/java/catches_strings_runme.java
new file mode 100644
index 0000000..75e0cf0
--- /dev/null
+++ b/Examples/test-suite/java/catches_strings_runme.java
@@ -0,0 +1,41 @@
+import catches_strings.*;
+
+public class catches_strings_runme {
+  static {
+    try {
+        System.loadLibrary("catches_strings");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) throws Throwable
+  {
+    {
+      boolean exception_thrown = false;
+      try {
+        StringsThrower.charstring();
+      } catch (RuntimeException e) {
+        if (!e.getMessage().contains("charstring message"))
+          throw new RuntimeException("incorrect exception message");
+        exception_thrown = true;
+      }
+      if (!exception_thrown)
+        throw new RuntimeException("Should have thrown an exception");
+    }
+
+    {
+      boolean exception_thrown = false;
+      try {
+        StringsThrower.stdstring();
+      } catch (RuntimeException e) {
+        if (!e.getMessage().contains("stdstring message"))
+          throw new RuntimeException("incorrect exception message");
+        exception_thrown = true;
+      }
+      if (!exception_thrown)
+        throw new RuntimeException("Should have thrown an exception");
+    }
+  }
+}
diff --git a/Examples/test-suite/java/constructor_copy_non_const_runme.java b/Examples/test-suite/java/constructor_copy_non_const_runme.java
new file mode 100644
index 0000000..8ed86f7
--- /dev/null
+++ b/Examples/test-suite/java/constructor_copy_non_const_runme.java
@@ -0,0 +1,30 @@
+import constructor_copy_non_const.*;
+
+public class constructor_copy_non_const_runme {
+
+  static {
+    try {
+	System.loadLibrary("constructor_copy_non_const");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    {
+      CCBase2 ccb2 = new CCBase2(new CCBase2());
+      CCDerived ccd = new CCDerived(new CCDerived());
+      CCMoreDerived ccmd = new CCMoreDerived(new CCMoreDerived());
+      CCMoreDerived2 ccmd2 = new CCMoreDerived2(new CCMoreDerived2());
+      CCMoreMoreDerived2 ccmmd2 = new CCMoreMoreDerived2(new CCMoreMoreDerived2());
+    }
+    {
+      // no copy ctor CCProtectedBase2
+      CCProtectedDerived ccd = new CCProtectedDerived(new CCProtectedDerived());
+      CCProtectedMoreDerived ccmd = new CCProtectedMoreDerived(new CCProtectedMoreDerived());
+      CCProtectedMoreDerived2 ccmd2 = new CCProtectedMoreDerived2(new CCProtectedMoreDerived2());
+      CCProtectedMoreMoreDerived2 ccmmd2 = new CCProtectedMoreMoreDerived2(new CCProtectedMoreMoreDerived2());
+    }
+  }
+}
diff --git a/Examples/test-suite/java/copyctor_runme.java b/Examples/test-suite/java/copyctor_runme.java
new file mode 100644
index 0000000..e30d0a5
--- /dev/null
+++ b/Examples/test-suite/java/copyctor_runme.java
@@ -0,0 +1,27 @@
+import copyctor.*;
+
+public class copyctor_runme {
+
+  static {
+    try {
+	System.loadLibrary("copyctor");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    Bar bar = new Bar();
+    bar = new Bar(bar);
+
+    Foo foo = new Foo();
+    foo = new Foo(bar);
+
+    Car car = new Car();
+
+    Hoo hoo = new Hoo();
+    hoo = new Hoo(bar);
+    hoo = new Hoo(car);
+  }
+}
diff --git a/Examples/test-suite/java/cpp11_assign_delete_runme.java b/Examples/test-suite/java/cpp11_assign_delete_runme.java
new file mode 100644
index 0000000..c156324
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_assign_delete_runme.java
@@ -0,0 +1,118 @@
+
+import cpp11_assign_delete.*;
+
+public class cpp11_assign_delete_runme {
+
+  static {
+    try {
+	System.loadLibrary("cpp11_assign_delete");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    MemberVars mv = new MemberVars();
+    MemberArrayVars mav = new MemberArrayVars();
+
+    // (1) Test directly non-assignable member variables
+    // These will only have getters
+    AssignPublic a1 = mv.getMemberPublic();
+    AssignProtected a2 = mv.getMemberProtected();
+    AssignPrivate a3 = mv.getMemberPrivate();
+
+    AssignPublic ma1 = mav.getArrayMemberPublic();
+    AssignProtected ma2 = mav.getArrayMemberProtected();
+    AssignPrivate ma3 = mav.getArrayMemberPrivate();
+
+    // (2) Test indirectly non-assignable member variables via inheritance
+    InheritedMemberVars imv = new InheritedMemberVars();
+    // These will only have getters
+    AssignPublicDerived a4 = imv.getMemberPublicDerived();
+    AssignProtectedDerived a5 = imv.getMemberProtectedDerived();
+    AssignPrivateDerived a6 = imv.getMemberPrivateDerived();
+
+    AssignPublicDerived sa4 = InheritedMemberVars.getStaticMemberPublicDerived();
+    AssignProtectedDerived sa5 = InheritedMemberVars.getStaticMemberProtectedDerived();
+    AssignPrivateDerived sa6 = InheritedMemberVars.getStaticMemberPrivateDerived();
+
+    AssignPublicDerived ga4 = cpp11_assign_delete.getGlobalPublicDerived();
+    AssignProtectedDerived ga5 = cpp11_assign_delete.getGlobalProtectedDerived();
+    AssignPrivateDerived ga6 = cpp11_assign_delete.getGlobalPrivateDerived();
+
+    // These will have getters and setters
+    AssignPublicDerivedSettable a7 = imv.getMemberPublicDerivedSettable();
+    imv.setMemberPublicDerivedSettable(a7);
+    AssignProtectedDerivedSettable a8 = imv.getMemberProtectedDerivedSettable();
+    imv.setMemberProtectedDerivedSettable(a8);
+    AssignPrivateDerivedSettable a9 = imv.getMemberPrivateDerivedSettable();
+    imv.setMemberPrivateDerivedSettable(a9);
+
+    AssignPublicDerivedSettable sa7 = InheritedMemberVars.getStaticMemberPublicDerivedSettable();
+    InheritedMemberVars.setStaticMemberPublicDerivedSettable(sa7);
+    AssignProtectedDerivedSettable sa8 = InheritedMemberVars.getStaticMemberProtectedDerivedSettable();
+    InheritedMemberVars.setStaticMemberProtectedDerivedSettable(sa8);
+    AssignPrivateDerivedSettable sa9 = InheritedMemberVars.getStaticMemberPrivateDerivedSettable();
+    InheritedMemberVars.setStaticMemberPrivateDerivedSettable(sa9);
+
+    AssignPublicDerivedSettable ga7 = cpp11_assign_delete.getGlobalPublicDerivedSettable();
+    cpp11_assign_delete.setGlobalPublicDerivedSettable(ga7);
+    AssignProtectedDerivedSettable ga8 = cpp11_assign_delete.getGlobalProtectedDerivedSettable();
+    cpp11_assign_delete.setGlobalProtectedDerivedSettable(ga8);
+    AssignPrivateDerivedSettable ga9 = cpp11_assign_delete.getGlobalPrivateDerivedSettable();
+    cpp11_assign_delete.setGlobalPrivateDerivedSettable(ga9);
+
+    // (3) Test indirectly non-assignable member variables via classes that themselves have non-assignable member variables
+    {
+    MembersMemberVars m = new MembersMemberVars();
+
+    // These will only have getters
+    MemberPublicVar mpv1 = m.getMemberPublic();
+    MemberProtectedVar mpv2 = m.getMemberProtected();
+    MemberPrivateVar mpv3 = m.getMemberPrivate();
+
+    MemberPublicVar smpv1 = StaticMembersMemberVars.getStaticMemberPublic();
+    MemberProtectedVar smpv2 = StaticMembersMemberVars.getStaticMemberProtected();
+    MemberPrivateVar smpv3 = StaticMembersMemberVars.getStaticMemberPrivate();
+
+    MemberPublicVar gmpv1 = cpp11_assign_delete.getGlobalMemberPublic();
+    MemberProtectedVar gmpv2 = cpp11_assign_delete.getGlobalMemberProtected();
+    MemberPrivateVar gmpv3 = cpp11_assign_delete.getGlobalMemberPrivate();
+
+    // Setters and getters available
+    StaticMembersMemberVarsHolder smmvh = new StaticMembersMemberVarsHolder();
+    StaticMembersMemberVars member = smmvh.getMember();
+    smmvh.setMember(member);
+
+    StaticMembersMemberVars smmv = cpp11_assign_delete.getGlobalStaticMembersMemberVars();
+    cpp11_assign_delete.setGlobalStaticMembersMemberVars(smmv);
+    }
+
+    // (4) Test indirectly non-assignable member variables via classes that themselves have non-assignable array member variables
+    {
+    MembersMemberArrayVars m = new MembersMemberArrayVars();
+
+    // These will only have getters
+    MemberPublicArrayVar mpv1 = m.getMemberPublic();
+    MemberProtectedArrayVar mpv2 = m.getMemberProtected();
+    MemberPrivateArrayVar mpv3 = m.getMemberPrivate();
+
+    MemberPublicArrayVar smpv1 = StaticMembersMemberArrayVars.getStaticMemberPublic();
+    MemberProtectedArrayVar smpv2 = StaticMembersMemberArrayVars.getStaticMemberProtected();
+    MemberPrivateArrayVar smpv3 = StaticMembersMemberArrayVars.getStaticMemberPrivate();
+
+    MemberPublicArrayVar gmpv1 = cpp11_assign_delete.getGlobalArrayMemberPublic();
+    MemberProtectedArrayVar gmpv2 = cpp11_assign_delete.getGlobalArrayMemberProtected();
+    MemberPrivateArrayVar gmpv3 = cpp11_assign_delete.getGlobalArrayMemberPrivate();
+
+    // Setters and getters available
+    StaticMembersMemberArrayVarsHolder smmvh = new StaticMembersMemberArrayVarsHolder();
+    StaticMembersMemberArrayVars member = smmvh.getMember();
+    smmvh.setMember(member);
+
+    StaticMembersMemberArrayVars smmv = cpp11_assign_delete.getGlobalStaticMembersMemberArrayVars();
+    cpp11_assign_delete.setGlobalStaticMembersMemberArrayVars(smmv);
+    }
+  }
+}
diff --git a/Examples/test-suite/java/cpp11_assign_rvalue_reference_runme.java b/Examples/test-suite/java/cpp11_assign_rvalue_reference_runme.java
new file mode 100644
index 0000000..87c0622
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_assign_rvalue_reference_runme.java
@@ -0,0 +1,89 @@
+
+import cpp11_assign_rvalue_reference.*;
+
+public class cpp11_assign_rvalue_reference_runme {
+
+  static {
+    try {
+	System.loadLibrary("cpp11_assign_rvalue_reference");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    AssignPublic ap = new AssignPublic();
+    SWIGTYPE_p_int pint = ap.getPublicMember();
+    ap.setPublicMember(cpp11_assign_rvalue_reference.getAnIntRValueRef());
+
+    MemberVars mv = new MemberVars();
+
+    // (1) Test directly non-assignable member variables
+    // These will only have getters
+    AssignPublic a1 = mv.getMemberPublic();
+    AssignProtected a2 = mv.getMemberProtected();
+    AssignPrivate a3 = mv.getMemberPrivate();
+
+    // (2) Test indirectly non-assignable member variables via inheritance
+    InheritedMemberVars imv = new InheritedMemberVars();
+    // These will only have getters
+    AssignPublicDerived a4 = imv.getMemberPublicDerived();
+    AssignProtectedDerived a5 = imv.getMemberProtectedDerived();
+    AssignPrivateDerived a6 = imv.getMemberPrivateDerived();
+
+    AssignPublicDerived sa4 = InheritedMemberVars.getStaticMemberPublicDerived();
+    AssignProtectedDerived sa5 = InheritedMemberVars.getStaticMemberProtectedDerived();
+    AssignPrivateDerived sa6 = InheritedMemberVars.getStaticMemberPrivateDerived();
+
+    AssignPublicDerived ga4 = cpp11_assign_rvalue_reference.getGlobalPublicDerived();
+    AssignProtectedDerived ga5 = cpp11_assign_rvalue_reference.getGlobalProtectedDerived();
+    AssignPrivateDerived ga6 = cpp11_assign_rvalue_reference.getGlobalPrivateDerived();
+
+    // These will have getters and setters
+    AssignPublicDerivedSettable a7 = imv.getMemberPublicDerivedSettable();
+    imv.setMemberPublicDerivedSettable(a7);
+    AssignProtectedDerivedSettable a8 = imv.getMemberProtectedDerivedSettable();
+    imv.setMemberProtectedDerivedSettable(a8);
+    AssignPrivateDerivedSettable a9 = imv.getMemberPrivateDerivedSettable();
+    imv.setMemberPrivateDerivedSettable(a9);
+
+    AssignPublicDerivedSettable sa7 = InheritedMemberVars.getStaticMemberPublicDerivedSettable();
+    InheritedMemberVars.setStaticMemberPublicDerivedSettable(sa7);
+    AssignProtectedDerivedSettable sa8 = InheritedMemberVars.getStaticMemberProtectedDerivedSettable();
+    InheritedMemberVars.setStaticMemberProtectedDerivedSettable(sa8);
+    AssignPrivateDerivedSettable sa9 = InheritedMemberVars.getStaticMemberPrivateDerivedSettable();
+    InheritedMemberVars.setStaticMemberPrivateDerivedSettable(sa9);
+
+    AssignPublicDerivedSettable ga7 = cpp11_assign_rvalue_reference.getGlobalPublicDerivedSettable();
+    cpp11_assign_rvalue_reference.setGlobalPublicDerivedSettable(ga7);
+    AssignProtectedDerivedSettable ga8 = cpp11_assign_rvalue_reference.getGlobalProtectedDerivedSettable();
+    cpp11_assign_rvalue_reference.setGlobalProtectedDerivedSettable(ga8);
+    AssignPrivateDerivedSettable ga9 = cpp11_assign_rvalue_reference.getGlobalPrivateDerivedSettable();
+    cpp11_assign_rvalue_reference.setGlobalPrivateDerivedSettable(ga9);
+
+    // (3) Test indirectly non-assignable member variables via classes that themselves have non-assignable member variables
+    MembersMemberVars m = new MembersMemberVars();
+
+    // These will only have getters
+    MemberPublicVar mpv1 = m.getMemberPublic();
+    MemberProtectedVar mpv2 = m.getMemberProtected();
+    MemberPrivateVar mpv3 = m.getMemberPrivate();
+
+    MemberPublicVar smpv1 = StaticMembersMemberVars.getStaticMemberPublic();
+    MemberProtectedVar smpv2 = StaticMembersMemberVars.getStaticMemberProtected();
+    MemberPrivateVar smpv3 = StaticMembersMemberVars.getStaticMemberPrivate();
+
+    MemberPublicVar gmpv1 = cpp11_assign_rvalue_reference.getGlobalMemberPublic();
+    MemberProtectedVar gmpv2 = cpp11_assign_rvalue_reference.getGlobalMemberProtected();
+    MemberPrivateVar gmpv3 = cpp11_assign_rvalue_reference.getGlobalMemberPrivate();
+
+    // Setters and getters available
+    StaticMembersMemberVarsHolder smmvh = new StaticMembersMemberVarsHolder();
+    StaticMembersMemberVars member = smmvh.getMember();
+    smmvh.setMember(member);
+
+    StaticMembersMemberVars smmv = cpp11_assign_rvalue_reference.getGlobalStaticMembersMemberVars();
+    cpp11_assign_rvalue_reference.setGlobalStaticMembersMemberVars(smmv);
+  }
+}
diff --git a/Examples/test-suite/java/cpp11_brackets_expression_runme.java b/Examples/test-suite/java/cpp11_brackets_expression_runme.java
new file mode 100644
index 0000000..fdd8e00
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_brackets_expression_runme.java
@@ -0,0 +1,24 @@
+import cpp11_brackets_expression.*;
+
+public class cpp11_brackets_expression_runme {
+
+  static {
+    try {
+	System.loadLibrary("cpp11_brackets_expression");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    long x = Piece.kMaxSize;
+    x = Piece.SimpleAsYouExpect123;
+    x = Piece.Just123;
+    x = cpp11_brackets_expression.getKMaxSizeGlobal();
+
+    x = cpp11_brackets_expression.getKMaxSizeGlobal();
+    x = cpp11_brackets_expression.global_as_you_expect(123);
+    x = cpp11_brackets_expression.global_one_two_three();
+  }
+}
diff --git a/Examples/test-suite/java/cpp11_copyctor_delete_runme.java b/Examples/test-suite/java/cpp11_copyctor_delete_runme.java
new file mode 100644
index 0000000..ed9d289
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_copyctor_delete_runme.java
@@ -0,0 +1,29 @@
+import cpp11_copyctor_delete.*;
+
+public class cpp11_copyctor_delete_runme {
+
+  static {
+    try {
+        System.loadLibrary("cpp11_copyctor_delete");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[])
+  {
+    // check copy constructors are generated
+    new CopyCtorDeletedPublic1(CopyCtorDeletedPublic1.make());
+    new CopyCtorDeletedProtected1(CopyCtorDeletedProtected1.make());
+    new CopyCtorDeletedPrivate1(CopyCtorDeletedPrivate1.make());
+
+    new DeletedPublic4();
+    new DeletedPublic5();
+    new CopyCtorDeletedPublic4();
+    new CopyCtorDeletedPublic5();
+
+    new StackOnly1();
+    new CopyCtorStackOnly1(new CopyCtorStackOnly1());
+  }
+}
diff --git a/Examples/test-suite/java/cpp11_default_delete_runme.java b/Examples/test-suite/java/cpp11_default_delete_runme.java
new file mode 100644
index 0000000..73d151a
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_default_delete_runme.java
@@ -0,0 +1,28 @@
+import cpp11_default_delete.*;
+
+public class cpp11_default_delete_runme {
+
+  static {
+    try {
+	System.loadLibrary("cpp11_default_delete");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    sometype st = new sometype(22.2);
+    sometype.take(st);
+    st = sometype.make(33.3);
+
+    sometype2 st2 = new sometype2(22.2);
+    sometype2.take(st2);
+    st2 = sometype2.make(33.3);
+
+    sometype3 st3 = sometype3.make(22);
+    sometype3.take(st3);
+    st3 = sometype3.make(33);
+  }
+}
+
diff --git a/Examples/test-suite/java/cpp11_director_using_constructor_runme.java b/Examples/test-suite/java/cpp11_director_using_constructor_runme.java
new file mode 100644
index 0000000..e1508a9
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_director_using_constructor_runme.java
@@ -0,0 +1,323 @@
+
+import cpp11_director_using_constructor.*;
+
+public class cpp11_director_using_constructor_runme {
+
+  static {
+    try {
+	System.loadLibrary("cpp11_director_using_constructor");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    // This is a copy of cpp11_using_constructor_runme.java for testing that the expected constructors can be called
+
+    // Public base constructors
+    new PublicDerived1(0, "hi").meth();
+    new PublicDerived2().meth();
+    new PublicDerived2(0, "hi").meth();
+    new PublicDerived3().meth();
+    new PublicDerived3(0, "hi").meth();
+    new PublicDerived4().meth();
+    new PublicDerived5().meth();
+
+    // Protected base constructors
+    // Cannot test most of these as the constructors are protected
+    new ProtectedDerived5();
+
+    // Mix of public and overloaded constructors
+    new MixedDerived1a(0, "hi").meth();
+    new MixedDerived1a().meth();
+    new MixedDerived1b(0, "hi").meth();
+    new MixedDerived1b().meth();
+
+    new MixedDerived2a(0, "hi").meth();
+    new MixedDerived2a().meth();
+    new MixedDerived2b(0, "hi").meth();
+    new MixedDerived2b().meth();
+
+    new MixedDerived2c(0, "hi").meth();
+    new MixedDerived2c().meth();
+    new MixedDerived2c(0).meth();
+
+    new MixedDerived2d(0, "hi").meth();
+    new MixedDerived2d().meth();
+    new MixedDerived2d(0).meth();
+
+    new MixedDerived3a(0, "hi").meth();
+    new MixedDerived3a().meth();
+    new MixedDerived3b(0, "hi").meth();
+    new MixedDerived3b().meth();
+
+    new MixedDerived3c(0, "hi").meth();
+    new MixedDerived3c().meth();
+    new MixedDerived3c(0).meth();
+
+    new MixedDerived3d(0, "hi").meth();
+    new MixedDerived3d().meth();
+    new MixedDerived3d(0).meth();
+
+    new MixedDerived4a(0, "hi").meth();
+    new MixedDerived4a().meth();
+    new MixedDerived4b(0, "hi").meth();
+    new MixedDerived4b().meth();
+
+    new MixedDerived4c().meth();
+    new MixedDerived4c(0).meth();
+
+    new MixedDerived4d().meth();
+    new MixedDerived4d(0).meth();
+
+    new MixedDerived4e().meth();
+
+    new MixedDerived4f().meth();
+
+    // Mix of protected base constructors and overloading
+    new ProotDerived1a().meth();
+
+    new ProotDerived1b(0, "hi").meth();
+    new ProotDerived1b().meth();
+
+    new ProotDerived1c(0, "hi").meth();
+    new ProotDerived1c().meth();
+
+    new ProotDerived1d(0).meth();
+    new ProotDerived1d().meth();
+
+    new ProotDerived1e(0).meth();
+    new ProotDerived1e().meth();
+
+    new ProotDerived2a(0, "hi").meth();
+
+    new ProotDerived2b(0, "hi").meth();
+
+    new ProotDerived2c(0, "hi").meth();
+    new ProotDerived2c().meth();
+
+    new ProotDerived2d(0, "hi").meth();
+    new ProotDerived2d().meth();
+
+    new ProotDerived2e(0, "hi").meth();
+    new ProotDerived2e().meth();
+
+    new ProotDerived2f(0, "hi").meth();
+    new ProotDerived2f().meth();
+    new ProotDerived2f(0).meth();
+
+    // Deeper inheritance chain
+    DeepBase3 db3 = new DeepBase3(11);
+    db3 = new DeepBase3(11, 22);
+    db3 = new DeepBase3(11, 22, 33);
+    DeepProtectedBase3 dbp3 = new DeepProtectedBase3(11, 22, 33);
+
+    // Missing base
+    new HiddenDerived1();
+
+    // Templates and public base constructors (derive from non-template)
+    new TemplatePublicDerived1Int(0, "hi").meth();
+    new TemplatePublicDerived2Int().meth();
+    new TemplatePublicDerived2Int(0, "hi").meth();
+    new TemplatePublicDerived3Int().meth();
+    new TemplatePublicDerived3Int(0, "hi").meth();
+    new TemplatePublicDerived4Int().meth();
+    new TemplatePublicDerived5Int().meth();
+
+    // Templates and public base constructors (derive from template)
+    new TemplPublicDerived1Int(0, "hi").meth();
+    new TemplPublicDerived2Int().meth();
+    new TemplPublicDerived2Int(0, "hi").meth();
+    new TemplPublicDerived3Int().meth();
+    new TemplPublicDerived3Int(0, "hi").meth();
+    new TemplPublicDerived4Int().meth();
+    new TemplPublicDerived5Int().meth();
+    new TemplPublicDerived6Int(0, "hi").meth();
+    new TemplPublicDerived6Int().meth();
+
+    // Templated constructors (public)
+    TemplateConstructor1Base tcb = new TemplateConstructor1Base(0, "hi");
+    tcb = new TemplateConstructor1Base("hi", "hi");
+    tcb = new TemplateConstructor1Base(11.1, "hi");
+    tcb.normal_method();
+    tcb.template_method(0, "hi");
+    tcb.template_method("hey", "ho");
+
+    TemplateConstructor1Derived tcd1 = new TemplateConstructor1Derived(0, "hi");
+    tcd1 = new TemplateConstructor1Derived("hi", "hi");
+    tcd1 = new TemplateConstructor1Derived(11.1, "hi");
+    // Not the best test as these are also in the base class, hence use also introspection below
+    tcd1.normal_method();
+    tcd1.template_method(0, "hi");
+    tcd1.template_method("hey", "ho");
+
+    // Templated methods
+    // Introspection to make sure these are actually generated in the derived class
+    try {
+      TemplateConstructor1Derived.class.getDeclaredMethod("normal_method", (java.lang.Class[])null);
+      TemplateConstructor1Derived.class.getDeclaredMethod("template_method", new java.lang.Class[]{String.class, String.class});
+      TemplateConstructor1Derived.class.getDeclaredMethod("template_method", new java.lang.Class[]{int.class, String.class});
+    } catch (NoSuchMethodException e) {
+      throw new RuntimeException(e);
+    }
+
+    // Templated constructors (protected)
+    TemplateConstructor2Derived tcd2 = new TemplateConstructor2Derived();
+    tcd2.normal_method();
+    tcd2.template_method(0, "hi");
+    tcd2.template_method("hey", "ho");
+  }
+
+  //
+  // Additional tests compared to cpp11_using_constructor test
+  //
+  // Protected constructors, check both protected and public constructors can be called from a derived class
+  class cpp11_director_using_constructor_MyProtectedBase1 extends ProtectedBase1 {
+    public cpp11_director_using_constructor_MyProtectedBase1(int i, String s) {
+      super(i, s);
+    }
+  }
+  class cpp11_director_using_constructor_MyProtectedDerived1 extends ProtectedDerived1 {
+    public cpp11_director_using_constructor_MyProtectedDerived1(int i, String s) {
+      super(i, s);
+    }
+  }
+  class cpp11_director_using_constructor_MyProtectedBase2 extends ProtectedBase2 {
+    public cpp11_director_using_constructor_MyProtectedBase2(int i, String s) {
+      super(i, s);
+    }
+    public cpp11_director_using_constructor_MyProtectedBase2() {
+      super();
+    }
+  }
+  class cpp11_director_using_constructor_MyProtectedDerived2 extends ProtectedDerived2 {
+    public cpp11_director_using_constructor_MyProtectedDerived2(int i, String s) {
+      super(i, s);
+    }
+    public cpp11_director_using_constructor_MyProtectedDerived2() {
+      super();
+    }
+  }
+  class cpp11_director_using_constructor_MyProtectedBase3 extends ProtectedBase3 {
+    public cpp11_director_using_constructor_MyProtectedBase3(int i, String s) {
+      super(i, s);
+    }
+    public cpp11_director_using_constructor_MyProtectedBase3() {
+      super();
+    }
+  }
+  class cpp11_director_using_constructor_MyProtectedDerived3 extends ProtectedDerived3 {
+    public cpp11_director_using_constructor_MyProtectedDerived3(int i, String s) {
+      super(i, s);
+    }
+    public cpp11_director_using_constructor_MyProtectedDerived3() {
+      super();
+    }
+  }
+  class cpp11_director_using_constructor_MyProtectedBase4 extends ProtectedBase4 {
+    public cpp11_director_using_constructor_MyProtectedBase4() {
+      super();
+    }
+  }
+  class cpp11_director_using_constructor_MyProtectedDerived4 extends ProtectedDerived4 {
+    public cpp11_director_using_constructor_MyProtectedDerived4() {
+      super();
+    }
+  }
+  class cpp11_director_using_constructor_MyProtectedBase5 extends ProtectedBase5 {
+    public cpp11_director_using_constructor_MyProtectedBase5() {
+      super();
+    }
+  }
+  class cpp11_director_using_constructor_MyProtectedDerived5 extends ProtectedDerived5 {
+    public cpp11_director_using_constructor_MyProtectedDerived5() {
+      super();
+    }
+  }
+
+  // Protected constructors, just check the protected constructors can be called from a derived class
+  class cpp11_director_using_constructor_MyProotBase1 extends ProotBase1 {
+    public cpp11_director_using_constructor_MyProotBase1(int i, String s) {
+      super(i, s);
+    }
+  }
+  class cpp11_director_using_constructor_MyProotDerived1a extends ProotDerived1a {
+    public cpp11_director_using_constructor_MyProotDerived1a(int i, String s) {
+      super(i, s);
+    }
+  }
+  class cpp11_director_using_constructor_MyProotDerived1d extends ProotDerived1d {
+    public cpp11_director_using_constructor_MyProotDerived1d(int i, String s) {
+      super(i, s);
+    }
+  }
+  class cpp11_director_using_constructor_MyProotDerived1e extends ProotDerived1e {
+    public cpp11_director_using_constructor_MyProotDerived1e(int i, String s) {
+      super(i, s);
+    }
+  }
+
+  // Protected constructors, check both protected and public constructors can be called from a derived class
+  class cpp11_director_using_constructor_MyProotBase2 extends ProotBase2 {
+    public cpp11_director_using_constructor_MyProotBase2(int i, String s) {
+      super(i, s);
+    }
+    public cpp11_director_using_constructor_MyProotBase2() {
+      super();
+    }
+  }
+  class cpp11_director_using_constructor_MyProotDerived2a extends ProotDerived2a {
+    public cpp11_director_using_constructor_MyProotDerived2a(int i, String s) {
+      super(i, s);
+    }
+    public cpp11_director_using_constructor_MyProotDerived2a() {
+      super();
+    }
+  }
+  class cpp11_director_using_constructor_MyProotDerived2b extends ProotDerived2b {
+    public cpp11_director_using_constructor_MyProotDerived2b(int i, String s) {
+      super(i, s);
+    }
+    public cpp11_director_using_constructor_MyProotDerived2b() {
+      super();
+    }
+  }
+  class cpp11_director_using_constructor_MyProotDerived2c extends ProotDerived2c {
+    public cpp11_director_using_constructor_MyProotDerived2c(int i, String s) {
+      super(i, s);
+    }
+    public cpp11_director_using_constructor_MyProotDerived2c() {
+      super();
+    }
+  }
+  class cpp11_director_using_constructor_MyProotDerived2d extends ProotDerived2d {
+    public cpp11_director_using_constructor_MyProotDerived2d(int i, String s) {
+      super(i, s);
+    }
+    public cpp11_director_using_constructor_MyProotDerived2d() {
+      super();
+    }
+  }
+  class cpp11_director_using_constructor_MyProotDerived2e extends ProotDerived2e {
+    public cpp11_director_using_constructor_MyProotDerived2e(int i, String s) {
+      super(i, s);
+    }
+    public cpp11_director_using_constructor_MyProotDerived2e() {
+      super();
+    }
+  }
+  class cpp11_director_using_constructor_MyProotDerived2f extends ProotDerived2f {
+    public cpp11_director_using_constructor_MyProotDerived2f(int i, String s) {
+      super(i, s);
+    }
+    public cpp11_director_using_constructor_MyProotDerived2f() {
+      super();
+    }
+    public cpp11_director_using_constructor_MyProotDerived2f(int i) {
+      super(i);
+    }
+  }
+
+
+}
diff --git a/Examples/test-suite/java/cpp11_inheriting_constructors_runme.java b/Examples/test-suite/java/cpp11_inheriting_constructors_runme.java
new file mode 100644
index 0000000..5f00c64
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_inheriting_constructors_runme.java
@@ -0,0 +1,27 @@
+import cpp11_inheriting_constructors.*;
+
+public class cpp11_inheriting_constructors_runme {
+
+  static {
+    try {
+	System.loadLibrary("cpp11_inheriting_constructors");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    // Constructor inheritance via using declaration
+    DerivedClass d = new DerivedClass(10);
+    if (d.retrieveValue() != 10)
+        throw new RuntimeException("retrieveValue() failed");
+
+    // Member initialization at the site of the declaration
+    SomeClass s = new SomeClass();
+    if (s.getValue() != 5)
+        throw new RuntimeException("s.value failed");
+  }
+}
+
+
diff --git a/Examples/test-suite/java/cpp11_move_only_runme.java b/Examples/test-suite/java/cpp11_move_only_runme.java
new file mode 100644
index 0000000..8f0f2ac
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_move_only_runme.java
@@ -0,0 +1,51 @@
+
+import cpp11_move_only.*;
+
+public class cpp11_move_only_runme {
+
+  static {
+    try {
+	System.loadLibrary("cpp11_move_only");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+
+    // Output
+    {
+      Counter.reset_counts();
+      MoveOnly mo = MoveOnly.create();
+      mo.delete();
+      Counter.check_counts(1, 0, 0, 2, 0, 3);
+    }
+
+    {
+      Counter.reset_counts();
+      MovableCopyable mo = MovableCopyable.create();
+      mo.delete();
+      Counter.check_counts(2, 1, 0, 0, 1, 3);
+    }
+
+    // Move semantics not used
+    {
+      Counter.reset_counts();
+      MovableCopyable mo = MovableCopyable.createConst();
+      mo.delete();
+      Counter.check_counts(2, 1, 1, 0, 0, 3);
+    }
+
+    // Input
+    {
+      Counter.reset_counts();
+      MovableCopyable mo = new MovableCopyable(222);
+      Counter.check_counts(1, 0, 0, 0, 0, 0);
+      MovableCopyable.take(mo);
+      Counter.check_counts(2, 0, 1, 1, 0, 2);
+      mo.delete();
+      Counter.check_counts(2, 0, 1, 1, 0, 3);
+    }
+  }
+}
diff --git a/Examples/test-suite/java/cpp11_move_only_valuewrapper_runme.java b/Examples/test-suite/java/cpp11_move_only_valuewrapper_runme.java
new file mode 100644
index 0000000..c857a7b
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_move_only_valuewrapper_runme.java
@@ -0,0 +1,44 @@
+import cpp11_move_only_valuewrapper.*;
+
+public class cpp11_move_only_valuewrapper_runme {
+
+  static {
+    try {
+	System.loadLibrary("cpp11_move_only_valuewrapper");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    Counter.reset_counts();
+    {
+      XXX xxx = cpp11_move_only_valuewrapper.createXXX();
+      xxx.delete();
+    }
+    if (cpp11_move_only_valuewrapper.has_cplusplus11())
+      // Was (1, 2, 0, 0, 0, 3) before SwigValueWrapper::operator=(T &&) was added.
+      // Was (1, 1, 0, 1, 0, 3) before SwigValueWrapper::operator T&&() was added with new "out" typemaps
+      Counter.check_counts(1, 0, 0, 2, 0, 3);
+    Counter.reset_counts();
+    {
+      XXX xxx = cpp11_move_only_valuewrapper.createXXX2();
+      xxx.delete();
+    }
+    if (cpp11_move_only_valuewrapper.has_cplusplus11())
+      Counter.check_counts(1, 0, 0, 2, 0, 3);
+    cpp11_move_only_valuewrapper.test1();
+    cpp11_move_only_valuewrapper.test2();
+    cpp11_move_only_valuewrapper.test3();
+    cpp11_move_only_valuewrapper.test4();
+    cpp11_move_only_valuewrapper.test5();
+    cpp11_move_only_valuewrapper.test6();
+
+    // Tests SwigValueWrapper, std::unique_ptr (SWIG not parsing a type that is move-only)
+    Counter.reset_counts();
+    SWIGTYPE_p_std__unique_ptrT_XXX_t ptr = cpp11_move_only_valuewrapper.makeUniqueXXX();
+    cpp11_move_only_valuewrapper.cleanup(ptr);
+    Counter.check_counts(1, 0, 0, 0, 0, 1);
+  }
+}
diff --git a/Examples/test-suite/java/cpp11_move_typemaps_runme.java b/Examples/test-suite/java/cpp11_move_typemaps_runme.java
new file mode 100644
index 0000000..1b5fd2e
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_move_typemaps_runme.java
@@ -0,0 +1,51 @@
+
+import cpp11_move_typemaps.*;
+
+public class cpp11_move_typemaps_runme {
+
+  static {
+    try {
+	System.loadLibrary("cpp11_move_typemaps");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    {
+      Counter.reset_counts();
+      MoveOnly mo = new MoveOnly(111);
+      Counter.check_counts(1, 0, 0, 0, 0, 0);
+      MoveOnly.take(mo);
+      Counter.check_counts(1, 0, 0, 1, 0, 2);
+      mo.delete();
+    }
+    Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+    {
+      Counter.reset_counts();
+      MovableCopyable mo = new MovableCopyable(111);
+      Counter.check_counts(1, 0, 0, 0, 0, 0);
+      MovableCopyable.take(mo);
+      Counter.check_counts(1, 0, 0, 1, 0, 2);
+      mo.delete();
+    }
+    Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+    {
+      MoveOnly mo = new MoveOnly(222);
+      MoveOnly.take(mo);
+      boolean exception_thrown = false;
+      try {
+        MoveOnly.take(mo);
+      } catch (RuntimeException e) {
+        if (!e.getMessage().contains("Cannot release ownership as memory is not owned"))
+          throw new RuntimeException("incorrect exception message");
+        exception_thrown = true;
+      }
+      if (!exception_thrown)
+        throw new RuntimeException("double usage of take should have been an error");
+    }
+  }
+}
diff --git a/Examples/test-suite/java/cpp11_rvalue_reference_move_runme.java b/Examples/test-suite/java/cpp11_rvalue_reference_move_runme.java
new file mode 100644
index 0000000..70ba243
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_rvalue_reference_move_runme.java
@@ -0,0 +1,97 @@
+
+import cpp11_rvalue_reference_move.*;
+
+public class cpp11_rvalue_reference_move_runme {
+
+  static {
+    try {
+	System.loadLibrary("cpp11_rvalue_reference_move");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+
+    {
+      // Function containing rvalue reference parameter
+      Counter.reset_counts();
+      MovableCopyable mo = new MovableCopyable(222);
+      Counter.check_counts(1, 0, 0, 0, 0, 0);
+      MovableCopyable.movein(mo);
+      Counter.check_counts(1, 0, 0, 1, 0, 2);
+      if (!MovableCopyable.is_nullptr(mo))
+        throw new RuntimeException("is_nullptr failed");
+      mo.delete();
+      Counter.check_counts(1, 0, 0, 1, 0, 2);
+    }
+
+    {
+      // Move constructor test
+      Counter.reset_counts();
+      MovableCopyable mo = new MovableCopyable(222);
+      Counter.check_counts(1, 0, 0, 0, 0, 0);
+      MovableCopyable mo_moved = new MovableCopyable(mo);
+      Counter.check_counts(1, 0, 0, 1, 0, 1);
+      if (!MovableCopyable.is_nullptr(mo))
+        throw new RuntimeException("is_nullptr failed");
+      mo.delete();
+      Counter.check_counts(1, 0, 0, 1, 0, 1);
+      mo_moved.delete();
+      Counter.check_counts(1, 0, 0, 1, 0, 2);
+    }
+
+    {
+      // Move assignment operator test
+      Counter.reset_counts();
+      MovableCopyable mo111 = new MovableCopyable(111);
+      MovableCopyable mo222 = new MovableCopyable(222);
+      Counter.check_counts(2, 0, 0, 0, 0, 0);
+      mo111.MoveAssign(mo222);
+      Counter.check_counts(2, 0, 0, 0, 1, 1);
+      if (!MovableCopyable.is_nullptr(mo222))
+        throw new RuntimeException("is_nullptr failed");
+      mo222.delete();
+      Counter.check_counts(2, 0, 0, 0, 1, 1);
+      mo111.delete();
+      Counter.check_counts(2, 0, 0, 0, 1, 2);
+    }
+
+    {
+      // null check
+      Counter.reset_counts();
+      boolean exception_thrown = false;
+      try {
+        MovableCopyable.movein(null);
+      } catch (NullPointerException e) {
+        if (!e.getMessage().contains("MovableCopyable && is null"))
+          throw new RuntimeException("incorrect exception message");
+        exception_thrown = true;
+      }
+      if (!exception_thrown)
+        throw new RuntimeException("Should have thrown null error");
+      Counter.check_counts(0, 0, 0, 0, 0, 0);
+    }
+
+    {
+      // output
+      Counter.reset_counts();
+      MovableCopyable mc = MovableCopyable.moveout(1234);
+      Counter.check_counts(2, 0, 0, 0, 1, 1);
+      MovableCopyable.check_numbers_match(mc, 1234);
+
+      boolean exception_thrown = false;
+      try {
+        MovableCopyable.movein(mc);
+      } catch (RuntimeException e) {
+        if (!e.getMessage().contains("Cannot release ownership as memory is not owned"))
+          throw new RuntimeException("incorrect exception message");
+        exception_thrown = true;
+      }
+      if (!exception_thrown)
+        throw new RuntimeException("Should have thrown 'Cannot release ownership as memory is not owned' error");
+      Counter.check_counts(2, 0, 0, 0, 1, 1);
+    }
+  }
+}
diff --git a/Examples/test-suite/java/cpp11_shared_ptr_template_upcast_runme.java b/Examples/test-suite/java/cpp11_shared_ptr_template_upcast_runme.java
new file mode 100644
index 0000000..2826f58
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_shared_ptr_template_upcast_runme.java
@@ -0,0 +1,24 @@
+// This is the cpp11_shared_ptr_template_upcast runtime testcase. It checks that SWIG generates the appropriate upcasted shared_ptr type for a template instantiation deriving from a base class.
+// For this case, the expected behavior is: given a cptr with underlying type shared_ptr<Printable<Derived> >, PrintableDerived_SWIGSmartPtrUpcast returns a cptr with 
+// underlying type std::shared_ptr< Derived >, where Printable<Derived> inherits from Derived.
+
+import cpp11_shared_ptr_template_upcast.*;
+
+public class cpp11_shared_ptr_template_upcast_runme {
+
+  static {
+    try {
+	System.loadLibrary("cpp11_shared_ptr_template_upcast");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    PrintableDerived pd = cpp11_shared_ptr_template_upcast.MakePrintableDerived(20);
+    pd.GetResult();
+    pd.GetFormatted();
+  }
+}
+
diff --git a/Examples/test-suite/java/cpp11_std_unique_ptr_runme.java b/Examples/test-suite/java/cpp11_std_unique_ptr_runme.java
new file mode 100644
index 0000000..f90ef70
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_std_unique_ptr_runme.java
@@ -0,0 +1,146 @@
+import cpp11_std_unique_ptr.*;
+
+public class cpp11_std_unique_ptr_runme {
+  static {
+    try {
+        System.loadLibrary("cpp11_std_unique_ptr");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  private static void WaitForGC()
+  {
+    System.gc();
+    System.runFinalization();
+    try {
+      java.lang.Thread.sleep(10);
+    } catch (java.lang.InterruptedException e) {
+    }
+  }
+
+  private static void checkCount(int expected_count) {
+    int actual_count = Klass.getTotal_count();
+    if (actual_count != expected_count)
+      throw new RuntimeException("Counts incorrect, expected:" + expected_count + " actual:" + actual_count);
+  }
+
+  public static void main(String argv[]) throws Throwable
+  {
+    // Test raw pointer handling involving virtual inheritance
+    {
+      KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+      checkCount(1);
+      String s = cpp11_std_unique_ptr.useKlassRawPtr(kini);
+      if (!s.equals("KlassInheritanceInput"))
+        throw new RuntimeException("Incorrect string: " + s);
+      kini.delete();
+      checkCount(0);
+    }
+
+    // unique_ptr as input
+    {
+      Klass kin = new Klass("KlassInput");
+      checkCount(1);
+      String s = cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+      checkCount(0);
+      if (!s.equals("KlassInput"))
+        throw new RuntimeException("Incorrect string: " + s);
+      if (!cpp11_std_unique_ptr.is_nullptr(kin))
+        throw new RuntimeException("is_nullptr failed");
+      kin.delete(); // Should not fail, even though already deleted
+      checkCount(0);
+    }
+
+    {
+      Klass kin = new Klass("KlassInput");
+      checkCount(1);
+      String s = cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+      checkCount(0);
+      if (!s.equals("KlassInput"))
+        throw new RuntimeException("Incorrect string: " + s);
+      if (!cpp11_std_unique_ptr.is_nullptr(kin))
+        throw new RuntimeException("is_nullptr failed");
+      boolean exception_thrown = false;
+      try {
+        cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+      } catch (RuntimeException e) {
+        if (!e.getMessage().contains("Cannot release ownership as memory is not owned"))
+          throw new RuntimeException("incorrect exception message");
+        exception_thrown = true;
+      }
+      if (!exception_thrown)
+          throw new RuntimeException("double usage of takeKlassUniquePtr should have been an error");
+      kin.delete(); // Should not fail, even though already deleted
+      checkCount(0);
+    }
+
+    {
+      Klass kin = new Klass("KlassInput");
+      boolean exception_thrown = false;
+      Klass notowned = cpp11_std_unique_ptr.get_not_owned_ptr(kin);
+      try {
+        cpp11_std_unique_ptr.takeKlassUniquePtr(notowned);
+      } catch (RuntimeException e) {
+        if (!e.getMessage().contains("Cannot release ownership as memory is not owned"))
+          throw new RuntimeException("incorrect exception message");
+        exception_thrown = true;
+      }
+      if (!exception_thrown)
+        throw new RuntimeException("Should have thrown 'Cannot release ownership as memory is not owned' error");
+      checkCount(1);
+      kin.delete();
+      checkCount(0);
+    }
+
+    {
+      KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+      checkCount(1);
+      String s = cpp11_std_unique_ptr.takeKlassUniquePtr(kini);
+      checkCount(0);
+      if (!s.equals("KlassInheritanceInput"))
+        throw new RuntimeException("Incorrect string: " + s);
+      if (!cpp11_std_unique_ptr.is_nullptr(kini))
+        throw new RuntimeException("is_nullptr failed");
+      kini.delete(); // Should not fail, even though already deleted
+      checkCount(0);
+    }
+
+    cpp11_std_unique_ptr.takeKlassUniquePtr(null);
+    cpp11_std_unique_ptr.takeKlassUniquePtr(cpp11_std_unique_ptr.make_null());
+    checkCount(0);
+
+    // overloaded parameters
+    if (cpp11_std_unique_ptr.overloadTest() != 0)
+      throw new RuntimeException("overloadTest failed");
+    if (cpp11_std_unique_ptr.overloadTest(null) != 1)
+      throw new RuntimeException("overloadTest failed");
+    if (cpp11_std_unique_ptr.overloadTest(new Klass("over")) != 1)
+      throw new RuntimeException("overloadTest failed");
+    checkCount(0);
+
+
+    // unique_ptr as output
+    Klass k1 = cpp11_std_unique_ptr.makeKlassUniquePtr("first");
+    if (!k1.getLabel().equals("first"))
+      throw new RuntimeException("wrong object label");
+
+    Klass k2 = cpp11_std_unique_ptr.makeKlassUniquePtr("second");
+    checkCount(2);
+
+    k1.delete();
+    k1 = null;
+    checkCount(1);
+
+    if (!k2.getLabel().equals("second"))
+      throw new RuntimeException("wrong object label");
+
+    k2.delete();
+    k2 = null;
+    checkCount(0);
+
+    if (cpp11_std_unique_ptr.makeNullUniquePtr() != null)
+      throw new RuntimeException("null failure");
+  }
+}
diff --git a/Examples/test-suite/java/cpp11_template_parameters_decltype_runme.java b/Examples/test-suite/java/cpp11_template_parameters_decltype_runme.java
new file mode 100644
index 0000000..dd5fc2d
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_template_parameters_decltype_runme.java
@@ -0,0 +1,45 @@
+import cpp11_template_parameters_decltype.*;
+
+public class cpp11_template_parameters_decltype_runme {
+
+  static {
+    try {
+	System.loadLibrary("cpp11_template_parameters_decltype");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    boolean show = false; // for debugging
+
+    cpp11_template_parameters_decltype.tester(show);
+    Json json0 = new Json("hi");
+    if (json0.getCtor() != 0)
+      throw new RuntimeException("json0 failed");
+    if (json0.mmm("bye") != 100)
+      throw new RuntimeException("json0.mmm failed");
+
+    Converter converter = new Converter();
+    Json json1 = new Json(converter);
+    if (json1.getCtor() != 1)
+      throw new RuntimeException("json1 failed");
+    if (json1.mmm(converter) != 101)
+      throw new RuntimeException("json1.mmm failed");
+
+    MapStringString myMapStringString = new MapStringString();
+    Json json2 = new Json(myMapStringString);
+    if (json2.getCtor() != 2)
+      throw new RuntimeException("json2 failed");
+    if (json2.mmm(myMapStringString) != 102)
+      throw new RuntimeException("json2.mmm failed");
+
+    VectorString myVectorString = new VectorString();
+    Json json3 = new Json(myVectorString);
+    if (json3.getCtor() != 3)
+      throw new RuntimeException("json3 failed");
+    if (json3.mmm(myVectorString) != 103)
+      throw new RuntimeException("json3.mmm failed");
+  }
+}
diff --git a/Examples/test-suite/java/cpp11_template_templated_methods_runme.java b/Examples/test-suite/java/cpp11_template_templated_methods_runme.java
new file mode 100644
index 0000000..dd087a0
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_template_templated_methods_runme.java
@@ -0,0 +1,81 @@
+
+import cpp11_template_templated_methods.*;
+
+public class cpp11_template_templated_methods_runme {
+
+  static {
+    try {
+	System.loadLibrary("cpp11_template_templated_methods");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    // assign test
+    {
+      OctetVector ov = new OctetVector();
+      octet o = new octet(111);
+      ov.add(o);
+      SimpleContainer sc = new SimpleContainer(ov);
+      OctetResourceLimitedVector orlv = new OctetResourceLimitedVector();
+      orlv.assign(sc.begin(), sc.end());
+      OctetVector collection = orlv.getCollection();
+      if (collection.size() != 1)
+        throw new RuntimeException("wrong size");
+      octet oo = collection.get(0);
+      if (oo.getNum() != 111)
+        throw new RuntimeException("wrong val");
+    }
+    // assign_and_append test
+    {
+      OctetVector ov = new OctetVector();
+      octet o = new octet(222);
+      ov.add(o);
+      SimpleContainer sc = new SimpleContainer(ov);
+      OctetResourceLimitedVector orlv = new OctetResourceLimitedVector();
+      octet final_octet = new octet(333);
+      orlv.assign_and_append(sc.begin(), sc.end(), final_octet);
+      OctetVector collection = orlv.getCollection();
+      if (collection.size() != 2)
+        throw new RuntimeException("wrong size");
+      octet oo = collection.get(0);
+      if (oo.getNum() != 222)
+        throw new RuntimeException("wrong val");
+      oo = collection.get(1);
+      if (oo.getNum() != 333)
+        throw new RuntimeException("wrong finalval");
+    }
+    // emplace_back test
+    {
+      OctetVector ov = new OctetVector();
+      octet o = new octet(222);
+      ov.add(o);
+      SimpleContainer sc = new SimpleContainer(ov);
+      OctetResourceLimitedVector orlv = new OctetResourceLimitedVector();
+      octet final_octet = new octet(444);
+      orlv.emplace_back(final_octet);
+      orlv.emplace_back();
+      orlv.emplace_back(555);
+      OctetVector collection = orlv.getCollection();
+      if (collection.size() != 3)
+        throw new RuntimeException("wrong size");
+      octet oo = collection.get(0);
+      if (oo.getNum() != 444)
+        throw new RuntimeException("wrong value 0");
+      oo = collection.get(1);
+      if (oo.getNum() != 0)
+        throw new RuntimeException("wrong value 1");
+      oo = collection.get(2);
+      if (oo.getNum() != 555)
+        throw new RuntimeException("wrong value 2");
+    }
+    // Variadic templated constructor in template
+    {
+      OctetResourceLimitedVector orlv = new OctetResourceLimitedVector(999);
+      octet o = new octet(888);
+      OctetResourceLimitedVector orlv2 = new OctetResourceLimitedVector(o);
+    }
+  }
+}
diff --git a/Examples/test-suite/java/cpp11_using_constructor_runme.java b/Examples/test-suite/java/cpp11_using_constructor_runme.java
new file mode 100644
index 0000000..fca19f1
--- /dev/null
+++ b/Examples/test-suite/java/cpp11_using_constructor_runme.java
@@ -0,0 +1,170 @@
+
+import cpp11_using_constructor.*;
+import java.lang.reflect.*;
+
+public class cpp11_using_constructor_runme {
+
+  static {
+    try {
+	System.loadLibrary("cpp11_using_constructor");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    // Public base constructors
+    new PublicDerived1(0, "hi").meth();
+    new PublicDerived2().meth();
+    new PublicDerived2(0, "hi").meth();
+    new PublicDerived3().meth();
+    new PublicDerived3(0, "hi").meth();
+    new PublicDerived4().meth();
+    new PublicDerived5().meth();
+
+    // Protected base constructors
+    // Cannot test most of these as the constructors are protected
+    new ProtectedDerived5();
+
+    // Mix of public and overloaded constructors
+    new MixedDerived1a(0, "hi").meth();
+    new MixedDerived1a().meth();
+    new MixedDerived1b(0, "hi").meth();
+    new MixedDerived1b().meth();
+
+    new MixedDerived2a(0, "hi").meth();
+    new MixedDerived2a().meth();
+    new MixedDerived2b(0, "hi").meth();
+    new MixedDerived2b().meth();
+
+    new MixedDerived2c(0, "hi").meth();
+    new MixedDerived2c().meth();
+    new MixedDerived2c(0).meth();
+
+    new MixedDerived2d(0, "hi").meth();
+    new MixedDerived2d().meth();
+    new MixedDerived2d(0).meth();
+
+    new MixedDerived3a(0, "hi").meth();
+    new MixedDerived3a().meth();
+    new MixedDerived3b(0, "hi").meth();
+    new MixedDerived3b().meth();
+
+    new MixedDerived3c(0, "hi").meth();
+    new MixedDerived3c().meth();
+    new MixedDerived3c(0).meth();
+
+    new MixedDerived3d(0, "hi").meth();
+    new MixedDerived3d().meth();
+    new MixedDerived3d(0).meth();
+
+    new MixedDerived4a(0, "hi").meth();
+    new MixedDerived4a().meth();
+    new MixedDerived4b(0, "hi").meth();
+    new MixedDerived4b().meth();
+
+    new MixedDerived4c().meth();
+    new MixedDerived4c(0).meth();
+
+    new MixedDerived4d().meth();
+    new MixedDerived4d(0).meth();
+
+    new MixedDerived4e().meth();
+
+    new MixedDerived4f().meth();
+
+    // Mix of protected base constructors and overloading
+    new ProotDerived1a().meth();
+
+    new ProotDerived1b(0, "hi").meth();
+    new ProotDerived1b().meth();
+
+    new ProotDerived1c(0, "hi").meth();
+    new ProotDerived1c().meth();
+
+    new ProotDerived1d(0).meth();
+    new ProotDerived1d().meth();
+
+    new ProotDerived1e(0).meth();
+    new ProotDerived1e().meth();
+
+    new ProotDerived2a(0, "hi").meth();
+
+    new ProotDerived2b(0, "hi").meth();
+
+    new ProotDerived2c(0, "hi").meth();
+    new ProotDerived2c().meth();
+
+    new ProotDerived2d(0, "hi").meth();
+    new ProotDerived2d().meth();
+
+    new ProotDerived2e(0, "hi").meth();
+    new ProotDerived2e().meth();
+
+    new ProotDerived2f(0, "hi").meth();
+    new ProotDerived2f().meth();
+    new ProotDerived2f(0).meth();
+
+    // Deeper inheritance chain
+    DeepBase3 db3 = new DeepBase3(11);
+    db3 = new DeepBase3(11, 22);
+    db3 = new DeepBase3(11, 22, 33);
+    DeepProtectedBase3 dbp3 = new DeepProtectedBase3(11, 22, 33);
+
+    // Missing base
+    new HiddenDerived1();
+
+    // Templates and public base constructors (derive from non-template)
+    new TemplatePublicDerived1Int(0, "hi").meth();
+    new TemplatePublicDerived2Int().meth();
+    new TemplatePublicDerived2Int(0, "hi").meth();
+    new TemplatePublicDerived3Int().meth();
+    new TemplatePublicDerived3Int(0, "hi").meth();
+    new TemplatePublicDerived4Int().meth();
+    new TemplatePublicDerived5Int().meth();
+
+    // Templates and public base constructors (derive from template)
+    new TemplPublicDerived1Int(0, "hi").meth();
+    new TemplPublicDerived2Int().meth();
+    new TemplPublicDerived2Int(0, "hi").meth();
+    new TemplPublicDerived3Int().meth();
+    new TemplPublicDerived3Int(0, "hi").meth();
+    new TemplPublicDerived4Int().meth();
+    new TemplPublicDerived5Int().meth();
+    new TemplPublicDerived6Int(0, "hi").meth();
+    new TemplPublicDerived6Int().meth();
+
+    // Templated constructors (public)
+    TemplateConstructor1Base tcb = new TemplateConstructor1Base(0, "hi");
+    tcb = new TemplateConstructor1Base("hi", "hi");
+    tcb = new TemplateConstructor1Base(11.1, "hi");
+    tcb.normal_method();
+    tcb.template_method(0, "hi");
+    tcb.template_method("hey", "ho");
+
+    TemplateConstructor1Derived tcd1 = new TemplateConstructor1Derived(0, "hi");
+    tcd1 = new TemplateConstructor1Derived("hi", "hi");
+    tcd1 = new TemplateConstructor1Derived(11.1, "hi");
+    // Not the best test as these are also in the base class, hence use also introspection below
+    tcd1.normal_method();
+    tcd1.template_method(0, "hi");
+    tcd1.template_method("hey", "ho");
+
+    // Templated methods
+    // Introspection to make sure these are actually generated in the derived class
+    try {
+      TemplateConstructor1Derived.class.getDeclaredMethod("normal_method", (java.lang.Class[])null);
+      TemplateConstructor1Derived.class.getDeclaredMethod("template_method", new java.lang.Class[]{String.class, String.class});
+      TemplateConstructor1Derived.class.getDeclaredMethod("template_method", new java.lang.Class[]{int.class, String.class});
+    } catch (NoSuchMethodException e) {
+      throw new RuntimeException(e);
+    }
+
+    // Templated constructors (protected)
+    TemplateConstructor2Derived tcd2 = new TemplateConstructor2Derived();
+    tcd2.normal_method();
+    tcd2.template_method(0, "hi");
+    tcd2.template_method("hey", "ho");
+  }
+}
diff --git a/Examples/test-suite/java/cpp17_director_string_view_runme.java b/Examples/test-suite/java/cpp17_director_string_view_runme.java
new file mode 100644
index 0000000..9ca4112
--- /dev/null
+++ b/Examples/test-suite/java/cpp17_director_string_view_runme.java
@@ -0,0 +1,58 @@
+
+import cpp17_director_string_view.*;
+
+public class cpp17_director_string_view_runme {
+
+  static {
+    try {
+      System.loadLibrary("cpp17_director_string_view");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+
+    String s;
+
+    cpp17_director_string_view_A c = new cpp17_director_string_view_A("hi");
+    for (int i=0; i<3; i++) {
+      s = c.call_get(i);
+      if (!s.equals(Integer.valueOf(i).toString())) throw new RuntimeException("cpp17_director_string_view_A.get(" + i + ") failed. Got:" + s);
+    }
+
+    cpp17_director_string_view_B b = new cpp17_director_string_view_B("hello");
+
+    s = b.get_first();
+    if (!s.equals("cpp17_director_string_view_B.get_first")) throw new RuntimeException("get_first() failed");
+
+    s = b.call_get_first();
+    if (!s.equals("cpp17_director_string_view_B.get_first")) throw new RuntimeException("call_get_first() failed");
+
+    s = b.call_get(0);
+    if (!s.equals("cpp17_director_string_view_B.get: hello")) throw new RuntimeException("get(0) failed");
+  }
+}
+
+class cpp17_director_string_view_B extends A {
+    public cpp17_director_string_view_B(String first) {
+      super(first);
+    }
+    public String get_first() {
+      return "cpp17_director_string_view_B.get_first";
+    }
+
+    public String get(int n) {
+      return "cpp17_director_string_view_B.get: " + super.get(n);
+    }
+}
+
+class cpp17_director_string_view_A extends A {
+    public cpp17_director_string_view_A(String first) {
+      super(first);
+    }
+    public String get(int n) {
+      return Integer.valueOf(n).toString();
+    }
+}
diff --git a/Examples/test-suite/java/cpp17_enable_if_t_runme.java b/Examples/test-suite/java/cpp17_enable_if_t_runme.java
new file mode 100644
index 0000000..25569f3
--- /dev/null
+++ b/Examples/test-suite/java/cpp17_enable_if_t_runme.java
@@ -0,0 +1,19 @@
+import cpp17_enable_if_t.*;
+
+public class cpp17_enable_if_t_runme {
+
+  static {
+    try {
+        System.loadLibrary("cpp17_enable_if_t");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[])
+  {
+    if (cpp17_enable_if_t.enableif5(10, 20) != 30)
+      throw new RuntimeException("enableif5 not working");
+  }
+}
diff --git a/Examples/test-suite/java/cpp17_string_view_runme.java b/Examples/test-suite/java/cpp17_string_view_runme.java
new file mode 100644
index 0000000..6636a52
--- /dev/null
+++ b/Examples/test-suite/java/cpp17_string_view_runme.java
@@ -0,0 +1,105 @@
+import cpp17_string_view.*;
+
+public class cpp17_string_view_runme {
+
+  static {
+    try {
+        System.loadLibrary("cpp17_string_view");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) throws Throwable
+  {
+      // Checking expected use of %typemap(in) std::string_view {}
+      cpp17_string_view.test_value("Fee");
+
+      // Checking expected result of %typemap(out) std::string_view {}
+      if (!cpp17_string_view.test_value("Fi").equals("Fi"))
+          throw new RuntimeException("Test 1 failed");
+
+      // Verify type-checking for %typemap(in) std::string_view {}
+      try {
+          cpp17_string_view.test_value(null);
+          throw new RuntimeException("Test 2 failed");
+      } catch (NullPointerException e) {
+      }
+
+      // Checking expected use of %typemap(in) const std::string_view & {}
+      cpp17_string_view.test_const_reference("Fo");
+
+      // Checking expected result of %typemap(out) const std::string_view& {}
+      if (!cpp17_string_view.test_const_reference("Fum").equals("Fum"))
+          throw new RuntimeException("Test 3 failed");
+
+      // Verify type-checking for %typemap(in) const std::string_view & {}
+      try {
+          cpp17_string_view.test_const_reference(null);
+          throw new RuntimeException("Test 4 failed");
+      } catch (NullPointerException e) {
+      }
+
+      //
+      // Input and output typemaps for pointers and non-const references to
+      // std::string_view are *not* supported; the following tests confirm
+      // that none of these cases are slipping through.
+      //
+
+      SWIGTYPE_p_std__string_view stringPtr = null;
+
+      stringPtr = cpp17_string_view.test_pointer_out();
+
+      cpp17_string_view.test_pointer(stringPtr);
+
+      stringPtr = cpp17_string_view.test_const_pointer_out();
+
+      cpp17_string_view.test_const_pointer(stringPtr);
+
+      stringPtr = cpp17_string_view.test_reference_out();
+
+      cpp17_string_view.test_reference(stringPtr);
+
+      // Check throw exception specification
+      try {
+          cpp17_string_view.test_throw();
+          throw new Throwable("Test 5 failed");
+      } catch (RuntimeException e) {
+        if (!e.getMessage().equals("test_throw message"))
+          throw new Exception("Test 5 string check: " + e.getMessage());
+      }
+      try {
+          cpp17_string_view.test_const_reference_throw();
+          throw new Throwable("Test 6 failed");
+      } catch (RuntimeException e) {
+        if (!e.getMessage().equals("test_const_reference_throw message"))
+          throw new Exception("Test 6 string check: " + e.getMessage());
+      }
+
+      // Global variables
+      if (!cpp17_string_view.getConstGlobalString().equals("const global string"))
+        throw new Exception("ConstGlobalString test");
+
+      // Member variables
+      Structure myStructure = new Structure();
+      if (!myStructure.getConstMemberString().equals("const member string"))
+        throw new Exception("ConstMemberString test");
+
+      if (!Structure.getConstStaticMemberString().equals("const static member string"))
+        throw new Exception("ConstStaticMemberString test");
+
+      if (!cpp17_string_view.stdstringview_empty().equals(""))
+        throw new Exception("stdstringview_empty test");
+      if (!cpp17_string_view.c_empty().equals(""))
+        throw new Exception("c_empty test");
+      if (cpp17_string_view.c_null() != null)
+        throw new Exception("c_null test");
+      if (cpp17_string_view.get_null(cpp17_string_view.c_null()) != null)
+        throw new Exception("get_null c_null test");
+      if (!cpp17_string_view.get_null(cpp17_string_view.c_empty()).equals("non-null"))
+        throw new Exception("get_null c_empty test");
+      if (!cpp17_string_view.get_null(cpp17_string_view.stdstringview_empty()).equals("non-null"))
+        throw new Exception("get_null stdstringview_empty test");
+  }
+}
diff --git a/Examples/test-suite/java/director_classes_runme.java b/Examples/test-suite/java/director_classes_runme.java
index 5992b5d..292cded 100644
--- a/Examples/test-suite/java/director_classes_runme.java
+++ b/Examples/test-suite/java/director_classes_runme.java
@@ -21,8 +21,8 @@
 Base - FullyOverloaded(bool 1)
 Base - SemiOverloaded(int -678)
 Base - SemiOverloaded(bool 1)
-Base - DefaultParms(10, 2.2)
-Base - DefaultParms(10, 1.1)
+Base - DefaultParms(10, 2.25)
+Base - DefaultParms(10, 1.125)
 --------------------------------
 Derived - Val(444.555)
 Derived - Ref(444.555)
@@ -32,8 +32,8 @@
 Derived - FullyOverloaded(bool 1)
 Derived - SemiOverloaded(int -678)
 Base - SemiOverloaded(bool 1)
-Derived - DefaultParms(10, 2.2)
-Derived - DefaultParms(10, 1.1)
+Derived - DefaultParms(10, 2.25)
+Derived - DefaultParms(10, 1.125)
 --------------------------------
 JavaDerived - Val(444.555)
 JavaDerived - Ref(444.555)
@@ -43,8 +43,8 @@
 JavaDerived - FullyOverloaded(bool True)
 JavaDerived - SemiOverloaded(-678)
 Base - SemiOverloaded(bool 1)
-JavaDerived - DefaultParms(10, 2.2)
-JavaDerived - DefaultParms(10, 1.1)
+JavaDerived - DefaultParms(10, 2.25)
+JavaDerived - DefaultParms(10, 1.125)
 ------------ Finish ------------
 */
 
@@ -128,7 +128,7 @@
     if (!myCaller.SemiOverloadedCall(true).equals("Base" + "::SemiOverloaded(bool)")) throw new RuntimeException("failed");
 
     // Default parameters methods test
-    if (!(myCaller.DefaultParmsCall(10, 2.2)).equals(baseSimpleName + "::DefaultParms(int, double)")) throw new RuntimeException("failed");
+    if (!(myCaller.DefaultParmsCall(10, 2.25)).equals(baseSimpleName + "::DefaultParms(int, double)")) throw new RuntimeException("failed");
     if (myBase instanceof JavaDerived) { // special handling for Java derived classes, there is no way to do this any other way
       if (!myCaller.DefaultParmsCall(10).equals(baseSimpleName + "::DefaultParms(int, double)")) throw new RuntimeException("failed");
     } else {
@@ -205,12 +205,12 @@
   // Note the following method can never be called from unmanaged code.
   // It is here only for code that calls it directly from managed code.
   // But should always be defined to ensure behaviour is consistent
-  // independent of where DefaultParsms is called from (managed or unmanaged code).
+  // independent of where DefaultParams is called from (managed or unmanaged code).
   // Note this method can never be called from unmanaged code
   public String DefaultParms(int x)
   {
     if (director_classes.getPrintDebug()) System.out.println("JavaDerived - DefaultParms(" + x + ")");
-    return DefaultParms(x, 1.1/*use C++ default here*/);
+    return DefaultParms(x, 1.125/*use C++ default here*/);
   }
 }
 
diff --git a/Examples/test-suite/java/director_default_runme.java b/Examples/test-suite/java/director_default_runme.java
index b71e45e..1ab1323 100644
--- a/Examples/test-suite/java/director_default_runme.java
+++ b/Examples/test-suite/java/director_default_runme.java
@@ -16,22 +16,29 @@
     {
       director_default_MyFoo a = new director_default_MyFoo();
       a = new director_default_MyFoo(10);
+      a.delete();
     }
 
-    director_default_MyFoo a = new director_default_MyFoo();
-    if (!a.GetMsg().equals("director_default_MyFoo-default")) {
-      throw new RuntimeException ( "Test 1 failed" );
-    }
-    if (!a.GetMsg("boo").equals("director_default_MyFoo-boo")) {
-      throw new RuntimeException ( "Test 2 failed" );
+    {
+      director_default_MyFoo a = new director_default_MyFoo();
+      if (!a.GetMsg().equals("director_default_MyFoo-default")) {
+        throw new RuntimeException ( "Test 1 failed" );
+      }
+      if (!a.GetMsg("boo").equals("director_default_MyFoo-boo")) {
+        throw new RuntimeException ( "Test 2 failed" );
+      }
+      a.delete();
     }
 
-    Foo b = new Foo();
-    if (!b.GetMsg().equals("Foo-default")) {
-      throw new RuntimeException ( "Test 1 failed" );
-    }
-    if (!b.GetMsg("boo").equals("Foo-boo")) {
-      throw new RuntimeException ( "Test 2 failed" );
+    {
+      Foo b = new Foo();
+      if (!b.GetMsg().equals("Foo-default")) {
+        throw new RuntimeException ( "Test 1 failed" );
+      }
+      if (!b.GetMsg("boo").equals("Foo-boo")) {
+        throw new RuntimeException ( "Test 2 failed" );
+      }
+      b.delete();
     }
 
   }
diff --git a/Examples/test-suite/java/director_pass_by_value_runme.java b/Examples/test-suite/java/director_pass_by_value_runme.java
index 24ded2c..1d34c3b 100644
--- a/Examples/test-suite/java/director_pass_by_value_runme.java
+++ b/Examples/test-suite/java/director_pass_by_value_runme.java
@@ -32,6 +32,8 @@
           break;
       };
     }
+    if (director_pass_by_value.has_cplusplus11())
+      Counter.check_counts(1, 0, 0, 1, 0, 1); // check move constructor called and just one destructor
     // bug was the passByVal 'global' object was destroyed after the call to virtualMethod had finished.
     int ret = director_pass_by_value_runme.passByVal.getVal();
     if (ret != 0x12345678)
diff --git a/Examples/test-suite/java/director_property_runme.java b/Examples/test-suite/java/director_property_runme.java
new file mode 100644
index 0000000..cc87277
--- /dev/null
+++ b/Examples/test-suite/java/director_property_runme.java
@@ -0,0 +1,66 @@
+
+import director_property.*;
+
+public class director_property_runme {
+
+  static {
+    try {
+      System.loadLibrary("director_property");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+
+    {
+      Foo a = new director_property_MyFoo();
+      if (!a.getA().equals("")) {
+        throw new RuntimeException( "Test failed" );
+      }
+      a.setA("Hello");
+      if (!a.getA().equals("Hello set from MyFoo")) {
+        throw new RuntimeException( "Test failed" );
+      }
+      a.setAByRef("Hello");
+      if (!a.getA().equals("Hello setAByRef from MyFoo")) {
+        throw new RuntimeException( "Test failed" );
+      }
+      a.delete();
+    }
+
+    {
+      Foo a_original = new director_property_MyFoo();
+      Foo a = Foo.get_self(a_original);
+      if (!a.getA().equals("")) {
+        throw new RuntimeException( "Test failed" );
+      }
+      a.setA("Hello");
+      if (!a.getA().equals("Hello set from MyFoo")) {
+        throw new RuntimeException( "Test failed" );
+      }
+      a.setAByRef("Hello");
+      if (!a.getA().equals("Hello setAByRef from MyFoo")) {
+        throw new RuntimeException( "Test failed" );
+      }
+      a.delete();
+    }
+  }
+}
+
+class director_property_MyFoo extends Foo {
+    public director_property_MyFoo() {
+      super();
+    }
+    @Override
+    public void setA(String a) {
+      super.setA(a + " set from MyFoo");
+    }
+    @Override
+    public void setAByRef(String a) {
+      super.setA(a + " setAByRef from MyFoo");
+    }
+}
+
+
diff --git a/Examples/test-suite/java/director_string_runme.java b/Examples/test-suite/java/director_string_runme.java
index a6ed671..f690707 100644
--- a/Examples/test-suite/java/director_string_runme.java
+++ b/Examples/test-suite/java/director_string_runme.java
@@ -19,11 +19,14 @@
     director_string_A c = new director_string_A("hi");
     for (int i=0; i<3; i++) {
       s = c.call_get(i);
-      if (!s.equals(new Integer(i).toString())) throw new RuntimeException("director_string_A.get(" + i + ") failed. Got:" + s);
+      if (!s.equals(Integer.valueOf(i).toString())) throw new RuntimeException("director_string_A.get(" + i + ") failed. Got:" + s);
     }
 
     director_string_B b = new director_string_B("hello");
 
+    s = b.get_first();
+    if (!s.equals("director_string_B.get_first")) throw new RuntimeException("get_first() failed");
+
     s = b.call_get_first();
     if (!s.equals("director_string_B.get_first")) throw new RuntimeException("call_get_first() failed");
 
@@ -39,7 +42,7 @@
     public String get_first() {
       return "director_string_B.get_first";
     }
-  
+
     public String get(int n) {
       return "director_string_B.get: " + super.get(n);
     }
@@ -50,7 +53,6 @@
       super(first);
     }
     public String get(int n) {
-      return new Integer(n).toString();
+      return Integer.valueOf(n).toString();
     }
 }
-
diff --git a/Examples/test-suite/java/director_using_member_scopes_runme.java b/Examples/test-suite/java/director_using_member_scopes_runme.java
new file mode 100644
index 0000000..d500014
--- /dev/null
+++ b/Examples/test-suite/java/director_using_member_scopes_runme.java
@@ -0,0 +1,64 @@
+
+import director_using_member_scopes.*;
+
+public class director_using_member_scopes_runme {
+
+  static {
+    try {
+      System.loadLibrary("director_using_member_scopes");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    NativeWindowType nwt = new NativeWindowType();
+
+    {
+      director_using_member_scopes_MyApplicationContextSDL a = new director_using_member_scopes_MyApplicationContextSDL();
+
+      if (ApplicationContextBase.call_setWindowGrab(a, nwt, true) != 100)
+        throw new RuntimeException("failed");
+
+      if (ApplicationContextSDL.call_setWindowGrab(a, nwt, true) != 100)
+        throw new RuntimeException("failed");
+    }
+
+    {
+      director_using_member_scopes_MyACSDL a = new director_using_member_scopes_MyACSDL();
+
+      if (ACB.call_setWindowGrab(a, nwt, true) != 100)
+        throw new RuntimeException("failed");
+      if (ACB.call_setWindowGrab(a, "hi", 0) != 200)
+        throw new RuntimeException("failed");
+
+      if (ACSDL.call_setWindowGrab(a, nwt, true) != 100)
+        throw new RuntimeException("failed");
+      if (ACSDL.call_setWindowGrab(a, "hi", 0) != 200)
+        throw new RuntimeException("failed");
+    }
+  }
+}
+
+class director_using_member_scopes_MyApplicationContextSDL extends ApplicationContextSDL {
+  @Override
+  public int setWindowGrab(NativeWindowType win, boolean grab)
+  {
+    return 100;
+  }
+}
+
+class director_using_member_scopes_MyACSDL extends ACSDL {
+  @Override
+  public int setWindowGrab(NativeWindowType win, boolean grab)
+  {
+    return 100;
+  }
+
+  @Override
+  public int setWindowGrab(String s, int val)
+  {
+    return 200;
+  }
+}
diff --git a/Examples/test-suite/java/doxygen_alias_runme.java b/Examples/test-suite/java/doxygen_alias_runme.java
index e21ed6d..98cd977 100644
--- a/Examples/test-suite/java/doxygen_alias_runme.java
+++ b/Examples/test-suite/java/doxygen_alias_runme.java
@@ -1,6 +1,5 @@
 
 import doxygen_alias.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_alias_runme {
@@ -15,10 +14,7 @@
 
   public static void main(String argv[])
   {
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_alias runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_alias"});
+    CommentParser.parse("doxygen_alias");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     wantedComments.put("doxygen_alias.doxygen_alias.make_something()",
@@ -27,6 +23,6 @@
       "     @return A new object which may be null.\n" +
       "");
 
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
diff --git a/Examples/test-suite/java/doxygen_basic_notranslate_runme.java b/Examples/test-suite/java/doxygen_basic_notranslate_runme.java
index e3d9b02..621cc9e 100644
--- a/Examples/test-suite/java/doxygen_basic_notranslate_runme.java
+++ b/Examples/test-suite/java/doxygen_basic_notranslate_runme.java
@@ -1,6 +1,5 @@
 
 import doxygen_basic_notranslate.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_basic_notranslate_runme {
@@ -15,14 +14,7 @@
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_basic_notranslate runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_basic_notranslate"});
+    CommentParser.parse("doxygen_basic_notranslate");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     wantedComments.put("doxygen_basic_notranslate.doxygen_basic_notranslate.function3(int)",
@@ -97,6 +89,6 @@
     		"");
     
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
diff --git a/Examples/test-suite/java/doxygen_basic_translate_runme.java b/Examples/test-suite/java/doxygen_basic_translate_runme.java
index ab343b5..c64262a 100644
--- a/Examples/test-suite/java/doxygen_basic_translate_runme.java
+++ b/Examples/test-suite/java/doxygen_basic_translate_runme.java
@@ -1,6 +1,5 @@
 
 import doxygen_basic_translate.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_basic_translate_runme {
@@ -15,14 +14,7 @@
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_basic_translate runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_basic_translate"});
+    CommentParser.parse("doxygen_basic_translate");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -94,8 +86,15 @@
     		" @param x Horizontal coordinate.\n" +
     		" @return Arc tangent of <code>y/x</code>.\n" +
     		"");
+    wantedComments.put("doxygen_basic_translate.doxygen_basic_translate.function8()",
+		" Test variadic function\n" +
+		"");
+
+    wantedComments.put("doxygen_basic_translate.doxygen_basic_translate.function9(int)",
+		" Test unnamed argument\n" +
+		"");    
 
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
diff --git a/Examples/test-suite/java/doxygen_basic_translate_style2_runme.java b/Examples/test-suite/java/doxygen_basic_translate_style2_runme.java
index 05e51cf..28cf2da 100644
--- a/Examples/test-suite/java/doxygen_basic_translate_style2_runme.java
+++ b/Examples/test-suite/java/doxygen_basic_translate_style2_runme.java
@@ -1,6 +1,5 @@
 
 import doxygen_basic_translate_style2.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_basic_translate_style2_runme {
@@ -15,14 +14,7 @@
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_basic_translate_style2 runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_basic_translate_style2"});
+    CommentParser.parse("doxygen_basic_translate_style2");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -96,6 +88,6 @@
     		"");
 
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
diff --git a/Examples/test-suite/java/doxygen_basic_translate_style3_runme.java b/Examples/test-suite/java/doxygen_basic_translate_style3_runme.java
new file mode 100644
index 0000000..a095364
--- /dev/null
+++ b/Examples/test-suite/java/doxygen_basic_translate_style3_runme.java
@@ -0,0 +1,93 @@
+
+import doxygen_basic_translate_style3.*;
+import java.util.HashMap;
+
+public class doxygen_basic_translate_style3_runme {
+  static {
+    try {
+      System.loadLibrary("doxygen_basic_translate_style3");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+  
+  public static void main(String argv[]) 
+  {
+    CommentParser.parse("doxygen_basic_translate_style3");
+
+    HashMap<String, String> wantedComments = new HashMap<String, String>();
+    
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.function()",
+    		" \n" +
+    		" Brief description.\n" +
+    		" \n" +
+    		" The comment text.\n" +
+    		" @author Some author\n" +
+    		" @return Some number\n" +
+    		" @see function2\n" +
+    		" \n" +
+    		"");
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.function2()",
+    		" A test of a very very very very very very very very very very very very very very very very \n" +
+    		" very very very very very long comment string. \n" +
+    		" \n" +
+    		"");
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.function4()",
+    		" A test of some mixed tag usage \n" +
+    		" If: CONDITION {\n" +
+    		" This <i>code </i>fragment shows us something . \n" +
+    		" <p alt=\"Minuses: \">\n" +
+    		" <li>it's senseless \n" +
+    		" </li><li>it's stupid \n" +
+    		" </li><li>it's null \n" +
+    		" \n" +
+    		" </li></p>Warning: This may not work as expected \n" +
+    		" \n" +
+    		" {@code \n" +
+    		"int main() { while(true); } \n" +
+		"\n" +
+		"int testBlankLine() {} \n" +
+    		" }\n" +
+    		" }\n" +
+    		" \n" +
+    		"");
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.function3(int)",
+    		" A test for overloaded functions \n" +
+    		" This is function <b>one </b>\n" +
+    		" \n" +
+    		"");
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.function5(int)",
+    		" This is a post comment. \n" +
+    		"");
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.function6(int)",
+    		" Test for default args \n" +
+    		" @param a Some parameter, default is 42" +
+    		" \n" +
+    		"");
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.function6()",
+    		" Test for default args \n" +
+    		" \n" +
+    		"");
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.function7(doxygen_basic_translate_style3.SWIGTYPE_p_p_p_Shape)",
+    		" Test for a parameter with difficult type \n" +
+    		" (mostly for python) \n" +
+    		" @param a Very strange param \n" +
+    		"");
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.function3(int, int)",
+    		" A test for overloaded functions \n" +
+    		" This is function <b>two </b>\n" +
+    		" \n" +
+    		"");
+    wantedComments.put("doxygen_basic_translate_style3.doxygen_basic_translate_style3.Atan2(double, double)",
+    		" Multiple parameters test.\n" +
+    		" \n" +
+    		" @param y Vertical coordinate.\n" +
+    		" @param x Horizontal coordinate.\n" +
+    		" @return Arc tangent of <code>y/x</code>.\n" +
+    		"");
+
+    // and ask the parser to check comments for us
+    System.exit(CommentParser.check(wantedComments));
+  }
+}
diff --git a/Examples/test-suite/java/doxygen_code_blocks_runme.java b/Examples/test-suite/java/doxygen_code_blocks_runme.java
new file mode 100644
index 0000000..8e8373b
--- /dev/null
+++ b/Examples/test-suite/java/doxygen_code_blocks_runme.java
@@ -0,0 +1,75 @@
+
+import doxygen_code_blocks.*;
+import java.util.HashMap;
+
+public class doxygen_code_blocks_runme {
+  static {
+    try {
+      System.loadLibrary("doxygen_code_blocks");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+  
+  public static void main(String argv[]) 
+  {
+    CommentParser.parse("doxygen_code_blocks");
+
+    HashMap<String, String> wantedComments = new HashMap<String, String>();
+    
+    wantedComments.put("doxygen_code_blocks.doxygen_code_blocks.function()",
+		       " Test for code blocks\n \n" +
+		       " \n \n" +
+		       " {@code  \n" +
+		       " simple code block \n" +
+		       " }\n \n" +
+		       " \n \n" +
+		       " More advanced usage with C++ characters:\n \n" +
+		       " {@code  \n" +
+		       " std::vector<int> first;                                // empty vector of ints \n" +
+		       " std::vector<int> second (4,100);                       // four ints with value 100 \n" +
+		       " std::vector<int> third (second.begin(),second.end());  // iterating through second \n" +
+		       " std::vector<int> fourth (third);                       // a copy of third \n" +
+		       " // the iterator constructor can also be used to construct from arrays: \n" +
+		       " int myints[] = {16,2,77,29}; \n" +
+		       " std::vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) ); \n" +
+		       "  \n" +
+		       " std::cout << \"The contents of fifth are:\"; \n" +
+		       " for (std::vector<int>::iterator it = fifth.begin(); it != fifth.end(); ++it) \n" +
+		       " std::cout << \' \' << *it; \n" +
+		       " std::cout << \'\\n\';  \n" +
+		       " }\n \n" +
+		       " \n \n" +
+		       " A code block for C:\n \n" +
+		       " {@code  \n" +
+		       " printf(\"hello world\"); \n" +
+		       " }\n \n" +
+		       " \n \n" +
+		       " A code block for Java:\n \n" +
+		       " {@code  \n" +
+		       " public class HelloWorld { \n" +
+		       " public static void main(String[] args) { \n" +
+		       " // Prints \"Hello, World\" to the terminal window. \n" +
+		       " System.out.println(\"Hello, World\"); \n" +
+		       " } \n" +
+		       " } \n" +
+		       " }\n \n" +
+		       " \n \n" +
+		       " A code block for python:\n \n" +
+		       " {@code  \n" +
+		       " print(\'hello world\') \n" +
+		       " }\n \n" +
+		       " \n \n" +
+		       " A python doctest example:\n \n" +
+		       " {@code  \n" +
+		       " >>> 1 + 1 \n" +
+		       " 2 \n" +
+		       " } \n" +
+		       " \n" +
+		       "");
+
+    // and ask the parser to check comments for us
+    System.exit(CommentParser.check(wantedComments));
+  }
+}
diff --git a/Examples/test-suite/java/doxygen_ignore_runme.java b/Examples/test-suite/java/doxygen_ignore_runme.java
index 6250ce5..29b6e06 100644
--- a/Examples/test-suite/java/doxygen_ignore_runme.java
+++ b/Examples/test-suite/java/doxygen_ignore_runme.java
@@ -1,6 +1,5 @@
 
 import doxygen_ignore.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_ignore_runme {
@@ -15,10 +14,7 @@
 
   public static void main(String argv[]) 
   {
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_ignore runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_ignore"});
+    CommentParser.parse("doxygen_ignore");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     wantedComments.put("doxygen_ignore.doxygen_ignore.func()",
@@ -39,6 +35,6 @@
       "\n" +
       "");
 
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
diff --git a/Examples/test-suite/java/doxygen_misc_constructs_runme.java b/Examples/test-suite/java/doxygen_misc_constructs_runme.java
index 5d95bd5..3735042 100644
--- a/Examples/test-suite/java/doxygen_misc_constructs_runme.java
+++ b/Examples/test-suite/java/doxygen_misc_constructs_runme.java
@@ -1,6 +1,5 @@
 
 import doxygen_misc_constructs.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_misc_constructs_runme {
@@ -15,14 +14,7 @@
 
   public static void main(String argv[])
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_misc_constructs runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_misc_constructs"});
+    CommentParser.parse("doxygen_misc_constructs");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
 
@@ -105,7 +97,7 @@
     		"\n");
 
     wantedComments.put("doxygen_misc_constructs.ClassWithNestedEnum.ENested",
-    		" Enum description.\n" +
+    		" ENested description.\n" +
     		"\n");
 
     wantedComments.put("doxygen_misc_constructs.ClassWithNestedEnum.ENested.ONE",
@@ -117,6 +109,81 @@
     wantedComments.put("doxygen_misc_constructs.ClassWithNestedEnum.ENested.THREE",
     		" desc of three\n");
 
+    wantedComments.put("doxygen_misc_constructs.ClassWithNestedEnum.ENestedOdd",
+    		" ENestedOdd description.\n" +
+    		"\n");
+
+    wantedComments.put("doxygen_misc_constructs.ClassWithNestedEnum.ENestedOdd.ODD_ONE",
+    		" desc of odd_one\n");
+
+    wantedComments.put("doxygen_misc_constructs.ClassWithNestedEnum.ENestedOdd.ODD_TWO",
+    		" desc of odd_two\n");
+
+    wantedComments.put("doxygen_misc_constructs.ClassWithNestedEnum.ENestedOdd.ODD_THREE",
+    		" desc of odd_three\n");
+
+    wantedComments.put("doxygen_misc_constructs.ClassWithNestedEnum.ENestedOddPartial1",
+    		" ENestedOddPartial1 description.\n" +
+    		"\n");
+
+    wantedComments.put("doxygen_misc_constructs.ClassWithNestedEnum.ENestedOddPartial1.ODD_PARTIAL1_THREE",
+    		" desc of odd_partial1_three\n");
+
+    wantedComments.put("doxygen_misc_constructs.ClassWithNestedEnum.ENestedOddPartial1.ODD_PARTIAL1_TWO",
+    		" desc of odd_partial1_two\n");
+
+    wantedComments.put("doxygen_misc_constructs.ClassWithNestedEnum.ENestedOddPartial3",
+    		" ENestedOddPartial3 description.\n" +
+    		"\n");
+
+    wantedComments.put("doxygen_misc_constructs.ClassWithNestedEnum.ENestedOddPartial3.ODD_PARTIAL3_ONE",
+    		" desc of odd_partial3_one\n");
+
+    wantedComments.put("doxygen_misc_constructs.ClassWithNestedEnum.ENestedOddPartial3.ODD_PARTIAL3_TWO",
+    		" desc of odd_partial3_two\n");
+
+    wantedComments.put("doxygen_misc_constructs.ClassWithNestedEnum.TESTENUM",
+    		" Description for TESTENUM.\n" +
+    		"\n");
+
+    wantedComments.put("doxygen_misc_constructs.ClassWithNestedEnum.TESTENUM.TEST_NONE",
+    		" something for none\n");
+
+    wantedComments.put("doxygen_misc_constructs.ClassWithNestedEnum.TESTENUM.TEST_ONE",
+    		" something for one\n");
+
+    wantedComments.put("doxygen_misc_constructs.ClassWithNestedEnum.TESTENUM.TEST_TWO",
+    		" something for two  something more for two\n");
+
+    wantedComments.put("doxygen_misc_constructs.SIOBeam",
+    		" SIOBeam struct description\n" +
+    		"\n");
+
+    wantedComments.put("doxygen_misc_constructs.SIOBeam.testfunction(int, double, boolean)",
+                "  testfunction - testing extra trailing doc comment <br>\n" +
+                " @param testf_aaa testfunction aaa parm <br>\n" +
+                " @param testf_bbb testfunction bbb parm <br>\n" +
+                " @param testf_ccc testfunction ccc parm  testfunction more for two parm\n" +
+    		"\n");
+
+    wantedComments.put("doxygen_misc_constructs.SIOBeam(java.lang.String, int, int)",
+                "  Constructor for input from an existing SIO file<br>\n" +
+                " @param filename Name of input SIO file.<br>\n" +
+                " @param elevationOrder Interpolation order (0-3) in elevation<br>\n" +
+                " @param bearingOrder Interpolation order (0-3) in bearing\n" +
+    		"\n");
+
+    wantedComments.put("doxygen_misc_constructs.SIOBeam(java.lang.String, int)",
+                "  Constructor for input from an existing SIO file<br>\n" +
+                " @param filename Name of input SIO file.<br>\n" +
+                " @param elevationOrder Interpolation order (0-3) in elevation<br>\n" +
+    		"\n");
+
+    wantedComments.put("doxygen_misc_constructs.SIOBeam(java.lang.String)",
+                "  Constructor for input from an existing SIO file<br>\n" +
+                " @param filename Name of input SIO file.<br>\n" +
+    		"\n");
+
     wantedComments.put("doxygen_misc_constructs.StructWithReturnComment",
     		" @return This is a bad place for this tag, but it should be ignored.");
 
@@ -132,6 +199,16 @@
 " <br>\n" +
 "        And this is not a list item any more.\n" +
     		"");
+
+    wantedComments.put("doxygen_misc_constructs.IncorrectlyDocumentedMembers",
+    		" Incorrectly documented members, these should be post document comments, Github issue #1636");
+
+    wantedComments.put("doxygen_misc_constructs.IncorrectlyDocumentedMembers.setBbbb(int)",
+    		" really for bbbb value");
+
+    wantedComments.put("doxygen_misc_constructs.IncorrectlyDocumentedMembers.getBbbb()",
+    		" really for bbbb value");
+
     wantedComments.put("doxygen_misc_constructs.doxygen_misc_constructs.isNoSpaceValidA()",
     		" This comment without space after '*' is valid in Doxygen.\n" +
     		"\n" +
@@ -193,8 +270,14 @@
                 "\n" +
                 " @param fileName name of the log file\n");
 
+    wantedComments.put("doxygen_misc_constructs.doxygen_misc_constructs.doc_ends_with_quote()",
+            "This doc comment ends with a quote: \"and that's ok\"");
+
+    wantedComments.put("doxygen_misc_constructs.doxygen_misc_constructs.doc_with_triple_quotes()",
+            "This comment contains embedded triple-quoted string:\n" +
+            "\"\"\"How quaint\"\"\"");
 
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
diff --git a/Examples/test-suite/java/doxygen_nested_class_runme.java b/Examples/test-suite/java/doxygen_nested_class_runme.java
index 3ffa796..e9d1a06 100644
--- a/Examples/test-suite/java/doxygen_nested_class_runme.java
+++ b/Examples/test-suite/java/doxygen_nested_class_runme.java
@@ -1,5 +1,4 @@
 import doxygen_nested_class.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_nested_class_runme {
@@ -14,14 +13,7 @@
 
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_nested_class runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_nested_class"});
+    CommentParser.parse("doxygen_nested_class");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -43,6 +35,6 @@
     		" doxShort const variable ");
     
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
diff --git a/Examples/test-suite/java/doxygen_parsing_enums_proper_runme.java b/Examples/test-suite/java/doxygen_parsing_enums_proper_runme.java
index ef1f06a..6b1e2b0 100644
--- a/Examples/test-suite/java/doxygen_parsing_enums_proper_runme.java
+++ b/Examples/test-suite/java/doxygen_parsing_enums_proper_runme.java
@@ -1,6 +1,5 @@
 
 import doxygen_parsing_enums_proper.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_parsing_enums_proper_runme {
@@ -15,14 +14,7 @@
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_parsing_enums_proper runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_parsing_enums_proper"});
+    CommentParser.parse("doxygen_parsing_enums_proper");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -61,6 +53,6 @@
     		"Post comment after last comma.");
     
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
diff --git a/Examples/test-suite/java/doxygen_parsing_enums_simple_runme.java b/Examples/test-suite/java/doxygen_parsing_enums_simple_runme.java
index 85ec0cb..1e0dd74 100644
--- a/Examples/test-suite/java/doxygen_parsing_enums_simple_runme.java
+++ b/Examples/test-suite/java/doxygen_parsing_enums_simple_runme.java
@@ -1,6 +1,5 @@
 
 import doxygen_parsing_enums_simple.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_parsing_enums_simple_runme {
@@ -15,14 +14,7 @@
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_parsing_enums_simple runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_parsing_enums_simple"});
+    CommentParser.parse("doxygen_parsing_enums_simple");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -53,6 +45,6 @@
     		"Post comment after last comma.");
     
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
diff --git a/Examples/test-suite/java/doxygen_parsing_enums_typesafe_runme.java b/Examples/test-suite/java/doxygen_parsing_enums_typesafe_runme.java
index 4e5f4b4..7cf3b17 100644
--- a/Examples/test-suite/java/doxygen_parsing_enums_typesafe_runme.java
+++ b/Examples/test-suite/java/doxygen_parsing_enums_typesafe_runme.java
@@ -1,6 +1,5 @@
 
 import doxygen_parsing_enums_typesafe.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_parsing_enums_typesafe_runme {
@@ -15,14 +14,7 @@
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_parsing_enums_typesafe runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_parsing_enums_typesafe"});
+    CommentParser.parse("doxygen_parsing_enums_typesafe");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -62,6 +54,6 @@
 
     
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
diff --git a/Examples/test-suite/java/doxygen_parsing_enums_typeunsafe_runme.java b/Examples/test-suite/java/doxygen_parsing_enums_typeunsafe_runme.java
index 4286491..3a41fe5 100644
--- a/Examples/test-suite/java/doxygen_parsing_enums_typeunsafe_runme.java
+++ b/Examples/test-suite/java/doxygen_parsing_enums_typeunsafe_runme.java
@@ -1,6 +1,5 @@
 
 import doxygen_parsing_enums_typeunsafe.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_parsing_enums_typeunsafe_runme {
@@ -15,14 +14,7 @@
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_parsing_enums_typeunsafe runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_parsing_enums_typeunsafe"});
+    CommentParser.parse("doxygen_parsing_enums_typeunsafe");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -61,6 +53,6 @@
     		"Post comment after last comma.");
     
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
diff --git a/Examples/test-suite/java/doxygen_parsing_runme.java b/Examples/test-suite/java/doxygen_parsing_runme.java
index d58b1f4..05828f2 100644
--- a/Examples/test-suite/java/doxygen_parsing_runme.java
+++ b/Examples/test-suite/java/doxygen_parsing_runme.java
@@ -1,6 +1,5 @@
 
 import doxygen_parsing.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_parsing_runme {
@@ -15,14 +14,7 @@
 
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_parsing runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_parsing"});
+    CommentParser.parse("doxygen_parsing");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -53,6 +45,12 @@
     		" The struct comment \n" +
     		" \n" +
     		"");
+    wantedComments.put("doxygen_parsing.SomeStruct.setWidth(int)",
+    		"**immutable** image width in pixels \n" +
+    		"");
+    wantedComments.put("doxygen_parsing.SomeStruct.getWidth()",
+    		"**immutable** image width in pixels \n" +
+    		"");
     wantedComments.put("doxygen_parsing.doxygen_parsing.setSomeVar(int)",
     		" The var comment \n" +
     		" \n" +
@@ -134,8 +132,24 @@
     wantedComments.put("doxygen_parsing.doxygen_parsingConstants.CONSTANT_VALUE",
     		"The constant comment \n" +
     		"");
+    wantedComments.put("doxygen_parsing.Foo1636.getGroupmember1()",
+	        "groupmember1 description");
+    wantedComments.put("doxygen_parsing.Foo1636.setGroupmember1(int)",
+	        "groupmember1 description");
+    wantedComments.put("doxygen_parsing.Foo1636.getGroupmember2()",
+	        "groupmember2 description");
+    wantedComments.put("doxygen_parsing.Foo1636.setGroupmember2(int)",
+	        "groupmember2 description");
+    wantedComments.put("doxygen_parsing.Foo1750.getA()",
+	        "");
+    wantedComments.put("doxygen_parsing.Foo1750.getB()",
+	        "");
+    wantedComments.put("doxygen_parsing.Foo1750.setA(int)",
+	        "");
+    wantedComments.put("doxygen_parsing.Foo1750.setB(int)",
+	        "");
     
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
diff --git a/Examples/test-suite/java/doxygen_translate_all_tags_runme.java b/Examples/test-suite/java/doxygen_translate_all_tags_runme.java
index d5c533f..80087c6 100644
--- a/Examples/test-suite/java/doxygen_translate_all_tags_runme.java
+++ b/Examples/test-suite/java/doxygen_translate_all_tags_runme.java
@@ -1,6 +1,5 @@
 
 import doxygen_translate_all_tags.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_translate_all_tags_runme {
@@ -15,14 +14,7 @@
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_translate_all_tags runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_translate_all_tags"});
+    CommentParser.parse("doxygen_translate_all_tags");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -89,7 +81,7 @@
     		" If not: SOMECONDITION {\n" +
     		" This is printed if not \n" +
     		" }\n" +
-    		" <img src=testImage.bmp alt=\"Hello, world!\" />\n" +
+    		" <img src=\"testImage.bmp\" alt=\"Hello, world!\"/>\n" +
     		" Some text \n" +
     		" describing invariant. \n");
     
@@ -101,10 +93,10 @@
     		" </li><li>With lots of items \n" +
     		" </li><li>lots of lots of items \n" +
     		" </li></ul> \n" +
-    		" {@link someMember Some description follows }\n" +
+    		" {@link someMember Some description follows} with text after\n" +
     		" This will only appear in man\n");
     
-    wantedComments.put("doxygen_translate_all_tags.doxygen_translate_all_tags.func07(int)",
+    wantedComments.put("doxygen_translate_all_tags.doxygen_translate_all_tags.func07(int, int, int, int)",
                        " Comment for <b>func07()</b>.\n" +
                        " Note: Here \n" +
     		" is the note! \n" +
@@ -115,7 +107,10 @@
     		" The paragraph text. \n" +
     		" Maybe even multiline \n" +
     		" </p>\n" +
-                " @param a the first param\n");
+                " @param a the first param\n" +
+                " @param b parameter with intent(in)\n" +
+                " @param c parameter with intent(out)\n" +
+		" @param d parameter with intent(in,out)\n");
     
     wantedComments.put("doxygen_translate_all_tags.doxygen_translate_all_tags.func08(int)",
                        "<a id=\"someAnchor\"></a>\n" +
@@ -154,6 +149,6 @@
     		" And here goes simple text \n" +
     		"");
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
diff --git a/Examples/test-suite/java/doxygen_translate_links_runme.java b/Examples/test-suite/java/doxygen_translate_links_runme.java
index 6d74e16..afee4ea 100644
--- a/Examples/test-suite/java/doxygen_translate_links_runme.java
+++ b/Examples/test-suite/java/doxygen_translate_links_runme.java
@@ -1,6 +1,5 @@
 
 import doxygen_translate_links.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 
 public class doxygen_translate_links_runme {
@@ -15,14 +14,7 @@
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_translate_links runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_translate_links"});
+    CommentParser.parse("doxygen_translate_links");
 
     HashMap<String, String> wantedComments = new HashMap<String, String>();
     
@@ -64,6 +56,6 @@
     		"");
     
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
\ No newline at end of file
diff --git a/Examples/test-suite/java/doxygen_translate_runme.java b/Examples/test-suite/java/doxygen_translate_runme.java
index 55e5d23..c55c951 100644
--- a/Examples/test-suite/java/doxygen_translate_runme.java
+++ b/Examples/test-suite/java/doxygen_translate_runme.java
@@ -1,6 +1,5 @@
 
 import doxygen_translate.*;
-import com.sun.javadoc.*;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -16,14 +15,7 @@
   
   public static void main(String argv[]) 
   {
-    /*
-      Here we are using internal javadoc tool, it accepts the name of the class as paramterer,
-      and calls the start() method of that class with parsed information.
-    */
-    CommentParser parser = new CommentParser();
-    com.sun.tools.javadoc.Main.execute("doxygen_translate runtime test",
-                                       "CommentParser",
-                                       new String[]{"-quiet", "doxygen_translate"});
+    CommentParser.parse("doxygen_translate");
 
     Map<String, String> wantedComments = new HashMap<String, String>();
     
@@ -77,7 +69,8 @@
     		" This is printed if not}\n" +
     		" \n" +
     		" \n" +
-    		" <img src=testImage.bmp alt=\"Hello, world!\"/>\n" +
+    		" <img src=\"testImage.bmp\" alt=\"Hello, world!\"/>\n" +
+    		" <img src=\"test image.jpg\" alt=\"Test jpeg\"/>\n" +
     		" \n" +
     		" <ul> \n" +
     		" \n" +
@@ -274,6 +267,6 @@
                 "");
         
     // and ask the parser to check comments for us
-    System.exit(parser.check(wantedComments));
+    System.exit(CommentParser.check(wantedComments));
   }
 }
diff --git a/Examples/test-suite/java/friends_runme.java b/Examples/test-suite/java/friends_runme.java
index 2dced9e..165b052 100644
--- a/Examples/test-suite/java/friends_runme.java
+++ b/Examples/test-suite/java/friends_runme.java
@@ -11,6 +11,11 @@
     }
   }
 
+  private static void check_equal(int a, int b) {
+    if (a != b)
+      throw new RuntimeException("Not equal " + a + " != " + b);
+  }
+
   public static void main(String argv[]) throws Throwable
   {
     A a = new A(2);
@@ -32,7 +37,7 @@
     if (friends.mix(a,b) != 5)
       throw new RuntimeException("failed");
 
-    D_d di = new D_d(2);
+    D_i di = new D_i(2);
     D_d dd = new D_d(3.3);
 
     // incredible template overloading working just fine
@@ -48,6 +53,22 @@
       throw new RuntimeException("failed");
     if (friends.get_val1(dd) != 1.3)
       throw new RuntimeException("failed");
+
+    if (friends.chum_blah() != 1234)
+      throw new RuntimeException("failed");
+    if (friends.mate_blah() != 4321)
+      throw new RuntimeException("failed");
+
+    Foe foe = new Foe(111);
+    check_equal(friends.friend_definition(), 10);
+    check_equal(friends.friend_declaration(), 11);
+    check_equal(friends.friend_args_definition(foe), 111);
+    check_equal(friends.friend_args_declaration(foe), 111);
+
+    check_equal(friends.friend_definition_compiler(), 20);
+    check_equal(friends.friend_declaration_compiler(), 21);
+    check_equal(friends.friend_args_definition_compiler(foe), 111);
+    check_equal(friends.friend_args_declaration_compiler(foe), 111);
   }
 }
 
diff --git a/Examples/test-suite/java/java_typemaps_proxy_runme.java b/Examples/test-suite/java/java_typemaps_proxy_runme.java
index 67a0831..0caeb1c 100644
--- a/Examples/test-suite/java/java_typemaps_proxy_runme.java
+++ b/Examples/test-suite/java/java_typemaps_proxy_runme.java
@@ -76,6 +76,15 @@
     java_typemaps_proxyJNI.Without_member_method(nullPtr, nullPtr);
     java_typemaps_proxyJNI.delete_Without(nullPtr);
     java_typemaps_proxyJNI.global_method_without(nullPtr);
+
+    // $imfuncname substitution
+    ProxyA pa = new ProxyA();
+    if (pa.imfuncname_test() != 123)
+      throw new RuntimeException("imfuncname_test is not 123");
+    if (ProxyA.imfuncname_static_test() != 234)
+      throw new RuntimeException("imfuncname_test is not 234");
+    if (java_typemaps_proxy.imfuncname_global_test() != 345)
+      throw new RuntimeException("imfuncname_test is not 345");
   }
 }
 
diff --git a/Examples/test-suite/java/li_boost_shared_ptr_runme.java b/Examples/test-suite/java/li_boost_shared_ptr_runme.java
index 64c356f..b513fad 100644
--- a/Examples/test-suite/java/li_boost_shared_ptr_runme.java
+++ b/Examples/test-suite/java/li_boost_shared_ptr_runme.java
@@ -605,7 +605,7 @@
       throw new RuntimeException("verify value failed. Expected: " + expected + " Got: " + got);
   }
   private void verifyCount(int expected, Klass k) {
-    int got = li_boost_shared_ptr.use_count(k); 
+    int got = (int)li_boost_shared_ptr.use_count(k); 
     if (expected != got)
       throw new RuntimeException("verify use_count failed. Expected: " + expected + " Got: " + got);
   }
diff --git a/Examples/test-suite/java/li_constraints_runme.java b/Examples/test-suite/java/li_constraints_runme.java
new file mode 100644
index 0000000..85027e8
--- /dev/null
+++ b/Examples/test-suite/java/li_constraints_runme.java
@@ -0,0 +1,77 @@
+
+import java.util.function.*;
+import li_constraints.*;
+
+public class li_constraints_runme {
+
+  static {
+    try {
+	System.loadLibrary("li_constraints");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void check_double(boolean except, Consumer<Double> f, double val, String ex) {
+      boolean actual = true;
+      boolean proper = false;
+      try {
+        f.accept(val);
+      } catch(RuntimeException e) {
+        actual = false;
+        proper = e.getMessage().equals(String.join(" ", "Expected", "a", ex, "value."));
+      }
+      if (actual) {
+        if (!except) {
+          throw new RuntimeException(String.join("", "function '", ex, "' with ", String.valueOf(val), " should perform an exception"));
+        }
+      } else {
+        if (except) {
+          throw new RuntimeException(String.join("", "function '", ex, "' with ", String.valueOf(val), " should not perform an exception"));
+        } else if (!proper) {
+          throw new RuntimeException(String.join("", "function '", ex, "' with ", String.valueOf(val), " should perform a proper exception"));
+        }
+      }
+  }
+
+  public static void main(String argv[]) {
+
+      Consumer<Double> func = v -> li_constraints.test_nonnegative(v);
+      check_double(true, func, 10, "non-negative");
+      check_double(true, func, 0, "non-negative");
+      check_double(false, func, -10, "non-negative");
+
+      func = v -> li_constraints.test_nonpositive(v);
+      check_double(false, func, 10, "non-positive");
+      check_double(true, func, 0, "non-positive");
+      check_double(true, func, -10, "non-positive");
+
+      func = v -> li_constraints.test_positive(v);
+      check_double(true, func, 10, "positive");
+      check_double(false, func, 0, "positive");
+      check_double(false, func, -10, "positive");
+
+      func = v -> li_constraints.test_negative(v);
+      check_double(false, func, 10, "negative");
+      check_double(false, func, 0, "negative");
+      check_double(true, func, -10, "negative");
+
+      func = v -> li_constraints.test_nonzero(v);
+      check_double(true, func, 10, "nonzero");
+      check_double(false, func, 0, "nonzero");
+      check_double(true, func, -10, "nonzero");
+
+      boolean have_exception = false;
+      try {
+        li_constraints.test_nonnull(null);
+      } catch(Exception e) {
+        have_exception = e.getMessage().equals("Received a NULL pointer.");
+      }
+      if (!have_exception) {
+          throw new RuntimeException("test_nonnull should perform proper exception with 'null' value");
+      }
+      SWIGTYPE_p_void nonnull = li_constraints.get_nonnull();
+      li_constraints.test_nonnull(nonnull);
+  }
+}
diff --git a/Examples/test-suite/java/li_std_auto_ptr_runme.java b/Examples/test-suite/java/li_std_auto_ptr_runme.java
index 50ed113..24e353d 100644
--- a/Examples/test-suite/java/li_std_auto_ptr_runme.java
+++ b/Examples/test-suite/java/li_std_auto_ptr_runme.java
@@ -20,49 +20,127 @@
     }
   }
 
+  private static void checkCount(int expected_count) {
+    int actual_count = Klass.getTotal_count();
+    if (actual_count != expected_count)
+      throw new RuntimeException("Counts incorrect, expected:" + expected_count + " actual:" + actual_count);
+  }
+
   public static void main(String argv[]) throws Throwable
   {
+    // Test raw pointer handling involving virtual inheritance
+    {
+      KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+      checkCount(1);
+      String s = li_std_auto_ptr.useKlassRawPtr(kini);
+      if (!s.equals("KlassInheritanceInput"))
+        throw new RuntimeException("Incorrect string: " + s);
+      kini.delete();
+      checkCount(0);
+    }
+
+    // auto_ptr as input
+    {
+      Klass kin = new Klass("KlassInput");
+      checkCount(1);
+      String s = li_std_auto_ptr.takeKlassAutoPtr(kin);
+      checkCount(0);
+      if (!s.equals("KlassInput"))
+        throw new RuntimeException("Incorrect string: " + s);
+      if (!li_std_auto_ptr.is_nullptr(kin))
+        throw new RuntimeException("is_nullptr failed");
+      kin.delete(); // Should not fail, even though already deleted
+      checkCount(0);
+    }
+
+    {
+      Klass kin = new Klass("KlassInput");
+      checkCount(1);
+      String s = li_std_auto_ptr.takeKlassAutoPtr(kin);
+      checkCount(0);
+      if (!s.equals("KlassInput"))
+        throw new RuntimeException("Incorrect string: " + s);
+      if (!li_std_auto_ptr.is_nullptr(kin))
+        throw new RuntimeException("is_nullptr failed");
+      boolean exception_thrown = false;
+      try {
+        li_std_auto_ptr.takeKlassAutoPtr(kin);
+      } catch (RuntimeException e) {
+        if (!e.getMessage().contains("Cannot release ownership as memory is not owned"))
+          throw new RuntimeException("incorrect exception message");
+        exception_thrown = true;
+      }
+      if (!exception_thrown)
+          throw new RuntimeException("double usage of takeKlassAutoPtr should have been an error");
+      kin.delete(); // Should not fail, even though already deleted
+      checkCount(0);
+    }
+
+    {
+      Klass kin = new Klass("KlassInput");
+      boolean exception_thrown = false;
+      Klass notowned = li_std_auto_ptr.get_not_owned_ptr(kin);
+      try {
+        li_std_auto_ptr.takeKlassAutoPtr(notowned);
+      } catch (RuntimeException e) {
+        if (!e.getMessage().contains("Cannot release ownership as memory is not owned"))
+          throw new RuntimeException("incorrect exception message");
+        exception_thrown = true;
+      }
+      if (!exception_thrown)
+        throw new RuntimeException("Should have thrown 'Cannot release ownership as memory is not owned' error");
+      checkCount(1);
+      kin.delete();
+      checkCount(0);
+    }
+
+    {
+      KlassInheritance kini = new KlassInheritance("KlassInheritanceInput");
+      checkCount(1);
+      String s = li_std_auto_ptr.takeKlassAutoPtr(kini);
+      checkCount(0);
+      if (!s.equals("KlassInheritanceInput"))
+        throw new RuntimeException("Incorrect string: " + s);
+      if (!li_std_auto_ptr.is_nullptr(kini))
+        throw new RuntimeException("is_nullptr failed");
+      kini.delete(); // Should not fail, even though already deleted
+      checkCount(0);
+    }
+
+    li_std_auto_ptr.takeKlassAutoPtr(null);
+    li_std_auto_ptr.takeKlassAutoPtr(li_std_auto_ptr.make_null());
+    checkCount(0);
+
+    // overloaded parameters
+    if (li_std_auto_ptr.overloadTest() != 0)
+      throw new RuntimeException("overloadTest failed");
+    if (li_std_auto_ptr.overloadTest(null) != 1)
+      throw new RuntimeException("overloadTest failed");
+    if (li_std_auto_ptr.overloadTest(new Klass("over")) != 1)
+      throw new RuntimeException("overloadTest failed");
+    checkCount(0);
+
+
+    // auto_ptr as output
     Klass k1 = li_std_auto_ptr.makeKlassAutoPtr("first");
     if (!k1.getLabel().equals("first"))
       throw new RuntimeException("wrong object label");
 
     Klass k2 = li_std_auto_ptr.makeKlassAutoPtr("second");
-    if (Klass.getTotal_count() != 2)
-      throw new RuntimeException("number of objects should be 2");
+    checkCount(2);
 
+    k1.delete();
     k1 = null;
-    {
-      int countdown = 500;
-      int expectedCount = 1;
-      while (true) {
-        WaitForGC();
-        if (--countdown == 0)
-          break;
-        if (Klass.getTotal_count() == expectedCount)
-          break;
-      }
-      int actualCount = Klass.getTotal_count();
-      if (actualCount != expectedCount)
-        System.err.println("GC failed to run (li_std_auto_ptr 1). Expected count: " + expectedCount + " Actual count: " + actualCount); // Finalizers are not guaranteed to be run and sometimes they just don't
-    }
+    checkCount(1);
 
     if (!k2.getLabel().equals("second"))
       throw new RuntimeException("wrong object label");
 
+    k2.delete();
     k2 = null;
-    {
-      int countdown = 500;
-      int expectedCount = 0;
-      while (true) {
-        WaitForGC();
-        if (--countdown == 0)
-          break;
-        if (Klass.getTotal_count() == expectedCount)
-          break;
-      };
-      int actualCount = Klass.getTotal_count();
-      if (actualCount != expectedCount)
-        System.err.println("GC failed to run (li_std_auto_ptr 2). Expected count: " + expectedCount + " Actual count: " + actualCount); // Finalizers are not guaranteed to be run and sometimes they just don't
-    }
+    checkCount(0);
+
+    if (li_std_auto_ptr.makeNullAutoPtr() != null)
+      throw new RuntimeException("null failure");
   }
 }
diff --git a/Examples/test-suite/java/li_std_string_runme.java b/Examples/test-suite/java/li_std_string_runme.java
index 1ee2a23..ffb9df9 100644
--- a/Examples/test-suite/java/li_std_string_runme.java
+++ b/Examples/test-suite/java/li_std_string_runme.java
@@ -104,5 +104,18 @@
         throw new Exception("StaticMemberString2 test 2");
       if (!Structure.getConstStaticMemberString().equals("const static member string"))
         throw new Exception("ConstStaticMemberString test");
+
+      if (!li_std_string.stdstring_empty().equals(""))
+        throw new Exception("stdstring_empty test");
+      if (!li_std_string.c_empty().equals(""))
+        throw new Exception("c_empty test");
+      if (li_std_string.c_null() != null)
+        throw new Exception("c_null test");
+      if (li_std_string.get_null(li_std_string.c_null()) != null)
+        throw new Exception("get_null c_null test");
+      if (!li_std_string.get_null(li_std_string.c_empty()).equals("non-null"))
+        throw new Exception("get_null c_empty test");
+      if (!li_std_string.get_null(li_std_string.stdstring_empty()).equals("non-null"))
+        throw new Exception("get_null stdstring_empty test");
   }
 }
diff --git a/Examples/test-suite/java/multiple_inheritance_abstract_runme.java b/Examples/test-suite/java/multiple_inheritance_abstract_runme.java
index 1489d92..4230e7b 100644
--- a/Examples/test-suite/java/multiple_inheritance_abstract_runme.java
+++ b/Examples/test-suite/java/multiple_inheritance_abstract_runme.java
@@ -224,6 +224,7 @@
     check(multiple_inheritance_abstract.InputCPtrRefBottom1(b1)!=103+104, "InputCPtrRefBottom1() failed");
     check(multiple_inheritance_abstract.InputCPtrRefBottom2(b2)!=206+205, "InputCPtrRefBottom2() failed");
     check(multiple_inheritance_abstract.InputCPtrRefBottom3(b3)!=307+308+309, "InputCPtrRefBottom3() failed");
+
     // Return pointers
     check(multiple_inheritance_abstract.MakePtrDerived1_CBase1().cbase1y()!=3, "MakePtrDerived1_CBase1 failed");
     check(multiple_inheritance_abstract.MakePtrDerived1_CBase2().cbase2()!=4, "MakePtrDerived1_CBase2 failed");
@@ -242,6 +243,15 @@
     check(multiple_inheritance_abstract.MakeRefDerived3_CBase1().cbase1y()!=7, "MakeRefDerived3_CBase1 failed");
     check(multiple_inheritance_abstract.MakeRefDerived3_CBase2().cbase2()!=8, "MakeRefDerived3_CBase2 failed");
 
+    // Return const pointer references
+    check(multiple_inheritance_abstract.MakeConstPtrRefDerived1_CBase1().cbase1y()!=3, "MakeConstPtrRefDerived1_CBase1 failed");
+    check(multiple_inheritance_abstract.MakeConstPtrRefDerived1_CBase2().cbase2()!=4, "MakeConstPtrRefDerived1_CBase2 failed");
+    check(multiple_inheritance_abstract.MakeConstPtrRefDerived2_CBase1().cbase1y()!=6, "MakeConstPtrRefDerived2_CBase1 failed");
+    check(multiple_inheritance_abstract.MakeConstPtrRefDerived2_ABase1().abase1()!=5, "MakeConstPtrRefDerived2_ABase1 failed");
+    check(multiple_inheritance_abstract.MakeConstPtrRefDerived3_ABase1().abase1()!=9, "MakeConstPtrRefDerived3_ABase1 failed");
+    check(multiple_inheritance_abstract.MakeConstPtrRefDerived3_CBase1().cbase1y()!=7, "MakeConstPtrRefDerived3_CBase1 failed");
+    check(multiple_inheritance_abstract.MakeConstPtrRefDerived3_CBase2().cbase2()!=8, "MakeConstPtrRefDerived3_CBase2 failed");
+
     // Return by value (sliced objects)
     check(multiple_inheritance_abstract.MakeValDerived1_CBase1().cbase1y()!=1, "MakeValDerived1_CBase1 failed");
     check(multiple_inheritance_abstract.MakeValDerived1_CBase2().cbase2()!=2, "MakeValDerived1_CBase2 failed");
diff --git a/Examples/test-suite/java/multiple_inheritance_interfaces_runme.java b/Examples/test-suite/java/multiple_inheritance_interfaces_runme.java
index 3f2b000..df3e217 100644
--- a/Examples/test-suite/java/multiple_inheritance_interfaces_runme.java
+++ b/Examples/test-suite/java/multiple_inheritance_interfaces_runme.java
@@ -46,17 +46,17 @@
     checkBaseAndInterfaces(IC.class, true, "", new String[] {"IA", "IB"});
     checkBaseAndInterfaces(A.class, false, "", new String[] {"IA"});
     checkBaseAndInterfaces(B.class, false, "", new String[] {"IB"});
-    checkBaseAndInterfaces(C.class, false, "", new String[] {"IA", "IB", "IC"});
-    checkBaseAndInterfaces(D.class, false, "", new String[] {"IA", "IB", "IC"});
+    checkBaseAndInterfaces(C.class, false, "", new String[] {"IC", "IA", "IB"});
+    checkBaseAndInterfaces(D.class, false, "", new String[] {"IC", "IA", "IB"});
     checkBaseAndInterfaces(E.class, false, "D", new String[] {});
 
     checkBaseAndInterfaces(IJ.class, true, "", new String[] {});
     checkBaseAndInterfaces(IK.class, true, "", new String[] {"IJ"});
     checkBaseAndInterfaces(IL.class, true, "", new String[] {"IK"});
     checkBaseAndInterfaces(J.class, false, "", new String[] {"IJ"});
-    checkBaseAndInterfaces(K.class, false, "", new String[] {"IJ", "IK"});
-    checkBaseAndInterfaces(L.class, false, "", new String[] {"IJ", "IK", "IL"});
-    checkBaseAndInterfaces(M.class, false, "", new String[] {"IJ", "IK", "IL"});
+    checkBaseAndInterfaces(K.class, false, "", new String[] {"IK", "IJ"});
+    checkBaseAndInterfaces(L.class, false, "", new String[] {"IL", "IK", "IJ"});
+    checkBaseAndInterfaces(M.class, false, "", new String[] {"IL", "IK", "IJ"});
 
     checkBaseAndInterfaces(P.class, false, "", new String[] {});
     checkBaseAndInterfaces(IQ.class, true, "", new String[] {});
@@ -74,5 +74,7 @@
     d.ia(10);
     d.ia("bye");
     d.ia("bye", false);
+
+    UndesirablesSwigImpl.UndesiredStaticMethod(UndesirablesSwigImpl.UndesiredEnum.UndesiredEnum1);
   }
 }
diff --git a/Examples/test-suite/java/multiple_inheritance_nspace_runme.java b/Examples/test-suite/java/multiple_inheritance_nspace_runme.java
index 461c7a1..ed2d337 100644
--- a/Examples/test-suite/java/multiple_inheritance_nspace_runme.java
+++ b/Examples/test-suite/java/multiple_inheritance_nspace_runme.java
@@ -244,6 +244,15 @@
     check(multiple_inheritance_nspace.MakeRefDerived3_CBase1().cbase1y()!=7, "MakeRefDerived3_CBase1 failed");
     check(multiple_inheritance_nspace.MakeRefDerived3_CBase2().cbase2()!=8, "MakeRefDerived3_CBase2 failed");
 
+    // Return const pointer references
+    check(multiple_inheritance_nspace.MakeConstPtrRefDerived1_CBase1().cbase1y()!=3, "MakeConstPtrRefDerived1_CBase1 failed");
+    check(multiple_inheritance_nspace.MakeConstPtrRefDerived1_CBase2().cbase2()!=4, "MakeConstPtrRefDerived1_CBase2 failed");
+    check(multiple_inheritance_nspace.MakeConstPtrRefDerived2_CBase1().cbase1y()!=6, "MakeConstPtrRefDerived2_CBase1 failed");
+    check(multiple_inheritance_nspace.MakeConstPtrRefDerived2_ABase1().abase1()!=5, "MakeConstPtrRefDerived2_ABase1 failed");
+    check(multiple_inheritance_nspace.MakeConstPtrRefDerived3_ABase1().abase1()!=9, "MakeConstPtrRefDerived3_ABase1 failed");
+    check(multiple_inheritance_nspace.MakeConstPtrRefDerived3_CBase1().cbase1y()!=7, "MakeConstPtrRefDerived3_CBase1 failed");
+    check(multiple_inheritance_nspace.MakeConstPtrRefDerived3_CBase2().cbase2()!=8, "MakeConstPtrRefDerived3_CBase2 failed");
+
     // Return by value (sliced objects)
     check(multiple_inheritance_nspace.MakeValDerived1_CBase1().cbase1y()!=1, "MakeValDerived1_CBase1 failed");
     check(multiple_inheritance_nspace.MakeValDerived1_CBase2().cbase2()!=2, "MakeValDerived1_CBase2 failed");
diff --git a/Examples/test-suite/java/multiple_inheritance_overload_runme.java b/Examples/test-suite/java/multiple_inheritance_overload_runme.java
new file mode 100644
index 0000000..e516e77
--- /dev/null
+++ b/Examples/test-suite/java/multiple_inheritance_overload_runme.java
@@ -0,0 +1,65 @@
+import multiple_inheritance_overload.*;
+
+public class multiple_inheritance_overload_runme {
+
+  static {
+    try {
+      System.loadLibrary("multiple_inheritance_overload");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void check(boolean fail, String msg) {
+    if (fail)
+      throw new RuntimeException(msg);
+  }
+
+  public static void main(String argv[]) {
+    int i = 0;
+    Base b1 = new Derived();
+    check(b1.Method(i) != 0, "b1.Method failed");
+    check(b1.MethodForRenaming(i) != 0, "b1.MethodForRenaming failed");
+    check(b1.MethodForRenamingConst(i) != 1, "b1.MethodForRenamingConst failed");
+    check(b1.MethodWarningSuppressed(i) != 0, "b1.MethodWarningSuppressed failed");
+    check(b1.NotVirtualMethod(i) != 0, "b1.NotVirtualMethod failed");
+    check(b1.SimilarOverloadedMethod(i) != 0, "b1.NotVirtualMethod failed");
+
+    Derived d1 = new Derived();
+    check(d1.Method(i) != 0, "d1.Method failed");
+    check(d1.MethodForRenaming(i) != 0, "d1.MethodForRenaming failed");
+    check(d1.MethodForRenamingConst(i) != 1, "d1.MethodForRenamingConst failed");
+    check(d1.MethodWarningSuppressed(i) != 0, "d1.MethodWarningSuppressed failed");
+    check(d1.NotVirtualMethod(i) != 0, "d1.NotVirtualMethod failed");
+    check(d1.SimilarOverloadedMethod(i) != 0, "d1.NotVirtualMethod failed");
+
+    check(d1.AnotherMethod(i) != 0, "d1.AnotherMethod failed");
+
+    Base db1 = BaseSwigImpl.in_out(d1);
+    check(db1.Method(i) != 0, "db1.Method failed");
+    check(db1.MethodForRenaming(i) != 0, "db1.MethodForRenaming failed");
+    check(db1.MethodForRenamingConst(i) != 1, "db1.MethodForRenamingConst failed");
+    check(db1.MethodWarningSuppressed(i) != 0, "db1.MethodWarningSuppressed failed");
+    check(db1.NotVirtualMethod(i) != 0, "db1.NotVirtualMethod failed");
+    check(db1.SimilarOverloadedMethod(i) != 0, "db1.NotVirtualMethod failed");
+
+    MoreDerived m1 = new MoreDerived();
+    check(m1.Method(i) != 0, "m1.Method failed");
+    check(m1.MethodForRenaming(i) != 0, "m1.MethodForRenaming failed");
+    check(m1.MethodForRenamingConst(i) != 1, "m1.MethodForRenamingConst failed");
+    check(m1.MethodWarningSuppressed(i) != 0, "m1.MethodWarningSuppressed failed");
+    check(m1.NotVirtualMethod(i) != 0, "m1.NotVirtualMethod failed");
+    check(m1.SimilarOverloadedMethod(i) != 0, "m1.NotVirtualMethod failed");
+
+    check(m1.AnotherMethod(i) != 0, "m1.AnotherMethod failed");
+
+    Base mb2 = BaseSwigImpl.in_out(m1);
+    check(mb2.Method(i) != 0, "mb2.Method failed");
+    check(mb2.MethodForRenaming(i) != 0, "mb2.MethodForRenaming failed");
+    check(mb2.MethodForRenamingConst(i) != 1, "mb2.MethodForRenamingConst failed");
+    check(mb2.MethodWarningSuppressed(i) != 0, "mb2.MethodWarningSuppressed failed");
+    check(mb2.NotVirtualMethod(i) != 0, "mb2.NotVirtualMethod failed");
+    check(mb2.SimilarOverloadedMethod(i) != 0, "mb2.NotVirtualMethod failed");
+  }
+}
diff --git a/Examples/test-suite/java/multiple_inheritance_shared_ptr_runme.java b/Examples/test-suite/java/multiple_inheritance_shared_ptr_runme.java
index 6472a91..9109130 100644
--- a/Examples/test-suite/java/multiple_inheritance_shared_ptr_runme.java
+++ b/Examples/test-suite/java/multiple_inheritance_shared_ptr_runme.java
@@ -309,6 +309,15 @@
     check(multiple_inheritance_shared_ptr.MakeRefDerived3_CBase1().cbase1y()!=7, "MakeRefDerived3_CBase1 failed");
     check(multiple_inheritance_shared_ptr.MakeRefDerived3_CBase2().cbase2()!=8, "MakeRefDerived3_CBase2 failed");
 
+    // Return const pointer references
+    check(multiple_inheritance_shared_ptr.MakeConstPtrRefDerived1_CBase1().cbase1y()!=3, "MakeConstPtrRefDerived1_CBase1 failed");
+    check(multiple_inheritance_shared_ptr.MakeConstPtrRefDerived1_CBase2().cbase2()!=4, "MakeConstPtrRefDerived1_CBase2 failed");
+    check(multiple_inheritance_shared_ptr.MakeConstPtrRefDerived2_CBase1().cbase1y()!=6, "MakeConstPtrRefDerived2_CBase1 failed");
+    check(multiple_inheritance_shared_ptr.MakeConstPtrRefDerived2_ABase1().abase1()!=5, "MakeConstPtrRefDerived2_ABase1 failed");
+    check(multiple_inheritance_shared_ptr.MakeConstPtrRefDerived3_ABase1().abase1()!=9, "MakeConstPtrRefDerived3_ABase1 failed");
+    check(multiple_inheritance_shared_ptr.MakeConstPtrRefDerived3_CBase1().cbase1y()!=7, "MakeConstPtrRefDerived3_CBase1 failed");
+    check(multiple_inheritance_shared_ptr.MakeConstPtrRefDerived3_CBase2().cbase2()!=8, "MakeConstPtrRefDerived3_CBase2 failed");
+
     // Return by value (sliced objects)
     check(multiple_inheritance_shared_ptr.MakeValDerived1_CBase1().cbase1y()!=1, "MakeValDerived1_CBase1 failed");
     check(multiple_inheritance_shared_ptr.MakeValDerived1_CBase2().cbase2()!=2, "MakeValDerived1_CBase2 failed");
diff --git a/Examples/test-suite/java/private_assign_runme.java b/Examples/test-suite/java/private_assign_runme.java
new file mode 100644
index 0000000..f214f98
--- /dev/null
+++ b/Examples/test-suite/java/private_assign_runme.java
@@ -0,0 +1,20 @@
+import private_assign.*;
+
+public class private_assign_runme {
+
+  static {
+    try {
+	System.loadLibrary("private_assign");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    Three three = new Three();
+    TwoNotAssignableCopyable tn = three.getTwoNot();
+    TwoIsAssignableCopyable ti = three.getTwoIs();
+    three.setTwoIs(new TwoIsAssignableCopyable());
+  }
+}
diff --git a/Examples/test-suite/java/rname_runme.java b/Examples/test-suite/java/rname_runme.java
index dac0a1e..4af6581 100644
--- a/Examples/test-suite/java/rname_runme.java
+++ b/Examples/test-suite/java/rname_runme.java
@@ -25,7 +25,7 @@
     bar.foo_u((long)10);
 
     RenamedBase base = new RenamedBase();
-    base.fn(base, base, base);
+    base.fn1(base, base, base);
     if (!base.newname(10.0).equals("Base"))
       throw new RuntimeException("base.newname");
 
diff --git a/Examples/test-suite/java/special_variable_macros_runme.java b/Examples/test-suite/java/special_variable_macros_runme.java
index 1cd50e9..c432c63 100644
--- a/Examples/test-suite/java/special_variable_macros_runme.java
+++ b/Examples/test-suite/java/special_variable_macros_runme.java
@@ -30,5 +30,9 @@
       throw new RuntimeException("test failed");
     NewName newName = NewName.factory("factoryname");
     name = newName.getStoredName();
+    if (!special_variable_macros.makeStringInt("stringint", 999).equals("stringint"))
+      throw new RuntimeException("test failed");
+    if (!special_variable_macros.provideStringInt(999).equals("1000"))
+      throw new RuntimeException("test failed");
   }
 }
diff --git a/Examples/test-suite/java/template_construct_runme.java b/Examples/test-suite/java/template_construct_runme.java
new file mode 100644
index 0000000..c4e8e35
--- /dev/null
+++ b/Examples/test-suite/java/template_construct_runme.java
@@ -0,0 +1,24 @@
+
+import template_construct.*;
+
+public class template_construct_runme {
+
+  static {
+    try {
+	System.loadLibrary("template_construct");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    Foo_int fi = new Foo_int(0);
+    fi.delete();
+    Foo_short fs = new Foo_short();
+    fs.delete();
+    fs = new Foo_short();
+    fs.delete();
+  }
+}
+
diff --git a/Examples/test-suite/java/template_function_parm_runme.java b/Examples/test-suite/java/template_function_parm_runme.java
new file mode 100644
index 0000000..3c8f3d1
--- /dev/null
+++ b/Examples/test-suite/java/template_function_parm_runme.java
@@ -0,0 +1,25 @@
+import template_function_parm.*;
+
+public class template_function_parm_runme {
+
+  static {
+    try {
+      System.loadLibrary("template_function_parm");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    VectorInt vi = new VectorInt();
+    vi.add(10);
+    vi.add(20);
+    vi.add(30);
+
+    MyC myc = new MyC();
+    int sum = myc.take_function(template_function_parmConstants.accumulate_integers, vi);
+    if (sum != 60)
+      throw new RuntimeException("Expected sum of 60, got " + sum);
+  }
+}
diff --git a/Examples/test-suite/java/template_nested_flat_runme.java b/Examples/test-suite/java/template_nested_flat_runme.java
new file mode 100644
index 0000000..023c185
--- /dev/null
+++ b/Examples/test-suite/java/template_nested_flat_runme.java
@@ -0,0 +1,35 @@
+
+import template_nested_flat.*;
+
+public class template_nested_flat_runme {
+
+  static {
+    try {
+      System.loadLibrary("template_nested_flat");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    new T_NormalTemplateNormalClass().tmethod(new NormalClass());
+    new OuterClass().T_OuterTMethodNormalClass(new NormalClass());
+
+    TemplateFuncs tf = new TemplateFuncs();
+    if (tf.T_TemplateFuncs1Int(-10) != -10)
+      throw new RuntimeException("it failed");
+    if (tf.T_TemplateFuncs2Double(-12.3) != -12.3)
+      throw new RuntimeException("it failed");
+
+    T_NestedOuterTemplateDouble tn = new T_NestedOuterTemplateDouble();
+    if (tn.hohum(-12.3) != -12.3)
+      throw new RuntimeException("it failed");
+    T_OuterClassInner1Int inner1 = new OuterClass().useInner1(new T_OuterClassInner1Int());
+    T_OuterClassInner2NormalClass inner2 = new T_OuterClassInner2NormalClass();
+    inner2.setEmbeddedVar(2);
+    T_OuterClassInner2NormalClass inner22 = new OuterClass().useInner2Again(inner2);
+    T_OuterClassInner1Double inner3 = new T_OuterClassInner1Double();
+  }
+}
+
diff --git a/Examples/test-suite/java/template_partial_specialization_more_runme.java b/Examples/test-suite/java/template_partial_specialization_more_runme.java
new file mode 100644
index 0000000..c990a1b
--- /dev/null
+++ b/Examples/test-suite/java/template_partial_specialization_more_runme.java
@@ -0,0 +1,49 @@
+import template_partial_specialization_more.*;
+
+public class template_partial_specialization_more_runme {
+
+  static {
+    try {
+	System.loadLibrary("template_partial_specialization_more");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    // (1)
+    VectInt vi = new VectInt();
+    int num = new FooVectIntDouble().partially_specialized(222);
+    new FooShortPtrDouble().pointer_specialize((short)0);
+    vi = new FooVectVectInt().partially_specialized(vi);
+
+    // (2)
+    new HeyInts().special_hey();
+
+    // (3)
+    new XX1().special1();
+    new XX2().special2();
+    new XX3().special3();
+
+    // (4)
+    new PartiallerPrimary().primary((short)0, (short)0);
+    new PartiallerSpecial().special(new PlainStruct(), 999, true);
+
+    // (5)
+    new LystDouble().primary(11.1, new AllocatorDouble());
+    new LystShort().primary((short)0, new AllocatorShort());
+    new LystPlainStructPtr().specialized1(new PlainStruct(), new AllocatorPlainStructPtr());
+    new LystDoublePtrPtr().specialized2(22.2, (SWIGTYPE_p_p_double)null);
+    new LystConstIntRef().specialized3(100);
+    new LystConstStringRef().specialized3("hello");
+
+    // (6)
+    SpecDoubleInt d = new SpecDoubleInt();
+    SpecStringInt i = new SpecStringInt();
+    d.spec_specialized(12.3);
+    i.spec_specialized("hi");
+    template_partial_specialization_more.UseSpec1(d, d);
+    template_partial_specialization_more.UseSpec2(i, i);
+  }
+}
diff --git a/Examples/test-suite/java/template_partial_specialization_typedef_runme.java b/Examples/test-suite/java/template_partial_specialization_typedef_runme.java
index 04653cd..008367c 100644
--- a/Examples/test-suite/java/template_partial_specialization_typedef_runme.java
+++ b/Examples/test-suite/java/template_partial_specialization_typedef_runme.java
@@ -12,12 +12,15 @@
   }
 
   public static void main(String argv[]) {
+    double dub = 11.1;
+    Concrete concrete = new Concrete();
+
     // One parameter tests
     new A().a();
-    new B().b();
-    new C().c();
-    new D().d();
-    new E().e();
+    new B().b(); new B().bb(dub);
+    new C().c(); new C().cc(dub);
+    new D().d(); new D().dd(dub);
+    new E().e(); new E().ee(dub);
 
     new F().f();
     new G().g();
@@ -28,10 +31,10 @@
     new M().m();
     new N().n();
 
-    new BB().b();
-    new BBB().b();
-    new BBBB().b();
-    new BBBBB().b();
+    new BB().b(); new BB().bb(true);
+    new BBB().b(); new BBB().bb('A');
+    new BBBB().b(); new BBBB().bb((short)12);
+    new BBBBB().b(); new BBBBB().bb(123);
 
     new B1().b();
     new B2().b();
@@ -40,18 +43,18 @@
 
     // Two parameter tests
     new A_().a();
-    new B_().b();
-    new C_().c();
-    new D_().d();
+    new B_().b(); new B_().bbb(dub);
+    new C_().c(); new C_().ccc(dub);
+    new D_().d(); new D_().ddd(123);
     new E_().e();
     new F_().f();
     new G_().g();
 
-    new C1_().c();
-    new C2_().c();
-    new C3_().c();
-    new C4_().c();
-    new B1_().b();
+    new C1_().c(); new C1_().ccc(concrete);
+    new C2_().c(); new C2_().ccc(concrete);
+    new C3_().c(); new C3_().ccc(concrete);
+    new C4_().c(); new C4_().ccc(concrete);
+    new B1_().b(); new B1_().bbb(concrete);
     new E1_().e();
     new E2_().e();
   }
diff --git a/Examples/test-suite/java/template_specialization_using_declaration_runme.java b/Examples/test-suite/java/template_specialization_using_declaration_runme.java
new file mode 100644
index 0000000..133771b
--- /dev/null
+++ b/Examples/test-suite/java/template_specialization_using_declaration_runme.java
@@ -0,0 +1,45 @@
+import template_specialization_using_declaration.*;
+
+public class template_specialization_using_declaration_runme {
+
+  static {
+    try {
+	System.loadLibrary("template_specialization_using_declaration");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+
+    ConcreteClass cc = new ConcreteClass(11);
+
+    // Base template tests
+    BaseTemplateString bs = new BaseTemplateString();
+    bs.method_primary("hi");
+
+    BaseTemplateConcreteClass cs = new BaseTemplateConcreteClass();
+    cs.method_specialization(cc);
+
+    BaseTemplateInt bi = new BaseTemplateInt();
+    bi.method_partial_specialization(22);
+
+
+    // Derived template tests
+    DerivedTemplateString ds = new DerivedTemplateString();
+    ds.method_primary("hi");
+    ds.method_primary_derived("hi");
+    ds.method_primary_hidden("hi");
+
+    DerivedTemplateConcreteClass dc = new DerivedTemplateConcreteClass();
+    dc.method_specialization(cc);
+    dc.method_specialization_derived(cc);
+    dc.method_specialization_hidden(cc);
+
+    DerivedTemplateInt di = new DerivedTemplateInt();
+    di.method_partial_specialization(22);
+    di.method_partial_specialization_derived(22);
+    di.method_partial_specialization_hidden(22);
+  }
+}
diff --git a/Examples/test-suite/java/template_template_parameters_runme.java b/Examples/test-suite/java/template_template_parameters_runme.java
index 42135b9..244e129 100644
--- a/Examples/test-suite/java/template_template_parameters_runme.java
+++ b/Examples/test-suite/java/template_template_parameters_runme.java
@@ -14,15 +14,37 @@
   }
 
   public static void main(String argv[]) {
+    // Test part 1
     ListFastBool listBool = new ListFastBool();
     listBool.setItem(true);
+    boolean x_boolean = listBool.getAllotype();
     if (listBool.getItem() != true)
       throw new RuntimeException("Failed");
 
     ListDefaultDouble listDouble = new ListDefaultDouble();
     listDouble.setItem(10.2);
+    double x_double = listDouble.getAllotype();
     if (listDouble.getItem() != 10.2)
       throw new RuntimeException("Failed");
+
+    // Test part 2
+    FloatTestStruct floatTestStruct = new FloatTestStruct();
+    FloatContainer2 floatContainer2 = floatTestStruct.getX();
+    floatContainer2.setX(8.1f);
+    IntTestStruct intTestStruct = new IntTestStruct();
+    IntContainer1 intContainer1 = intTestStruct.getX();
+    intContainer1.setX(91);
+    if (intContainer1.getX() != 91)
+      throw new RuntimeException("Failed");
+    if (intTestStruct.getX().getX() != 91)
+      throw new RuntimeException("Failed");
+    IntTestStruct intTestStructReturned = template_template_parameters.TestStructContainer1Method(intTestStruct);
+    if (intTestStructReturned.getX().getX() != 101)
+      throw new RuntimeException("Failed");
+
+    // Test part 3
+    MyFootInt99 mfi99 = new MyFootInt99();
+    mfi99.OperatorPlusEquals(mfi99);
   }
 }
 
diff --git a/Examples/test-suite/java/template_template_template_parameters_runme.java b/Examples/test-suite/java/template_template_template_parameters_runme.java
new file mode 100644
index 0000000..519a9e0
--- /dev/null
+++ b/Examples/test-suite/java/template_template_template_parameters_runme.java
@@ -0,0 +1,36 @@
+
+
+import template_template_template_parameters.*;
+
+public class template_template_template_parameters_runme {
+
+  static {
+    try {
+	System.loadLibrary("template_template_template_parameters");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    CustomAttrs custom_attrs = new CustomAttrs();
+    AC ac = new AC();
+    BAC bac = new BAC();
+    CBAC cbac = new CBAC();
+    DBAC dbac = new DBAC();
+
+    custom_attrs = ac.getAttributes();
+    custom_attrs = bac.getAttributes();
+    custom_attrs = cbac.getAttributes();
+    custom_attrs = dbac.getAttributes();
+
+    bac.BMethod(custom_attrs, ac);
+    cbac.BMethod(custom_attrs, ac);
+    dbac.BMethod(custom_attrs, ac);
+
+    cbac.CMethod(custom_attrs, bac);
+    dbac.DMethod(custom_attrs, bac);
+  }
+}
+
diff --git a/Examples/test-suite/java/template_templated_constructors_runme.java b/Examples/test-suite/java/template_templated_constructors_runme.java
index cd3f31d..ec20b94 100644
--- a/Examples/test-suite/java/template_templated_constructors_runme.java
+++ b/Examples/test-suite/java/template_templated_constructors_runme.java
@@ -21,6 +21,16 @@
     TClass2Int tc2a = new TClass2Int();
     TClass2Int tc2b = new TClass2Int(123.4);
 
+    DoublePair double_pair = new DoublePair(1.1, 2.2);
+    ShortPair short_pair = new ShortPair((short)0, (short)1);
+    StringPair string_pair = new StringPair("10", "11");
+    IntPair ip1 = new IntPair();
+    IntPair ip2 = new IntPair(20, 21);
+    IntPair ip3 = new IntPair(ip1);
+    IntPair ip4 = new IntPair(short_pair);
+    // These next two use IntPair constructors, unlike Python which requires factory function calls
+    IntPair ip5 = new IntPair(double_pair);
+    IntPair ip6 = new IntPair(string_pair);
   }
 }
 
diff --git a/Examples/test-suite/java/template_type_collapse_runme.java b/Examples/test-suite/java/template_type_collapse_runme.java
new file mode 100644
index 0000000..11c6c8c
--- /dev/null
+++ b/Examples/test-suite/java/template_type_collapse_runme.java
@@ -0,0 +1,26 @@
+import template_type_collapse.*;
+
+public class template_type_collapse_runme {
+
+  static {
+    try {
+	System.loadLibrary("template_type_collapse");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    int i = 1234;
+    ConsterInt ci = new DerivedConsterInt();
+    ci.cccc1(i);
+    ci.cccc2(i);
+    ci.cccc3(i);
+    ci.cccc4(i);
+
+    DerivedConsterInt dci = new DerivedConsterInt();
+    dci.dddd(i);
+  }
+}
+
diff --git a/Examples/test-suite/java/template_using_member_default_arg_runme.java b/Examples/test-suite/java/template_using_member_default_arg_runme.java
new file mode 100644
index 0000000..5939158
--- /dev/null
+++ b/Examples/test-suite/java/template_using_member_default_arg_runme.java
@@ -0,0 +1,22 @@
+import template_using_member_default_arg.*;
+
+public class template_using_member_default_arg_runme {
+
+  static {
+    try {
+	System.loadLibrary("template_using_member_default_arg");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[]) {
+    ThingADerivedInt a = new ThingADerivedInt();
+    a.describeA();
+    ThingBDerivedInt b = new ThingBDerivedInt();
+    b.describeB();
+  }
+}
+
+
diff --git a/Examples/test-suite/java/typemap_out_optimal_runme.java b/Examples/test-suite/java/typemap_out_optimal_runme.java
index 8a87f0c..254b0c6 100644
--- a/Examples/test-suite/java/typemap_out_optimal_runme.java
+++ b/Examples/test-suite/java/typemap_out_optimal_runme.java
@@ -12,10 +12,16 @@
     }
   }
 
-  public static XX x = null;
   public static void main(String argv[]) {
-    XX.setDebug(false);
-    x = XX.create();
+    XX.setTrace(false);
+    {
+      XX x = XX.create();
+      x.delete();
+    }
+    {
+      XX x = XX.createConst();
+      x.delete();
+    }
   }
 }
 
diff --git a/Examples/test-suite/java/using_member_multiple_inherit_runme.java b/Examples/test-suite/java/using_member_multiple_inherit_runme.java
new file mode 100644
index 0000000..769ba6c
--- /dev/null
+++ b/Examples/test-suite/java/using_member_multiple_inherit_runme.java
@@ -0,0 +1,46 @@
+import using_member_multiple_inherit.*;
+
+public class using_member_multiple_inherit_runme {
+  static {
+    try {
+        System.loadLibrary("using_member_multiple_inherit");
+    } catch (UnsatisfiedLinkError e) {
+      System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
+      System.exit(1);
+    }
+  }
+
+  public static void main(String argv[])
+  {
+    // Single inheritance three deep, only using declarations
+    Susing3 s3 = new Susing3();
+    s3.usingmethod(11);
+
+    // Single inheritance three deep, overload using and methods
+    Using3 u3 = new Using3();
+    u3.usingmethod(11);
+    u3.usingmethod(11, 22);
+    u3.usingmethod(11, 22, 33);
+
+    Musing3 m3 = new Musing3();
+    m3.usingmethod(11);
+    m3.usingmethod(11, 22);
+    m3.usingmethod(11, 22, 33);
+
+    Dusing3 d3 = new Dusing3();
+    d3.usingmethod(11);
+    d3.usingmethod(11, 22);
+
+    // Multiple inheritance, multiple using declarations
+    MultMiddleA ma = new MultMiddleA();
+    ma.multmethod(123);
+    ma.multmethod("hi");
+    ma.multmethod(123, 234);
+
+    MultBottomB mb = new MultBottomB();
+    mb.multmethod(123);
+    mb.multmethod("hi");
+    mb.multmethod(123, 234);
+    mb.multmethod(123, 345, 567);
+  }
+}
diff --git a/Examples/test-suite/java_director.i b/Examples/test-suite/java_director.i
index 6b2cb6d..adfffaa 100644
--- a/Examples/test-suite/java_director.i
+++ b/Examples/test-suite/java_director.i
@@ -7,7 +7,7 @@
 %module(directors="1") java_director
 
 %typemap(javafinalize) SWIGTYPE %{
-  @SuppressWarnings("deprecation")
+  @SuppressWarnings({"deprecation", "removal"})
   protected void finalize() {
 //    System.out.println("Finalizing " + this);
     delete();
diff --git a/Examples/test-suite/java_director_exception_feature.i b/Examples/test-suite/java_director_exception_feature.i
index 7978ac2..dfc85de 100644
--- a/Examples/test-suite/java_director_exception_feature.i
+++ b/Examples/test-suite/java_director_exception_feature.i
@@ -139,7 +139,7 @@
 %rename(MyJavaException2) MyNS::Exception2;
 %rename(MyJavaUnexpected) MyNS::Unexpected;
 
-%typemap(javabase) ::MyNS::Exception1,::MyNS::Exception2,::MyNS::Unexpected "java.lang.Exception";
+%typemap(javabase) ::MyNS::Exception1,::MyNS::Exception2,::MyNS::Unexpected "java.lang.Exception"
 %rename(getMessage) what() const;  // Rename all what() methods
 
 namespace MyNS {
diff --git a/Examples/test-suite/java_director_exception_feature_nspace.i b/Examples/test-suite/java_director_exception_feature_nspace.i
index b52c1ac..f2f7327 100644
--- a/Examples/test-suite/java_director_exception_feature_nspace.i
+++ b/Examples/test-suite/java_director_exception_feature_nspace.i
@@ -146,7 +146,7 @@
 %rename(MyJavaException2) MyNS::Exception2;
 %rename(MyJavaUnexpected) MyNS::Unexpected;
 
-%typemap(javabase) ::MyNS::Exception1,::MyNS::Exception2,::MyNS::Unexpected "java.lang.Exception";
+%typemap(javabase) ::MyNS::Exception1,::MyNS::Exception2,::MyNS::Unexpected "java.lang.Exception"
 %rename(getMessage) what() const;  // Rename all what() methods
 
 namespace MyNS {
diff --git a/Examples/test-suite/java_throws.i b/Examples/test-suite/java_throws.i
index 6cd47b4..7463fee 100644
--- a/Examples/test-suite/java_throws.i
+++ b/Examples/test-suite/java_throws.i
@@ -88,7 +88,7 @@
 %}
 
 // except feature (%javaexception) specifying a checked exception class for the throws clause
-%typemap(javabase) MyException "Throwable";
+%typemap(javabase) MyException "Throwable"
 %typemap(javacode) MyException %{
   public static final long serialVersionUID = 0x52151000; // Suppress ecj warning
 %}
@@ -183,7 +183,7 @@
 
 // Need to handle the checked exception in NoExceptTest.delete()
 %typemap(javafinalize) SWIGTYPE %{
-  @SuppressWarnings("deprecation")
+  @SuppressWarnings({"deprecation", "removal"})
   protected void finalize() {
     try {
       delete();
@@ -193,6 +193,37 @@
   }
 %}
 
+%typemap(javabody) SWIGTYPE %{
+  private transient long swigCPtr;
+  protected transient boolean swigCMemOwn;
+
+  protected $javaclassname(long cPtr, boolean cMemoryOwn) {
+    swigCMemOwn = cMemoryOwn;
+    swigCPtr = cPtr;
+  }
+
+  protected static long getCPtr($javaclassname obj) {
+    return (obj == null) ? 0 : obj.swigCPtr;
+  }
+
+  protected static long swigRelease($javaclassname obj) {
+    long ptr = 0;
+    if (obj != null) {
+      if (!obj.swigCMemOwn)
+        throw new RuntimeException("Cannot release ownership as memory is not owned");
+      ptr = obj.swigCPtr;
+      obj.swigCMemOwn = false;
+      try {
+        obj.delete();
+      } catch (MyException e) {
+        throw new RuntimeException(e);
+      }
+    }
+    return ptr;
+  }
+%}
+
+
 %inline %{
 struct NoExceptTest {
   unsigned int noExceptionPlease() { return 123; }
diff --git a/Examples/test-suite/java_typemaps_proxy.i b/Examples/test-suite/java_typemaps_proxy.i
index 3e9b183..7e90b5a 100644
--- a/Examples/test-suite/java_typemaps_proxy.i
+++ b/Examples/test-suite/java_typemaps_proxy.i
@@ -3,21 +3,21 @@
 %module java_typemaps_proxy
 
 
-%typemap(javaimports) SWIGTYPE "import java.math.*;";
+%typemap(javaimports) SWIGTYPE "import java.math.*;"
 %typemap(javacode) NS::Farewell %{
   public void saybye(BigDecimal num_times) {
     // BigDecimal requires the java.math library
   }
 %}
-%typemap(javaclassmodifiers) NS::Farewell "public final class";
+%typemap(javaclassmodifiers) NS::Farewell "public final class"
 
 %typemap(javaimports) NS::Greeting %{
 import java.util.*; // for EventListener
 import java.lang.*; // for Exception
 %};
 
-%typemap(javabase) NS::Greeting "Exception";
-%typemap(javainterfaces) NS::Greeting "EventListener";
+%typemap(javabase) NS::Greeting "Exception"
+%typemap(javainterfaces) NS::Greeting "EventListener"
 %typemap(javacode) NS::Greeting %{
   public static final long serialVersionUID = 0x52151000; // Suppress ecj warning
   // Pure Java code generated using %typemap(javacode) 
@@ -60,7 +60,7 @@
 %}
 
 // get rid of the finalize method for NS::Farewell
-%typemap(javafinalize) NS::Farewell "";
+%typemap(javafinalize) NS::Farewell ""
 
 // Test typemaps are being found for templated classes
 %typemap(javacode) NS::Adieu<int**> %{
@@ -89,7 +89,7 @@
 %template(AdieuIntPtrPtr) NS::Adieu<int**>;
 
 // Check the premature garbage collection prevention parameter can be turned off
-%typemap(jtype, nopgcpp="1") Without * "long";
+%typemap(jtype, nopgcpp="1") Without * "long"
 %pragma(java) jniclassclassmodifiers="public class"
 
 %inline %{
@@ -109,7 +109,7 @@
 void global_method_with(With *p) {}
 %}
 
-%typemap(jtype, nopgcpp="1") const ConstWithout * "long";
+%typemap(jtype, nopgcpp="1") const ConstWithout * "long"
 %inline %{
 class ConstWithout {
 public:
@@ -119,11 +119,26 @@
   void const_member_method(const ConstWithout *p) const {}
   const ConstWithout * const_var;
   const ConstWithout * const var_const;
-private:
-  ConstWithout& operator=(const ConstWithout &);
 };
 const ConstWithout * global_constwithout = 0;
 void global_method_constwithout(const ConstWithout *p) {}
 %}
 
 
+// $imfuncname substitution
+%typemap(javaout) int imfuncname_test {
+    return $moduleJNI.$imfuncname(swigCPtr, this) + 123;
+  }
+%typemap(javaout) int imfuncname_static_test {
+    return $moduleJNI.$imfuncname() + 234;
+  }
+%typemap(javaout) int imfuncname_global_test {
+    return $moduleJNI.$imfuncname() + 345;
+  }
+%inline %{
+struct ProxyA {
+  int imfuncname_test() { return 0; }
+  static int imfuncname_static_test() { return 0; }
+};
+int imfuncname_global_test() { return 0; }
+%}
diff --git a/Examples/test-suite/java_typemaps_typewrapper.i b/Examples/test-suite/java_typemaps_typewrapper.i
index b7bf847..d3ee543 100644
--- a/Examples/test-suite/java_typemaps_typewrapper.i
+++ b/Examples/test-suite/java_typemaps_typewrapper.i
@@ -3,7 +3,7 @@
 %module java_typemaps_typewrapper
 
 
-%typemap(javaimports) SWIGTYPE * "import java.math.*;";
+%typemap(javaimports) SWIGTYPE * "import java.math.*;"
 %typemap(javacode) Farewell * %{
   public static $javaclassname CreateNullPointer() {
     return new $javaclassname();
@@ -12,15 +12,15 @@
     // BigDecimal requires the java.math library
   }
 %}
-%typemap(javaclassmodifiers) Farewell * "public final class";
+%typemap(javaclassmodifiers) Farewell * "public final class"
 
 %typemap(javaimports) Greeting * %{
 import java.util.*; // for EventListener
 import java.lang.*; // for Exception
 %};
 
-%typemap(javabase) Greeting * "Exception";
-%typemap(javainterfaces) Greeting * "EventListener";
+%typemap(javabase) Greeting * "Exception"
+%typemap(javainterfaces) Greeting * "EventListener"
 %typemap(javacode) Greeting * %{
   public static final long serialVersionUID = 0x52151000; // Suppress ecj warning
   // Pure Java code generated using %typemap(javacode) 
diff --git a/Examples/test-suite/javascript/Makefile.in b/Examples/test-suite/javascript/Makefile.in
index 8127415..febff16 100644
--- a/Examples/test-suite/javascript/Makefile.in
+++ b/Examples/test-suite/javascript/Makefile.in
@@ -8,18 +8,49 @@
 SCRIPTSUFFIX = _runme.js
 OBJEXT = @OBJEXT@
 SO = @SO@
+GYP_CXXFLAGS = @BOOST_CPPFLAGS@ @PLATCXXFLAGS@ -I$(shell npm config get prefix)/lib/node_modules/node-addon-api
 
+HAVE_CXX11   = @HAVE_CXX11@
+HAVE_CXX14   = @HAVE_CXX14@
+HAVE_CXX17   = @HAVE_CXX17@
+HAVE_CXX20   = @HAVE_CXX20@
 srcdir       = @srcdir@
 top_srcdir   = @top_srcdir@
 top_builddir = @top_builddir@
 
+CPP_TEST_CASES += \
+	iadd \
+	inplaceadd \
+	input \
+	javascript_lib_arrays \
+	li_factory \
+	li_std_containers_int \
+	li_std_map_member
+
+# napi fails
+FAILING_CPP_TESTS += \
+	smart_pointer_static \
+
 SWIGEXE   = $(top_builddir)/swig
 SWIG_LIB_DIR = $(top_srcdir)/Lib
 
 ifneq (, $(ENGINE))
-	JSENGINE=$(ENGINE)
+    JSENGINE=$(ENGINE)
 else
-	JSENGINE=node
+ifneq (, $(NODEJS))
+    JSENGINE=node
+else
+ifneq (, @JSCENABLED@)
+    JSENGINE=jsc
+else
+ifneq (, @JSV8ENABLED@)
+    JSENGINE=v8
+else
+    # Shouldn't happen, but avoid empty value if it does.
+    JSENGINE=node
+endif
+endif
+endif
 endif
 
 ifneq (, $(V8_VERSION))
@@ -39,45 +70,61 @@
 	  echo "$(ACTION)ing $(LANGUAGE) ($(JSENGINE)) testcase $*" ;     \
 	fi;
 
-ifeq (node,$(JSENGINE))
+SWIGOPT += -$(JSENGINE)
 
-  SWIGOPT += -v8 -DBUILDING_NODE_EXTENSION=1
-
+ifeq ($(JSENGINE), $(filter $(JSENGINE), node napi))
+  SWIGOPT += -DBUILDING_NODE_EXTENSION=1
+  
   # shut up some warnings
-  # contract macro has an empty 'else' at the end...
-  aggregate.cpptest: GYP_CFLAGS = \"-Wno-empty-body\"
-  contract.cpptest: GYP_CFLAGS = \"-Wno-empty-body\"
 
   # dunno... ignoring generously
   apply_signed_char.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\"
   constant_pointers.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\"
+  cpp11_ref_qualifiers.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\"
+  director_basic.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\"
   enum_thorough.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\"
+  member_funcptr_galore.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\"
+  director_unwrap_result.cpptest: GYP_CFLAGS = \"-Wno-ignored-qualifiers\"
+
+	# Run with asan:
+	# ASAN=1 ENGINE=napi make <test_name>.cpptest
+	#
+	ifneq (, $(ASAN))
+		GYP_CFLAGS += \"-fsanitize=address\"
+		GYP_OPTS = --debug
+		ASAN_PRELOAD = $(shell $(CC) -print-file-name=libasan.so)
+		LSAN_OPTIONS = suppressions=$(srcdir)/node_template/napi-leaks-suppression.txt
+		BUILD = Debug
+	else
+		BUILD = Release
+	endif
 
 	setup_node = \
 		test -d $* || mkdir $* && \
-		sed -e 's|$$testcase|$*|g; s|$$cflags|$(GYP_CFLAGS)|g; s|$$srcdir|$(srcdir)|g' \
+		sed -e 's|$$testcase|$*|g; s|$$cflags|$(GYP_CFLAGS)|g; s|$$cxxflags|"$(GYP_CXXFLAGS)"|g; s|$$srcdir|$(srcdir)|g' \
 			$(srcdir)/node_template/binding.gyp.in > $*/binding.gyp && \
-		sed -e 's|$$testcase|$*|g;' \
+		sed -e 's|$$testcase|$*|g; s|$$build|$(BUILD)|g;' \
 			$(srcdir)/node_template/index.js.in > $*/index.js
-
+		
 	# Note: we need to use swig in C parse mode, but make node-gyp believe it is c++ (via file extension)
 	swig_and_compile_c = \
 		$(setup_node) && \
 		$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' \
 		SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
 		SWIGOPT='-javascript $(SWIGOPT) -o $*_wrap.cxx $(srcdir)/../$*.i' swiginvoke && \
-		MAKEFLAGS= $(COMPILETOOL) $(NODEGYP) --loglevel=silent --directory $* configure build 1>>/dev/null
+		MAKEFLAGS= $(COMPILETOOL) $(NODEGYP) --loglevel=silent --directory $* configure $(GYP_OPTS) build 1>>/dev/null
 
 	swig_and_compile_cpp = \
 		$(setup_node) && \
 		$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' \
 		SWIG_LIB_DIR='$(SWIG_LIB_DIR)' SWIGEXE='$(SWIGEXE)' \
 		SWIGOPT='-c++ -javascript $(SWIGOPT) $(srcdir)/../$*.i' swiginvoke && \
-		MAKEFLAGS= $(COMPILETOOL) $(NODEGYP) --loglevel=silent --directory $* configure build 1>>/dev/null
+		MAKEFLAGS= $(COMPILETOOL) $(NODEGYP) --loglevel=silent --directory $* configure $(GYP_OPTS) build 1>>/dev/null
 
 	run_testcase = \
 		if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \
-			env NODE_PATH=$$PWD:$(srcdir) $(RUNTOOL) $(NODEJS) $(srcdir)/$*$(SCRIPTSUFFIX); \
+			env NODE_PATH=$$PWD:$(srcdir) LD_PRELOAD=$(ASAN_PRELOAD) LSAN_OPTIONS=$(LSAN_OPTIONS) \
+				$(RUNTOOL) $(NODEJS) $(srcdir)/$*$(SCRIPTSUFFIX); \
 		fi
 
 
@@ -96,8 +143,6 @@
 
 else
 
-  SWIGOPT += -$(JSENGINE)
-
 	run_testcase = \
 		if [ -f $(srcdir)/$*$(SCRIPTSUFFIX) ]; then \
 		  $(RUNTOOL) $(top_builddir)/Tools/javascript/javascript -$(JSENGINE) $(srcdir)/$*$(SCRIPTSUFFIX); \
@@ -131,6 +176,7 @@
 		rm -f imports_a$${ext} imports_b$${ext}; \
 		rm -f import_stl_a$${ext} import_stl_b$${ext}; \
 		rm -f mod_a$${ext} mod_b$${ext}; \
-		rm -f multi_import_a$${ext} multi_import_b$${ext}; \
+		rm -f multi_import_a$${ext} multi_import_b$${ext} multi_import_d$${ext}; \
 		rm -f packageoption_a$${ext} packageoption_b$${ext} packageoption_c$${ext}; \
+		rm -f template_typedef_cplx2$${ext}; \
 	done
diff --git a/Examples/test-suite/javascript/argcargvtest_runme.js b/Examples/test-suite/javascript/argcargvtest_runme.js
new file mode 100644
index 0000000..8553542
--- /dev/null
+++ b/Examples/test-suite/javascript/argcargvtest_runme.js
@@ -0,0 +1,45 @@
+var test = require("argcargvtest");
+
+const largs = ["hi", "hola", "hello"];
+if (test.mainc(largs) != 3)
+   throw "calling mainc failed";
+
+const targs = ["hi", "hola"];
+if (test.mainv(targs, 0) != "hi")
+   throw "calling mainv failed";
+if (test.mainv(targs, 1) != "hola")
+   throw "calling mainv failed";
+if (test.mainv(targs, 2) != "<<NULL>>")
+   throw "calling mainv failed";
+
+caughtException = false;
+try {
+   test.mainv("hello", 1);
+} catch (err) {
+   caughtException = true;
+}
+if (!caughtException) {
+   throw "mainv without array should fail"
+}
+
+test.initializeApp(largs);
+
+// Check that an empty array works.
+const empty_args = [];
+if (test.mainc(empty_args) != 0)
+  throw "bad main typemap";
+if (test.mainv(empty_args, 0) != "<<NULL>>")
+   throw "calling mainv failed";
+
+// Check that empty strings are handled.
+const empty_string = ["hello", "", "world"];
+if (test.mainc(empty_string) != 3)
+  throw "bad main typemap";
+if (test.mainv(empty_string, 0) != "hello")
+  throw "bad main typemap";
+if (test.mainv(empty_string, 1) != "")
+  throw "bad main typemap";
+if (test.mainv(empty_string, 2) != "world")
+  throw "bad main typemap";
+if (test.mainv(empty_string, 3) != "<<NULL>>")
+  throw "bad main typemap";
diff --git a/Examples/test-suite/javascript/catches_strings_runme.js b/Examples/test-suite/javascript/catches_strings_runme.js
new file mode 100644
index 0000000..9d9db32
--- /dev/null
+++ b/Examples/test-suite/javascript/catches_strings_runme.js
@@ -0,0 +1,23 @@
+var catches_strings = require("catches_strings");
+
+exception_thrown = false;
+try {
+  catches_strings.StringsThrower.charstring();
+} catch (e) {
+  if (!(e.message || e).includes("charstring message"))
+    throw new Error("incorrect exception message " + e.message);
+  exception_thrown = true;
+}
+if (!exception_thrown)
+  throw new Error("Should have thrown an exception");
+
+exception_thrown = false;
+try {
+  catches_strings.StringsThrower.stdstring();
+} catch (e) {
+  if (!(e.message || e).includes("stdstring message"))
+    throw new Error("incorrect exception message " + e.message);
+  exception_thrown = true;
+}
+if (!exception_thrown)
+  throw new Error("Should have thrown an exception");
diff --git a/Examples/test-suite/javascript/class_scope_weird_runme.js b/Examples/test-suite/javascript/class_scope_weird_runme.js
index 73c118d..ca18c1b 100644
--- a/Examples/test-suite/javascript/class_scope_weird_runme.js
+++ b/Examples/test-suite/javascript/class_scope_weird_runme.js
@@ -4,3 +4,14 @@
 g = new class_scope_weird.Foo(3);
 if (f.bar(3) != 3)
     throw RuntimeError;
+
+// Test missing new keyword during constructor call
+var caughtException = false;
+try {
+  g = class_scope_weird.Foo(4);
+} catch (err) {
+  caughtException = true;
+}
+if (!caughtException) {
+  throw new Error("Instantiation exception not thrown");
+}
diff --git a/Examples/test-suite/javascript/constant_directive_runme.js b/Examples/test-suite/javascript/constant_directive_runme.js
new file mode 100644
index 0000000..2bebfff
--- /dev/null
+++ b/Examples/test-suite/javascript/constant_directive_runme.js
@@ -0,0 +1,36 @@
+var constant_directive = require("constant_directive");
+
+if (!constant_directive.TYPE1_CONSTANT1 instanceof constant_directive.Type1) {
+    throw new Error("Failure: TYPE1_CONSTANT1 type: " +
+        typeof constant_directive.TYPE1_CONSTANT1);
+
+}
+if (!constant_directive.getType1Instance() instanceof constant_directive.Type1) {
+    throw new Error("Failure: getType1Instance() type: " +
+        typeof constant_directive.getType1Instance());
+}
+
+if (constant_directive.TYPE1_CONSTANT1.val != 1) {
+    throw new Error("constant_directive.TYPE1_CONSTANT1.val is %r (should be 1) " +
+        constant_directive.TYPE1_CONSTANT1.val);
+}
+
+if (constant_directive.TYPE1_CONSTANT2.val != 2) {
+    throw new Error("constant_directive.TYPE1_CONSTANT2.val is %r (should be 2) " +
+        constant_directive.TYPE1_CONSTANT2.val);
+}
+
+if (constant_directive.TYPE1_CONSTANT3.val != 3) {
+    throw new Error("constant_directive.TYPE1_CONSTANT3.val is %r (should be 3) " +
+        constant_directive.TYPE1_CONSTANT3.val);
+}
+
+if (constant_directive.TYPE1CONST_CONSTANT1.val != 1) {
+    throw new Error("constant_directive.TYPE1CONST_CONSTANT1.val is %r (should be 1) " +
+        constant_directive.TYPE1CONST_CONSTANT1.val);
+}
+
+if (constant_directive.TYPE1CPTR_CONSTANT1.val != 1) {
+    throw new Error("constant_directive.TYPE1CPTR_CONSTANT1.val is %r (should be 1) " +
+        constant_directive.TYPE1CPTR_CONSTANT1.val);
+}
diff --git a/Examples/test-suite/javascript/cpp11_alternate_function_syntax_runme.js b/Examples/test-suite/javascript/cpp11_alternate_function_syntax_runme.js
new file mode 100644
index 0000000..2823a67
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp11_alternate_function_syntax_runme.js
@@ -0,0 +1,28 @@
+var cpp11_alternate_function_syntax = require("cpp11_alternate_function_syntax");
+
+a = new cpp11_alternate_function_syntax.SomeStruct();
+
+res = a.addNormal(4, 5);
+if (res != 9) {
+    throw new Error("SomeStruct::addNormal(4,5) returns ", res, " should be 9.");
+}
+
+res = a.addAlternate(4, 5);
+if (res != 9) {
+    throw new Error("SomeStruct::addAlternate(4,5) returns ", res, " should be 9.");
+}
+
+res = a.addAlternateConst(4, 5);
+if (res != 9) {
+    throw new Error("SomeStruct::addAlternateConst(4,5) returns ", res, " should be 9.");
+}
+
+res = a.addAlternateNoExcept(4, 5);
+if (res != 9) {
+    throw new Error("SomeStruct::addAlternateNoExcept(4,5) returns ", res, " should be 9.");
+}
+
+res = a.addAlternateConstNoExcept(4, 5);
+if (res != 9) {
+    throw new Error("SomeStruct::addAlternateConstNoExcept(4,5) returns ", res, " should be 9.");
+}
diff --git a/Examples/test-suite/javascript/cpp11_decltype_runme.js b/Examples/test-suite/javascript/cpp11_decltype_runme.js
new file mode 100644
index 0000000..c067d9b
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp11_decltype_runme.js
@@ -0,0 +1,22 @@
+var cpp11_decltype = require("cpp11_decltype");
+
+a = new cpp11_decltype.A;
+a.i = 5;
+if (a.i != 5) {
+    throw new Error("Assignment to a.i failed.");
+}
+
+a.j = 10;
+if (a.j != 10) {
+    throw new Error("Assignment to a.j failed.");
+}
+
+b = a.get_number(5);
+if (b != 10) {
+    throw new Error("get_number(5) should return 10.");
+}
+
+b = a.get_number(6);
+if (b != 0) {
+    throw new Error("get_number(6) should return 0.");
+}
diff --git a/Examples/test-suite/javascript/cpp11_final_class_runme.js b/Examples/test-suite/javascript/cpp11_final_class_runme.js
new file mode 100644
index 0000000..3e72b05
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp11_final_class_runme.js
@@ -0,0 +1,64 @@
+var cpp11_final_class = require("cpp11_final_class");
+
+fc1 = new cpp11_final_class.FinalClass1();
+fc1.method1();
+
+fc2 = new cpp11_final_class.FinalClass2();
+fc2.method2();
+
+fc3 = new cpp11_final_class.FinalClass3();
+fc3.method3();
+
+fc4 = new cpp11_final_class.FinalClass4();
+fc4.method4();
+fc4final = cpp11_final_class.final;
+cpp11_final_class.final.method4();
+
+fc5 = new cpp11_final_class.FinalClass5();
+fc5.method5();
+fc5.final_member_var.finalmethod();
+fc5final = fc5.get_final_member();
+fc5final.finalmethod();
+fc5final = fc5.get_final_member2();
+fc5final.finalmethod();
+
+fc6 = new cpp11_final_class.FinalClass6();
+fc6.method6();
+fc6.final();
+
+o = new cpp11_final_class.override();
+o.omethod();
+
+y = new cpp11_final_class.Y();
+fv4 = new cpp11_final_class.FinalVar4();
+yy = fv4.final;
+
+fv5 = new cpp11_final_class.FinalVar5();
+yy = fv5.final;
+
+fv6 = new cpp11_final_class.FinalVar6();
+yy = fv6.final;
+
+fv7 = new cpp11_final_class.FinalVar7();
+yy = fv7.final;
+
+fv8 = new cpp11_final_class.FinalVar8();
+yy = fv8.final;
+
+fv9 = new cpp11_final_class.FinalVar9();
+yy = fv9.final;
+
+fv10 = new cpp11_final_class.FinalVar10();
+fv10.b10(y);
+
+// Removed due to Visual C++ compiler limitations
+/*fv11 = FinalVar11()
+fv11.a11(y)
+fe1 = FinalEnum1()
+fe1.enum_in(FinalEnum1.final)
+
+fe2 = FinalEnum2()
+fe2f = fe2.final*/
+
+s3f = new cpp11_final_class.Space3_final();
+s3f.fmethod();
diff --git a/Examples/test-suite/javascript/cpp11_initializer_list_runme.js b/Examples/test-suite/javascript/cpp11_initializer_list_runme.js
new file mode 100644
index 0000000..dfff44f
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp11_initializer_list_runme.js
@@ -0,0 +1,4 @@
+var cpp11_initializer_list = require("cpp11_initializer_list");
+
+a = new cpp11_initializer_list.A();
+a = new cpp11_initializer_list.A(11.1);
diff --git a/Examples/test-suite/javascript/cpp11_move_only_runme.js b/Examples/test-suite/javascript/cpp11_move_only_runme.js
new file mode 100644
index 0000000..26daf5d
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp11_move_only_runme.js
@@ -0,0 +1,22 @@
+var cpp11_move_only = require("cpp11_move_only");
+
+// Output
+cpp11_move_only.Counter.reset_counts();
+var mo = cpp11_move_only.MoveOnly.create();
+cpp11_move_only.Counter.check_counts(1, 0, 0, 2, 0, 2);
+
+cpp11_move_only.Counter.reset_counts();
+var mo = cpp11_move_only.MovableCopyable.create();
+cpp11_move_only.Counter.check_counts(2, 1, 0, 0, 1, 2);
+
+// Move semantics not used
+cpp11_move_only.Counter.reset_counts();
+var mo = cpp11_move_only.MovableCopyable.createConst();
+cpp11_move_only.Counter.check_counts(2, 1, 1, 0, 0, 2);
+
+// Input
+cpp11_move_only.Counter.reset_counts();
+var mo = new cpp11_move_only.MovableCopyable(222);
+cpp11_move_only.Counter.check_counts(1, 0, 0, 0, 0, 0);
+cpp11_move_only.MovableCopyable.take(mo);
+cpp11_move_only.Counter.check_counts(2, 0, 1, 1, 0, 2);
diff --git a/Examples/test-suite/javascript/cpp11_move_typemaps_runme.js b/Examples/test-suite/javascript/cpp11_move_typemaps_runme.js
new file mode 100644
index 0000000..1e888cb
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp11_move_typemaps_runme.js
@@ -0,0 +1,30 @@
+var cpp11_move_typemaps = require("cpp11_move_typemaps");
+
+cpp11_move_typemaps.Counter.reset_counts();
+mo = new cpp11_move_typemaps.MoveOnly(111);
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 0, 0, 0);
+cpp11_move_typemaps.MoveOnly.take(mo);
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2);
+delete mo;
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+cpp11_move_typemaps.Counter.reset_counts();
+mo = new cpp11_move_typemaps.MovableCopyable(111);
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 0, 0, 0);
+cpp11_move_typemaps.MovableCopyable.take(mo);
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2);
+delete mo;
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+mo = new cpp11_move_typemaps.MoveOnly(222);
+cpp11_move_typemaps.MoveOnly.take(mo);
+exception_thrown = false;
+try {
+  cpp11_move_typemaps.MoveOnly.take(mo);
+} catch (e) {
+  if (!e.message.includes("cannot release ownership as memory is not owned"))
+    throw new Error("incorrect exception message:" + e.message);
+  exception_thrown = true;
+}
+if (!exception_thrown)
+  throw new Error("double usage of take should have been an error");
diff --git a/Examples/test-suite/javascript/cpp11_null_pointer_constant_runme.js b/Examples/test-suite/javascript/cpp11_null_pointer_constant_runme.js
new file mode 100644
index 0000000..5477c40
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp11_null_pointer_constant_runme.js
@@ -0,0 +1,20 @@
+var cpp11_null_pointer_constant = require("cpp11_null_pointer_constant");
+
+a = new cpp11_null_pointer_constant.A();
+
+if (a._myA != null) {
+    throw new Error(
+        "cpp11_null_pointer_constant: _myA should be None, but is ", a._myA);
+}
+
+b = new cpp11_null_pointer_constant.A();
+if (a._myA != b._myA) {
+    throw new Error(
+        "cpp11_null_pointer_constant: a._myA should be the same as b._myA, but ", a._myA, "!=", b._myA);
+}
+
+a._myA = new cpp11_null_pointer_constant.A();
+if (a._myA == null) {
+    throw new Error((
+        "cpp11_null_pointer_constant: _myA should be object, but is None"));
+}
diff --git a/Examples/test-suite/javascript/cpp11_ref_qualifiers_runme.js b/Examples/test-suite/javascript/cpp11_ref_qualifiers_runme.js
new file mode 100644
index 0000000..d544caf
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp11_ref_qualifiers_runme.js
@@ -0,0 +1,51 @@
+var cpp11_ref_qualifiers = require("cpp11_ref_qualifiers");
+
+h = new cpp11_ref_qualifiers.Host();
+
+// Basic testing
+h.h1();
+h.h2();
+h.h6();
+h.h7();
+
+h.h();
+
+// %feature testing
+f = new cpp11_ref_qualifiers.Features();
+if (f.F1() != "F1") {
+    throw new Error("Fail");
+}
+if (f.F2() != "F2") {
+    throw new Error("Fail");
+}
+if (f.F3() != "F3") {
+    throw new Error("Fail");
+}
+
+if (f.C1(0) != "C1") {
+    throw new Error("Fail");
+}
+if (f.C2(0) != "C2") {
+    throw new Error("Fail");
+}
+if (f.C3(0) != "C3") {
+    throw new Error("Fail");
+}
+
+// %rename testing
+r = new cpp11_ref_qualifiers.Renames();
+r.RR1();
+r.RR2();
+r.RR3();
+
+r.SS1(0);
+r.SS2(0);
+r.SS3(0);
+
+// Conversion operators
+co = new cpp11_ref_qualifiers.ConversionOperators();
+s = co.StringConvertCopy();
+s = co.StringConvertMove();
+
+co2 = new cpp11_ref_qualifiers.ConversionOperators2();
+s = co2.StringConvertMove();
diff --git a/Examples/test-suite/javascript/cpp11_ref_qualifiers_rvalue_unignore_runme.js b/Examples/test-suite/javascript/cpp11_ref_qualifiers_rvalue_unignore_runme.js
new file mode 100644
index 0000000..19d2095
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp11_ref_qualifiers_rvalue_unignore_runme.js
@@ -0,0 +1,4 @@
+var cpp11_ref_qualifiers_rvalue_unignore = require("cpp11_ref_qualifiers_rvalue_unignore");
+
+new cpp11_ref_qualifiers_rvalue_unignore.RefQualifier().m1();
+new cpp11_ref_qualifiers_rvalue_unignore.RefQualifier().m2();
diff --git a/Examples/test-suite/javascript/cpp11_result_of_runme.js b/Examples/test-suite/javascript/cpp11_result_of_runme.js
new file mode 100644
index 0000000..d996ca1
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp11_result_of_runme.js
@@ -0,0 +1,13 @@
+var cpp11_result_of = require("cpp11_result_of");
+
+result = cpp11_result_of.test_result(cpp11_result_of.SQUARE, 3.0);
+if (result != 9.0) {
+    throw new Error("test_result(square, 3.0) is not 9.0. Got: " + str(
+        result));
+}
+
+result = cpp11_result_of.test_result_alternative1(cpp11_result_of.SQUARE, 3.0);
+if (result != 9.0) {
+    throw new Error("test_result_alternative1(square, 3.0) is not 9.0. Got: " + str(
+        result));
+}
diff --git a/Examples/test-suite/javascript/cpp11_rvalue_reference_move_runme.js b/Examples/test-suite/javascript/cpp11_rvalue_reference_move_runme.js
new file mode 100644
index 0000000..c642b42
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp11_rvalue_reference_move_runme.js
@@ -0,0 +1,87 @@
+var cpp11_rvalue_reference_move = require("cpp11_rvalue_reference_move");
+
+{
+  // Function containing rvalue reference parameter
+  cpp11_rvalue_reference_move.Counter.reset_counts();
+  mo = new cpp11_rvalue_reference_move.MovableCopyable(222);
+  cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 0, 0, 0);
+  cpp11_rvalue_reference_move.MovableCopyable.movein(mo);
+  cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 2);
+  if (!cpp11_rvalue_reference_move.MovableCopyable.is_nullptr(mo))
+    throw new Error("is_nullptr failed");
+  delete mo;
+  cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 2);
+}
+
+{
+  // Move constructor test
+  cpp11_rvalue_reference_move.Counter.reset_counts();
+  mo = new cpp11_rvalue_reference_move.MovableCopyable(222);
+  cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 0, 0, 0);
+  mo_moved = new cpp11_rvalue_reference_move.MovableCopyable(mo);
+  cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 1);
+  if (!cpp11_rvalue_reference_move.MovableCopyable.is_nullptr(mo))
+    throw new Error("is_nullptr failed");
+  delete mo;
+  cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 1);
+  // delete mo_moved;
+  // cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 2);
+  // Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete
+  cpp11_rvalue_reference_move.MovableCopyable.movein(mo_moved);
+  cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 2, 0, 3);
+}
+
+{
+  // Move assignment operator test
+  cpp11_rvalue_reference_move.Counter.reset_counts();
+  mo111 = new cpp11_rvalue_reference_move.MovableCopyable(111);
+  mo222 = new cpp11_rvalue_reference_move.MovableCopyable(222);
+  cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 0, 0);
+  mo111.MoveAssign(mo222);
+  cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1);
+  if (!cpp11_rvalue_reference_move.MovableCopyable.is_nullptr(mo222))
+    throw new Error("is_nullptr failed");
+  delete mo222;
+  cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1);
+  // delete mo111;
+  // cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 2);
+  // Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete
+  cpp11_rvalue_reference_move.MovableCopyable.movein(mo111);
+  cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 1, 1, 3);
+}
+
+{
+  // null check
+  cpp11_rvalue_reference_move.Counter.reset_counts();
+  exception_thrown = false;
+  try {
+    cpp11_rvalue_reference_move.MovableCopyable.movein(null);
+  } catch (e) {
+    if (!e.message.includes("invalid null reference"))
+      throw new Error("incorrect exception message " + e.message);
+    exception_thrown = true;
+  }
+  if (!exception_thrown)
+    throw new Error("Should have thrown null error");
+  cpp11_rvalue_reference_move.Counter.check_counts(0, 0, 0, 0, 0, 0);
+}
+
+{
+  // output
+  cpp11_rvalue_reference_move.Counter.reset_counts();
+  var mc = cpp11_rvalue_reference_move.MovableCopyable.moveout(1234);
+  cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1);
+  cpp11_rvalue_reference_move.MovableCopyable.check_numbers_match(mc, 1234);
+
+  exception_thrown = false;
+  try {
+    cpp11_rvalue_reference_move.MovableCopyable.movein(mc);
+  } catch (e) {
+    if (!e.message.includes("cannot release ownership as memory is not owned"))
+      throw new Error("incorrect exception message " + e.message);
+    exception_thrown = true;
+  }
+  if (!exception_thrown)
+    throw new Error("Should have thrown 'Cannot release ownership as memory is not owned' error");
+  cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1);
+}
diff --git a/Examples/test-suite/javascript/cpp11_rvalue_reference_runme.js b/Examples/test-suite/javascript/cpp11_rvalue_reference_runme.js
new file mode 100644
index 0000000..5ffe08d
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp11_rvalue_reference_runme.js
@@ -0,0 +1,31 @@
+var cpp11_rvalue_reference = require("cpp11_rvalue_reference");
+
+a = new cpp11_rvalue_reference.A();
+
+a.setAcopy(5);
+if (a.getAcopy() != 5) {
+    throw new Error("int A::getAcopy() value is " +
+        a.getAcopy() + " should be 5");
+}
+
+ptr = a.getAptr();
+
+a.setAptr(ptr);
+if (a.getAcopy() != 5) {
+    throw new Error("after A::setAptr(): int A::getAcopy() value is " + a.getAcopy(
+    ) + " should be 5");
+}
+
+a.setAref(ptr);
+if (a.getAcopy() != 5) {
+    throw new Error("after A::setAref(): int A::getAcopy() value is " + a.getAcopy(
+    ) + " should be 5");
+}
+
+rvalueref = a.getAmove();
+
+a.setAref(rvalueref);
+if (a.getAcopy() != 5) {
+    throw new Error("after A::setAmove(): int A::getAcopy() value is " + a.getAcopy(
+    ) + " should be 5");
+}
diff --git a/Examples/test-suite/javascript/cpp11_std_unique_ptr_runme.js b/Examples/test-suite/javascript/cpp11_std_unique_ptr_runme.js
new file mode 100644
index 0000000..9e7d879
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp11_std_unique_ptr_runme.js
@@ -0,0 +1,129 @@
+var cpp11_std_unique_ptr = require("cpp11_std_unique_ptr");
+
+var checkCount = function(expected_count) {
+  actual_count = cpp11_std_unique_ptr.Klass.getTotal_count();
+  if (actual_count != expected_count)
+    throw new Error("Counts incorrect, expected:" + expected_count + " actual:" + actual_count);
+}
+
+// Test raw pointer handling involving virtual inheritance
+{
+  kini = new cpp11_std_unique_ptr.KlassInheritance("KlassInheritanceInput");
+  checkCount(1);
+  s = cpp11_std_unique_ptr.useKlassRawPtr(kini);
+  if (s !== "KlassInheritanceInput")
+    throw new Error("Incorrect string: " + s);
+  // delete kini;
+  // Above not deleting the C++ object(node v12) - can't reliably control GC
+  cpp11_std_unique_ptr.takeKlassUniquePtr(kini);
+  checkCount(0);
+}
+
+
+// unique_ptr as input
+{
+  kin = new cpp11_std_unique_ptr.Klass("KlassInput");
+  checkCount(1);
+  s = cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+  checkCount(0);
+  if (s !== "KlassInput")
+    throw new Error("Incorrect string: " + s);
+  if (!cpp11_std_unique_ptr.is_nullptr(kin))
+    throw new Error("is_nullptr failed");
+  delete kin; // Should not fail, even though already deleted
+  checkCount(0);
+}
+
+{
+  kin = new cpp11_std_unique_ptr.Klass("KlassInput");
+  checkCount(1);
+  s = cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+  checkCount(0);
+  if (s !== "KlassInput")
+    throw new Error("Incorrect string: " + s);
+  if (!cpp11_std_unique_ptr.is_nullptr(kin))
+    throw new Error("is_nullptr failed");
+  exception_thrown = false;
+  try {
+    cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+  } catch (e) {
+    if (!e.message.includes("cannot release ownership as memory is not owned"))
+      throw new Error("incorrect exception message " + e.message);
+    exception_thrown = true;
+  }
+  if (!exception_thrown)
+      throw new Error("double usage of takeKlassUniquePtr should have been an error");
+  delete kin; // Should not fail, even though already deleted
+  checkCount(0);
+}
+
+{
+  kin = new cpp11_std_unique_ptr.Klass("KlassInput");
+  exception_thrown = false;
+  notowned = cpp11_std_unique_ptr.get_not_owned_ptr(kin);
+  try {
+    cpp11_std_unique_ptr.takeKlassUniquePtr(notowned);
+  } catch (e) {
+    if (!e.message.includes("cannot release ownership as memory is not owned"))
+      throw new Error("incorrect exception message " + e.message);
+    exception_thrown = true;
+  }
+  if (!exception_thrown)
+    throw new Error("Should have thrown 'Cannot release ownership as memory is not owned' error");
+  checkCount(1);
+  // delete kin;
+  // Above not deleting the C++ object(node v12) - can't reliably control GC
+  cpp11_std_unique_ptr.takeKlassUniquePtr(kin);
+  checkCount(0);
+}
+
+{
+  kini = new cpp11_std_unique_ptr.KlassInheritance("KlassInheritanceInput");
+  checkCount(1);
+  s = cpp11_std_unique_ptr.takeKlassUniquePtr(kini);
+  checkCount(0);
+  if (s !== "KlassInheritanceInput")
+    throw new Error("Incorrect string: " + s);
+  if (!cpp11_std_unique_ptr.is_nullptr(kini))
+    throw new Error("is_nullptr failed");
+  delete kini; // Should not fail, even though already deleted
+  checkCount(0);
+}
+
+cpp11_std_unique_ptr.takeKlassUniquePtr(null);
+cpp11_std_unique_ptr.takeKlassUniquePtr(cpp11_std_unique_ptr.make_null());
+checkCount(0);
+
+// overloaded parameters
+if (cpp11_std_unique_ptr.overloadTest() != 0)
+  throw new RuntimeException("overloadTest failed");
+if (cpp11_std_unique_ptr.overloadTest(null) != 1)
+  throw new RuntimeException("overloadTest failed");
+if (cpp11_std_unique_ptr.overloadTest(new cpp11_std_unique_ptr.Klass("over")) != 1)
+  throw new RuntimeException("overloadTest failed");
+checkCount(0);
+
+
+// unique_ptr as output
+k1 = cpp11_std_unique_ptr.makeKlassUniquePtr("first");
+if (k1.getLabel() !== "first")
+  throw new Error("wrong object label");
+
+k2 = cpp11_std_unique_ptr.makeKlassUniquePtr("second");
+checkCount(2);
+
+// delete k1;
+// Above not deleting the C++ object(node v12) - can't reliably control GC
+cpp11_std_unique_ptr.takeKlassUniquePtr(k1);
+checkCount(1);
+
+if (k2.getLabel() !== "second")
+  throw new Error("wrong object label");
+
+// delete k2;
+// Above not deleting the C++ object(node v12) - can't reliably control GC
+cpp11_std_unique_ptr.takeKlassUniquePtr(k2);
+checkCount(0);
+
+if (cpp11_std_unique_ptr.makeNullUniquePtr() != null)
+  throw new Error("null failure");
diff --git a/Examples/test-suite/javascript/cpp11_thread_local_runme.js b/Examples/test-suite/javascript/cpp11_thread_local_runme.js
new file mode 100644
index 0000000..5419307
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp11_thread_local_runme.js
@@ -0,0 +1,47 @@
+var cpp11_thread_local = require("cpp11_thread_local");
+
+t = new cpp11_thread_local.ThreadLocals();
+if (t.stval != 11) {
+    throw new Error;
+}
+if (t.tsval != 22) {
+    throw new Error;
+}
+if (t.tscval99 != 99) {
+    throw new Error;
+}
+
+cpp11_thread_local.etval = -11;
+if (cpp11_thread_local.etval != -11) {
+    throw new Error;
+}
+
+cpp11_thread_local.stval = -22;
+if (cpp11_thread_local.stval != -22) {
+    throw new Error;
+}
+
+cpp11_thread_local.tsval = -33;
+if (cpp11_thread_local.tsval != -33) {
+    throw new Error;
+}
+
+cpp11_thread_local.etval = -44;
+if (cpp11_thread_local.etval != -44) {
+    throw new Error;
+}
+
+cpp11_thread_local.teval = -55;
+if (cpp11_thread_local.teval != -55) {
+    throw new Error;
+}
+
+cpp11_thread_local.ectval = -66;
+if (cpp11_thread_local.ectval != -66) {
+    throw new Error;
+}
+
+cpp11_thread_local.ecpptval = -66;
+if (cpp11_thread_local.ecpptval != -66) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/cpp11_using_typedef_struct_runme.js b/Examples/test-suite/javascript/cpp11_using_typedef_struct_runme.js
new file mode 100644
index 0000000..4acfdb8
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp11_using_typedef_struct_runme.js
@@ -0,0 +1,13 @@
+var cpp11_using_typedef_struct = require("cpp11_using_typedef_struct");
+
+var b = new cpp11_using_typedef_struct.AffineMatrix();
+b.x = b.y = b.z = 1;
+
+if (cpp11_using_typedef_struct.fn1(b) != b.x)
+  throw new Error('failed');
+
+var bb = new cpp11_using_typedef_struct.xCacheView();
+bb.x = 123;
+
+if (cpp11_using_typedef_struct.fn2(bb) != 123)
+  throw new Error('failed');
diff --git a/Examples/test-suite/javascript/cpp11_variadic_function_templates_runme.js b/Examples/test-suite/javascript/cpp11_variadic_function_templates_runme.js
new file mode 100644
index 0000000..11c538c
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp11_variadic_function_templates_runme.js
@@ -0,0 +1,23 @@
+var cpp11_variadic_function_templates = require("cpp11_variadic_function_templates");
+
+const {A, B, C, D, variadicmix1} = cpp11_variadic_function_templates;
+
+ec = new cpp11_variadic_function_templates.EmplaceContainer();
+ec.emplace(new A());
+ec.emplace(new A(), new B());
+ec.emplace(new A(), new B(), new C());
+ec.emplace(new A(), new B(), new C(), new D());
+
+function check(expected, got) {
+    if (expected != got) {
+        throw new Error("failed: {} != {}".format(expected, got));
+    }
+}
+a = new A();
+b = new B();
+c = new C();
+check(variadicmix1(), 20);
+check(variadicmix1(a), 20);
+check(variadicmix1(a, b), 10);
+check(variadicmix1(a, b, c), 20);
+check(variadicmix1(11, 22), 10);
diff --git a/Examples/test-suite/javascript/cpp14_binary_integer_literals_runme.js b/Examples/test-suite/javascript/cpp14_binary_integer_literals_runme.js
new file mode 100644
index 0000000..655ef91
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp14_binary_integer_literals_runme.js
@@ -0,0 +1,33 @@
+var cpp14_binary_integer_literals = require("cpp14_binary_integer_literals");
+
+if (cpp14_binary_integer_literals.b1 != 1) {
+    throw new Error;
+}
+
+if (cpp14_binary_integer_literals.b2 != 2) {
+    throw new Error;
+}
+
+if (cpp14_binary_integer_literals.b3 != 3) {
+    throw new Error;
+}
+
+if (cpp14_binary_integer_literals.b4 != 4) {
+    throw new Error;
+}
+
+if (cpp14_binary_integer_literals.b5 != 5) {
+    throw new Error;
+}
+
+if (cpp14_binary_integer_literals.b6 != 6) {
+    throw new Error;
+}
+
+if (cpp14_binary_integer_literals.b7 != 7) {
+    throw new Error;
+}
+
+if (cpp14_binary_integer_literals.b8 != 8) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/cpp17_hex_floating_literals_runme.js b/Examples/test-suite/javascript/cpp17_hex_floating_literals_runme.js
new file mode 100644
index 0000000..0d2585f
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp17_hex_floating_literals_runme.js
@@ -0,0 +1,37 @@
+var cpp17_hex_floating_literals = require("cpp17_hex_floating_literals");
+
+if (cpp17_hex_floating_literals.f1 != 0.) {
+    throw new Error;
+}
+
+if (cpp17_hex_floating_literals.f2 != 0.) {
+    throw new Error;
+}
+
+if (cpp17_hex_floating_literals.f3 != 0.) {
+    throw new Error;
+}
+
+if (cpp17_hex_floating_literals.f4 != 7.5) {
+    throw new Error;
+}
+
+if (cpp17_hex_floating_literals.f5 != 20.) {
+    throw new Error;
+}
+
+if (cpp17_hex_floating_literals.f6 != 64.) {
+    throw new Error;
+}
+
+if (cpp17_hex_floating_literals.f7 != 11452.) {
+    throw new Error;
+}
+
+if (cpp17_hex_floating_literals.f8 != 149140.) {
+    throw new Error;
+}
+
+if (cpp17_hex_floating_literals.f9 != 18253638.) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/cpp17_nested_namespaces_runme.js b/Examples/test-suite/javascript/cpp17_nested_namespaces_runme.js
new file mode 100644
index 0000000..f711c72
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp17_nested_namespaces_runme.js
@@ -0,0 +1,18 @@
+var cpp17_nested_namespaces = require("cpp17_nested_namespaces");
+
+new cpp17_nested_namespaces.A1Struct().A1Method()
+new cpp17_nested_namespaces.B1Struct().B1Method()
+new cpp17_nested_namespaces.C1Struct().C1Method()
+new cpp17_nested_namespaces.createA1Struct().A1Method()
+new cpp17_nested_namespaces.createB1Struct().B1Method()
+new cpp17_nested_namespaces.createC1Struct().C1Method()
+
+new cpp17_nested_namespaces.B2Struct().B2Method()
+new cpp17_nested_namespaces.C2Struct().C2Method()
+new cpp17_nested_namespaces.createB2Struct().B2Method()
+new cpp17_nested_namespaces.createC2Struct().C2Method()
+
+new cpp17_nested_namespaces.B3Struct().B3Method()
+new cpp17_nested_namespaces.C3Struct().C3Method()
+new cpp17_nested_namespaces.createB3Struct().B3Method()
+new cpp17_nested_namespaces.createC3Struct().C3Method()
diff --git a/Examples/test-suite/javascript/cpp17_u8_char_literals_runme.js b/Examples/test-suite/javascript/cpp17_u8_char_literals_runme.js
new file mode 100644
index 0000000..94aaafd
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp17_u8_char_literals_runme.js
@@ -0,0 +1,13 @@
+var cpp17_u8_char_literals = require("cpp17_u8_char_literals");
+
+if (cpp17_u8_char_literals.a != "a") {
+    throw new Error;
+}
+
+if (cpp17_u8_char_literals.u != "u") {
+    throw new Error;
+}
+
+if (cpp17_u8_char_literals.u8 != "8") {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/cpp20_spaceship_operator_runme.js b/Examples/test-suite/javascript/cpp20_spaceship_operator_runme.js
new file mode 100644
index 0000000..d59a9f6
--- /dev/null
+++ b/Examples/test-suite/javascript/cpp20_spaceship_operator_runme.js
@@ -0,0 +1,21 @@
+var cpp20_spaceship_operator = require("cpp20_spaceship_operator");
+
+function check_equal(a, b) {
+    if (a != b) {
+        throw new Error("{} is not equal to {}".format(a, b));
+    }
+}
+
+check_equal(cpp20_spaceship_operator.ALIEN, 1);
+check_equal(cpp20_spaceship_operator.SPACE, 1);
+check_equal(cpp20_spaceship_operator.COMET, 1);
+check_equal(cpp20_spaceship_operator.v, 42);
+
+x = new cpp20_spaceship_operator.A(1);
+y = new cpp20_spaceship_operator.A(2);
+
+check_equal(cpp20_spaceship_operator.spaceship(x, y) < 0, true);
+check_equal(cpp20_spaceship_operator.spaceship(x, x), 0);
+check_equal(cpp20_spaceship_operator.spaceship(y, x) > 0, true);
+
+check_equal(cpp20_spaceship_operator.f(), 42);
diff --git a/Examples/test-suite/javascript/default_arg_values_runme.js b/Examples/test-suite/javascript/default_arg_values_runme.js
new file mode 100644
index 0000000..f9cc443
--- /dev/null
+++ b/Examples/test-suite/javascript/default_arg_values_runme.js
@@ -0,0 +1,36 @@
+var default_arg_values = require("default_arg_values");
+
+var d = new default_arg_values.Display();
+
+if (d.draw1() != 0) {
+    throw new Error;
+}
+
+if (d.draw1(12) != 12) {
+    throw new Error;
+}
+
+p = default_arg_values.createPtr(123);
+if (d.draw2() != 0) {
+    throw new Error;
+}
+
+if (d.draw2(p) != 123) {
+    throw new Error;
+}
+
+if (d.bool0() != false || typeof d.bool0() != typeof false) {
+    throw new Error;
+}
+
+if (d.bool1() != true || typeof d.bool1() != typeof true) {
+    throw new Error;
+}
+
+if (d.mybool0() != false || typeof d.mybool0() != typeof false) {
+    throw new Error;
+}
+
+if (d.mybool1() != true || typeof d.mybool1() != typeof false) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/default_args_c_runme.js b/Examples/test-suite/javascript/default_args_c_runme.js
new file mode 100644
index 0000000..a252802
--- /dev/null
+++ b/Examples/test-suite/javascript/default_args_c_runme.js
@@ -0,0 +1,28 @@
+var default_args_c = require("default_args_c");
+
+if (default_args_c.foo1() != 1) {
+  throw new Error("failed");
+}
+if (default_args_c.foo43() != 43) {
+  throw new Error("failed");
+}
+
+f = new default_args_c.FooStruct();
+f.no_arg();
+f.one_req(null);
+f.one_opt();
+f.one_opt(null);
+f.two_arg(null);
+f.two_arg(null, null);
+
+default_args_c.StaticStruct.no_arg();
+default_args_c.StaticStruct.one_req(null);
+default_args_c.StaticStruct.one_opt();
+default_args_c.StaticStruct.one_opt(null);
+default_args_c.StaticStruct.two_arg(null);
+default_args_c.StaticStruct.two_arg(null, null);
+
+default_args_c.global_opts1();
+default_args_c.global_opts1(null);
+default_args_c.global_opts2(null);
+default_args_c.global_opts2(null, null);
diff --git a/Examples/test-suite/javascript/default_args_runme.js b/Examples/test-suite/javascript/default_args_runme.js
new file mode 100644
index 0000000..2360348
--- /dev/null
+++ b/Examples/test-suite/javascript/default_args_runme.js
@@ -0,0 +1,216 @@
+var default_args = require('default_args');
+ec = new default_args.EnumClass();
+if (!ec.blah()) {
+    throw new Error("EnumClass::blah() default arguments don't work");
+}
+
+de = new default_args.DerivedEnumClass();
+de.accelerate();
+de.accelerate(default_args.EnumClass.SLOW);
+
+if (default_args.Statics.staticMethod() != 60) {
+    throw new Error;
+}
+
+if (default_args.cfunc1(1) != 2) {
+    throw new Error;
+}
+
+if (default_args.cfunc2(1) != 3) {
+    throw new Error;
+}
+
+if (default_args.cfunc3(1) != 4) {
+    throw new Error;
+}
+
+f = new default_args.Foo();
+
+f.newname();
+f.newname(1);
+f.defaulted1();
+f.defaulted2();
+
+if (f.double_if_void_ptr_is_null(2, null) != 4) {
+    throw new Error;
+}
+
+if (f.double_if_void_ptr_is_null(3) != 6) {
+    throw new Error;
+}
+
+if (f.double_if_handle_is_null(4, null) != 8) {
+    throw new Error;
+}
+
+if (f.double_if_handle_is_null(5) != 10) {
+    throw new Error;
+}
+
+if (f.double_if_dbl_ptr_is_null(6, null) != 12) {
+    throw new Error;
+}
+
+if (f.double_if_dbl_ptr_is_null(7) != 14) {
+    throw new Error;
+}
+
+try {
+    f = default_args.Foo(1);
+    error = 1;
+} catch {
+    error = 0;
+}
+if (error) {
+    throw new Error("Foo::Foo ignore is not working");
+}
+
+try {
+    f = default_args.Foo(1, 2);
+    error = 1;
+} catch {
+    error = 0;
+}
+if (error) {
+    throw new Error("Foo::Foo ignore is not working");
+}
+
+try {
+    f = default_args.Foo(1, 2, 3);
+    error = 1;
+} catch {
+    error = 0;
+}
+if (error) {
+    throw new Error("Foo::Foo ignore is not working");
+}
+
+try {
+    m = f.meth(1);
+    error = 1;
+} catch {
+    error = 0;
+}
+if (error) {
+    throw new Error("Foo::meth ignore is not working");
+}
+
+try {
+    m = f.meth(1, 2);
+    error = 1;
+} catch {
+    error = 0;
+}
+if (error) {
+    throw new Error("Foo::meth ignore is not working");
+}
+
+try {
+    m = f.meth(1, 2, 3);
+    error = 1;
+} catch {
+    error = 0;
+}
+if (error) {
+    throw new Error("Foo::meth ignore is not working");
+}
+
+Klass_inc = default_args.Klass.inc;
+
+if (Klass_inc(100, new default_args.Klass(22)).val != 122) {
+    throw new Error("Klass::inc failed");
+}
+
+if (Klass_inc(100).val != 99) {
+    throw new Error("Klass::inc failed");
+}
+
+if (Klass_inc().val != 0) {
+    throw new Error("Klass::inc failed");
+}
+
+tricky = new default_args.TrickyInPython();
+if (tricky.value_m1(10) != -1) {
+    throw new Error("trickyvalue_m1 failed");
+}
+if (tricky.value_m1(10, 10) != 10) {
+    throw new Error("trickyvalue_m1 failed");
+}
+if (tricky.value_0xabcdef(10) != 0xabcdef) {
+    throw new Error("trickyvalue_0xabcdef failed");
+}
+if (tricky.value_0644(10) != 420) {
+    throw new Error("trickyvalue_0644 failed");
+}
+if (tricky.value_perm(10) != 420) {
+    throw new Error("trickyvalue_perm failed");
+}
+if (tricky.value_m01(10) != -1) {
+    throw new Error("trickyvalue_m01 failed");
+}
+if (!tricky.booltest2()) {
+    throw new Error("booltest2 failed");
+}
+
+if (tricky.max_32bit_int1() != 0x7FFFFFFF) {
+    throw new Error("max_32bit_int1 failed");
+}
+if (tricky.min_32bit_int1() != -2147483648) {
+    throw new Error("min_32bit_int1 failed");
+}
+if (tricky.max_32bit_int2() != 0x7FFFFFFF) {
+    throw new Error("max_32bit_int2 failed");
+}
+
+tricky.too_big_32bit_int1();
+tricky.too_small_32bit_int1();
+tricky.too_big_32bit_int2();
+tricky.too_small_32bit_int2();
+
+default_args.seek();
+default_args.seek(10);
+
+if (!default_args.booltest()) {
+    throw new Error("booltest failed");
+}
+
+if (default_args.slightly_off_square(10) != 102) {
+    throw new Error;
+}
+
+if (default_args.slightly_off_square() != 291) {
+    throw new Error;
+}
+
+if ((new default_args.CDA()).cdefaultargs_test1() != 1) {
+    throw new Error;
+}
+
+if ((new default_args.CDA()).cdefaultargs_test2() != 1) {
+    throw new Error;
+}
+
+if (default_args.chartest1() != "x") {
+    throw new Error;
+}
+
+// JavaScriptCore cannot accept a '\0' string
+if (default_args.chartest2() != "\0" && default_args.chartest2() != '') {
+    throw new Error;
+}
+
+if (default_args.chartest3() != "\1") {
+    throw new Error;
+}
+
+if (default_args.chartest4() != "\n") {
+    throw new Error;
+}
+
+if (default_args.chartest5() != "B") {
+    throw new Error;
+}
+
+if (default_args.chartest6() != "C") {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/enums_runme.js b/Examples/test-suite/javascript/enums_runme.js
new file mode 100644
index 0000000..02f6a4c
--- /dev/null
+++ b/Examples/test-suite/javascript/enums_runme.js
@@ -0,0 +1,22 @@
+
+var enums = require("enums");
+
+enums.bar2(1);
+enums.bar3(1);
+enums.bar1(1);
+
+if (enums.enumInstance != 2) {
+    throw new Error;
+}
+
+if (enums.Slap != 10) {
+    throw new Error;
+}
+
+if (enums.Mine != 11) {
+    throw new Error;
+}
+
+if (enums.Thigh != 12) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/exception_classname_runme.js b/Examples/test-suite/javascript/exception_classname_runme.js
new file mode 100644
index 0000000..6e97cb6
--- /dev/null
+++ b/Examples/test-suite/javascript/exception_classname_runme.js
@@ -0,0 +1,6 @@
+var exception_classname = require("exception_classname");
+
+a = new exception_classname.Exception();
+if (a.testfunc() != 42) {
+    throw new Error("Not 42!");
+}
diff --git a/Examples/test-suite/javascript/extend_placement_runme.js b/Examples/test-suite/javascript/extend_placement_runme.js
new file mode 100644
index 0000000..1644cb7
--- /dev/null
+++ b/Examples/test-suite/javascript/extend_placement_runme.js
@@ -0,0 +1,46 @@
+var extend_placement = require("extend_placement");
+
+foo = new extend_placement.Foo();
+foo = new extend_placement.Foo(1);
+foo = new extend_placement.Foo(1, 1);
+foo.spam();
+foo.spam("hello");
+foo.spam(1);
+foo.spam(1, 1);
+foo.spam(1, 1, 1);
+foo.spam(new extend_placement.Foo());
+foo.spam(new extend_placement.Foo(), 1.0);
+
+
+bar = new extend_placement.Bar();
+bar = new extend_placement.Bar(1);
+bar.spam();
+bar.spam("hello");
+bar.spam(1);
+bar.spam(1, 1);
+bar.spam(1, 1, 1);
+bar.spam(new extend_placement.Bar());
+bar.spam(new extend_placement.Bar(), 1.0);
+
+
+foo = new extend_placement.FooTi();
+foo = new extend_placement.FooTi(1);
+foo = new extend_placement.FooTi(1, 1);
+foo.spam();
+foo.spam("hello");
+foo.spam(1);
+foo.spam(1, 1);
+foo.spam(1, 1, 1);
+foo.spam(new extend_placement.Foo());
+foo.spam(new extend_placement.Foo(), 1.0);
+
+
+bar = new extend_placement.BarTi();
+bar = new extend_placement.BarTi(1);
+bar.spam();
+bar.spam("hello");
+bar.spam(1);
+bar.spam(1, 1);
+bar.spam(1, 1, 1);
+bar.spam(new extend_placement.Bar());
+bar.spam(new extend_placement.Bar(), 1.0);
diff --git a/Examples/test-suite/javascript/extend_template_method_runme.js b/Examples/test-suite/javascript/extend_template_method_runme.js
new file mode 100644
index 0000000..4240204
--- /dev/null
+++ b/Examples/test-suite/javascript/extend_template_method_runme.js
@@ -0,0 +1,54 @@
+var extend_template_method = require("extend_template_method");
+
+em = new extend_template_method.ExtendMe();
+
+ret_double = em.do_stuff_double(1, 1.1);
+if (ret_double != 1.1) {
+    throw new Error("double failed " + ret_double);
+}
+ret_string = em.do_stuff_string(1, "hello there");
+if (ret_string != "hello there") {
+    throw new Error("string failed " + ret_string);
+}
+
+ret_double = em.do_overloaded_stuff(1.1);
+if (ret_double != 1.1) {
+    throw new Error("double failed " + ret_double);
+}
+ret_string = em.do_overloaded_stuff("hello there");
+if (ret_string != "hello there") {
+    throw new Error("string failed " + ret_string);
+}
+
+if (extend_template_method.ExtendMe.static_method(123) != 123) {
+    throw new Error("static_method failed");
+}
+
+em2 = new extend_template_method.ExtendMe(123);
+
+em = new extend_template_method.TemplateExtend();
+
+ret_double = em.do_template_stuff_double(1, 1.1);
+if (ret_double != 1.1) {
+    throw new Error("double failed " + ret_double);
+}
+ret_string = em.do_template_stuff_string(1, "hello there");
+if (ret_string != "hello there") {
+    throw new Error("string failed " + ret_string);
+}
+
+
+ret_double = em.do_template_overloaded_stuff(1.1);
+if (ret_double != 1.1) {
+    throw new Error("double failed " + ret_double);
+}
+ret_string = em.do_template_overloaded_stuff("hello there");
+if (ret_string != "hello there") {
+    throw new Error("string failed " + ret_string);
+}
+
+if (extend_template_method.TemplateExtend.static_template_method(123) != 123) {
+    throw new Error("static_template_method failed");
+}
+
+em2 = new extend_template_method.TemplateExtend(123);
diff --git a/Examples/test-suite/javascript/extend_template_ns_runme.js b/Examples/test-suite/javascript/extend_template_ns_runme.js
new file mode 100644
index 0000000..d6ae71c
--- /dev/null
+++ b/Examples/test-suite/javascript/extend_template_ns_runme.js
@@ -0,0 +1,9 @@
+var extend_template_ns = require("extend_template_ns");
+f = new extend_template_ns.Foo_One();
+if (f.test1(37) != 37) {
+    throw new Error;
+}
+
+if (f.test2(42) != 42) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/extend_template_runme.js b/Examples/test-suite/javascript/extend_template_runme.js
new file mode 100644
index 0000000..e8decbb
--- /dev/null
+++ b/Examples/test-suite/javascript/extend_template_runme.js
@@ -0,0 +1,10 @@
+var extend_template = require("extend_template");
+
+f = new extend_template.Foo_0();
+if (f.test1(37) != 37) {
+    throw new Error;
+}
+
+if (f.test2(42) != 42) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/extend_variable_runme.js b/Examples/test-suite/javascript/extend_variable_runme.js
new file mode 100644
index 0000000..5e111a5
--- /dev/null
+++ b/Examples/test-suite/javascript/extend_variable_runme.js
@@ -0,0 +1,5 @@
+var extend_variable = require("extend_variable");
+
+if (extend_variable.Foo.Bar != 42) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/extern_c_runme.js b/Examples/test-suite/javascript/extern_c_runme.js
new file mode 100644
index 0000000..43d60a6
--- /dev/null
+++ b/Examples/test-suite/javascript/extern_c_runme.js
@@ -0,0 +1,12 @@
+var extern_c = require("extern_c");
+
+function check(flag) {
+    if (!flag) {
+        throw new Error("Test failed");
+    }
+}
+
+extern_c.RealFunction(2);
+check(extern_c.int2 == 123);
+check(extern_c.int3 == 456);
+check(extern_c.int4 == 789);
diff --git a/Examples/test-suite/javascript/final_c_runme.js b/Examples/test-suite/javascript/final_c_runme.js
new file mode 100644
index 0000000..98d74ed
--- /dev/null
+++ b/Examples/test-suite/javascript/final_c_runme.js
@@ -0,0 +1,7 @@
+var final_c = require("final_c");
+
+final_c.init();
+f = final_c.final;
+if ((f.yval != 123)) {
+  throw new Error("f.yval fail");
+}
diff --git a/Examples/test-suite/javascript/friends_runme.js b/Examples/test-suite/javascript/friends_runme.js
new file mode 100644
index 0000000..6913eb9
--- /dev/null
+++ b/Examples/test-suite/javascript/friends_runme.js
@@ -0,0 +1,53 @@
+var friends = require("friends");
+
+a = new friends.A(2);
+
+if (friends.get_val1(a) != 2) {
+    throw new Error;
+}
+if (friends.get_val2(a) != 4) {
+    throw new Error;
+}
+if (friends.get_val3(a) != 6) {
+    throw new Error;
+}
+
+// nice overload working fine
+if (friends.get_val1(1, 2, 3) != 1) {
+    throw new Error;
+}
+
+b = new friends.B(3);
+
+// David's case
+if (friends.mix(a, b) != 5) {
+    throw new Error;
+}
+
+di = new friends.D_i(2);
+dd = new friends.D_d(3.3);
+
+// incredible template overloading working just fine
+if (friends.get_val1(di) != 2) {
+    throw new Error;
+}
+if (friends.get_val1(dd) != 3.3) {
+    throw new Error;
+}
+
+friends.set(di, 4);
+friends.set(dd, 1.3);
+
+if (friends.get_val1(di) != 4) {
+    throw new Error;
+}
+if (friends.get_val1(dd) != 1.3) {
+    throw new Error;
+}
+
+if (friends.chum_blah() != 1234) {
+  throw new Error("failed");
+}
+if (friends.mate_blah() != 4321) {
+  throw new Error("failed");
+}
diff --git a/Examples/test-suite/javascript/funcptr_cpp_runme.js b/Examples/test-suite/javascript/funcptr_cpp_runme.js
new file mode 100644
index 0000000..c1f76ca
--- /dev/null
+++ b/Examples/test-suite/javascript/funcptr_cpp_runme.js
@@ -0,0 +1,17 @@
+var funcptr_cpp = require("funcptr_cpp");
+
+if (funcptr_cpp.call1(funcptr_cpp.ADD_BY_VALUE, 10, 11) != 21) {
+    throw new Error;
+}
+if (funcptr_cpp.call2(funcptr_cpp.ADD_BY_POINTER, 12, 13) != 25) {
+    throw new Error;
+}
+if (funcptr_cpp.call3(funcptr_cpp.ADD_BY_REFERENCE, 14, 15) != 29) {
+    throw new Error;
+}
+if (funcptr_cpp.call1(funcptr_cpp.ADD_BY_VALUE_C, 2, 3) != 5) {
+    throw new Error;
+}
+if (funcptr_cpp.callconst1(funcptr_cpp.ADD_BY_VALUE_C, 2, 3) != 5) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/functors_runme.js b/Examples/test-suite/javascript/functors_runme.js
new file mode 100644
index 0000000..1c68282
--- /dev/null
+++ b/Examples/test-suite/javascript/functors_runme.js
@@ -0,0 +1,12 @@
+var functors = require("functors");
+
+var a = new functors.Functor0(10);
+var b = new functors.Functor1(10);
+var c = new functors.Functor2(10);
+
+if (a.Funktor() != -10)
+    throw Error("a failed");
+if (b.Funktor(1) != 11)
+    throw Error("b failed");
+if (c.Funktor(1, 2) != 13)
+    throw Error("c failed");
diff --git a/Examples/test-suite/javascript/fvirtual_runme.js b/Examples/test-suite/javascript/fvirtual_runme.js
new file mode 100644
index 0000000..a6dbcb9
--- /dev/null
+++ b/Examples/test-suite/javascript/fvirtual_runme.js
@@ -0,0 +1,8 @@
+var fvirtual = require('fvirtual');
+
+var sw = new fvirtual.NodeSwitch();
+var n = new fvirtual.Node();
+var i = sw.addChild(n);
+
+if (i != 2)
+    throw Error("addChild");
diff --git a/Examples/test-suite/javascript/global_functions_runme.js b/Examples/test-suite/javascript/global_functions_runme.js
new file mode 100644
index 0000000..f2d8f0e
--- /dev/null
+++ b/Examples/test-suite/javascript/global_functions_runme.js
@@ -0,0 +1,69 @@
+var global_functions = require("global_functions");
+
+
+function check(a, b) {
+    if (a != b) {
+        throw new Error("Failed: " + str(a) + " != " + str(b));
+    }
+}
+global_functions.global_void();
+check(global_functions.global_one(1), 1);
+check(global_functions.global_two(2, 2), 4);
+
+fail = true;
+try {
+    global_functions.global_void(1);
+} catch (e) {
+    if (e instanceof TypeError) fail = false;
+}
+fail = false;
+if (fail) {
+    throw new Error("argument count check failed");
+}
+
+fail = true;
+try {
+    global_functions.global_one();
+} catch (e) {
+    if (e instanceof TypeError) fail = false;
+}
+fail = false;
+if (fail) {
+    throw new Error("argument count check failed");
+}
+
+fail = true;
+try {
+    global_functions.global_one(2, 2);
+} catch (e) {
+    if (e instanceof TypeError) fail = false;
+}
+fail = false;
+
+if (fail) {
+    throw new Error("argument count check failed");
+}
+
+fail = true;
+try {
+    global_functions.global_two(1);
+} catch (e) {
+    if (e instanceof TypeError) fail = false;
+}
+fail = false;
+
+if (fail) {
+    throw new Error("argument count check failed");
+}
+
+fail = true;
+try {
+    global_functions.global_two(3, 3, 3);
+} catch (e) {
+    if (e instanceof TypeError) fail = false;
+}
+fail = false;
+
+if (fail) {
+    throw new Error("argument count check failed");
+}
diff --git a/Examples/test-suite/javascript/global_namespace_runme.js b/Examples/test-suite/javascript/global_namespace_runme.js
new file mode 100644
index 0000000..f90fece
--- /dev/null
+++ b/Examples/test-suite/javascript/global_namespace_runme.js
@@ -0,0 +1,41 @@
+var global_namespace = require("global_namespace");
+
+
+k1 = new global_namespace.Klass1();
+k2 = new global_namespace.Klass2();
+k3 = new global_namespace.Klass3();
+k4 = new global_namespace.Klass4();
+k5 = new global_namespace.Klass5();
+k6 = new global_namespace.Klass6();
+k7 = new global_namespace.Klass7();
+
+global_namespace.KlassMethods.methodA(k1, k2, k3, k4, k5, k6, k7);
+global_namespace.KlassMethods.methodB(k1, k2, k3, k4, k5, k6, k7);
+
+k1 = global_namespace.getKlass1A();
+k2 = global_namespace.getKlass2A();
+k3 = global_namespace.getKlass3A();
+k4 = global_namespace.getKlass4A();
+k5 = global_namespace.getKlass5A();
+k6 = global_namespace.getKlass6A();
+k7 = global_namespace.getKlass7A();
+
+global_namespace.KlassMethods.methodA(k1, k2, k3, k4, k5, k6, k7);
+global_namespace.KlassMethods.methodB(k1, k2, k3, k4, k5, k6, k7);
+
+k1 = global_namespace.getKlass1B();
+k2 = global_namespace.getKlass2B();
+k3 = global_namespace.getKlass3B();
+k4 = global_namespace.getKlass4B();
+k5 = global_namespace.getKlass5B();
+k6 = global_namespace.getKlass6B();
+k7 = global_namespace.getKlass7B();
+
+global_namespace.KlassMethods.methodA(k1, k2, k3, k4, k5, k6, k7);
+global_namespace.KlassMethods.methodB(k1, k2, k3, k4, k5, k6, k7);
+
+global_namespace.XYZMethods.methodA(new global_namespace.XYZ1(), new global_namespace.XYZ2(), new global_namespace.XYZ3(), new global_namespace.XYZ4(), new global_namespace.XYZ5(), new global_namespace.XYZ6(), new global_namespace.XYZ7());
+global_namespace.XYZMethods.methodB(new global_namespace.XYZ1(), new global_namespace.XYZ2(), new global_namespace.XYZ3(), new global_namespace.XYZ4(), new global_namespace.XYZ5(), new global_namespace.XYZ6(), new global_namespace.XYZ7());
+
+global_namespace.TheEnumMethods.methodA(global_namespace.theenum1, global_namespace.theenum2, global_namespace.theenum3);
+global_namespace.TheEnumMethods.methodA(global_namespace.theenum1, global_namespace.theenum2, global_namespace.theenum3);
diff --git a/Examples/test-suite/javascript/global_ns_arg_runme.js b/Examples/test-suite/javascript/global_ns_arg_runme.js
new file mode 100644
index 0000000..fbbc659
--- /dev/null
+++ b/Examples/test-suite/javascript/global_ns_arg_runme.js
@@ -0,0 +1,4 @@
+var global_ns_arg = require("global_ns_arg");
+
+a = global_ns_arg.foo(1);
+b = global_ns_arg.bar_fn();
diff --git a/Examples/test-suite/javascript/global_vars_runme.js b/Examples/test-suite/javascript/global_vars_runme.js
new file mode 100644
index 0000000..1f5e171
--- /dev/null
+++ b/Examples/test-suite/javascript/global_vars_runme.js
@@ -0,0 +1,25 @@
+var global_vars = require("global_vars");
+
+// In javascript, assigning to a non-existent variable is
+// not an error
+
+global_vars.init();
+b = global_vars.b;
+if (b != "string b") {
+    throw new Error("Unexpected string: " + b.toString());
+}
+global_vars.b = "a string value";
+b = global_vars.b;
+if (b != "a string value") {
+    throw new Error("Unexpected string: " + b.toString());
+}
+
+x = global_vars.x;
+if (x != 1234) {
+    throw new Error("Unexpected x: " + x.toString());
+}
+global_vars.x = 9876;
+x = global_vars.x;
+if (x != 9876) {
+    throw new Error("Unexpected string: " + x.toString());
+}
diff --git a/Examples/test-suite/javascript/grouping_runme.js b/Examples/test-suite/javascript/grouping_runme.js
new file mode 100644
index 0000000..2649dea
--- /dev/null
+++ b/Examples/test-suite/javascript/grouping_runme.js
@@ -0,0 +1,15 @@
+var grouping = require("grouping");
+
+var x = grouping.test1(42);
+if (x != 42)
+    throw new Error;
+
+grouping.test2(42);
+
+var x = grouping.do_unary(37, grouping.NEGATE);
+if (x != -37)
+    throw new Error;
+
+grouping.test3 = 42;
+if (grouping.test3 !== 42)
+    throw new Error;
diff --git a/Examples/test-suite/javascript/iadd_runme.js b/Examples/test-suite/javascript/iadd_runme.js
new file mode 100644
index 0000000..0036ac3
--- /dev/null
+++ b/Examples/test-suite/javascript/iadd_runme.js
@@ -0,0 +1,9 @@
+var iadd = require('iadd');
+
+var f = new iadd.Foo();
+
+f.AsA.x = 3;
+f.AsA.addto(f.AsA);
+
+if (f.AsA.x != 6)
+    throw new Error;
diff --git a/Examples/test-suite/javascript/ignore_parameter_runme.js b/Examples/test-suite/javascript/ignore_parameter_runme.js
new file mode 100644
index 0000000..07dcf2f
--- /dev/null
+++ b/Examples/test-suite/javascript/ignore_parameter_runme.js
@@ -0,0 +1,24 @@
+const ignore_parameter = require('ignore_parameter');
+
+function check(a, b) {
+  if (a !== b) throw new Error(`'${a}' != '${b}`);
+}
+
+check(ignore_parameter.jaguar(200, 0), "hello");
+check(ignore_parameter.lotus("foo", 1), 101);
+check(ignore_parameter.tvr("bar", 2), 8.8);
+check(ignore_parameter.ferrari(), 101);
+check(ignore_parameter.fiat(17), 17);
+
+car = new ignore_parameter.SportsCars();
+check(car.daimler(200, 0), "hello");
+check(car.astonmartin("foo", 1), 101);
+check(car.bugatti("bar", 2), 8.8);
+check(car.lamborghini(), 101);
+check(car.maseratti(289), 289);
+check(car.audi(), 8.8);
+
+new ignore_parameter.MiniCooper(200, 0);
+new ignore_parameter.MorrisMinor("baz", 0);
+new ignore_parameter.FordAnglia("quux", 200);
+new ignore_parameter.AustinAllegro();
diff --git a/Examples/test-suite/javascript/import_nomodule_runme.js b/Examples/test-suite/javascript/import_nomodule_runme.js
new file mode 100644
index 0000000..ad33401
--- /dev/null
+++ b/Examples/test-suite/javascript/import_nomodule_runme.js
@@ -0,0 +1,8 @@
+var import_nomodule = require("import_nomodule");
+
+f = import_nomodule.create_Foo();
+import_nomodule.test1(f, 42);
+import_nomodule.delete_Foo(f);
+
+b = new import_nomodule.Bar();
+import_nomodule.test1(b, 37);
diff --git a/Examples/test-suite/javascript/inctest_runme.js b/Examples/test-suite/javascript/inctest_runme.js
new file mode 100644
index 0000000..e0a42ea
--- /dev/null
+++ b/Examples/test-suite/javascript/inctest_runme.js
@@ -0,0 +1,22 @@
+var inctest = require("inctest");
+
+try {
+    a = new inctest.A();
+} catch (e) {
+    throw new Error("didn't find A, therefore, I didn't include 'testdir/subdir1/hello.i'");
+}
+
+try {
+    b = new inctest.B();
+} catch (e) {
+    throw new Error("didn't find B, therefore, I didn't include 'testdir/subdir2/hello.i'");
+}
+
+// Check the var in subdirectory worked = require("in subdirectory worked")
+if (inctest.importtest1(5) != 15) {
+    throw new Error("var test 1 failed");
+}
+
+if (inctest.importtest2("black") != "white") {
+    throw new Error("var test 2 failed");
+}
diff --git a/Examples/test-suite/javascript/inherit_missing_runme.js b/Examples/test-suite/javascript/inherit_missing_runme.js
new file mode 100644
index 0000000..05f5760
--- /dev/null
+++ b/Examples/test-suite/javascript/inherit_missing_runme.js
@@ -0,0 +1,19 @@
+var inherit_missing = require("inherit_missing");
+
+a = inherit_missing.new_Foo()
+b = new inherit_missing.Bar()
+c = new inherit_missing.Spam()
+
+x = inherit_missing.do_blah(a)
+if (x != "Foo::blah")
+    throw new Error("Whoa! Bad return {}".format(x))
+
+x = inherit_missing.do_blah(b)
+if (x != "Bar::blah")
+    throw new Error("Whoa! Bad return {}".format(x))
+
+x = inherit_missing.do_blah(c)
+if (x != "Spam::blah")
+    throw new Error("Whoa! Bad return {}".format(x))
+
+inherit_missing.delete_Foo(a)
diff --git a/Examples/test-suite/javascript/inplaceadd_runme.js b/Examples/test-suite/javascript/inplaceadd_runme.js
new file mode 100644
index 0000000..436d581
--- /dev/null
+++ b/Examples/test-suite/javascript/inplaceadd_runme.js
@@ -0,0 +1,23 @@
+var inplaceadd = require("inplaceadd");
+a = new inplaceadd.A(7);
+
+a.addTo(5);
+if (a.val != 12) {
+    throw new Error(`a.val: ${a.val}`);
+}
+
+a.subFrom(5);
+if (a.val != 7) {
+    throw new Error(`a.val: ${a.val}`);
+}
+
+a.mulTo(2);
+
+if (a.val != 14) {
+    throw new Error(`a.val: ${a.val}`);
+}
+
+a.addTo(a);
+if (a.val != 28) {
+    throw new Error(`a.val: ${a.val}`);
+}
diff --git a/Examples/test-suite/javascript/input_runme.js b/Examples/test-suite/javascript/input_runme.js
new file mode 100644
index 0000000..bc970f0
--- /dev/null
+++ b/Examples/test-suite/javascript/input_runme.js
@@ -0,0 +1,22 @@
+var input = require("input");
+
+f = new input.Foo();
+if (f.foo(2) != 4) {
+    throw new Error;
+}
+
+if (f.foo(null) != null) {
+    throw new Error;
+}
+
+if (f.foo() != null) {
+    throw new Error;
+}
+
+if (input.sfoo("Hello") != "Hello world") {
+    throw new Error;
+}
+
+if (input.sfoo() != null) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/integers_runme.js b/Examples/test-suite/javascript/integers_runme.js
new file mode 100644
index 0000000..4aeb13d
--- /dev/null
+++ b/Examples/test-suite/javascript/integers_runme.js
@@ -0,0 +1,24 @@
+var integers = require("integers");
+
+function checkOne(val, signed, typeName) {
+  typeName = (signed ? 'signed_' : 'unsigned_') + typeName
+
+  var size = integers[typeName + '_size']()
+  if ((!signed && val < 0) || (size < 8))
+    return // out of range, skip test
+
+  ret = integers[typeName + '_identity'](val)
+  if (ret !== val)
+    throw "Incorrect value: expected " + val + ", got " + ret
+}
+
+function checkAll(val) {
+  checkOne(val, true, 'long')
+  checkOne(val, false, 'long')
+  checkOne(val, true, 'long_long')
+  checkOne(val, false, 'long_long')
+}
+
+checkAll(3902408827)
+checkAll(Number.MAX_SAFE_INTEGER)
+checkAll(Number.MIN_SAFE_INTEGER)
diff --git a/Examples/test-suite/javascript/javascript_lib_arrays_runme.js b/Examples/test-suite/javascript/javascript_lib_arrays_runme.js
new file mode 100644
index 0000000..1eb5861
--- /dev/null
+++ b/Examples/test-suite/javascript/javascript_lib_arrays_runme.js
@@ -0,0 +1,20 @@
+var javascript_lib_arrays = require("javascript_lib_arrays");
+
+var arr = [1, 2, 3, 4, 5];
+
+function check(a, b) {
+  if (a !== b) {
+    throw new Error("Not equal: " + a + " " + b)
+  }
+}
+
+function check_array(a, b) {
+  if (a.length != b.length)
+    throw new Error("Array length mismatch " + a.length + " " + b.length)
+  if (!a.every(function(element, index) { return element === b[index]; }))
+    throw new Error("Arrays don't match a:" + a + " b:" + b)
+}
+
+check(15, javascript_lib_arrays.sum1(arr, arr.length));
+check(6, javascript_lib_arrays.sum2(arr));
+check_array([1, 2, 3, 4], javascript_lib_arrays.data3)
diff --git a/Examples/test-suite/javascript/keyword_rename_c_runme.js b/Examples/test-suite/javascript/keyword_rename_c_runme.js
new file mode 100644
index 0000000..1484437
--- /dev/null
+++ b/Examples/test-suite/javascript/keyword_rename_c_runme.js
@@ -0,0 +1,3 @@
+var keyword_rename_c = require("keyword_rename_c");
+keyword_rename_c._instanceof(1);
+keyword_rename_c._finally(1);
diff --git a/Examples/test-suite/javascript/keyword_rename_runme.js b/Examples/test-suite/javascript/keyword_rename_runme.js
new file mode 100644
index 0000000..54b9ecc
--- /dev/null
+++ b/Examples/test-suite/javascript/keyword_rename_runme.js
@@ -0,0 +1,3 @@
+var keyword_rename = require("keyword_rename")
+keyword_rename._instanceof(1)
+keyword_rename._finally(1)
diff --git a/Examples/test-suite/javascript/langobj_runme.js b/Examples/test-suite/javascript/langobj_runme.js
new file mode 100644
index 0000000..c033c98
--- /dev/null
+++ b/Examples/test-suite/javascript/langobj_runme.js
@@ -0,0 +1,7 @@
+var langobj = require("langobj");
+
+x = "hello";
+v = langobj.identity(x);
+if (v !== x) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/li_attribute_runme.js b/Examples/test-suite/javascript/li_attribute_runme.js
new file mode 100644
index 0000000..707bea1
--- /dev/null
+++ b/Examples/test-suite/javascript/li_attribute_runme.js
@@ -0,0 +1,107 @@
+var li_attribute = require("li_attribute");
+
+aa = new li_attribute.A(1, 2, 3);
+
+if (aa.a != 1) {
+    throw new Error;
+}
+aa.a = 3;
+if (aa.a != 3) {
+    throw new Error("aa.a: {}" + aa.a.toString());
+}
+
+if (aa.b != 2) {
+    throw new Error("aa.b: {}" + aa.b.toString());
+}
+aa.b = 5;
+if (aa.b != 5) {
+    throw new Error;
+}
+
+if (aa.d != aa.b) {
+    throw new Error;
+}
+
+if (aa.c != 3) {
+    throw new Error;
+}
+fail = true;
+try {
+    aa.c = 5;
+} catch (e) {
+    fail = false;
+}
+if (aa.c != 3 || fail) {
+    throw new Error;
+}
+
+pi = new li_attribute.Param_i(7);
+if (pi.value != 7) {
+    throw new Error;
+}
+
+pi.value = 3;
+if (pi.value != 3) {
+    throw new Error;
+}
+
+b = new li_attribute.B(aa);
+
+if (b.a.c != 3) {
+    throw new Error;
+}
+
+// class/struct attribute with get/set methods using return/pass by reference
+myFoo = new li_attribute.MyFoo();
+myFoo.x = 8;
+myClass = new li_attribute.MyClass();
+myClass.Foo = myFoo;
+if (myClass.Foo.x != 8) {
+    throw new Error;
+}
+myClass.Foo2 = myFoo;
+if (myClass.Foo2.x != 8) {
+    throw new Error;
+}
+
+// class/struct attribute with get/set methods using return/pass by value
+myClassVal = new li_attribute.MyClassVal();
+if (myClassVal.ReadWriteFoo.x != -1) {
+    throw new Error;
+}
+if (myClassVal.ReadOnlyFoo.x != -1) {
+    throw new Error;
+}
+myClassVal.ReadWriteFoo = myFoo;
+if (myClassVal.ReadWriteFoo.x != 8) {
+    throw new Error;
+}
+if (myClassVal.ReadOnlyFoo.x != 8) {
+    throw new Error;
+}
+
+// string attribute with get/set methods using return/pass by value
+myStringyClass = new li_attribute.MyStringyClass("initial string");
+if (myStringyClass.ReadWriteString != "initial string") {
+    throw new Error;
+}
+if (myStringyClass.ReadOnlyString != "initial string") {
+    throw new Error;
+}
+myStringyClass.ReadWriteString = "changed string";
+if (myStringyClass.ReadWriteString != "changed string") {
+    throw new Error;
+}
+if (myStringyClass.ReadOnlyString != "changed string") {
+    throw new Error;
+}
+
+// In JS, accessing a non-existing attribute does not throw, it returns undefined
+if (myFoo.does_not_exist !== undefined) {
+    throw new Error;
+}
+// Additionally, creating attributes is always possible unless the object is frozen
+myFoo.does_not_exist = 'value';
+if (myFoo.does_not_exist !== 'value') {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/li_attribute_template_runme.js b/Examples/test-suite/javascript/li_attribute_template_runme.js
new file mode 100644
index 0000000..57a934e
--- /dev/null
+++ b/Examples/test-suite/javascript/li_attribute_template_runme.js
@@ -0,0 +1,69 @@
+// Check usage of template attributes
+
+var li_attribute_template = require("li_attribute_template");
+
+chell = new li_attribute_template.Cintint(1, 2, 3);
+
+
+function rassert(what, master) {
+    if (what != master) {
+        throw new Error("what: {}".format(what));
+    }
+}
+
+// Testing primitive by value attribute
+rassert(chell.a, 1);
+
+chell.a = 3;
+rassert(chell.a, 3);
+
+// Testing primitive by ref attribute
+
+rassert(chell.b, 2);
+
+chell.b = 5;
+rassert(chell.b, 5);
+
+// Testing string
+chell.str = "abc";
+rassert(chell.str, "abc");
+
+// Testing class by value
+
+rassert(chell.d.value, 1);
+
+chell.d = new li_attribute_template.Foo(2);
+rassert(chell.d.value, 2);
+
+// Testing class by reference
+
+rassert(chell.e.value, 2);
+
+chell.e = new li_attribute_template.Foo(3);
+rassert(chell.e.value, 3);
+
+chell.e.value = 4;
+rassert(chell.e.value, 4);
+
+// Testing moderately complex template by value
+rassert(chell.f.first, 1);
+rassert(chell.f.second, 2);
+
+pair = new li_attribute_template.pair_intint(3, 4);
+chell.f = pair;
+rassert(chell.f.first, 3);
+rassert(chell.f.second, 4);
+
+// Testing moderately complex template by ref
+rassert(chell.g.first, 2);
+rassert(chell.g.second, 3);
+
+pair = new li_attribute_template.pair_intint(4, 5);
+chell.g = pair;
+rassert(chell.g.first, 4);
+rassert(chell.g.second, 5);
+
+chell.g.first = 6;
+chell.g.second = 7;
+rassert(chell.g.first, 6);
+rassert(chell.g.second, 7);
diff --git a/Examples/test-suite/javascript/li_carrays_cpp_runme.js b/Examples/test-suite/javascript/li_carrays_cpp_runme.js
new file mode 100644
index 0000000..ca4802e
--- /dev/null
+++ b/Examples/test-suite/javascript/li_carrays_cpp_runme.js
@@ -0,0 +1,25 @@
+var li_carrays_cpp = require("li_carrays_cpp");
+
+d = new li_carrays_cpp.doubleArray(10);
+
+d.setitem(0, 7);
+d.setitem(5, d.getitem(0) + 3);
+
+if (d.getitem(5) + d.getitem(0) != 17) {
+    throw new Error;
+}
+
+shorts = new li_carrays_cpp.shortArray(5);
+
+sum = li_carrays_cpp.sum_array(shorts);
+if (sum != 0) {
+    throw new Error("incorrect zero sum, got: " + sum.toString());
+}
+
+for (i = 0; i < 5; i++)
+    shorts.setitem(i, i);
+
+sum = li_carrays_cpp.sum_array(shorts);
+if (sum != 0 + 1 + 2 + 3 + 4) {
+    throw new Error("incorrect sum, got: " + sum.toString());
+}
diff --git a/Examples/test-suite/javascript/li_carrays_runme.js b/Examples/test-suite/javascript/li_carrays_runme.js
new file mode 100644
index 0000000..44f1f26
--- /dev/null
+++ b/Examples/test-suite/javascript/li_carrays_runme.js
@@ -0,0 +1,25 @@
+var li_carrays = require("li_carrays");
+
+d = new li_carrays.doubleArray(10);
+
+d.setitem(0, 7);
+d.setitem(5, d.getitem(0) + 3);
+
+if (d.getitem(5) + d.getitem(0) != 17) {
+    throw new Error;
+}
+
+shorts = new li_carrays.shortArray(5);
+
+sum = li_carrays.sum_array(shorts);
+if (sum != 0) {
+    throw new Error("incorrect zero sum, got: " + sum.toString());
+}
+
+for (i = 0; i < 5; i++)
+    shorts.setitem(i, i);
+
+sum = li_carrays.sum_array(shorts);
+if (sum != 0 + 1 + 2 + 3 + 4) {
+    throw new Error("incorrect sum, got: " + sum.toString());
+}
diff --git a/Examples/test-suite/javascript/li_cdata_cpp_runme.js b/Examples/test-suite/javascript/li_cdata_cpp_runme.js
new file mode 100644
index 0000000..1a88d00
--- /dev/null
+++ b/Examples/test-suite/javascript/li_cdata_cpp_runme.js
@@ -0,0 +1,10 @@
+
+var li_cdata_cpp = require("li_cdata_cpp");
+
+s = "ABC abc";
+m = li_cdata_cpp.malloc(256);
+li_cdata_cpp.memmove(m, s);
+ss = li_cdata_cpp.cdata(m, 7);
+if (ss !== "ABC abc") {
+    throw new Error("failed");
+}
diff --git a/Examples/test-suite/javascript/li_cdata_runme.js b/Examples/test-suite/javascript/li_cdata_runme.js
new file mode 100644
index 0000000..38c8467
--- /dev/null
+++ b/Examples/test-suite/javascript/li_cdata_runme.js
@@ -0,0 +1,10 @@
+
+var li_cdata = require("li_cdata");
+
+s = "ABC abc";
+m = li_cdata.malloc(256);
+li_cdata.memmove(m, s);
+ss = li_cdata.cdata(m, 7);
+if (ss !== "ABC abc") {
+    throw new Error("failed");
+}
diff --git a/Examples/test-suite/javascript/li_cmalloc_runme.js b/Examples/test-suite/javascript/li_cmalloc_runme.js
new file mode 100644
index 0000000..5c2ba85
--- /dev/null
+++ b/Examples/test-suite/javascript/li_cmalloc_runme.js
@@ -0,0 +1,16 @@
+var li_cmalloc = require("li_cmalloc");
+
+p = li_cmalloc.malloc_int(1);
+li_cmalloc.free_int(p);
+
+ok = false;
+try {
+    p = li_cmalloc.calloc_int(-1);
+    li_cmalloc.free_int(p);
+} catch {
+    ok = true;
+}
+
+if (!ok) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/li_constraints_runme.js b/Examples/test-suite/javascript/li_constraints_runme.js
new file mode 100644
index 0000000..785ca44
--- /dev/null
+++ b/Examples/test-suite/javascript/li_constraints_runme.js
@@ -0,0 +1,58 @@
+var li_constraints = require("li_constraints");
+
+function check_double(except, f, val, name) {
+  var actual = true;
+  var proper = false;
+  try {
+    f(val);
+  } catch(e) {
+    actual = false;
+    proper = e.message === "Expected a " + name + " value.";
+  }
+  if (actual) {
+    if (!except)
+      throw new Error("function '" + name + "' with " + val + " should perform an exception");
+  } else {
+    if (except)
+      throw new Error("function '" + name + "' with " + val + " should not perform an exception");
+    else if (!proper)
+      throw new Error("function '" + name + "' with " + val + " should perform a proper exception");
+  }
+}
+
+const nonnegative = function (val) { li_constraints.test_nonnegative(val); };
+check_double(true, nonnegative, 10, "non-negative");
+check_double(true, nonnegative, 0, "non-negative");
+check_double(false, nonnegative, -10, "non-negative");
+
+const nonpositive = function (val) { li_constraints.test_nonpositive(val); };
+check_double(false, nonpositive, 10, "non-positive");
+check_double(true, nonpositive, 0, "non-positive");
+check_double(true, nonpositive, -10, "non-positive");
+
+const positive = function (val) { li_constraints.test_positive(val); };
+check_double(true, positive, 10, "positive");
+check_double(false, positive, 0, "positive");
+check_double(false, positive, -10, "positive");
+
+const negative = function (val) { li_constraints.test_negative(val); };
+check_double(false, negative, 10, "negative");
+check_double(false, negative, 0, "negative");
+check_double(true, negative, -10, "negative");
+
+const nonzero = function (val) { li_constraints.test_nonzero(val); };
+check_double(true, nonzero, 10, "nonzero");
+check_double(false, nonzero, 0, "nonzero");
+check_double(true, nonzero, -10, "nonzero");
+
+var have_exception = false;
+try {
+  li_constraints.test_nonnull(null);
+} catch(e) {
+  have_exception = e.message === "Received a NULL pointer.";
+}
+if (!have_exception) {
+    throw new Error("test_nonnull should perform a proper exception with 'null' value");
+}
+const nonnull = li_constraints.get_nonnull();
+li_constraints.test_nonnull(nonnull);
diff --git a/Examples/test-suite/javascript/li_cpointer_cpp_runme.js b/Examples/test-suite/javascript/li_cpointer_cpp_runme.js
new file mode 100644
index 0000000..4ba19ee
--- /dev/null
+++ b/Examples/test-suite/javascript/li_cpointer_cpp_runme.js
@@ -0,0 +1,16 @@
+var li_cpointer_cpp = require("li_cpointer_cpp");
+
+
+p = li_cpointer_cpp.new_intp();
+
+if (li_cpointer_cpp.intp_value(p) != 0) {
+    throw new Error("not initialized");
+}
+
+li_cpointer_cpp.intp_assign(p, 3);
+
+if (li_cpointer_cpp.intp_value(p) != 3) {
+    throw new Error;
+}
+
+li_cpointer_cpp.delete_intp(p);
diff --git a/Examples/test-suite/javascript/li_cpointer_runme.js b/Examples/test-suite/javascript/li_cpointer_runme.js
new file mode 100644
index 0000000..836b79f
--- /dev/null
+++ b/Examples/test-suite/javascript/li_cpointer_runme.js
@@ -0,0 +1,16 @@
+var li_cpointer = require("li_cpointer");
+
+
+p = li_cpointer.new_intp();
+
+if (li_cpointer.intp_value(p) != 0) {
+    throw new Error("not initialized");
+}
+
+li_cpointer.intp_assign(p, 3);
+
+if (li_cpointer.intp_value(p) != 3) {
+    throw new Error;
+}
+
+li_cpointer.delete_intp(p);
diff --git a/Examples/test-suite/javascript/li_factory_runme.js b/Examples/test-suite/javascript/li_factory_runme.js
new file mode 100644
index 0000000..c7a963f
--- /dev/null
+++ b/Examples/test-suite/javascript/li_factory_runme.js
@@ -0,0 +1,13 @@
+var li_factory = require("li_factory");
+
+circle = li_factory.Geometry.create(li_factory.Geometry.CIRCLE);
+r = circle.radius();
+if ((r != 1.5)) {
+    throw new Error;
+}
+
+point = li_factory.Geometry.create(li_factory.Geometry.POINT);
+w = point.width();
+if ((w != 1.0)) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/li_std_auto_ptr_runme.js b/Examples/test-suite/javascript/li_std_auto_ptr_runme.js
new file mode 100644
index 0000000..b336076
--- /dev/null
+++ b/Examples/test-suite/javascript/li_std_auto_ptr_runme.js
@@ -0,0 +1,130 @@
+var li_std_auto_ptr = require("li_std_auto_ptr");
+
+var checkCount = function(expected_count) {
+  actual_count = li_std_auto_ptr.Klass.getTotal_count();
+  if (actual_count != expected_count)
+    throw new Error("Counts incorrect, expected:" + expected_count + " actual:" + actual_count);
+}
+
+// Test raw pointer handling involving virtual inheritance
+{
+  kini = new li_std_auto_ptr.KlassInheritance("KlassInheritanceInput");
+  checkCount(1);
+  s = li_std_auto_ptr.useKlassRawPtr(kini);
+  if (s !== "KlassInheritanceInput")
+    throw new Error("Incorrect string: " + s);
+  // delete kini;
+  // Above not deleting the C++ object(node v12) - can't reliably control GC
+  li_std_auto_ptr.takeKlassAutoPtr(kini);
+  checkCount(0);
+}
+
+
+// auto_ptr as input
+{
+  kin = new li_std_auto_ptr.Klass("KlassInput");
+  checkCount(1);
+  s = li_std_auto_ptr.takeKlassAutoPtr(kin);
+  checkCount(0);
+  if (s !== "KlassInput")
+    throw new Error("Incorrect string: " + s);
+  if (!li_std_auto_ptr.is_nullptr(kin))
+    throw new Error("is_nullptr failed");
+  delete kin; // Should not fail, even though already deleted
+  checkCount(0);
+}
+
+{
+  kin = new li_std_auto_ptr.Klass("KlassInput");
+  checkCount(1);
+  s = li_std_auto_ptr.takeKlassAutoPtr(kin);
+  checkCount(0);
+  if (s !== "KlassInput")
+    throw new Error("Incorrect string: " + s);
+  if (!li_std_auto_ptr.is_nullptr(kin))
+    throw new Error("is_nullptr failed");
+  exception_thrown = false;
+  try {
+    li_std_auto_ptr.takeKlassAutoPtr(kin);
+  } catch (e) {
+    if (!e.message.includes("cannot release ownership as memory is not owned"))
+      throw new Error("incorrect exception message " + e.message);
+    exception_thrown = true;
+  }
+  if (!exception_thrown)
+      throw new Error("double usage of takeKlassAutoPtr should have been an error");
+  delete kin; // Should not fail, even though already deleted
+  checkCount(0);
+}
+
+{
+  kin = new li_std_auto_ptr.Klass("KlassInput");
+  exception_thrown = false;
+  notowned = li_std_auto_ptr.get_not_owned_ptr(kin);
+  try {
+    li_std_auto_ptr.takeKlassAutoPtr(notowned);
+  } catch (e) {
+    if (!e.message.includes("cannot release ownership as memory is not owned"))
+      throw new Error("incorrect exception message " + e.message);
+    exception_thrown = true;
+  }
+  if (!exception_thrown)
+    throw new Error("Should have thrown 'Cannot release ownership as memory is not owned' error");
+  checkCount(1);
+  // delete kin;
+  // Above not deleting the C++ object(node v12) - can't reliably control GC
+  li_std_auto_ptr.takeKlassAutoPtr(kin);
+  checkCount(0);
+}
+
+{
+  kini = new li_std_auto_ptr.KlassInheritance("KlassInheritanceInput");
+  checkCount(1);
+  s = li_std_auto_ptr.takeKlassAutoPtr(kini);
+  checkCount(0);
+  if (s !== "KlassInheritanceInput")
+    throw new Error("Incorrect string: " + s);
+  if (!li_std_auto_ptr.is_nullptr(kini))
+    throw new Error("is_nullptr failed");
+  delete kini; // Should not fail, even though already deleted
+  checkCount(0);
+}
+
+li_std_auto_ptr.takeKlassAutoPtr(null);
+li_std_auto_ptr.takeKlassAutoPtr(li_std_auto_ptr.make_null());
+checkCount(0);
+
+// overloaded parameters
+if (li_std_auto_ptr.overloadTest() != 0)
+  throw new Error("overloadTest failed");
+if (li_std_auto_ptr.overloadTest(null) != 1)
+  throw new Error("overloadTest failed");
+if (li_std_auto_ptr.overloadTest(new li_std_auto_ptr.Klass("over")) != 1)
+  throw new Error("overloadTest failed");
+checkCount(0);
+
+
+// auto_ptr as output
+k1 = li_std_auto_ptr.makeKlassAutoPtr("first");
+if (k1.getLabel() !== "first")
+  throw new Error("wrong object label");
+
+k2 = li_std_auto_ptr.makeKlassAutoPtr("second");
+checkCount(2);
+
+// delete k1;
+// Above not deleting the C++ object(node v12) - can't reliably control GC
+li_std_auto_ptr.takeKlassAutoPtr(k1);
+checkCount(1);
+
+if (k2.getLabel() !== "second")
+  throw new Error("wrong object label");
+
+// delete k2;
+// Above not deleting the C++ object(node v12) - can't reliably control GC
+li_std_auto_ptr.takeKlassAutoPtr(k2);
+
+if (li_std_auto_ptr.makeNullAutoPtr() != null)
+  throw new Error("null failure");
+
+checkCount(0);
diff --git a/Examples/test-suite/javascript/li_std_containers_int_runme.js b/Examples/test-suite/javascript/li_std_containers_int_runme.js
new file mode 100644
index 0000000..88688e3
--- /dev/null
+++ b/Examples/test-suite/javascript/li_std_containers_int_runme.js
@@ -0,0 +1,37 @@
+// In JS std::vector and std::list cannot behave as native containers
+// because there is no overloading
+var li_std_containers_int = require("li_std_containers_int");
+
+function set_check(container, idx, value, size) {
+    container.set(idx, value);
+    if (container.get(idx) !== value)
+        throw new Error(
+            `Failed setting value at ${idx} in ${container.toString} to ${value}, got ${container.getitem(idx)}`);
+    if (container.size() != size)
+        throw new Error(`Expected a size of ${size}, got ${container.size()}`);
+}
+
+function err_check(container, idx, value, size) {
+    let fail = true;
+    try {
+        container.set(idx, value);
+    } catch {
+        fail = false;
+    }
+    if (fail) throw new Error(
+        `Expected an exception setting value at ${idx} in ${container.toString} to ${value}, got ${container.get(idx)}`);
+    if (container.size() != size)
+        throw new Error(`Expected a size of ${size}, got ${container.size()}`);
+}
+
+var vector;
+
+vector = new li_std_containers_int.vector_int();
+err_check(vector, 0, 10, 0);
+
+vector = new li_std_containers_int.vector_int(2);
+set_check(vector, 0, 10, 2);
+set_check(vector, 1, 0, 2);
+err_check(vector, 2, 20, 2);
+err_check(vector, 0, 'string', 2);
+err_check(vector, 0, {}, 2);
diff --git a/Examples/test-suite/javascript/li_std_map_member_runme.js b/Examples/test-suite/javascript/li_std_map_member_runme.js
new file mode 100644
index 0000000..98e2745
--- /dev/null
+++ b/Examples/test-suite/javascript/li_std_map_member_runme.js
@@ -0,0 +1,13 @@
+var li_std_map_member = require("li_std_map_member");
+
+a = new li_std_map_member.mapita();
+a.set(1, new li_std_map_member.TestA());
+
+if ((a.get(1).i != 1)) {
+    throw new Error("a[1] != 1");
+}
+
+a.get(1).i = 2;
+if ((a.get(1).i != 2)) {
+    throw new Error("a[1] != 2");
+}
diff --git a/Examples/test-suite/javascript/li_std_map_runme.js b/Examples/test-suite/javascript/li_std_map_runme.js
new file mode 100644
index 0000000..5f9b0f6
--- /dev/null
+++ b/Examples/test-suite/javascript/li_std_map_runme.js
@@ -0,0 +1,49 @@
+// In JavaScript, std::map has very limited capabilities and no iterator at all
+var li_std_map = require("li_std_map");
+
+function set_check(container, idx, value, size) {
+    container.set(idx, value);
+    if (container.get(idx) !== value)
+        throw new Error(
+            `Failed setting value at ${idx} in ${container.toString} to ${value}, got ${container.getitem(idx)}`);
+    if (container.size() != size)
+        throw new Error(`Expected a size of ${size}, got ${container.size()}`);
+}
+
+function err_check(container, idx, value, size) {
+    let fail = true;
+    try {
+        container.set(idx, value);
+    } catch {
+        fail = false;
+    }
+    if (fail) throw new Error(
+        `Expected an exception setting value at ${idx} in ${container.toString} to ${value}, got ${container.get(idx)}`);
+    if (container.size() != size)
+        throw new Error(`Expected a size of ${size}, got ${container.size()}`);
+}
+
+var map;
+
+map = new li_std_map.IntIntMap();
+set_check(map, 0, 10, 1);
+set_check(map, 1, 0, 2);
+set_check(map, 2, 20, 3);
+err_check(map, 0, 'string', 3);
+
+if (!map.has_key(2)) throw new Error('Expected key to be found');
+if (map.has_key(5)) throw new Error('Expected key to not be found');
+map.del(2);
+if (map.has_key(2)) throw new Error('Expected key to not be found');
+
+
+map = new li_std_map.StringIntMap();
+set_check(map, '0', 10, 1);
+set_check(map, '1', 0, 2);
+set_check(map, '2', 20, 3);
+err_check(map, '0', 'string', 3);
+
+if (!map.has_key('2')) throw new Error('Expected key to be found');
+if (map.has_key('5')) throw new Error('Expected key to not be found');
+map.del('2');
+if (map.has_key('2')) throw new Error('Expected key to not be found');
diff --git a/Examples/test-suite/javascript/li_std_pair_runme.js b/Examples/test-suite/javascript/li_std_pair_runme.js
new file mode 100644
index 0000000..97bd970
--- /dev/null
+++ b/Examples/test-suite/javascript/li_std_pair_runme.js
@@ -0,0 +1,53 @@
+var li_std_pair = require("li_std_pair");
+
+function check(flag) {
+    if (!flag) {
+        throw new Error("Check failed");
+    }
+}
+
+intPair = li_std_pair.makeIntPair(7, 6);
+check(typeof intPair === 'object');
+if (Object.keys(intPair).length) {
+    // When using raw V8, intPair will be an object with two properties
+    check(Object.keys(intPair).length == 2);
+} else {
+    // When using NAPI, intPair will be an object of class intPair whose
+    // prototype will have two properties
+    check(Object.keys(Object.getPrototypeOf(intPair)).length == 2);
+}
+check(intPair.first === 7);
+check(intPair.second === 6);
+
+intPairConstRef = li_std_pair.makeIntPairConstRef(7, 6);
+check(typeof intPairConstRef === 'object');
+check(intPairConstRef.first === 7);
+check(intPairConstRef.second === 6);
+
+//
+// Each of these should return a reference to a wrapped
+// std:: pair < int, int > object(i.e.an intPair instance).
+intPairPtr = li_std_pair.makeIntPairPtr(7, 6);
+check(typeof intPairPtr === 'object');
+check(intPairPtr.first === 7);
+check(intPairPtr.second === 6);
+
+intPairRef = li_std_pair.makeIntPairRef(7, 6);
+check(typeof intPairRef === 'object');
+check(intPairRef.first === 7);
+check(intPairRef.second === 6);
+
+// Now test various input typemaps.Each of the wrapped C++ functions
+//(product1, product2 and product3) is expecting an argument of a
+// different type(see li_std_pair.i).Typemaps should be in place to
+// convert this tuple into the expected argument type.
+check(li_std_pair.product1(intPair) === 42);
+check(li_std_pair.product2(intPair) === 42);
+// check(product3(intPair) == 42) # TODO, if (desirable to match Ruby wrappers behaviour.Requires equivalent to typemap(in) std:: pair * in Lib / ruby / std_pair.i and further fixes to stop recursive calls to swig:) {asptr which this testcase shows.Plus further changes for any type of sequence type(including other STL containers) to be accepted by all methods taking an STL container to match Ruby behaviour.
+
+//
+// Similarly, each of the input typemaps should know what to do
+// with an intPair instance.
+check(li_std_pair.product1(intPairPtr) === 42);
+check(li_std_pair.product2(intPairPtr) === 42);
+check(li_std_pair.product3(intPairPtr) === 42);
diff --git a/Examples/test-suite/javascript/li_std_pair_using_runme.js b/Examples/test-suite/javascript/li_std_pair_using_runme.js
new file mode 100644
index 0000000..5e9ac72
--- /dev/null
+++ b/Examples/test-suite/javascript/li_std_pair_using_runme.js
@@ -0,0 +1,9 @@
+var li_std_pair_using = require("li_std_pair_using");
+
+one = new li_std_pair_using.StringStringPair("one", "numero uno");
+two = new li_std_pair_using.StringIntPair("two", 2);
+
+tuple = li_std_pair_using.bounce(one);
+if (typeof tuple !== 'object' && tuple.first !== one.first || tuple.second !== one.second) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/li_std_vector_enum_runme.js b/Examples/test-suite/javascript/li_std_vector_enum_runme.js
new file mode 100644
index 0000000..cc46cd8
--- /dev/null
+++ b/Examples/test-suite/javascript/li_std_vector_enum_runme.js
@@ -0,0 +1,21 @@
+var li_std_vector_enum = require("li_std_vector_enum");
+
+
+function check(a, b) {
+    if ((a != b)) {
+        throw new Error("Not equal: ", a, b);
+    }
+}
+
+ev = new li_std_vector_enum.EnumVector();
+
+check(ev.nums.get(0), 10);
+check(ev.nums.get(1), 20);
+check(ev.nums.get(2), 30);
+
+expected = 10;
+for (let i = 0; i < ev.nums.size(); i++) {
+    let val = ev.nums.get(i);
+    check(val, expected);
+    expected += 10;
+}
diff --git a/Examples/test-suite/javascript/li_std_vector_runme.js b/Examples/test-suite/javascript/li_std_vector_runme.js
new file mode 100644
index 0000000..500a4e5
--- /dev/null
+++ b/Examples/test-suite/javascript/li_std_vector_runme.js
@@ -0,0 +1,14 @@
+var li_std_vector = require("li_std_vector");
+
+if (li_std_vector.typedef_test(101) != 101) {
+  throw new Error;
+}
+
+let fail = false;
+try {
+  sv = new li_std_vector.StructVector();
+  sv.add(null);
+  fail = true;
+} catch { }
+
+if (fail) throw new Error();
diff --git a/Examples/test-suite/javascript/li_typemaps_runme.js b/Examples/test-suite/javascript/li_typemaps_runme.js
new file mode 100644
index 0000000..c0b1b43
--- /dev/null
+++ b/Examples/test-suite/javascript/li_typemaps_runme.js
@@ -0,0 +1,50 @@
+var li_typemaps = require("li_typemaps");
+
+function check(a, b) {
+  if (a !== b) {
+    throw new Error("Not equal: " + a + " " + b)
+  }
+}
+
+function check_array(a, b) {
+  if (a.length != b.length)
+    throw new Error("Array length mismatch " + a.length + " " + b.length)
+  if (!a.every(function(element, index) { return element === b[index]; }))
+    throw new Error("Arrays don't match a:" + a + " b:" + b)
+}
+
+// Check double INPUT typemaps
+check(li_typemaps.in_double(22.22), 22.22)
+check(li_typemaps.inr_double(22.22), 22.22)
+
+// Check double OUTPUT typemaps
+check_array(li_typemaps.out_double(22.22), [22.22])
+check_array(li_typemaps.outr_double(22.22), [22.22])
+
+// Check double INOUT typemaps
+check_array(li_typemaps.inout_double(22.22), [22.22])
+check_array(li_typemaps.inoutr_double(22.22), [22.22])
+
+// check long long
+check(li_typemaps.in_ulonglong(20), 20)
+check(li_typemaps.inr_ulonglong(20), 20)
+check_array(li_typemaps.out_ulonglong(20), [20])
+check_array(li_typemaps.outr_ulonglong(20), [20])
+check_array(li_typemaps.inout_ulonglong(20), [20])
+check_array(li_typemaps.inoutr_ulonglong(20), [20])
+
+// check bools
+check(li_typemaps.in_bool(true), true)
+check(li_typemaps.inr_bool(false), false)
+check_array(li_typemaps.out_bool(true), [true])
+check_array(li_typemaps.outr_bool(false), [false])
+check_array(li_typemaps.inout_bool(true), [true])
+check_array(li_typemaps.inoutr_bool(false), [false])
+
+// the others
+check_array(li_typemaps.inoutr_int2(1,2), [1, 2])
+
+fi = li_typemaps.out_foo(10)
+check(fi[0].a, 10)
+check(fi[1], 20)
+check(fi[2], 30)
diff --git a/Examples/test-suite/javascript/member_pointer_const_runme.js b/Examples/test-suite/javascript/member_pointer_const_runme.js
new file mode 100644
index 0000000..a4f0d0a
--- /dev/null
+++ b/Examples/test-suite/javascript/member_pointer_const_runme.js
@@ -0,0 +1,51 @@
+// Example using pointers to member functions
+var member_pointer_const = require("member_pointer_const");
+
+function check(what, expected, actual) {
+    if (expected != actual) {
+        throw new Error(
+            "Failed: ", what, " Expected: ", expected, " Actual: ", actual);
+    }
+}
+
+// Get the pointers
+
+area_pt = member_pointer_const.areapt();
+perim_pt = member_pointer_const.perimeterpt();
+
+// Create some objects
+
+s = new member_pointer_const.Square(10);
+
+// Do some calculations
+
+check("Square area ", 100.0, member_pointer_const.do_op(s, area_pt));
+check("Square perim", 40.0, member_pointer_const.do_op(s, perim_pt));
+
+memberPtr = member_pointer_const.areavar;
+memberPtr = member_pointer_const.perimetervar;
+
+// Try the variables
+check("Square area ", 100.0, member_pointer_const.do_op(s, member_pointer_const.areavar));
+check("Square perim", 40.0, member_pointer_const.do_op(s, member_pointer_const.perimetervar));
+
+// Modify one of the variables
+member_pointer_const.areavar = perim_pt;
+
+check("Square perimeter", 40.0, member_pointer_const.do_op(s, member_pointer_const.areavar));
+
+// Try the constants
+memberPtr = member_pointer_const.AREAPT;
+memberPtr = member_pointer_const.PERIMPT;
+memberPtr = member_pointer_const.NULLPT;
+
+check("Square area ", 100.0, member_pointer_const.do_op(s, member_pointer_const.AREAPT));
+check("Square perim", 40.0, member_pointer_const.do_op(s, member_pointer_const.PERIMPT));
+
+// Typedefs
+check("Square perim", 40.0, member_pointer_const.do_op_td(s, perim_pt));
+
+check("Add by value", 3, member_pointer_const.call1(member_pointer_const.ADD_BY_VALUE, 1, 2));
+// TODO: For some reason, these are commented out in the shared interface file?
+//check("Add by pointer", 7, member_pointer_const.call2(member_pointer_const.ADD_BY_POINTER, 3, 4));
+//check("Add by reference", 11, member_pointer_const.call3(member_pointer_const.ADD_BY_REFERENCE, 5, 6));
diff --git a/Examples/test-suite/javascript/member_pointer_runme.js b/Examples/test-suite/javascript/member_pointer_runme.js
new file mode 100644
index 0000000..6c11ec6
--- /dev/null
+++ b/Examples/test-suite/javascript/member_pointer_runme.js
@@ -0,0 +1,51 @@
+// Example using pointers to member functions
+
+var member_pointer = require("member_pointer");
+
+function check(what, expected, actual) {
+    if (expected != actual) {
+        throw new Error(
+            "Failed: ", what, " Expected: ", expected, " Actual: ", actual);
+    }
+}
+
+// Get the pointers
+
+area_pt = member_pointer.areapt();
+perim_pt = member_pointer.perimeterpt();
+
+// Create some objects
+
+s = new member_pointer.Square(10);
+
+// Do some calculations
+
+check("Square area ", 100.0, member_pointer.do_op(s, area_pt));
+check("Square perim", 40.0, member_pointer.do_op(s, perim_pt));
+
+memberPtr = member_pointer.areavar;
+memberPtr = member_pointer.perimetervar;
+
+// Try the variables
+check("Square area ", 100.0, member_pointer.do_op(s, member_pointer.areavar));
+check("Square perim", 40.0, member_pointer.do_op(s, member_pointer.perimetervar));
+
+// Modify one of the variables
+member_pointer.areavar = perim_pt;
+
+check("Square perimeter", 40.0, member_pointer.do_op(s, member_pointer.areavar));
+
+// Try the constants
+memberPtr = member_pointer.AREAPT;
+memberPtr = member_pointer.PERIMPT;
+memberPtr = member_pointer.NULLPT;
+
+check("Square area ", 100.0, member_pointer.do_op(s, member_pointer.AREAPT));
+check("Square perim", 40.0, member_pointer.do_op(s, member_pointer.PERIMPT));
+
+// Typedefs
+check("Square perim", 40.0, member_pointer.do_op_td(s, perim_pt));
+
+check("Add by value", 3, member_pointer.call1(member_pointer.ADD_BY_VALUE, 1, 2));
+check("Add by pointer", 7, member_pointer.call2(member_pointer.ADD_BY_POINTER, 3, 4));
+check("Add by reference", 11, member_pointer.call3(member_pointer.ADD_BY_REFERENCE, 5, 6));
diff --git a/Examples/test-suite/javascript/memberin_extend_c_runme.js b/Examples/test-suite/javascript/memberin_extend_c_runme.js
new file mode 100644
index 0000000..d5cf69d
--- /dev/null
+++ b/Examples/test-suite/javascript/memberin_extend_c_runme.js
@@ -0,0 +1,7 @@
+var memberin_extend_c = require("memberin_extend_c");
+
+t = new memberin_extend_c.Person();
+t.name = "Fred Bloggs";
+if (t.name != "FRED BLOGGS") {
+    throw new Error("name wrong");
+}
diff --git a/Examples/test-suite/javascript/multivalue_runme.js b/Examples/test-suite/javascript/multivalue_runme.js
new file mode 100644
index 0000000..c3bad52
--- /dev/null
+++ b/Examples/test-suite/javascript/multivalue_runme.js
@@ -0,0 +1,25 @@
+var multivalue = require("multivalue");
+
+var [q, r] = multivalue.divide_l(37, 5);
+if (q != 7) {
+    throw new Error("Test divide_l quotient");
+}
+if (r != 2) {
+    throw new Error("Test divide_l remainder");
+}
+
+var [q, r] = multivalue.divide_v(41, 7);
+if (q != 5) {
+    throw new Error("Test divide_v quotient");
+}
+if (r != 6) {
+    throw new Error("Test divide_v remainder");
+}
+
+var [q, r] = multivalue.divide_l(91, 13);
+if (q != 7) {
+    throw new Error("Test divide_mv quotient");
+}
+if (r != 0) {
+    throw new Error("Test divide_mv remainder");
+}
diff --git a/Examples/test-suite/javascript/name_warnings_runme.js b/Examples/test-suite/javascript/name_warnings_runme.js
new file mode 100644
index 0000000..30605d1
--- /dev/null
+++ b/Examples/test-suite/javascript/name_warnings_runme.js
@@ -0,0 +1,10 @@
+var name_warnings = require("name_warnings");
+
+function check(flag) {
+    if (!flag) {
+        throw new Error("Test failed");
+    }
+}
+
+four = name_warnings.double_an_int(2);
+check(four == 4);
diff --git a/Examples/test-suite/javascript/namespace_class_runme.js b/Examples/test-suite/javascript/namespace_class_runme.js
new file mode 100644
index 0000000..6aa0105
--- /dev/null
+++ b/Examples/test-suite/javascript/namespace_class_runme.js
@@ -0,0 +1,45 @@
+var namespace_class = require("namespace_class");
+
+try {
+    p = namespace_class.Private1();
+    error = 1;
+} catch {
+    error = 0;
+}
+
+if ((error)) {
+    throw new Error("Private1 is private");
+}
+
+try {
+    p = namespace_class.Private2();
+    error = 1;
+} catch {
+    error = 0;
+}
+
+if ((error)) {
+    throw new Error("Private2 is private");
+}
+
+namespace_class.EulerT3D.toFrame(1, 1, 1);
+
+b = new namespace_class.BooT_i();
+b = new namespace_class.BooT_H();
+
+
+f = new namespace_class.FooT_i();
+f.quack(1);
+
+f = new namespace_class.FooT_d();
+f.moo(1);
+
+f = new namespace_class.FooT_H();
+f.foo(namespace_class.Hi);
+
+// This test works only in Node.js
+if (typeof process !== 'undefined') {
+    if (!f.constructor.name.includes("FooT_H") || !(f instanceof namespace_class.FooT_H)) {
+        throw new Error("Incorrect type: " + f.toString());
+    }
+}
diff --git a/Examples/test-suite/javascript/namespace_typemap_runme.js b/Examples/test-suite/javascript/namespace_typemap_runme.js
new file mode 100644
index 0000000..b51605a
--- /dev/null
+++ b/Examples/test-suite/javascript/namespace_typemap_runme.js
@@ -0,0 +1,49 @@
+var namespace_typemap = require("namespace_typemap");
+
+if (namespace_typemap.stest1("hello") != "hello") {
+    throw new Error;
+}
+
+if (namespace_typemap.stest2("hello") != "hello") {
+    throw new Error;
+}
+
+if (namespace_typemap.stest3("hello") != "hello") {
+    throw new Error;
+}
+
+if (namespace_typemap.stest4("hello") != "hello") {
+    throw new Error;
+}
+
+if (namespace_typemap.stest5("hello") != "hello") {
+    throw new Error;
+}
+
+if (namespace_typemap.stest6("hello") != "hello") {
+    throw new Error;
+}
+
+if (namespace_typemap.stest7("hello") != "hello") {
+    throw new Error;
+}
+
+if (namespace_typemap.stest8("hello") != "hello") {
+    throw new Error;
+}
+
+if (namespace_typemap.stest9("hello") != "hello") {
+    throw new Error;
+}
+
+if (namespace_typemap.stest10("hello") != "hello") {
+    throw new Error;
+}
+
+if (namespace_typemap.stest11("hello") != "hello") {
+    throw new Error;
+}
+
+if (namespace_typemap.stest12("hello") != "hello") {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/naturalvar_runme.js b/Examples/test-suite/javascript/naturalvar_runme.js
new file mode 100644
index 0000000..894bd4c
--- /dev/null
+++ b/Examples/test-suite/javascript/naturalvar_runme.js
@@ -0,0 +1,13 @@
+var naturalvar = require("naturalvar");
+
+f = new naturalvar.Foo();
+b = new naturalvar.Bar();
+
+b.f = f;
+
+naturalvar.s = "hello";
+b.s = "hello";
+
+if (b.s != naturalvar.s) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/nested_in_template_runme.js b/Examples/test-suite/javascript/nested_in_template_runme.js
new file mode 100644
index 0000000..c3c58e7
--- /dev/null
+++ b/Examples/test-suite/javascript/nested_in_template_runme.js
@@ -0,0 +1,6 @@
+var nested_in_template = require("nested_in_template");
+
+cd = new nested_in_template.ConcreteDerived(88);
+if (cd.m_value != 88) {
+    throw new Error("ConcreteDerived not created correctly");
+}
diff --git a/Examples/test-suite/javascript/nested_template_base_runme.js b/Examples/test-suite/javascript/nested_template_base_runme.js
new file mode 100644
index 0000000..fcf8416
--- /dev/null
+++ b/Examples/test-suite/javascript/nested_template_base_runme.js
@@ -0,0 +1,14 @@
+var nested_template_base = require("nested_template_base");
+
+ois = new nested_template_base.InnerS(123);
+oic = new nested_template_base.InnerC();
+
+// Check base method is available
+if ((oic.outer(ois).val != 123)) {
+    throw new Error("Wrong value calling outer");
+}
+
+// Check non-derived class using base class
+if ((oic.innerc().outer(ois).val != 123)) {
+    throw new Error("Wrong value calling innerc");
+}
diff --git a/Examples/test-suite/javascript/nested_workaround_runme.js b/Examples/test-suite/javascript/nested_workaround_runme.js
new file mode 100644
index 0000000..5d02e7c
--- /dev/null
+++ b/Examples/test-suite/javascript/nested_workaround_runme.js
@@ -0,0 +1,15 @@
+var nested_workaround = require("nested_workaround");
+
+inner = new nested_workaround.Inner(5);
+outer = new nested_workaround.Outer();
+newInner = outer.doubleInnerValue(inner);
+if (newInner.getValue() != 10) {
+    throw new Error;
+}
+
+outer = new nested_workaround.Outer();
+inner = outer.createInner(3);
+newInner = outer.doubleInnerValue(inner);
+if (outer.getInnerValue(newInner) != 6) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/node_template/binding.gyp.in b/Examples/test-suite/javascript/node_template/binding.gyp.in
index a82ac2f..87e70bb 100644
--- a/Examples/test-suite/javascript/node_template/binding.gyp.in
+++ b/Examples/test-suite/javascript/node_template/binding.gyp.in
@@ -19,7 +19,7 @@
         ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"',
           {
             'cflags': [ "-Wno-unused-variable", "-Wno-unused-but-set-variable", "-Wno-unused-but-set-parameter", $cflags],
-            'cflags_cc': [ "-Wno-unused-variable", "-Wno-unused-but-set-variable", "-Wno-unused-but-set-parameter", $cflags],
+            'cflags_cc': [ "-Wno-unused-variable", "-Wno-unused-but-set-variable", "-Wno-unused-but-set-parameter", $cxxflags, $cflags],
             'cflags!': [ '-fno-exceptions' ],
             'cflags_cc!': [ '-fno-exceptions', '-fno-rtti' ]
           }
diff --git a/Examples/test-suite/javascript/node_template/index.js.in b/Examples/test-suite/javascript/node_template/index.js.in
index 7233049..107545f 100644
--- a/Examples/test-suite/javascript/node_template/index.js.in
+++ b/Examples/test-suite/javascript/node_template/index.js.in
@@ -1 +1 @@
-module.exports = require('./build/Release/$testcase');
+module.exports = require('./build/$build/$testcase');
diff --git a/Examples/test-suite/javascript/not_c_keywords_runme.js b/Examples/test-suite/javascript/not_c_keywords_runme.js
new file mode 100644
index 0000000..e74976f
--- /dev/null
+++ b/Examples/test-suite/javascript/not_c_keywords_runme.js
@@ -0,0 +1,8 @@
+var not_c_keywords = require("not_c_keywords");
+
+cs = new not_c_keywords.ComplexStruct();
+cs.init();
+if (cs.complex != 123) {
+    throw new Error("complex not correct");
+}
+cs.complex = 456;
diff --git a/Examples/test-suite/javascript/operator_overload_runme.js b/Examples/test-suite/javascript/operator_overload_runme.js
new file mode 100644
index 0000000..1f3f388
--- /dev/null
+++ b/Examples/test-suite/javascript/operator_overload_runme.js
@@ -0,0 +1,111 @@
+var operator_overload = require("operator_overload");
+var { Op } = operator_overload;
+
+// first check all the operators are implemented correctly from pure C++ code
+Op.sanity_check();
+
+pop = (new Op(6)).Divide(new Op(3));
+
+// test routine
+a = new Op();
+b = new Op(5);
+c = new Op(b); // copy construct
+d = new Op(2);
+dd = new Op();
+dd.Equal(d); // assignment operator
+
+// test equality
+if (!a.NotEqual(b)) {
+  throw new Error("a!=b");
+}
+if (!b.EqualEqual(c)) {
+  throw new Error("b==c");
+}
+if (!a.NotEqual(d)) {
+  throw new Error("a!=d");
+}
+if (!d.EqualEqual(dd)) {
+  throw new Error("d==dd");
+}
+
+// test <
+if (!a.LessThan(b)) {
+  throw new Error("a<b");
+}
+if (!a.LessThanEqual(b)) {
+  throw new Error("a<=b");
+}
+if (!b.LessThanEqual(c)) {
+  throw new Error("b<=c");
+}
+if (!b.GreaterThanEqual(c)) {
+  throw new Error("b>=c");
+}
+if (!b.GreaterThan(d)) {
+  throw new Error("b>d");
+}
+if (!b.GreaterThanEqual(d)) {
+  throw new Error("b>=d");
+}
+
+// test +=
+e = new Op(3);
+e.PlusEqual(d);
+if (!e.EqualEqual(b)) {
+  throw new Error(`e==b (${e.i}==${b.i})`);
+}
+e.MinusEqual(c);
+if (!e.EqualEqual(a)) {
+  throw new Error("e==a");
+}
+e = new Op(1);
+e.MultiplyEqual(b);
+if (!e.EqualEqual(c)) {
+  throw new Error("e==c");
+}
+e.DivideEqual(d);
+if (!e.EqualEqual(d)) {
+  throw new Error("e==d");
+}
+e.PercentEqual(c);
+if (!e.EqualEqual(d)) {
+  throw new Error("e==d");
+}
+
+// test +
+f = new Op(1);
+g = new Op(1);
+if (!f.Plus(g).EqualEqual(new Op(2))) {
+  throw new Error("f+g==Op(2)");
+}
+if (!f.Minus(g).EqualEqual(new Op(0))) {
+  throw new Error("f-g==Op(0)");
+}
+if (!f.Multiply(g).EqualEqual(new Op(1))) {
+  throw new Error("f*g==Op(1)");
+}
+if (!f.Divide(g).EqualEqual(new Op(1))) {
+  throw new Error("f/g==Op(1)");
+}
+if (!f.Percent(g).EqualEqual(new Op(0))) {
+  throw new Error("f%g==Op(0)");
+}
+
+// test unary operators
+if (!a.Minus().EqualEqual(a)) {
+  throw new Error("-a==a");
+}
+if (!b.Minus().EqualEqual(new Op(-5))) {
+  throw new Error("-b==Op(-5)");
+}
+
+// test functors
+if (!b.Functor() == 5) {
+  throw new Error("functor");
+}
+if (!b.Functor(1) == 6) {
+  throw new Error("functor");
+}
+if (!b.Functor(1, 2) == 8) {
+  throw new Error("functor");
+}
diff --git a/Examples/test-suite/javascript/operbool_runme.js b/Examples/test-suite/javascript/operbool_runme.js
new file mode 100644
index 0000000..b1bf89f
--- /dev/null
+++ b/Examples/test-suite/javascript/operbool_runme.js
@@ -0,0 +1,6 @@
+#!/usr/bin/env python
+var operbool = require("operbool");
+const b = new operbool.Test();
+if (b.operator_bool()) {
+    throw new Error("operbool failed");
+}
diff --git a/Examples/test-suite/javascript/overload_bool_runme.js b/Examples/test-suite/javascript/overload_bool_runme.js
new file mode 100644
index 0000000..2a1a955
--- /dev/null
+++ b/Examples/test-suite/javascript/overload_bool_runme.js
@@ -0,0 +1,60 @@
+var overload_bool = require("overload_bool");
+
+// Overloading bool, int, string
+if (overload_bool.overloaded(true) != "bool") {
+    throw new Error("wrong!");
+}
+if (overload_bool.overloaded(false) != "bool") {
+    throw new Error("wrong!");
+}
+
+if (overload_bool.overloaded(0) != "int") {
+    throw new Error("wrong!");
+}
+if (overload_bool.overloaded(1) != "int") {
+    throw new Error("wrong!");
+}
+if (overload_bool.overloaded(2) != "int") {
+    throw new Error("wrong!");
+}
+
+if (overload_bool.overloaded("1234") != "string") {
+    throw new Error("wrong!");
+}
+
+// Test bool masquerading as int
+// Not possible
+
+// Test int masquerading as bool
+// Not possible
+
+
+///////////////////////////////////////////////
+
+// Overloading bool, int, string
+if (overload_bool.overloaded_ref(true) != "bool") {
+    throw new Error("wrong!");
+}
+if (overload_bool.overloaded_ref(false) != "bool") {
+    throw new Error("wrong!");
+}
+
+if (overload_bool.overloaded_ref(0) != "int") {
+    throw new Error("wrong!");
+}
+if (overload_bool.overloaded_ref(1) != "int") {
+    throw new Error("wrong!");
+}
+if (overload_bool.overloaded_ref(2) != "int") {
+    throw new Error("wrong!");
+}
+
+if (overload_bool.overloaded_ref("1234") != "string") {
+    throw new Error("wrong!");
+}
+
+// Test bool masquerading as int
+// Not possible
+
+// Test int masquerading as bool
+// Not possible
diff --git a/Examples/test-suite/javascript/overload_complicated_runme.js b/Examples/test-suite/javascript/overload_complicated_runme.js
new file mode 100644
index 0000000..19ba3ee
--- /dev/null
+++ b/Examples/test-suite/javascript/overload_complicated_runme.js
@@ -0,0 +1,58 @@
+var overload_complicated = require("overload_complicated");
+
+pInt = null;
+
+// Check the correct constructors are available
+p = new overload_complicated.Pop(pInt);
+
+p = new overload_complicated.Pop(pInt, false);
+
+// Check overloaded in const only and pointers/references which target
+// languages cannot disambiguate
+if (p.hip(false) != 701) {
+    throw new Error("Test 1 failed");
+}
+
+if (p.hip(pInt) != 702) {
+    throw new Error("Test 2 failed");
+}
+
+// Reverse the order for the above
+if (p.hop(pInt) != 805) {
+    throw new Error("Test 3 failed");
+}
+
+if (p.hop(false) != 801) {
+    throw new Error("Test 4 failed");
+}
+
+// Few more variations and order shuffled
+if (p.pop(false) != 901) {
+    throw new Error("Test 5 failed");
+}
+
+if (p.pop(pInt) != 902) {
+    throw new Error("Test 6 failed");
+}
+
+if (p.pop() != 905) {
+    throw new Error("Test 7 failed");
+}
+
+// Overload on const only
+if (p.bop(pInt) != 1001) {
+    throw new Error("Test 8 failed");
+}
+
+if (p.bip(pInt) != 2001) {
+    throw new Error("Test 9 failed");
+}
+
+// Globals
+if (overload_complicated.muzak(false) != 3001) {
+    throw new Error("Test 10 failed");
+}
+
+if (overload_complicated.muzak(pInt) != 3002) {
+    throw new Error("Test 11 failed");
+}
diff --git a/Examples/test-suite/javascript/overload_extend2_runme.js b/Examples/test-suite/javascript/overload_extend2_runme.js
new file mode 100644
index 0000000..c5463ab
--- /dev/null
+++ b/Examples/test-suite/javascript/overload_extend2_runme.js
@@ -0,0 +1,29 @@
+var overload_extend2 = require("overload_extend2");
+
+f = new overload_extend2.Foo();
+if (f.test(3) != 1) {
+    throw new Error;
+}
+if (f.test("hello") != 2) {
+    throw new Error;
+}
+if (f.test(3.5, 2.5) != 3) {
+    throw new Error;
+}
+if (f.test("hello", 20) != 1020) {
+    throw new Error;
+}
+if (f.test("hello", 20, 100) != 120) {
+    throw new Error;
+}
+
+// C default args
+if (f.test(f) != 30) {
+    throw new Error;
+}
+if (f.test(f, 100) != 120) {
+    throw new Error;
+}
+if (f.test(f, 100, 200) != 300) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/overload_extend_c_runme.js b/Examples/test-suite/javascript/overload_extend_c_runme.js
new file mode 100644
index 0000000..d69a205
--- /dev/null
+++ b/Examples/test-suite/javascript/overload_extend_c_runme.js
@@ -0,0 +1,19 @@
+var overload_extend_c = require("overload_extend_c");
+
+f = new overload_extend_c.Foo();
+if (f.test() != 0) {
+    throw new Error;
+}
+if (f.test(3) != 1) {
+    throw new Error;
+}
+if (f.test("hello") != 2) {
+    throw new Error;
+}
+if (f.test(3, 2) != 5) {
+    throw new Error;
+}
+// In JavaScript there is no difference between 3.0 and 3
+if (f.test(3.0) != 1) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/overload_extend_runme.js b/Examples/test-suite/javascript/overload_extend_runme.js
new file mode 100644
index 0000000..cd127db
--- /dev/null
+++ b/Examples/test-suite/javascript/overload_extend_runme.js
@@ -0,0 +1,19 @@
+var overload_extend = require("overload_extend")
+
+f = new overload_extend.Foo()
+if (f.test() != 0) {
+    throw new Error
+}
+if (f.test(3) != 1) {
+    throw new Error
+}
+if (f.test("hello") != 2) {
+    throw new Error
+}
+if (f.test(3, 2) != 5) {
+    throw new Error
+}
+// In JavaScript there is no difference between 3.0 and 3
+if (f.test(3.0) != 1) {
+    throw new Error
+}
diff --git a/Examples/test-suite/javascript/overload_null_runme.js b/Examples/test-suite/javascript/overload_null_runme.js
index f1e35ca..f6c31a4 100644
--- a/Examples/test-suite/javascript/overload_null_runme.js
+++ b/Examples/test-suite/javascript/overload_null_runme.js
@@ -37,13 +37,13 @@
 // check(15, o.byval2cpr(null));
 check(16, o.byval2cpr(x));
 
-// forward class declaration
-check(17, o.byval1forwardptr(x));
-// check(18, o.byval1forwardptr(null));
+// fwd class declaration
+check(17, o.byval1fwdptr(x));
+// check(18, o.byval1fwdptr(null));
 
-// check(19, o.byval2forwardptr(null));
-check(20, o.byval2forwardptr(x));
+// check(19, o.byval2fwdptr(null));
+check(20, o.byval2fwdptr(x));
 
-check(21, o.byval1forwardref(x));
+check(21, o.byval1fwdref(x));
 
-check(22, o.byval2forwardref(x));
+check(22, o.byval2fwdref(x));
diff --git a/Examples/test-suite/javascript/overload_simple_runme.js b/Examples/test-suite/javascript/overload_simple_runme.js
new file mode 100644
index 0000000..8a56ee2
--- /dev/null
+++ b/Examples/test-suite/javascript/overload_simple_runme.js
@@ -0,0 +1,105 @@
+var overload_simple = require("overload_simple");
+
+if (overload_simple.foo(3) != "foo:int") {
+    throw new Error("foo(int)");
+}
+
+if (overload_simple.foo("hello") != "foo:char *") {
+    throw new Error("foo(char *)");
+}
+
+f = new overload_simple.Foo();
+b = new overload_simple.Bar();
+
+if (overload_simple.foo(f) != "foo:Foo *") {
+    throw new Error("foo(Foo *)");
+}
+
+if (overload_simple.foo(b) != "foo:Bar *") {
+    throw new Error("foo(Bar *)");
+}
+
+v = overload_simple.malloc_void(32);
+
+if (overload_simple.foo(v) != "foo:void *") {
+    throw new Error("foo(void *)");
+}
+
+s = new overload_simple.Spam();
+
+if (s.foo(3) != "foo:int") {
+    throw new Error("Spam::foo(int)");
+}
+
+if (s.foo("hello") != "foo:char *") {
+    throw new Error("Spam::foo(char *)");
+}
+
+if (s.foo(f) != "foo:Foo *") {
+    throw new Error("Spam::foo(Foo *)");
+}
+
+if (s.foo(b) != "foo:Bar *") {
+    throw new Error("Spam::foo(Bar *)");
+}
+
+if (s.foo(v) != "foo:void *") {
+    throw new Error("Spam::foo(void *)");
+}
+
+if (overload_simple.Spam.bar(3) != "bar:int") {
+    throw new Error("Spam::bar(int)");
+}
+
+if (overload_simple.Spam.bar("hello") != "bar:char *") {
+    throw new Error("Spam::bar(char *)");
+}
+
+if (overload_simple.Spam.bar(f) != "bar:Foo *") {
+    throw new Error("Spam::bar(Foo *)");
+}
+
+if (overload_simple.Spam.bar(b) != "bar:Bar *") {
+    throw new Error("Spam::bar(Bar *)");
+}
+
+if (overload_simple.Spam.bar(v) != "bar:void *") {
+    throw new Error("Spam::bar(void *)");
+}
+
+// Test constructors
+
+s = new overload_simple.Spam();
+if (s.type != "none") {
+    throw new Error("Spam()");
+}
+
+s = new overload_simple.Spam(3);
+if (s.type != "int") {
+    throw new Error("Spam(int)");
+}
+
+s = new overload_simple.Spam("hello");
+if (s.type != "char *") {
+    throw new Error("Spam(char *)");
+}
+
+s = new overload_simple.Spam(f);
+if (s.type != "Foo *") {
+    throw new Error("Spam(Foo *)");
+}
+
+s = new overload_simple.Spam(b);
+if (s.type != "Bar *") {
+    throw new Error("Spam(Bar *)");
+}
+
+s = new overload_simple.Spam(v);
+if (s.type != "void *") {
+    throw new Error("Spam(void *)");
+}
+
+overload_simple.free_void(v);
+
+a = new overload_simple.ClassA();
+b = a.method1(1);
diff --git a/Examples/test-suite/javascript/overload_template_fast_runme.js b/Examples/test-suite/javascript/overload_template_fast_runme.js
new file mode 100644
index 0000000..759c7c9
--- /dev/null
+++ b/Examples/test-suite/javascript/overload_template_fast_runme.js
@@ -0,0 +1,136 @@
+var overload_template_fast = require("overload_template_fast");
+
+f = overload_template_fast.foo();
+
+a = overload_template_fast.maximum(3, 4);
+b = overload_template_fast.maximum(3.4, 5.2);
+
+// overload_template_fast.mix 1
+if (overload_template_fast.mix1("hi") != 101) {
+    throw new Error("mix1(const char*)");
+}
+
+if (overload_template_fast.mix1(1.0, 1.0) != 102) {
+    throw new Error("mix1(double, const double &)");
+}
+
+if (overload_template_fast.mix1(1.0) != 103) {
+    throw new Error("mix1(double)");
+}
+// overload_template_fast.mix 2
+if (overload_template_fast.mix2("hi") != 101) {
+    throw new Error("mix2(const char*)");
+}
+if (overload_template_fast.mix2(1.0, 1.0) != 102) {
+    throw new Error("mix2(double, const double &)");
+}
+if (overload_template_fast.mix2(1.0) != 103) {
+    throw new Error("mix2(double)");
+}
+// overload_template_fast.mix 3
+if (overload_template_fast.mix3("hi") != 101) {
+    throw new Error("mix3(const char*)");
+}
+if (overload_template_fast.mix3(1.0, 1.0) != 102) {
+    throw new Error("mix3(double, const double &)");
+}
+if (overload_template_fast.mix3(1.0) != 103) {
+    throw new Error("mix3(double)");
+}
+// Combination 1
+if (overload_template_fast.overtparams1(100) != 10) {
+    throw new Error("overtparams1(int)");
+}
+if (overload_template_fast.overtparams1(100.0, 100) != 20) {
+    throw new Error("overtparams1(double, int)");
+}
+// Combination 2
+if (overload_template_fast.overtparams2(100.0, 100) != 40) {
+    throw new Error("overtparams2(double, int)");
+}
+// Combination 3
+if (overload_template_fast.overloaded() != 60) {
+    throw new Error("overloaded()");
+}
+if (overload_template_fast.overloaded(100.0, 100) != 70) {
+    throw new Error("overloaded(double, int)");
+}
+// Combination 4
+if (overload_template_fast.overloadedagain("hello") != 80) {
+    throw new Error("overloadedagain(const char *)");
+}
+if (overload_template_fast.overloadedagain() != 90) {
+    throw new Error("overloadedagain(double)");
+}
+// specializations
+if (overload_template_fast.specialization(10) != 202) {
+    throw new Error("specialization(int)");
+}
+if (overload_template_fast.specialization(10, 10) != 204) {
+    throw new Error("specialization(int, int)");
+}
+if (overload_template_fast.specialization("hi", "hi") != 201) {
+    throw new Error("specialization(const char *, const char *)");
+}
+
+// simple specialization
+overload_template_fast.xyz();
+overload_template_fast.xyz_int();
+overload_template_fast.xyz_double();
+
+// a bit of everything
+if (overload_template_fast.overload("hi") != 0) {
+    throw new Error("overload()");
+}
+if (overload_template_fast.overload(1) != 10) {
+    throw new Error("overload(int t)");
+}
+if (overload_template_fast.overload(1, 1) != 20) {
+    throw new Error("overload(int t, const int &)");
+}
+if (overload_template_fast.overload(1, "hello") != 30) {
+    throw new Error("overload(int t, const char *)");
+}
+k = new overload_template_fast.Klass();
+if (overload_template_fast.overload(k) != 10) {
+    throw new Error("overload(Klass t)");
+}
+if (overload_template_fast.overload(k, k) != 20) {
+    throw new Error("overload(Klass t, const Klass &)");
+}
+if (overload_template_fast.overload(k, "hello") != 30) {
+    throw new Error("overload(Klass t, const char *)");
+}
+if (overload_template_fast.overload() != 50) {
+    throw new Error("overload(const char *)");
+}
+
+// everything put in a namespace
+if (overload_template_fast.nsoverload("hi") != 1000) {
+    throw new Error("nsoverload()");
+}
+if (overload_template_fast.nsoverload(1) != 1010) {
+    throw new Error("nsoverload(int t)");
+}
+if (overload_template_fast.nsoverload(1, 1) != 1020) {
+    throw new Error("nsoverload(int t, const int &)");
+}
+if (overload_template_fast.nsoverload(1, "hello") != 1030) {
+    throw new Error("nsoverload(int t, const char *)");
+}
+if (overload_template_fast.nsoverload(k) != 1010) {
+    throw new Error("nsoverload(Klass t)");
+}
+if (overload_template_fast.nsoverload(k, k) != 1020) {
+    throw new Error("nsoverload(Klass t, const Klass &)");
+}
+if (overload_template_fast.nsoverload(k, "hello") != 1030) {
+    throw new Error("nsoverload(Klass t, const char *)");
+}
+if (overload_template_fast.nsoverload() != 1050) {
+    throw new Error("nsoverload(const char *)");
+}
+
+overload_template_fast.A.foo(1);
+b = new overload_template_fast.B();
+b.foo(1);
diff --git a/Examples/test-suite/javascript/overload_template_runme.js b/Examples/test-suite/javascript/overload_template_runme.js
new file mode 100644
index 0000000..ef4e238
--- /dev/null
+++ b/Examples/test-suite/javascript/overload_template_runme.js
@@ -0,0 +1,133 @@
+var overload_template = require("overload_template");
+f = overload_template.foo();
+
+a = overload_template.maximum(3, 4);
+b = overload_template.maximum(3.4, 5.2);
+
+// mix 1
+if (overload_template.mix1("hi") != 101) {
+    throw new Error("mix1(const char*)");
+}
+if (overload_template.mix1(1.0, 1.0) != 102) {
+    throw new Error("mix1(double, const double &)");
+}
+if (overload_template.mix1(1.0) != 103) {
+    throw new Error("mix1(double)");
+}
+// mix 2
+if (overload_template.mix2("hi") != 101) {
+    throw new Error("mix2(const char*)");
+}
+if (overload_template.mix2(1.0, 1.0) != 102) {
+    throw new Error("mix2(double, const double &)");
+}
+if (overload_template.mix2(1.0) != 103) {
+    throw new Error("mix2(double)");
+}
+// mix 3
+if (overload_template.mix3("hi") != 101) {
+    throw new Error("mix3(const char*)");
+}
+if (overload_template.mix3(1.0, 1.0) != 102) {
+    throw new Error("mix3(double, const double &)");
+}
+if (overload_template.mix3(1.0) != 103) {
+    throw new Error("mix3(double)");
+}
+// Combination 1
+if (overload_template.overtparams1(100) != 10) {
+    throw new Error("overtparams1(int)");
+}
+if (overload_template.overtparams1(100.0, 100) != 20) {
+    throw new Error("overtparams1(double, int)");
+}
+// Combination 2
+if (overload_template.overtparams2(100.0, 100) != 40) {
+    throw new Error("overtparams2(double, int)");
+}
+// Combination 3
+if (overload_template.overloaded() != 60) {
+    throw new Error("overloaded()");
+}
+if (overload_template.overloaded(100.0, 100) != 70) {
+    throw new Error("overloaded(double, int)");
+}
+// Combination 4
+if (overload_template.overloadedagain("hello") != 80) {
+    throw new Error("overloadedagain(const char *)");
+}
+if (overload_template.overloadedagain() != 90) {
+    throw new Error("overloadedagain(double)");
+}
+// specializations
+if (overload_template.specialization(10) != 202) {
+    throw new Error("specialization(int)");
+}
+if (overload_template.specialization(10, 10) != 204) {
+    throw new Error("specialization(int, int)");
+}
+if (overload_template.specialization("hi", "hi") != 201) {
+    throw new Error("specialization(const char *, const char *)");
+}
+
+// simple specialization
+overload_template.xyz();
+overload_template.xyz_int();
+overload_template.xyz_double();
+
+// a bit of everything
+if (overload_template.overload("hi") != 0) {
+    throw new Error("overload()");
+}
+if (overload_template.overload(1) != 10) {
+    throw new Error("overload(int t)");
+}
+if (overload_template.overload(1, 1) != 20) {
+    throw new Error("overload(int t, const int &)");
+}
+if (overload_template.overload(1, "hello") != 30) {
+    throw new Error("overload(int t, const char *)");
+}
+k = new overload_template.Klass();
+if (overload_template.overload(k) != 10) {
+    throw new Error("overload(Klass t)");
+}
+if (overload_template.overload(k, k) != 20) {
+    throw new Error("overload(Klass t, const Klass &)");
+}
+if (overload_template.overload(k, "hello") != 30) {
+    throw new Error("overload(Klass t, const char *)");
+}
+if (overload_template.overload() != 50) {
+    throw new Error("overload(const char *)");
+}
+
+// everything put in a namespace
+if (overload_template.nsoverload("hi") != 1000) {
+    throw new Error("nsoverload()");
+}
+if (overload_template.nsoverload(1) != 1010) {
+    throw new Error("nsoverload(int t)");
+}
+if (overload_template.nsoverload(1, 1) != 1020) {
+    throw new Error("nsoverload(int t, const int &)");
+}
+if (overload_template.nsoverload(1, "hello") != 1030) {
+    throw new Error("nsoverload(int t, const char *)");
+}
+if (overload_template.nsoverload(k) != 1010) {
+    throw new Error("nsoverload(Klass t)");
+}
+if (overload_template.nsoverload(k, k) != 1020) {
+    throw new Error("nsoverload(Klass t, const Klass &)");
+}
+if (overload_template.nsoverload(k, "hello") != 1030) {
+    throw new Error("nsoverload(Klass t, const char *)");
+}
+if (overload_template.nsoverload() != 1050) {
+    throw new Error("nsoverload(const char *)");
+}
+
+overload_template.A.foo(1);
+b = new overload_template.B();
+b.foo(1);
diff --git a/Examples/test-suite/javascript/pointer_reference_runme.js b/Examples/test-suite/javascript/pointer_reference_runme.js
new file mode 100644
index 0000000..d63b2fd
--- /dev/null
+++ b/Examples/test-suite/javascript/pointer_reference_runme.js
@@ -0,0 +1,20 @@
+var pointer_reference = require("pointer_reference");
+
+s = pointer_reference.get();
+if (s.value != 10) {
+    throw new Error("get test failed");
+}
+
+ss = new pointer_reference.Struct(20);
+pointer_reference.set(ss);
+if (pointer_reference.Struct.instance.value != 20) {
+    throw new Error("set test failed");
+}
+
+if (pointer_reference.overloading(1) != 111) {
+    throw new Error("overload test 1 failed");
+}
+
+if (pointer_reference.overloading(ss) != 222) {
+    throw new Error("overload test 2 failed");
+}
diff --git a/Examples/test-suite/javascript/preproc_cpp_runme.js b/Examples/test-suite/javascript/preproc_cpp_runme.js
new file mode 100644
index 0000000..e426bfb
--- /dev/null
+++ b/Examples/test-suite/javascript/preproc_cpp_runme.js
@@ -0,0 +1,4 @@
+var preproc_cpp = require("preproc_cpp");
+
+t1 = new preproc_cpp.tcxMessageTest();
+t2 = new preproc_cpp.tcxMessageBug();
diff --git a/Examples/test-suite/javascript/preproc_defined_runme.js b/Examples/test-suite/javascript/preproc_defined_runme.js
new file mode 100644
index 0000000..433de64
--- /dev/null
+++ b/Examples/test-suite/javascript/preproc_defined_runme.js
@@ -0,0 +1,24 @@
+var preproc_defined = require("preproc_defined");
+
+if (preproc_defined.call_checking() != 1) {
+    throw new Error;
+}
+
+d = new preproc_defined.Defined();
+d.defined = 10;
+
+preproc_defined.thing(10);
+preproc_defined.stuff(10);
+preproc_defined.bumpf(10);
+
+if (preproc_defined.a != 2) {
+    throw new Error;
+}
+
+if (preproc_defined.b != 42) {
+    throw new Error;
+}
+
+if (preproc_defined.z != 8) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/preproc_gcc_output_runme.js b/Examples/test-suite/javascript/preproc_gcc_output_runme.js
new file mode 100644
index 0000000..8bc4dcb
--- /dev/null
+++ b/Examples/test-suite/javascript/preproc_gcc_output_runme.js
@@ -0,0 +1,5 @@
+var preproc_gcc_output = require("preproc_gcc_output");
+
+preproc_gcc_output.header1_function_a(99);
+preproc_gcc_output.header1_function_b(99);
+preproc_gcc_output.header2_function(99);
diff --git a/Examples/test-suite/javascript/primitive_ref_runme.js b/Examples/test-suite/javascript/primitive_ref_runme.js
new file mode 100644
index 0000000..23556e5
--- /dev/null
+++ b/Examples/test-suite/javascript/primitive_ref_runme.js
@@ -0,0 +1,53 @@
+var primitive_ref = require("primitive_ref");
+
+if (primitive_ref.ref_int(3) != 3) {
+    throw new Error
+}
+
+if (primitive_ref.ref_uint(3) != 3) {
+    throw new Error
+}
+
+if (primitive_ref.ref_short(3) != 3) {
+    throw new Error
+}
+
+if (primitive_ref.ref_ushort(3) != 3) {
+    throw new Error
+}
+
+if (primitive_ref.ref_long(3) != 3) {
+    throw new Error
+}
+
+if (primitive_ref.ref_ulong(3) != 3) {
+    throw new Error
+}
+
+if (primitive_ref.ref_schar(3) != 3) {
+    throw new Error
+}
+
+if (primitive_ref.ref_uchar(3) != 3) {
+    throw new Error
+}
+
+if (primitive_ref.ref_float(3.5) != 3.5) {
+    throw new Error
+}
+
+if (primitive_ref.ref_double(3.5) != 3.5) {
+    throw new Error
+}
+
+if (primitive_ref.ref_bool(true) != true) {
+    throw new Error
+}
+
+if (primitive_ref.ref_char("x") != "x") {
+    throw new Error
+}
+
+if (primitive_ref.ref_over(0) != 0) {
+    throw new Error
+}
diff --git a/Examples/test-suite/javascript/profiletest_runme.js b/Examples/test-suite/javascript/profiletest_runme.js
new file mode 100644
index 0000000..241f172
--- /dev/null
+++ b/Examples/test-suite/javascript/profiletest_runme.js
@@ -0,0 +1,30 @@
+var profiletest = require("profiletest");
+
+a = new profiletest.A();
+
+b = new profiletest.B();
+// Directly calling fn is not possible in JavaScript where
+// member methods require passing a this object (like C/C++)
+fn = b.fn;
+for (let i = 50000; i >= 0; i--) {
+    a = fn.call(b, a);  // 1
+    a = fn.call(b, a);  // 2
+    a = fn.call(b, a);  // 3
+    a = fn.call(b, a);  // 4
+    a = fn.call(b, a);  // 5
+    a = fn.call(b, a);  // 6
+    a = fn.call(b, a);  // 7
+    a = fn.call(b, a);  // 8
+    a = fn.call(b, a);  // 9
+    a = fn.call(b, a);  // 10
+    a = fn.call(b, a);  // 1
+    a = fn.call(b, a);  // 2
+    a = fn.call(b, a);  // 3
+    a = fn.call(b, a);  // 4
+    a = fn.call(b, a);  // 5
+    a = fn.call(b, a);  // 6
+    a = fn.call(b, a);  // 7
+    a = fn.call(b, a);  // 8
+    a = fn.call(b, a);  // 9
+    a = fn.call(b, a);  // 20
+}
diff --git a/Examples/test-suite/javascript/reference_global_vars_runme.js b/Examples/test-suite/javascript/reference_global_vars_runme.js
new file mode 100644
index 0000000..295e0f3
--- /dev/null
+++ b/Examples/test-suite/javascript/reference_global_vars_runme.js
@@ -0,0 +1,90 @@
+var reference_global_vars = require("reference_global_vars");
+
+// const class reference variable
+if (reference_global_vars.getconstTC().num != 33) {
+    throw new Error;
+}
+
+// primitive reference variables
+reference_global_vars.var_bool = reference_global_vars.createref_bool(false);
+if (reference_global_vars.value_bool(reference_global_vars.var_bool) != false) {
+    throw new Error;
+}
+
+reference_global_vars.var_bool = reference_global_vars.createref_bool(true);
+if (reference_global_vars.value_bool(reference_global_vars.var_bool) != true) {
+    throw new Error;
+}
+
+reference_global_vars.var_char = reference_global_vars.createref_char("w");
+if (reference_global_vars.value_char(reference_global_vars.var_char) != "w") {
+    throw new Error;
+}
+
+reference_global_vars.var_unsigned_char = reference_global_vars.createref_unsigned_char(10);
+if (reference_global_vars.value_unsigned_char(reference_global_vars.var_unsigned_char) != 10) {
+    throw new Error;
+}
+
+reference_global_vars.var_signed_char = reference_global_vars.createref_signed_char(10);
+if (reference_global_vars.value_signed_char(reference_global_vars.var_signed_char) != 10) {
+    throw new Error;
+}
+
+reference_global_vars.var_short = reference_global_vars.createref_short(10);
+if (reference_global_vars.value_short(reference_global_vars.var_short) != 10) {
+    throw new Error;
+}
+
+reference_global_vars.var_unsigned_short = reference_global_vars.createref_unsigned_short(10);
+if (reference_global_vars.value_unsigned_short(reference_global_vars.var_unsigned_short) != 10) {
+    throw new Error;
+}
+
+reference_global_vars.var_int = reference_global_vars.createref_int(10);
+if (reference_global_vars.value_int(reference_global_vars.var_int) != 10) {
+    throw new Error;
+}
+
+reference_global_vars.var_unsigned_int = reference_global_vars.createref_unsigned_int(10);
+if (reference_global_vars.value_unsigned_int(reference_global_vars.var_unsigned_int) != 10) {
+    throw new Error;
+}
+
+reference_global_vars.var_long = reference_global_vars.createref_long(10);
+if (reference_global_vars.value_long(reference_global_vars.var_long) != 10) {
+    throw new Error;
+}
+
+reference_global_vars.var_unsigned_long = reference_global_vars.createref_unsigned_long(10);
+if (reference_global_vars.value_unsigned_long(reference_global_vars.var_unsigned_long) != 10) {
+    throw new Error;
+}
+
+reference_global_vars.var_long_long = reference_global_vars.createref_long_long(0x6FFFFFFFFFFFFFF8);
+if (reference_global_vars.value_long_long(reference_global_vars.var_long_long) != 0x6FFFFFFFFFFFFFF8) {
+    throw new Error;
+}
+
+//ull = abs(0xFFFFFFF2FFFFFFF0)
+ull = 55834574864;
+reference_global_vars.var_unsigned_long_long = reference_global_vars.createref_unsigned_long_long(ull);
+if (reference_global_vars.value_unsigned_long_long(reference_global_vars.var_unsigned_long_long) != ull) {
+    throw new Error;
+}
+
+reference_global_vars.var_float = reference_global_vars.createref_float(10.5);
+if (reference_global_vars.value_float(reference_global_vars.var_float) != 10.5) {
+    throw new Error;
+}
+
+reference_global_vars.var_double = reference_global_vars.createref_double(10.5);
+if (reference_global_vars.value_double(reference_global_vars.var_double) != 10.5) {
+    throw new Error;
+}
+
+// class reference variable
+reference_global_vars.var_TestClass = reference_global_vars.createref_TestClass(new reference_global_vars.TestClass(20));
+if (reference_global_vars.value_TestClass(reference_global_vars.var_TestClass).num != 20) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/rename_pcre_encoder_runme.js b/Examples/test-suite/javascript/rename_pcre_encoder_runme.js
new file mode 100644
index 0000000..b0e3a28
--- /dev/null
+++ b/Examples/test-suite/javascript/rename_pcre_encoder_runme.js
@@ -0,0 +1,18 @@
+var rename_pcre_encoder = require("rename_pcre_encoder");
+
+s = new rename_pcre_encoder.SomeWidget();
+s.put_borderWidth(3);
+if (s.get_borderWidth() != 3) {
+    throw new Error(`Border should be 3, not ${s.get_borderWidth()}`);
+}
+
+s.put_size(4, 5);
+a = new rename_pcre_encoder.AnotherWidget();
+a.DoSomething();
+
+evt = new rename_pcre_encoder.wxEVTSomeEvent();
+t = new rename_pcre_encoder.xUnchangedName();
+
+if (rename_pcre_encoder.StartINSAneAndUNSAvoryTraNSAtlanticRaNSAck() != 42) {
+    throw new Error("Unexpected result of renamed function call");
+}
diff --git a/Examples/test-suite/javascript/rename_predicates_runme.js b/Examples/test-suite/javascript/rename_predicates_runme.js
new file mode 100644
index 0000000..d8c69cc
--- /dev/null
+++ b/Examples/test-suite/javascript/rename_predicates_runme.js
@@ -0,0 +1,48 @@
+var rename_predicates = require("rename_predicates");
+
+r = new rename_predicates.RenamePredicates(123);
+r.MF_member_function();
+rename_predicates.RenamePredicates.MF_static_member_function();
+r.MF_extend_function_before();
+r.MF_extend_function_after();
+rename_predicates.GF_global_function();
+
+if (r.MV_member_variable != 123) {
+    throw new Error("variable wrong");
+}
+r.MV_member_variable = 1234;
+if (r.MV_member_variable != 1234) {
+    throw new Error("variable wrong");
+}
+
+if (rename_predicates.RenamePredicates.MV_static_member_variable != 456) {
+    throw new Error("variable wrong");
+}
+rename_predicates.RenamePredicates_MV_static_member_variable = 4567;
+if (rename_predicates.RenamePredicates_MV_static_member_variable != 4567) {
+    throw new Error("variable wrong");
+}
+
+if (rename_predicates.GV_global_variable != 789) {
+    throw new Error("variable wrong");
+}
+rename_predicates.GV_global_variable = 7890;
+if (rename_predicates.GV_global_variable != 7890) {
+    throw new Error("variable wrong");
+}
+
+rename_predicates.UC_UPPERCASE();
+rename_predicates.LC_lowercase();
+rename_predicates.TI_Title();
+rename_predicates.FU_FirstUpperCase();
+rename_predicates.FL_firstLowerCase();
+rename_predicates.CA_CamelCase();
+rename_predicates.LC_lowerCamelCase();
+rename_predicates.UC_under_case_it();
+
+ex = new rename_predicates.ExtendCheck();
+ex.MF_real_member1();
+ex.MF_real_member2();
+ex.EX_EXTENDMETHOD1();
+ex.EX_EXTENDMETHOD2();
+ex.EX_EXTENDMETHOD3();
diff --git a/Examples/test-suite/javascript/rename_rstrip_encoder_runme.js b/Examples/test-suite/javascript/rename_rstrip_encoder_runme.js
new file mode 100644
index 0000000..129749c
--- /dev/null
+++ b/Examples/test-suite/javascript/rename_rstrip_encoder_runme.js
@@ -0,0 +1,5 @@
+var rename_rstrip_encoder = require("rename_rstrip_encoder");
+
+s = new rename_rstrip_encoder.SomeThing();
+a = new rename_rstrip_encoder.AnotherThing();
+a.DoClsX();
diff --git a/Examples/test-suite/javascript/rename_strip_encoder_runme.js b/Examples/test-suite/javascript/rename_strip_encoder_runme.js
new file mode 100644
index 0000000..67a6a93
--- /dev/null
+++ b/Examples/test-suite/javascript/rename_strip_encoder_runme.js
@@ -0,0 +1,5 @@
+var rename_strip_encoder = require("rename_strip_encoder");
+
+s = new rename_strip_encoder.SomeWidget();
+a = new rename_strip_encoder.AnotherWidget();
+a.DoSomething();
diff --git a/Examples/test-suite/javascript/return_const_value_runme.js b/Examples/test-suite/javascript/return_const_value_runme.js
new file mode 100644
index 0000000..ef0ba28
--- /dev/null
+++ b/Examples/test-suite/javascript/return_const_value_runme.js
@@ -0,0 +1,11 @@
+var return_const_value = require("return_const_value");
+
+p = return_const_value.Foo_ptr.getPtr();
+if ((p.getVal() != 17)) {
+    throw new Error(`Runtime test1 failed. p.getVal()=${p.getVal()}`);
+}
+
+p = return_const_value.Foo_ptr.getConstPtr();
+if ((p.getVal() != 17)) {
+    throw new Error(`Runtime test2 failed. p.getVal()=${p.getVal()}`);
+}
diff --git a/Examples/test-suite/javascript/smart_pointer_member_runme.js b/Examples/test-suite/javascript/smart_pointer_member_runme.js
new file mode 100644
index 0000000..9cf4893
--- /dev/null
+++ b/Examples/test-suite/javascript/smart_pointer_member_runme.js
@@ -0,0 +1,24 @@
+var smart_pointer_member = require("smart_pointer_member");
+
+
+f = new smart_pointer_member.Foo();
+f.y = 1;
+
+if (f.y != 1) {
+    throw new Error;
+}
+
+b = new smart_pointer_member.Bar(f);
+b.y = 2;
+
+if (f.y != 2) {
+    throw new Error(`Failed ${f.y} ${f.x}`);
+}
+
+if (b.ZZ != f.ZZ) {
+    throw new Error(`Failed ${b.x} ${f.x}`);
+}
+
+if (b.z != f.z) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/smart_pointer_multi_runme.js b/Examples/test-suite/javascript/smart_pointer_multi_runme.js
new file mode 100644
index 0000000..089bcc8
--- /dev/null
+++ b/Examples/test-suite/javascript/smart_pointer_multi_runme.js
@@ -0,0 +1,16 @@
+var smart_pointer_multi = require("smart_pointer_multi");
+
+f = new smart_pointer_multi.Foo();
+b = new smart_pointer_multi.Bar(f);
+s = new smart_pointer_multi.Spam(b);
+g = new smart_pointer_multi.Grok(b);
+
+s.x = 3;
+if (s.getx() != 3) {
+    throw new Error;
+}
+
+g.x = 4;
+if (g.getx() != 4) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/smart_pointer_multi_typedef_runme.js b/Examples/test-suite/javascript/smart_pointer_multi_typedef_runme.js
new file mode 100644
index 0000000..aaf5baf
--- /dev/null
+++ b/Examples/test-suite/javascript/smart_pointer_multi_typedef_runme.js
@@ -0,0 +1,16 @@
+var smart_pointer_multi_typedef = require("smart_pointer_multi_typedef");
+
+f = new smart_pointer_multi_typedef.Foo();
+b = new smart_pointer_multi_typedef.Bar(f);
+s = new smart_pointer_multi_typedef.Spam(b);
+g = new smart_pointer_multi_typedef.Grok(b);
+
+s.x = 3;
+if (s.getx() != 3) {
+    throw new Error;
+}
+
+g.x = 4;
+if (g.getx() != 4) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/smart_pointer_not_runme.js b/Examples/test-suite/javascript/smart_pointer_not_runme.js
new file mode 100644
index 0000000..2c3a65e
--- /dev/null
+++ b/Examples/test-suite/javascript/smart_pointer_not_runme.js
@@ -0,0 +1,30 @@
+var smart_pointer_not = require("smart_pointer_not");
+
+f = new smart_pointer_not.Foo();
+b = new smart_pointer_not.Bar(f);
+s = new smart_pointer_not.Spam(f);
+g = new smart_pointer_not.Grok(f);
+
+// This is the only that should work
+f.getx();
+
+// Accessing an inexistent property in JS
+// does not throw - it returns undefined
+fail = false;
+try {
+    x = b.getx();
+    fail = new Error("Error! b.x");
+} catch { }
+if (fail) throw fail;
+
+try {
+    x = s.getx();
+    fail = new Error("Error! b.x");
+} catch { }
+if (fail) throw fail;
+
+try {
+    x = g.getx();
+    fail = new Error("Error! b.x");
+} catch { }
+if (fail) throw fail;
diff --git a/Examples/test-suite/javascript/smart_pointer_rename_runme.js b/Examples/test-suite/javascript/smart_pointer_rename_runme.js
new file mode 100644
index 0000000..f497c51
--- /dev/null
+++ b/Examples/test-suite/javascript/smart_pointer_rename_runme.js
@@ -0,0 +1,16 @@
+var smart_pointer_rename = require("smart_pointer_rename");
+
+f = new smart_pointer_rename.Foo();
+b = new smart_pointer_rename.Bar(f);
+
+if (b.test() != 3) {
+    throw new Error;
+}
+
+if (b.ftest1(1) != 1) {
+    throw new Error;
+}
+
+if (b.ftest2(2, 3) != 2) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/smart_pointer_simple_runme.js b/Examples/test-suite/javascript/smart_pointer_simple_runme.js
new file mode 100644
index 0000000..e00dcef
--- /dev/null
+++ b/Examples/test-suite/javascript/smart_pointer_simple_runme.js
@@ -0,0 +1,15 @@
+var smart_pointer_simple = require("smart_pointer_simple");
+
+f = new smart_pointer_simple.Foo();
+b = new smart_pointer_simple.Bar(f);
+
+b.x = 3;
+if (b.getx() != 3) {
+    throw new Error;
+}
+
+fp = b.__deref__();
+fp.x = 4;
+if (fp.getx() != 4) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/smart_pointer_templatevariables_runme.js b/Examples/test-suite/javascript/smart_pointer_templatevariables_runme.js
new file mode 100644
index 0000000..ddb5f8b
--- /dev/null
+++ b/Examples/test-suite/javascript/smart_pointer_templatevariables_runme.js
@@ -0,0 +1,22 @@
+var smart_pointer_templatevariables = require("smart_pointer_templatevariables");
+
+d = new smart_pointer_templatevariables.DiffImContainerPtr_D(smart_pointer_templatevariables.create(1234, 5678));
+
+// TODO xyz has been commented out in the shared test file, find out why
+
+if ((d.id != 1234)) {
+    throw new Error;
+}
+//if ((d.xyz != 5678)) {
+//    throw new Error;
+//}
+
+d.id = 4321;
+//d.xyz = 8765;
+
+if ((d.id != 4321)) {
+    throw new Error;
+}
+//if ((d.xyz != 8765)) {
+//    throw new Error;
+//}
diff --git a/Examples/test-suite/javascript/smart_pointer_typedef_runme.js b/Examples/test-suite/javascript/smart_pointer_typedef_runme.js
new file mode 100644
index 0000000..9641a12
--- /dev/null
+++ b/Examples/test-suite/javascript/smart_pointer_typedef_runme.js
@@ -0,0 +1,15 @@
+var smart_pointer_typedef = require("smart_pointer_typedef");
+
+f = new smart_pointer_typedef.Foo();
+b = new smart_pointer_typedef.Bar(f);
+
+b.x = 3;
+if (b.getx() != 3) {
+    throw new Error;
+}
+
+fp = b.__deref__();
+fp.x = 4;
+if (fp.getx() != 4) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/sneaky1_runme.js b/Examples/test-suite/javascript/sneaky1_runme.js
new file mode 100644
index 0000000..bb887ff
--- /dev/null
+++ b/Examples/test-suite/javascript/sneaky1_runme.js
@@ -0,0 +1,5 @@
+var sneaky1 = require("sneaky1");
+x = sneaky1.add(3, 4);
+y = sneaky1.subtract(3, 4);
+z = sneaky1.mul(3, 4);
+w = sneaky1.divide(3, 4);
diff --git a/Examples/test-suite/javascript/special_variable_macros_runme.js b/Examples/test-suite/javascript/special_variable_macros_runme.js
new file mode 100644
index 0000000..264a1a9
--- /dev/null
+++ b/Examples/test-suite/javascript/special_variable_macros_runme.js
@@ -0,0 +1,37 @@
+var special_variable_macros = require("special_variable_macros");
+
+var cvar = special_variable_macros;
+var name = new special_variable_macros.Name();
+if (special_variable_macros.testFred(name) != "none") {
+    throw new Error("test failed");
+}
+if (cvar.accessed_examplekw != 0) {
+    throw new Error("Precondition failed");
+}
+if (special_variable_macros.testJack(name) != "$specialname") {
+    throw new Error("test failed");
+}
+if (cvar.accessed_examplekw != 1) {
+    throw new Error("Postcondition failed");
+}
+if (special_variable_macros.testJill(name) != "jilly") {
+    throw new Error("test failed");
+}
+if (special_variable_macros.testMary(name) != "SWIGTYPE_p_NameWrap") {
+    throw new Error("test failed");
+}
+if (special_variable_macros.testJames(name) != "SWIGTYPE_Name") {
+    throw new Error("test failed");
+}
+if (special_variable_macros.testJim(name) != "multiname num") {
+    throw new Error("test failed");
+}
+if (special_variable_macros.testJohn(new special_variable_macros.PairIntBool(10, false)) != 123) {
+    throw new Error("test failed");
+}
+if (special_variable_macros.makeStringInt("stringint", 999) != "stringint") {
+    throw new Error("test failed");
+}
+if (special_variable_macros.provideStringInt(999) != "1000") {
+    throw new Error("test failed");
+}
diff --git a/Examples/test-suite/javascript/static_const_member_2_runme.js b/Examples/test-suite/javascript/static_const_member_2_runme.js
new file mode 100644
index 0000000..be54c78
--- /dev/null
+++ b/Examples/test-suite/javascript/static_const_member_2_runme.js
@@ -0,0 +1,13 @@
+var static_const_member_2 = require("static_const_member_2");
+
+c = new static_const_member_2.Test_int();
+a = c.forward_field;
+a = c.current_profile;
+a = c.RightIndex;
+a = static_const_member_2.Test_int.backward_field;
+a = static_const_member_2.Test_int.LeftIndex;
+a = static_const_member_2.Test_int.cavity_flags;
+
+if (static_const_member_2.Foo.BAZ.val != 2 * static_const_member_2.Foo.BAR.val) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/struct_initialization_runme.js b/Examples/test-suite/javascript/struct_initialization_runme.js
new file mode 100644
index 0000000..9ae8e79
--- /dev/null
+++ b/Examples/test-suite/javascript/struct_initialization_runme.js
@@ -0,0 +1,25 @@
+var struct_initialization = require("struct_initialization");
+
+if (struct_initialization.instanceC1.x != 10) {
+    throw new Error;
+}
+
+if (struct_initialization.instanceD1.x != 10) {
+    throw new Error;
+}
+
+if (struct_initialization.instanceD2.x != 20) {
+    throw new Error;
+}
+
+if (struct_initialization.instanceD3.x != 30) {
+    throw new Error;
+}
+
+if (struct_initialization.instanceE1.x != 1) {
+    throw new Error;
+}
+
+if (struct_initialization.instanceF1.x != 1) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/struct_rename_runme.js b/Examples/test-suite/javascript/struct_rename_runme.js
new file mode 100644
index 0000000..25ec7a0
--- /dev/null
+++ b/Examples/test-suite/javascript/struct_rename_runme.js
@@ -0,0 +1,3 @@
+var struct_rename = require("struct_rename");
+
+b = new struct_rename.Bar();
diff --git a/Examples/test-suite/javascript/template_class_reuse_name_runme.js b/Examples/test-suite/javascript/template_class_reuse_name_runme.js
new file mode 100644
index 0000000..aa44496
--- /dev/null
+++ b/Examples/test-suite/javascript/template_class_reuse_name_runme.js
@@ -0,0 +1,42 @@
+var template_class_reuse_name = require("template_class_reuse_name");
+
+new template_class_reuse_name.Bool1().tt()
+new template_class_reuse_name.Bool1False().ff()
+
+new template_class_reuse_name.Bool2().tt()
+new template_class_reuse_name.Bool2False().ff()
+
+new template_class_reuse_name.Bool3().tt()
+new template_class_reuse_name.Bool3False().ff()
+
+new template_class_reuse_name.Bool4().tt()
+new template_class_reuse_name.Bool4False().ff()
+
+
+new template_class_reuse_name.BoolForward1().tt()
+new template_class_reuse_name.BoolForward1False().ff()
+
+new template_class_reuse_name.BoolForward2().tt()
+new template_class_reuse_name.BoolForward2False().ff()
+
+new template_class_reuse_name.BoolForward3().tt()
+new template_class_reuse_name.BoolForward3False().ff()
+
+new template_class_reuse_name.BoolForward4().tt()
+new template_class_reuse_name.BoolForward4False().ff()
+
+
+new template_class_reuse_name.IntBool1().tt()
+new template_class_reuse_name.IntBool1False().ff()
+
+new template_class_reuse_name.IntBool2().tt()
+new template_class_reuse_name.IntBool2False().ff()
+
+new template_class_reuse_name.IntBool3().tt()
+new template_class_reuse_name.IntBool3False().ff()
+
+new template_class_reuse_name.IntBool4().tt()
+new template_class_reuse_name.IntBool4False().ff()
+
+new template_class_reuse_name.Duplicate2_0().n()
+new template_class_reuse_name.Duplicate3().n()
diff --git a/Examples/test-suite/javascript/template_classes_runme.js b/Examples/test-suite/javascript/template_classes_runme.js
new file mode 100644
index 0000000..2d898ea
--- /dev/null
+++ b/Examples/test-suite/javascript/template_classes_runme.js
@@ -0,0 +1,52 @@
+var template_classes = require("template_classes");
+
+// This test is just testing incorrect number of arguments/parameters checking
+
+point = new template_classes.PointInt();
+
+rectangle = new template_classes.RectangleInt();
+rectangle.setPoint(point);
+rectangle.getPoint();
+template_classes.RectangleInt.static_noargs();
+template_classes.RectangleInt.static_onearg(1);
+
+fail = true;
+try {
+    rectangle.setPoint();
+} catch {
+    fail = false;
+}
+if (fail) {
+    throw new Error("argument count check failed");
+}
+
+
+fail = true;
+try {
+    rectangle.getPoint(0);
+} catch {
+    fail = false;
+}
+if (fail) {
+    throw new Error("argument count check failed");
+}
+
+fail = true;
+try {
+    RectangleInt.static_noargs(0);
+} catch {
+    fail = false;
+}
+if (fail) {
+    throw new Error("argument count check failed");
+}
+
+fail = true;
+try {
+    RectangleInt.static_onearg();
+} catch {
+    fail = false;
+}
+if (fail) {
+    throw new Error("argument count check failed");
+}
diff --git a/Examples/test-suite/javascript/template_construct_runme.js b/Examples/test-suite/javascript/template_construct_runme.js
new file mode 100644
index 0000000..8191c0e
--- /dev/null
+++ b/Examples/test-suite/javascript/template_construct_runme.js
@@ -0,0 +1,3 @@
+var template_construct = require("template_construct")
+
+f = new template_construct.Foo_int(2);
diff --git a/Examples/test-suite/javascript/template_default_arg_overloaded_extend_runme.js b/Examples/test-suite/javascript/template_default_arg_overloaded_extend_runme.js
new file mode 100644
index 0000000..5f7f512
--- /dev/null
+++ b/Examples/test-suite/javascript/template_default_arg_overloaded_extend_runme.js
@@ -0,0 +1,22 @@
+var template_default_arg_overloaded_extend = require("template_default_arg_overloaded_extend");
+
+function check(flag) {
+  if (!flag) {
+    throw new Error("failed");
+  }
+}
+
+rs = new template_default_arg_overloaded_extend.ResultSet();
+
+check(rs.go_get_method(0, new template_default_arg_overloaded_extend.SearchPoint()) == -1);
+check(rs.go_get_method(0, new template_default_arg_overloaded_extend.SearchPoint(), 100) == 100);
+
+check(rs.go_get_template(0, new template_default_arg_overloaded_extend.SearchPoint()) == -2);
+check(rs.go_get_template(0, new template_default_arg_overloaded_extend.SearchPoint(), 100) == 100);
+
+check(rs.over() == "over(int)");
+check(rs.over(10) == "over(int)");
+check(rs.over(new template_default_arg_overloaded_extend.SearchPoint()) == "over(giai2::SearchPoint, int)");
+check(rs.over(new template_default_arg_overloaded_extend.SearchPoint(), 10) == "over(giai2::SearchPoint, int)");
+check(rs.over(true, new template_default_arg_overloaded_extend.SearchPoint()) == "over(bool, gaia2::SearchPoint, int)");
+check(rs.over(true, new template_default_arg_overloaded_extend.SearchPoint(), 10) == "over(bool, gaia2::SearchPoint, int)");
diff --git a/Examples/test-suite/javascript/template_default_arg_overloaded_runme.js b/Examples/test-suite/javascript/template_default_arg_overloaded_runme.js
new file mode 100644
index 0000000..d0b61b0
--- /dev/null
+++ b/Examples/test-suite/javascript/template_default_arg_overloaded_runme.js
@@ -0,0 +1,49 @@
+var template_default_arg_overloaded = require("template_default_arg_overloaded");
+
+function check(expected, got) {
+  if (expected != got) {
+    throw new Error("Expected: " + str(expected) + " got: " + str(got));
+  }
+}
+
+
+pl = new template_default_arg_overloaded.PropertyList();
+check(1, pl.setInt("int", 10));
+check(1, pl.setInt("int", 10, false));
+
+check(2, pl.set("int", pl));
+check(2, pl.set("int", pl, false));
+
+check(3, pl.setInt("int", 10, "int"));
+check(3, pl.setInt("int", 10, "int", false));
+
+
+pl = new template_default_arg_overloaded.PropertyListGlobal();
+check(1, pl.setIntGlobal("int", 10));
+check(1, pl.setIntGlobal("int", 10, false));
+
+check(2, pl.set("int", pl));
+check(2, pl.set("int", pl, false));
+
+check(3, pl.setIntGlobal("int", 10, "int"));
+check(3, pl.setIntGlobal("int", 10, "int", false));
+
+
+check(1, template_default_arg_overloaded.GoopIntGlobal(10));
+check(1, template_default_arg_overloaded.GoopIntGlobal(10, true));
+
+check(2, template_default_arg_overloaded.goopGlobal(3));
+check(2, template_default_arg_overloaded.goopGlobal());
+
+check(3, template_default_arg_overloaded.GoopIntGlobal("int", false));
+check(3, template_default_arg_overloaded.GoopIntGlobal("int"));
+
+
+check(1, template_default_arg_overloaded.GoopInt(10));
+check(1, template_default_arg_overloaded.GoopInt(10, true));
+
+check(2, template_default_arg_overloaded.goop(3));
+check(2, template_default_arg_overloaded.goop());
+
+check(3, template_default_arg_overloaded.GoopInt("int", false));
+check(3, template_default_arg_overloaded.GoopInt("int"));
diff --git a/Examples/test-suite/javascript/template_default_arg_runme.js b/Examples/test-suite/javascript/template_default_arg_runme.js
new file mode 100644
index 0000000..f8b7fd9
--- /dev/null
+++ b/Examples/test-suite/javascript/template_default_arg_runme.js
@@ -0,0 +1,112 @@
+var template_default_arg = require("template_default_arg");
+
+
+helloInt = new template_default_arg.Hello_int();
+helloInt.foo(template_default_arg.Hello_int.hi);
+
+
+x = new template_default_arg.X_int();
+if ((x.meth(20, 200) != 200)) {
+    throw new Error(("X_int test 1 failed"));
+}
+if ((x.meth(20) != 0)) {
+    throw new Error(("X_int test 2 failed"));
+}
+if ((x.meth() != 0)) {
+    throw new Error(("X_int test 3 failed"));
+}
+
+
+y = new template_default_arg.Y_unsigned();
+if ((y.meth(20.0, 200) != 200)) {
+    throw new Error(("Y_unsigned test 1 failed"));
+}
+if ((y.meth(20) != 0)) {
+    throw new Error(("Y_unsigned test 2 failed"));
+}
+if ((y.meth() != 0)) {
+    throw new Error(("Y_unsigned test 3 failed"));
+}
+
+
+x = new template_default_arg.X_longlong();
+x = new template_default_arg.X_longlong(20.0);
+x = new template_default_arg.X_longlong(20.0, 200);
+
+
+x = new template_default_arg.X_int();
+x = new template_default_arg.X_int(20.0);
+x = new template_default_arg.X_int(20.0, 200);
+
+
+x = new template_default_arg.X_hello_unsigned();
+x = new template_default_arg.X_hello_unsigned(20.0);
+x = new template_default_arg.X_hello_unsigned(
+    20.0, new template_default_arg.Hello_int());
+
+
+y = new template_default_arg.Y_hello_unsigned();
+y.meth(20.0, new template_default_arg.Hello_int());
+y.meth(new template_default_arg.Hello_int());
+y.meth();
+
+
+fz = new template_default_arg.Foo_Z_8();
+x = new template_default_arg.X_Foo_Z_8();
+fzc = x.meth(fz);
+
+
+// Templated functions
+
+// plain function: int ott(Foo<int>)
+if ((template_default_arg.ott(new template_default_arg.Foo_int()) != 30)) {
+    throw new Error(("ott test 1 failed"));
+}
+
+// %template(ott) ott<int, int>
+if ((template_default_arg.ott() != 10)) {
+    throw new Error(("ott test 2 failed"));
+}
+if ((template_default_arg.ott(1) != 10)) {
+    throw new Error(("ott test 3 failed"));
+}
+if ((template_default_arg.ott(1, 1) != 10)) {
+    throw new Error(("ott test 4 failed"));
+}
+
+if ((template_default_arg.ott("hi") != 20)) {
+    throw new Error(("ott test 5 failed"));
+}
+if ((template_default_arg.ott("hi", 1) != 20)) {
+    throw new Error(("ott test 6 failed"));
+}
+if ((template_default_arg.ott("hi", 1, 1) != 20)) {
+    throw new Error(("ott test 7 failed"));
+}
+
+// %template(ott) ott<const char *>
+if ((template_default_arg.ottstring(new template_default_arg.Hello_int(), "hi") != 40)) {
+    throw new Error(("ott test 8 failed"));
+}
+
+if ((template_default_arg.ottstring(new template_default_arg.Hello_int()) != 40)) {
+    throw new Error(("ott test 9 failed"));
+}
+
+// %template(ott) ott<int>
+if ((template_default_arg.ottint(new template_default_arg.Hello_int(), 1) != 50)) {
+    throw new Error(("ott test 10 failed"));
+}
+
+if ((template_default_arg.ottint(new template_default_arg.Hello_int()) != 50)) {
+    throw new Error(("ott test 11 failed"));
+}
+
+// %template(ott) ott<double>
+if ((template_default_arg.ott(new template_default_arg.Hello_int(), 1.0) != 60)) {
+    throw new Error(("ott test 12 failed"));
+}
+
+if ((template_default_arg.ott(new template_default_arg.Hello_int()) != 60)) {
+    throw new Error(("ott test 13 failed"));
+}
diff --git a/Examples/test-suite/javascript/template_default_cache_runme.js b/Examples/test-suite/javascript/template_default_cache_runme.js
new file mode 100644
index 0000000..d1376d4
--- /dev/null
+++ b/Examples/test-suite/javascript/template_default_cache_runme.js
@@ -0,0 +1,11 @@
+var template_default_cache = require("template_default_cache");
+
+ap = template_default_cache.get_mp_a();
+bp = template_default_cache.get_mp_b();
+
+if (!ap instanceof template_default_cache.AModelPtr) {
+    throw new Error("get_mp_a fail");
+}
+if (!bp instanceof template_default_cache.BModelPtr) {
+    throw new Error("get_mp_b fail");
+}
diff --git a/Examples/test-suite/javascript/template_extend1_runme.js b/Examples/test-suite/javascript/template_extend1_runme.js
new file mode 100644
index 0000000..20ebbf2
--- /dev/null
+++ b/Examples/test-suite/javascript/template_extend1_runme.js
@@ -0,0 +1,12 @@
+var template_extend1 = require("template_extend1");
+
+a = new template_extend1.lBaz();
+b = new template_extend1.dBaz();
+
+if (a.foo() != "lBaz::foo") {
+    throw new Error;
+}
+
+if (b.foo() != "dBaz::foo") {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/template_extend2_runme.js b/Examples/test-suite/javascript/template_extend2_runme.js
new file mode 100644
index 0000000..84eab3a
--- /dev/null
+++ b/Examples/test-suite/javascript/template_extend2_runme.js
@@ -0,0 +1,12 @@
+var template_extend2 = require("template_extend2");
+
+a = new template_extend2.lBaz();
+b = new template_extend2.dBaz();
+
+if (a.foo() != "lBaz::foo") {
+    throw new Error;
+}
+
+if (b.foo() != "dBaz::foo") {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/template_inherit_runme.js b/Examples/test-suite/javascript/template_inherit_runme.js
new file mode 100644
index 0000000..f5ba569
--- /dev/null
+++ b/Examples/test-suite/javascript/template_inherit_runme.js
@@ -0,0 +1,67 @@
+var template_inherit = require("template_inherit");
+a = new template_inherit.FooInt();
+b = new template_inherit.FooDouble();
+c = new template_inherit.BarInt();
+d = new template_inherit.BarDouble();
+e = new template_inherit.FooUInt();
+f = new template_inherit.BarUInt();
+
+if (a.blah() != "Foo") {
+    throw new Error;
+}
+
+if (b.blah() != "Foo") {
+    throw new Error;
+}
+
+if (e.blah() != "Foo") {
+    throw new Error;
+}
+
+if (c.blah() != "Bar") {
+    throw new Error;
+}
+
+if (d.blah() != "Bar") {
+    throw new Error;
+}
+
+if (f.blah() != "Bar") {
+    throw new Error;
+}
+
+if (c.foomethod() != "foomethod") {
+    throw new Error;
+}
+
+if (d.foomethod() != "foomethod") {
+    throw new Error;
+}
+
+if (f.foomethod() != "foomethod") {
+    throw new Error;
+}
+
+if (template_inherit.invoke_blah_int(a) != "Foo") {
+    throw new Error;
+}
+
+if (template_inherit.invoke_blah_int(c) != "Bar") {
+    throw new Error;
+}
+
+if (template_inherit.invoke_blah_double(b) != "Foo") {
+    throw new Error;
+}
+
+if (template_inherit.invoke_blah_double(d) != "Bar") {
+    throw new Error;
+}
+
+if (template_inherit.invoke_blah_uint(e) != "Foo") {
+    throw new Error;
+}
+
+if (template_inherit.invoke_blah_uint(f) != "Bar") {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/template_ns4_runme.js b/Examples/test-suite/javascript/template_ns4_runme.js
new file mode 100644
index 0000000..3ba5762
--- /dev/null
+++ b/Examples/test-suite/javascript/template_ns4_runme.js
@@ -0,0 +1,6 @@
+var template_ns4 = require("template_ns4");
+
+d = template_ns4.make_Class_DD();
+if (d.test() != "test") {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/template_ns_runme.js b/Examples/test-suite/javascript/template_ns_runme.js
new file mode 100644
index 0000000..dde3a33
--- /dev/null
+++ b/Examples/test-suite/javascript/template_ns_runme.js
@@ -0,0 +1,21 @@
+var template_ns = require("template_ns");
+p1 = new template_ns.pairii(2, 3);
+p2 = new template_ns.pairii(p1);
+
+if (p2.first != 2) {
+    throw new Error;
+}
+if (p2.second != 3) {
+    throw new Error;
+}
+
+p3 = new template_ns.pairdd(3.5, 2.5);
+p4 = new template_ns.pairdd(p3);
+
+if (p4.first != 3.5) {
+    throw new Error;
+}
+
+if (p4.second != 2.5) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/template_opaque_runme.js b/Examples/test-suite/javascript/template_opaque_runme.js
new file mode 100644
index 0000000..cb115ac
--- /dev/null
+++ b/Examples/test-suite/javascript/template_opaque_runme.js
@@ -0,0 +1,5 @@
+var template_opaque = require("template_opaque");
+
+v = new template_opaque.OpaqueVectorType(10);
+
+template_opaque.FillVector(v);
diff --git a/Examples/test-suite/javascript/template_ref_type_runme.js b/Examples/test-suite/javascript/template_ref_type_runme.js
new file mode 100644
index 0000000..7fd0530
--- /dev/null
+++ b/Examples/test-suite/javascript/template_ref_type_runme.js
@@ -0,0 +1,5 @@
+var template_ref_type = require("template_ref_type");
+
+xr = new template_ref_type.XC();
+y = new template_ref_type.Y();
+y.find(xr);
diff --git a/Examples/test-suite/javascript/template_rename_runme.js b/Examples/test-suite/javascript/template_rename_runme.js
new file mode 100644
index 0000000..ae8f849
--- /dev/null
+++ b/Examples/test-suite/javascript/template_rename_runme.js
@@ -0,0 +1,12 @@
+var template_rename = require("template_rename");
+
+i = new template_rename.iFoo();
+d = new template_rename.dFoo();
+
+a = i.blah_test(4);
+b = i.spam_test(5);
+c = i.groki_test(6);
+
+x = d.blah_test(7);
+y = d.spam(8);
+z = d.grok_test(9);
diff --git a/Examples/test-suite/javascript/template_tbase_template_runme.js b/Examples/test-suite/javascript/template_tbase_template_runme.js
new file mode 100644
index 0000000..090126d
--- /dev/null
+++ b/Examples/test-suite/javascript/template_tbase_template_runme.js
@@ -0,0 +1,6 @@
+var template_tbase_template = require("template_tbase_template");
+
+a = template_tbase_template.make_Class_dd();
+if (a.test() != "test") {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/template_template_parameters_runme.js b/Examples/test-suite/javascript/template_template_parameters_runme.js
new file mode 100644
index 0000000..b832b2c
--- /dev/null
+++ b/Examples/test-suite/javascript/template_template_parameters_runme.js
@@ -0,0 +1,38 @@
+var template_template_parameters = require("template_template_parameters");
+
+// Test part 1
+listBool = new template_template_parameters.ListFastBool();
+listBool.item = true;
+x_boolean = listBool.allotype;
+if (listBool.item != true) {
+  throw new Error("Failed");
+}
+
+listDouble = new template_template_parameters.ListDefaultDouble();
+listDouble.item = 10.2;
+x_double = listDouble.allotype;
+if (listDouble.item != 10.2) {
+  throw new Error("Failed");
+}
+
+// Test part 2
+floatTestStruct = new template_template_parameters.FloatTestStruct();
+floatContainer2 = floatTestStruct.x;
+floatContainer2.x = 8.1;
+intTestStruct = new template_template_parameters.IntTestStruct();
+intContainer1 = intTestStruct.x;
+intContainer1.x = 91;
+if (intContainer1.x != 91) {
+  throw new Error("Failed");
+}
+if (intTestStruct.x.x != 91) {
+  throw new Error("Failed");
+}
+intTestStructReturned = template_template_parameters.TestStructContainer1Method(intTestStruct);
+if (intTestStructReturned.x.x != 101) {
+  throw new Error("Failed");
+}
+
+// Test part 3
+mfi99 = new template_template_parameters.MyFootInt99();
+mfi99.addTo(mfi99); // __iadd__
diff --git a/Examples/test-suite/javascript/template_type_namespace_runme.js b/Examples/test-suite/javascript/template_type_namespace_runme.js
new file mode 100644
index 0000000..056d645
--- /dev/null
+++ b/Examples/test-suite/javascript/template_type_namespace_runme.js
@@ -0,0 +1,5 @@
+var template_type_namespace = require("template_type_namespace");
+
+if (template_type_namespace.foo().get(0) != "foo") {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/template_typedef_cplx2_runme.js b/Examples/test-suite/javascript/template_typedef_cplx2_runme.js
new file mode 100644
index 0000000..f97e927
--- /dev/null
+++ b/Examples/test-suite/javascript/template_typedef_cplx2_runme.js
@@ -0,0 +1,24 @@
+var template_typedef_cplx2 = require("template_typedef_cplx2");
+
+//
+// double case
+//
+
+var d, e;
+
+try {
+    d = template_typedef_cplx2.make_Identity_double();
+    // This test is not possible in JSC where all SWIG proxies inherit from Object
+    if (typeof print === 'undefined')
+        if (!d.constructor.name.includes('ArithUnaryFunction')) throw new Error;
+} catch {
+    throw new Error(`${d} is not an ArithUnaryFunction`);
+}
+
+try {
+    e = template_typedef_cplx2.make_Multiplies_double_double_double_double(d, d);
+    if (typeof print === 'undefined')
+        if (!e.constructor.name.includes('ArithUnaryFunction')) throw new Error;
+} catch {
+    throw new Error(`${e} is not an ArithUnaryFunction`);
+}
diff --git a/Examples/test-suite/javascript/template_typedef_cplx3_runme.js b/Examples/test-suite/javascript/template_typedef_cplx3_runme.js
new file mode 100644
index 0000000..0bec611
--- /dev/null
+++ b/Examples/test-suite/javascript/template_typedef_cplx3_runme.js
@@ -0,0 +1,19 @@
+var template_typedef_cplx3 = require("template_typedef_cplx3");
+
+//
+// this is OK
+//
+
+
+s = new template_typedef_cplx3.Sin();
+s.get_base_value();
+s.get_value();
+s.get_arith_value();
+template_typedef_cplx3.my_func_r(s);
+template_typedef_cplx3.make_Multiplies_double_double_double_double(s, s);
+
+//
+// Here we fail
+//
+d = template_typedef_cplx3.make_Identity_double();
+template_typedef_cplx3.my_func_r(d);
diff --git a/Examples/test-suite/javascript/template_typedef_cplx4_runme.js b/Examples/test-suite/javascript/template_typedef_cplx4_runme.js
new file mode 100644
index 0000000..1f6a65c
--- /dev/null
+++ b/Examples/test-suite/javascript/template_typedef_cplx4_runme.js
@@ -0,0 +1,19 @@
+var template_typedef_cplx4 = require("template_typedef_cplx4");
+
+//
+// this is OK
+//
+
+
+s = new template_typedef_cplx4.Sin();
+s.get_base_value();
+s.get_value();
+s.get_arith_value();
+template_typedef_cplx4.my_func_r(s);
+template_typedef_cplx4.make_Multiplies_double_double_double_double(s, s);
+
+//
+// Here we fail
+//
+d = template_typedef_cplx4.make_Identity_double();
+template_typedef_cplx4.my_func_r(d);
diff --git a/Examples/test-suite/javascript/template_typedef_cplx_runme.js b/Examples/test-suite/javascript/template_typedef_cplx_runme.js
new file mode 100644
index 0000000..977b986
--- /dev/null
+++ b/Examples/test-suite/javascript/template_typedef_cplx_runme.js
@@ -0,0 +1,24 @@
+var template_typedef_cplx = require("template_typedef_cplx");
+
+//
+// double case
+//
+
+var d, e;
+
+try {
+    d = template_typedef_cplx.make_Identity_double();
+    // This test is not possible in JSC where all SWIG proxies inherit from Object
+    if (typeof print === 'undefined')
+        if (!d.constructor.name.includes('ArithUnaryFunction')) throw new Error;
+} catch {
+    throw new Error(`${d} is not an ArithUnaryFunction`);
+}
+
+try {
+    e = template_typedef_cplx.make_Multiplies_double_double_double_double(d, d);
+    if (typeof print === 'undefined')
+        if (!e.constructor.name.includes('ArithUnaryFunction')) throw new Error;
+} catch {
+    throw new Error(`${e} is not an ArithUnaryFunction`);
+}
diff --git a/Examples/test-suite/javascript/template_typemaps_typedef2_runme.js b/Examples/test-suite/javascript/template_typemaps_typedef2_runme.js
new file mode 100644
index 0000000..911a3fc
--- /dev/null
+++ b/Examples/test-suite/javascript/template_typemaps_typedef2_runme.js
@@ -0,0 +1,42 @@
+var template_typemaps_typedef2 = require("template_typemaps_typedef2");
+
+m1 = new template_typemaps_typedef2.MultimapIntA();
+
+dummy_pair = m1.make_dummy_pair();
+val = m1.typemap_test(dummy_pair).val;
+if (val != 1234) {
+    throw new Error("typemaps not working");
+}
+
+m2 = new template_typemaps_typedef2.MultimapAInt();
+
+// TODO: typemaps and specializations not quite working as expected. T needs expanding, but at least the right typemap is being picked up.
+//dummy_pair = m2.make_dummy_pair()
+//val = m2.typemap_test(dummy_pair)
+
+// if (val != 4321) {
+//    throw new Error, "typemaps not working"
+
+if (template_typemaps_typedef2.typedef_test1(dummy_pair).val != 1234) {
+    throw new Error("template_typemaps_typedef2.typedef_test1 not working");
+}
+
+if (template_typemaps_typedef2.typedef_test2(dummy_pair).val != 1234) {
+    throw new Error("template_typemaps_typedef2.typedef_test2 not working");
+}
+
+if (template_typemaps_typedef2.typedef_test3(dummy_pair).val != 1234) {
+    throw new Error("template_typemaps_typedef2.typedef_test3 not working");
+}
+
+if (template_typemaps_typedef2.typedef_test4(dummy_pair).val != 1234) {
+    throw new Error("template_typemaps_typedef2.typedef_test4 not working");
+}
+
+if (template_typemaps_typedef2.typedef_test5(dummy_pair).val != 1234) {
+    throw new Error("template_typemaps_typedef2.typedef_test5 not working");
+}
+
+if (template_typemaps_typedef2.typedef_test6(dummy_pair).val != 1234) {
+    throw new Error("template_typemaps_typedef2.typedef_test6 not working");
+}
diff --git a/Examples/test-suite/javascript/template_typemaps_typedef_runme.js b/Examples/test-suite/javascript/template_typemaps_typedef_runme.js
new file mode 100644
index 0000000..d94c4be
--- /dev/null
+++ b/Examples/test-suite/javascript/template_typemaps_typedef_runme.js
@@ -0,0 +1,42 @@
+var template_typemaps_typedef = require("template_typemaps_typedef");
+
+m1 = new template_typemaps_typedef.MultimapIntA();
+
+dummy_pair = m1.make_dummy_pair();
+val = m1.typemap_test(dummy_pair).val;
+if (val != 1234) {
+    throw new Error("typemaps not working");
+}
+
+m2 = new template_typemaps_typedef.MultimapAInt();
+
+// TODO: typemaps and specializations not quite working as expected. T needs expanding, but at least the right typemap is being picked up.
+//dummy_pair = m2.make_dummy_pair()
+//val = m2.typemap_test(dummy_pair)
+
+// if (val != 4321) {
+//    throw new Error, "typemaps not working"
+
+if (template_typemaps_typedef.typedef_test1(dummy_pair).val != 1234) {
+    throw new Error("template_typemaps_typedef.typedef_test1 not working");
+}
+
+if (template_typemaps_typedef.typedef_test2(dummy_pair).val != 1234) {
+    throw new Error("template_typemaps_typedef.typedef_test2 not working");
+}
+
+if (template_typemaps_typedef.typedef_test3(dummy_pair).val != 1234) {
+    throw new Error("template_typemaps_typedef.typedef_test3 not working");
+}
+
+if (template_typemaps_typedef.typedef_test4(dummy_pair).val != 1234) {
+    throw new Error("template_typemaps_typedef.typedef_test4 not working");
+}
+
+if (template_typemaps_typedef.typedef_test5(dummy_pair).val != 1234) {
+    throw new Error("template_typemaps_typedef.typedef_test5 not working");
+}
+
+if (template_typemaps_typedef.typedef_test6(dummy_pair).val != 1234) {
+    throw new Error("template_typemaps_typedef.typedef_test6 not working");
+}
diff --git a/Examples/test-suite/javascript/template_using_directive_typedef_runme.js b/Examples/test-suite/javascript/template_using_directive_typedef_runme.js
new file mode 100644
index 0000000..de5482f
--- /dev/null
+++ b/Examples/test-suite/javascript/template_using_directive_typedef_runme.js
@@ -0,0 +1,15 @@
+var template_using_directive_typedef = require("template_using_directive_typedef")
+
+vo = new template_using_directive_typedef.Vector_Obj();
+
+h = new template_using_directive_typedef.Holder();
+h.holder_use1(vo, vo, vo);
+h.holder_use2(vo, vo, vo);
+h.holder_use3(vo, vo, vo);
+
+template_using_directive_typedef.tns_holder_use(vo, vo);
+template_using_directive_typedef.tns_use(vo, vo, vo);
+template_using_directive_typedef.global_holder_use(vo);
+template_using_directive_typedef.global_use(vo, vo, vo);
+template_using_directive_typedef.ns1_holder_use(vo);
+template_using_directive_typedef.ns2_holder_use(vo, vo, vo, vo);
diff --git a/Examples/test-suite/javascript/typedef_classforward_same_name_runme.js b/Examples/test-suite/javascript/typedef_classforward_same_name_runme.js
new file mode 100644
index 0000000..ff8a1ed
--- /dev/null
+++ b/Examples/test-suite/javascript/typedef_classforward_same_name_runme.js
@@ -0,0 +1,13 @@
+var typedef_classforward_same_name = require("typedef_classforward_same_name");
+
+foo = new typedef_classforward_same_name.Foo();
+foo.x = 5;
+if (typedef_classforward_same_name.extractFoo(foo) != 5) {
+    throw new Error("unexpected value");
+}
+
+boo = new typedef_classforward_same_name.Boo();
+boo.x = 5;
+if (typedef_classforward_same_name.extractBoo(boo) != 5) {
+    throw new Error("unexpected value");
+}
diff --git a/Examples/test-suite/javascript/typedef_funcptr_runme.js b/Examples/test-suite/javascript/typedef_funcptr_runme.js
new file mode 100644
index 0000000..ca0f81a
--- /dev/null
+++ b/Examples/test-suite/javascript/typedef_funcptr_runme.js
@@ -0,0 +1,25 @@
+var typedef_funcptr = require("typedef_funcptr");
+
+a = 100;
+b = 10;
+
+if (typedef_funcptr.do_op(a, b, typedef_funcptr.addf) != 110) {
+  throw new Error("addf failed");
+}
+if (typedef_funcptr.do_op(a, b, typedef_funcptr.subf) != 90) {
+  throw new Error("subf failed");
+}
+
+if (typedef_funcptr.do_op_typedef_int(a, b, typedef_funcptr.addf) != 110) {
+  throw new Error("addf failed");
+}
+if (typedef_funcptr.do_op_typedef_int(a, b, typedef_funcptr.subf) != 90) {
+  throw new Error("subf failed");
+}
+
+if (typedef_funcptr.do_op_typedef_Integer(a, b, typedef_funcptr.addf) != 110) {
+  throw new Error("addf failed");
+}
+if (typedef_funcptr.do_op_typedef_Integer(a, b, typedef_funcptr.subf) != 90) {
+  throw new Error("subf failed");
+}
diff --git a/Examples/test-suite/javascript/typedef_inherit_runme.js b/Examples/test-suite/javascript/typedef_inherit_runme.js
index 7590e1e..1ebb128 100644
--- a/Examples/test-suite/javascript/typedef_inherit_runme.js
+++ b/Examples/test-suite/javascript/typedef_inherit_runme.js
@@ -21,3 +21,7 @@
 x = typedef_inherit.do_blah2(d);
 if (x != "Grok::blah")
     print ("Whoa! Bad return" + x);
+
+x = d.far();
+if (x != "Spam::far")
+    print ("Whoa! Bad return" + x);
diff --git a/Examples/test-suite/javascript/typedef_typedef_runme.js b/Examples/test-suite/javascript/typedef_typedef_runme.js
new file mode 100644
index 0000000..2a7b649
--- /dev/null
+++ b/Examples/test-suite/javascript/typedef_typedef_runme.js
@@ -0,0 +1,6 @@
+var typedef_typedef = require("typedef_typedef");
+
+b = new typedef_typedef.B();
+if (b.getValue(123) != 1234) {
+    throw new Error("Failed");
+}
diff --git a/Examples/test-suite/javascript/typemap_documentation_runme.js b/Examples/test-suite/javascript/typemap_documentation_runme.js
new file mode 100644
index 0000000..c0118d7
--- /dev/null
+++ b/Examples/test-suite/javascript/typemap_documentation_runme.js
@@ -0,0 +1,27 @@
+var typemap_documentation = require("typemap_documentation");
+
+f = new typemap_documentation.Foo();
+f.x = 55;
+b = new typemap_documentation.Bar();
+b.y = 44;
+
+if (55 != typemap_documentation.GrabVal(f)) {
+    throw new Error("bad value");
+}
+
+try {
+    typemap_documentation.GrabVal(b);
+} catch (e) {
+    // This is working only in NAPI, other backends throw generic errors
+    //if (!(e instanceof TypeError))
+    //    throw e;
+    if (!e.message.includes('expecting type Foo'))
+        throw e;
+}
+
+if (55 != typemap_documentation.GrabValFooBar(f)) {
+    throw new Error("bad f value");
+}
+if (44 != typemap_documentation.GrabValFooBar(b)) {
+    throw new Error("bad b value");
+}
diff --git a/Examples/test-suite/javascript/typemap_out_optimal_runme.js b/Examples/test-suite/javascript/typemap_out_optimal_runme.js
new file mode 100644
index 0000000..d9f303a
--- /dev/null
+++ b/Examples/test-suite/javascript/typemap_out_optimal_runme.js
@@ -0,0 +1,5 @@
+var typemap_out_optimal = require("typemap_out_optimal");
+
+typemap_out_optimal.XX.trace = false;
+x = typemap_out_optimal.XX.create();
+x = typemap_out_optimal.XX.createConst();
diff --git a/Examples/test-suite/javascript/typemap_qualifier_strip_runme.js b/Examples/test-suite/javascript/typemap_qualifier_strip_runme.js
new file mode 100644
index 0000000..e4f5c12
--- /dev/null
+++ b/Examples/test-suite/javascript/typemap_qualifier_strip_runme.js
@@ -0,0 +1,69 @@
+var typemap_qualifier_strip = require("typemap_qualifier_strip");
+
+val = typemap_qualifier_strip.create_int(111);
+if (typemap_qualifier_strip.testA1(val) != 1234) {
+    throw new Error;
+}
+
+if (typemap_qualifier_strip.testA2(val) != 1234) {
+    throw new Error;
+}
+
+if (typemap_qualifier_strip.testA3(val) != 1234) {
+    throw new Error;
+}
+
+if (typemap_qualifier_strip.testA4(val) != 1234) {
+    throw new Error;
+}
+
+
+if (typemap_qualifier_strip.testB1(val) != 111) {
+    throw new Error;
+}
+
+if (typemap_qualifier_strip.testB2(val) != 111) {
+    throw new Error;
+}
+
+if (typemap_qualifier_strip.testB3(val) != 111) {
+    throw new Error;
+}
+
+if (typemap_qualifier_strip.testB4(val) != 111) {
+    throw new Error;
+}
+
+
+if (typemap_qualifier_strip.testC1(val) != 5678) {
+    throw new Error;
+}
+
+if (typemap_qualifier_strip.testC2(val) != 111) {
+    throw new Error;
+}
+
+if (typemap_qualifier_strip.testC3(val) != 5678) {
+    throw new Error;
+}
+
+if (typemap_qualifier_strip.testC4(val) != 111) {
+    throw new Error;
+}
+
+
+if (typemap_qualifier_strip.testD1(val) != 111) {
+    throw new Error;
+}
+
+if (typemap_qualifier_strip.testD2(val) != 3456) {
+    throw new Error;
+}
+
+if (typemap_qualifier_strip.testD3(val) != 111) {
+    throw new Error;
+}
+
+if (typemap_qualifier_strip.testD4(val) != 111) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/typemap_template_typedef_runme.js b/Examples/test-suite/javascript/typemap_template_typedef_runme.js
new file mode 100644
index 0000000..3410e12
--- /dev/null
+++ b/Examples/test-suite/javascript/typemap_template_typedef_runme.js
@@ -0,0 +1,33 @@
+var typemap_template_typedef = require("typemap_template_typedef");
+
+function check(got, expected) {
+    if (got != expected) {
+        throw new Error("got: " + got.toString() + " expected: " + expected.toString());
+    }
+}
+
+x = new typemap_template_typedef.XXXInt();
+
+check(x.aa1(0), 0);
+check(x.aa2(0), 55);
+check(x.aa3(0), 0);
+check(typemap_template_typedef.aa1(0), 0);
+check(typemap_template_typedef.aa2(0), 0);
+
+check(x.bb1(0), 0);
+check(x.bb2(0), 66);
+check(x.bb3(0), 0);
+check(typemap_template_typedef.bb1(0), 0);
+check(typemap_template_typedef.bb2(0), 0);
+
+check(x.cc1(0), 0);
+check(x.cc2(0), 77);
+check(x.cc3(0), 77);
+check(typemap_template_typedef.cc1(0), 0);
+check(typemap_template_typedef.cc2(0), 0);
+
+check(x.dd1(0), 0);
+check(x.dd2(0), 88);
+check(x.dd3(0), 0);
+check(typemap_template_typedef.dd1(0), 0);
+check(typemap_template_typedef.dd2(0), 0)
diff --git a/Examples/test-suite/javascript/typename_runme.js b/Examples/test-suite/javascript/typename_runme.js
new file mode 100644
index 0000000..48434ec
--- /dev/null
+++ b/Examples/test-suite/javascript/typename_runme.js
@@ -0,0 +1,12 @@
+var typename = require("typename");
+f = new typename.Foo();
+b = new typename.Bar();
+
+x = typename.twoFoo(f);
+if (typeof x !== 'number') {
+    throw new Error("Wrong return type (FloatType) !");
+}
+y = typename.twoBar(b);
+if (typeof y !== 'number') {
+    throw new Error("Wrong return type (IntType)!");
+}
diff --git a/Examples/test-suite/javascript/types_directive_runme.js b/Examples/test-suite/javascript/types_directive_runme.js
new file mode 100644
index 0000000..f4f0a2b
--- /dev/null
+++ b/Examples/test-suite/javascript/types_directive_runme.js
@@ -0,0 +1,14 @@
+var types_directive = require("types_directive");
+
+d1 = new types_directive.Time1(2001, 2, 3, 60)
+// check that a Time1 instance is accepted where Date is expected
+newDate = types_directive.add(d1, 7)
+if (newDate.day != 10)
+    throw new Error("newDate mismatch")
+
+d2 = new types_directive.Time2(1999, 8, 7, 60)
+// check that a Time2 instance is accepted where Date is expected
+newDate = types_directive.add(d2, 7)
+if (newDate.day != 14)
+    throw new Error("newDate mismatch")
+
diff --git a/Examples/test-suite/javascript/unicode_strings_runme.js b/Examples/test-suite/javascript/unicode_strings_runme.js
new file mode 100644
index 0000000..cd7f537
--- /dev/null
+++ b/Examples/test-suite/javascript/unicode_strings_runme.js
@@ -0,0 +1,27 @@
+var unicode_strings = require("unicode_strings");
+
+// This uses slightly different encoding than the Python test
+// but AFAIK, it is the V8 handling that is the correct one
+
+function check(s1, s2) {
+    for (let i in s1) {
+        if (s1[i] !== s2[i])
+            console.error(`Character number ${i}, ${s1.charCodeAt(i)} != ${s2.charCodeAt(i)}`);
+    }
+    if (s1 != s2) {
+        throw new Error(`'${s1}' != '${s2}'`);
+    }
+}
+
+// The C++ string contains an invalid UTF-8 character
+// V8 transforms it to \ufffd
+// JSC silently refuses it
+test_string = "h\ufffdllo w\u00f6rld";
+
+if (typeof print === 'undefined') {
+    check(unicode_strings.non_utf8_c_str(), test_string);
+    check(unicode_strings.non_utf8_std_string(), test_string);
+} else {
+    check(unicode_strings.non_utf8_c_str(), '');
+    check(unicode_strings.non_utf8_std_string(), '');
+}
diff --git a/Examples/test-suite/javascript/using_private_runme.js b/Examples/test-suite/javascript/using_private_runme.js
new file mode 100644
index 0000000..ee3ecb3
--- /dev/null
+++ b/Examples/test-suite/javascript/using_private_runme.js
@@ -0,0 +1,16 @@
+var using_private = require("using_private");
+
+f = new using_private.FooBar();
+f.x = 3;
+
+if (f.blah(4) != 4) {
+    throw new Error("blah(int)");
+}
+
+if (f.defaulted() != -1) {
+    throw new Error("defaulted()");
+}
+
+if (f.defaulted(222) != 222) {
+    throw new Error("defaulted(222)");
+}
diff --git a/Examples/test-suite/javascript/using_protected_runme.js b/Examples/test-suite/javascript/using_protected_runme.js
new file mode 100644
index 0000000..990f561
--- /dev/null
+++ b/Examples/test-suite/javascript/using_protected_runme.js
@@ -0,0 +1,8 @@
+var using_protected = require("using_protected");
+
+f = new using_protected.FooBar();
+f.x = 3;
+
+if (f.blah(4) != 4) {
+    throw new Error("blah(int)");
+}
diff --git a/Examples/test-suite/javascript/varargs_overload_runme.js b/Examples/test-suite/javascript/varargs_overload_runme.js
new file mode 100644
index 0000000..337f4ad
--- /dev/null
+++ b/Examples/test-suite/javascript/varargs_overload_runme.js
@@ -0,0 +1,79 @@
+var varargs_overload = require("varargs_overload");
+
+if (varargs_overload.vararg_over1("Hello") != "Hello") {
+    throw new Error("Failed");
+}
+
+if (varargs_overload.vararg_over1(2) != "2") {
+    throw new Error("Failed");
+}
+
+
+if (varargs_overload.vararg_over2("Hello") != "Hello") {
+    throw new Error("Failed");
+}
+
+if (varargs_overload.vararg_over2(2, 2.2) != "2 2.2") {
+    throw new Error("Failed");
+}
+
+
+if (varargs_overload.vararg_over3("Hello") != "Hello") {
+    throw new Error("Failed");
+}
+
+if (varargs_overload.vararg_over3(2, 2.2, "hey") != "2 2.2 hey") {
+    throw new Error("Failed");
+}
+
+if (varargs_overload.vararg_over4("Hello") != "Hello") {
+    throw new Error("Failed");
+}
+
+if (varargs_overload.vararg_over4(123) != "123") {
+    throw new Error("Failed");
+}
+
+if (varargs_overload.vararg_over4("Hello", 123) != "Hello") {
+    throw new Error("Failed");
+}
+
+
+// Same as above but non-vararg function declared first
+
+if (varargs_overload.vararg_over6("Hello") != "Hello") {
+    throw new Error("Failed");
+}
+
+if (varargs_overload.vararg_over6(2) != "2") {
+    throw new Error("Failed");
+}
+
+
+if (varargs_overload.vararg_over7("Hello") != "Hello") {
+    throw new Error("Failed");
+}
+
+if (varargs_overload.vararg_over7(2, 2.2) != "2 2.2") {
+    throw new Error("Failed");
+}
+
+if (varargs_overload.vararg_over8("Hello") != "Hello") {
+    throw new Error("Failed");
+}
+
+if (varargs_overload.vararg_over8(2, 2.2, "hey") != "2 2.2 hey") {
+    throw new Error("Failed");
+}
+
+if (varargs_overload.vararg_over9("Hello") != "Hello") {
+    throw new Error("Failed");
+}
+
+if (varargs_overload.vararg_over9(123) != "123") {
+    throw new Error("Failed");
+}
+
+if (varargs_overload.vararg_over9("Hello", 123) != "Hello") {
+    throw new Error("Failed");
+}
diff --git a/Examples/test-suite/javascript/virtual_derivation_runme.js b/Examples/test-suite/javascript/virtual_derivation_runme.js
new file mode 100644
index 0000000..be87a5d
--- /dev/null
+++ b/Examples/test-suite/javascript/virtual_derivation_runme.js
@@ -0,0 +1,8 @@
+var virtual_derivation = require("virtual_derivation");
+//
+// very innocent example
+//
+b = new virtual_derivation.B(3)
+if (b.get_a() != b.get_b())
+    throw new Error("something is really wrong")
+
diff --git a/Examples/test-suite/javascript/virtual_poly_runme.js b/Examples/test-suite/javascript/virtual_poly_runme.js
new file mode 100644
index 0000000..7cdb039
--- /dev/null
+++ b/Examples/test-suite/javascript/virtual_poly_runme.js
@@ -0,0 +1,44 @@
+var virtual_poly = require("virtual_poly");
+
+d = new virtual_poly.NDouble(3.5);
+i = new virtual_poly.NInt(2);
+
+//
+// the copy methods return the right polymorphic types
+//
+dc = d.copy();
+ic = i.copy();
+
+if (d.get() != dc.get()) {
+    throw new Error;
+}
+
+if (i.get() != ic.get()) {
+    throw new Error;
+}
+
+virtual_poly.incr(ic);
+
+if ((i.get() + 1) != ic.get()) {
+    throw new Error;
+}
+
+
+dr = d.ref_this();
+if (d.get() != dr.get()) {
+    throw new Error;
+}
+
+
+//
+// 'narrowing' also works
+//
+ddc = virtual_poly.NDouble.narrow(d.nnumber());
+if (d.get() != ddc.get()) {
+    throw new Error;
+}
+
+dic = virtual_poly.NInt.narrow(i.nnumber());
+if (i.get() != dic.get()) {
+    throw new Error;
+}
diff --git a/Examples/test-suite/javascript/voidtest_runme.js b/Examples/test-suite/javascript/voidtest_runme.js
new file mode 100644
index 0000000..8ff0c0b
--- /dev/null
+++ b/Examples/test-suite/javascript/voidtest_runme.js
@@ -0,0 +1,28 @@
+var voidtest = require("voidtest");
+
+voidtest.globalfunc();
+var f = new voidtest.Foo();
+f.memberfunc();
+
+voidtest.Foo.staticmemberfunc();
+
+if (f.memberfunc() !== (function(){}())) {
+  throw new Error("f.memberfunc() didn't return same result as pure Javascript equivalent");
+}
+
+v1 = voidtest.vfunc1(f);
+v2 = voidtest.vfunc2(f);
+if (!voidtest.test_pointers_equal(v1, v2)) {
+  throw new Error("!voidtest.test_pointers_equal(v1, v2)");
+}
+
+v3 = voidtest.vfunc3(v1);
+if (!voidtest.test_pointers_equal(v3.get_this(), f.get_this())) {
+  throw new Error("!voidtest.test_pointers_equal(v3.get_this(), f.get_this())");
+}
+v4 = voidtest.vfunc1(f);
+if (!voidtest.test_pointers_equal(v4, v1)) {
+  throw new Error("!voidtest.test_pointers_equal(v4, v1)");
+}
+
+v3.memberfunc();
diff --git a/Examples/test-suite/javascript_lib_arrays.i b/Examples/test-suite/javascript_lib_arrays.i
new file mode 100644
index 0000000..512084a
--- /dev/null
+++ b/Examples/test-suite/javascript_lib_arrays.i
@@ -0,0 +1,30 @@
+%module javascript_lib_arrays
+
+%include <arrays_javascript.i>
+
+%apply int[] { int *data1 }
+%apply int[3] { int data2[3] }
+%apply int[4] { int data3[4] }
+
+%inline %{
+
+int sum1(int *data1, int size) {
+  int sum = 0;
+  for (int i = 0; i < size; i++) {
+    sum += data1[i];
+  }
+  return sum;
+}
+
+int sum2(int data2[3]) {
+  int sum = 0;
+  for (int i = 0; i < 3; i++) {
+    sum += data2[i];
+  }
+  return sum;
+}
+
+int data3[4] = {1, 2, 3, 4};
+
+%}
+
diff --git a/Examples/test-suite/keyword_rename.i b/Examples/test-suite/keyword_rename.i
index 23c0108..8600f78 100644
--- a/Examples/test-suite/keyword_rename.i
+++ b/Examples/test-suite/keyword_rename.i
@@ -27,7 +27,7 @@
 
 /* C# Keywords */
 KW(string, out)
-struct sealed {int i;};
+struct stackalloc {int i;};
 
 /* Go Keywords */
 KW(go, defer)
@@ -37,6 +37,9 @@
 KW(end, function)
 KW(nil,local)
 
+/* Javascript keywords */
+KW(instanceof, finally)
+KW(finally, instanceof)
 %}
 
 
diff --git a/Examples/test-suite/kwargs_feature.i b/Examples/test-suite/kwargs_feature.i
index a8d1c38..5b94181 100644
--- a/Examples/test-suite/kwargs_feature.i
+++ b/Examples/test-suite/kwargs_feature.i
@@ -27,6 +27,7 @@
 
     virtual int foo(int a = 1, int b = 0) {return a + b; }
     static int statfoo(int a = 1, int b = 0) {return a + b; }
+    static int statfoo_onearg(int x = 10) {return x + x; }
 
     static Foo *create(int a = 1, int b = 0) 
     {
@@ -100,3 +101,52 @@
 
   int foo_mm(int min = 1, int max = 2) {return min + max; }
 %}
+
+
+// Extended constructors
+%extend Extending0 {
+  Extending0() { return new Extending0(); }
+}
+%extend Extending1 {
+  Extending1(int one) { return new Extending1(); }
+}
+%extend Extending2 {
+  Extending2(int one, const char *two) { return new Extending2(); }
+}
+%extend ExtendingOptArgs1 {
+  ExtendingOptArgs1(int one = 0) { return new ExtendingOptArgs1(); }
+}
+%extend ExtendingOptArgs2 {
+  ExtendingOptArgs2(int one = 0, const char* two = NULL) { return new ExtendingOptArgs2(); }
+}
+
+%inline %{
+struct Extending0 {};
+struct Extending1 {};
+struct Extending2 {};
+struct ExtendingOptArgs1 {};
+struct ExtendingOptArgs2 {};
+%}
+
+// For strlen/strcpy
+%{
+#include <string.h>
+%}
+
+// Varargs
+%warnfilter(SWIGWARN_LANG_VARARGS_KEYWORD) VarargConstructor::VarargConstructor; // Can't wrap varargs with keyword arguments enabled
+%warnfilter(SWIGWARN_LANG_VARARGS_KEYWORD) VarargConstructor::vararg_method; // Can't wrap varargs with keyword arguments enabled
+%inline %{
+struct VarargConstructor {
+  char *str;
+  VarargConstructor(const char *fmt, ...) {
+    str = new char[strlen(fmt) + 1];
+    strcpy(str, fmt);
+  }
+  void vararg_method(const char *fmt, ...) {
+    delete [] str;
+    str = new char[strlen(fmt) + 1];
+    strcpy(str, fmt);
+  }
+};
+%}
diff --git a/Examples/test-suite/li_attribute.i b/Examples/test-suite/li_attribute.i
index 4f9497a..95389b2 100644
--- a/Examples/test-suite/li_attribute.i
+++ b/Examples/test-suite/li_attribute.i
@@ -95,6 +95,7 @@
 
 // class/struct attribute with get/set methods using return/pass by reference
 %attribute2(MyClass, MyFoo, Foo, GetFoo, SetFoo);
+%attribute2ref(MyClass, MyFoo, Foo2);
 %inline %{
   struct MyFoo { 
     MyFoo() : x(-1) {}
@@ -102,9 +103,11 @@
   };
   class MyClass {
     MyFoo foo;
+    MyFoo foo2;
   public:
     MyFoo& GetFoo() { return foo; }
     void SetFoo(const MyFoo& other) { foo = other; }
+    MyFoo& Foo2() { return foo2; }
   };
 %} 
 
diff --git a/Examples/test-suite/li_boost_intrusive_ptr.i b/Examples/test-suite/li_boost_intrusive_ptr.i
index c3b2112..1393743 100644
--- a/Examples/test-suite/li_boost_intrusive_ptr.i
+++ b/Examples/test-suite/li_boost_intrusive_ptr.i
@@ -5,7 +5,7 @@
 // like 'top'. There is a wrapper for intrusive_ptr in intrusive_ptr_wrapper.h which enables one to
 // count the instances of intrusive_ptr. Uncomment the INTRUSIVE_PTR_WRAPPER macro to turn this on.
 //
-// Also note the debug_shared flag  which can be set from the target language.
+// Also note the debug_shared flag which can be set from the target language.
 //
 // Usage of intrusive_ptr_add_ref and intrusive_ptr_release based on boost testing:
 // http://www.boost.org/doc/libs/1_36_0/libs/smart_ptr/test/intrusive_ptr_test.cpp
diff --git a/Examples/test-suite/li_boost_shared_ptr.i b/Examples/test-suite/li_boost_shared_ptr.i
index b64197b..6780039 100644
--- a/Examples/test-suite/li_boost_shared_ptr.i
+++ b/Examples/test-suite/li_boost_shared_ptr.i
@@ -5,7 +5,7 @@
 // like 'top'. There is a wrapper for shared_ptr in shared_ptr_wrapper.h which enables one to
 // count the instances of shared_ptr. Uncomment the SHARED_PTR_WRAPPER macro to turn this on.
 //
-// Also note the debug_shared flag  which can be set from the target language.
+// Also note the debug_shared flag which can be set from the target language.
 
 %module li_boost_shared_ptr
 
@@ -44,7 +44,7 @@
 # define SWIG_SHARED_PTR_NAMESPACE SwigBoost
 #endif
 
-#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGD) || defined(SWIGOCTAVE) || defined(SWIGRUBY)
+#if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGPYTHON) || defined(SWIGD) || defined(SWIGOCTAVE) || defined(SWIGRUBY) || defined(SWIGR)
 #define SHARED_PTR_WRAPPERS_IMPLEMENTED
 #endif
 
@@ -242,6 +242,10 @@
   else
     return "also not null";
 }
+
+SwigBoost::shared_ptr<Klass>* sp_pointer_null() { return NULL; }
+SwigBoost::shared_ptr<Klass>* null_sp_pointer() { static SwigBoost::shared_ptr<Klass> static_sp; return &static_sp; }
+SwigBoost::shared_ptr<Klass> sp_value_null() { return SwigBoost::shared_ptr<Klass>(); }
 // $owner
 Klass *pointerownertest() {
   return new Klass("pointerownertest");
@@ -264,6 +268,7 @@
 long use_count(const SwigBoost::shared_ptr<Klass>& sptr) {
   return sptr.use_count();
 }
+
 const SwigBoost::shared_ptr<Klass>& ref_1() {
   static SwigBoost::shared_ptr<Klass> sptr;
   return sptr;
diff --git a/Examples/test-suite/li_cdata.i b/Examples/test-suite/li_cdata.i
index 2180af9..4e1a01e 100644
--- a/Examples/test-suite/li_cdata.i
+++ b/Examples/test-suite/li_cdata.i
@@ -5,4 +5,8 @@
 %cdata(int);
 %cdata(double);
 
+%{
+#include <stdlib.h>
+%}
+
 void *malloc(size_t size);
diff --git a/Examples/test-suite/li_cdata_cpp.i b/Examples/test-suite/li_cdata_cpp.i
index 2d7d300..80ff293 100644
--- a/Examples/test-suite/li_cdata_cpp.i
+++ b/Examples/test-suite/li_cdata_cpp.i
@@ -5,4 +5,8 @@
 %cdata(int);
 %cdata(double);
 
+%{
+#include <stdlib.h>
+%}
+
 void *malloc(size_t size);
diff --git a/Examples/test-suite/li_constraints.i b/Examples/test-suite/li_constraints.i
index 1bbecf1..675d334 100644
--- a/Examples/test-suite/li_constraints.i
+++ b/Examples/test-suite/li_constraints.i
@@ -11,7 +11,7 @@
 void test_positive(double POSITIVE) {
 }
 
-void test_negative(double POSITIVE) {
+void test_negative(double NEGATIVE) {
 }
 
 void test_nonzero(double NONZERO) {
@@ -20,6 +20,12 @@
 void test_nonnull(void *NONNULL) {
 }
 
+/* Provide a non null void pointer for test_nonnull */
+void* get_nonnull() {
+    static int i;
+    return &i;
+}
+
 /* These generated non-portable code and there isn't an obvious fix
 
 void test_align8(void *ALIGN8) {
diff --git a/Examples/test-suite/li_factory.i b/Examples/test-suite/li_factory.i
index 7c59d53..0de3791 100644
--- a/Examples/test-suite/li_factory.i
+++ b/Examples/test-suite/li_factory.i
@@ -16,34 +16,33 @@
   struct Geometry {
     enum GeomType{
       POINT,
-      CIRCLE
+      CIRCLE,
+      SHAPELESS
     };
-    
-    virtual ~Geometry() {}    
+
+    virtual ~Geometry() {}
     virtual int draw() = 0;
     static Geometry *create(GeomType i);
-		virtual Geometry *clone() = 0;
+    virtual Geometry *clone() = 0;
   };
 
   struct Point : Geometry  {
     int draw() { return 1; }
-    double width() { return 1.0; }    
-		Geometry *clone() { return new Point(); }
+    double width() { return 1.0; }
+    Geometry *clone() { return new Point(); }
   };
 
   struct Circle : Geometry  {
     int draw() { return 2; }
-    double radius() { return 1.5; }      
-		Geometry *clone() { return new Circle(); }
-  }; 
+    double radius() { return 1.5; }
+    Geometry *clone() { return new Circle(); }
+  };
 
   Geometry *Geometry::create(GeomType type) {
     switch (type) {
     case POINT: return new Point();
-    case CIRCLE: return new Circle(); 
+    case CIRCLE: return new Circle();
     default: return 0;
     }
   }
 }
-
-
diff --git a/Examples/test-suite/li_math.i b/Examples/test-suite/li_math.i
index 3aa3db3..db39cd3 100644
--- a/Examples/test-suite/li_math.i
+++ b/Examples/test-suite/li_math.i
@@ -1,7 +1,2 @@
 %module li_math
-#ifdef SWIGPHP
-// PHP already provides these functions with the same names, so just kill that
-// warning.
-%warnfilter(SWIGWARN_PARSE_KEYWORD);
-#endif
 %include math.i
diff --git a/Examples/test-suite/li_std_auto_ptr.i b/Examples/test-suite/li_std_auto_ptr.i
index 5bde387..18df513 100644
--- a/Examples/test-suite/li_std_auto_ptr.i
+++ b/Examples/test-suite/li_std_auto_ptr.i
@@ -12,30 +12,51 @@
 #endif
 %}
 
-#if defined(SWIGCSHARP) || defined(SWIGJAVA) || defined(SWIGPYTHON)
+#if !(defined(SWIGGO) || defined(SWIGOCAML) || defined(SWIGR) || defined(SWIGSCILAB))
 
+%warnfilter(509, 516) overloadTest(Klass);
+
+%include "std_string.i"
+//#include <iostream>
 %include "std_auto_ptr.i"
 
 %auto_ptr(Klass)
 
+%inline %{
+void show_cplusplus_version() {
+  printf("__cplusplus %d\n", (int)__cplusplus);
+}
+%}
+
 %{
 #if __cplusplus < 201703L
 #include <memory>
 #else
+
+// If <memory> has already been include (Octave does) then unfortunately gcc incorrectly still provides
+// std::auto_ptr when _GLIBCXX_USE_DEPRECATED is defined by the compiler configuration/OS/who knows what!!
+#include <memory> // Now need to include it in case _GLIBCXX_USE_DEPRECATED is defined and <memory> has not been included, argh
+#if !defined(_GLIBCXX_USE_DEPRECATED)
 // Simple std::auto_ptr implementation for testing after its removal in C++17
 namespace std {
   template <class T> class auto_ptr {
     T *ptr;
     public:
-      auto_ptr(T *ptr = 0) : ptr(ptr) {}
+      explicit auto_ptr(T *p = 0) : ptr(p) {}
       auto_ptr(auto_ptr&& a) : ptr(a.ptr) { a.ptr = 0;}
       ~auto_ptr() { delete ptr; }
       T *release() { T *p = ptr; ptr = 0; return p; }
+      T* get() const { return ptr; }
+      void reset(T *p = 0) { delete ptr; ptr = p; }
+      T &operator*() const { return *ptr; }
+      T *operator->() const { return ptr; }
       auto_ptr& operator=(auto_ptr&& a) { if (&a != this) { delete ptr; ptr = a.ptr; a.ptr = 0; } return *this; }
   };
 }
 #endif
 
+#endif
+
 #include <string>
 #include "swig_examples_lock.h"
 %}
@@ -53,7 +74,7 @@
 
   const char* getLabel() const { return m_label.c_str(); }
 
-  ~Klass()
+  virtual ~Klass()
   {
     SwigExamples::Lock lock(critical_section);
     total_count--;
@@ -73,14 +94,62 @@
 
 %}
 
-%template(KlassAutoPtr) std::auto_ptr<Klass>;
-
 %inline %{
 
+// Virtual inheritance used as this usually results in different values for Klass* and KlassInheritance*
+// for testing class inheritance and auto_ptr
+struct KlassInheritance : virtual Klass {
+  KlassInheritance(const char* label) : Klass(label) {
+    // std::cout << "ptrs.... " << std::hex << (Klass*)this << " " << (KlassInheritance*)this << std::endl;
+  }
+};
+
+std::string useKlassRawPtr(Klass* k) {
+//  std::cout << "useKlassRawPtr " << std::hex << (Klass*)k << std::endl;
+  std::string s(k->getLabel());
+//  std::cout << "useKlassRawPtr string: " << s << std::endl;
+  return s;
+}
+
+std::string takeKlassAutoPtr(std::auto_ptr<Klass> k) {
+//  std::cout << "takeKlassAutoPtr " << std::hex << (Klass*)k.get() << std::endl;
+  std::string s(k.get() ? k->getLabel() : "null smart pointer");
+//  std::cout << "takeKlassAutoPtr string: " << s << std::endl;
+  return s;
+}
+
+Klass *make_null() {
+  return 0;
+}
+
+bool is_nullptr(Klass *p) {
+  return p == 0;
+}
+
+Klass *get_not_owned_ptr(Klass *p) {
+  return p;
+}
+
 std::auto_ptr<Klass> makeKlassAutoPtr(const char* label) {
   return std::auto_ptr<Klass>(new Klass(label));
 }
 
+std::auto_ptr<Klass> makeNullAutoPtr() {
+  return std::auto_ptr<Klass>();
+}
+
+int overloadTest() {
+  return 0;
+}
+
+int overloadTest(std::auto_ptr<Klass> kover) {
+  return 1;
+}
+
+int overloadTest(Klass k) {
+  return 2;
+}
+
 %}
 
 #endif
diff --git a/Examples/test-suite/li_std_carray.i b/Examples/test-suite/li_std_carray.i
deleted file mode 100644
index b38e0e4..0000000
--- a/Examples/test-suite/li_std_carray.i
+++ /dev/null
@@ -1,8 +0,0 @@
-%module li_std_carray
-
-%include <std_carray.i>
-
-%template(Vector3) std::carray<double, 3>;
-
-%template(Matrix3) std::carray<std::carray<double, 3>, 3>;
-
diff --git a/Examples/test-suite/li_std_containers_int.i b/Examples/test-suite/li_std_containers_int.i
index d0c76d9..14dbd1e 100644
--- a/Examples/test-suite/li_std_containers_int.i
+++ b/Examples/test-suite/li_std_containers_int.i
@@ -5,8 +5,14 @@
 //
 
 %include std_vector.i
+
+#ifndef SWIGJAVASCRIPT
 %include std_list.i
+#endif
+
 
 %template(vector_int) std::vector<int>;
-%template(list_int) std::list<int>;
 
+#ifndef SWIGJAVASCRIPT
+%template(list_int) std::list<int>;
+#endif
diff --git a/Examples/test-suite/li_std_except.i b/Examples/test-suite/li_std_except.i
index 60bce99..9bf70cd 100644
--- a/Examples/test-suite/li_std_except.i
+++ b/Examples/test-suite/li_std_except.i
@@ -9,6 +9,8 @@
 %}
 
 %inline %{
+  #include <stdexcept>
+  #include <typeinfo>
   struct E1 : public std::exception
   {
   };
diff --git a/Examples/test-suite/li_std_string.i b/Examples/test-suite/li_std_string.i
index 47a9090..6f8fec1 100644
--- a/Examples/test-suite/li_std_string.i
+++ b/Examples/test-suite/li_std_string.i
@@ -1,9 +1,10 @@
 %module li_std_string
 %include <std_string.i>
 
-#if defined(SWIGUTL)
+#if defined(SWIGLUA) || defined(SWIGPHP) || defined(SWIGUTL)
 %apply std::string& INPUT { std::string &input }
 %apply std::string& INOUT { std::string &inout }
+%apply std::string& OUTPUT { std::string &output }
 #endif
 
 // throw is invalid in C++17 and later, only SWIG to use it
@@ -53,13 +54,28 @@
 }
 
 std::string test_reference_input(std::string &input) {
-  return input;
+  // For PHP to allow checking that we haven't used the default string&
+  // typemap which wraps as a PHP pass-by-reference string parameter.
+  std::string copy = input;
+  input = "MODIFIED";
+  return copy;
 }
 
 void test_reference_inout(std::string &inout) {
   inout += inout;
 }
 
+void test_reference_output(std::string &output) {
+  output = "output";
+}
+
+#ifdef SWIGPHP
+// Test PHP-specific default wrapping string& as pass-by-ref PHP string.
+void test_reference_php(std::string &s) {
+  s += ".php";
+}
+#endif
+
 void test_throw() TESTCASE_THROW1(std::string){
   static std::string x = "test_throw message";
   throw x;
diff --git a/Examples/test-suite/li_std_vector.i b/Examples/test-suite/li_std_vector.i
index 33fb797..a76604b 100644
--- a/Examples/test-suite/li_std_vector.i
+++ b/Examples/test-suite/li_std_vector.i
@@ -140,3 +140,27 @@
     return(result);
   }
 %}
+
+// regression test for Tcl typecheck bug with empty list fixed in 4.1.0
+%inline %{
+int sum(const std::vector<int> &v) {
+  return std::accumulate(v.begin(),v.end(),0);
+}
+int sum(int v) {
+  return v;
+}
+%}
+
+// Variables
+%inline %{
+struct VariableHolder {
+  static std::vector<int> static_variable;
+  std::vector<int> instance_variable;
+};
+std::vector<int> VariableHolder::static_variable;
+std::vector<int> global_variable;
+
+void vector_append(std::vector<int>& vec, int val) {
+  vec.push_back(val);
+}
+%}
diff --git a/Examples/test-suite/li_std_vector_vector.i b/Examples/test-suite/li_std_vector_vector.i
new file mode 100644
index 0000000..8dbc10e
--- /dev/null
+++ b/Examples/test-suite/li_std_vector_vector.i
@@ -0,0 +1,68 @@
+%module li_std_vector_vector
+
+%include <std_string.i>
+%include <std_vector.i>
+
+namespace std {
+  %template(VectorInt)   vector<int>;
+  %template(VectorString)   vector<string>;
+  %template(VectorVectorInt)   vector<vector<int>>;
+  %template(VectorVectorString)   vector<vector<string>>;
+};
+
+%inline %{
+std::vector<int> make_vector_int() {
+    int x[5] = {1, 2, 3, 4, 5};
+    std::vector<int> v;
+    for (size_t i = 0; i < 5; ++i)
+      v.push_back(x[i]);
+    return v;
+}
+
+std::vector<std::vector<int> > make_vector_vector_int() {
+    int x[5] = {1, 2, 3, 4, 5};
+    std::vector<std::vector<int> > vv;
+    std::vector<int> v;
+    for (size_t i = 0; i < 5; ++i)
+      v.push_back(x[i]);
+    vv.push_back(v);
+    return vv;
+}
+
+std::vector<bool> make_vector_bool() {
+    bool x[5] = {true, false, false, false, true};
+    std::vector<bool> v;
+    for (size_t i = 0; i < 5; ++i)
+      v.push_back(x[i]);
+    return v;
+}
+
+std::vector<std::vector<bool> > make_vector_vector_bool() {
+    bool x[5] = {false, true, true, true, false};
+    std::vector<std::vector<bool> > vv;
+    std::vector<bool> v;
+    for (size_t i = 0; i < 5; ++i)
+      v.push_back(x[i]);
+    vv.push_back(v);
+    return vv;
+}
+
+std::vector<std::string> make_vector_string() {
+    std::string x[5] = {"aa", "bb", "cc", "dd", "ee"};
+    std::vector<std::string> v;
+    for (size_t i = 0; i < 5; ++i)
+      v.push_back(x[i]);
+    return v;
+}
+
+std::vector<std::vector<std::string> > make_vector_vector_string() {
+    std::string x[5] = {"1", "2", "3", "4", "5"};
+    std::vector<std::vector<std::string> > vv;
+    std::vector<std::string> v;
+    for (size_t i = 0; i < 5; ++i)
+      v.push_back(x[i]);
+    vv.push_back(v);
+    return vv;
+}
+
+%}
diff --git a/Examples/test-suite/li_std_wstring.h b/Examples/test-suite/li_std_wstring.h
new file mode 100644
index 0000000..a16b7cd
--- /dev/null
+++ b/Examples/test-suite/li_std_wstring.h
@@ -0,0 +1,5 @@
+// This file has a BOM set to UTF-8, which is one way for Visual C++ to correctly interpet these strings
+// Alternatively, the /utf-8 command line option could be used
+#define JP_WSTRING L"JP: 日本語"
+#define DE_WSTRING L"DE: Kröpeliner Straße"
+#define RU_WSTRING L"RU: Война и мир"
\ No newline at end of file
diff --git a/Examples/test-suite/li_std_wstring.i b/Examples/test-suite/li_std_wstring.i
index 55d4538..88f80be 100644
--- a/Examples/test-suite/li_std_wstring.i
+++ b/Examples/test-suite/li_std_wstring.i
@@ -3,44 +3,71 @@
 // The languages below are yet to provide std_wstring.i
 #if !(defined(SWIGD) || defined(SWIGGO) || defined(SWIGGUILE) || defined(SWIGJAVASCRIPT) || defined(SWIGLUA) || defined(SWIGMZSCHEME) || defined(SWIGOCAML) || defined(SWIGOCTAVE) || defined(SWIGPERL) || defined(SWIGPHP) || defined(SWIGR) || defined(SWIGSCILAB))
 
+%warnfilter(SWIGWARN_TYPEMAP_WCHARLEAK_MSG) wchar_t_const_ptr_member;  // Setting a const wchar_t * variable may leak memory.
+
 %include <std_wstring.i>
 
+
 // throw is invalid in C++17 and later, only SWIG to use it
 #define TESTCASE_THROW1(T1) throw(T1)
 %{
 #define TESTCASE_THROW1(T1)
 %}
 
+%{
+// Unicode strings are stored in li_std_wstring.h file which has the BOM appropriately set, primarily for Visual C++ to correctly interpret the wide strings
+#include "li_std_wstring.h"
+%}
+
 %inline %{
 #include <string>
+#include <iostream>
+
+bool trace = false;
+
+void show_wstring_bytes(const std::wstring &s) {
+  unsigned char *p = (unsigned char *)s.data();
+  size_t len = s.size()*sizeof(wchar_t);
+  std::wcout << L"s: " << /*s <<*/ L"[";
+  for (size_t i = 0; i<len; i++) {
+    std::wcout << std::hex << *p << L" ";
+    p++;
+  }
+  std::wcout << L"]" << std::endl;
+  std::wcout << std::flush;
+}
 
 wchar_t test_wcvalue(wchar_t x) {
-   return x;
+  return x;
 }
 
 const wchar_t* test_ccvalue(const wchar_t* x) {
-   return x;
+  return x;
 }
 
 wchar_t* test_cvalue(wchar_t* x) {
-   return x;
+  return x;
 }
   
 
 wchar_t* test_wchar_overload() {
-   return 0;
+  return 0;
 }
 
 wchar_t* test_wchar_overload(wchar_t *x) {
-   return x;
+  return x;
 }
 
 std::wstring test_value(std::wstring x) {
-   return x;
+  if (trace) {
+    std::wcout << "received(C++): " /*<< x */<< std::endl;
+    show_wstring_bytes(x);
+  }
+  return x;
 }
 
 const std::wstring& test_const_reference(const std::wstring &x) {
-   return x;
+  return x;
 }
 
 void test_pointer(std::wstring *x) {
@@ -52,13 +79,47 @@
 void test_reference(std::wstring &x) {
 }
 
-bool test_equal_abc(const std::wstring &s) {
-  return L"abc" == s;
+bool test_equal(const wchar_t *wcs, const std::wstring& s) {
+  if (trace) {
+    show_wstring_bytes(wcs);
+    show_wstring_bytes(s);
+  }
+  return wcs == s;
 }
 
-void test_throw() TESTCASE_THROW1(std::wstring){
+bool test_equal_abc(const std::wstring &s) {
+  return test_equal(L"abc", s);
+}
+
+bool test_equal_jp(const std::wstring &s) {
+  return test_equal(JP_WSTRING, s);
+}
+
+bool test_equal_de(const std::wstring &s) {
+  return test_equal(DE_WSTRING, s);
+}
+
+bool test_equal_ru(const std::wstring &s) {
+  return test_equal(RU_WSTRING, s);
+}
+
+void test_throw() TESTCASE_THROW1(std::wstring) {
   static std::wstring x = L"throwing test_throw";
-  
+  throw x;
+}
+
+void test_throw_wchar_t_ptr() TESTCASE_THROW1(std::wstring) {
+  static std::wstring x = JP_WSTRING;
+  throw x;
+}
+
+void test_throw_jp() TESTCASE_THROW1(std::wstring) {
+  static std::wstring x = JP_WSTRING;
+  throw x;
+}
+
+void test_throw_ref_jp() TESTCASE_THROW1(const std::wstring&) {
+  static std::wstring x = JP_WSTRING;
   throw x;
 }
 
@@ -70,6 +131,13 @@
   return s.size();
 }
 
+struct wchar_test_struct {
+  wchar_t wchar_t_member;
+  wchar_t* wchar_t_ptr_member;
+  const wchar_t* wchar_t_const_ptr_member;
+  wchar_test_struct() : wchar_t_member(), wchar_t_ptr_member(), wchar_t_const_ptr_member() {}
+};
+
 %}
 
 #endif
diff --git a/Examples/test-suite/li_typemaps.i b/Examples/test-suite/li_typemaps.i
index a53c1c7..d508c1c 100644
--- a/Examples/test-suite/li_typemaps.i
+++ b/Examples/test-suite/li_typemaps.i
@@ -2,6 +2,7 @@
 
 %include "typemaps.i"
 
+%apply int *OUTPUT { int *OUTPUT2 };
 %apply int &INOUT { int &INOUT2 };
 %newobject out_foo;
 %inline %{
@@ -51,10 +52,13 @@
 void out_ulonglong(unsigned long long x, unsigned long long *OUTPUT) {  *OUTPUT = x; }
 
 /* Tests a returning a wrapped pointer and an output argument */
-struct Foo *out_foo(int a, int *OUTPUT) {
+struct Foo *out_foo(int a, int *OUTPUT, int *OUTPUT2) {
   struct Foo *f = new struct Foo();
   f->a = a;
   *OUTPUT = a * 2;
+  struct Foo *f2 = new struct Foo();
+  f2->a = a;
+  *OUTPUT2 = a * 3;
   return f;
 }
 
diff --git a/Examples/test-suite/lua/Makefile.in b/Examples/test-suite/lua/Makefile.in
index 63b8692..af67351 100644
--- a/Examples/test-suite/lua/Makefile.in
+++ b/Examples/test-suite/lua/Makefile.in
@@ -6,6 +6,10 @@
 LUA          = @LUABIN@
 SCRIPTSUFFIX = _runme.lua
 
+HAVE_CXX11   = @HAVE_CXX11@
+HAVE_CXX14   = @HAVE_CXX14@
+HAVE_CXX17   = @HAVE_CXX17@
+HAVE_CXX20   = @HAVE_CXX20@
 srcdir       = @srcdir@
 top_srcdir   = @top_srcdir@
 top_builddir = @top_builddir@
@@ -15,6 +19,7 @@
 CPP_TEST_CASES += \
 	lua_no_module_global \
 	lua_inherit_getitem  \
+	lua_lightuserdata  \
 
 
 C_TEST_CASES += \
@@ -52,7 +57,7 @@
 	  env LUA_PATH="$(srcdir)/?.lua;" $(RUNTOOL) $(LUA) $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \
 	fi
 
-# Clean: (does nothing, we dont generate extra lua code)
+# Clean: (does nothing, we don't generate extra lua code)
 %.clean:
 	@exit 0
 
diff --git a/Examples/test-suite/lua/argcargvtest_runme.lua b/Examples/test-suite/lua/argcargvtest_runme.lua
new file mode 100644
index 0000000..eea5222
--- /dev/null
+++ b/Examples/test-suite/lua/argcargvtest_runme.lua
@@ -0,0 +1,38 @@
+require("import")	-- the import fn
+import("argcargvtest")	-- import lib
+v = argcargvtest
+
+-- catch "undefined" global variables
+local env = _ENV -- Lua 5.2
+if not env then env = getfenv () end -- Lua 5.1
+setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
+
+largs = {"hi", "hola", "hello"}
+assert(v.mainc(largs) == 3, "bad main typemap")
+
+targs = {"hi", "hola"}
+assert(v.mainv(targs, 0) == "hi", "bad main typemap")
+assert(v.mainv(targs, 1) == "hola", "bad main typemap")
+assert(v.mainv(targs, 2) == "<<NULL>>", "bad main typemap")
+
+errorVal = 0
+function try()
+    mainv("hello", 1)
+    errorVal = 1
+end
+assert(not pcall(try) and errorVal == 0, "bad main typemap")
+
+v.initializeApp(largs)
+
+-- Check that an empty array works.
+empty_args = {}
+assert(v.mainc(empty_args) == 0, "bad main typemap")
+assert(v.mainv(empty_args, 0) == "<<NULL>>", "bad main typemap")
+
+-- Check that empty strings are handled.
+empty_string = {"hello", "", "world"}
+assert(v.mainc(empty_string) == 3, "bad main typemap")
+assert(v.mainv(empty_string, 0) == "hello", "bad main typemap")
+assert(v.mainv(empty_string, 1) == "", "bad main typemap")
+assert(v.mainv(empty_string, 2) == "world", "bad main typemap")
+assert(v.mainv(empty_string, 3) == "<<NULL>>", "bad main typemap")
diff --git a/Examples/test-suite/lua/catches_strings_runme.lua b/Examples/test-suite/lua/catches_strings_runme.lua
new file mode 100644
index 0000000..b0dbaee
--- /dev/null
+++ b/Examples/test-suite/lua/catches_strings_runme.lua
@@ -0,0 +1,13 @@
+require("import")	-- the import fn
+import("catches_strings")	-- import code
+
+-- catch "undefined" global variables
+local env = _ENV -- Lua 5.2
+if not env then env = getfenv () end -- Lua 5.1
+setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
+
+s, msg = pcall(function() catches_strings.StringsThrower.charstring() end)
+assert(s == false and msg:find("charstring message", 1, true))
+
+s, msg = pcall(function() catches_strings.StringsThrower.stdstring() end)
+assert(s == false and msg:find("stdstring message", 1, true))
diff --git a/Examples/test-suite/lua/cpp11_move_typemaps_runme.lua b/Examples/test-suite/lua/cpp11_move_typemaps_runme.lua
new file mode 100644
index 0000000..d8947b7
--- /dev/null
+++ b/Examples/test-suite/lua/cpp11_move_typemaps_runme.lua
@@ -0,0 +1,28 @@
+require("import")	-- the import fn
+import("cpp11_move_typemaps")	-- import code
+
+-- catch "undefined" global variables
+local env = _ENV -- Lua 5.2
+if not env then env = getfenv () end -- Lua 5.1
+setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
+
+cpp11_move_typemaps.Counter.reset_counts()
+mo = cpp11_move_typemaps.MoveOnly(111)
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 0, 0, 0)
+cpp11_move_typemaps.MoveOnly.take(mo)
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2)
+mo = nil
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+cpp11_move_typemaps.Counter.reset_counts()
+mo = cpp11_move_typemaps.MovableCopyable(111)
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 0, 0, 0)
+cpp11_move_typemaps.MovableCopyable.take(mo)
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2)
+mo = nil
+cpp11_move_typemaps.Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+mo = cpp11_move_typemaps.MoveOnly(222)
+cpp11_move_typemaps.MoveOnly.take(mo)
+s, msg = pcall(function() cpp11_move_typemaps.MoveOnly.take(mo) end)
+assert(s == false and msg:find("Cannot release ownership as memory is not owned", 1, true))
diff --git a/Examples/test-suite/lua/cpp11_rvalue_reference_move_runme.lua b/Examples/test-suite/lua/cpp11_rvalue_reference_move_runme.lua
new file mode 100644
index 0000000..773760c
--- /dev/null
+++ b/Examples/test-suite/lua/cpp11_rvalue_reference_move_runme.lua
@@ -0,0 +1,66 @@
+require("import")	-- the import fn
+import("cpp11_rvalue_reference_move")	-- import code
+
+-- catch "undefined" global variables
+local env = _ENV -- Lua 5.2
+if not env then env = getfenv () end -- Lua 5.1
+setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
+
+-- Function containing rvalue reference parameter
+cpp11_rvalue_reference_move.Counter.reset_counts()
+mo = cpp11_rvalue_reference_move.MovableCopyable(222)
+cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 0, 0, 0)
+cpp11_rvalue_reference_move.MovableCopyable.movein(mo)
+cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 2)
+if not (cpp11_rvalue_reference_move.MovableCopyable_is_nullptr(mo)) then
+  error("is_nullptr failed")
+end
+mo = nil
+cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+-- Move constructor test
+cpp11_rvalue_reference_move.Counter.reset_counts()
+mo = cpp11_rvalue_reference_move.MovableCopyable(222)
+cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 0, 0, 0)
+mo_moved = cpp11_rvalue_reference_move.MovableCopyable(mo)
+cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 1)
+if not (cpp11_rvalue_reference_move.MovableCopyable_is_nullptr(mo)) then
+  error("is_nullptr failed")
+end
+mo = nil
+cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 1)
+mo_moved = nil
+collectgarbage() -- gc nudge needed here
+cpp11_rvalue_reference_move.Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+-- Move assignment operator test
+cpp11_rvalue_reference_move.Counter.reset_counts()
+mo111 = cpp11_rvalue_reference_move.MovableCopyable(111)
+mo222 = cpp11_rvalue_reference_move.MovableCopyable(222)
+cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 0, 0)
+mo111:MoveAssign(mo222)
+cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1)
+if not (cpp11_rvalue_reference_move.MovableCopyable_is_nullptr(mo222)) then
+  error("is_nullptr failed")
+end
+mo222 = nil
+cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1)
+mo111 = nil
+collectgarbage() -- gc nudge needed here
+cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 2)
+
+-- null check
+cpp11_rvalue_reference_move.Counter.reset_counts()
+s, msg = pcall(function() cpp11_rvalue_reference_move.MovableCopyable.movein(nil) end)
+assert(s == false and msg:find("Error in MovableCopyable::movein (arg 1), expected 'MovableCopyable &&' got 'nil'", 1, true))
+cpp11_rvalue_reference_move.Counter.check_counts(0, 0, 0, 0, 0, 0)
+
+-- output
+cpp11_rvalue_reference_move.Counter.reset_counts()
+mc = cpp11_rvalue_reference_move.MovableCopyable.moveout(1234)
+cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1)
+cpp11_rvalue_reference_move.MovableCopyable.check_numbers_match(mc, 1234)
+
+s, msg = pcall(function() cpp11_rvalue_reference_move.MovableCopyable.movein(mc) end)
+assert(s == false and msg:find("Cannot release ownership as memory is not owned", 1, true))
+cpp11_rvalue_reference_move.Counter.check_counts(2, 0, 0, 0, 1, 1)
diff --git a/Examples/test-suite/lua/cpp11_std_unique_ptr_runme.lua b/Examples/test-suite/lua/cpp11_std_unique_ptr_runme.lua
new file mode 100644
index 0000000..88d453e
--- /dev/null
+++ b/Examples/test-suite/lua/cpp11_std_unique_ptr_runme.lua
@@ -0,0 +1,112 @@
+require("import")	-- the import fn
+import("cpp11_std_unique_ptr")	-- import code
+
+-- catch "undefined" global variables
+local env = _ENV -- Lua 5.2
+if not env then env = getfenv () end -- Lua 5.1
+setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
+
+
+function checkCount(expected_count)
+  -- call gc to make unused objects are collected
+  collectgarbage()
+  actual_count = cpp11_std_unique_ptr.Klass.getTotal_count()
+  if not (actual_count == expected_count) then
+    error("Counts incorrect, expected:"..expected_count.." actual:"..actual_count)
+  end
+end
+
+--Test raw pointer handling involving virtual inheritance
+kini = cpp11_std_unique_ptr.KlassInheritance("KlassInheritanceInput")
+checkCount(1)
+s = cpp11_std_unique_ptr.useKlassRawPtr(kini)
+if not (s == "KlassInheritanceInput") then
+  error("Incorrect string: "..s)
+end
+kini = nil
+checkCount(0)
+
+-- unique_ptr as input
+kin = cpp11_std_unique_ptr.Klass("KlassInput")
+checkCount(1)
+s = cpp11_std_unique_ptr.takeKlassUniquePtr(kin)
+checkCount(0)
+if not (s == "KlassInput") then
+  error("Incorrect string: "..s)
+end
+if not (cpp11_std_unique_ptr.is_nullptr(kin)) then
+  error("is_nullptr failed")
+end
+kin = nil -- Should not fail, even though already deleted
+checkCount(0)
+
+kin = cpp11_std_unique_ptr.Klass("KlassInput")
+checkCount(1)
+s = cpp11_std_unique_ptr.takeKlassUniquePtr(kin)
+checkCount(0)
+if not (s == "KlassInput") then
+  error("Incorrect string: "..s)
+end
+if not (cpp11_std_unique_ptr.is_nullptr(kin)) then
+  error("is_nullptr failed")
+end
+s, msg = pcall(function() cpp11_std_unique_ptr.takeKlassUniquePtr(kin) end)
+assert(s == false and msg == "Cannot release ownership as memory is not owned for argument 1 of type 'Klass *' in takeKlassUniquePtr")
+
+kin = nil -- Should not fail, even though already deleted
+checkCount(0)
+
+kin = cpp11_std_unique_ptr.Klass("KlassInput")
+notowned = cpp11_std_unique_ptr.get_not_owned_ptr(kin)
+s, msg = pcall(function() cpp11_std_unique_ptr.takeKlassUniquePtr(notowned) end)
+assert(s == false and msg == "Cannot release ownership as memory is not owned for argument 1 of type 'Klass *' in takeKlassUniquePtr")
+checkCount(1)
+kin = nil
+checkCount(0)
+
+kini = cpp11_std_unique_ptr.KlassInheritance("KlassInheritanceInput")
+checkCount(1)
+s = cpp11_std_unique_ptr.takeKlassUniquePtr(kini)
+checkCount(0)
+if not (s == "KlassInheritanceInput") then
+  error("Incorrect string: "..s)
+end
+if not (cpp11_std_unique_ptr.is_nullptr(kini)) then
+  error("is_nullptr failed")
+end
+kini = nil -- Should not fail, even though already deleted
+checkCount(0)
+
+cpp11_std_unique_ptr.takeKlassUniquePtr(nil);
+cpp11_std_unique_ptr.takeKlassUniquePtr(cpp11_std_unique_ptr.make_null());
+checkCount(0);
+
+-- overloaded parameters
+if not (cpp11_std_unique_ptr.overloadTest() == 0) then
+  error("overloadTest failed")
+end
+if not (cpp11_std_unique_ptr.overloadTest(nil) == 1) then
+  error("overloadTest failed")
+end
+if not (cpp11_std_unique_ptr.overloadTest(cpp11_std_unique_ptr.Klass("over")) == 1) then
+  error("overloadTest failed")
+end
+checkCount(0)
+
+
+-- unique_ptr as output
+k1 = cpp11_std_unique_ptr.makeKlassUniquePtr("first")
+k2 = cpp11_std_unique_ptr.makeKlassUniquePtr("second")
+checkCount(2)
+
+k1 = nil
+checkCount(1)
+
+if not (k2:getLabel() == "second") then
+  error("wrong object label")
+end
+
+k2 = nil
+checkCount(0)
+
+assert(cpp11_std_unique_ptr.makeNullUniquePtr() == nil)
diff --git a/Examples/test-suite/lua/cpp17_string_view_runme.lua b/Examples/test-suite/lua/cpp17_string_view_runme.lua
new file mode 100644
index 0000000..f30e615
--- /dev/null
+++ b/Examples/test-suite/lua/cpp17_string_view_runme.lua
@@ -0,0 +1,63 @@
+require("import")	-- the import fn
+import("cpp17_string_view")	-- import lib
+
+for k,v in pairs(cpp17_string_view) do _G[k]=v end -- move to global
+
+-- catch "undefined" global variables
+local env = _ENV -- Lua 5.2
+if not env then env = getfenv () end -- Lua 5.1
+setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
+
+-- Checking expected use of %typemap(in) std::string_view {}
+test_value("Fee")
+
+-- Checking expected result of %typemap(out) std::string_view {}
+s=test_value("Fi")
+assert(type(s)=="string" and s =="Fi")
+
+-- Checking expected use of %typemap(in) const std::string_view & {}
+test_const_reference("Fo")
+
+-- Checking expected result of %typemap(out) const std::string_view& {}
+s=test_const_reference("Fum")
+assert(type(s)=="string" and s =="Fum")
+
+-- Input and output typemaps for pointers and non-const references to
+-- std::string_view are *not* supported; the following tests confirm
+-- that none of these cases are slipping through.
+
+stringPtr = test_pointer_out()
+
+test_pointer(stringPtr)
+
+stringPtr = test_const_pointer_out()
+
+test_const_pointer(stringPtr)
+
+stringPtr = test_reference_out()
+
+test_reference(stringPtr)
+
+-- Global variables
+assert(cpp17_string_view.ConstGlobalString=="const global string")
+
+-- Member variables
+myStructure = Structure()
+assert(myStructure.ConstMemberString=="const member string")
+
+assert(Structure.ConstStaticMemberString=="const static member string")
+
+test_const_reference_returning_void("foo")
+
+assert(stdstringview_empty()=="")
+assert(c_empty()=="")
+assert(c_null()==nil)
+assert(get_null(c_null())==nil)
+assert(get_null(c_empty())=="non-null")
+assert(get_null(stdstringview_empty())=="non-null")
+
+-- Regression test for bug in initial implementation, spotted before release:
+-- depending on the order of evaluation of function arguments by the compiler,
+-- a numeric value might be passed as an empty string (seen with GCC 12.2 on
+-- x86-64 Linux).
+assert(test_value(1234) == "1234")
diff --git a/Examples/test-suite/lua/exception_memory_leak_runme.lua b/Examples/test-suite/lua/exception_memory_leak_runme.lua
new file mode 100644
index 0000000..f3fc0f2
--- /dev/null
+++ b/Examples/test-suite/lua/exception_memory_leak_runme.lua
@@ -0,0 +1,29 @@
+require("import")	-- the import fn
+import("exception_memory_leak")	-- import code
+eml=exception_memory_leak --alias
+
+-- catch "undefined" global variables
+local env = _ENV -- Lua 5.2
+if not env then env = getfenv () end -- Lua 5.1
+setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
+
+a = eml.Foo()
+assert(eml.Foo_get_count() == 1)
+b = eml.Foo()
+assert(eml.Foo_get_count() == 2)
+
+-- Normal behaviour
+eml.trigger_internal_swig_exception("no problem", a)
+assert(eml.Foo_get_count() == 2)
+assert(eml.Foo_get_freearg_count() == 1)
+
+-- SWIG exception triggered and handled (return new object case)
+ok,ex=pcall(eml.trigger_internal_swig_exception, "null", b)
+assert(ok==false)
+assert(eml.Foo_get_count() == 2)
+assert(eml.Foo_get_freearg_count() == 2)
+
+-- SWIG exception triggered and handled (return by value case).
+ok,ex=pcall(eml.trigger_internal_swig_exception, "null")
+assert(ok==false)
+assert(eml.Foo_get_count() == 2)
diff --git a/Examples/test-suite/lua/friends_runme.lua b/Examples/test-suite/lua/friends_runme.lua
index bdf9793..c41d0ae 100644
--- a/Examples/test-suite/lua/friends_runme.lua
+++ b/Examples/test-suite/lua/friends_runme.lua
@@ -25,3 +25,6 @@
 assert(f.get_val1(d1) == 7)
 f.set(d1,9)
 assert(f.get_val1(d1) == 9)
+
+assert(friends.chum_blah() == 1234)
+assert(friends.mate_blah() == 4321)
diff --git a/Examples/test-suite/lua/li_constraints_runme.lua b/Examples/test-suite/lua/li_constraints_runme.lua
new file mode 100644
index 0000000..c7577c2
--- /dev/null
+++ b/Examples/test-suite/lua/li_constraints_runme.lua
@@ -0,0 +1,40 @@
+require('import')       -- the import fn
+import('li_constraints') -- import lib into global
+cn=li_constraints --alias
+
+function check_func(except, f, val, name)
+  actual, err = pcall(f, val);
+  assert(actual == except, 'function perform exception wrongly');
+  if name == nil then
+    r = 'SWIG_ValueError:Received a NULL pointer.';
+  else
+    r = 'SWIG_ValueError:Expected a ' .. name .. ' value.';
+  end
+  if not actual then
+    assert(err == r, 'function perform the wrong exception');
+  end
+end
+
+check_func(true, cn.test_nonnegative, 10, 'non-negative');
+check_func(true, cn.test_nonnegative, 0, 'non-negative');
+check_func(false, cn.test_nonnegative, -10, 'non-negative');
+
+check_func(false, cn.test_nonpositive, 10, 'non-positive');
+check_func(true, cn.test_nonpositive, 0, 'non-positive');
+check_func(true, cn.test_nonpositive, -10, 'non-positive');
+
+check_func(true, cn.test_positive, 10, 'positive');
+check_func(false, cn.test_positive, 0, 'positive');
+check_func(false, cn.test_positive, -10, 'positive');
+
+check_func(false, cn.test_negative, 10, 'negative');
+check_func(false, cn.test_negative, 0, 'negative');
+check_func(true, cn.test_negative, -10, 'negative');
+
+check_func(true, cn.test_nonzero, 10, 'nonzero');
+check_func(false, cn.test_nonzero, 0, 'nonzero');
+check_func(true, cn.test_nonzero, -10, 'nonzero');
+
+check_func(false, cn.test_nonnull, nil);
+nonnull = cn.get_nonnull();
+check_func(true, cn.test_nonnull, nonnull);
diff --git a/Examples/test-suite/lua/li_std_auto_ptr_runme.lua b/Examples/test-suite/lua/li_std_auto_ptr_runme.lua
new file mode 100644
index 0000000..118a62f
--- /dev/null
+++ b/Examples/test-suite/lua/li_std_auto_ptr_runme.lua
@@ -0,0 +1,112 @@
+require("import")	-- the import fn
+import("li_std_auto_ptr")	-- import code
+
+-- catch "undefined" global variables
+local env = _ENV -- Lua 5.2
+if not env then env = getfenv () end -- Lua 5.1
+setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
+
+
+function checkCount(expected_count)
+  -- call gc to make unused objects are collected
+  collectgarbage()
+  actual_count = li_std_auto_ptr.Klass.getTotal_count()
+  if not (actual_count == expected_count) then
+    error("Counts incorrect, expected:"..expected_count.." actual:"..actual_count)
+  end
+end
+
+--Test raw pointer handling involving virtual inheritance
+kini = li_std_auto_ptr.KlassInheritance("KlassInheritanceInput")
+checkCount(1)
+s = li_std_auto_ptr.useKlassRawPtr(kini)
+if not (s == "KlassInheritanceInput") then
+  error("Incorrect string: "..s)
+end
+kini = nil
+checkCount(0)
+
+-- auto_ptr as input
+kin = li_std_auto_ptr.Klass("KlassInput")
+checkCount(1)
+s = li_std_auto_ptr.takeKlassAutoPtr(kin)
+checkCount(0)
+if not (s == "KlassInput") then
+  error("Incorrect string: "..s)
+end
+if not (li_std_auto_ptr.is_nullptr(kin)) then
+  error("is_nullptr failed")
+end
+kin = nil -- Should not fail, even though already deleted
+checkCount(0)
+
+kin = li_std_auto_ptr.Klass("KlassInput")
+checkCount(1)
+s = li_std_auto_ptr.takeKlassAutoPtr(kin)
+checkCount(0)
+if not (s == "KlassInput") then
+  error("Incorrect string: "..s)
+end
+if not (li_std_auto_ptr.is_nullptr(kin)) then
+  error("is_nullptr failed")
+end
+s, msg = pcall(function() li_std_auto_ptr.takeKlassAutoPtr(kin) end)
+assert(s == false and msg == "Cannot release ownership as memory is not owned for argument 1 of type 'Klass *' in takeKlassAutoPtr")
+
+kin = nil -- Should not fail, even though already deleted
+checkCount(0)
+
+kin = li_std_auto_ptr.Klass("KlassInput")
+notowned = li_std_auto_ptr.get_not_owned_ptr(kin)
+s, msg = pcall(function() li_std_auto_ptr.takeKlassAutoPtr(notowned) end)
+assert(s == false and msg == "Cannot release ownership as memory is not owned for argument 1 of type 'Klass *' in takeKlassAutoPtr")
+checkCount(1)
+kin = nil
+checkCount(0)
+
+kini = li_std_auto_ptr.KlassInheritance("KlassInheritanceInput")
+checkCount(1)
+s = li_std_auto_ptr.takeKlassAutoPtr(kini)
+checkCount(0)
+if not (s == "KlassInheritanceInput") then
+  error("Incorrect string: "..s)
+end
+if not (li_std_auto_ptr.is_nullptr(kini)) then
+  error("is_nullptr failed")
+end
+kini = nil -- Should not fail, even though already deleted
+checkCount(0)
+
+li_std_auto_ptr.takeKlassAutoPtr(nil);
+li_std_auto_ptr.takeKlassAutoPtr(li_std_auto_ptr.make_null());
+checkCount(0);
+
+-- overloaded parameters
+if not (li_std_auto_ptr.overloadTest() == 0) then
+  error("overloadTest failed")
+end
+if not (li_std_auto_ptr.overloadTest(nil) == 1) then
+  error("overloadTest failed")
+end
+if not (li_std_auto_ptr.overloadTest(li_std_auto_ptr.Klass("over")) == 1) then
+  error("overloadTest failed")
+end
+checkCount(0)
+
+
+-- auto_ptr as output
+k1 = li_std_auto_ptr.makeKlassAutoPtr("first")
+k2 = li_std_auto_ptr.makeKlassAutoPtr("second")
+checkCount(2)
+
+k1 = nil
+checkCount(1)
+
+if not (k2:getLabel() == "second") then
+  error("wrong object label")
+end
+
+k2 = nil
+checkCount(0)
+
+assert(li_std_auto_ptr.makeNullAutoPtr() == nil)
diff --git a/Examples/test-suite/lua/li_std_string_runme.lua b/Examples/test-suite/lua/li_std_string_runme.lua
index a36bf7e..db6c408 100644
--- a/Examples/test-suite/lua/li_std_string_runme.lua
+++ b/Examples/test-suite/lua/li_std_string_runme.lua
@@ -36,7 +36,7 @@
 -- swig doesn't appear to diff between const object ptrs & object ptrs very well
 test_pointer(cobj)	-- this wants an non const object (give it a const one!)
 
--- refs are also wrappered as ptrs (unless the correct typemaps are applied)
+-- refs are also wrapped as ptrs (unless the correct typemaps are applied)
 robj=test_reference_out()
 assert(is_std_string(robj) and robj:c_str()=="test_reference_out message")	-- check type & value
 
@@ -44,6 +44,12 @@
 test_reference(obj)	-- object ptr is ok
 test_reference(cobj)	-- obj const ptr is also ok
 
+-- Test INPUT, INOUT and OUTPUT string& typemaps:
+assert(test_reference_input("hello")=="hello")
+s=test_reference_inout("hello")
+assert(s=="hellohello")
+assert(test_reference_output()=="output")
+
 -- throwing string
 ok,ex=pcall(test_throw)
 assert(ok==false and type(ex)=="string")	-- failed & threw string
@@ -113,3 +119,16 @@
 assert(type(li_std_string.Structure_StaticMemberString)=="string")
 assert(type(li_std_string.Structure_StaticMemberString2)=="string")
 assert(type(li_std_string.Structure_ConstStaticMemberString)=="string")
+
+
+assert(stdstring_empty()=="")
+assert(c_empty()=="")
+assert(c_null()==nil)
+assert(get_null(c_null())==nil)
+assert(get_null(c_empty())=="non-null")
+assert(get_null(stdstring_empty())=="non-null")
+
+-- Regression test for bug fixed in SWIG 4.2.0: depending on the order of
+-- evaluation of function arguments by the compiler, a numeric value might be
+-- passed as an empty string (seen with GCC 12.2 on x86-64 Linux).
+assert(test_value(1234) == "1234")
diff --git a/Examples/test-suite/lua/li_typemaps_runme.lua b/Examples/test-suite/lua/li_typemaps_runme.lua
index 7456d82..342634a 100644
--- a/Examples/test-suite/lua/li_typemaps_runme.lua
+++ b/Examples/test-suite/lua/li_typemaps_runme.lua
@@ -38,5 +38,5 @@
 a,b=li_typemaps.inoutr_int2(1,2)
 assert(a==1 and b==2)
 
-f,i=li_typemaps.out_foo(10)
-assert(f.a==10 and i==20)
+f,i,i2=li_typemaps.out_foo(10)
+assert(f.a==10 and i==20 and i2==30)
diff --git a/Examples/test-suite/lua/lua_lightuserdata_runme.lua b/Examples/test-suite/lua/lua_lightuserdata_runme.lua
new file mode 100644
index 0000000..c1c3c1d
--- /dev/null
+++ b/Examples/test-suite/lua/lua_lightuserdata_runme.lua
@@ -0,0 +1,7 @@
+require("import") -- the import fn
+import("lua_lightuserdata") -- import lib
+
+local t = lua_lightuserdata
+local d = t.get_lightuserdata()
+local r = t.check_lighuserdata(d)
+assert(r)
diff --git a/Examples/test-suite/lua/mod_runme.lua b/Examples/test-suite/lua/mod_runme.lua
new file mode 100644
index 0000000..444a61b
--- /dev/null
+++ b/Examples/test-suite/lua/mod_runme.lua
@@ -0,0 +1,12 @@
+require("import")	-- the import fn
+import("mod_a")	-- import lib
+import("mod_b")	-- import lib
+
+-- catch "undefined" global variables
+local env = _ENV -- Lua 5.2
+if not env then env = getfenv () end -- Lua 5.1
+setmetatable(env, {__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
+
+c = mod_b.C()
+d = mod_b.D()
+d:DoSomething(c)
diff --git a/Examples/test-suite/lua/overload_null_runme.lua b/Examples/test-suite/lua/overload_null_runme.lua
index 69b7de2..9b5ef56 100644
--- a/Examples/test-suite/lua/overload_null_runme.lua
+++ b/Examples/test-suite/lua/overload_null_runme.lua
@@ -29,13 +29,13 @@
 assert(15 == o:byval2cpr(nil))
 assert(16 == o:byval2cpr(x))
 
--- forward class declaration
-assert(17 == o:byval1forwardptr(x))
-assert(18 == o:byval1forwardptr(nil))
+-- fwd class declaration
+assert(17 == o:byval1fwdptr(x))
+assert(18 == o:byval1fwdptr(nil))
 
-assert(19 == o:byval2forwardptr(nil))
-assert(20 == o:byval2forwardptr(x))
+assert(19 == o:byval2fwdptr(nil))
+assert(20 == o:byval2fwdptr(x))
 
-assert(21 == o:byval1forwardref(x))
+assert(21 == o:byval1fwdref(x))
 
-assert(22 == o:byval2forwardref(x))
+assert(22 == o:byval2fwdref(x))
diff --git a/Examples/test-suite/lua_lightuserdata.i b/Examples/test-suite/lua_lightuserdata.i
new file mode 100644
index 0000000..9069b6a
--- /dev/null
+++ b/Examples/test-suite/lua_lightuserdata.i
@@ -0,0 +1,17 @@
+%module lua_lightuserdata
+
+%native(get_lightuserdata) int get_lightuserdata(lua_State* L);
+%{
+static int foo;
+int get_lightuserdata(lua_State* L)
+{
+  lua_pushlightuserdata(L, &foo);
+  return 1;
+}
+%}
+
+%inline %{
+bool check_lighuserdata(const void* d) {
+  return d == &foo;
+}
+%}
diff --git a/Examples/test-suite/memberin_extend.i b/Examples/test-suite/memberin_extend.i
index c6eb105..4325197 100644
--- a/Examples/test-suite/memberin_extend.i
+++ b/Examples/test-suite/memberin_extend.i
@@ -11,6 +11,7 @@
 
 %{
 #include <map>
+#include <string.h>
 std::map<ExtendMe*, char *> ExtendMeStringMap;
 void ExtendMe_thing_set(ExtendMe *self, const char *val) {
   char *old_val = ExtendMeStringMap[self];
diff --git a/Examples/test-suite/memberin_extend_c.i b/Examples/test-suite/memberin_extend_c.i
index 0599e65..c7e0173 100644
--- a/Examples/test-suite/memberin_extend_c.i
+++ b/Examples/test-suite/memberin_extend_c.i
@@ -32,7 +32,8 @@
 }
 
 void Person_name_set(Person *p, char *val) {
-  strncpy(p->name,val,50);
+  p->name[0] = '\0';
+  strncat(p->name, val, sizeof(p->name) - 1);
   make_upper(p->name);
 }
 %}
diff --git a/Examples/test-suite/minherit2.i b/Examples/test-suite/minherit2.i
index 2baea64..965225c 100644
--- a/Examples/test-suite/minherit2.i
+++ b/Examples/test-suite/minherit2.i
@@ -40,18 +40,18 @@
 #endif
 
 // Modify multiple inherited base classes into inheriting interfaces
-%typemap(javainterfaces) RemoteMpe "IRemoteSyncIO, IRemoteAsyncIO";
-%typemap(javabase, replace="1") RemoteMpe "";
+%typemap(javainterfaces) RemoteMpe "IRemoteSyncIO, IRemoteAsyncIO"
+%typemap(javabase, replace="1") RemoteMpe ""
 
 // Turn the proxy class into an interface
-%typemap(javaclassmodifiers) IRemoteSyncIO "public interface";
-%typemap(javaclassmodifiers) IRemoteAsyncIO "public interface";
-%typemap(javabody) IRemoteSyncIO "";
-%typemap(javabody) IRemoteAsyncIO "";
-%typemap(javafinalize) IRemoteSyncIO "";
-%typemap(javafinalize) IRemoteAsyncIO "";
-%typemap(javadestruct) IRemoteSyncIO "";
-%typemap(javadestruct) IRemoteAsyncIO "";
+%typemap(javaclassmodifiers) IRemoteSyncIO "public interface"
+%typemap(javaclassmodifiers) IRemoteAsyncIO "public interface"
+%typemap(javabody) IRemoteSyncIO ""
+%typemap(javabody) IRemoteAsyncIO ""
+%typemap(javafinalize) IRemoteSyncIO ""
+%typemap(javafinalize) IRemoteAsyncIO ""
+%typemap(javadestruct) IRemoteSyncIO ""
+%typemap(javadestruct) IRemoteAsyncIO ""
 
 // Turn the methods into abstract methods
 %typemap(javaout) void IRemoteSyncIO::syncmethod ";"
diff --git a/Examples/test-suite/mod.h b/Examples/test-suite/mod.h
index aae6298..60eb36b 100644
--- a/Examples/test-suite/mod.h
+++ b/Examples/test-suite/mod.h
@@ -1,4 +1,4 @@
-
+#include <cstddef>
 
 class C;
 
diff --git a/Examples/test-suite/multi_import.h b/Examples/test-suite/multi_import.h
index fa7a460..f893e3d 100644
--- a/Examples/test-suite/multi_import.h
+++ b/Examples/test-suite/multi_import.h
@@ -1,3 +1,11 @@
+#ifndef MULTI_IMPORT_H
+#define MULTI_IMPORT_H
+
+class WWW {
+  public:
+    void nullop() const {}
+};
+
 class XXX
 {
 	public:
@@ -15,3 +23,5 @@
 	public:
 		int testz() { return 2;}
 };
+
+#endif /* MULTI_IMPORT_H */
diff --git a/Examples/test-suite/multi_import.list b/Examples/test-suite/multi_import.list
index 6f7f98c..a42944f 100644
--- a/Examples/test-suite/multi_import.list
+++ b/Examples/test-suite/multi_import.list
@@ -1,2 +1,3 @@
-multi_import_a
+multi_import_d
 multi_import_b
+multi_import_a
diff --git a/Examples/test-suite/multi_import_a.i b/Examples/test-suite/multi_import_a.i
index 62d7cc0..7cb3110 100644
--- a/Examples/test-suite/multi_import_a.i
+++ b/Examples/test-suite/multi_import_a.i
@@ -2,7 +2,8 @@
 
 %module multi_import_a
 
-%import multi_import_b.i
+%import multi_import_d.i
+%import "multi_import_b.i"
 
 %{
 #include "multi_import.h"
@@ -13,3 +14,7 @@
 public:
    int testz();
 };
+
+%inline %{
+void use_www_a(const WWW& w) {w.nullop();}
+%}
diff --git a/Examples/test-suite/multi_import_b.i b/Examples/test-suite/multi_import_b.i
index a2be270..f196082 100644
--- a/Examples/test-suite/multi_import_b.i
+++ b/Examples/test-suite/multi_import_b.i
@@ -11,3 +11,7 @@
 public:
         int testy();
 };
+
+%inline %{
+void use_www_b(const WWW& w) {w.nullop();}
+%}
diff --git a/Examples/test-suite/multi_import_c.i b/Examples/test-suite/multi_import_c.i
index 854e6b1..0e5a02e 100644
--- a/Examples/test-suite/multi_import_c.i
+++ b/Examples/test-suite/multi_import_c.i
@@ -1,3 +1,8 @@
+%import "multi_import_d.i"
+
+// NB: this module is only imported, never compiled, so it's not necessary to
+// include the header for testing purposes.
+
 class XXX
 {
 public:
diff --git a/Examples/test-suite/multi_import_d.i b/Examples/test-suite/multi_import_d.i
new file mode 100644
index 0000000..bb9cf01
--- /dev/null
+++ b/Examples/test-suite/multi_import_d.i
@@ -0,0 +1,12 @@
+%module multi_import_d
+
+%constant int myval = 1234;
+
+%{
+#include "multi_import.h"
+%}
+
+class WWW {
+  public:
+    void nullop() const;
+};
diff --git a/Examples/test-suite/multiple_inheritance_abstract.i b/Examples/test-suite/multiple_inheritance_abstract.i
index b54a37d..aea330d 100644
--- a/Examples/test-suite/multiple_inheritance_abstract.i
+++ b/Examples/test-suite/multiple_inheritance_abstract.i
@@ -1,12 +1,10 @@
-// This is a copy of the multiple_inheritance_abstract test
-%module  multiple_inheritance_abstract
+%module(ruby_minherit="1") multiple_inheritance_abstract
 
-%warnfilter(SWIGWARN_RUBY_MULTIPLE_INHERITANCE,
-	    SWIGWARN_D_MULTIPLE_INHERITANCE,
-	    SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance or %interface */
+%warnfilter(SWIGWARN_D_MULTIPLE_INHERITANCE,
+	    SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance */
 
 #if defined(SWIGJAVA) || defined(SWIGCSHARP)
-%include "swiginterface.i"
+%include <swiginterface.i>
 %interface_impl(Space::ABase1)
 %interface_impl(Space::CBase1)
 %interface_impl(Space::CBase2)
@@ -23,7 +21,7 @@
   struct CBase1 {
     virtual void cbase1x() {
       return;
-    } 
+    }
     virtual int cbase1y() {
       return 1;
     }
@@ -307,6 +305,36 @@
     return d;
   }
 
+  // Return const pointer references
+  CBase1 *const&MakeConstPtrRefDerived1_CBase1() {
+    static CBase1 *d = new Derived1();
+    return d;
+  }
+  CBase2 *const&MakeConstPtrRefDerived1_CBase2() {
+    static CBase2 *const& d = new Derived1();
+    return d;
+  }
+  CBase1 *const&MakeConstPtrRefDerived2_CBase1() {
+    static CBase1 *const& d = new Derived2();
+    return d;
+  }
+  ABase1 *const&MakeConstPtrRefDerived2_ABase1() {
+    static ABase1 *const& d = new Derived2();
+    return d;
+  }
+  ABase1 *const&MakeConstPtrRefDerived3_ABase1() {
+    static ABase1 *const& d = new Derived3();
+    return d;
+  }
+  CBase1 *const&MakeConstPtrRefDerived3_CBase1() {
+    static CBase1 *const& d = new Derived3();
+    return d;
+  }
+  CBase2 *const&MakeConstPtrRefDerived3_CBase2() {
+    static CBase2 *const& d = new Derived3();
+    return d;
+  }
+
   // Return by value (sliced objects)
   CBase1 MakeValDerived1_CBase1() {
     return Derived1();
diff --git a/Examples/test-suite/multiple_inheritance_interfaces.i b/Examples/test-suite/multiple_inheritance_interfaces.i
index 2972922..891e20f 100644
--- a/Examples/test-suite/multiple_inheritance_interfaces.i
+++ b/Examples/test-suite/multiple_inheritance_interfaces.i
@@ -1,11 +1,10 @@
-%module  multiple_inheritance_interfaces
+%module(ruby_minherit="1") multiple_inheritance_interfaces
 
-%warnfilter(SWIGWARN_RUBY_MULTIPLE_INHERITANCE,
-	    SWIGWARN_D_MULTIPLE_INHERITANCE,
-	    SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance or %interface */
+%warnfilter(SWIGWARN_D_MULTIPLE_INHERITANCE,
+	    SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance */
 
 #if defined(SWIGJAVA) || defined(SWIGCSHARP)
-%include "swiginterface.i"
+%include <swiginterface.i>
 %interface_custom("A", "IA", IA)
 %interface_custom("B", "IB", IB)
 %interface_custom("%(strip:[I])s", "I%s", IC) // same as %interface_custom("C", "IC", IC)
@@ -51,6 +50,33 @@
 %}
 
 #if defined(SWIGJAVA) || defined(SWIGCSHARP)
+%interface_impl(Undesirables);
+#endif
+
+%inline %{
+// Don't put variables and enums into interface
+class Undesirables
+{
+public:
+  Undesirables() : UndesiredVariable() {}
+  virtual ~Undesirables() {}
+  virtual void Method(int i) = 0;
+
+  enum UndesiredEnum { UndesiredEnum1, UndesiredEnum2 };
+  static void UndesiredStaticMethod(UndesiredEnum e) {}
+  int UndesiredVariable;
+  static int UndesiredStaticVariable;
+  static const int UndesiredStaticConstVariable = 0;
+};
+
+int Undesirables::UndesiredStaticVariable = 0;
+
+struct UndesirablesDerived : Undesirables {
+  virtual void Method(int i) {}
+};
+%}
+
+#if defined(SWIGJAVA) || defined(SWIGCSHARP)
 %interface_impl(BaseOverloaded);
 #endif
 %inline %{
@@ -64,3 +90,32 @@
   virtual void identical_overload(int i, const PTypedef &p = PTypedef()) {}
 };
 %}
+
+
+#if defined(SWIGJAVA) || defined(SWIGCSHARP)
+%interface(Space::X)
+#endif
+
+// Test the csinterfacemodifiers and javainterfacemodifiers typemaps.
+#if defined(SWIGCSHARP)
+/* change access from default "public class" to "internal class" */
+%typemap(csclassmodifiers) InternalAccess "internal class"
+/* The following modifiers are also needed with the above access modifier change */
+%typemap(csclassmodifiers) Space::X "internal class"
+%typemap(csinterfacemodifiers) Space::X "internal interface"
+#elif defined(SWIGJAVA)
+%typemap(javaclassmodifiers) InternalAccess "final /*notpublic*/ class"
+%typemap(javaclassmodifiers) Space::X "final class"
+%typemap(javainterfacemodifiers) Space::X "/*notpublic*/ interface"
+#endif
+
+%inline %{
+struct InternalAccess {};
+namespace Space {
+  class X {
+  public:
+    virtual void x(const InternalAccess& date) const = 0;
+    virtual ~X() {}
+  };
+}
+%}
diff --git a/Examples/test-suite/multiple_inheritance_nspace.i b/Examples/test-suite/multiple_inheritance_nspace.i
index 4faef57..f82285f 100644
--- a/Examples/test-suite/multiple_inheritance_nspace.i
+++ b/Examples/test-suite/multiple_inheritance_nspace.i
@@ -1,9 +1,8 @@
 // This is a copy of the multiple_inheritance_abstract test
-%module  multiple_inheritance_nspace
+%module(ruby_minherit="1") multiple_inheritance_nspace
 
-%warnfilter(SWIGWARN_RUBY_MULTIPLE_INHERITANCE,
-	    SWIGWARN_D_MULTIPLE_INHERITANCE,
-	    SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance or %interface */
+%warnfilter(SWIGWARN_D_MULTIPLE_INHERITANCE,
+	    SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance */
 
 // nspace feature only supported by these languages
 #if defined(SWIGJAVA) || defined(SWIGCSHARP) || defined(SWIGD) || defined(SWIGLUA) || defined(SWIGJAVASCRIPT)
@@ -11,7 +10,7 @@
 #endif
 
 #if defined(SWIGJAVA) || defined(SWIGCSHARP)
-%include "swiginterface.i"
+%include <swiginterface.i>
 %interface(Space::ABase1)
 %interface(Space::CBase1)
 %interface(Space::CBase2)
@@ -32,7 +31,7 @@
   struct CBase1 {
     virtual void cbase1x() {
       return;
-    } 
+    }
     virtual int cbase1y() {
       return 1;
     }
@@ -316,6 +315,36 @@
     return d;
   }
 
+  // Return const pointer references
+  CBase1 *const&MakeConstPtrRefDerived1_CBase1() {
+    static CBase1 *d = new Derived1();
+    return d;
+  }
+  CBase2 *const&MakeConstPtrRefDerived1_CBase2() {
+    static CBase2 *const& d = new Derived1();
+    return d;
+  }
+  CBase1 *const&MakeConstPtrRefDerived2_CBase1() {
+    static CBase1 *const& d = new Derived2();
+    return d;
+  }
+  ABase1 *const&MakeConstPtrRefDerived2_ABase1() {
+    static ABase1 *const& d = new Derived2();
+    return d;
+  }
+  ABase1 *const&MakeConstPtrRefDerived3_ABase1() {
+    static ABase1 *const& d = new Derived3();
+    return d;
+  }
+  CBase1 *const&MakeConstPtrRefDerived3_CBase1() {
+    static CBase1 *const& d = new Derived3();
+    return d;
+  }
+  CBase2 *const&MakeConstPtrRefDerived3_CBase2() {
+    static CBase2 *const& d = new Derived3();
+    return d;
+  }
+
   // Return by value (sliced objects)
   CBase1 MakeValDerived1_CBase1() {
     return Derived1();
diff --git a/Examples/test-suite/multiple_inheritance_overload.i b/Examples/test-suite/multiple_inheritance_overload.i
new file mode 100644
index 0000000..237ebd6
--- /dev/null
+++ b/Examples/test-suite/multiple_inheritance_overload.i
@@ -0,0 +1,67 @@
+%module(ruby_minherit="1") multiple_inheritance_overload
+
+%warnfilter(SWIGWARN_D_MULTIPLE_INHERITANCE,
+	    SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance */
+
+#if defined(SWIGJAVA) || defined(SWIGCSHARP)
+%include <swiginterface.i>
+%interface_impl(Space::Base);
+%interface_impl(Space::AnotherBase);
+#endif
+
+%ignore AnotherSpace::AnotherBase::AnotherMethod(int i) const;
+%ignore Space::Base::Method(int i) const;
+%ignore Space::Base::NotVirtualMethod(int i) const;
+%ignore Space::Base::SimilarOverloadedMethod(unsigned short i);
+%rename(MethodForRenamingConst) Space::Base::MethodForRenaming(int i) const;
+
+// Different overloaded warning filters needed for scripting languages (eg Python) and for statically typed languages (eg C#).
+%warnfilter(509, 516) Space::Base::MethodWarningSuppressed(int i) const;
+
+%inline %{
+namespace AnotherSpace {
+class AnotherBase {
+public:
+  virtual int AnotherMethod(int i) { return 0; }
+  virtual int AnotherMethod(int i) const { return 1; }
+  virtual ~AnotherBase() {}
+};
+}
+
+namespace Space {
+class Base
+{
+public:
+  virtual int Method(int i) { return 0; }
+  virtual int Method(int i) const { return 1; }
+  virtual int MethodForRenaming(int i) { return 0; }
+  virtual int MethodForRenaming(int i) const { return 1; }
+  virtual int MethodWarningSuppressed(int i) { return 0; }
+  virtual int MethodWarningSuppressed(int i) const { return 1; }
+  int NotVirtualMethod(int i) { return 0; }
+  int NotVirtualMethod(int i) const { return 1; }
+
+  typedef int Integer;
+
+  // int and unsigned short are wrapped with a Java int and so would be automatically ignored with a warning
+  virtual int SimilarOverloadedMethod(Integer i) { return 0; }
+  virtual int SimilarOverloadedMethod(unsigned short i) { return 1; }
+  virtual ~Base() {}
+  static Base *in_out(Base *p) { return p; }
+};
+
+class Derived : public Base, public AnotherSpace::AnotherBase
+{
+public:
+  int member_var;
+};
+class MoreDerived : public Derived {
+};
+}
+
+namespace OtherSpace {
+class OtherDerived : public Space::Base
+{
+};
+}
+%}
diff --git a/Examples/test-suite/multiple_inheritance_shared_ptr.i b/Examples/test-suite/multiple_inheritance_shared_ptr.i
index 3c061e1..d68e12d 100644
--- a/Examples/test-suite/multiple_inheritance_shared_ptr.i
+++ b/Examples/test-suite/multiple_inheritance_shared_ptr.i
@@ -1,9 +1,8 @@
 // This is a copy of the multiple_inheritance_abstract test and extended for testing %shared_ptr and %interface_impl
-%module  multiple_inheritance_shared_ptr
+%module(ruby_minherit="1") multiple_inheritance_shared_ptr
 
-%warnfilter(SWIGWARN_RUBY_MULTIPLE_INHERITANCE,
-	    SWIGWARN_D_MULTIPLE_INHERITANCE,
-	    SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance or %interface */
+%warnfilter(SWIGWARN_D_MULTIPLE_INHERITANCE,
+	    SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance */
 
 // Typemap changes required to mix %shared_ptr and %interface_impl
 // Note we don't have a way to use $javainterfacename/$csinterfacename (yet),
@@ -49,7 +48,7 @@
 %shared_ptr(Space::Bottom2)
 %shared_ptr(Space::Bottom3)
 
-%include "swiginterface.i"
+%include <swiginterface.i>
 SWIG_SHARED_PTR_INTERFACE_TYPEMAPS(, Space::ABase1)
 SWIG_SHARED_PTR_INTERFACE_TYPEMAPS(, Space::CBase1)
 SWIG_SHARED_PTR_INTERFACE_TYPEMAPS(, Space::CBase2)
@@ -425,6 +424,36 @@
     return d;
   }
 
+  // Return const pointer references
+  CBase1 *const&MakeConstPtrRefDerived1_CBase1() {
+    static CBase1 *d = new Derived1();
+    return d;
+  }
+  CBase2 *const&MakeConstPtrRefDerived1_CBase2() {
+    static CBase2 *const& d = new Derived1();
+    return d;
+  }
+  CBase1 *const&MakeConstPtrRefDerived2_CBase1() {
+    static CBase1 *const& d = new Derived2();
+    return d;
+  }
+  ABase1 *const&MakeConstPtrRefDerived2_ABase1() {
+    static ABase1 *const& d = new Derived2();
+    return d;
+  }
+  ABase1 *const&MakeConstPtrRefDerived3_ABase1() {
+    static ABase1 *const& d = new Derived3();
+    return d;
+  }
+  CBase1 *const&MakeConstPtrRefDerived3_CBase1() {
+    static CBase1 *const& d = new Derived3();
+    return d;
+  }
+  CBase2 *const&MakeConstPtrRefDerived3_CBase2() {
+    static CBase2 *const& d = new Derived3();
+    return d;
+  }
+
   // Return by value (sliced objects)
   CBase1 MakeValDerived1_CBase1() {
     return Derived1();
diff --git a/Examples/test-suite/mzscheme/Makefile.in b/Examples/test-suite/mzscheme/Makefile.in
index 6a8ef74..212379c 100644
--- a/Examples/test-suite/mzscheme/Makefile.in
+++ b/Examples/test-suite/mzscheme/Makefile.in
@@ -6,6 +6,10 @@
 MZSCHEME     = mzscheme
 SCRIPTSUFFIX = _runme.scm
 
+HAVE_CXX11   = @HAVE_CXX11@
+HAVE_CXX14   = @HAVE_CXX14@
+HAVE_CXX17   = @HAVE_CXX17@
+HAVE_CXX20   = @HAVE_CXX20@
 srcdir       = @srcdir@
 top_srcdir   = @top_srcdir@
 top_builddir = @top_builddir@
@@ -19,6 +23,11 @@
 chartest \
 class_scope_weird \
 constant_pointers \
+cpp11_alternate_function_syntax \
+cpp11_director_enums \
+cpp11_ref_qualifiers \
+cpp11_rvalue_reference2 \
+cpp11_strongly_typed_enumerations \
 cpp_basic \
 cpp_enum \
 curiously_recurring_template_pattern \
diff --git a/Examples/test-suite/mzscheme/argcargvtest_runme.scm b/Examples/test-suite/mzscheme/argcargvtest_runme.scm
new file mode 100644
index 0000000..f1c43a7
--- /dev/null
+++ b/Examples/test-suite/mzscheme/argcargvtest_runme.scm
@@ -0,0 +1,44 @@
+(load-extension "argcargvtest.so")
+
+(define largs #("hi" "hola" "hello"))
+(when (not (= (mainc largs) 3))
+    (error "calling mainc failed"))
+
+(define targs #("hi" "hola"))
+(when (not (string=? (mainv targs 0) "hi"))
+    (error "calling mainv failed"))
+(when (not (string=? (mainv targs 1) "hola"))
+    (error "calling mainv failed"))
+(when (not (string=? (mainv targs 2) "<<NULL>>"))
+    (error "calling mainv failed"))
+
+(with-handlers ([exn:fail? (lambda (exn)
+                 (when (not (string=? (exn-message exn)
+                       "SWIG contract, assertion failed: function=mainv, message=null array"))
+                    (error "wrong error")))])
+  (mainv "hello" 1)
+  (error "mainv should generate exception"))
+
+(initializeApp largs)
+
+; Check that an empty array works.
+(define empty_args #())
+(when (not (= (mainc empty_args) 0))
+    (error "calling mainc failed"))
+(when (not (string=? (mainv empty_args 0) "<<NULL>>"))
+    (error "calling mainv failed"))
+
+; Check that empty strings are handled.
+(define empty_string #("hello" "" "world"))
+(when (not (= (mainc empty_string) 3))
+    (error "calling mainc failed"))
+(when (not (string=? (mainv empty_string 0) "hello"))
+    (error "calling mainv 0 failed"))
+(when (not (string=? (mainv empty_string 1) ""))
+    (error "calling mainv 1 failed"))
+(when (not (string=? (mainv empty_string 2) "world"))
+    (error "calling mainv 2 failed"))
+(when (not (string=? (mainv empty_string 3) "<<NULL>>"))
+    (error "calling mainv 3 failed"))
+
+(exit 0)
diff --git a/Examples/test-suite/mzscheme/catches_strings_runme.scm b/Examples/test-suite/mzscheme/catches_strings_runme.scm
new file mode 100644
index 0000000..745a7cf
--- /dev/null
+++ b/Examples/test-suite/mzscheme/catches_strings_runme.scm
@@ -0,0 +1,18 @@
+(load-extension "catches_strings.so")
+(require (lib "defmacro.ss"))
+
+(define exception_thrown "no exception thrown for kin")
+(with-handlers ([exn:fail? (lambda (exn)
+                             (set! exception_thrown (exn-message exn)))])
+  (StringsThrower-charstring))
+(unless (string-contains? exception_thrown "charstring message")
+  (error (format "incorrect exception message: ~a" exception_thrown)))
+
+(define exception_thrown "no exception thrown for kin")
+(with-handlers ([exn:fail? (lambda (exn)
+                             (set! exception_thrown (exn-message exn)))])
+  (StringsThrower-stdstring))
+(unless (string-contains? exception_thrown "stdstring message")
+  (error (format "incorrect exception message: ~a" exception_thrown)))
+
+(exit 0)
diff --git a/Examples/test-suite/mzscheme/cpp11_move_typemaps_runme.scm b/Examples/test-suite/mzscheme/cpp11_move_typemaps_runme.scm
new file mode 100644
index 0000000..910cb39
--- /dev/null
+++ b/Examples/test-suite/mzscheme/cpp11_move_typemaps_runme.scm
@@ -0,0 +1,35 @@
+(load-extension "cpp11_move_typemaps.so")
+(require (lib "defmacro.ss"))
+
+; Copied from ../schemerunme/cpp11_move_typemaps.scm and modified for exceptions
+
+; Define an equivalent to Guile's gc procedure
+(define-macro (gc)
+  `(collect-garbage 'major))
+
+(Counter-reset-counts)
+(define mo (new-MoveOnly 111))
+(Counter-check-counts 1 0 0 0 0 0)
+(MoveOnly-take mo)
+(Counter-check-counts 1 0 0 1 0 2)
+(delete-MoveOnly mo)
+(Counter-check-counts 1 0 0 1 0 2)
+
+(Counter-reset-counts)
+(define mo (new-MovableCopyable 111))
+(Counter-check-counts 1 0 0 0 0 0)
+(MovableCopyable-take mo)
+(Counter-check-counts 1 0 0 1 0 2)
+(delete-MovableCopyable mo)
+(Counter-check-counts 1 0 0 1 0 2)
+
+(define mo (new-MoveOnly 222))
+(MoveOnly-take mo)
+(define exception_thrown "no exception thrown for mo")
+(with-handlers ([exn:fail? (lambda (exn)
+                             (set! exception_thrown (exn-message exn)))])
+  (MoveOnly-take mo))
+(unless (string-contains? exception_thrown "cannot release ownership as memory is not owned")
+  (error "Wrong or no exception thrown: " exception_thrown))
+
+(exit 0)
diff --git a/Examples/test-suite/mzscheme/cpp11_rvalue_reference_move_runme.scm b/Examples/test-suite/mzscheme/cpp11_rvalue_reference_move_runme.scm
new file mode 100644
index 0000000..6c68fef
--- /dev/null
+++ b/Examples/test-suite/mzscheme/cpp11_rvalue_reference_move_runme.scm
@@ -0,0 +1,68 @@
+(load-extension "cpp11_rvalue_reference_move.so")
+(require (lib "defmacro.ss"))
+
+; Copied from ../schemerunme/cpp11_rvalue_reference_move.scm and modified for exceptions
+
+; Function containing rvalue reference parameter
+(Counter-reset-counts)
+(define mo (new-MovableCopyable 222))
+(Counter-check-counts 1 0 0 0 0 0)
+(MovableCopyable-movein mo)
+(Counter-check-counts 1 0 0 1 0 2)
+(unless (MovableCopyable-is-nullptr mo)
+  (error "is_nullptr failed"))
+(delete-MovableCopyable mo)
+(Counter-check-counts 1 0 0 1 0 2)
+
+; Move constructor test
+(Counter-reset-counts)
+(define mo (new-MovableCopyable 222))
+(Counter-check-counts 1 0 0 0 0 0)
+(define mo_moved (new-MovableCopyable mo))
+(Counter-check-counts 1 0 0 1 0 1)
+(unless (MovableCopyable-is-nullptr mo)
+  (error "is_nullptr failed"))
+(delete-MovableCopyable mo)
+(Counter-check-counts 1 0 0 1 0 1)
+(delete-MovableCopyable mo_moved)
+(Counter-check-counts 1 0 0 1 0 2)
+
+; Move assignment operator test
+(Counter-reset-counts)
+(define mo111 (new-MovableCopyable 111))
+(define mo222 (new-MovableCopyable 222))
+(Counter-check-counts 2 0 0 0 0 0)
+(MovableCopyable-MoveAssign mo111 mo222)
+(Counter-check-counts 2 0 0 0 1 1)
+(unless (MovableCopyable-is-nullptr mo222)
+  (error "is_nullptr failed"))
+(delete-MovableCopyable mo222)
+(Counter-check-counts 2 0 0 0 1 1)
+(delete-MovableCopyable mo111)
+(Counter-check-counts 2 0 0 0 1 2)
+
+; null check
+(Counter-reset-counts)
+(define exception_thrown "no exception thrown for kin")
+(with-handlers ([exn:fail? (lambda (exn)
+                             (set! exception_thrown (exn-message exn)))])
+  (MovableCopyable-movein '()))
+(unless (string=? exception_thrown "MovableCopyable-movein: swig-type-error (null reference)")
+  (error (format "incorrect exception message: ~a" exception_thrown)))
+(Counter-check-counts 0 0 0 0 0 0)
+
+; output
+(Counter-reset-counts)
+(define mc (MovableCopyable-moveout 1234))
+(Counter-check-counts 2 0 0 0 1 1)
+(MovableCopyable-check-numbers-match mc 1234)
+
+(define exception_thrown "no exception thrown for kin")
+(with-handlers ([exn:fail? (lambda (exn)
+                             (set! exception_thrown (exn-message exn)))])
+  (MovableCopyable-movein mc))
+(unless (string-contains? exception_thrown "cannot release ownership as memory is not owned")
+  (error (format "incorrect exception message: ~a" exception_thrown)))
+(Counter-check-counts 2 0 0 0 1 1)
+
+(exit 0)
diff --git a/Examples/test-suite/mzscheme/cpp11_std_unique_ptr_runme.scm b/Examples/test-suite/mzscheme/cpp11_std_unique_ptr_runme.scm
new file mode 100644
index 0000000..cd0e180
--- /dev/null
+++ b/Examples/test-suite/mzscheme/cpp11_std_unique_ptr_runme.scm
@@ -0,0 +1,109 @@
+(load-extension "cpp11_std_unique_ptr.so")
+(require (lib "defmacro.ss"))
+
+; Copied from ../schemerunme/cpp11_std_unique_ptr.scm and modified for exceptions
+
+; Define an equivalent to Guile's gc procedure
+(define-macro (gc)
+  `(collect-garbage 'major))
+
+(define checkCount
+  (lambda (expected-count)
+    (define actual-count (Klass-getTotal-count))
+    (unless (= actual-count expected-count) (error (format "Counts incorrect, expected:~a actual:~a" expected-count  actual-count)))))
+
+; Test raw pointer handling involving virtual inheritance
+(define kini (new-KlassInheritance "KlassInheritanceInput"))
+(checkCount 1)
+(define s (useKlassRawPtr kini))
+(unless (string=? s "KlassInheritanceInput")
+  (error "Incorrect string: " s))
+(set! kini '()) (gc)
+(checkCount 0)
+
+; unique_ptr as input
+(define kin (new-Klass "KlassInput"))
+(checkCount 1)
+(define s (takeKlassUniquePtr kin))
+(checkCount 0)
+(unless (string=? s "KlassInput")
+  (error "Incorrect string: " s))
+(unless (is-nullptr kin)
+  (error "is_nullptr failed"))
+(set! kini '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define kin (new-Klass "KlassInput"))
+(checkCount 1)
+(define s (takeKlassUniquePtr kin))
+(checkCount 0)
+(unless (string=? s "KlassInput")
+  (error "Incorrect string: " s))
+(unless (is-nullptr kin)
+  (error "is_nullptr failed"))
+
+(define exception_thrown "no exception thrown for kin")
+(with-handlers ([exn:fail? (lambda (exn)
+                             (set! exception_thrown (exn-message exn)))])
+  (takeKlassUniquePtr kin))
+(unless (string=? exception_thrown "takeKlassUniquePtr: cannot release ownership as memory is not owned for argument 1 of type 'Klass *'")
+  (error "Wrong or no exception thrown: " exception_thrown))
+(set! kin '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define kin (new-Klass "KlassInput"))
+(define notowned (get-not-owned-ptr kin))
+(set! exception_thrown "no exception thrown for notowned")
+(with-handlers ([exn:fail? (lambda (exn)
+                             (set! exception_thrown (exn-message exn)))])
+  (takeKlassUniquePtr notowned))
+(unless (string=? exception_thrown "takeKlassUniquePtr: cannot release ownership as memory is not owned for argument 1 of type 'Klass *'")
+  (error "Wrong or no exception thrown: " exception_thrown))
+(checkCount 1)
+(set! kin '()) (gc)
+(checkCount 0)
+
+(define kini (new-KlassInheritance "KlassInheritanceInput"))
+(checkCount 1)
+(define s (takeKlassUniquePtr kini))
+(checkCount 0)
+(unless (string=? s "KlassInheritanceInput")
+  (error "Incorrect string: " s))
+(unless (is-nullptr kini)
+  (error "is_nullptr failed"))
+(set! kini '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define null '())
+(takeKlassUniquePtr null)
+(takeKlassUniquePtr (make-null))
+(checkCount 0)
+
+; overloaded parameters
+(unless (= (overloadTest) 0)
+  (error "overloadTest failed"))
+(unless (= (overloadTest null) 1)
+  (error "overloadTest failed"))
+(unless (= (overloadTest (new-Klass "over")) 1)
+  (error "overloadTest failed"))
+(checkCount 0)
+
+
+; unique_ptr as output
+(define k1 (makeKlassUniquePtr "first"))
+(define k2 (makeKlassUniquePtr "second"))
+(checkCount 2)
+
+(set! k1 '()) (gc)
+(checkCount 1)
+
+(unless (string=? (Klass-getLabel k2) "second")
+  (error "wrong object label" ))
+
+(set! k2 '()) (gc)
+(checkCount 0)
+
+(unless (null? (makeNullUniquePtr))
+  (error "null failure"))
+
+(exit 0)
diff --git a/Examples/test-suite/mzscheme/integers_runme.scm b/Examples/test-suite/mzscheme/integers_runme.scm
index 03c8021..e2e8817 100644
--- a/Examples/test-suite/mzscheme/integers_runme.scm
+++ b/Examples/test-suite/mzscheme/integers_runme.scm
@@ -6,4 +6,4 @@
      ,form
      #f))
 
-(load "../schemerunme/integers.scm")
+(load (build-path (path-only (path->complete-path (find-system-path 'run-file))) "../schemerunme/integers.scm"))
diff --git a/Examples/test-suite/mzscheme/li_std_auto_ptr_runme.scm b/Examples/test-suite/mzscheme/li_std_auto_ptr_runme.scm
new file mode 100644
index 0000000..c6c43db
--- /dev/null
+++ b/Examples/test-suite/mzscheme/li_std_auto_ptr_runme.scm
@@ -0,0 +1,109 @@
+(load-extension "li_std_auto_ptr.so")
+(require (lib "defmacro.ss"))
+
+; Copied from ../schemerunme/li_std_auto_ptr.scm and modified for exceptions
+
+; Define an equivalent to Guile's gc procedure
+(define-macro (gc)
+  `(collect-garbage 'major))
+
+(define checkCount
+  (lambda (expected-count)
+    (define actual-count (Klass-getTotal-count))
+    (unless (= actual-count expected-count) (error (format "Counts incorrect, expected:~a actual:~a" expected-count  actual-count)))))
+
+; Test raw pointer handling involving virtual inheritance
+(define kini (new-KlassInheritance "KlassInheritanceInput"))
+(checkCount 1)
+(define s (useKlassRawPtr kini))
+(unless (string=? s "KlassInheritanceInput")
+  (error "Incorrect string: " s))
+(set! kini '()) (gc)
+(checkCount 0)
+
+; auto_ptr as input
+(define kin (new-Klass "KlassInput"))
+(checkCount 1)
+(define s (takeKlassAutoPtr kin))
+(checkCount 0)
+(unless (string=? s "KlassInput")
+  (error "Incorrect string: " s))
+(unless (is-nullptr kin)
+  (error "is_nullptr failed"))
+(set! kini '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define kin (new-Klass "KlassInput"))
+(checkCount 1)
+(define s (takeKlassAutoPtr kin))
+(checkCount 0)
+(unless (string=? s "KlassInput")
+  (error "Incorrect string: " s))
+(unless (is-nullptr kin)
+  (error "is_nullptr failed"))
+
+(define exception_thrown "no exception thrown for kin")
+(with-handlers ([exn:fail? (lambda (exn)
+                             (set! exception_thrown (exn-message exn)))])
+  (takeKlassAutoPtr kin))
+(unless (string=? exception_thrown "takeKlassAutoPtr: cannot release ownership as memory is not owned for argument 1 of type 'Klass *'")
+  (error "Wrong or no exception thrown: " exception_thrown))
+(set! kin '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define kin (new-Klass "KlassInput"))
+(define notowned (get-not-owned-ptr kin))
+(set! exception_thrown "no exception thrown for notowned")
+(with-handlers ([exn:fail? (lambda (exn)
+                             (set! exception_thrown (exn-message exn)))])
+  (takeKlassAutoPtr notowned))
+(unless (string=? exception_thrown "takeKlassAutoPtr: cannot release ownership as memory is not owned for argument 1 of type 'Klass *'")
+  (error "Wrong or no exception thrown: " exception_thrown))
+(checkCount 1)
+(set! kin '()) (gc)
+(checkCount 0)
+
+(define kini (new-KlassInheritance "KlassInheritanceInput"))
+(checkCount 1)
+(define s (takeKlassAutoPtr kini))
+(checkCount 0)
+(unless (string=? s "KlassInheritanceInput")
+  (error "Incorrect string: " s))
+(unless (is-nullptr kini)
+  (error "is_nullptr failed"))
+(set! kini '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define null '())
+(takeKlassAutoPtr null)
+(takeKlassAutoPtr (make-null))
+(checkCount 0)
+
+; overloaded parameters
+(unless (= (overloadTest) 0)
+  (error "overloadTest failed"))
+(unless (= (overloadTest null) 1)
+  (error "overloadTest failed"))
+(unless (= (overloadTest (new-Klass "over")) 1)
+  (error "overloadTest failed"))
+(checkCount 0)
+
+
+; auto_ptr as output
+(define k1 (makeKlassAutoPtr "first"))
+(define k2 (makeKlassAutoPtr "second"))
+(checkCount 2)
+
+(set! k1 '()) (gc)
+(checkCount 1)
+
+(unless (string=? (Klass-getLabel k2) "second")
+  (error "wrong object label" ))
+
+(set! k2 '()) (gc)
+(checkCount 0)
+
+(unless (null? (makeNullAutoPtr))
+  (error "null failure"))
+
+(exit 0)
diff --git a/Examples/test-suite/mzscheme/newobject1_runme.scm b/Examples/test-suite/mzscheme/newobject1_runme.scm
new file mode 100644
index 0000000..17333ed
--- /dev/null
+++ b/Examples/test-suite/mzscheme/newobject1_runme.scm
@@ -0,0 +1,9 @@
+(load-extension "newobject1.so")
+
+(require (lib "defmacro.ss"))
+
+; Define an equivalent to Guile's gc procedure
+(define-macro (gc)
+  `(collect-garbage 'major))
+
+(load (build-path (path-only (path->complete-path (find-system-path 'run-file))) "../schemerunme/newobject1.scm"))
diff --git a/Examples/test-suite/mzscheme/null_pointer_runme.scm b/Examples/test-suite/mzscheme/null_pointer_runme.scm
new file mode 100644
index 0000000..35f83a4
--- /dev/null
+++ b/Examples/test-suite/mzscheme/null_pointer_runme.scm
@@ -0,0 +1,3 @@
+(load-extension "null_pointer.so")
+
+(load (build-path (path-only (path->complete-path (find-system-path 'run-file))) "../schemerunme/null_pointer.scm"))
diff --git a/Examples/test-suite/name.i b/Examples/test-suite/name.i
index 70e80dc..56ce106 100644
--- a/Examples/test-suite/name.i
+++ b/Examples/test-suite/name.i
@@ -1,28 +1,21 @@
-/* This interface file tests whether SWIG/Guile handle the %rename and
-   %name directives, which was not the case in 1.3a5.
+/* This interface file tests whether SWIG/Guile handle the %rename
+   directive, which was not the case in 1.3a5.
 */
 
 %module name
 
-#pragma SWIG nowarn=SWIGWARN_DEPRECATED_NAME // %name is deprecated. Use %rename instead.
-
 #ifdef SWIGGUILE
 %rename foo_1 "foo-2";
+%rename bar_1 "bar-2";
 #else
 %rename foo_1 "foo_2";
+%rename bar_1 "bar_2";
 #endif
+%rename Baz_1 "Baz_2";
+
 %inline %{
 void foo_1() {}
-%}
-
-#ifdef SWIGGUILE
-%name("bar-2")
-#else
-%name("bar_2")
-#endif
-%inline %{
 int bar_1 = 17;
 %}
 
-%name("Baz_2")
 %constant int Baz_1 = 47;
diff --git a/Examples/test-suite/name_cxx.i b/Examples/test-suite/name_cxx.i
index 64d79c3..be69ce8 100644
--- a/Examples/test-suite/name_cxx.i
+++ b/Examples/test-suite/name_cxx.i
@@ -1,23 +1,18 @@
 /* This interface files tests whether SWIG handles overloaded
-   renamed functions. 
+   renamed functions and inheriting from a renamed class.
 */
 
 %module name_cxx
 
-#pragma SWIG nowarn=SWIGWARN_DEPRECATED_NAME // %name is deprecated. Use %rename instead.
+%rename bar(int) "bar_int";
+%rename bar(double) "bar_double";
+%rename A "AA";
 
-%name("bar_int")
 %inline %{
 void bar(int i) {}
-%}
-
-%name("bar_double")
-%inline %{
 void bar(double i) {}
-%}
 
-// %name inheritance test
-%{
+// %rename inheritance test
 class A {
 };
 
@@ -25,7 +20,3 @@
 };
 
 %}
-
-%name(AA) class A { };
-class B : public A { };
-
diff --git a/Examples/test-suite/name_warnings.i b/Examples/test-suite/name_warnings.i
index 0b62ec5..12e46ac 100644
--- a/Examples/test-suite/name_warnings.i
+++ b/Examples/test-suite/name_warnings.i
@@ -69,3 +69,20 @@
 #endif
   double bar(double native, bool boolean) { return 1.0; }
 }
+
+// Test that anonymous template instantiations are ignored from
+// %rename/%namewarn
+%namewarn(%warningmsg(SWIGWARN_LANG_IDENTIFIER, "incorrectly warning about non-wrapped instantiated template"), error=1) "__dummy_0__";
+%inline %{
+template<typename T> struct Foo {
+    typedef T value_type;
+};
+%}
+%template() Foo<int>;
+
+// But they should still generate the correct typemaps etc
+%inline %{
+int double_an_int(Foo<int>::value_type v) {
+    return v * 2;
+}
+%}
diff --git a/Examples/test-suite/namespace_class.i b/Examples/test-suite/namespace_class.i
index cc9940d..17670a4 100644
--- a/Examples/test-suite/namespace_class.i
+++ b/Examples/test-suite/namespace_class.i
@@ -155,10 +155,8 @@
 
 %}
 
-namespace test {
-  
-  %template(BooT_H) ::BooT<Hello>;
-}
+using test::Hello;
+%template(BooT_H) ::BooT<Hello>;
 %template(BooT_i) ::BooT<int>;
 
 
diff --git a/Examples/test-suite/namespace_struct.i b/Examples/test-suite/namespace_struct.i
new file mode 100644
index 0000000..2d2bf55
--- /dev/null
+++ b/Examples/test-suite/namespace_struct.i
@@ -0,0 +1,8 @@
+%module namespace_struct
+
+%inline %{
+
+// SWIG/R generated bad code for copyToR for a struct in a namespace in SWIG < 4.1.0
+namespace X { struct Y { int x, y; }; }
+
+%}
diff --git a/Examples/test-suite/namespace_typemap.i b/Examples/test-suite/namespace_typemap.i
index 9c74715..8636f43 100644
--- a/Examples/test-suite/namespace_typemap.i
+++ b/Examples/test-suite/namespace_typemap.i
@@ -2,6 +2,7 @@
 %module namespace_typemap
 
 %{
+#include <string.h>
 namespace test {
    /* A minimalistic string class */
    class string_class {
@@ -15,7 +16,7 @@
 	strcpy(data,s);
       }
      ~string_class() {
-        if (data) delete [] data;
+        delete [] data;
       }
       char *c_str() {
         return data;
@@ -84,7 +85,9 @@
     class string_class;
 #ifdef SWIGPYTHON
 	%typemap(in) string_class * {
-	    $1 = new string_class(SWIG_Python_str_AsChar($input));
+	    PyObject *bytes = NULL;
+	    $1 = new string_class(SWIG_PyUnicode_AsUTF8AndSize($input, NULL, &bytes));
+	    Py_XDECREF(bytes);
 	}
 	%typemap(freearg) string_class * {
 	    delete $1;
@@ -119,6 +122,18 @@
 	    delete $1;
 	}
 #endif
+#ifdef SWIGJAVASCRIPT
+  %fragment("SWIG_AsCharPtrAndSize");
+	%typemap(in) string_class * {
+			char *data;
+			SWIG_AsCharPtrAndSize($input, &data, NULL, NULL);
+			$1 = new string_class(data);
+			free(data);
+	}
+	%typemap(freearg) string_class * {
+	    delete $1;
+	}
+#endif
 }
 
 %inline %{
diff --git a/Examples/test-suite/native_directive.i b/Examples/test-suite/native_directive.i
index 9ae76e0..778791d 100644
--- a/Examples/test-suite/native_directive.i
+++ b/Examples/test-suite/native_directive.i
@@ -48,12 +48,39 @@
 
 #ifdef SWIGJAVASCRIPT
 %native(CountAlphaCharacters) void JavaScript_alpha_count();
+#if defined(SWIG_JAVASCRIPT_NAPI)      /* engine = napi */
 %{
-#ifdef SWIG_V8_VERSION /* engine = node || v8 */
+
+static Napi::Value JavaScript_alpha_count(const Napi::CallbackInfo &info) {
+  Napi::Env env = info.Env();
+  Napi::EscapableHandleScope scope(env);
+
+  Napi::Value jsresult;
+  char *arg1 = (char *)0;
+  int res1;
+  char *buf1 = 0;
+  int alloc1 = 0;
+  int result;
+  if (info.Length() != 1) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for _wrap_alpha_count.");
+  res1 = SWIG_AsCharPtrAndSize(info[0], &buf1, NULL, &alloc1);
+  if (!SWIG_IsOK(res1))
+    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "alpha_count" "', argument " "1"" of type '" "char const *""'");
+  arg1 = reinterpret_cast< char * >(buf1);
+  result = (int)alpha_count((char const *)arg1);
+  jsresult = SWIG_From_int(env, static_cast< int >(result));
+  if (alloc1 == SWIG_NEWOBJ) delete[] buf1;
+  return scope.Escape(jsresult);
+fail:
+  return Napi::Value();
+}
+
+%}
+#elif defined(SWIG_JAVASCRIPT_V8) /* engine = node || v8 */
+%{
 
 static SwigV8ReturnValue JavaScript_alpha_count(const SwigV8Arguments &args) {
   SWIGV8_HANDLESCOPE();
-  v8::Handle<v8::Value> jsresult;
+  SWIGV8_VALUE jsresult;
   char *arg1 = (char *)0;
   int res1;
   char *buf1 = 0;
@@ -72,7 +99,9 @@
   SWIGV8_RETURN(SWIGV8_UNDEFINED());
 }
 
-#else /* engine = jsc */
+%}
+#elif defined(SWIG_JAVASCRIPT_JSC) /* engine = jsc */
+%{
 
 static JSValueRef JavaScript_alpha_count(JSContextRef context, JSObjectRef function,
   JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception)
@@ -96,7 +125,11 @@
   return JSValueMakeUndefined(context);
 }
 
-#endif /* engine */
 %}
+#else
+%{
+#error No valid JS engine configured
+%}
+#endif /* engine */
 #endif /* SWIGJAVASCRIPT */
 
diff --git a/Examples/test-suite/nested.i b/Examples/test-suite/nested.i
index 6c4ffe3..c99d262 100644
--- a/Examples/test-suite/nested.i
+++ b/Examples/test-suite/nested.i
@@ -13,7 +13,7 @@
 %rename(InUnNamed) OuterStructNamed::Inner_union_named;
 #endif
 
-#if defined(SWIG_JAVASCRIPT_V8)
+#if defined(SWIG_JAVASCRIPT_V8) || defined(SWIG_JAVASCRIPT_NAPI)
 
 %inline %{
 #if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
diff --git a/Examples/test-suite/nested_class.i b/Examples/test-suite/nested_class.i
index b10c339..4815fc8 100644
--- a/Examples/test-suite/nested_class.i
+++ b/Examples/test-suite/nested_class.i
@@ -55,6 +55,11 @@
 #pragma GCC diagnostic ignored "-Wpedantic"
 #endif
 
+#if defined(__clang__)
+// Suppress: anonymous non-C-compatible type given name for linkage purposes by typedef declaration; add a tag name here [-Wnon-c-typedef-for-linkage]
+#pragma clang diagnostic ignored "-Wnon-c-typedef-for-linkage"
+#endif
+
 namespace bar {
     int foo() { return 0; }
 }
@@ -133,8 +138,13 @@
     Integer x;
   } InnerClass4Typedef;
 
-#ifdef _MSC_VER
-  int Outer::foo(){ return 1; } // should correctly ignore qualification here (#508)
+#ifdef SWIG
+  // SWIG should ignore the redundant qualification here (#508)...
+  int Outer::foo(){ return 1; }
+#else
+  // ..but that redundant qualification is actually invalid and many compilers
+  // now reject it with an error, so feed a valid version to the compiler.
+  int foo(){ return 1; }
 #endif
 
   typedef struct {
@@ -201,7 +211,7 @@
     Integer xx;
   } MultipleInstanceAnonDerived1, MultipleInstanceAnonDerived2, *MultipleInstanceAnonDerived3, MultipleInstanceAnonDerived4[2];
 
-#if defined(__GNUC__) || defined(_MSC_VER) || defined(SWIG)
+#if (defined(__GNUC__) && __GNUC__ < 12) || defined(_MSC_VER) || defined(SWIG)
 /* some compilers do not accept these */
   struct : public InnerMultiple {
     Integer xx;
diff --git a/Examples/test-suite/nested_extend_c.i b/Examples/test-suite/nested_extend_c.i
index f1d7ff2..9a2487c 100644
--- a/Examples/test-suite/nested_extend_c.i
+++ b/Examples/test-suite/nested_extend_c.i
@@ -1,6 +1,6 @@
 %module nested_extend_c
 
-#if defined(SWIG_JAVASCRIPT_V8)
+#if defined(SWIG_JAVASCRIPT_V8) || defined(SWIG_JAVASCRIPT_NAPI)
 
 %inline %{
 #if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
@@ -12,7 +12,11 @@
 
 #endif
 
-#if !defined(SWIGOCTAVE) && !defined(SWIG_JAVASCRIPT_V8)
+%{
+#include "stdlib.h"
+%}
+
+#if !defined(SWIGOCTAVE) && !defined(SWIG_JAVASCRIPT_V8) && !defined(SWIG_JAVASCRIPT_NAPI)
 %extend hiA {
   hiA() {
    union hiA *self = (union hiA *)malloc(sizeof(union hiA));
diff --git a/Examples/test-suite/nested_inheritance_interface.i b/Examples/test-suite/nested_inheritance_interface.i
index f8335c0..09238ea 100644
--- a/Examples/test-suite/nested_inheritance_interface.i
+++ b/Examples/test-suite/nested_inheritance_interface.i
@@ -5,7 +5,7 @@
 	    SWIGWARN_PHP_MULTIPLE_INHERITANCE); /* languages not supporting multiple inheritance or %interface */
 
 #if defined(SWIGJAVA) || defined(SWIGCSHARP)
-%include "swiginterface.i"
+%include <swiginterface.i>
 %interface(IA)
 #endif
 
diff --git a/Examples/test-suite/nested_scope.i b/Examples/test-suite/nested_scope.i
index bd66eec..dabea31 100644
--- a/Examples/test-suite/nested_scope.i
+++ b/Examples/test-suite/nested_scope.i
@@ -1,9 +1,5 @@
 %module nested_scope
 
-#if !defined(SWIGCSHARP) && !defined(SWIGJAVA)
-%feature ("flatnested");
-#endif
-
 %inline %{
 namespace ns {
         // "global" is a case-insensitive keyword in PHP.
@@ -31,9 +27,9 @@
 		public:
 			struct Nested2;
 #ifdef __clang__
-		struct Nested2 {
-			int data;
-		};
+			struct Nested2 {
+				int data;
+			};
 #endif
 			template <class T> class AbstractClass;
 			class Real;
diff --git a/Examples/test-suite/nested_scope_flat.i b/Examples/test-suite/nested_scope_flat.i
new file mode 100644
index 0000000..6aab723
--- /dev/null
+++ b/Examples/test-suite/nested_scope_flat.i
@@ -0,0 +1,5 @@
+%module nested_scope_flat
+
+%feature ("flatnested");
+
+%include "nested_scope.i"
diff --git a/Examples/test-suite/nested_structs.i b/Examples/test-suite/nested_structs.i
index 48bd9f2..1bc92e4 100644
--- a/Examples/test-suite/nested_structs.i
+++ b/Examples/test-suite/nested_structs.i
@@ -1,6 +1,6 @@
 %module nested_structs
 
-#if defined(SWIG_JAVASCRIPT_V8)
+#if defined(SWIG_JAVASCRIPT_V8) || defined(SWIG_JAVASCRIPT_NAPI)
 
 %inline %{
 #if __GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
diff --git a/Examples/test-suite/not_c_keywords.i b/Examples/test-suite/not_c_keywords.i
new file mode 100644
index 0000000..013575b
--- /dev/null
+++ b/Examples/test-suite/not_c_keywords.i
@@ -0,0 +1,13 @@
+%module not_c_keywords
+
+%extend ComplexStruct {
+void init() {
+  $self->complex = 123;
+}
+}
+
+%inline %{
+struct ComplexStruct {
+  int complex; /* complex as variable name */
+};
+%}
diff --git a/Examples/test-suite/numeric_bounds_checking.i b/Examples/test-suite/numeric_bounds_checking.i
new file mode 100644
index 0000000..1b704d0
--- /dev/null
+++ b/Examples/test-suite/numeric_bounds_checking.i
@@ -0,0 +1,47 @@
+%module numeric_bounds_checking
+
+// Tests the bounds checking for integral parameters passed to wrapped functions.
+// Note that it needs an accompanying _runme file to perform the actual test.
+
+%inline %{
+#include <limits.h>
+struct Limits {
+  signed char schar_min() { return SCHAR_MIN; }
+  signed char schar_max() { return SCHAR_MAX; }
+  unsigned char uchar_min() { return 0U; }
+  unsigned char uchar_max() { return UCHAR_MAX; }
+  short shrt_min() { return SHRT_MIN; }
+  short shrt_max() { return SHRT_MAX; }
+  unsigned short ushrt_min() { return 0U; }
+  unsigned short ushrt_max() { return USHRT_MAX; }
+  int int_min() { return INT_MIN; }
+  int int_max() { return INT_MAX; }
+  unsigned int uint_min() { return 0U; }
+  unsigned int uint_max() { return UINT_MAX; }
+  long long_min() { return LONG_MIN; }
+  long long_max() { return LONG_MAX; }
+  unsigned long ulong_min() { return 0UL; }
+  unsigned long ulong_max() { return ULONG_MAX; }
+#ifdef LLONG_MIN
+  long long llong_min() { return LLONG_MIN; }
+  long long llong_max() { return LLONG_MAX; }
+  unsigned long long ullong_min() { return 0ULL; }
+  unsigned long long ullong_max() { return ULLONG_MAX; }
+#endif
+};
+
+struct Checker {
+  signed char pass_schar(signed char v) { return v; }
+  unsigned char pass_uchar(unsigned char v) { return v; }
+  short pass_shrt(short v) { return v; }
+  unsigned short pass_ushrt(unsigned short v) { return v; }
+  int pass_int(int v) { return v; }
+  unsigned int pass_uint(unsigned int v) { return v; }
+  long pass_long(long v) { return v; }
+  unsigned long pass_ulong(unsigned long v) { return v; }
+#ifdef LLONG_MIN
+  long long pass_long(long long v) { return v; }
+  unsigned long long pass_ulong(unsigned long long v) { return v; }
+#endif
+};
+%}
diff --git a/Examples/test-suite/ocaml/Makefile.in b/Examples/test-suite/ocaml/Makefile.in
index 775b1ea..1863a4d 100644
--- a/Examples/test-suite/ocaml/Makefile.in
+++ b/Examples/test-suite/ocaml/Makefile.in
@@ -9,30 +9,33 @@
 VARIANT      = _static
 SCRIPTSUFFIX = _runme.ml
 
+HAVE_CXX11   = @HAVE_CXX11@
+HAVE_CXX14   = @HAVE_CXX14@
+HAVE_CXX17   = @HAVE_CXX17@
+HAVE_CXX20   = @HAVE_CXX20@
 srcdir       = @srcdir@
 top_srcdir   = @top_srcdir@
 top_builddir = @top_builddir@
 
 FAILING_CPP_TESTS = \
 allprotected \
-apply_signed_char \
 apply_strings \
+cpp11_decltype \
+cpp11_director_enums \
+cpp11_strongly_typed_enumerations \
 cpp_enum \
 default_constructor \
 director_binary_string \
+director_comparison_operators \
 director_enum \
 director_primitives \
-director_redefined \
 director_string \
+director_using_member_scopes \
 enum_thorough \
-li_windows \
-member_pointer_const \
-preproc_constants \
 smart_pointer_inherit \
 
 FAILING_C_TESTS = \
 enums \
-preproc_constants_c \
 
 CPP_TEST_CASES += \
 	inout \
@@ -92,15 +95,20 @@
 
 $(C_TEST_CASES:=.ctest): extra_objects
 $(CPP_TEST_CASES:=.cpptest): extra_objects
+$(CPP11_TEST_CASES:=.cpptest): extra_objects
 $(MULTI_CPP_TEST_CASES:=.multicpptest): extra_objects
 
 # Clean
 %.clean:
-	@rm -f $*.ml $*.mli $*_runme;
+	@rm -f $*_wrap.* $*.cmo $*.cmi $*.ml $*.mli $*_runme;
 	@if test $(srcdir) != .; then rm -f $(ml_runme); fi
 
 clean:
 	$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' ocaml_clean
-	rm -f clientdata_prop_a.ml clientdata_prop_b.ml import_stl_a.ml import_stl_b.ml
-	rm -f imports_a.ml imports_b.ml mod_a.ml mod_b.ml multi_import_a.ml
-	rm -f multi_import_b.ml packageoption_a.ml packageoption_b.ml packageoption_c.ml
+	rm -f clientdata_prop_a.ml clientdata_prop_b.ml
+	rm -f import_stl_a.ml import_stl_b.ml
+	rm -f imports_a.ml imports_b.ml
+	rm -f mod_a.ml mod_b.ml
+	rm -f multi_import_a.ml multi_import_b.ml multi_import_d.ml
+	rm -f packageoption_a.ml packageoption_b.ml packageoption_c.ml
+	rm -f template_typedef_cplx2.ml
diff --git a/Examples/test-suite/ocaml/catches_strings_runme.ml b/Examples/test-suite/ocaml/catches_strings_runme.ml
new file mode 100644
index 0000000..901aed0
--- /dev/null
+++ b/Examples/test-suite/ocaml/catches_strings_runme.ml
@@ -0,0 +1,14 @@
+open Swig
+open Catches_strings
+
+let _ =
+  try
+    ignore (_StringsThrower_charstring (C_void)); assert false
+  with Failure s ->
+    assert (s = "charstring message")
+
+let _ =
+  try
+    ignore (_StringsThrower_stdstring (C_void)); assert false
+  with Failure s ->
+    assert (s = "stdstring message")
diff --git a/Examples/test-suite/ocaml/director_pass_by_value_runme.ml b/Examples/test-suite/ocaml/director_pass_by_value_runme.ml
index af862f1..ce2137f 100644
--- a/Examples/test-suite/ocaml/director_pass_by_value_runme.ml
+++ b/Examples/test-suite/ocaml/director_pass_by_value_runme.ml
@@ -14,10 +14,13 @@
     (director_pass_by_value_Derived)
     '()
 
+let cpp11 = _has_cplusplus11 '() as bool
+
 let _ =
   let caller = new_Caller '() in
   assert (caller -> call_virtualMethod (d) = C_void);
   assert (Array.length !passByVal = 1);
+(* TODO: only run if cpp11... let _ = _Counter_check_counts (C_list [C_int 0; C_int 0; C_int 0; C_int 1; C_int 0; C_int 1]) in*) (* check move constructor called and just one destructor *)
   let a = List.hd (fnhelper (!passByVal.(0))) in
   assert (a -> getVal () as int = 0x12345678);
   assert (a -> "~" () = C_void);
diff --git a/Examples/test-suite/ocaml/enum_rename_runme.ml b/Examples/test-suite/ocaml/enum_rename_runme.ml
new file mode 100644
index 0000000..4aef31b
--- /dev/null
+++ b/Examples/test-suite/ocaml/enum_rename_runme.ml
@@ -0,0 +1,10 @@
+open Swig
+open Enum_rename
+
+let mydec = C_enum `M_Dec
+let _ = assert (((enum_to_int `Month mydec)) = C_int 2)
+let _ = assert (((int_to_enum `Month 2)) = C_enum `M_Dec)
+
+let mymay = C_enum `May
+let _ = assert (((enum_to_int `Month mymay)) = C_int 1)
+let _ = assert (((int_to_enum `Month 1)) = C_enum `May)
diff --git a/Examples/test-suite/ocaml/extend_template_method_runme.ml b/Examples/test-suite/ocaml/extend_template_method_runme.ml
new file mode 100644
index 0000000..5f418c9
--- /dev/null
+++ b/Examples/test-suite/ocaml/extend_template_method_runme.ml
@@ -0,0 +1,20 @@
+open Swig
+open Extend_template_method
+
+let _ =
+  let em = new_ExtendMe '() in
+  assert (em -> do_stuff_double (1, 1.1) as float = 1.1);
+  assert (em -> do_stuff_string (1, "hello there") as string = "hello there");
+  assert (em -> do_overloaded_stuff (1.1) as float = 1.1);
+  assert (em -> do_overloaded_stuff ("hello there") as string = "hello there");
+
+  assert (_ExtendMe_static_method '(123) as int = 123);
+  ignore (new_ExtendMe '(123));
+  let em = new_TemplateExtend '() in
+  assert (em -> do_template_stuff_double (1, 1.1) as float = 1.1);
+  assert (em -> do_template_stuff_string (1, "hello there") as string = "hello there");
+  assert (em -> do_template_overloaded_stuff (1.1) as float = 1.1);
+  assert (em -> do_template_overloaded_stuff ("hello there") as string = "hello there");
+  assert (_TemplateExtend_static_template_method '(123) as int = 123);
+  ignore (new_TemplateExtend '(123))
+;;
diff --git a/Examples/test-suite/ocaml/li_std_string_runme.ml b/Examples/test-suite/ocaml/li_std_string_runme.ml
new file mode 100644
index 0000000..3e0ad2c
--- /dev/null
+++ b/Examples/test-suite/ocaml/li_std_string_runme.ml
@@ -0,0 +1,53 @@
+open Swig
+open Li_std_string
+
+let _ =
+  assert (_test_value '("Fee") as string = "Fee");
+  try
+    ignore (_test_value '(None)); assert false
+  with Invalid_argument _ -> ()
+
+  assert (_test_const_reference '("Fee") as string = "Fee");
+  try
+    ignore (_test_const_reference '(None)); assert false
+  with Invalid_argument _ -> ()
+
+  let stringPtr = _test_pointer_out '() in
+  ignore (_test_pointer '(stringPtr));
+  let stringPtr = _test_const_pointer_out '() in
+  ignore (_test_const_pointer '(stringPtr));
+  let stringPtr = _test_reference_out '() in
+  ignore (_test_reference '(stringPtr));
+
+  try
+    ignore (_test_throw '()); assert false
+  with Failure s -> assert (s = "test_throw message")
+  try
+    ignore (_test_const_reference_throw '()); assert false
+  with Failure s -> assert (s = "test_const_reference_throw message")
+  assert (_GlobalString2 '() as string = "global string 2");
+  let s = C_string "initial string" in
+  ignore (_GlobalString2 '(s));
+  assert (_GlobalString2 '() = s);
+  assert (_ConstGlobalString '() as string = "const global string");
+
+  let myStructure = new_Structure '() in
+  assert (myStructure -> "[MemberString2]" () as string = "member string 2");
+  assert (myStructure -> "[MemberString2]" (s) = C_void);
+  assert (myStructure -> "[MemberString2]" () = s);
+  assert (myStructure -> "[ConstMemberString]" () as string = "const member string");
+
+  assert (_Structure_StaticMemberString2 '() as string = "static member string 2");
+  ignore (_Structure_StaticMemberString2 '(s));
+  assert (_Structure_StaticMemberString2 '() = s);
+  assert (_Structure_ConstStaticMemberString '() as string = "const static member string")
+
+  assert (_stdstring_empty '() as string = "")
+  assert (_c_empty '() as string = "")
+  (* FIXME: Can't work out what C++ NULL maps to here...
+  assert (_c_null '() = None)
+  assert (_get_null (_c_null '()) = None)
+  *)
+  assert (_get_null (_c_empty '()) as string = "non-null")
+  assert (_get_null (_stdstring_empty '()) as string = "non-null")
+;;
diff --git a/Examples/test-suite/ocaml/mod_runme.ml b/Examples/test-suite/ocaml/mod_runme.ml
new file mode 100644
index 0000000..8adb50b
--- /dev/null
+++ b/Examples/test-suite/ocaml/mod_runme.ml
@@ -0,0 +1,7 @@
+open Swig
+open Mod_a
+open Mod_b
+
+let c = new_C '()
+let d = new_D '()
+let _ = d -> "DoSomething" (c)
diff --git a/Examples/test-suite/ocaml/rename_rstrip_encoder_runme.ml b/Examples/test-suite/ocaml/rename_rstrip_encoder_runme.ml
new file mode 100644
index 0000000..88be24f
--- /dev/null
+++ b/Examples/test-suite/ocaml/rename_rstrip_encoder_runme.ml
@@ -0,0 +1,7 @@
+open Swig
+open Rename_rstrip_encoder
+
+let s = new_SomeThing '()
+let a = new_AnotherThing '() in
+  assert (a -> DoClsX () = C_void);
+;;
diff --git a/Examples/test-suite/ocaml/special_variable_macros_runme.ml b/Examples/test-suite/ocaml/special_variable_macros_runme.ml
index 7f4980e..50b2b1f 100644
--- a/Examples/test-suite/ocaml/special_variable_macros_runme.ml
+++ b/Examples/test-suite/ocaml/special_variable_macros_runme.ml
@@ -11,4 +11,6 @@
   assert (_testJim '(name) as string = "multiname num");
   let arg = new_PairIntBool '(10, false) in
   assert (_testJohn '(arg) as int = 123);
+  assert (_makeStringInt '("stringint", 999) as string = "stringint");
+  assert (_provideStringInt '(999) as string = "1000");
 ;;
diff --git a/Examples/test-suite/ocaml/template_methods_runme.ml b/Examples/test-suite/ocaml/template_methods_runme.ml
new file mode 100644
index 0000000..aaa5a34
--- /dev/null
+++ b/Examples/test-suite/ocaml/template_methods_runme.ml
@@ -0,0 +1,25 @@
+open Swig
+open Template_methods
+
+let _ =
+  let num = C_float 1. in
+  assert (_convolve1Bool '() as int = 0);
+  assert (_convolve1Bool '(true) = C_void);
+  assert (_convolve2Float '() as int = 0);
+  assert (_convolve3FloatRenamed '(num) = C_void);
+  assert (_convolve4Float '() as int = 0);
+  assert (_convolve4FloatRenamed '(num) = C_void);
+  assert (_convolve5FloatRenamed '() as int = 0);
+  assert (_convolve5FloatRenamed '(num) = C_void);
+
+  let k = new_Klass '() in
+  assert (k -> KlassTMethodBoolRenamed (true) as bool = true);
+  assert (k -> KlassTMethodBool () = C_void);
+  assert (_Klass_KlassStaticTMethodBoolRenamed '(true) as bool = true);
+  assert (_Klass_KlassStaticTMethodBool '() = C_void);
+
+  let cp = new_ComponentProperties '() in
+  assert (cp -> adda ("key1", "val1", "key2", 22.2) = C_void);
+  assert (cp -> adda ("key1", "val1", "key2", "val2", "key3", "val3") = C_void);
+  assert (cp -> adda ("key1", 1, "key2", 2, "key3", 3) = C_void)
+;;
diff --git a/Examples/test-suite/ocaml/typedef_inherit_runme.ml b/Examples/test-suite/ocaml/typedef_inherit_runme.ml
index 6352fd4..a5feb7c 100644
--- a/Examples/test-suite/ocaml/typedef_inherit_runme.ml
+++ b/Examples/test-suite/ocaml/typedef_inherit_runme.ml
@@ -7,5 +7,6 @@
   assert (_do_blah (b) as string = "Bar::blah");
   let c = new_Spam '() and d = new_Grok '() in
   assert (_do_blah2 (c) as string = "Spam::blah");
-  assert (_do_blah2 (d) as string = "Grok::blah")
+  assert (_do_blah2 (d) as string = "Grok::blah");
+  assert (d -> far() as string = "Spam::far")
 ;;
diff --git a/Examples/test-suite/ocaml/using2_runme.ml b/Examples/test-suite/ocaml/using2_runme.ml
new file mode 100644
index 0000000..1ec9e2e
--- /dev/null
+++ b/Examples/test-suite/ocaml/using2_runme.ml
@@ -0,0 +1,4 @@
+open Swig
+open Using2
+
+let _ = assert (_spam '(37) as int = 37)
diff --git a/Examples/test-suite/octave/Makefile.in b/Examples/test-suite/octave/Makefile.in
index 3c8f3b1..78d4dec 100644
--- a/Examples/test-suite/octave/Makefile.in
+++ b/Examples/test-suite/octave/Makefile.in
@@ -5,11 +5,19 @@
 LANGUAGE     = octave
 OCTAVE       = @OCTAVE@
 SCRIPTSUFFIX = _runme.m
+PCHSUPPORT   = @PCHSUPPORT@
 
+HAVE_CXX11   = @HAVE_CXX11@
+HAVE_CXX14   = @HAVE_CXX14@
+HAVE_CXX17   = @HAVE_CXX17@
+HAVE_CXX20   = @HAVE_CXX20@
 srcdir       = @srcdir@
 top_srcdir   = @top_srcdir@
 top_builddir = @top_builddir@
 
+FAILING_CPP_TESTS = \
+	cpp17_map_no_default_ctor \
+
 CPP_TEST_CASES += \
 	li_std_pair_extra \
 	li_std_string_extra \
@@ -18,24 +26,11 @@
 
 CPP11_TEST_CASES += \
 	cpp11_shared_ptr_const \
+	cpp11_shared_ptr_crtp_upcast \
 	cpp11_shared_ptr_nullptr_in_containers \
 	cpp11_shared_ptr_overload \
 	cpp11_shared_ptr_upcast \
 
-CPP_TEST_BROKEN += \
-	implicittest \
-	li_implicit \
-	li_std_set \
-	li_std_stream
-
-#C_TEST_CASES +=
-
-#
-# This test only works with modern C compilers
-#
-#C_TEST_CASES += \
-#	complextest
-
 include $(srcdir)/../common.mk
 
 # Overridden variables here
@@ -61,6 +56,23 @@
 	+$(swig_and_compile_multi_cpp)
 	$(run_testcase)
 
+# Pre-compile Octave headers, if supported
+
+ifeq (yes,$(PCHSUPPORT))
+
+export OCTHEADERSSRC = @top_srcdir@/Lib/octave/octheaders.hpp
+export OCTHEADERS    = @top_builddir@/Examples/test-suite/octave/octheaders.hpp
+export OCTHEADERSGCH = $(OCTHEADERS).gch
+export SWIGOCTHDROPT = -DSWIG_OCTAVE_EXTERNAL_OCTHEADERS
+export IOCTHEADERS   = -I@top_builddir@/Examples/test-suite/octave @PCHINCLUDEARG@ $(OCTHEADERS)@PCHINCLUDEEXT@
+
+$(OCTHEADERSGCH): $(OCTHEADERSSRC)
+	$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile octave_precompile_headers
+
+$(NOT_BROKEN_TEST_CASES) $(BROKEN_TEST_CASES): $(OCTHEADERSGCH)
+
+endif
+
 # Runs the testcase. A testcase is only run if
 # a file is found which has _runme.m appended after the testcase name.
 run_testcase = \
diff --git a/Examples/test-suite/octave/abstract_access_runme.m b/Examples/test-suite/octave/abstract_access_runme.m
index e49343a..e47223c 100644
--- a/Examples/test-suite/octave/abstract_access_runme.m
+++ b/Examples/test-suite/octave/abstract_access_runme.m
@@ -2,6 +2,6 @@
 
 d = abstract_access.D();
 if (d.do_x() != 1)
-   error
+   error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/abstract_typedef_runme.m b/Examples/test-suite/octave/abstract_typedef_runme.m
index e57f715..6f90b81 100644
--- a/Examples/test-suite/octave/abstract_typedef_runme.m
+++ b/Examples/test-suite/octave/abstract_typedef_runme.m
@@ -10,7 +10,7 @@
   
 
 if (a.write(e) != 1)
-  error
+  error("failed");
 endif
 
 
diff --git a/Examples/test-suite/octave/argcargvtest_runme.m b/Examples/test-suite/octave/argcargvtest_runme.m
index f246dd9..d1e4f3a 100644
--- a/Examples/test-suite/octave/argcargvtest_runme.m
+++ b/Examples/test-suite/octave/argcargvtest_runme.m
@@ -11,9 +11,15 @@
 endif
 
 targs={'hi', 'hola'};
+if (mainv(targs,0) != 'hi')
+  error("bad main typemap");
+endif
 if (mainv(targs,1) != 'hola')
   error("bad main typemap");
 endif
+if (mainv(targs,2) != '<<NULL>>')
+  error("bad main typemap");
+endif
 
 try
   error_flag = 0;
@@ -27,3 +33,30 @@
 
 
 initializeApp(largs);
+
+# Check that an empty array works.
+empty_args={};
+if (mainc(empty_args) != 0)
+  error("bad main typemap");
+endif
+if (mainv(empty_args,0) != '<<NULL>>')
+  error("bad main typemap");
+endif
+
+# Check that empty strings are handled.
+empty_string={"hello", blanks(0), "world"};
+if (mainc(empty_string) != 3)
+  error("bad main typemap");
+endif
+if (mainv(empty_string, 0) != "hello")
+  error("bad main typemap");
+endif
+if (mainv(empty_string, 1) != "")
+  error("bad main typemap");
+endif
+if (mainv(empty_string, 2) != "world")
+  error("bad main typemap");
+endif
+if (mainv(empty_string, 3) != "<<NULL>>")
+  error("bad main typemap");
+endif
diff --git a/Examples/test-suite/octave/callback_runme.m b/Examples/test-suite/octave/callback_runme.m
index db9f788..95df598 100644
--- a/Examples/test-suite/octave/callback_runme.m
+++ b/Examples/test-suite/octave/callback_runme.m
@@ -2,39 +2,39 @@
 callback
 
 if (foo(2) != 2)
-  error
+  error("failed");
 endif
 
 if (A_bar(2) != 4)
-  error
+  error("failed");
 endif
 
 if (foobar(3, _callback.foo) != foo(3))
-  error  
+  error("failed");
 endif
 
 if (foobar(3, foo) != foo(3))
-  error  
+  error("failed");
 endif
 
 if (foobar(3, A_bar) != A_bar(3))
-  error
+  error("failed");
 endif
 
 if (foobar(3, foof) != foof(3))
-  error
+  error("failed");
 endif
 
 if (foobar_i(3, foo_i) != foo_i(3))
-  error
+  error("failed");
 endif
 
 
 if (foobar_d(3.5, foo_d) != foo_d(3.5))
-  error
+  error("failed");
 endif
 
 a = A();
 if (foobarm(3, a, A.foom_cb_ptr) != a.foom(3))
-  error
+  error("failed");
 endif
diff --git a/Examples/test-suite/octave/catches_strings_runme.m b/Examples/test-suite/octave/catches_strings_runme.m
new file mode 100644
index 0000000..7e323cc
--- /dev/null
+++ b/Examples/test-suite/octave/catches_strings_runme.m
@@ -0,0 +1,32 @@
+# do not dump Octave core
+if exist("crash_dumps_octave_core", "builtin")
+  crash_dumps_octave_core(0);
+endif
+
+catches_strings
+
+exception_thrown = false;
+try
+  StringsThrower.charstring();
+catch e
+  if (isempty(strfind(e.message, "charstring message")))
+    error("incorrect exception message: %s", e.message)
+  endif
+  exception_thrown = true;
+end_try_catch
+if (!exception_thrown)
+  error("Should have thrown an exception");
+endif
+
+exception_thrown = false;
+try
+  StringsThrower.stdstring();
+catch e
+  if (isempty(strfind(e.message, "stdstring message")))
+    error("incorrect exception message: %s", e.message)
+  endif
+  exception_thrown = true;
+end_try_catch
+if (!exception_thrown)
+  error("Should have thrown an exception");
+endif
diff --git a/Examples/test-suite/octave/char_binary_runme.m b/Examples/test-suite/octave/char_binary_runme.m
new file mode 100644
index 0000000..e2cdb01
--- /dev/null
+++ b/Examples/test-suite/octave/char_binary_runme.m
@@ -0,0 +1,57 @@
+char_binary
+
+t = char_binary.Test();
+str = "hile";
+if (t.strlen(str) != 4)
+  disp(t.strlen(str));
+  error("bad multi-arg typemap");
+endif
+if (t.ustrlen(str) != 4)
+  disp(t.ustrlen(str));
+  error("bad multi-arg typemap");
+endif
+
+if (t.strlen("hil\000") != 4)
+  error("bad multi-arg typemap");
+endif
+if (t.ustrlen("hil\000") != 4)
+  error("bad multi-arg typemap");
+endif
+
+% creating a raw char*
+pc = new_pchar(5);
+pchar_setitem(pc, 0, 'h');
+pchar_setitem(pc, 1, 'o');
+pchar_setitem(pc, 2, 'l');
+pchar_setitem(pc, 3, 'a');
+pchar_setitem(pc, 4, 0);
+
+if (0)
+  % FIXME: Can not convert to const (SWIG_TypeError)
+  if (t.strlen(pc) != 4)
+    error("bad multi-arg typemap");
+  endif
+
+  % FIXME: Can not convert to const (SWIG_TypeError)
+  if (t.ustrlen(pc) != 4)
+    error("bad multi-arg typemap");
+  endif
+endif
+
+char_binary.var_pchar = pc;
+if (0)
+  % FIXME: could not dispatch binary operator
+  if (char_binary.var_pchar != "hola")
+    error("bad pointer case");
+  endif
+endif
+
+char_binary.var_namet = pc;
+if (0)
+  % FIXME: could not dispatch binary operator
+  if (char_binary.var_namet != "hola")
+    error("bad pointer case");
+  endif
+endif
+
+delete_pchar(pc);
diff --git a/Examples/test-suite/octave/class_ignore_runme.m b/Examples/test-suite/octave/class_ignore_runme.m
index 3e52047..53cad95 100644
--- a/Examples/test-suite/octave/class_ignore_runme.m
+++ b/Examples/test-suite/octave/class_ignore_runme.m
@@ -8,5 +8,5 @@
 a = class_ignore.Bar();
 
 if (!strcmp(class_ignore.do_blah(a),"Bar::blah"))
-    error
+    error("failed");
 endif
diff --git a/Examples/test-suite/octave/class_scope_weird_runme.m b/Examples/test-suite/octave/class_scope_weird_runme.m
index 2fc8578..b0e9753 100644
--- a/Examples/test-suite/octave/class_scope_weird_runme.m
+++ b/Examples/test-suite/octave/class_scope_weird_runme.m
@@ -3,5 +3,5 @@
 f = class_scope_weird.Foo();
 g = class_scope_weird.Foo(3);
 if (f.bar(3) != 3)
-    error
+    error("failed");
 endif
diff --git a/Examples/test-suite/octave/compactdefaultargs_runme.m b/Examples/test-suite/octave/compactdefaultargs_runme.m
index 08e8727..ada60dc 100644
--- a/Examples/test-suite/octave/compactdefaultargs_runme.m
+++ b/Examples/test-suite/octave/compactdefaultargs_runme.m
@@ -4,21 +4,21 @@
 defaults1 = Defaults1();
 
 if (defaults1.ret(10.0) != 10.0)
-  error
+  error("failed");
 endif
 
 if (defaults1.ret() != -1.0)
-  error
+  error("failed");
 endif
 
 defaults2 = Defaults2(1000);
 defaults2 = Defaults2();
 
 if (defaults2.ret(10.0) != 10.0)
-  error
+  error("failed");
 endif
 
 if (defaults2.ret() != -1.0)
-  error
+  error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/constructor_copy_runme.m b/Examples/test-suite/octave/constructor_copy_runme.m
index e450214..b6d3c3b 100644
--- a/Examples/test-suite/octave/constructor_copy_runme.m
+++ b/Examples/test-suite/octave/constructor_copy_runme.m
@@ -10,7 +10,7 @@
 
 
 if (f1.x != f11.x)
-    error
+    error("failed");
 endif
 
 
@@ -23,7 +23,7 @@
 end_try_catch
 
 if (!good)
-    error
+    error("failed");
 endif
 
 
@@ -31,7 +31,7 @@
 bc = Bari(bi);
 
 if (bi.x != bc.x)
-    error
+    error("failed");
 endif
     
 
@@ -44,6 +44,6 @@
 end_try_catch
 
 if (!good)
-    error
+    error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/cpp11_move_typemaps_runme.m b/Examples/test-suite/octave/cpp11_move_typemaps_runme.m
new file mode 100644
index 0000000..c053256
--- /dev/null
+++ b/Examples/test-suite/octave/cpp11_move_typemaps_runme.m
@@ -0,0 +1,37 @@
+# do not dump Octave core
+if exist("crash_dumps_octave_core", "builtin")
+  crash_dumps_octave_core(0);
+endif
+
+cpp11_move_typemaps
+
+Counter.reset_counts();
+mo = MoveOnly(111);
+Counter_check_counts(1, 0, 0, 0, 0, 0);
+MoveOnly.take(mo);
+Counter_check_counts(1, 0, 0, 1, 0, 2);
+clear mo;
+Counter_check_counts(1, 0, 0, 1, 0, 2);
+
+Counter.reset_counts();
+mo = MovableCopyable(111);
+Counter_check_counts(1, 0, 0, 0, 0, 0);
+MovableCopyable.take(mo);
+Counter_check_counts(1, 0, 0, 1, 0, 2);
+clear mo;
+Counter_check_counts(1, 0, 0, 1, 0, 2);
+
+mo = MoveOnly(222);
+MoveOnly.take(mo);
+exception_thrown = false;
+try
+  MoveOnly.take(mo);
+catch e
+  if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
+    error("incorrect exception message %s", e.message);
+  endif
+  exception_thrown = true;
+end_try_catch
+if (!exception_thrown)
+    error("double usage of take should have been an error");
+endif
diff --git a/Examples/test-suite/octave/cpp11_rvalue_reference_move_runme.m b/Examples/test-suite/octave/cpp11_rvalue_reference_move_runme.m
new file mode 100644
index 0000000..5be37cc
--- /dev/null
+++ b/Examples/test-suite/octave/cpp11_rvalue_reference_move_runme.m
@@ -0,0 +1,85 @@
+# do not dump Octave core
+if exist("crash_dumps_octave_core", "builtin")
+  crash_dumps_octave_core(0);
+endif
+
+cpp11_rvalue_reference_move
+
+# Function containing rvalue reference parameter
+Counter.reset_counts();
+mo = MovableCopyable(222);
+Counter.check_counts(1, 0, 0, 0, 0, 0);
+MovableCopyable.movein(mo);
+Counter.check_counts(1, 0, 0, 1, 0, 2);
+if (!MovableCopyable_is_nullptr(mo))
+  error("is_nullptr failed");
+endif
+clear mo;
+Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+# Move constructor test
+Counter.reset_counts();
+mo = MovableCopyable(222);
+Counter.check_counts(1, 0, 0, 0, 0, 0);
+mo_moved = MovableCopyable(mo);
+Counter.check_counts(1, 0, 0, 1, 0, 1);
+if (!MovableCopyable_is_nullptr(mo))
+  error("is_nullptr failed");
+endif
+clear mo;
+Counter.check_counts(1, 0, 0, 1, 0, 1);
+clear mo_moved;
+Counter.check_counts(1, 0, 0, 1, 0, 2);
+
+# Move assignment operator test
+Counter.reset_counts();
+mo111 = MovableCopyable(111);
+mo222 = MovableCopyable(222);
+Counter.check_counts(2, 0, 0, 0, 0, 0);
+mo111.MoveAssign(mo222);
+Counter.check_counts(2, 0, 0, 0, 1, 1);
+if (!MovableCopyable_is_nullptr(mo222))
+  error("is_nullptr failed");
+endif
+clear mo222;
+Counter.check_counts(2, 0, 0, 0, 1, 1);
+clear mo111;
+Counter.check_counts(2, 0, 0, 0, 1, 2);
+
+# null check
+null = []; # NULL pointer
+Counter.reset_counts();
+exception_thrown = false;
+try
+  MovableCopyable.movein(null);
+catch e
+  if (isempty(strfind(e.message, "invalid null reference")))
+    error("incorrect exception message: %s", e.message)
+  endif
+  exception_thrown = true;
+end_try_catch
+if (!exception_thrown)
+  error("Should have thrown null error");
+endif
+Counter.check_counts(0, 0, 0, 0, 0, 0);
+
+
+# output
+Counter.reset_counts();
+mc = MovableCopyable.moveout(1234);
+Counter.check_counts(2, 0, 0, 0, 1, 1);
+MovableCopyable.check_numbers_match(mc, 1234);
+
+exception_thrown = false;
+try
+  MovableCopyable.movein(mc);
+catch e
+  if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
+    error("incorrect exception message: %s", e.message)
+  endif
+  exception_thrown = true;
+end_try_catch
+if (!exception_thrown)
+  error("Should have thrown 'Cannot release ownership as memory is not owned' error");
+endif
+Counter.check_counts(2, 0, 0, 0, 1, 1);
diff --git a/Examples/test-suite/octave/cpp11_std_unique_ptr_runme.m b/Examples/test-suite/octave/cpp11_std_unique_ptr_runme.m
new file mode 100644
index 0000000..dbd4617
--- /dev/null
+++ b/Examples/test-suite/octave/cpp11_std_unique_ptr_runme.m
@@ -0,0 +1,138 @@
+# do not dump Octave core
+if exist("crash_dumps_octave_core", "builtin")
+  crash_dumps_octave_core(0);
+endif
+
+cpp11_std_unique_ptr
+
+function checkCount(expected_count)
+  actual_count = Klass_getTotal_count();
+  if (actual_count != expected_count)
+    error("Counts incorrect, expected:%d actual:%d", expected_count, actual_count);
+  endif
+end
+
+# Test raw pointer handling involving virtual inheritance
+kini = KlassInheritance("KlassInheritanceInput");
+checkCount(1);
+s = useKlassRawPtr(kini);
+if (!strcmp(s, "KlassInheritanceInput"))
+  error("Incorrect string: %s", s);
+endif
+clear kini;
+checkCount(0);
+
+
+# unique_ptr as input
+kin = Klass("KlassInput");
+checkCount(1);
+s = takeKlassUniquePtr(kin);
+checkCount(0);
+if (!strcmp(s, "KlassInput"))
+  error("Incorrect string: %s", s);
+endif
+if (!is_nullptr(kin))
+  error("is_nullptr failed");
+endif
+clear kin; # Should not fail, even though already deleted
+checkCount(0);
+
+kin = Klass("KlassInput");
+checkCount(1);
+s = takeKlassUniquePtr(kin);
+checkCount(0);
+if (!strcmp(s, "KlassInput"))
+  error("Incorrect string: %s", s);
+endif
+if (!is_nullptr(kin))
+  error("is_nullptr failed");
+endif
+exception_thrown = false;
+try
+  takeKlassUniquePtr(kin);
+catch e
+  if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
+    error("incorrect exception message %s", e.message);
+  endif
+  exception_thrown = true;
+end_try_catch
+if (!exception_thrown)
+    error("double usage of takeKlassUniquePtr should have been an error");
+endif
+clear kin; # Should not fail, even though already deleted
+checkCount(0);
+
+kin = Klass("KlassInput");
+exception_thrown = false;
+notowned = get_not_owned_ptr(kin);
+try
+  takeKlassUniquePtr(notowned);
+catch e
+  if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
+    error("incorrect exception message %s", e.message);
+  endif
+  exception_thrown = true;
+end_try_catch
+if (!exception_thrown)
+  error("Should have thrown 'Cannot release ownership as memory is not owned' error");
+endif
+checkCount(1);
+clear kin;
+checkCount(0);
+
+kini = KlassInheritance("KlassInheritanceInput");
+checkCount(1);
+s = takeKlassUniquePtr(kini);
+checkCount(0);
+if (!strcmp(s, "KlassInheritanceInput"))
+  error("Incorrect string: %s", s);
+endif
+if (!is_nullptr(kini))
+  error("is_nullptr failed");
+endif
+clear kini; # Should not fail, even though already deleted
+checkCount(0);
+
+null = []; # NULL pointer
+null_ptr = make_null();
+takeKlassUniquePtr([]);
+takeKlassUniquePtr(null);
+takeKlassUniquePtr(null_ptr);
+checkCount(0);
+
+# overloaded parameters
+if (overloadTest() != 0)
+  error("overloadTest failed");
+endif
+if (overloadTest(null) != 1)
+  error("overloadTest failed");
+endif
+if (overloadTest(Klass("over")) != 1)
+  error("overloadTest failed");
+endif
+checkCount(0);
+
+
+# unique_ptr as output
+k1 = makeKlassUniquePtr("first");
+if (!strcmp(k1.getLabel(), "first"))
+  error("wrong object label");
+endif
+
+k2 = makeKlassUniquePtr("second");
+checkCount(2);
+
+clear k1;
+checkCount(1);
+
+if (!strcmp(k2.getLabel(), "second"))
+  error("wrong object label");
+endif
+
+clear k2;
+checkCount(0);
+
+null_smart_prt = makeNullUniquePtr();
+assert(ismatrix(null_smart_prt))
+assert(size(null_smart_prt) == size([]))
+assert(isequal([], null_smart_prt))
diff --git a/Examples/test-suite/octave/default_args_runme.m b/Examples/test-suite/octave/default_args_runme.m
index 3d00f63..d2c6b4a 100644
--- a/Examples/test-suite/octave/default_args_runme.m
+++ b/Examples/test-suite/octave/default_args_runme.m
@@ -7,19 +7,19 @@
 
 
 if (default_args.Statics.staticmethod() != 60)
-  error
+  error("failed");
 endif
 
 if (default_args.cfunc1(1) != 2)
-  error
+  error("failed");
 endif
 
 if (default_args.cfunc2(1) != 3)
-  error
+  error("failed");
 endif
 
 if (default_args.cfunc3(1) != 4)
-  error
+  error("failed");
 endif
 
 
diff --git a/Examples/test-suite/octave/director_abstract_runme.m b/Examples/test-suite/octave/director_abstract_runme.m
index 657e2e1..c96cf75 100644
--- a/Examples/test-suite/octave/director_abstract_runme.m
+++ b/Examples/test-suite/octave/director_abstract_runme.m
@@ -28,17 +28,17 @@
 
 me1 = MyExample1();
 if (director_abstract.Example1.get_color(me1, 1,2,3) != 1)
-  error
+  error("failed");
 endif
 
 me2 = MyExample2(1,2);
 if (me2.get_color(me2, 1,2,3) != 2)
-  error
+  error("failed");
 endif
 
 me3 = MyExample3();
 if (me3.get_color(me3, 1,2,3) != 3)
-  error
+  error("failed");
 endif
 
 
diff --git a/Examples/test-suite/octave/director_basic_runme.m b/Examples/test-suite/octave/director_basic_runme.m
index 9de54a3..9a411a7 100644
--- a/Examples/test-suite/octave/director_basic_runme.m
+++ b/Examples/test-suite/octave/director_basic_runme.m
@@ -33,7 +33,7 @@
 a = director_basic.A1(1);
 
 if (a.rg(2) != 2)
-  error
+  error("failed");
 endif
 
 function self=OctClass()
@@ -62,16 +62,16 @@
 
 cc.method(b);
 if (c.cmethod != 7)
-  error
+  error("failed");
 endif
 
 if (bc.x != 34)
-  error
+  error("failed");
 endif
 
 
 if (bd.x != 16)
-  error
+  error("failed");
 endif
 
 
diff --git a/Examples/test-suite/octave/director_enum_runme.m b/Examples/test-suite/octave/director_enum_runme.m
index 96f158d..59a5ccf 100644
--- a/Examples/test-suite/octave/director_enum_runme.m
+++ b/Examples/test-suite/octave/director_enum_runme.m
@@ -6,5 +6,5 @@
 a = MyFoo();
 
 if (a.say_hi(director_enum.hello) != b.say_hello(director_enum.hi))
-  error
+  error("failed");
 endif
diff --git a/Examples/test-suite/octave/director_nested_runme.m b/Examples/test-suite/octave/director_nested_runme.m
index 6e1d0de..614af0c 100644
--- a/Examples/test-suite/octave/director_nested_runme.m
+++ b/Examples/test-suite/octave/director_nested_runme.m
@@ -31,9 +31,9 @@
 c.advance();
 
 if (!strcmp(c.get_name(),"FooBar::get_name hello"))
-  error
+  error("failed");
 endif
 
 if (!strcmp(c.name(),"FooBar::get_name hello"))
-  error
+  error("failed");
 endif
diff --git a/Examples/test-suite/octave/director_unroll_runme.m b/Examples/test-suite/octave/director_unroll_runme.m
index 6ca213c..607b9d5 100644
--- a/Examples/test-suite/octave/director_unroll_runme.m
+++ b/Examples/test-suite/octave/director_unroll_runme.m
@@ -11,6 +11,6 @@
 
 if (swig_this(a) != swig_this(c))
   a,c
-  error
+  error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/enum_template_runme.m b/Examples/test-suite/octave/enum_template_runme.m
index a9f940a..1474ce1 100644
--- a/Examples/test-suite/octave/enum_template_runme.m
+++ b/Examples/test-suite/octave/enum_template_runme.m
@@ -6,13 +6,13 @@
 enum_template
 
 if (enum_template.MakeETest() != 1)
-  error
+  error("failed");
 endif
 
 enum_template.TakeETest(0);
 try
   a=enum_template.TakeETest(0);
-  error
+  error("failed");
 catch
 end_try_catch
   
diff --git a/Examples/test-suite/octave/enums_runme.m b/Examples/test-suite/octave/enums_runme.m
index b654d9d..5f6bd69 100644
--- a/Examples/test-suite/octave/enums_runme.m
+++ b/Examples/test-suite/octave/enums_runme.m
@@ -6,18 +6,18 @@
 enums.bar1(1)
 
 if (enums.cvar.enumInstance != 2)
-  error
+  error("failed");
 endif
 
 if (enums.cvar.Slap != 10)
-  error
+  error("failed");
 endif
 
 if (enums.cvar.Mine != 11)
-  error
+  error("failed");
 endif
 
 if (enums.cvar.Thigh != 12)
-  error
+  error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/extend_template_ns_runme.m b/Examples/test-suite/octave/extend_template_ns_runme.m
index e79a00d..7196fac 100644
--- a/Examples/test-suite/octave/extend_template_ns_runme.m
+++ b/Examples/test-suite/octave/extend_template_ns_runme.m
@@ -7,9 +7,9 @@
 
 f = Foo_One();
 if (f.test1(37) != 37)
-    error
+    error("failed");
 endif
 
 if (f.test2(42) != 42)
-    error
+    error("failed");
 endif
diff --git a/Examples/test-suite/octave/extend_template_runme.m b/Examples/test-suite/octave/extend_template_runme.m
index 1cad7bf..125bd4a 100644
--- a/Examples/test-suite/octave/extend_template_runme.m
+++ b/Examples/test-suite/octave/extend_template_runme.m
@@ -2,9 +2,9 @@
 
 f = extend_template.Foo_0();
 if (f.test1(37) != 37)
-    error
+    error("failed");
 endif
 
 if (f.test2(42) != 42)
-    error
+    error("failed");
 endif
diff --git a/Examples/test-suite/octave/extend_variable_runme.m b/Examples/test-suite/octave/extend_variable_runme.m
index c55b6c5..89af26c 100644
--- a/Examples/test-suite/octave/extend_variable_runme.m
+++ b/Examples/test-suite/octave/extend_variable_runme.m
@@ -1,6 +1,6 @@
 extend_variable
 
 if (Foo.Bar != 42)
-    error
+    error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/friends_runme.m b/Examples/test-suite/octave/friends_runme.m
index 3121156..1b60710 100644
--- a/Examples/test-suite/octave/friends_runme.m
+++ b/Examples/test-suite/octave/friends_runme.m
@@ -8,44 +8,51 @@
 a = friends.A(2);
 
 if (friends.get_val1(a) != 2)
-  error
+  error("failed");
 endif
 if (friends.get_val2(a) != 4)
-  error
+  error("failed");
 endif
 if (friends.get_val3(a) != 6)
-  error
+  error("failed");
 endif
 
 				# nice overload working fine
 if (friends.get_val1(1,2,3) != 1)
-  error
+  error("failed");
 endif
 
 b = friends.B(3);
 
 				# David's case
 if (friends.mix(a,b) != 5)
-  error
+  error("failed");
 endif
 
-di = friends.D_d(2);
+di = friends.D_i(2);
 dd = friends.D_d(3.3);
 
 				# incredible template overloading working just fine
 if (friends.get_val1(di) != 2)
-  error
+  error("failed");
 endif
 if (friends.get_val1(dd) != 3.3)
-  error
+  error("failed");
 endif
 
 friends.set(di, 4);
 friends.set(dd, 1.3);
 
 if (friends.get_val1(di) != 4)
-  error
+  error("failed");
 endif
 if (friends.get_val1(dd) != 1.3)
-  error
+  error("failed");
+endif
+
+if (friends.chum_blah() != 1234)
+  error("failed");
+endif
+if (friends.mate_blah() != 4321)
+  error("failed");
 endif
diff --git a/Examples/test-suite/octave/grouping_runme.m b/Examples/test-suite/octave/grouping_runme.m
index 6d1a2d6..4e2c9ea 100644
--- a/Examples/test-suite/octave/grouping_runme.m
+++ b/Examples/test-suite/octave/grouping_runme.m
@@ -7,14 +7,14 @@
 
 x = grouping.test1(42);
 if (x != 42)
-    error
+    error("failed");
 endif
 
 grouping.test2(42);
 
 x = (grouping.do_unary(37, grouping.NEGATE));
 if (x != -37)
-    error
+    error("failed");
 endif
 
 grouping.cvar.test3 = 42;
diff --git a/Examples/test-suite/octave/iadd_runme.m b/Examples/test-suite/octave/iadd_runme.m
index c386c66..70cd75d 100644
--- a/Examples/test-suite/octave/iadd_runme.m
+++ b/Examples/test-suite/octave/iadd_runme.m
@@ -6,5 +6,5 @@
 f.AsA += f.AsA;
 
 if (f.AsA.x != 6)
-    error
+    error("failed");
 endif
diff --git a/Examples/test-suite/octave/inout_runme.m b/Examples/test-suite/octave/inout_runme.m
index 74caaff..c5d293e 100644
--- a/Examples/test-suite/octave/inout_runme.m
+++ b/Examples/test-suite/octave/inout_runme.m
@@ -2,26 +2,26 @@
 
 a = inout.AddOne1(1);
 if (a != 2)
-  error
+  error("failed");
 endif
 
 a = inout.AddOne3(1,1,1);
 if (a != [2,2,2])
-  error
+  error("failed");
 endif
 
 a = inout.AddOne1p((1,1));
 if (a != (2,2))
-  error
+  error("failed");
 endif
 
 a = inout.AddOne2p((1,1),1);
 if (a != [(2,2),2])
-  error
+  error("failed");
 endif
 
 a = inout.AddOne3p(1,(1,1),1);
 if (a != [2,(2,2),2])
-  error
+  error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/inplaceadd_runme.m b/Examples/test-suite/octave/inplaceadd_runme.m
index 2bc1937..50b680a 100644
--- a/Examples/test-suite/octave/inplaceadd_runme.m
+++ b/Examples/test-suite/octave/inplaceadd_runme.m
@@ -3,22 +3,22 @@
 
 a += 5;
 if (a.val != 12)
-  error
+  error("failed");
 endif
 
 a -= 5;
 if a.val != 7:
-  error
+  error("failed");
 endif
 
 a *= 2;
 
 if (a.val != 14)
-  error
+  error("failed");
 endif
 
 a += a;
 if (a.val != 28)
-  error
+  error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/input_runme.m b/Examples/test-suite/octave/input_runme.m
index 1a92d03..477ffaa 100644
--- a/Examples/test-suite/octave/input_runme.m
+++ b/Examples/test-suite/octave/input_runme.m
@@ -7,21 +7,21 @@
 
 f = Foo();
 if (f.foo(2) != 4)
-  error
+  error("failed");
 endif
 
 try
   a=f.foo();
-  error
+  error("failed");
 catch
 end_try_catch
 
 if (!strcmp(sfoo("Hello"),"Hello world"))
-  error
+  error("failed");
 endif
 
 try
   a=sfoo();
-  error
+  error("failed");
 catch
 end_try_catch
diff --git a/Examples/test-suite/octave/li_attribute_runme.m b/Examples/test-suite/octave/li_attribute_runme.m
index ed051d9..5e23904 100644
--- a/Examples/test-suite/octave/li_attribute_runme.m
+++ b/Examples/test-suite/octave/li_attribute_runme.m
@@ -8,7 +8,7 @@
 aa = li_attribute.A(1,2,3);
 
 if (aa.a != 1)
-  error
+  error("failed");
 endif
 aa.a = 3;
 if (aa.a != 3)
@@ -20,31 +20,31 @@
 endif
 aa.b = 5;
 if (aa.b != 5)
-  error
+  error("failed");
 endif
 
 if (aa.d != aa.b)
-  error
+  error("failed");
 endif
 
 if (aa.c != 3)
-  error
+  error("failed");
 endif
 
 pi = li_attribute.Param_i(7);
 if (pi.value != 7)
- error
+ error("failed");
 endif
 
 pi.value=3;
 if (pi.value != 3)
- error
+ error("failed");
 endif
 
 b = li_attribute.B(aa);
 
 if (b.a.c != 3)
- error
+ error("failed");
 endif
 
 # class/struct attribute with get/set methods using return/pass by reference
@@ -53,38 +53,38 @@
 myClass = li_attribute.MyClass();
 myClass.Foo = myFoo;
 if (myClass.Foo.x != 8)
-  error
+  error("failed");
 endif
 
 # class/struct attribute with get/set methods using return/pass by value
 myClassVal = li_attribute.MyClassVal();
 if (myClassVal.ReadWriteFoo.x != -1)
-  error
+  error("failed");
 endif
 if (myClassVal.ReadOnlyFoo.x != -1)
-  error
+  error("failed");
 endif
 myClassVal.ReadWriteFoo = myFoo;
 if (myClassVal.ReadWriteFoo.x != 8)
-  error
+  error("failed");
 endif
 if (myClassVal.ReadOnlyFoo.x != 8)
-  error
+  error("failed");
 endif
 
 # string attribute with get/set methods using return/pass by value
 myStringyClass = li_attribute.MyStringyClass("initial string");
 if (myStringyClass.ReadWriteString != "initial string")
-  error
+  error("failed");
 endif
 if (myStringyClass.ReadOnlyString != "initial string")
-  error
+  error("failed");
 endif
 myStringyClass.ReadWriteString = "changed string";
 if (myStringyClass.ReadWriteString != "changed string")
-  error
+  error("failed");
 endif
 if (myStringyClass.ReadOnlyString != "changed string")
-  error
+  error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/li_carrays_cpp_runme.m b/Examples/test-suite/octave/li_carrays_cpp_runme.m
index b3b5209..57e3e9a 100644
--- a/Examples/test-suite/octave/li_carrays_cpp_runme.m
+++ b/Examples/test-suite/octave/li_carrays_cpp_runme.m
@@ -11,5 +11,5 @@
 d(5) = d(0) + 3;
 
 if (d(5) + d(0) != 17)
-    error
+    error("failed");
 endif
diff --git a/Examples/test-suite/octave/li_carrays_runme.m b/Examples/test-suite/octave/li_carrays_runme.m
index c6b5f16..5f180cc 100644
--- a/Examples/test-suite/octave/li_carrays_runme.m
+++ b/Examples/test-suite/octave/li_carrays_runme.m
@@ -11,5 +11,5 @@
 d(5) = d(0) + 3;
 
 if (d(5) + d(0) != 17)
-    error
+    error("failed");
 endif
diff --git a/Examples/test-suite/octave/li_cmalloc_runme.m b/Examples/test-suite/octave/li_cmalloc_runme.m
index 92bcd95..5daea2c 100644
--- a/Examples/test-suite/octave/li_cmalloc_runme.m
+++ b/Examples/test-suite/octave/li_cmalloc_runme.m
@@ -17,6 +17,6 @@
 end_try_catch
 
 if (ok != 1)
-    error
+    error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/li_constraints_runme.m b/Examples/test-suite/octave/li_constraints_runme.m
new file mode 100644
index 0000000..eaea571
--- /dev/null
+++ b/Examples/test-suite/octave/li_constraints_runme.m
@@ -0,0 +1,62 @@
+li_constraints
+
+function check_double(except, f, val, name)
+  actual = true;
+  proper = false;
+  try
+    f(val);
+  catch
+    actual = false;
+    proper = strcmp(lasterr, ["Expected a ", name , " value. (SWIG_ValueError)"]) == 1;
+  end
+  if (actual)
+    if (!except)
+      error(["function '", name, "' with ", num2str(val), " should perform an exception"]);
+    end
+  else
+    if (except)
+      error(["function '", name, "' with ", num2str(val), " should not perform an exception"]);
+    elseif (!proper)
+      error(["function '", name, "' with ", num2str(val), " should perform a proper exception"]);
+    end
+  end
+end
+
+function nonnegative(x);global li_constraints;li_constraints.test_nonnegative(x);end
+check_double(true, @nonnegative, 10, "non-negative");
+check_double(true, @nonnegative, 0, "non-negative");
+check_double(false, @nonnegative, -10, "non-negative");
+
+function nonpositive(x);global li_constraints;li_constraints.test_nonpositive(x);end
+check_double(false, @nonpositive, 10, "non-positive");
+check_double(true, @nonpositive, 0, "non-positive");
+check_double(true, @nonpositive, -10, "non-positive");
+
+function positive(x);global li_constraints;li_constraints.test_positive(x);end
+check_double(true, @positive, 10, "positive");
+check_double(false, @positive, 0, "positive");
+check_double(false, @positive, -10, "positive");
+
+function negative(x);global li_constraints;li_constraints.test_negative(x);end
+check_double(false, @negative, 10, "negative");
+check_double(false, @negative, 0, "negative");
+check_double(true, @negative, -10, "negative");
+
+function nonzero(x);global li_constraints;li_constraints.test_nonzero(x);end
+check_double(true, @nonzero, 10, "nonzero");
+check_double(false, @nonzero, 0, "nonzero");
+check_double(true, @nonzero, -10, "nonzero");
+
+have_exception = false;
+try
+  # Empty matrix translate to null pointer
+  li_constraints.test_nonnull([]);
+catch
+  have_exception = strcmp("Received a NULL pointer. (SWIG_ValueError)", lasterr) == 1;
+end
+if (!have_exception)
+    error("test_nonnull should perform exception with 'null' value");
+end
+
+nonnull = li_constraints.get_nonnull();
+li_constraints.test_nonnull(nonnull);
diff --git a/Examples/test-suite/octave/li_cpointer_cpp_runme.m b/Examples/test-suite/octave/li_cpointer_cpp_runme.m
index 463cf44..3551a17 100644
--- a/Examples/test-suite/octave/li_cpointer_cpp_runme.m
+++ b/Examples/test-suite/octave/li_cpointer_cpp_runme.m
@@ -5,7 +5,7 @@
 intp_assign(p,3);
 
 if (intp_value(p) != 3)
-    error
+    error("failed");
 endif
 
 delete_intp(p);
diff --git a/Examples/test-suite/octave/li_cpointer_runme.m b/Examples/test-suite/octave/li_cpointer_runme.m
index ce055cd..995cc2a 100644
--- a/Examples/test-suite/octave/li_cpointer_runme.m
+++ b/Examples/test-suite/octave/li_cpointer_runme.m
@@ -10,7 +10,7 @@
 intp_assign(p,3);
 
 if (intp_value(p) != 3)
-    error
+    error("failed");
 endif
 
 delete_intp(p);
diff --git a/Examples/test-suite/octave/li_cstring_runme.m b/Examples/test-suite/octave/li_cstring_runme.m
index 8aea6b7..4a706d3 100644
--- a/Examples/test-suite/octave/li_cstring_runme.m
+++ b/Examples/test-suite/octave/li_cstring_runme.m
@@ -7,15 +7,15 @@
 
 
 if (count("ab\0ab\0ab\0", 0) != 3)
-    error    
+    error("failed");
 endif
 
 if (!strcmp(test1(),"Hello World"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(test2()," !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(test3("hello"),"hello-suffix"))
@@ -27,18 +27,18 @@
 endif
     
 if (!strcmp(test5(4),'xxxx'))
-    error
+    error("failed");
 endif
 
 if (!strcmp(test6(10),'xxxxx'))
-    error
+    error("failed");
 endif
     
 if (!strcmp(test7(),"Hello world!"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(test8()," !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_"))
-    error
+    error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/li_cwstring_runme.m b/Examples/test-suite/octave/li_cwstring_runme.m
index 1fb0962..5b90551 100644
--- a/Examples/test-suite/octave/li_cwstring_runme.m
+++ b/Examples/test-suite/octave/li_cwstring_runme.m
@@ -6,38 +6,38 @@
 li_cwstring
 
 if (count("ab\0ab\0ab\0", 0) != 3)
-    error    
+    error("failed");
 endif
 
 if (!strcmp(test1(),"Hello World"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(test2()," !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(test3("hello"),"hello-suffix"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(test4("hello"),"hello-suffix"))
-    error
+    error("failed");
 endif
     
 if (!strcmp(test5(4),'xxxx'))
-    error
+    error("failed");
 endif
 
 if (!strcmp(test6(10),'xxxxx'))
-    error
+    error("failed");
 endif
     
 if (!strcmp(test7(),"Hello world!"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(test8()," !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_"))
-    error
+    error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/li_factory_runme.m b/Examples/test-suite/octave/li_factory_runme.m
index 5ea9b77..7c07825 100644
--- a/Examples/test-suite/octave/li_factory_runme.m
+++ b/Examples/test-suite/octave/li_factory_runme.m
@@ -8,11 +8,11 @@
 circle = Geometry_create(Geometry.CIRCLE);
 r = circle.radius();
 if (r != 1.5)
-  error
+  error("failed");
 endif
 
 point = Geometry_create(Geometry.POINT);
 w = point.width();
 if (w != 1.0)
-  error
+  error("failed");
 endif
diff --git a/Examples/test-suite/octave/li_std_auto_ptr_runme.m b/Examples/test-suite/octave/li_std_auto_ptr_runme.m
new file mode 100644
index 0000000..9f0dd16
--- /dev/null
+++ b/Examples/test-suite/octave/li_std_auto_ptr_runme.m
@@ -0,0 +1,138 @@
+# do not dump Octave core
+if exist("crash_dumps_octave_core", "builtin")
+  crash_dumps_octave_core(0);
+endif
+
+li_std_auto_ptr
+
+function checkCount(expected_count)
+  actual_count = Klass_getTotal_count();
+  if (actual_count != expected_count)
+    error("Counts incorrect, expected:%d actual:%d", expected_count, actual_count);
+  endif
+end
+
+# Test raw pointer handling involving virtual inheritance
+kini = KlassInheritance("KlassInheritanceInput");
+checkCount(1);
+s = useKlassRawPtr(kini);
+if (!strcmp(s, "KlassInheritanceInput"))
+  error("Incorrect string: %s", s);
+endif
+clear kini;
+checkCount(0);
+
+
+# auto_ptr as input
+kin = Klass("KlassInput");
+checkCount(1);
+s = takeKlassAutoPtr(kin);
+checkCount(0);
+if (!strcmp(s, "KlassInput"))
+  error("Incorrect string: %s", s);
+endif
+if (!is_nullptr(kin))
+  error("is_nullptr failed");
+endif
+clear kin; # Should not fail, even though already deleted
+checkCount(0);
+
+kin = Klass("KlassInput");
+checkCount(1);
+s = takeKlassAutoPtr(kin);
+checkCount(0);
+if (!strcmp(s, "KlassInput"))
+  error("Incorrect string: %s", s);
+endif
+if (!is_nullptr(kin))
+  error("is_nullptr failed");
+endif
+exception_thrown = false;
+try
+  takeKlassAutoPtr(kin);
+catch e
+  if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
+    error("incorrect exception message %s", e.message);
+  endif
+  exception_thrown = true;
+end_try_catch
+if (!exception_thrown)
+    error("double usage of takeKlassAutoPtr should have been an error");
+endif
+clear kin; # Should not fail, even though already deleted
+checkCount(0);
+
+kin = Klass("KlassInput");
+exception_thrown = false;
+notowned = get_not_owned_ptr(kin);
+try
+  takeKlassAutoPtr(notowned);
+catch e
+  if (isempty(strfind(e.message, "cannot release ownership as memory is not owned")))
+    error("incorrect exception message %s", e.message);
+  endif
+  exception_thrown = true;
+end_try_catch
+if (!exception_thrown)
+  error("Should have thrown 'Cannot release ownership as memory is not owned' error");
+endif
+checkCount(1);
+clear kin;
+checkCount(0);
+
+kini = KlassInheritance("KlassInheritanceInput");
+checkCount(1);
+s = takeKlassAutoPtr(kini);
+checkCount(0);
+if (!strcmp(s, "KlassInheritanceInput"))
+  error("Incorrect string: %s", s);
+endif
+if (!is_nullptr(kini))
+  error("is_nullptr failed");
+endif
+clear kini; # Should not fail, even though already deleted
+checkCount(0);
+
+null = []; # NULL pointer
+null_ptr = make_null();
+takeKlassAutoPtr([]);
+takeKlassAutoPtr(null);
+takeKlassAutoPtr(null_ptr);
+checkCount(0);
+
+# overloaded parameters
+if (overloadTest() != 0)
+  error("overloadTest failed");
+endif
+if (overloadTest(null) != 1)
+  error("overloadTest failed");
+endif
+if (overloadTest(Klass("over")) != 1)
+  error("overloadTest failed");
+endif
+checkCount(0);
+
+
+# auto_ptr as output
+k1 = makeKlassAutoPtr("first");
+if (!strcmp(k1.getLabel(), "first"))
+  error("wrong object label");
+endif
+
+k2 = makeKlassAutoPtr("second");
+checkCount(2);
+
+clear k1;
+checkCount(1);
+
+if (!strcmp(k2.getLabel(), "second"))
+  error("wrong object label");
+endif
+
+clear k2;
+checkCount(0);
+
+null_smart_prt = makeNullAutoPtr();
+assert(ismatrix(null_smart_prt))
+assert(size(null_smart_prt) == size([]))
+assert(isequal([], null_smart_prt))
diff --git a/Examples/test-suite/octave/li_std_carray_runme.m b/Examples/test-suite/octave/li_std_carray_runme.m
deleted file mode 100644
index 4943fa8..0000000
--- a/Examples/test-suite/octave/li_std_carray_runme.m
+++ /dev/null
@@ -1,52 +0,0 @@
-li_std_carray
-
-
-v3 = Vector3();
-for i=0:len(v3),
-    v3(i) = i;
-endfor
-
-i = 0;
-for d in v3,
-  if (d != i)
-    error
-  endif
-  i = i + 1;
-endfor
-
-
-m3 = Matrix3();
-
-for i=0:len(m3),
-  v3 = m3(i);
-  for j=0:len(v3),
-    v3(j) = i + j;
-  endfor
-endfor
-
-i = 0;
-for v3 in m3,
-  j = 0;
-  for d in v3,
-    if (d != i + j)
-      error
-    endif
-    j = j + 1;
-  endfor
-  i = i + 1
-endfor
-
-for i=0:len(m3),
-  for j=0:len(m3),
-    if (m3(i,j) != i + j)
-      error
-    endif
-  endfor
-endfor
-
-da = Vector3([1,2,3]);
-ma = Matrix3({[1,2,3],[4,5,6],[7,8,9]});
-
-
-
-
diff --git a/Examples/test-suite/octave/li_std_set_runme.m b/Examples/test-suite/octave/li_std_set_runme.m
index 9bd4f15..7f43f2f 100644
--- a/Examples/test-suite/octave/li_std_set_runme.m
+++ b/Examples/test-suite/octave/li_std_set_runme.m
@@ -11,15 +11,15 @@
     sum = sum + i
 
 if (sum != "abc")
-    error
+    error("failed");
 
 i = s.__iter__()
 if i.next() != "a":
-    error
+    error("failed");
 if i.next() != "b":
-    error
+    error("failed");
 if i.next() != "c":
-    error
+    error("failed");
 
 
 b = s.begin()
@@ -28,7 +28,7 @@
 while (b != e):    
     sum = sum + b.next()
 if sum != "abc":
-    error
+    error("failed");
 
 b = s.rbegin()
 e = s.rend()
@@ -37,7 +37,7 @@
     sum = sum  + b.next()
 
 if sum != "cba":
-    error
+    error("failed");
 
 
 
@@ -49,11 +49,11 @@
 i = si.__iter__()
 
 if i.next() != 1:
-    error
+    error("failed");
 if i.next() != 2:
-    error
+    error("failed");
 if i.next() != 3:
-    error
+    error("failed");
 
 
 
@@ -68,17 +68,17 @@
 while (b != e):    
     sum = sum + b.next()
 if sum != "ac":
-    error
+    error("failed");
 
 
 b = s.begin()
 e = s.end()
 if e - b != 2:
-    error
+    error("failed");
     
 m = b + 1
 if m.value() != "c":
-    error
+    error("failed");
 
 
 
@@ -93,4 +93,4 @@
     sum = sum  + (i,)
 
 if sum != (1, 'hello', (1, 2)):
-    error
+    error("failed");
diff --git a/Examples/test-suite/octave/li_std_stream_runme.m b/Examples/test-suite/octave/li_std_stream_runme.m
index bf9402e..cedc8e5 100644
--- a/Examples/test-suite/octave/li_std_stream_runme.m
+++ b/Examples/test-suite/octave/li_std_stream_runme.m
@@ -8,6 +8,6 @@
 
 
 if (o.str() !=  "A class 2345 1.435")
-  error
+  error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/li_std_string_extra_runme.m b/Examples/test-suite/octave/li_std_string_extra_runme.m
index 8d506af..15e18ee 100644
--- a/Examples/test-suite/octave/li_std_string_extra_runme.m
+++ b/Examples/test-suite/octave/li_std_string_extra_runme.m
@@ -140,23 +140,23 @@
 
 
 if (li_std_string_extra.test_reference_input("hello") != "hello")
-  error
+  error("failed");
 endif
 s = li_std_string_extra.test_reference_inout("hello");
 if (s != "hellohello")
-  error
+  error("failed");
 endif
 
 
 if (li_std_string_extra.stdstring_empty() != "")
-  error
+  error("failed");
 endif
 
 
 if (li_std_string_extra.c_empty() != "")
-  error
+  error("failed");
 endif
 
 #if (li_std_string_extra.c_null() != None)
-#  error
+#  error("failed");
 #endif
diff --git a/Examples/test-suite/octave/li_std_wstream_runme.m b/Examples/test-suite/octave/li_std_wstream_runme.m
index a017e8a..4f1c621 100644
--- a/Examples/test-suite/octave/li_std_wstream_runme.m
+++ b/Examples/test-suite/octave/li_std_wstream_runme.m
@@ -9,6 +9,6 @@
 o << a << u" " << 2345 << u" " << 1.435 << wends;
 
 if (o.str() !=  "A class 2345 1.435\0")
-  error
+  error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/multi_import_runme.m b/Examples/test-suite/octave/multi_import_runme.m
index 2b7a610..d22ff5c 100644
--- a/Examples/test-suite/octave/multi_import_runme.m
+++ b/Examples/test-suite/octave/multi_import_runme.m
@@ -8,22 +8,22 @@
 
 x = multi_import_b.XXX();
 if (x.testx() != 0)
-  error
+  error("failed");
 endif
 
 y = multi_import_b.YYY();
 if (y.testx() != 0)
-  error
+  error("failed");
 endif
 if (y.testy() != 1)
-  error
+  error("failed");
 endif
 
 z = multi_import_a.ZZZ();
 if (z.testx() != 0)
-  error
+  error("failed");
 endif
 if (z.testz() != 2)
-  error
+  error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/namespace_typemap_runme.m b/Examples/test-suite/octave/namespace_typemap_runme.m
index ca37307..d7e3381 100644
--- a/Examples/test-suite/octave/namespace_typemap_runme.m
+++ b/Examples/test-suite/octave/namespace_typemap_runme.m
@@ -1,106 +1,106 @@
 namespace_typemap
 
 if (!strcmp(stest1("hello"),"hello"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(stest2("hello"),"hello"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(stest3("hello"),"hello"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(stest4("hello"),"hello"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(stest5("hello"),"hello"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(stest6("hello"),"hello"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(stest7("hello"),"hello"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(stest8("hello"),"hello"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(stest9("hello"),"hello"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(stest10("hello"),"hello"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(stest11("hello"),"hello"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(stest12("hello"),"hello"))
-    error
+    error("failed");
 endif
 
 c = complex(2,3);
 r = real(c);
 
 if (ctest1(c) != r)
-    error
+    error("failed");
 endif
 
 if (ctest2(c) != r)
-    error
+    error("failed");
 endif
 
 if (ctest3(c) != r)
-    error
+    error("failed");
 endif
 
 if (ctest4(c) != r)
-    error
+    error("failed");
 endif
 
 if (ctest5(c) != r)
-    error
+    error("failed");
 endif
 
 if (ctest6(c) != r)
-    error
+    error("failed");
 endif
 
 if (ctest7(c) != r)
-    error
+    error("failed");
 endif
 
 if (ctest8(c) != r)
-    error
+    error("failed");
 endif
 
 if (ctest9(c) != r)
-    error
+    error("failed");
 endif
 
 if (ctest10(c) != r)
-    error
+    error("failed");
 endif
 
 if (ctest11(c) != r)
-    error
+    error("failed");
 endif
 
 if (ctest12(c) != r)
-    error
+    error("failed");
 endif
 
 try
     ttest1(-14)
-    error
+    error("failed");
 catch
 end_try_catch
diff --git a/Examples/test-suite/octave/naturalvar_runme.m b/Examples/test-suite/octave/naturalvar_runme.m
index 6059b02..40546f2 100644
--- a/Examples/test-suite/octave/naturalvar_runme.m
+++ b/Examples/test-suite/octave/naturalvar_runme.m
@@ -14,6 +14,6 @@
 b.s = "hello";
 
 if (b.s != cvar.s)
-    error
+    error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/null_pointer_runme.m b/Examples/test-suite/octave/null_pointer_runme.m
index 72362f4..7a49d37 100644
--- a/Examples/test-suite/octave/null_pointer_runme.m
+++ b/Examples/test-suite/octave/null_pointer_runme.m
@@ -6,3 +6,13 @@
 null_pointer;
 
 assert(funk([]));
+null_ptr = getnull();
+assert(ismatrix(null_ptr))
+assert(size(null_ptr) == size([]))
+assert(isequal([], null_ptr))
+
+# Can't use isnull as a test due to null matrix not being copyable...
+#   n = []
+#   isnull(n) # ans = 0
+#   isnull([]) # ans = 1
+#   isnull(getnull()) # ans = 0
diff --git a/Examples/test-suite/octave/overload_extend2_runme.m b/Examples/test-suite/octave/overload_extend2_runme.m
index 6db6b66..e461194 100644
--- a/Examples/test-suite/octave/overload_extend2_runme.m
+++ b/Examples/test-suite/octave/overload_extend2_runme.m
@@ -2,29 +2,29 @@
 
 f = overload_extend2.Foo();
 if (f.test(3) != 1)
-    error
+    error("failed");
 endif
 if (f.test("hello") != 2)
-    error
+    error("failed");
 endif
 if (f.test(3.5,2.5) != 3)
-    error
+    error("failed");
 endif
 if (f.test("hello",20) != 1020)
-    error
+    error("failed");
 endif
 if (f.test("hello",20,100) != 120)
-    error
+    error("failed");
 endif
 
 # C default args
 if (f.test(f) != 30)
-    error
+    error("failed");
 endif
 if (f.test(f,100) != 120)
-    error
+    error("failed");
 endif
 if (f.test(f,100,200) != 300)
-    error
+    error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/overload_extend_c_runme.m b/Examples/test-suite/octave/overload_extend_c_runme.m
index 79b92ca..2a6c5c2 100644
--- a/Examples/test-suite/octave/overload_extend_c_runme.m
+++ b/Examples/test-suite/octave/overload_extend_c_runme.m
@@ -7,18 +7,18 @@
 
 f = overload_extend_c.Foo();
 if (f.test() != 0)
-    error
+    error("failed");
 endif
 if (f.test(3) != 1)
-    error
+    error("failed");
 endif
 if (f.test("hello") != 2)
-    error
+    error("failed");
 endif
 if (f.test(3,2) != 5)
-    error
+    error("failed");
 endif
 if (f.test(3.1)-.1 != 1003) # :)
-    error
+    error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/overload_extend_runme.m b/Examples/test-suite/octave/overload_extend_runme.m
index d995980..a29f191 100644
--- a/Examples/test-suite/octave/overload_extend_runme.m
+++ b/Examples/test-suite/octave/overload_extend_runme.m
@@ -7,18 +7,18 @@
 
 f = overload_extend.Foo();
 if (f.test() != 0)
-    error
+    error("failed");
 endif
 if (f.test(3) != 1)
-    error
+    error("failed");
 endif
 if (f.test("hello") != 2)
-    error
+    error("failed");
 endif
 if (f.test(3,2) != 5)
-    error
+    error("failed");
 endif
 if (f.test(3.1)-.1 != 1003) # :)
-    error
+    error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/overload_null_runme.m b/Examples/test-suite/octave/overload_null_runme.m
index a7c346c..83c11a1 100644
--- a/Examples/test-suite/octave/overload_null_runme.m
+++ b/Examples/test-suite/octave/overload_null_runme.m
@@ -40,13 +40,13 @@
 check(15, o.byval2cpr(null));
 check(16, o.byval2cpr(x));
 
-# forward class declaration
-check(17, o.byval1forwardptr(x));
-check(18, o.byval1forwardptr(null));
+# fwd class declaration
+check(17, o.byval1fwdptr(x));
+check(18, o.byval1fwdptr(null));
 
-check(19, o.byval2forwardptr(null));
-check(20, o.byval2forwardptr(x));
+check(19, o.byval2fwdptr(null));
+check(20, o.byval2fwdptr(x));
 
-check(21, o.byval1forwardref(x));
+check(21, o.byval1fwdref(x));
 
-check(22, o.byval2forwardref(x));
+check(22, o.byval2fwdref(x));
diff --git a/Examples/test-suite/octave/preproc_runme.m b/Examples/test-suite/octave/preproc_runme.m
index e9af66e..80f1d32 100644
--- a/Examples/test-suite/octave/preproc_runme.m
+++ b/Examples/test-suite/octave/preproc_runme.m
@@ -6,18 +6,18 @@
 preproc
 
 if (preproc.cvar.endif != 1)
-  error
+  error("failed");
 endif
 
 if (preproc.cvar.define != 1)
-  error
+  error("failed");
 endif
 
 if (preproc.cvar.defined != 1)
-  error
+  error("failed");
 endif
 
 if (2*preproc.one != preproc.two)
-  error
+  error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/primitive_ref_runme.m b/Examples/test-suite/octave/primitive_ref_runme.m
index 68a5750..799b6db 100644
--- a/Examples/test-suite/octave/primitive_ref_runme.m
+++ b/Examples/test-suite/octave/primitive_ref_runme.m
@@ -1,53 +1,53 @@
 primitive_ref
 
 if (ref_int(3) != 3)
-    error
+    error("failed");
 endif
 
 if (ref_uint(3) != 3)
-    error
+    error("failed");
 endif
 
 if (ref_short(3) != 3)
-    error
+    error("failed");
 endif
 
 if (ref_ushort(3) != 3)
-    error
+    error("failed");
 endif
 
 if (ref_long(3) != 3)
-    error
+    error("failed");
 endif
 
 if (ref_ulong(3) != 3)
-    error
+    error("failed");
 endif
 
 if (ref_schar(3) != 3)
-    error
+    error("failed");
 endif
 
 if (ref_uchar(3) != 3)
-    error
+    error("failed");
 endif
 
 if (ref_float(3.5) != 3.5)
-    error
+    error("failed");
 endif
 
 if (ref_double(3.5) != 3.5)
-    error
+    error("failed");
 endif
 
 if (ref_bool(true) != true)
-    error
+    error("failed");
 endif
 
 if (!strcmp(ref_char('x'),'x'))
-    error
+    error("failed");
 endif
 
 if (ref_over(0) != 0)
-    error
+    error("failed");
 endif
diff --git a/Examples/test-suite/octave/reference_global_vars_runme.m b/Examples/test-suite/octave/reference_global_vars_runme.m
index 67ad9c5..c7f4f56 100644
--- a/Examples/test-suite/octave/reference_global_vars_runme.m
+++ b/Examples/test-suite/octave/reference_global_vars_runme.m
@@ -2,90 +2,90 @@
 
 # const class reference variable
 if (getconstTC().num != 33)
-    error
+    error("failed");
 endif
 
 # primitive reference variables
 cvar.var_bool = createref_bool(false);
 if (value_bool(cvar.var_bool) != 0)
-    error
+    error("failed");
 endif
 
 cvar.var_bool = createref_bool(true);
 if (value_bool(cvar.var_bool) != 1)
-    error
+    error("failed");
 endif
 
 cvar.var_char = createref_char('w');
 if (!strcmp(value_char(cvar.var_char),'w'))
-    error
+    error("failed");
 endif
 
 cvar.var_unsigned_char = createref_unsigned_char(10);
 if (value_unsigned_char(cvar.var_unsigned_char) != 10)
-    error
+    error("failed");
 endif
 
 cvar.var_signed_char = createref_signed_char(10);
 if (value_signed_char(cvar.var_signed_char) != 10)
-    error
+    error("failed");
 endif
 
 cvar.var_short = createref_short(10);
 if (value_short(cvar.var_short) != 10)
-    error
+    error("failed");
 endif
 
 cvar.var_unsigned_short = createref_unsigned_short(10);
 if (value_unsigned_short(cvar.var_unsigned_short) != 10)
-    error
+    error("failed");
 endif
 
 cvar.var_int = createref_int(10);
 if (value_int(cvar.var_int) != 10)
-    error
+    error("failed");
 endif
 
 cvar.var_unsigned_int = createref_unsigned_int(10);
 if (value_unsigned_int(cvar.var_unsigned_int) != 10)
-    error
+    error("failed");
 endif
 
 cvar.var_long = createref_long(10);
 if (value_long(cvar.var_long) != 10)
-    error
+    error("failed");
 endif
 
 cvar.var_unsigned_long = createref_unsigned_long(10);
 if (value_unsigned_long(cvar.var_unsigned_long) != 10)
-    error
+    error("failed");
 endif
 
 cvar.var_long_long = createref_long_long(int64(0x6FFFFFFFFFFFFFF8));
 if (value_long_long(cvar.var_long_long) != int64(0x6FFFFFFFFFFFFFF8))
-    error
+    error("failed");
 endif
 
 #ull = abs(0xFFFFFFF2FFFFFFF0)
 ull = uint64(55834574864);
 cvar.var_unsigned_long_long = createref_unsigned_long_long(ull);
 if (value_unsigned_long_long(cvar.var_unsigned_long_long) != ull)
-    error
+    error("failed");
 endif
 
 cvar.var_float = createref_float(10.5);
 if (value_float(cvar.var_float) != 10.5)
-    error
+    error("failed");
 endif
 
 cvar.var_double = createref_double(10.5);
 if (value_double(cvar.var_double) != 10.5)
-    error
+    error("failed");
 endif
 
 # class reference variable
 cvar.var_TestClass = createref_TestClass(TestClass(20));
 if (value_TestClass(cvar.var_TestClass).num != 20)
-    error
+    error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/rename_scope_runme.m b/Examples/test-suite/octave/rename_scope_runme.m
index 154f99d..776d218 100644
--- a/Examples/test-suite/octave/rename_scope_runme.m
+++ b/Examples/test-suite/octave/rename_scope_runme.m
@@ -4,11 +4,11 @@
 b = Natural_BP();
 
 if (a.rtest() != 1)
-    error
+    error("failed");
 endif
 
 if (b.rtest() != 1)
-    error
+    error("failed");
 endif
 
 f = @equals;
diff --git a/Examples/test-suite/octave/ret_by_value_runme.m b/Examples/test-suite/octave/ret_by_value_runme.m
index 67f80aa..c1c5083 100644
--- a/Examples/test-suite/octave/ret_by_value_runme.m
+++ b/Examples/test-suite/octave/ret_by_value_runme.m
@@ -7,9 +7,9 @@
 
 a = ret_by_value.get_test();
 if (a.myInt != 100)
-    error
+    error("failed");
 endif
 
 if (a.myShort != 200)
-    error
+    error("failed");
 endif
diff --git a/Examples/test-suite/octave/smart_pointer_extend_runme.m b/Examples/test-suite/octave/smart_pointer_extend_runme.m
index 6c9258e..cf82f73 100644
--- a/Examples/test-suite/octave/smart_pointer_extend_runme.m
+++ b/Examples/test-suite/octave/smart_pointer_extend_runme.m
@@ -9,7 +9,7 @@
 b = Bar(f);
 
 if (b.extension() != f.extension())
-  error
+  error("failed");
 endif
 
 
@@ -18,15 +18,15 @@
 p = CPtr();
 
 if (b.bar() != p.bar())
-  error
+  error("failed");
 endif
 
 if (d.foo() != p.foo())
-  error
+  error("failed");
 endif
 
 if (b.hello() != p.hello())
-  error
+  error("failed");
 endif
 
 
@@ -36,11 +36,11 @@
 dp = DPtrFoo(d);
 
 if (d.SExt(1) != dp.SExt(1))
-  error
+  error("failed");
 endif
 
 if (d.Ext(1) != dp.Ext(1))
-  error
+  error("failed");
 endif
 
   
diff --git a/Examples/test-suite/octave/smart_pointer_member_runme.m b/Examples/test-suite/octave/smart_pointer_member_runme.m
index 30251c3..1c2d0e9 100644
--- a/Examples/test-suite/octave/smart_pointer_member_runme.m
+++ b/Examples/test-suite/octave/smart_pointer_member_runme.m
@@ -4,7 +4,7 @@
 f.y = 1;
 
 if (f.y != 1)
-  error
+  error("failed");
 endif
 
 b = Bar(f);
@@ -15,18 +15,18 @@
 endif
 
 if (swig_this(b.x) != swig_this(f.x))
-  error
+  error("failed");
 endif
 
 if (b.z != f.z)
-  error
+  error("failed");
 endif
 
 try
   if (Foo.z == Bar.z)
-    error
+    error("failed");
   endif
-    error
+    error("failed");
 catch
 end_try_catch
 
diff --git a/Examples/test-suite/octave/smart_pointer_multi_runme.m b/Examples/test-suite/octave/smart_pointer_multi_runme.m
index 71ef910..ea15d04 100644
--- a/Examples/test-suite/octave/smart_pointer_multi_runme.m
+++ b/Examples/test-suite/octave/smart_pointer_multi_runme.m
@@ -7,11 +7,11 @@
 
 s.x = 3;
 if (s.getx() != 3)
-    error
+    error("failed");
 endif
 
 g.x = 4;
 if (g.getx() != 4)
-    error
+    error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/smart_pointer_multi_typedef_runme.m b/Examples/test-suite/octave/smart_pointer_multi_typedef_runme.m
index 4b77e0e..c2ab787 100644
--- a/Examples/test-suite/octave/smart_pointer_multi_typedef_runme.m
+++ b/Examples/test-suite/octave/smart_pointer_multi_typedef_runme.m
@@ -7,12 +7,12 @@
 
 s.x = 3;
 if (s.getx() != 3)
-    error
+    error("failed");
 endif
 
 g.x = 4;
 if (g.getx() != 4)
-    error
+    error("failed");
 endif
 
 
diff --git a/Examples/test-suite/octave/smart_pointer_overload_runme.m b/Examples/test-suite/octave/smart_pointer_overload_runme.m
index a5df0de..1bfb683 100644
--- a/Examples/test-suite/octave/smart_pointer_overload_runme.m
+++ b/Examples/test-suite/octave/smart_pointer_overload_runme.m
@@ -10,23 +10,23 @@
 
 
 if (f.test(3) != 1)
-    error
+    error("failed");
 endif
 if (f.test(3.5) != 2)
-    error
+    error("failed");
 endif
 if (f.test("hello") != 3)
-    error
+    error("failed");
 endif
 
 if (b.test(3) != 1)
-    error
+    error("failed");
 endif
 if (b.test(3.5) != 2)
-    error
+    error("failed");
 endif
 if (b.test("hello") != 3)
-    error
+    error("failed");
 endif
 
 
diff --git a/Examples/test-suite/octave/smart_pointer_rename_runme.m b/Examples/test-suite/octave/smart_pointer_rename_runme.m
index 5eb6d4c..307bd8f 100644
--- a/Examples/test-suite/octave/smart_pointer_rename_runme.m
+++ b/Examples/test-suite/octave/smart_pointer_rename_runme.m
@@ -9,14 +9,14 @@
 b = Bar(f);
 
 if (b.test() != 3)
-    error
+    error("failed");
 endif
 
 if (b.ftest1(1) != 1)
-    error
+    error("failed");
 endif
 
 if (b.ftest2(2,3) != 2)
-    error
+    error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/smart_pointer_simple_runme.m b/Examples/test-suite/octave/smart_pointer_simple_runme.m
index 30b1387..c15c43c 100644
--- a/Examples/test-suite/octave/smart_pointer_simple_runme.m
+++ b/Examples/test-suite/octave/smart_pointer_simple_runme.m
@@ -10,11 +10,11 @@
 
 b.x = 3;
 if (b.getx() != 3)
-    error
+    error("failed");
 endif
 
 fp = b.__deref__();
 fp.x = 4;
 if (fp.getx() != 4)
-    error
+    error("failed");
 endif
diff --git a/Examples/test-suite/octave/smart_pointer_templatevariables_runme.m b/Examples/test-suite/octave/smart_pointer_templatevariables_runme.m
index 4884fa2..ee45f68 100644
--- a/Examples/test-suite/octave/smart_pointer_templatevariables_runme.m
+++ b/Examples/test-suite/octave/smart_pointer_templatevariables_runme.m
@@ -3,17 +3,17 @@
 d = DiffImContainerPtr_D(create(1234, 5678));
 
 if (d.id != 1234)
-  error
+  error("failed");
 endif
 #if (d.xyz != 5678):
-#  error
+#  error("failed");
 
 d.id = 4321;
 #d.xyz = 8765
 
 if (d.id != 4321)
-  error
+  error("failed");
 endif
 #if (d.xyz != 8765):
-#  error
+#  error("failed");
 
diff --git a/Examples/test-suite/octave/smart_pointer_typedef_runme.m b/Examples/test-suite/octave/smart_pointer_typedef_runme.m
index 0e1c8a6..3a09467 100644
--- a/Examples/test-suite/octave/smart_pointer_typedef_runme.m
+++ b/Examples/test-suite/octave/smart_pointer_typedef_runme.m
@@ -10,11 +10,11 @@
 
 b.x = 3;
 if (b.getx() != 3)
-    error
+    error("failed");
 endif
 
 fp = b.__deref__();
 fp.x = 4;
 if (fp.getx() != 4)
-    error
+    error("failed");
 endif
diff --git a/Examples/test-suite/octave/static_const_member_2_runme.m b/Examples/test-suite/octave/static_const_member_2_runme.m
index 73260ba..8619fd1 100644
--- a/Examples/test-suite/octave/static_const_member_2_runme.m
+++ b/Examples/test-suite/octave/static_const_member_2_runme.m
@@ -18,6 +18,6 @@
 
 
 if (Foo.BAZ.val != 2*Foo.BAR.val)
-    error
+    error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/std_containers_runme.m b/Examples/test-suite/octave/std_containers_runme.m
index eae3d5d..d069b58 100644
--- a/Examples/test-suite/octave/std_containers_runme.m
+++ b/Examples/test-suite/octave/std_containers_runme.m
@@ -132,7 +132,7 @@
 j=1;
 for i in s,
   if (i != j)
-    error
+    error("failed");
   endif
   j = j + 1;
 endfor
diff --git a/Examples/test-suite/octave/struct_value_runme.m b/Examples/test-suite/octave/struct_value_runme.m
index ff34404..7f7448b 100644
--- a/Examples/test-suite/octave/struct_value_runme.m
+++ b/Examples/test-suite/octave/struct_value_runme.m
@@ -9,10 +9,10 @@
 
 b.a.x = 3;
 if (b.a.x != 3)
-  error
+  error("failed");
 endif
 
 b.b.x = 3;
 if (b.b.x != 3)
-  error
+  error("failed");
 endif
diff --git a/Examples/test-suite/octave/swigobject_runme.m b/Examples/test-suite/octave/swigobject_runme.m
index 73167e4..9ab3aa8 100644
--- a/Examples/test-suite/octave/swigobject_runme.m
+++ b/Examples/test-suite/octave/swigobject_runme.m
@@ -11,7 +11,7 @@
 a2 = a_ptr(a);
 
 if (swig_this(a1) != swig_this(a2))
-  error
+  error("failed");
 endif
   
 
@@ -20,7 +20,7 @@
 xstr2 = pointer_str(a);
 
 if (xstr1 != xstr2)
-  error
+  error("failed");
 endif
 
 s = str(a.this);
@@ -29,5 +29,5 @@
 v1 = v_ptr(a);
 v2 = v_ptr(a);
 if (uint64(v1) != uint64(v2))
-  error
+  error("failed");
 endif
diff --git a/Examples/test-suite/octave/template_extend1_runme.m b/Examples/test-suite/octave/template_extend1_runme.m
index 5035deb..05e5341 100644
--- a/Examples/test-suite/octave/template_extend1_runme.m
+++ b/Examples/test-suite/octave/template_extend1_runme.m
@@ -9,9 +9,9 @@
 b = template_extend1.dBaz();
 
 if (!strcmp(a.foo(),"lBaz::foo"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(b.foo(),"dBaz::foo"))
-    error
+    error("failed");
 endif
diff --git a/Examples/test-suite/octave/template_extend2_runme.m b/Examples/test-suite/octave/template_extend2_runme.m
index 24472a9..e9b5fb7 100644
--- a/Examples/test-suite/octave/template_extend2_runme.m
+++ b/Examples/test-suite/octave/template_extend2_runme.m
@@ -9,9 +9,9 @@
 b = template_extend2.dBaz();
 
 if (!strcmp(a.foo(),"lBaz::foo"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(b.foo(),"dBaz::foo"))
-    error
+    error("failed");
 endif
diff --git a/Examples/test-suite/octave/template_inherit_runme.m b/Examples/test-suite/octave/template_inherit_runme.m
index 368cce2..72d7e75 100644
--- a/Examples/test-suite/octave/template_inherit_runme.m
+++ b/Examples/test-suite/octave/template_inherit_runme.m
@@ -12,62 +12,62 @@
 f = BarUInt();
 
 if (!strcmp(a.blah(),"Foo"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(b.blah(),"Foo"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(e.blah(),"Foo"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(c.blah(),"Bar"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(d.blah(),"Bar"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(f.blah(),"Bar"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(c.foomethod(),"foomethod"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(d.foomethod(),"foomethod"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(f.foomethod(),"foomethod"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(invoke_blah_int(a),"Foo"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(invoke_blah_int(c),"Bar"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(invoke_blah_double(b),"Foo"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(invoke_blah_double(d),"Bar"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(invoke_blah_uint(e),"Foo"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(invoke_blah_uint(f),"Bar"))
-    error
+    error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/template_ns4_runme.m b/Examples/test-suite/octave/template_ns4_runme.m
index b574642..6dff556 100644
--- a/Examples/test-suite/octave/template_ns4_runme.m
+++ b/Examples/test-suite/octave/template_ns4_runme.m
@@ -7,5 +7,5 @@
 
 d = make_Class_DD();
 if (!strcmp(d.test(),"test"))
-  error
+  error("failed");
 endif
diff --git a/Examples/test-suite/octave/template_ns_runme.m b/Examples/test-suite/octave/template_ns_runme.m
index 29a2f53..44b13e6 100644
--- a/Examples/test-suite/octave/template_ns_runme.m
+++ b/Examples/test-suite/octave/template_ns_runme.m
@@ -3,19 +3,19 @@
 p2 = pairii(p1);
 
 if (p2.first != 2)
-    error
+    error("failed");
 endif
 if (p2.second != 3)
-    error
+    error("failed");
 endif
 
 p3 = pairdd(3.5,2.5);
 p4 = pairdd(p3);
 
 if (p4.first != 3.5)
-    error
+    error("failed");
 endif
 
 if (p4.second != 2.5)
-    error
+    error("failed");
 endif
diff --git a/Examples/test-suite/octave/template_tbase_template_runme.m b/Examples/test-suite/octave/template_tbase_template_runme.m
index da8ec4c..b1bfd8f7 100644
--- a/Examples/test-suite/octave/template_tbase_template_runme.m
+++ b/Examples/test-suite/octave/template_tbase_template_runme.m
@@ -2,5 +2,5 @@
 
 a = make_Class_dd();
 if (!strcmp(a.test(),"test"))
-  error
+  error("failed");
 endif
diff --git a/Examples/test-suite/octave/template_typedef_cplx2_runme.m b/Examples/test-suite/octave/template_typedef_cplx2_runme.m
index a72e0f1..eb783fe 100644
--- a/Examples/test-suite/octave/template_typedef_cplx2_runme.m
+++ b/Examples/test-suite/octave/template_typedef_cplx2_runme.m
@@ -15,7 +15,7 @@
 if (strfind('ArithUnaryFunction',swig_type(d)) != 1)
   d
   error("is not an ArithUnaryFunction")
-  error
+  error("failed");
 endif
 
 try
@@ -77,7 +77,7 @@
 if (strfind('ArithUnaryFunction',swig_type(g)) != 1)
   g
   error("is not an ArithUnaryFunction")
-  error
+  error("failed");
 endif
 
 
@@ -98,6 +98,6 @@
   a = g.get_value();
 catch
   error(g, "has not get_value() method")
-  error
+  error("failed");
 end_try_catch
 
diff --git a/Examples/test-suite/octave/template_typedef_runme.m b/Examples/test-suite/octave/template_typedef_runme.m
index 8d8af79..2a734e2 100644
--- a/Examples/test-suite/octave/template_typedef_runme.m
+++ b/Examples/test-suite/octave/template_typedef_runme.m
@@ -8,7 +8,7 @@
   a = swig_this(d);
   a = swig_this(c);
 catch
-  error
+  error("failed");
 end_try_catch
 
 try
@@ -37,15 +37,15 @@
 
 # the old large format
 if (strcmp("<unknown>",swig_typequery("vfncs::ArithUnaryFunction<vfncs::arith_traits<float,double>::argument_type,vfncs::arith_traits<float,double >::result_type > *")))
-  error
+  error("failed");
 endif
 
 # the reduced format
 if (strcmp("<unknown>",swig_typequery("vfncs::ArithUnaryFunction<double,double> *")))
-  error
+  error("failed");
 endif
 
 # this is a bad name
 if (!strcmp("<unknown>",swig_typequery("vfncs::ArithUnaryFunction<double,doublex> *")))
-  error
+  error("failed");
 endif
diff --git a/Examples/test-suite/octave/typedef_inherit_runme.m b/Examples/test-suite/octave/typedef_inherit_runme.m
index fbe5436..b562e31 100644
--- a/Examples/test-suite/octave/typedef_inherit_runme.m
+++ b/Examples/test-suite/octave/typedef_inherit_runme.m
@@ -30,3 +30,8 @@
 if (!strcmp(x,"Grok::blah"))
     error("Whoa! Bad return", x)
 endif
+
+x = d.far();
+if (!strcmp(x,"Spam::far"))
+    error("Whoa! Bad return", x)
+endif
diff --git a/Examples/test-suite/octave/typemap_namespace_runme.m b/Examples/test-suite/octave/typemap_namespace_runme.m
index ec62a39..e67781c 100644
--- a/Examples/test-suite/octave/typemap_namespace_runme.m
+++ b/Examples/test-suite/octave/typemap_namespace_runme.m
@@ -1,10 +1,10 @@
 typemap_namespace
 
 if (!strcmp(test1("hello"),"hello"))
-    error
+    error("failed");
 endif
 
 if (!strcmp(test2("hello"),"hello"))
-    error
+    error("failed");
 endif
 
diff --git a/Examples/test-suite/octave/typemap_ns_using_runme.m b/Examples/test-suite/octave/typemap_ns_using_runme.m
index dd3f657..d94241b 100644
--- a/Examples/test-suite/octave/typemap_ns_using_runme.m
+++ b/Examples/test-suite/octave/typemap_ns_using_runme.m
@@ -1,5 +1,5 @@
 typemap_ns_using
 
 if (typemap_ns_using.spam(37) != 37)
-    error
+    error("failed");
 endif
diff --git a/Examples/test-suite/octave/types_directive_runme.m b/Examples/test-suite/octave/types_directive_runme.m
index 0757c6c..5ad4af1 100644
--- a/Examples/test-suite/octave/types_directive_runme.m
+++ b/Examples/test-suite/octave/types_directive_runme.m
@@ -3,13 +3,13 @@
 d1 = Time1(2001, 2, 3, 60);
 newDate = add(d1, 7); # check that a Time1 instance is accepted where Date is expected
 if (newDate.day != 10)
-  error
+  error("failed");
 endif
 
 d2 = Time2(1999, 8, 7, 60);
 newDate = add(d2, 7); # check that a Time2 instance is accepted where Date is expected
 if (newDate.day != 14)
-  error
+  error("failed");
 endif
 
 
diff --git a/Examples/test-suite/octave/using1_runme.m b/Examples/test-suite/octave/using1_runme.m
index 9253a1d..e25128e 100644
--- a/Examples/test-suite/octave/using1_runme.m
+++ b/Examples/test-suite/octave/using1_runme.m
@@ -6,5 +6,5 @@
 using1
 
 if (using1.spam(37) != 37)
-    error
+    error("failed");
 endif
diff --git a/Examples/test-suite/octave/using2_runme.m b/Examples/test-suite/octave/using2_runme.m
index 7cc6689..0213ee7 100644
--- a/Examples/test-suite/octave/using2_runme.m
+++ b/Examples/test-suite/octave/using2_runme.m
@@ -6,5 +6,5 @@
 using2
 
 if (using2.spam(37) != 37)
-    error
+    error("failed");
 endif
diff --git a/Examples/test-suite/octave/virtual_poly_runme.m b/Examples/test-suite/octave/virtual_poly_runme.m
index 0c7c951..363f867 100644
--- a/Examples/test-suite/octave/virtual_poly_runme.m
+++ b/Examples/test-suite/octave/virtual_poly_runme.m
@@ -10,23 +10,23 @@
 ic = i.copy();
 
 if (d.get() != dc.get())
-  error
+  error("failed");
 endif
 
 if (i.get() != ic.get())
-  error
+  error("failed");
 endif
 
 virtual_poly.incr(ic);
 
 if ((i.get() + 1) != ic.get())
-  error
+  error("failed");
 endif
 
 
 dr = d.ref_this();
 if (d.get() != dr.get())
-  error
+  error("failed");
 endif
 
 
@@ -35,10 +35,10 @@
 #
 ddc = virtual_poly.NDouble_narrow(d.nnumber());
 if (d.get() != ddc.get())
-  error
+  error("failed");
 endif
 
 dic = virtual_poly.NInt_narrow(i.nnumber());
 if (i.get() != dic.get())
-  error
+  error("failed");
 endif
diff --git a/Examples/test-suite/octave/voidtest_runme.m b/Examples/test-suite/octave/voidtest_runme.m
index fb411ee..c4815a5 100644
--- a/Examples/test-suite/octave/voidtest_runme.m
+++ b/Examples/test-suite/octave/voidtest_runme.m
@@ -27,16 +27,16 @@
 v1 = voidtest.vfunc1(f);
 v2 = voidtest.vfunc2(f);
 if (swig_this(v1) != swig_this(v2))
-    error
+    error("failed");
 endif
 
 v3 = voidtest.vfunc3(v1);
 if (swig_this(v3) != swig_this(f))
-    error
+    error("failed");
 endif
 v4 = voidtest.vfunc1(f);
 if (swig_this(v4) != swig_this(v1))
-    error
+    error("failed");
 endif
 
 
diff --git a/Examples/test-suite/operator_overload.i b/Examples/test-suite/operator_overload.i
index af884e5..cfbced8 100644
--- a/Examples/test-suite/operator_overload.i
+++ b/Examples/test-suite/operator_overload.i
@@ -69,6 +69,7 @@
 #endif
 
 #ifdef SWIGPHP
+// "And" and "Or" can't be used as function names in PHP.
 %rename(AndOperator) operator &&;
 %rename(OrOperator) operator ||;
 #endif
@@ -78,8 +79,8 @@
 #endif
 
 #ifdef SWIGD
-// Due to the way operator overloading is implemented in D1 and D2, the prefix
-// increment/decrement operators (D1) resp. the postfix ones (D2) are ignored. 
+// Due to the way operator overloading is implemented in D2, the postfix
+// increment/decrement operators are ignored.
 %warnfilter(SWIGWARN_IGNORE_OPERATOR_PLUSPLUS, SWIGWARN_IGNORE_OPERATOR_MINUSMINUS);
 #endif
 
@@ -174,25 +175,24 @@
   Op operator-(const Op& a,const Op& b){return Op(a.i-b.i);}
 %}
 
-// in order to wrapper this correctly
-// we need to extend the class
+// in order to wrap this correctly we need to extend the class
 // to make the friends & non members part of the class
-%extend Op{
-        Op operator &&(const Op& b){return Op($self->i&&b.i);}
-        Op operator or(const Op& b){return Op($self->i||b.i);}
+%extend Op {
+        Op operator &&(const Op& b){return *$self && b;}
+        Op operator or(const Op& b){return  *self || b;}
 
-	Op operator+(const Op& b){return Op($self->i+b.i);}
-	Op operator-(const Op& b){return Op($self->i-b.i);}
-	Op operator*(const Op& b){return Op($self->i*b.i);}
-	Op operator/(const Op& b){return Op($self->i/b.i);}
-	Op operator%(const Op& b){return Op($self->i%b.i);}
+	Op operator+(const Op& b){return *$self + b;}
+	Op operator-(const Op& b){return *$self - b;}
+	Op operator*(const Op& b){return *$self * b;}
+	Op operator/(const Op& b){return *$self / b;}
+	Op operator%(const Op& b){return *$self % b;}
 
-	bool operator==(const Op& b){return $self->i==b.i;}
-	bool operator!=(const Op& b){return $self->i!=b.i;}
-	bool operator< (const Op& b){return $self->i<b.i;}
-	bool operator<=(const Op& b){return $self->i<=b.i;}
-	bool operator> (const Op& b){return $self->i>b.i;}
-	bool operator>=(const Op& b){return $self->i>=b.i;}
+	bool operator==(const Op& b){return *$self == b;}
+	bool operator!=(const Op& b){return *$self != b;}
+	bool operator< (const Op& b){return *$self <  b;}
+	bool operator<=(const Op& b){return *$self <= b;}
+	bool operator> (const Op& b){return *$self >  b;}
+	bool operator>=(const Op& b){return *$self >= b;}
 
 	// subtraction with reversed arguments
 	Op __rsub__(const int b){return Op(b - $self->i);}
diff --git a/Examples/test-suite/operator_overload_break.i b/Examples/test-suite/operator_overload_break.i
index a948f2d..809498f 100644
--- a/Examples/test-suite/operator_overload_break.i
+++ b/Examples/test-suite/operator_overload_break.i
@@ -18,6 +18,7 @@
 
 %{
 #include <iostream>
+#include <stdlib.h>
 using namespace std;
 %}
 
diff --git a/Examples/test-suite/operator_pointer_ref.i b/Examples/test-suite/operator_pointer_ref.i
index 84182da..cd4ed2d 100644
--- a/Examples/test-suite/operator_pointer_ref.i
+++ b/Examples/test-suite/operator_pointer_ref.i
@@ -4,6 +4,8 @@
 #if defined(_MSC_VER)
   #pragma warning(disable: 4996) // 'strdup': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _strdup. See online help for details.
 #endif
+#include <string.h>
+#include <stdlib.h>
 %}
 
 %rename(AsCharStarRef) operator char*&;
diff --git a/Examples/test-suite/overload_arrays.i b/Examples/test-suite/overload_arrays.i
index 272c96a..e6bd09a 100644
--- a/Examples/test-suite/overload_arrays.i
+++ b/Examples/test-suite/overload_arrays.i
@@ -2,10 +2,6 @@
 // Based on overload_simple testcase
 %module overload_arrays
 
-#ifdef SWIGCHICKEN
-%warnfilter(SWIGWARN_LANG_OVERLOAD_SHADOW) fbool;
-#endif
-
 #ifdef SWIGLUA
 // lua only has one numeric type, so most of the overloads shadow each other creating warnings
 %warnfilter(SWIGWARN_LANG_OVERLOAD_SHADOW) foo;
diff --git a/Examples/test-suite/overload_extend.i b/Examples/test-suite/overload_extend.i
index acabdd5..7a5c03b 100644
--- a/Examples/test-suite/overload_extend.i
+++ b/Examples/test-suite/overload_extend.i
@@ -5,7 +5,7 @@
 #include <stdlib.h>
 %}
 
-%typemap(default) double y "$1=1000;";
+%typemap(default) double y "$1=1000;"
 #endif
 
 #ifdef SWIGLUA
diff --git a/Examples/test-suite/overload_extend2.i b/Examples/test-suite/overload_extend2.i
index f917386..ded1e5e 100644
--- a/Examples/test-suite/overload_extend2.i
+++ b/Examples/test-suite/overload_extend2.i
@@ -1,6 +1,6 @@
 %module overload_extend2
 
-%typemap(default) int int2 "$1=1000;";
+%typemap(default) int int2 "$1=1000;"
 
 %inline %{
 typedef struct Foo {
diff --git a/Examples/test-suite/overload_null.i b/Examples/test-suite/overload_null.i
index d4879fd..0ec9703 100644
--- a/Examples/test-suite/overload_null.i
+++ b/Examples/test-suite/overload_null.i
@@ -35,18 +35,18 @@
   int byval2cpr(Y*const& y) { return 15; }
   int byval2cpr(X x) { return 16; }
 
-  // forward class declaration
-  int byval1forwardptr(X x) { return 17; }
-  int byval1forwardptr(F* f) { return 18; }
+  // fwd class declaration
+  int byval1fwdptr(X x) { return 17; }
+  int byval1fwdptr(F* f) { return 18; }
 
-  int byval2forwardptr(F* f) { return 19; }
-  int byval2forwardptr(X x) { return 20; }
+  int byval2fwdptr(F* f) { return 19; }
+  int byval2fwdptr(X x) { return 20; }
 
-  int byval1forwardref(X x) { return 21; }
-  int byval1forwardref(F& f) { return -21; }
+  int byval1fwdref(X x) { return 21; }
+  int byval1fwdref(F& f) { return -21; }
 
-  int byval2forwardref(F& f) { return -22; }
-  int byval2forwardref(X x) { return 22; }
+  int byval2fwdref(F& f) { return -22; }
+  int byval2fwdref(X x) { return 22; }
 
 };
 %}
diff --git a/Examples/test-suite/overload_polymorphic.i b/Examples/test-suite/overload_polymorphic.i
index ac004f9..72aabd8 100644
--- a/Examples/test-suite/overload_polymorphic.i
+++ b/Examples/test-suite/overload_polymorphic.i
@@ -23,4 +23,7 @@
 int test2(Unknown* unknown) { return 0; }
 int test2(Base* base) { return 1; }
 
+int test3(const char*, const Base* = 0, bool = false) { return 0; }
+int test3(Base&, const char* = 0, const Base* = 0, bool = false) { return 1; }
+
 %}
diff --git a/Examples/test-suite/overload_simple.i b/Examples/test-suite/overload_simple.i
index ba1900b..b2a794e 100644
--- a/Examples/test-suite/overload_simple.i
+++ b/Examples/test-suite/overload_simple.i
@@ -1,10 +1,6 @@
 // Simple tests of overloaded functions
 %module overload_simple
 
-#ifdef SWIGCHICKEN
-%warnfilter(SWIGWARN_LANG_OVERLOAD_SHADOW) fbool;
-#endif
-
 #ifdef SWIGLUA
 // lua only has one numeric type, so most of the overloads shadow each other creating warnings
 %warnfilter(SWIGWARN_LANG_OVERLOAD_SHADOW) foo;
@@ -170,10 +166,17 @@
 %}
 
 %inline %{
-unsigned long long ull() { return 0ULL; }
-unsigned long long ull(unsigned long long ull) { return ull; }
-long long ll() { return 0LL; }
-long long ll(long long ull) { return ull; }
+int sizeof_long() { return sizeof(long); }
+
+unsigned long as_ul() { return 0UL; }
+unsigned long as_ul(unsigned long ul) { return ul; }
+long as_l() { return 0L; }
+long as_l(long l) { return l; }
+
+unsigned long long as_ull() { return 0ULL; }
+unsigned long long as_ull(unsigned long long ull) { return ull; }
+long long as_ll() { return 0LL; }
+long long as_ll(long long ll) { return ll; }
 %}
 
 %include cmalloc.i
diff --git a/Examples/test-suite/perl5/Makefile.in b/Examples/test-suite/perl5/Makefile.in
index 48d5fa5..688b985 100644
--- a/Examples/test-suite/perl5/Makefile.in
+++ b/Examples/test-suite/perl5/Makefile.in
@@ -7,6 +7,10 @@
 SCRIPTSUFFIX = _runme.pl
 TEST_RUNNER  = $(srcdir)/run-perl-test.pl
 
+HAVE_CXX11   = @HAVE_CXX11@
+HAVE_CXX14   = @HAVE_CXX14@
+HAVE_CXX17   = @HAVE_CXX17@
+HAVE_CXX20   = @HAVE_CXX20@
 srcdir       = @srcdir@
 top_srcdir   = @top_srcdir@
 top_builddir = @top_builddir@
@@ -16,11 +20,13 @@
 	li_cstring \
 	li_cdata_carrays_cpp \
 	li_reference \
+	memberin1 \
 	director_nestedmodule \
 
 C_TEST_CASES += \
 	li_cstring \
 	li_cdata_carrays \
+	multivalue \
 
 include $(srcdir)/../common.mk
 
diff --git a/Examples/test-suite/perl5/argcargvtest_runme.pl b/Examples/test-suite/perl5/argcargvtest_runme.pl
new file mode 100644
index 0000000..ccc570f
--- /dev/null
+++ b/Examples/test-suite/perl5/argcargvtest_runme.pl
@@ -0,0 +1,35 @@
+use strict;
+use warnings;
+use Test::More tests => 17;
+BEGIN { use_ok('argcargvtest') }
+require_ok('argcargvtest');
+
+my $largs = ["hi", "hola", "hello"];
+is(argcargvtest::mainc($largs), 3, "test main typemap 1");
+
+my $targs = ["hi", "hola"];
+is(argcargvtest::mainv($targs, 0), "hi", "test main typemap 2a");
+is(argcargvtest::mainv($targs, 1), "hola", "test main typemap 2b");
+is(argcargvtest::mainv($targs, 2), "<<NULL>>", "test main typemap 2c");
+
+my $errorVal = 0;
+my $ret = eval qq(argcargvtest::mainv("hello", 1); \$errorVal = 1;);
+is($ret, undef, "test main typemap 3");
+is($errorVal, 0, "test main typemap 4");
+
+is(argcargvtest::initializeApp($largs), undef, "test main typemap 5");
+
+# Check that an empty array works.
+my @empty_args = ();
+is(argcargvtest::mainc(\@empty_args), 0, "test main typemap 6");
+is(argcargvtest::mainv(\@empty_args, 0), "<<NULL>>", "test main typemap 6a");
+
+# Check that empty strings are handled.
+my @empty_string = ("hello", "", "world");
+is(argcargvtest::mainc(\@empty_string), 3, "test main typemap 7");
+is(argcargvtest::mainv(\@empty_string, 0), "hello", "test main typemap 8a");
+is(argcargvtest::mainv(\@empty_string, 1), "", "test main typemap 8b");
+is(argcargvtest::mainv(\@empty_string, 2), "world", "test main typemap 8c");
+is(argcargvtest::mainv(\@empty_string, 3), "<<NULL>>", "test main typemap 8d");
+
+ok(1, "done");
diff --git a/Examples/test-suite/perl5/catches_strings_runme.pl b/Examples/test-suite/perl5/catches_strings_runme.pl
new file mode 100644
index 0000000..742b5bc
--- /dev/null
+++ b/Examples/test-suite/perl5/catches_strings_runme.pl
@@ -0,0 +1,15 @@
+use strict;
+use warnings;
+use Test::More tests => 4;
+BEGIN { use_ok('catches_strings') }
+require_ok('catches_strings');
+
+eval {
+  catches_strings::StringsThrower::charstring();
+};
+like($@, qr/\bcharstring message/, "Should have thrown an exception");
+
+eval {
+  catches_strings::StringsThrower::stdstring();
+};
+like($@, qr/\bstdstring message/, "Should have thrown an exception");
diff --git a/Examples/test-suite/perl5/cpp11_move_typemaps_runme.pl b/Examples/test-suite/perl5/cpp11_move_typemaps_runme.pl
new file mode 100644
index 0000000..aae3e4d
--- /dev/null
+++ b/Examples/test-suite/perl5/cpp11_move_typemaps_runme.pl
@@ -0,0 +1,34 @@
+use strict;
+use warnings;
+use Test::More tests => 3;
+BEGIN { use_ok('cpp11_move_typemaps') }
+require_ok('cpp11_move_typemaps');
+
+{
+  cpp11_move_typemaps::Counter::reset_counts();
+  my $mo = new cpp11_move_typemaps::MoveOnly(111);
+  cpp11_move_typemaps::Counter::check_counts(1, 0, 0, 0, 0, 0);
+  cpp11_move_typemaps::MoveOnly::take($mo);
+  cpp11_move_typemaps::Counter::check_counts(1, 0, 0, 1, 0, 2);
+  undef $mo;
+}
+cpp11_move_typemaps::Counter::check_counts(1, 0, 0, 1, 0, 2);
+
+{
+  cpp11_move_typemaps::Counter::reset_counts();
+  my $mo = new cpp11_move_typemaps::MovableCopyable(111);
+  cpp11_move_typemaps::Counter::check_counts(1, 0, 0, 0, 0, 0);
+  cpp11_move_typemaps::MovableCopyable::take($mo);
+  cpp11_move_typemaps::Counter::check_counts(1, 0, 0, 1, 0, 2);
+  undef $mo;
+}
+cpp11_move_typemaps::Counter::check_counts(1, 0, 0, 1, 0, 2);
+
+{
+  my $mo = new cpp11_move_typemaps::MoveOnly(222);
+  cpp11_move_typemaps::MoveOnly::take($mo);
+  eval {
+    cpp11_move_typemaps::MoveOnly::take($mo);
+  };
+  like($@, qr/\bcannot release ownership as memory is not owned\b/, "double usage of takeKlassUniquePtr should be an error");
+}
diff --git a/Examples/test-suite/perl5/cpp11_rvalue_reference_move_runme.pl b/Examples/test-suite/perl5/cpp11_rvalue_reference_move_runme.pl
new file mode 100644
index 0000000..756691d
--- /dev/null
+++ b/Examples/test-suite/perl5/cpp11_rvalue_reference_move_runme.pl
@@ -0,0 +1,70 @@
+use strict;
+use warnings;
+use Test::More tests => 7;
+BEGIN { use_ok('cpp11_rvalue_reference_move') }
+require_ok('cpp11_rvalue_reference_move');
+
+{
+  # Function containing rvalue reference parameter
+  cpp11_rvalue_reference_move::Counter::reset_counts();
+  my $mo = new cpp11_rvalue_reference_move::MovableCopyable(222);
+  cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 0, 0, 0);
+  cpp11_rvalue_reference_move::MovableCopyable::movein($mo);
+  cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 1, 0, 2);
+  is(cpp11_rvalue_reference_move::MovableCopyable::is_nullptr($mo), 1, "is_nullptr check");
+  undef $mo;
+  cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 1, 0, 2);
+}
+
+{
+  # Move constructor test
+  cpp11_rvalue_reference_move::Counter::reset_counts();
+  my $mo = new cpp11_rvalue_reference_move::MovableCopyable(222);
+  cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 0, 0, 0);
+  my $mo_moved = new cpp11_rvalue_reference_move::MovableCopyable($mo);
+  cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 1, 0, 1);
+  is(cpp11_rvalue_reference_move::MovableCopyable::is_nullptr($mo), 1, "is_nullptr check");
+  undef $mo;
+  cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 1, 0, 1);
+  undef $mo_moved;
+  cpp11_rvalue_reference_move::Counter::check_counts(1, 0, 0, 1, 0, 2);
+}
+
+{
+  # Move assignment operator test
+  cpp11_rvalue_reference_move::Counter::reset_counts();
+  my $mo111 = new cpp11_rvalue_reference_move::MovableCopyable(111);
+  my $mo222 = new cpp11_rvalue_reference_move::MovableCopyable(222);
+  cpp11_rvalue_reference_move::Counter::check_counts(2, 0, 0, 0, 0, 0);
+  $mo111->MoveAssign($mo222);
+  cpp11_rvalue_reference_move::Counter::check_counts(2, 0, 0, 0, 1, 1);
+  is(cpp11_rvalue_reference_move::MovableCopyable::is_nullptr($mo222), 1, "is_nullptr check");
+  undef $mo222;
+  cpp11_rvalue_reference_move::Counter::check_counts(2, 0, 0, 0, 1, 1);
+  undef $mo111;
+  cpp11_rvalue_reference_move::Counter::check_counts(2, 0, 0, 0, 1, 2);
+}
+
+{
+  # null check
+  cpp11_rvalue_reference_move::Counter::reset_counts();
+  eval {
+    cpp11_rvalue_reference_move::MovableCopyable::movein(undef);
+  };
+  like($@, qr/\binvalid null reference/, "Should have thrown null error");
+  cpp11_rvalue_reference_move::Counter::check_counts(0, 0, 0, 0, 0, 0);
+}
+
+{
+  # output
+  cpp11_rvalue_reference_move::Counter::reset_counts();
+  my $mc = cpp11_rvalue_reference_move::MovableCopyable::moveout(1234);
+  cpp11_rvalue_reference_move::Counter::check_counts(2, 0, 0, 0, 1, 1);
+  cpp11_rvalue_reference_move::MovableCopyable::check_numbers_match($mc, 1234);
+
+  eval {
+    cpp11_rvalue_reference_move::MovableCopyable::movein($mc);
+  };
+  like($@, qr/\bcannot release ownership as memory is not owned\b/, "Should have thrown 'Cannot release ownership as memory is not owned' error");
+  cpp11_rvalue_reference_move::Counter::check_counts(2, 0, 0, 0, 1, 1);
+}
diff --git a/Examples/test-suite/perl5/cpp11_std_unique_ptr_runme.pl b/Examples/test-suite/perl5/cpp11_std_unique_ptr_runme.pl
new file mode 100644
index 0000000..d61964b
--- /dev/null
+++ b/Examples/test-suite/perl5/cpp11_std_unique_ptr_runme.pl
@@ -0,0 +1,100 @@
+use strict;
+use warnings;
+use Test::More tests => 34;
+BEGIN { use_ok('cpp11_std_unique_ptr') }
+require_ok('cpp11_std_unique_ptr');
+
+# adapted from ../java/cpp11_std_unique_ptr_runme.java
+
+sub checkCount {
+  my($expected_count) = @_;
+  my $actual_count = cpp11_std_unique_ptr::Klass::getTotal_count();
+  is($actual_count, $expected_count, "Counts incorrect, expected: $expected_count actual: $actual_count");
+}
+
+# Test raw pointer handling involving virtual inheritance
+{
+  my $kini = new cpp11_std_unique_ptr::KlassInheritance("KlassInheritanceInput");
+  checkCount(1);
+  my $s = cpp11_std_unique_ptr::useKlassRawPtr($kini);
+  is($s, "KlassInheritanceInput", "Incorrect string: $s");
+  undef $kini;
+  checkCount(0);
+}
+
+
+# unique_ptr as input
+{
+  my $kin = new cpp11_std_unique_ptr::Klass("KlassInput");
+  checkCount(1);
+  my $s = cpp11_std_unique_ptr::takeKlassUniquePtr($kin);
+  checkCount(0);
+  is($s, "KlassInput", "Incorrect string: $s");
+  is(cpp11_std_unique_ptr::is_nullptr($kin), 1, "is_nullptr check");
+  undef $kin; # Should not fail, even though already deleted
+  checkCount(0);
+}
+
+{
+  my $kin = new cpp11_std_unique_ptr::Klass("KlassInput");
+  checkCount(1);
+  my $s = cpp11_std_unique_ptr::takeKlassUniquePtr($kin);
+  checkCount(0);
+  is($s, "KlassInput", "Incorrect string: $s");
+  is(cpp11_std_unique_ptr::is_nullptr($kin), 1, "is_nullptr check");
+  eval {
+    cpp11_std_unique_ptr::takeKlassUniquePtr($kin);
+  };
+  like($@, qr/\bcannot release ownership as memory is not owned\b/, "double usage of takeKlassUniquePtr should be an error");
+  undef $kin; # Should not fail, even though already deleted
+  checkCount(0);
+}
+
+{
+  my $kin = new cpp11_std_unique_ptr::Klass("KlassInput");
+  my $notowned = cpp11_std_unique_ptr::get_not_owned_ptr($kin);
+  eval {
+    cpp11_std_unique_ptr::takeKlassUniquePtr($notowned);
+  };
+  like($@, qr/\bcannot release ownership as memory is not owned\b/, "double usage of takeKlassUniquePtr should be an error");
+  checkCount(1);
+  undef $kin;
+  checkCount(0);
+}
+
+{
+  my $kini = new cpp11_std_unique_ptr::KlassInheritance("KlassInheritanceInput");
+  checkCount(1);
+  my $s = cpp11_std_unique_ptr::takeKlassUniquePtr($kini);
+  checkCount(0);
+  is($s, "KlassInheritanceInput", "Incorrect string: $s");
+  is(cpp11_std_unique_ptr::is_nullptr($kini), 1, "is_nullptr failed");
+  undef $kini; # Should not fail, even though already deleted
+  checkCount(0);
+}
+
+cpp11_std_unique_ptr::takeKlassUniquePtr(undef);
+cpp11_std_unique_ptr::takeKlassUniquePtr(cpp11_std_unique_ptr::make_null());
+checkCount(0);
+
+# overloaded parameters
+is(cpp11_std_unique_ptr::overloadTest(), 0, "overloadTest failed");
+is(cpp11_std_unique_ptr::overloadTest(undef), 1, "overloadTest failed");
+is(cpp11_std_unique_ptr::overloadTest(new cpp11_std_unique_ptr::Klass("over")), 1, "overloadTest failed");
+checkCount(0);
+
+
+# unique_ptr as output
+my $k1 = cpp11_std_unique_ptr::makeKlassUniquePtr("first");
+my $k2 = cpp11_std_unique_ptr::makeKlassUniquePtr("second");
+checkCount(2);
+
+undef $k1;
+checkCount(1);
+
+is($k2->getLabel, "second", "proper label");
+
+undef $k2;
+checkCount(0);
+
+is(cpp11_std_unique_ptr::makeNullUniquePtr(), undef);
diff --git a/Examples/test-suite/perl5/cpp17_director_string_view_runme.pl b/Examples/test-suite/perl5/cpp17_director_string_view_runme.pl
new file mode 100644
index 0000000..d282050
--- /dev/null
+++ b/Examples/test-suite/perl5/cpp17_director_string_view_runme.pl
@@ -0,0 +1,41 @@
+use strict;
+use warnings;
+use Test::More tests => 7;
+BEGIN { use_ok 'cpp17_director_string_view' }
+require_ok 'cpp17_director_string_view';
+
+{
+  package B;
+  use base 'cpp17_director_string_view::A';
+  our $in_first = 0;
+  sub get_first { my($self) = @_;
+    die "SUPER RESOLVE BAD" if $in_first;
+    local $in_first = 1;
+    # Since std::string_view contains a pointer into a string, the string
+    # cannot be a temporary in order to avoid undefined behaviour.
+    my $x = $self->SUPER::get_first();
+    $self->{cached_string} = $x . " world!";
+    return $self->{cached_string};
+  }
+  our $in_process_text = 0;
+  sub process_text { my($self, $string) = @_;
+    die "SUPER RESOLVE BAD" if $in_process_text;
+    local $in_process_text = 1;
+    $self->SUPER::process_text($string);
+    $self->{'smem'} = "hello";
+  }
+}
+
+my $b = B->new("hello");
+isa_ok $b, 'B';
+
+is $b->get(0), "hello";
+
+{ local $TODO = "Return value gets corrupted";
+is $b->get_first(), "hello world!";
+is $b->call_get_first(), "hello world!";
+}
+
+$b->call_process_func();
+
+is $b->{'smem'}, "hello";
diff --git a/Examples/test-suite/perl5/cpp17_string_view_runme.pl b/Examples/test-suite/perl5/cpp17_string_view_runme.pl
new file mode 100644
index 0000000..bc91637
--- /dev/null
+++ b/Examples/test-suite/perl5/cpp17_string_view_runme.pl
@@ -0,0 +1,79 @@
+use strict;
+use warnings;
+use Test::More tests => 17;
+BEGIN { use_ok('cpp17_string_view') }
+require_ok('cpp17_string_view');
+
+use Devel::Peek;
+# Checking expected use of %typemap(in) std::string_view {}
+cpp17_string_view::test_value("Fee");
+
+# Checking expected result of %typemap(out) std::string_view {}
+is(cpp17_string_view::test_value("Fi"), "Fi", "Test 1");
+
+
+# Verify type-checking for %typemap(in) std::string_view {}
+eval { cpp17_string_view::test_value(undef) };
+like($@, qr/\bTypeError\b/, "Test 2");
+
+# Checking expected use of %typemap(in) const std::string_view & {}
+cpp17_string_view::test_const_reference("Fo");
+
+# Checking expected result of %typemap(out) const std::string_view& {}
+is(cpp17_string_view::test_const_reference("Fum"), "Fum", "Test 3");
+
+# Verify type-checking for %typemap(in) const std::string_view & {}
+eval { cpp17_string_view::test_const_reference(undef) };
+like($@, qr/\bValueError\b/, "Test 4");
+
+#
+# Input and output typemaps for pointers and non-const references to
+# std::string_view are *not* supported; the following tests confirm
+# that none of these cases are slipping through.
+#
+
+my $stringPtr = undef;
+
+$stringPtr = cpp17_string_view::test_pointer_out();
+
+cpp17_string_view::test_pointer($stringPtr);
+
+$stringPtr = cpp17_string_view::test_const_pointer_out();
+
+cpp17_string_view::test_const_pointer($stringPtr);
+
+$stringPtr = cpp17_string_view::test_reference_out();
+
+cpp17_string_view::test_reference($stringPtr);
+
+# Check throw exception specification
+eval { cpp17_string_view::test_throw() };
+like($@, qr/^test_throw message/, "Test 5");
+{ local $TODO = "why is the error not a Perl string?";
+eval { cpp17_string_view::test_const_reference_throw() };
+is($@, "<some kind of string>", "Test 6");
+}
+
+# Global variables
+is($cpp17_string_view::ConstGlobalString, "const global string", "ConstGlobalString test");
+
+# Member variables
+my $myStructure = new cpp17_string_view::Structure();
+is($myStructure->{ConstMemberString}, "const member string", "ConstMemberString test");
+
+is($cpp17_string_view::Structure::ConstStaticMemberString, "const static member string", "ConstStaticMemberString test");
+
+
+is(cpp17_string_view::stdstringview_empty(), "", "stdstringview_empty");
+
+is(cpp17_string_view::c_empty(), "", "c_empty");
+
+
+is(cpp17_string_view::c_null(), undef, "c_null");
+
+
+is(cpp17_string_view::get_null(cpp17_string_view::c_null()), undef, "get_null c_null");
+
+is(cpp17_string_view::get_null(cpp17_string_view::c_empty()), "non-null", "get_null c_empty");
+
+is(cpp17_string_view::get_null(cpp17_string_view::stdstringview_empty()), "non-null", "get_null stdstringview_empty");
diff --git a/Examples/test-suite/perl5/director_string_runme.pl b/Examples/test-suite/perl5/director_string_runme.pl
index 4d996ef..5ce9216 100644
--- a/Examples/test-suite/perl5/director_string_runme.pl
+++ b/Examples/test-suite/perl5/director_string_runme.pl
@@ -1,6 +1,6 @@
 use strict;
 use warnings;
-use Test::More tests => 5;
+use Test::More tests => 7;
 BEGIN { use_ok 'director_string' }
 require_ok 'director_string';
 
@@ -25,9 +25,10 @@
 my $b = B->new("hello");
 isa_ok $b, 'B';
 
-$b->get(0);
+is $b->get(0), "hello";
 
-is $b->get_first(),  "hello world!";
+is $b->get_first(), "hello world!";
+is $b->call_get_first(), "hello world!";
 
 $b->call_process_func();
 
diff --git a/Examples/test-suite/perl5/li_constraints_runme.pl b/Examples/test-suite/perl5/li_constraints_runme.pl
new file mode 100644
index 0000000..b1fd143
--- /dev/null
+++ b/Examples/test-suite/perl5/li_constraints_runme.pl
@@ -0,0 +1,56 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+use Test::More tests => 27;
+BEGIN { use_ok('li_constraints') }
+require_ok('li_constraints');
+
+sub check_double {
+    my ($except, $func, $name, $val) = @_;
+    my $fname = "li_constraints::test_$name";
+    $fname =~ s/-//;
+    my $actual = eval { $func->($val); 1; };
+    my $err = $@;
+    $actual = 0 unless defined $actual;
+    if($actual) {
+      is($actual, $except, "$fname pass with $val");
+    } else {
+      is($actual, $except, "$fname throw exception with $val");
+      ok($err =~ "^ValueError Expected a $name value.", "$fname throw proper exception");
+    }
+}
+
+my $nonnegative = sub { li_constraints::test_nonnegative(shift); };
+check_double(1, $nonnegative, "non-negative", 10);
+check_double(1, $nonnegative, "non-negative", 0);
+check_double(0, $nonnegative, "non-negative", -10);
+
+my $nonpositive = sub { li_constraints::test_nonpositive(shift); };
+check_double(0, $nonpositive, "non-positive", 10);
+check_double(1, $nonpositive, "non-positive", 0);
+check_double(1, $nonpositive, "non-positive", -10);
+
+my $positive = sub { li_constraints::test_positive(shift); };
+check_double(1, $positive, "positive", 10);
+check_double(0, $positive, "positive", 0);
+check_double(0, $positive, "positive", -10);
+
+my $negative = sub { li_constraints::test_negative(shift); };
+check_double(0, $negative, "negative", 10);
+check_double(0, $negative, "negative", 0);
+check_double(1, $negative, "negative", -10);
+
+my $nonzero = sub { li_constraints::test_nonzero(shift); };
+check_double(1, $nonzero, "nonzero", 10);
+check_double(0, $nonzero, "nonzero", 0);
+check_double(1, $nonzero, "nonzero", -10);
+
+# Pass null value
+my $ret = eval { li_constraints::test_nonnull(undef); 1; };
+my $err = $@;
+is($ret, undef, "li_constraints::test_nonnull throw exception with null");
+ok($err =~ "^ValueError Received a NULL pointer.", "li_constraints::test_nonnull throw proper exception");
+my $ptr = li_constraints::get_nonnull();
+# There should be no exception, we can use Perl lambda function
+$ret = (sub { li_constraints::test_nonnull($ptr); 1; })->();
+is($ret, 1, "li_constraints::test_nonnull pass with non null value");
diff --git a/Examples/test-suite/perl5/li_std_auto_ptr_runme.pl b/Examples/test-suite/perl5/li_std_auto_ptr_runme.pl
new file mode 100644
index 0000000..bfcd386
--- /dev/null
+++ b/Examples/test-suite/perl5/li_std_auto_ptr_runme.pl
@@ -0,0 +1,100 @@
+use strict;
+use warnings;
+use Test::More tests => 34;
+BEGIN { use_ok('li_std_auto_ptr') }
+require_ok('li_std_auto_ptr');
+
+# adapted from ../java/li_std_auto_ptr_runme.java
+
+sub checkCount {
+  my($expected_count) = @_;
+  my $actual_count = li_std_auto_ptr::Klass::getTotal_count();
+  is($actual_count, $expected_count, "Counts incorrect, expected: $expected_count actual: $actual_count");
+}
+
+# Test raw pointer handling involving virtual inheritance
+{
+  my $kini = new li_std_auto_ptr::KlassInheritance("KlassInheritanceInput");
+  checkCount(1);
+  my $s = li_std_auto_ptr::useKlassRawPtr($kini);
+  is($s, "KlassInheritanceInput", "Incorrect string: $s");
+  undef $kini;
+  checkCount(0);
+}
+
+
+# auto_ptr as input
+{
+  my $kin = new li_std_auto_ptr::Klass("KlassInput");
+  checkCount(1);
+  my $s = li_std_auto_ptr::takeKlassAutoPtr($kin);
+  checkCount(0);
+  is($s, "KlassInput", "Incorrect string: $s");
+  is(li_std_auto_ptr::is_nullptr($kin), 1, "is_nullptr check");
+  undef $kin; # Should not fail, even though already deleted
+  checkCount(0);
+}
+
+{
+  my $kin = new li_std_auto_ptr::Klass("KlassInput");
+  checkCount(1);
+  my $s = li_std_auto_ptr::takeKlassAutoPtr($kin);
+  checkCount(0);
+  is($s, "KlassInput", "Incorrect string: $s");
+  is(li_std_auto_ptr::is_nullptr($kin), 1, "is_nullptr check");
+  eval {
+    li_std_auto_ptr::takeKlassAutoPtr($kin);
+  };
+  like($@, qr/\bcannot release ownership as memory is not owned\b/, "double usage of takeKlassAutoPtr should be an error");
+  undef $kin; # Should not fail, even though already deleted
+  checkCount(0);
+}
+
+{
+  my $kin = new li_std_auto_ptr::Klass("KlassInput");
+  my $notowned = li_std_auto_ptr::get_not_owned_ptr($kin);
+  eval {
+    li_std_auto_ptr::takeKlassAutoPtr($notowned);
+  };
+  like($@, qr/\bcannot release ownership as memory is not owned\b/, "double usage of takeKlassAutoPtr should be an error");
+  checkCount(1);
+  undef $kin;
+  checkCount(0);
+}
+
+{
+  my $kini = new li_std_auto_ptr::KlassInheritance("KlassInheritanceInput");
+  checkCount(1);
+  my $s = li_std_auto_ptr::takeKlassAutoPtr($kini);
+  checkCount(0);
+  is($s, "KlassInheritanceInput", "Incorrect string: $s");
+  is(li_std_auto_ptr::is_nullptr($kini), 1, "is_nullptr failed");
+  undef $kini; # Should not fail, even though already deleted
+  checkCount(0);
+}
+
+li_std_auto_ptr::takeKlassAutoPtr(undef);
+li_std_auto_ptr::takeKlassAutoPtr(li_std_auto_ptr::make_null());
+checkCount(0);
+
+# overloaded parameters
+is(li_std_auto_ptr::overloadTest(), 0, "overloadTest failed");
+is(li_std_auto_ptr::overloadTest(undef), 1, "overloadTest failed");
+is(li_std_auto_ptr::overloadTest(new li_std_auto_ptr::Klass("over")), 1, "overloadTest failed");
+checkCount(0);
+
+
+# auto_ptr as output
+my $k1 = li_std_auto_ptr::makeKlassAutoPtr("first");
+my $k2 = li_std_auto_ptr::makeKlassAutoPtr("second");
+checkCount(2);
+
+undef $k1;
+checkCount(1);
+
+is($k2->getLabel, "second", "proper label");
+
+undef $k2;
+checkCount(0);
+
+is(li_std_auto_ptr::makeNullAutoPtr(), undef);
diff --git a/Examples/test-suite/perl5/li_std_string_runme.pl b/Examples/test-suite/perl5/li_std_string_runme.pl
index e6358ff..0eb0b14 100644
--- a/Examples/test-suite/perl5/li_std_string_runme.pl
+++ b/Examples/test-suite/perl5/li_std_string_runme.pl
@@ -1,6 +1,6 @@
 use strict;
 use warnings;
-use Test::More tests => 30;
+use Test::More tests => 31;
 BEGIN { use_ok('li_std_string') }
 require_ok('li_std_string');
 
@@ -77,6 +77,7 @@
 
 is(li_std_string::test_reference_inout("hello"), "hellohello", "reference_inout");
 
+is(li_std_string::test_reference_output(), "output", "reference_output");
 
 no strict;
 my $gen1 = new li_std_string::Foo();
@@ -100,14 +101,14 @@
 
 is(li_std_string::stdstring_empty(), "", "stdstring_empty");
 
-is(li_std_string::c_empty(),  "", "c_empty");
+is(li_std_string::c_empty(), "", "c_empty");
 
 
-is(li_std_string::c_null(), undef, "c_empty");
+is(li_std_string::c_null(), undef, "c_null");
 
 
-is(li_std_string::get_null(li_std_string::c_null()), undef, "c_empty");
+is(li_std_string::get_null(li_std_string::c_null()), undef, "get_null c_null");
 
-is(li_std_string::get_null(li_std_string::c_empty()), "non-null", "c_empty");
+is(li_std_string::get_null(li_std_string::c_empty()), "non-null", "get_null c_empty");
 
-is(li_std_string::get_null(li_std_string::stdstring_empty()), "non-null", "stdstring_empty");
+is(li_std_string::get_null(li_std_string::stdstring_empty()), "non-null", "get_null stdstring_empty");
diff --git a/Examples/test-suite/perl5/li_typemaps_runme.pl b/Examples/test-suite/perl5/li_typemaps_runme.pl
index a573b89..2755862 100644
--- a/Examples/test-suite/perl5/li_typemaps_runme.pl
+++ b/Examples/test-suite/perl5/li_typemaps_runme.pl
@@ -1,7 +1,7 @@
 #!/usr/bin/perl
 use strict;
 use warnings;
-use Test::More tests => 415;
+use Test::More tests => 416;
 BEGIN { use_ok('li_typemaps') }
 require_ok('li_typemaps');
 
@@ -75,10 +75,11 @@
   batch('ulonglong', $c);
 }
 
-my($foo, $int) = li_typemaps::out_foo(10);
+my($foo, $int, $int2) = li_typemaps::out_foo(10);
 isa_ok($foo, 'li_typemaps::Foo');
 is($foo->{a}, 10);
 is($int, 20);
+is($int2, 30);
 
 my($a, $b) = li_typemaps::inoutr_int2(13, 31);
 is($a, 13);
diff --git a/Examples/test-suite/perl5/multivalue_runme.pl b/Examples/test-suite/perl5/multivalue_runme.pl
new file mode 100644
index 0000000..b58a58a
--- /dev/null
+++ b/Examples/test-suite/perl5/multivalue_runme.pl
@@ -0,0 +1,20 @@
+use strict;
+use warnings;
+use Test::More tests => 8;
+
+BEGIN { use_ok('multivalue') }
+require_ok('multivalue');
+
+my ($q, $r);
+
+($q, $r) = multivalue::divide_l(37, 5);
+is($q, 7, "Test divide_l quotient");
+is($r, 2, "Test divide_l remainder");
+
+($q, $r) = multivalue::divide_v(41, 7);
+is($q, 5, "Test divide_v quotient");
+is($r, 6, "Test divide_v remainder");
+
+($q, $r) = multivalue::divide_mv(91, 13);
+is($q, 7, "Test divide_mv quotient");
+is($r, 0, "Test divide_mv remainder");
diff --git a/Examples/test-suite/perl5/operator_overload_break_runme.pl b/Examples/test-suite/perl5/operator_overload_break_runme.pl
index fd3fe33..c692dfa 100644
--- a/Examples/test-suite/perl5/operator_overload_break_runme.pl
+++ b/Examples/test-suite/perl5/operator_overload_break_runme.pl
@@ -4,15 +4,6 @@
 
 use operator_overload_break;
 
-# Workaround for 
-#   ok( not (expression) , "test description" );
-# does not working in older versions of Perl, eg 5.004_04
-sub ok_not ($;$) {
-    my($test, $name) = @_;
-    $test = not $test;
-    ok($test, $name);
-}
-
 pass("loaded");
 
 my $op = operator_overload_break::Op->new(5);
@@ -32,7 +23,7 @@
 ok((10 == (32 - $op)),
    "reversed subtraction");
 
-ok_not((3 == $op),
+ok(not(3 == $op),
        'not equal');
 
 $op->{k} = 3;
diff --git a/Examples/test-suite/perl5/operator_overload_runme.pl b/Examples/test-suite/perl5/operator_overload_runme.pl
index ba3f33a..43a77a9 100644
--- a/Examples/test-suite/perl5/operator_overload_runme.pl
+++ b/Examples/test-suite/perl5/operator_overload_runme.pl
@@ -4,15 +4,6 @@
 
 use operator_overload;
 
-# Workaround for 
-#   ok( not (expression) , "test description" );
-# does not working in older versions of Perl, eg 5.004_04
-sub ok_not ($;$) {
-    my($test, $name) = @_;
-    $test = not $test;
-    ok($test, $name);
-}
-
 pass("loaded");
 
 # first check all the operators are implemented correctly from pure C++ code
@@ -30,7 +21,7 @@
 $op->{i} = 5;
 $op2->{i} = 3;
 
-ok_not(($op == $op2), "operator equal: not equal");
+ok(not($op == $op2), "operator equal: not equal");
 
 $op->{i} = 3;
 ok(($op == $op2), "operator equal: equal");
@@ -42,7 +33,7 @@
 ok(($op != $op2), "operator not equal: not equal");
 
 $op->{i} = 3;
-ok_not(($op != $op2), "operator not equal: equal");
+ok(not($op != $op2), "operator not equal: equal");
 
 # stringify operator
 $op->{i} = 3;
@@ -99,16 +90,16 @@
 $op->{i} = 8;
 $op2->{i} = 3;
 ok($op > $op2, "operator greater than");
-ok_not(($op2 > $op), "operator greater than");
+ok(not($op2 > $op), "operator greater than");
 $op->{i} = 3;
-ok_not(($op2 > $op), "operator greater than");
-ok_not(($op > $op2), "operator greater than");
+ok(not($op2 > $op), "operator greater than");
+ok(not($op > $op2), "operator greater than");
 
 # greater than or equal operator
 $op->{i} = 8;
 $op2->{i} = 3;
 ok($op >= $op2, "operator greater than or equal");
-ok_not(($op2 >= $op), "operator greater than or equal");
+ok(not($op2 >= $op), "operator greater than or equal");
 $op->{i} = 3;
 ok(($op2 >= $op), "operator greater than or equal");
 ok(($op >= $op2), "operator greater than or equal");
@@ -117,16 +108,16 @@
 $op2->{i} = 8;
 $op->{i} = 3;
 ok($op < $op2, "operator lesser than");
-ok_not(($op2 < $op), "operator lesser than");
+ok(not($op2 < $op), "operator lesser than");
 $op2->{i} = 3;
-ok_not(($op2 < $op), "operator lesser than");
-ok_not(($op < $op2), "operator lesser than");
+ok(not($op2 < $op), "operator lesser than");
+ok(not($op < $op2), "operator lesser than");
 
 # less than or equal operator
 $op2->{i} = 8;
 $op->{i} = 3;
 ok($op <= $op2, "operator lesser than or equal");
-ok_not(($op2 <= $op), "operator lesser than or equal");
+ok(not($op2 <= $op), "operator lesser than or equal");
 $op2->{i} = 3;
 ok(($op2 <= $op), "operator less than or equal");
 ok(($op <= $op2), "operator less than or equal");
diff --git a/Examples/test-suite/perl5/overload_null_runme.pl b/Examples/test-suite/perl5/overload_null_runme.pl
index 7cc5090..6c01b58 100644
--- a/Examples/test-suite/perl5/overload_null_runme.pl
+++ b/Examples/test-suite/perl5/overload_null_runme.pl
@@ -32,13 +32,13 @@
 is(15, $o->byval2cpr(undef));
 is(16, $o->byval2cpr($x));
 
-# forward class declaration
-is(17, $o->byval1forwardptr($x));
-is(18, $o->byval1forwardptr(undef));
+# fwd class declaration
+is(17, $o->byval1fwdptr($x));
+is(18, $o->byval1fwdptr(undef));
 
-is(19, $o->byval2forwardptr(undef));
-is(20, $o->byval2forwardptr($x));
+is(19, $o->byval2fwdptr(undef));
+is(20, $o->byval2fwdptr($x));
 
-is(21, $o->byval1forwardref($x));
+is(21, $o->byval1fwdref($x));
 
-is(22, $o->byval2forwardref($x));
+is(22, $o->byval2fwdref($x));
diff --git a/Examples/test-suite/perl5/packageoption_runme.pl b/Examples/test-suite/perl5/packageoption_runme.pl
index d94a7a1..02e95f7 100644
--- a/Examples/test-suite/perl5/packageoption_runme.pl
+++ b/Examples/test-suite/perl5/packageoption_runme.pl
@@ -5,15 +5,6 @@
 BEGIN { use_ok('packageoption_a'); }
 BEGIN { use_ok('packageoption_b'); }
 
-# Workaround for 
-#   ok( not (expression) , "test description" );
-# does not working in older versions of Perl, eg 5.004_04
-sub ok_not ($;$) {
-    my($test, $name) = @_;
-    $test = not $test;
-    ok($test, $name);
-}
-
 my $a = CommonPackage::A->new();
 
 isa_ok($a, 'CommonPackage::A');
diff --git a/Examples/test-suite/php/Makefile.in b/Examples/test-suite/php/Makefile.in
index 64f0d1f..3811bd0 100644
--- a/Examples/test-suite/php/Makefile.in
+++ b/Examples/test-suite/php/Makefile.in
@@ -5,16 +5,29 @@
 LANGUAGE     = php
 SCRIPTSUFFIX = _runme.php
 
+HAVE_CXX11   = @HAVE_CXX11@
+HAVE_CXX14   = @HAVE_CXX14@
+HAVE_CXX17   = @HAVE_CXX17@
+HAVE_CXX20   = @HAVE_CXX20@
 srcdir       = @srcdir@
 top_srcdir   = @top_srcdir@
 top_builddir = @top_builddir@
 
 CPP_TEST_CASES += \
 	callback \
+	director_stl \
+	exception_partial_info \
+	inout \
+	li_cdata_carrays_cpp \
 	li_factory \
 	php_iterator \
 	php_namewarn_rename \
 	php_pragma \
+	prefix \
+
+C_TEST_CASES += \
+	li_cdata_carrays \
+	multivalue \
 
 include $(srcdir)/../common.mk
 
@@ -44,10 +57,18 @@
 	+$(swig_and_compile_c)
 	+$(run_testcase)
 
+# Trying to load the modules for imports.multicpptest fails with:
+#
+# Warning: Function registration failed - duplicate name - global_test in Unknown on line 0
+# Segmentation fault
+#
+# This was previously hidden because we didn't even try to load the modules for
+# .multicpptest testcases, so for now just do the parts of the test we did
+# before.  FIXME: Fix this!
 %.multicpptest:
 	$(setup)
 	+$(swig_and_compile_multi_cpp)
-	+$(run_testcase)
+	+[ "$*" = "imports" ] || $(run_multi_testcase)
 
 # Smart target
 %.test:
@@ -58,18 +79,27 @@
 	@echo ' $(MULTI_CPP_TEST_CASES) '|grep -F -v ' $* ' >/dev/null ||\
 	    $(MAKE) $*.multicpptest
 
-# Runs the testcase. Tries to run testcase_runme.php, and if that's not
-# found, runs testcase.php, except for multicpptests.
+# Runs the testcase. Tries to run testcase_runme.php, and if that's not found,
+# at least test that the module loads without errors.
 run_testcase = \
 	if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
-	  $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile PHP_SCRIPT=$(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) RUNTOOL='$(RUNTOOL)' php_run; \
-	elif [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*.php -a ! -f $(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list ]; then \
-	  $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile PHP_SCRIPT=$(SCRIPTDIR)/$(SCRIPTPREFIX)$*.php RUNTOOL='$(RUNTOOL)' php_run; \
+	  $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile PHP_EXTENSION=$(TARGETPREFIX)$*@PHP_SO@ PHP_SCRIPT=$(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) RUNTOOL='$(RUNTOOL)' php_run; \
+	else \
+	  $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile PHP_EXTENSION=$(TARGETPREFIX)$*@PHP_SO@ PHP_SCRIPT= RUNTOOL='$(RUNTOOL)' php_run; \
 	fi
 
-# Clean: remove the generated .php file
+# Runs a multicpptest testcase. Tries to run testcase_runme.php, and if that's
+# not found, at least test that the modules load without errors.
+run_multi_testcase = \
+	if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
+	  $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile PHP_EXTENSION_LIST=$(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list PHP_SCRIPT=$(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) RUNTOOL='$(RUNTOOL)' php_run_multi; \
+	else \
+	  $(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile PHP_EXTENSION_LIST=$(top_srcdir)/$(EXAMPLES)/$(TEST_SUITE)/$*.list PHP_SCRIPT= RUNTOOL='$(RUNTOOL)' php_run_multi; \
+	fi
+
+# Clean: remove the generated PHP-specific files
 %.clean:
-	@rm -f $*.php php_$*.h
+	@rm -f php_$*.h
 
 clean:
 	$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' php_clean
@@ -77,5 +107,6 @@
 	rm -f import_stl_a.php import_stl_b.php php_import_stl_a.h php_import_stl_b.h
 	rm -f imports_a.php imports_b.php php_imports_a.h php_imports_b.h
 	rm -f mod_a.php mod_b.php php_mod_a.h php_mod_b.h
-	rm -f multi_import_a.php multi_import_b.php php_multi_import_a.h php_multi_import_b.h
+	rm -f multi_import_a.php multi_import_b.php multi_import_d.php php_multi_import_a.h php_multi_import_b.h php_multi_import_d.h
 	rm -f packageoption_a.php packageoption_b.php packageoption_c.php php_packageoption_a.h php_packageoption_b.h php_packageoption_c.h
+	rm -f template_typedef_cplx2.php php_template_typedef_cplx2.h
diff --git a/Examples/test-suite/php/abstract_inherit_ok_runme.php b/Examples/test-suite/php/abstract_inherit_ok_runme.php
index c2c343d..add4191 100644
--- a/Examples/test-suite/php/abstract_inherit_ok_runme.php
+++ b/Examples/test-suite/php/abstract_inherit_ok_runme.php
@@ -1,12 +1,25 @@
 <?php
 
 require "tests.php";
-require "abstract_inherit_ok.php";
+
+// No new functions
+check::functions(array());
 
 check::classes(array('Foo','Spam'));
-$spam=new Spam();
 
+// No new vars
+check::globals(array());
+
+// We shouldn't be able to instantiate abstract class Foo.
+$class = 'Foo';
+try {
+    $obj = eval("new $class();");
+    check::fail("Should not be able to instantiate abstract class $class");
+} catch (Error $e) {
+    check::equal($e->getMessage(), "Cannot instantiate abstract class $class", "Unexpected exception: {$e->getMessage()}");
+}
+
+$spam=new Spam();
 check::equal(0,$spam->blah(),"spam object method");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/abstract_inherit_runme.php b/Examples/test-suite/php/abstract_inherit_runme.php
index 514bbc3..376a2ad 100644
--- a/Examples/test-suite/php/abstract_inherit_runme.php
+++ b/Examples/test-suite/php/abstract_inherit_runme.php
@@ -1,14 +1,19 @@
 <?php
 
 require "tests.php";
-require "abstract_inherit.php";
 
 check::classes(array('Foo','Bar','Spam','NRFilter_i','NRRCFilter_i','NRRCFilterpro_i','NRRCFilterpri_i'));
-// This constructor attempt should fail as there isn't one
-//$spam=new Spam();
 
-//check::equal(0,$spam->blah(),"spam object method");
-//check::equal(0,Spam::blah($spam),"spam class method");
+// We shouldn't be able to instantiate any of these classes since they are all
+// abstract (in each case there's a pure virtual function in the base class
+// which isn't implemented).
+foreach (array('Foo','Bar','Spam','NRFilter_i','NRRCFilter_i','NRRCFilterpro_i','NRRCFilterpri_i')as $class) {
+    try {
+	$obj = eval("new $class();");
+	check::fail("Should not be able to instantiate abstract class $class");
+    } catch (Error $e) {
+	check::equal($e->getMessage(), "Cannot instantiate abstract class $class", "Unexpected exception: {$e->getMessage()}");
+    }
+}
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/add_link_runme.php b/Examples/test-suite/php/add_link_runme.php
index 3e16fa1..073dee3 100644
--- a/Examples/test-suite/php/add_link_runme.php
+++ b/Examples/test-suite/php/add_link_runme.php
@@ -1,10 +1,9 @@
 <?php
 
 require "tests.php";
-require "add_link.php";
 
-// No new functions, except the flat functions
-check::functions(array('new_foo','foo_blah'));
+// No new functions
+check::functions(array());
 
 check::classes(array('Foo'));
 
@@ -19,4 +18,3 @@
 //check::is_a($class_foo_blah,foo);
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/argcargvtest_runme.php b/Examples/test-suite/php/argcargvtest_runme.php
new file mode 100644
index 0000000..dac4270
--- /dev/null
+++ b/Examples/test-suite/php/argcargvtest_runme.php
@@ -0,0 +1,44 @@
+<?php
+
+require "tests.php";
+
+// New functions
+check::functions(array('mainc', 'mainv', 'initializeapp'));
+// New classes
+check::classes(array('argcargvtest'));
+// No new vars
+check::globals(array());
+
+$largs = array('hi', 'hola', 'hello');
+check::equal(mainc($largs), 3, 'Test main typemap 1');
+
+$targs = array('hi', 'hola');
+check::equal(mainv($targs, 0), 'hi', 'Test main typemap 2a');
+check::equal(mainv($targs, 1), 'hola', 'Test main typemap 2b');
+check::equal(mainv($targs, 2), '<<NULL>>', 'Test main typemap 2c');
+
+$error = 0;
+try {
+    mainv('hello', 1);
+    $error = 1;
+}
+catch (exception $e) {
+}
+check::equal($error, 0, 'Test main typemap 3');
+
+initializeApp($largs);
+
+# Check that an empty array works.
+$empty_args = [];
+check::equal(mainc($empty_args), 0, "test main typemap 4");
+check::equal(mainv($empty_args, 0), '<<NULL>>', 'Test main typemap 4a');
+
+# Check that empty strings are handled.
+$empty_string = ["hello", "", "world"];
+check::equal(mainc($empty_string), 3, "test main typemap 5");
+check::equal(mainv($empty_string, 0), "hello", "test main typemap 6a");
+check::equal(mainv($empty_string, 1), "", "test main typemap 6b");
+check::equal(mainv($empty_string, 2), "world", "test main typemap 6c");
+check::equal(mainv($empty_string, 3), "<<NULL>>", "test main typemap 6d");
+
+check::done();
diff --git a/Examples/test-suite/php/argout_runme.php b/Examples/test-suite/php/argout_runme.php
index 8b66613..554d077 100644
--- a/Examples/test-suite/php/argout_runme.php
+++ b/Examples/test-suite/php/argout_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "argout.php";
 
 check::functions(array('incp','incr','inctr','new_intp','copy_intp','delete_intp','intp_assign','intp_value','voidhandle','handle'));
 
@@ -21,18 +20,14 @@
 check::equal(4,inctr($tr),"4==incr($tr)");
 check::equal(5,intp_value($tr),"5==$tr");
 
-# Check the voidhandle call, first with null
-unset($handle);
-# FIXME: Call-time pass-by-reference has been deprecated for ages, and was
-# removed in PHP 5.4.  We need to rework 
-#voidhandle(&$handle);
-#check::resource($handle,"_p_void",'$handle is not _p_void');
-#$handledata=handle($handle);
-#check::equal($handledata,"Here it is","\$handledata != \"Here it is\"");
-
+# Check the voidhandle call, first with NULL and then with the SWIG\p_void we
+# get from the first call.
 $handle=NULL;
-voidhandle($handle);
-check::isnull($handle,'$handle not null');
+for ($i=0; $i != 1; $i++) {
+  voidhandle($handle);
+  check::equal(get_class($handle),"SWIG\\_p_void",'$handle is not _p_void');
+  $handledata=handle($handle);
+  check::equal($handledata,"Here it is","\$handledata != \"Here it is\"");
+}
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/arrayptr_runme.php b/Examples/test-suite/php/arrayptr_runme.php
deleted file mode 100644
index 86b7f86..0000000
--- a/Examples/test-suite/php/arrayptr_runme.php
+++ /dev/null
@@ -1,14 +0,0 @@
-<?php
-
-require "tests.php";
-require "arrayptr.php";
-
-// No new functions
-check::functions(array('foo'));
-// No new classes
-check::classes(array());
-// now new vars
-check::globals(array());
-
-check::done();
-?>
diff --git a/Examples/test-suite/php/arrays_global_runme.php b/Examples/test-suite/php/arrays_global_runme.php
index 95a3007..6a97db9 100644
--- a/Examples/test-suite/php/arrays_global_runme.php
+++ b/Examples/test-suite/php/arrays_global_runme.php
@@ -1,11 +1,11 @@
 <?php
 
 require "tests.php";
-require "arrays_global.php";
 
-check::functions(array('test_a','test_b','new_simplestruct','new_material'));
+check::functions(array('test_a','test_b'));
 check::classes(array('arrays_global','SimpleStruct','Material'));
-check::globals(array('array_c','array_sc','array_uc','array_s','array_us','array_i','array_ui','array_l','array_ul','array_ll','array_f','array_d','array_struct','array_structpointers','array_ipointers','array_enum','array_enumpointers','array_const_i','beginstring_fix44a','beginstring_fix44b','beginstring_fix44c','beginstring_fix44d','beginstring_fix44e','beginstring_fix44f','chitmat','hitmat_val','hitmat','simplestruct_double_field'));
+check::globals(array('array_c','array_sc','array_uc','array_s','array_us','array_i','array_ui','array_l','array_ul','array_ll','array_f','array_d','array_struct','array_structpointers','array_ipointers','array_enum','array_enumpointers','array_const_i','BeginString_FIX44a','BeginString_FIX44b','BeginString_FIX44c','BeginString_FIX44d','BeginString_FIX44e','BeginString_FIX44f','chitMat','hitMat_val','hitMat'));
+
 // The size of array_c is 2, but the last byte is \0, so we can only store a
 // single byte string in it.
 check::set("array_c","Z");
@@ -16,4 +16,3 @@
 check::equal("h",check::get("array_c"),"set array_c");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/arrays_global_twodim_runme.php b/Examples/test-suite/php/arrays_global_twodim_runme.php
index d9f50a6..e6fbf52 100644
--- a/Examples/test-suite/php/arrays_global_twodim_runme.php
+++ b/Examples/test-suite/php/arrays_global_twodim_runme.php
@@ -1,11 +1,11 @@
 <?php
 
 require "tests.php";
-require "arrays_global_twodim.php";
 
-check::functions(array('fn_taking_arrays','get_2d_array','new_simplestruct','new_material'));
+check::functions(array('fn_taking_arrays','get_2d_array',));
 check::classes(array('arrays_global_twodim','SimpleStruct','Material'));
-check::globals(array('array_c','array_sc','array_uc','array_s','array_us','array_i','array_ui','array_l','array_ul','array_ll','array_f','array_d','array_struct','array_structpointers','array_ipointers','array_enum','array_enumpointers','array_const_i','chitmat','hitmat_val','hitmat','simplestruct_double_field'));
+check::globals(array('array_c','array_sc','array_uc','array_s','array_us','array_i','array_ui','array_l','array_ul','array_ll','array_f','array_d','array_struct','array_structpointers','array_ipointers','array_enum','array_enumpointers','array_const_i','chitMat','hitMat_val','hitMat'));
+
 $a1=array(10,11,12,13);
 $a2=array(14,15,16,17);
 $a=array($a1,$a2);
@@ -19,4 +19,3 @@
 }
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/arrays_runme.php b/Examples/test-suite/php/arrays_runme.php
index c6e9e8f..1d9e44d 100644
--- a/Examples/test-suite/php/arrays_runme.php
+++ b/Examples/test-suite/php/arrays_runme.php
@@ -1,10 +1,10 @@
 <?php
+
 require "tests.php";
-require "arrays.php";
 
 check::functions(array('fn_taking_arrays','newintpointer','setintfrompointer','getintfrompointer','array_pointer_func'));
 check::classes(array('arrays','SimpleStruct','ArrayStruct','CartPoseData_t'));
-check::globals(array('simplestruct_double_field','arraystruct_array_c','arraystruct_array_sc','arraystruct_array_uc','arraystruct_array_s','arraystruct_array_us','arraystruct_array_i','arraystruct_array_ui','arraystruct_array_l','arraystruct_array_ul','arraystruct_array_ll','arraystruct_array_f','arraystruct_array_d','arraystruct_array_struct','arraystruct_array_structpointers','arraystruct_array_ipointers','arraystruct_array_enum','arraystruct_array_enumpointers','arraystruct_array_const_i','cartposedata_t_p'));
+check::globals(array('array_shifted_size'));
 
 $ss=new simplestruct();
 check::classname('simplestruct',$ss);
@@ -15,4 +15,3 @@
 check::equal(isset($as->array_const_i),TRUE,'isset($as->array_const_i)');
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/arrays_scope_runme.php b/Examples/test-suite/php/arrays_scope_runme.php
index 11c1808..8455b83 100644
--- a/Examples/test-suite/php/arrays_scope_runme.php
+++ b/Examples/test-suite/php/arrays_scope_runme.php
@@ -1,16 +1,18 @@
 <?php
 
 require "tests.php";
-require "arrays_scope.php";
 
-// New functions
-check::functions(array('new_bar','bar_blah'));
+// No new functions
+check::functions(array());
 // New classes
 check::classes(array('arrays_scope','Bar'));
-// New vars
-check::globals(array('bar_adata','bar_bdata','bar_cdata'));
+// No new globals
+check::globals(array());
 
 $bar=new bar();
+$bar->blah($bar->adata, $bar->bdata, $bar->cdata);
+// Like C/C++, SWIG treats `int asize[ASIZE]` as `int*` so there's no checking
+// of the passed array size.
+$bar->blah($bar->bdata, $bar->cdata, $bar->adata);
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/callback_runme.php b/Examples/test-suite/php/callback_runme.php
index fefa325..7171856 100644
--- a/Examples/test-suite/php/callback_runme.php
+++ b/Examples/test-suite/php/callback_runme.php
@@ -1,9 +1,10 @@
 <?php
 
 require "tests.php";
-require "callback.php";
+
 // In 2.0.6 and earlier, the constant was misnamed.
-if (gettype(callback::FOO_I_Cb_Ptr) !== 'resource') die("callback::FOO_I_Cb_Ptr not a resource\n");
+check::equal(gettype(callback::FOO_I_Cb_Ptr), 'object', "callback::FOO_I_Cb_Ptr not an object");
+
+check::equal(get_class(callback::FOO_I_Cb_Ptr), 'SWIG\_p_f_int__int', "callback::FOO_I_Cb_Ptr not expected class");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/casts_runme.php b/Examples/test-suite/php/casts_runme.php
index a9623a3..6234f0f 100644
--- a/Examples/test-suite/php/casts_runme.php
+++ b/Examples/test-suite/php/casts_runme.php
@@ -1,13 +1,12 @@
 <?php
 
 require "tests.php";
-require "casts.php";
 
 // No new functions
-check::functions(array('new_a','a_hello','new_b'));
-// No new classes
+check::functions(array());
+// New classes
 check::classes(array('A','B'));
-// now new vars
+// No new vars
 check::globals(array());
 
 # Make sure $b inherits hello() from class A
@@ -15,4 +14,3 @@
 $b->hello();
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/catches_strings_runme.php b/Examples/test-suite/php/catches_strings_runme.php
new file mode 100644
index 0000000..758c3f6
--- /dev/null
+++ b/Examples/test-suite/php/catches_strings_runme.php
@@ -0,0 +1,23 @@
+<?php
+
+require "tests.php";
+
+$exception_thrown = false;
+try {
+  StringsThrower::charstring();
+} catch (Exception $e) {
+  check::equal($e->getMessage(), "charstring message", "incorrect exception message: {$e->getMessage()}");
+  $exception_thrown = true;
+}
+check::equal($exception_thrown, true, "Should have thrown an exception");
+
+$exception_thrown = false;
+try {
+  StringsThrower::stdstring();
+} catch (Exception $e) {
+  check::equal($e->getMessage(), "stdstring message", "incorrect exception message: {$e->getMessage()}");
+  $exception_thrown = true;
+}
+check::equal($exception_thrown, true, "Should have thrown an exception");
+
+check::done();
diff --git a/Examples/test-suite/php/char_binary_runme.php b/Examples/test-suite/php/char_binary_runme.php
new file mode 100644
index 0000000..87c3fd4
--- /dev/null
+++ b/Examples/test-suite/php/char_binary_runme.php
@@ -0,0 +1,39 @@
+<?php
+
+require "tests.php";
+
+check::functions(array('new_pchar', 'delete_pchar', 'pchar_getitem', 'pchar_setitem'));
+
+check::classes(array('Test', 'char_binary'));
+
+$t = new Test();
+$str = 'hile';
+check::equal(4, $t->strlen($str), "bad multi-arg typemap");
+check::equal(4, $t->ustrlen($str), "bad multi-arg typemap");
+check::equal(4, $t->strlen("hil\000"), "bad multi-arg typemap");
+check::equal(4, $t->ustrlen("hil\000"), "bad multi-arg typemap");
+
+// creating a raw char*
+$pc = new_pchar(5);
+pchar_setitem($pc, 0, 'h');
+pchar_setitem($pc, 1, 'o');
+pchar_setitem($pc, 2, 'l');
+pchar_setitem($pc, 3, 'a');
+pchar_setitem($pc, 4, 0);
+
+// FIXME: These don't work as we get the stringified pointer object, e.g.
+// "SWIGPointer(0x55dafc88c0a0,owned=0"
+if (0) {
+    check::equal($t->strlen($pc), 4, "bad multi-arg typemap");
+    check::equal($t->ustrlen($pc), 4, "bad multi-arg typemap");
+
+    var_pchar_set($pc);
+    check::equal(var_pchar_get(), "hola", "bad pointer case");
+
+    var_namet_set($pc);
+    check::equal(var_namet_get(), "hola", "bad pointer case");
+}
+
+delete_pchar($pc);
+
+check::done();
diff --git a/Examples/test-suite/php/char_strings_runme.php b/Examples/test-suite/php/char_strings_runme.php
index e06ee9d..7dc8fe7 100644
--- a/Examples/test-suite/php/char_strings_runme.php
+++ b/Examples/test-suite/php/char_strings_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "char_strings.php";
 
 $CPLUSPLUS_MSG = "A message from the deep dark world of C++, where anything is possible.";
 $OTHERLAND_MSG_10 = "Little message from the safe world.10";
@@ -40,4 +39,3 @@
 check::equal(SetConstCharPointerRef($OTHERLAND_MSG_10, 10), true, "failed SetConstCharPointerRef");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/class_ignore_runme.php b/Examples/test-suite/php/class_ignore_runme.php
index ae4881f..f52bc1a 100644
--- a/Examples/test-suite/php/class_ignore_runme.php
+++ b/Examples/test-suite/php/class_ignore_runme.php
@@ -1,9 +1,8 @@
 <?php
 
 require "tests.php";
-require "class_ignore.php";
 
-check::functions(array('do_blah','new_bar','bar_blah','new_boo','boo_away','new_far','new_hoo'));
+check::functions(array('do_blah'));
 check::classes(array('class_ignore','Bar','Boo','Far','Hoo'));
 // No new vars
 check::globals(array());
@@ -13,4 +12,3 @@
 check::classparent($bar,"");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/constant_expr_c_runme.php b/Examples/test-suite/php/constant_expr_c_runme.php
new file mode 100644
index 0000000..877d13b
--- /dev/null
+++ b/Examples/test-suite/php/constant_expr_c_runme.php
@@ -0,0 +1,15 @@
+<?php
+
+require "tests.php";
+
+// New functions
+check::functions(array('xx', 'yy'));
+// New classes
+check::classes(array('constant_expr_c'));
+// New vars
+check::globals(array('X','d_array','s1a','s2a','s2b','s3a','s3b','s4a','s4b','s5a','s5b','s6a','s6b','s7a','s7b','s8a','s8b'));
+
+check::equal(XX, xx());
+check::equal(YY, yy());
+
+check::done();
diff --git a/Examples/test-suite/php/conversion_namespace_runme.php b/Examples/test-suite/php/conversion_namespace_runme.php
index e21ff74..858bf89 100644
--- a/Examples/test-suite/php/conversion_namespace_runme.php
+++ b/Examples/test-suite/php/conversion_namespace_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "conversion_namespace.php";
 
 check::classes(array("Foo","Bar"));
 $bar=new Bar;
@@ -10,4 +9,3 @@
 check::classname("foo",$foo);
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/conversion_ns_template_runme.php b/Examples/test-suite/php/conversion_ns_template_runme.php
index 9702eed..4157b10 100644
--- a/Examples/test-suite/php/conversion_ns_template_runme.php
+++ b/Examples/test-suite/php/conversion_ns_template_runme.php
@@ -1,10 +1,8 @@
 <?php
 
 require "tests.php";
-require "conversion_ns_template.php";
 
 check::classes(array("conversion_ns_template","Foo_One","Bar_One","Hi"));
 // this is too hard, I'm not sure what to test for,
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/conversion_runme.php b/Examples/test-suite/php/conversion_runme.php
index 1a10ff4..858bf89 100644
--- a/Examples/test-suite/php/conversion_runme.php
+++ b/Examples/test-suite/php/conversion_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "conversion.php";
 
 check::classes(array("Foo","Bar"));
 $bar=new Bar;
@@ -10,4 +9,3 @@
 check::classname("foo",$foo);
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/cpp11_attribute_specifiers_runme.php b/Examples/test-suite/php/cpp11_attribute_specifiers_runme.php
new file mode 100644
index 0000000..2336b31
--- /dev/null
+++ b/Examples/test-suite/php/cpp11_attribute_specifiers_runme.php
@@ -0,0 +1,14 @@
+<?php
+
+require "tests.php";
+
+// New functions
+check::functions(array('noReturn','noDiscard','noDiscardDeprecated','maybeUnused1','maybeUnused2','likely','test_string_literal'));
+// New classes
+check::classes(array('cpp11_attribute_specifiers','S'));
+// No new vars
+check::globals(array());
+
+check::equal(test_string_literal(), 'Test [[ and ]] in string literal', "test_string_literal() wrong");
+
+check::done();
diff --git a/Examples/test-suite/php/cpp11_auto_variable_runme.php b/Examples/test-suite/php/cpp11_auto_variable_runme.php
new file mode 100644
index 0000000..4e2d489
--- /dev/null
+++ b/Examples/test-suite/php/cpp11_auto_variable_runme.php
@@ -0,0 +1,40 @@
+<?php
+
+require "tests.php";
+
+// No new functions
+check::functions(array());
+check::classes(array('cpp11_auto_variable'));
+check::globals(array('f', 't', 'zero', 'one', 'la', 'da', 'fa', 'lc', 'dc', 'fc', 'pi_approx', 'Bar', 'Bar2', 'Bar3', 'Foo', 'Foo2', 'Foo3'));
+
+check::equal(f_get(), false);
+check::equal(gettype(f_get()), "boolean");
+check::equal(t_get(), true);
+check::equal(gettype(t_get()), "boolean");
+
+t_set(false);
+check::equal(t_get(), false);
+
+check::equal(function_exists('f_set'), false, "f should be constant but f_set() exists");
+
+check::equal(zero_get(), 0);
+check::equal(gettype(zero_get()), "integer");
+check::equal(one_get(), 1);
+check::equal(gettype(one_get()), "integer");
+
+zero_set(42);
+check::equal(zero_get(), 42);
+
+check::equal(function_exists('one_set'), false, "one should be constant but one_set() exists");
+
+check::equal(fa_get(), 1.0);
+check::equal(da_get(), 1.0);
+// PHP doesn't have a native "long double" type, so SWIG/PHP doesn't have
+// typemaps for it and so it should get wrapped as an opaque type.
+check::str_contains(la_get(), "SWIGPointer(");
+
+check::equal(fc_get(), 1.0);
+check::equal(dc_get(), 1.0);
+// PHP doesn't have a native "long double" type, so SWIG/PHP doesn't have
+// typemaps for it and so it should get wrapped as an opaque type.
+check::str_contains(lc_get(), "SWIGPointer(");
diff --git a/Examples/test-suite/php/cpp11_decltype_runme.php b/Examples/test-suite/php/cpp11_decltype_runme.php
new file mode 100644
index 0000000..6c19f06
--- /dev/null
+++ b/Examples/test-suite/php/cpp11_decltype_runme.php
@@ -0,0 +1,62 @@
+<?php
+
+require "tests.php";
+
+// No new functions
+check::functions(array());
+check::classes(array('A', 'B'));
+// No new vars
+check::globals(array());
+
+$a = new A();
+
+$a->i = 5;
+check::equal($a->i, 5, 'Assignment to $a->i failed.');
+
+$a->j = 10;
+check::equal($a->j, 10, 'Assignment to $a->j failed.');
+
+$n = $a->get_number(5);
+check::equal($n, 10, 'get_number(5) should return 10.');
+
+$n = $a->get_number(6);
+check::equal($n, 0, 'get_number(6) should return 0.');
+
+$b = new B();
+
+check::equal($b->a, false);
+
+check::equal($b->b, true);
+
+$b->ij = 42;
+check::equal($b->ij, 42, 'Assignment to $b->ij failed.');
+
+$b->i = 7;
+$b->j = 17;
+$n = $b->get_number_sum(0);
+check::equal($n, 24, '$b->get_number_sum(0) should return 24.');
+
+check::equal($b->negate(true), false);
+
+check::equal($b->negate(false), true);
+
+check::equal(gettype($b->should_be_int), "integer");
+check::equal(gettype($b->should_be_int2), "integer");
+check::equal(gettype($b->should_be_int3), "integer");
+check::equal(gettype($b->should_be_int4), "integer");
+check::equal(gettype($b->should_be_int5), "integer");
+check::equal(gettype($b->should_be_int6), "integer");
+check::equal(gettype($b->should_be_int7), "integer");
+check::equal(gettype($b->should_be_int8), "integer");
+check::equal(gettype($b->should_be_int9), "integer");
+check::equal(gettype($b->should_be_int10), "integer");
+
+check::equal(gettype($b->should_be_bool), "boolean");
+
+check::equal(gettype($b::should_be_char), "string");
+check::equal($b::should_be_char, "\0");
+
+check::equal(gettype($b::should_be_string), "string");
+check::equal($b::should_be_string, "xyzzy");
+
+check::equal(gettype($b->should_be_enum), "integer");
diff --git a/Examples/test-suite/php/cpp11_final_directors_runme.php b/Examples/test-suite/php/cpp11_final_directors_runme.php
new file mode 100644
index 0000000..07e04b1
--- /dev/null
+++ b/Examples/test-suite/php/cpp11_final_directors_runme.php
@@ -0,0 +1,16 @@
+<?php
+
+require "tests.php";
+
+// No new functions
+check::functions(array());
+check::classes(array('Base','BaseFinalDestructor','BaseFinalDestructor2','Derived'));
+// No new vars
+check::globals(array());
+
+class Derived2 extends Derived {
+  function meth() { return 3; }
+}
+
+$b = new Derived2();
+check::equal($b->meth(), 3, "Wrong return value");
diff --git a/Examples/test-suite/php/cpp11_move_typemaps_runme.php b/Examples/test-suite/php/cpp11_move_typemaps_runme.php
new file mode 100644
index 0000000..2d4b5e0
--- /dev/null
+++ b/Examples/test-suite/php/cpp11_move_typemaps_runme.php
@@ -0,0 +1,32 @@
+<?php
+
+require "tests.php";
+
+Counter::reset_counts();
+$mo = new MoveOnly(111);
+Counter::check_counts(1, 0, 0, 0, 0, 0);
+MoveOnly::take($mo);
+Counter::check_counts(1, 0, 0, 1, 0, 2);
+$mo = NULL;
+Counter::check_counts(1, 0, 0, 1, 0, 2);
+
+Counter::reset_counts();
+$mo = new MovableCopyable(111);
+Counter::check_counts(1, 0, 0, 0, 0, 0);
+MovableCopyable::take($mo);
+Counter::check_counts(1, 0, 0, 1, 0, 2);
+$mo = NULL;
+Counter::check_counts(1, 0, 0, 1, 0, 2);
+
+$mo = new MoveOnly(222);
+MoveOnly::take($mo);
+$exception_thrown = false;
+try {
+  MoveOnly::take($mo);
+} catch (TypeError $e) {
+  check::str_contains($e->getMessage(), "Cannot release ownership as memory is not owned", "incorrect exception message: {$e->getMessage()}");
+  $exception_thrown = true;
+}
+check::equal($exception_thrown, true, "double usage of takeKlassUniquePtr should have been an error");
+
+check::done();
diff --git a/Examples/test-suite/php/cpp11_rvalue_reference_move_runme.php b/Examples/test-suite/php/cpp11_rvalue_reference_move_runme.php
new file mode 100644
index 0000000..38bb758
--- /dev/null
+++ b/Examples/test-suite/php/cpp11_rvalue_reference_move_runme.php
@@ -0,0 +1,80 @@
+<?php
+
+require "tests.php";
+
+# Function containing rvalue reference parameter
+Counter::reset_counts();
+$mo = new MovableCopyable(222);
+Counter::check_counts(1, 0, 0, 0, 0, 0);
+MovableCopyable::movein($mo);
+Counter::check_counts(1, 0, 0, 1, 0, 2);
+try {
+    MovableCopyable::is_nullptr($mo);
+    check::fail("is_nullptr check");
+} catch (TypeError $e) {
+}
+$mo = NULL;
+Counter::check_counts(1, 0, 0, 1, 0, 2);
+
+# Move constructor test
+Counter::reset_counts();
+$mo = new MovableCopyable(222);
+Counter::check_counts(1, 0, 0, 0, 0, 0);
+$mo_moved = new MovableCopyable($mo);
+Counter::check_counts(1, 0, 0, 1, 0, 1);
+try {
+    MovableCopyable::is_nullptr($mo);
+    check::fail("is_nullptr check");
+} catch (TypeError $e) {
+}
+$mo = NULL;
+Counter::check_counts(1, 0, 0, 1, 0, 1);
+$mo_moved = NULL;
+Counter::check_counts(1, 0, 0, 1, 0, 2);
+
+# Move assignment operator test
+Counter::reset_counts();
+$mo111 = new MovableCopyable(111);
+$mo222 = new MovableCopyable(222);
+Counter::check_counts(2, 0, 0, 0, 0, 0);
+$mo111->MoveAssign($mo222);
+Counter::check_counts(2, 0, 0, 0, 1, 1);
+try {
+    MovableCopyable::is_nullptr($mo222);
+    check::fail("is_nullptr check");
+} catch (TypeError $e) {
+}
+$mo222 = NULL;
+Counter::check_counts(2, 0, 0, 0, 1, 1);
+$mo111 = NULL;
+Counter::check_counts(2, 0, 0, 0, 1, 2);
+
+# null check
+Counter::reset_counts();
+$exception_thrown = false;
+try {
+  MovableCopyable::movein(NULL);
+} catch (TypeError $e) {
+  check::str_contains($e->getMessage(), "Invalid null reference", "incorrect exception message: {$e->getMessage()}");
+  $exception_thrown = true;
+}
+check::equal($exception_thrown, true, "Should have thrown null error");
+Counter::check_counts(0, 0, 0, 0, 0, 0);
+
+# output
+Counter::reset_counts();
+$mc = MovableCopyable::moveout(1234);
+Counter::check_counts(2, 0, 0, 0, 1, 1);
+MovableCopyable::check_numbers_match($mc, 1234);
+
+$exception_thrown = false;
+try {
+  MovableCopyable::movein($mc);
+} catch (TypeError $e) {
+  check::str_contains($e->getMessage(), "Cannot release ownership as memory is not owned", "incorrect exception message: {$e->getMessage()}");
+  $exception_thrown = true;
+}
+check::equal($exception_thrown, true, "Should have thrown 'Cannot release ownership as memory is not owned' error");
+Counter::check_counts(2, 0, 0, 0, 1, 1);
+
+check::done();
diff --git a/Examples/test-suite/php/cpp11_std_unique_ptr_runme.php b/Examples/test-suite/php/cpp11_std_unique_ptr_runme.php
new file mode 100644
index 0000000..425f653
--- /dev/null
+++ b/Examples/test-suite/php/cpp11_std_unique_ptr_runme.php
@@ -0,0 +1,108 @@
+<?php
+
+require "tests.php";
+
+function checkCount($expected_count) {
+    $actual_count = Klass::getTotal_count();
+    check::equal($actual_count, $expected_count, "Counts incorrect");
+}
+
+# Test raw pointer handling involving virtual inheritance
+$kini = new KlassInheritance("KlassInheritanceInput");
+checkCount(1);
+$s = useKlassRawPtr($kini);
+check::equal($s, "KlassInheritanceInput", "Incorrect string: $s");
+$kini = NULL;
+checkCount(0);
+
+
+# unique_ptr as input
+$kin = new Klass("KlassInput");
+checkCount(1);
+$s = takeKlassUniquePtr($kin);
+checkCount(0);
+check::equal($s, "KlassInput", "Incorrect string: $s");
+try {
+    is_nullptr($kin);
+    check::fail("is_nullptr check");
+} catch (TypeError $e) {
+}
+$kin = NULL; # Should not fail, even though already deleted
+checkCount(0);
+
+$kin = new Klass("KlassInput");
+checkCount(1);
+$s = takeKlassUniquePtr($kin);
+checkCount(0);
+check::equal($s, "KlassInput", "Incorrect string: $s");
+try {
+    is_nullptr($kin);
+    check::fail("is_nullptr check");
+} catch (TypeError $e) {
+}
+$exception_thrown = false;
+try {
+  takeKlassUniquePtr($kin);
+} catch (TypeError $e) {
+  check::equal($e->getMessage(), "Cannot release ownership as memory is not owned for argument 1 of SWIGTYPE_p_Klass of takeKlassUniquePtr", "Unexpected exception: {$e->getMessage()}");
+  $exception_thrown = true;
+}
+check::equal($exception_thrown, true, "double usage of takeKlassUniquePtr should have been an error");
+$kin = NULL; # Should not fail, even though already deleted
+checkCount(0);
+
+$kin = new Klass("KlassInput");
+$exception_thrown = false;
+$notowned = get_not_owned_ptr($kin);
+try {
+  takeKlassUniquePtr($notowned);
+} catch (TypeError $e) {
+  check::equal($e->getMessage(), "Cannot release ownership as memory is not owned for argument 1 of SWIGTYPE_p_Klass of takeKlassUniquePtr", "Unexpected exception: {$e->getMessage()}");
+  $exception_thrown = true;
+}
+check::equal($exception_thrown, true, "double usage of takeKlassUniquePtr should have been an error");
+checkCount(1);
+$kin = NULL;
+checkCount(0);
+
+$kini = new KlassInheritance("KlassInheritanceInput");
+checkCount(1);
+$s = takeKlassUniquePtr($kini);
+checkCount(0);
+check::equal($s, "KlassInheritanceInput", "Incorrect string: $s");
+try {
+    is_nullptr($kini);
+    check::fail("is_nullptr check");
+} catch (TypeError $e) {
+}
+
+$kini = NULL; # Should not fail, even though already deleted
+checkCount(0);
+
+takeKlassUniquePtr(NULL);
+takeKlassUniquePtr(make_null());
+checkCount(0);
+
+# overloaded parameters
+check::equal(overloadTest(), 0, "overloadTest failed");
+check::equal(overloadTest(NULL), 1, "overloadTest failed");
+check::equal(overloadTest(new Klass("over")), 1, "overloadTest failed");
+checkCount(0);
+
+
+# unique_ptr as output
+$k1 = makeKlassUniquePtr("first");
+$k2 = makeKlassUniquePtr("second");
+checkCount(2);
+
+$k1 = NULL;
+checkCount(1);
+
+check::equal($k2->getLabel(), "second", "proper label");
+
+$k2 = NULL;
+checkCount(0);
+
+check::equal(makeNullUniquePtr(), NULL);
+
+check::done();
diff --git a/Examples/test-suite/php/cpp11_strongly_typed_enumerations_runme.php b/Examples/test-suite/php/cpp11_strongly_typed_enumerations_runme.php
index bee59b2..ca327d5 100644
--- a/Examples/test-suite/php/cpp11_strongly_typed_enumerations_runme.php
+++ b/Examples/test-suite/php/cpp11_strongly_typed_enumerations_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "cpp11_strongly_typed_enumerations.php";
 
 function enumCheck($actual, $expected) {
   check::equal($actual, $expected, "Enum value mismatch");
@@ -166,4 +165,4 @@
 enumCheck(globalTest2(Class1::Enum12_Val5c), 1121);
 #enumCheck(globalTest3(Class1::Struct1.Enum12_Val5f), 3121);
 
-?>
+check::done();
diff --git a/Examples/test-suite/php/cpp14_auto_return_type_runme.php b/Examples/test-suite/php/cpp14_auto_return_type_runme.php
new file mode 100644
index 0000000..41d9ed8
--- /dev/null
+++ b/Examples/test-suite/php/cpp14_auto_return_type_runme.php
@@ -0,0 +1,14 @@
+<?php
+
+require "tests.php";
+
+check::functions(array('va_static_cast'));
+check::classes(array('cpp14_auto_return_type', 'X'));
+check::classmethods("X",array("__construct","__set","__isset","__get","a"));
+
+// No new vars
+check::globals(array());
+
+check::equal(va_static_cast(), 42);
+$x = new X();
+check::equal($x->a(), "a string");
diff --git a/Examples/test-suite/php/cpp17_director_string_view_runme.php b/Examples/test-suite/php/cpp17_director_string_view_runme.php
new file mode 100644
index 0000000..44a4b7b
--- /dev/null
+++ b/Examples/test-suite/php/cpp17_director_string_view_runme.php
@@ -0,0 +1,42 @@
+<?php
+
+require "tests.php";
+
+// No new functions
+check::functions(array());
+// New classes
+check::classes(array('A'));
+// No new vars
+check::globals(array());
+
+class B extends A {
+  public $smem;
+
+  private $cached_string;
+
+  function get_first() {
+    // Since std::string_view contains a pointer into a string, the string
+    // cannot be a temporary in order to avoid undefined behaviour.
+    $this->cached_string = parent::get_first() . " world!";
+    return $this->cached_string;
+  }
+
+  function process_text($string) {
+    parent::process_text($string);
+    $this->smem = "hello";
+  }
+}
+
+$b = new B("hello");
+
+check::equal($b->get(0), "hello", "get(0) failed");
+
+check::equal($b->get_first(), "hello world!", "get_first failed");
+
+check::equal($b->call_get_first(), "hello world!", "call_get_first failed");
+
+$b->call_process_func();
+
+check::equal($b->smem, "hello", "smem failed");
+
+check::done();
diff --git a/Examples/test-suite/php/cpp17_string_view_runme.php b/Examples/test-suite/php/cpp17_string_view_runme.php
new file mode 100644
index 0000000..ff9b4d2
--- /dev/null
+++ b/Examples/test-suite/php/cpp17_string_view_runme.php
@@ -0,0 +1,51 @@
+<?php
+
+require "tests.php";
+
+# Checking expected use of %typemap(in) std::string_view {}
+cpp17_string_view::test_value("Fee");
+
+# Checking expected result of %typemap(out) std::string_view {}
+check::equal(cpp17_string_view::test_value("Fi"), "Fi", "Test 1");
+
+# Checking expected use of %typemap(in) const std::string_view & {}
+cpp17_string_view::test_const_reference("Fo");
+
+# Checking expected result of %typemap(out) const std::string_view& {}
+check::equal(cpp17_string_view::test_const_reference("Fum"), "Fum", "Test 3");
+
+# Input and output typemaps for pointers and non-const references to
+# std::string_view are *not* supported; the following tests confirm
+# that none of these cases are slipping through.
+
+$stringPtr = cpp17_string_view::test_pointer_out();
+
+cpp17_string_view::test_pointer($stringPtr);
+
+$stringPtr = cpp17_string_view::test_const_pointer_out();
+
+cpp17_string_view::test_const_pointer($stringPtr);
+
+$stringPtr = cpp17_string_view::test_reference_out();
+
+cpp17_string_view::test_reference($stringPtr);
+
+// Global variables
+check::equal(ConstGlobalString_get(), "const global string", "ConstGlobalString test");
+
+// Member variables
+$myStructure = new Structure();
+check::equal($myStructure->ConstMemberString, "const member string", "ConstMemberString test");
+
+check::equal(Structure::ConstStaticMemberString(), "const static member string", "ConstStaticMemberString test");
+
+cpp17_string_view::test_const_reference_returning_void("foo");
+
+check::equal(cpp17_string_view::stdstringview_empty(), "", "stdstringview_empty test");
+check::equal(cpp17_string_view::c_empty(), "", "c_empty test");
+check::isnull(cpp17_string_view::c_null(), "c_null test");
+check::isnull(cpp17_string_view::get_null(cpp17_string_view::c_null()), "get_null c_null test");
+check::equal(cpp17_string_view::get_null(cpp17_string_view::c_empty()), "non-null", "get_null c_empty test");
+check::equal(cpp17_string_view::get_null(cpp17_string_view::stdstringview_empty()), "non-null", "get_null stdstringview_empty test");
+
+check::done();
diff --git a/Examples/test-suite/php/cpp20_spaceship_operator_runme.php b/Examples/test-suite/php/cpp20_spaceship_operator_runme.php
new file mode 100644
index 0000000..00484f7
--- /dev/null
+++ b/Examples/test-suite/php/cpp20_spaceship_operator_runme.php
@@ -0,0 +1,23 @@
+<?php
+
+require "tests.php";
+
+check::functions(array('f', 'spaceship'));
+check::classes(array('cpp20_spaceship_operator','A'));
+check::globals(array('v', 'SPACE'));
+
+//check::equal(ALIEN, true);
+check::equal(SPACE_get(), 1);
+check::equal(COMET, 1);
+check::equal(v_get(), 42);
+
+$x = new A(1);
+$y = new A(2);
+
+check::equal(spaceship($x, $y) < 0, true);
+check::equal(spaceship($x, $x), 0);
+check::equal(spaceship($y, $x) > 0, true);
+
+check::equal(f(), 42);
+
+check::done();
diff --git a/Examples/test-suite/php/cpp_basic_runme.php b/Examples/test-suite/php/cpp_basic_runme.php
index b24cf70..548767c 100644
--- a/Examples/test-suite/php/cpp_basic_runme.php
+++ b/Examples/test-suite/php/cpp_basic_runme.php
@@ -1,14 +1,13 @@
 <?php
 
 require "tests.php";
-require "cpp_basic.php";
 
 // New functions
-check::functions(array('foo_func1','foo_func2','foo___str__','foosubsub___str__','bar_test','bar_testfoo','get_func1_ptr','get_func2_ptr','test_func_ptr','fl_window_show'));
+check::functions(array('get_func1_ptr','get_func2_ptr','get_const_reference','get_reference','test_func_ptr'));
 // New classes
-check::classes(array('cpp_basic','Foo','FooSub','FooSubSub','Bar','Fl_Window'));
-// New vars
-check::globals(array('foo_num','foo_func_ptr','bar_fptr','bar_fref','bar_fval','bar_cint','bar_global_fptr','bar_global_fref','bar_global_fval'));
+check::classes(array('cpp_basic','Foo','FooSub','FooSubSub','Bar','Fl_Window','JustConst'));
+// No new vars
+check::globals(array());
 
 $f = new Foo(3);
 $f->func_ptr = get_func1_ptr();
@@ -16,5 +15,18 @@
 $f->func_ptr = get_func2_ptr();
 check::equal(test_func_ptr($f, 7), -7*3, "get_func2_ptr() didn't work");
 
+// Test that custom properties work when enabled with
+// %feature(php:allowdynamicproperties, 1).
+check::equal($f->custom_prop, NULL, "Test unset custom property");
+$f->custom_prop = "test";
+check::equal($f->custom_prop, "test", "Test custom property setting");
+$f->custom_prop = 42;
+check::equal($f->custom_prop, 42, "Test custom property setting");
+
+// Test that %feature(php:allowdynamicproperties, 0) doesn't enable them
+// (regression test for bug fixed in 4.2.0).
+$b = new Bar();
+$b->custom_prop = 42;
+check::equal($b->custom_prop === 42, false, "Managed to set custom property with %feature(php:allowdynamicproperties, 0)");
+
 check::done();
-?>
diff --git a/Examples/test-suite/php/cpp_enum_runme.php b/Examples/test-suite/php/cpp_enum_runme.php
new file mode 100644
index 0000000..5028f68
--- /dev/null
+++ b/Examples/test-suite/php/cpp_enum_runme.php
@@ -0,0 +1,43 @@
+<?php
+
+require "tests.php";
+
+// New functions
+check::functions(array());
+// New classes
+check::classes(array('cpp_enum', 'StructWithEnums', 'Foo'));
+// New vars
+check::globals(array('hi'));
+
+
+$f = new Foo();
+
+check::equal($f->hola, Foo::Hello);
+
+$f->hola = Foo::Hi;
+check::equal($f->hola, Foo::Hi);
+
+$f->hola = Foo::Hello;
+check::equal($f->hola, Foo::Hello);
+
+$hi = Hello;
+check::equal($hi, Hello);
+
+check::equal(CASE0A, 10);
+check::equal(CASE0B, 10);
+check::equal(CASE0C, 10);
+check::equal(CASE1A, 10);
+check::equal(CASE1B, 10);
+check::equal(CASE1C, 10);
+check::equal(CASE2A, 10);
+check::equal(CASE2B, 10);
+check::equal(CASE2C, 10);
+check::equal(CASE3A, 10);
+check::equal(CASE3B, 10);
+check::equal(CASE3C, 10);
+check::equal(CASE4A, 10);
+check::equal(CASE4B, 10);
+check::equal(CASE4C, 10);
+check::equal(CASE4D, 10);
+
+check::done();
diff --git a/Examples/test-suite/php/cpp_static_runme.php b/Examples/test-suite/php/cpp_static_runme.php
index 20b50dd..2687333 100644
--- a/Examples/test-suite/php/cpp_static_runme.php
+++ b/Examples/test-suite/php/cpp_static_runme.php
@@ -1,14 +1,12 @@
 <?php
 
 require "tests.php";
-require "cpp_static.php";
 
-// New functions
-check::functions(array('staticfunctiontest_static_func','staticfunctiontest_static_func_2','staticfunctiontest_static_func_3','is_python_builtin','staticmembertest_grab_int','staticbase_grab_statty_base','staticderived_grab_statty_derived'));
+// No new functions
+check::functions(array());
 // New classes
 check::classes(array('StaticMemberTest','StaticFunctionTest','cpp_static','StaticBase','StaticDerived'));
-// New vars
-check::globals(array('staticmembertest_static_int','staticbase_statty','staticderived_statty'));
+// No new vars
+check::globals(array());
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/default_args_runme.php b/Examples/test-suite/php/default_args_runme.php
new file mode 100644
index 0000000..cf49322
--- /dev/null
+++ b/Examples/test-suite/php/default_args_runme.php
@@ -0,0 +1,142 @@
+<?php
+require "tests.php";
+
+// New functions
+check::functions(array('doublevalue1','doublevalue2','seek','seek2','seek3','seek4','seek5','seek6','seek7','seek8','seek9','seeka','seekb','anonymous','booltest','casts1','casts2','chartest1','chartest2','chartest3','chartest4','chartest5','chartest6','dummy','afunction','reftest1','reftest2','chops','exceptionspec','constructorcall','cfunc1','cfunc2','cfunc3','slightly_off_square'));
+// New classes
+check::classes(array('TrickyInPython','default_args','EnumClass','DerivedEnumClass','Tree','Foo','MyClass1','MyClass2','Except','Statics','Tricky','Klass','ConstMethods','Pointf','CDA'));
+// New vars
+check::globals(array('CONST_NUM'));
+
+$ec = new EnumClass();
+check::equal($ec->blah(), true, "EnumClass::blah() default arguments don't work");
+
+$de = new DerivedEnumClass();
+$de->accelerate();
+$de->accelerate(EnumClass::SLOW);
+
+check::equal(Statics::staticMethod(), 60, "Statics::staticMethod()");
+
+check::equal(cfunc1(1), 2.0, "cfunc1(1)");
+
+check::equal(cfunc2(1), 3.0, "cfunc2(1)");
+
+check::equal(cfunc3(1), 4.0, "cfunc3(1)");
+
+$f = new Foo();
+
+$f->newname();
+$f->newname(1);
+$f->defaulted1();
+$f->defaulted2();
+
+check::equal($f->double_if_void_ptr_is_null(2, Null), 4, "\$f->double_if_void_ptr_is_null(2, Null)");
+
+check::equal($f->double_if_void_ptr_is_null(3), 6, "\$f->double_if_void_ptr_is_null(3)");
+
+check::equal($f->double_if_void_ptr_is_null(4, Null), 8, "\$f->double_if_void_ptr_is_null(4, Null)");
+
+check::equal($f->double_if_void_ptr_is_null(5, Null), 10, "\$f->double_if_void_ptr_is_null(5, Null)");
+
+check::equal($f->double_if_void_ptr_is_null(6, Null), 12, "\$f->double_if_void_ptr_is_null(6, Null)");
+
+check::equal($f->double_if_void_ptr_is_null(7), 14, "\$f->double_if_void_ptr_is_null(7)");
+
+try {
+    $f = new Foo(1);
+    check::fail("Foo::Foo ignore is not working");
+} catch (ArgumentCountError $e) {
+}
+
+try {
+    $f = new Foo(1, 2);
+    check::fail("Foo::Foo ignore is not working");
+} catch (ArgumentCountError $e) {
+}
+
+try {
+    $f = new Foo(1, 2, 3);
+    check::fail("Foo::Foo ignore is not working");
+} catch (ArgumentCountError $e) {
+}
+
+try {
+    $m = $f->meth(1);
+    check::fail("Foo::meth ignore is not working");
+} catch (Error $e) {
+}
+
+try {
+    $m = $f->meth(1, 2);
+    check::fail("Foo::meth ignore is not working");
+} catch (Error $e) {
+}
+
+try {
+    $m = $f->meth(1, 2, 3);
+    check::fail("Foo::meth ignore is not working");
+} catch (Error $e) {
+}
+
+check::equal(Klass::inc(100, new Klass(22))->val, 122, "Klass::inc failed");
+
+check::equal(klass::inc(100)->val, 99, "klass::inc failed");
+
+check::equal(klass::inc()->val, 0, "klass::inc failed");
+
+$tricky = new TrickyInPython();
+check::equal($tricky->value_m1(10), -1, "trickyvalue_m1 failed");
+check::equal($tricky->value_m1(10, 10), 10, "trickyvalue_m1 failed");
+check::equal($tricky->value_0xabcdef(10), 0xabcdef, "trickyvalue_0xabcdef failed");
+check::equal($tricky->value_0644(10), 420, "trickyvalue_0644 failed");
+check::equal($tricky->value_perm(10), 420, "trickyvalue_perm failed");
+check::equal($tricky->value_m01(10), -1, "trickyvalue_m01 failed");
+check::equal($tricky->booltest2(), True, "booltest2 failed");
+
+check::equal($tricky->max_32bit_int1(), 0x7FFFFFFF, "max_32bit_int1 failed");
+// On 32-bit platforms -2147483648 is a PHP float (rather than
+// PHP int on 64-bit platforms) so only check equivalence rather
+// than strict equality.
+check::equivalent($tricky->min_32bit_int1(), -2147483648, "min_32bit_int1 failed");
+check::equal($tricky->max_32bit_int2(), 0x7FFFFFFF, "max_32bit_int2 failed");
+
+$tricky->too_big_32bit_int1();
+$tricky->too_small_32bit_int1();
+$tricky->too_big_32bit_int2();
+$tricky->too_small_32bit_int2();
+
+seek();
+seek(10);
+
+check::equal(booltest(), True, "booltest failed");
+
+check::equal(slightly_off_square(10), 102, "slightly_off_square(10)");
+
+check::equal(slightly_off_square(), 291, "slightly_off_square()");
+
+check::equal(chartest1(), "x", "chartest1()");
+
+check::equal(chartest2(), "\0", "chartest2()");
+
+check::equal(chartest3(), "\1", "chartest3()");
+
+check::equal(chartest4(), "\n", "chartest4()");
+
+check::equal(chartest5(), "B", "chartest5()");
+
+check::equal(chartest6(), "C", "chartest6()");
+
+// Regression test for bug in initial implementation of PHP type declarations.
+$p = (new ReflectionMethod('TrickyInPython', 'value_m1'))->getParameters();
+// empty array in buggy version
+check::equal(count($p), 2, "Expected 2 parameters");
+check::equal((string)$p[0]->getType(), 'int', "Expected int parameter");
+check::equal((string)$p[1]->getType(), 'int', "Expected int parameter");
+
+$p = (new ReflectionMethod('EnumClass', 'blah'))->getParameters();
+// empty array in buggy version
+check::equal(count($p), 2, "Expected 2 parameters");
+check::equal((string)$p[0]->getType(), 'int', "Expected int parameter");
+check::equal((string)$p[1]->getType(), 'int', "Expected int parameter");
+
+check::done();
diff --git a/Examples/test-suite/php/director_abstract_runme.php b/Examples/test-suite/php/director_abstract_runme.php
index 1a119cf..2d9799f 100644
--- a/Examples/test-suite/php/director_abstract_runme.php
+++ b/Examples/test-suite/php/director_abstract_runme.php
@@ -1,13 +1,12 @@
 <?php
 
 require "tests.php";
-require "director_abstract.php";
 
-// No new functions
-check::functions(array('foo_ping','foo_pong','example0_getxsize','example0_color','example0_get_color','example1_getxsize','example1_color','example1_get_color','example2_getxsize','example2_color','example2_get_color','example4_getxsize','example4_color','example4_get_color','example3_i_color','example3_i_get_color','g','a_f'));
-// No new classes
+// New functions
+check::functions(array('g'));
+// New classes
 check::classes(array('director_abstract','Foo','Example0','Example1','Example2','Example4','Example3_i','A'));
-// now new vars
+// No new vars
 check::globals(array());
 
 class MyFoo extends Foo {
@@ -23,19 +22,19 @@
 check::equal($a->pong(), "Foo::pong();MyFoo::ping()", "MyFoo::pong failed");
 
 class MyExample1 extends Example1 {
-  function Color($r, $g, $b) {
+  function Color($r, $g = NULL, $b = NULL) {
     return $r;
   }
 }
 
 class MyExample2 extends Example1 {
-  function Color($r, $g, $b) {
+  function Color($r, $g = NULL, $b = NULL) {
     return $g;
   }
 }
 
 class MyExample3 extends Example1 {
-  function Color($r, $g, $b) {
+  function Color($r, $g = NULL, $b = NULL) {
     return $b;
   }
 }
@@ -59,4 +58,3 @@
 check::equal($class->isAbstract(), true, "Example3_i abstractness failed");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/director_alternating_runme.php b/Examples/test-suite/php/director_alternating_runme.php
new file mode 100644
index 0000000..de33038
--- /dev/null
+++ b/Examples/test-suite/php/director_alternating_runme.php
@@ -0,0 +1,11 @@
+<?php
+
+require "tests.php";
+
+check::functions(array('getBar','idFromGetBar'));
+check::classes(array('Foo','Bar','Baz','director_alternating'));
+// No new vars
+check::globals(array());
+
+$id = director_alternating::getBar()->id();
+check::equal($id, director_alternating::idFromGetBar(), "idFromGetBar() failed");
diff --git a/Examples/test-suite/php/director_basic_runme.php b/Examples/test-suite/php/director_basic_runme.php
index 478a36f..db7adef 100644
--- a/Examples/test-suite/php/director_basic_runme.php
+++ b/Examples/test-suite/php/director_basic_runme.php
@@ -1,14 +1,12 @@
 <?php
 
 require "tests.php";
-require "director_basic.php";
 
 // No new functions
-check::functions(array('foo_ping','foo_pong','foo_get_self','a_f','a_rg','a1_ff','myclass_method','myclass_vmethod','myclass_pmethod','myclass_cmethod','myclass_get_self','myclass_call_pmethod','myclasst_i_method','myclass_nonvirtual','myclass_nonoverride','myclass_call_nonvirtual','myclass_call_nonoverride','myclass_connect'));
-// No new classes
-check::classes(array('Foo','A','A1','Bar','MyClass','MyClassT_i'));
-// now new vars
-check::globals(array('bar_x'));
+check::functions(array());
+check::classes(array('Foo','A','A1','Bar','MyClass','MyClassT_i','ConstPtrClass'));
+// No new vars
+check::globals(array());
 
 class PhpFoo extends Foo {
   function ping() {
@@ -55,4 +53,3 @@
 check::equal($bd->x, 16, "bd failed");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/director_classes_runme.php b/Examples/test-suite/php/director_classes_runme.php
new file mode 100644
index 0000000..c25d85d
--- /dev/null
+++ b/Examples/test-suite/php/director_classes_runme.php
@@ -0,0 +1,79 @@
+<?php
+require "tests.php";
+
+// No new functions
+check::functions(array());
+// New classes
+check::classes(array('director_classes', 'Base', 'BaseClass', 'Caller', 'Derived', 'DerivedClass', 'DoubleHolder'));
+// New vars
+check::globals(array('PrintDebug'));
+
+class PHPDerived extends Base {
+  function Val(DoubleHolder $x) { return $x; }
+  function Ref(DoubleHolder $x) { return $x; }
+  function Ptr(?DoubleHolder $x) { return $x; }
+  function ConstPtrRef(?DoubleHolder $x) { return $x; }
+  function FullyOverloaded($x) {
+    $rv = parent::FullyOverloaded($x);
+    $rv = preg_replace('/Base/', 'PHPDerived', $rv);
+    return $rv;
+  }
+  function SemiOverloaded($x) {
+    # this is going to be awkward because we can't really
+    # semi-overload in PHP, but we can sort of fake it.
+    if (!is_int($x)) {
+      return parent::SemiOverloaded($x);
+    }
+    $rv = parent::SemiOverloaded($x);
+    $rv = preg_replace('/Base/', 'PHPDerived', $rv);
+    return $rv;
+  }
+  function DefaultParms(int $x, float $y = 1.125) {
+    $rv = parent::DefaultParms($x, $y);
+    $rv = preg_replace('/Base/', 'PHPDerived', $rv);
+    return $rv;
+  }
+}
+
+{
+  $c = new Caller();
+  makeCalls($c, new Base(100.0));
+  makeCalls($c, new Derived(200.0));
+  makeCalls($c, new PHPDerived(300.0));
+}
+
+function makeCalls($caller, $base) {
+  $bname = get_class($base);
+  if ($bname == 'PHPDerived') {
+      // TODO: Debug and make this work:
+      return;
+  }
+  $caller->set($base);
+  $dh = new DoubleHolder(444.555);
+  check::equal($caller->ValCall($dh)->val, $dh->val, "$bname.Val");
+  check::equal($caller->RefCall($dh)->val, $dh->val, "$bname.Ref");
+  check::equal($caller->PtrCall($dh)->val, $dh->val, "$bname.Ptr");
+  check::equal($caller->ConstPtrRefCall($dh)->val, $dh->val, "$bname.ConstPtrRef");
+  check::equal($caller->FullyOverloadedCall(1),
+	       "{$bname}::FullyOverloaded(int)",
+	       "$bname.FullyOverloaded(int)");
+  check::equal($caller->FullyOverloadedCall(false),
+	       "{$bname}::FullyOverloaded(bool)",
+	       "$bname.FullyOverloaded(bool)");
+  // This next one is TODO for Perl with PerlDerived.
+  check::equal($caller->SemiOverloadedCall(-678),
+	       "{$bname}::SemiOverloaded(int)",
+	       "$bname.SemiOverloaded(int)");
+  check::equal($caller->SemiOverloadedCall(false),
+	       "Base::SemiOverloaded(bool)",
+	       "$bname.SemiOverloaded(bool)");
+  check::equal($caller->DefaultParmsCall(10, 2.2),
+	       "{$bname}::DefaultParms(int, double)",
+	       "$bname.DefaultParms(int, double)");
+  check::equal($caller->DefaultParmsCall(10),
+	       "{$bname}::DefaultParms(int)",
+	       "$bname.DefaultParms(int)");
+  $caller->reset();
+}
+
+check::done();
diff --git a/Examples/test-suite/php/director_classic_runme.php b/Examples/test-suite/php/director_classic_runme.php
index a44881e..e2ac1f7 100644
--- a/Examples/test-suite/php/director_classic_runme.php
+++ b/Examples/test-suite/php/director_classic_runme.php
@@ -1,13 +1,12 @@
 <?php
 
 require "tests.php";
-require "director_classic.php";
 
 // No new functions
-check::functions(array('being_id','person_id','child_id','grandchild_id','caller_delcallback','caller_setcallback','caller_resetcallback','caller_call','caller_baseclass'));
-// No new classes
+check::functions(array());
+// New classes
 check::classes(array('Being','Person','Child','GrandChild','OrphanPerson','OrphanChild','Caller'));
-// now new vars
+// No new vars
 check::globals(array());
 
 class TargetLangPerson extends Person {
@@ -81,11 +80,7 @@
   $ret = $baseclass->id();
   if ($debug)
     print $ret . "\n";
-  # TODO: Currently we do not track the dynamic type of returned 
-  # objects, so in case it's possible that the dynamic type is not equal 
-  # to the static type, we skip this check.
-  if (get_parent_class($person) === false)
-    check::equal($ret, $expected, "#3 failed");
+  check::equal($ret, $expected, "#3 failed");
 
   $caller->resetCallback();
   if ($debug)
@@ -147,4 +142,3 @@
 unset($person);
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/director_default_runme.php b/Examples/test-suite/php/director_default_runme.php
index c459ce3..92e4150 100644
--- a/Examples/test-suite/php/director_default_runme.php
+++ b/Examples/test-suite/php/director_default_runme.php
@@ -1,13 +1,12 @@
 <?php
 
 require "tests.php";
-require "director_default.php";
 
 // No new functions
-check::functions(array('foo_msg','foo_getmsg','bar_msg','bar_getmsg','defaultsbase_defaultargs','defaultsderived_defaultargs'));
-// No new classes
+check::functions(array());
+// New classes
 check::classes(array('Foo','Bar','DefaultsBase','DefaultsDerived'));
-// now new vars
+// No new vars
 check::globals(array());
 
 $f = new Foo();
@@ -17,4 +16,3 @@
 $f = new Bar(1);
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/director_detect_runme.php b/Examples/test-suite/php/director_detect_runme.php
index a6d3aeb..b9d0a6e 100644
--- a/Examples/test-suite/php/director_detect_runme.php
+++ b/Examples/test-suite/php/director_detect_runme.php
@@ -1,16 +1,17 @@
 <?php
 
 require "tests.php";
-require "director_detect.php";
 
 // No new functions
-check::functions(array('foo_cloner','foo_get_value','foo_get_class','foo_just_do_it','bar_baseclass','bar_cloner','bar_get_value','bar_get_class','bar_just_do_it'));
-// No new classes
+check::functions(array());
+// New classes
 check::classes(array('A','Foo','Bar'));
-// now new vars
+// No new vars
 check::globals(array());
 
 class MyBar extends Bar {
+  public $val;
+
   function __construct($val = 2) {
     parent::__construct();
     $this->val = $val;
@@ -52,4 +53,3 @@
 check::equal($vc, 6, "c: Bad virtual detection");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/director_enum_runme.php b/Examples/test-suite/php/director_enum_runme.php
index 0571ec0..21e07a5 100644
--- a/Examples/test-suite/php/director_enum_runme.php
+++ b/Examples/test-suite/php/director_enum_runme.php
@@ -1,13 +1,12 @@
 <?php
 
 require "tests.php";
-require "director_enum.php";
 
 // No new functions
-check::functions(array('foo_say_hello','foo_say_hi','foo_say_bye','foo_say_hi_ref','foo_ping','foo_ping_ref','foo_ping_member_enum','a_f','a2_f'));
-// No new classes
+check::functions(array());
+// New classes
 check::classes(array('director_enum','Foo','A','B','A2','B2'));
-// now new vars
+// No new vars
 check::globals(array());
 
 class MyFoo extends Foo {
@@ -22,4 +21,3 @@
 check::equal($a->say_hi(director_enum::hello), $b->say_hello(director_enum::hi), "say failed");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/director_exception_catches_runme.php b/Examples/test-suite/php/director_exception_catches_runme.php
new file mode 100644
index 0000000..51c5663
--- /dev/null
+++ b/Examples/test-suite/php/director_exception_catches_runme.php
@@ -0,0 +1,26 @@
+<?php
+
+require "tests.php";
+
+// No new functions
+check::functions(array());
+// New classes
+check::classes(array('BaseClass'));
+// No new vars
+check::globals(array());
+
+class MyClass extends BaseClass {
+  function description() {
+    throw new Exception("Testing exception thrown in description()");
+  }
+}
+
+$b = new MyClass();
+try {
+    BaseClass::call_description($b);
+    check::fail("No exception thrown by BaseClass::call_description(\$b)");
+} catch (Exception $e) {
+    check::equal($e->getMessage(), "Testing exception thrown in description()", "Unexpected exception message: ".$e->getMessage());
+}
+
+check::done();
diff --git a/Examples/test-suite/php/director_exception_nothrow_runme.php b/Examples/test-suite/php/director_exception_nothrow_runme.php
new file mode 100644
index 0000000..2bc4a0c
--- /dev/null
+++ b/Examples/test-suite/php/director_exception_nothrow_runme.php
@@ -0,0 +1,23 @@
+<?php
+
+require "tests.php";
+
+// No new functions
+check::functions(array());
+// New classes
+check::classes(array('Bar', 'Base'));
+// No new vars
+check::globals(array());
+
+class MyBar extends Bar {
+  function pang() {
+    return "MyBar::pang()";
+  }
+}
+
+$a = new MyBar();
+check::equal($a->pang(), "MyBar::pang()", "MyBar::pang() not called as expected");
+$b = new Bar();
+check::equal($b->pang(), "Bar::pang()", "Bar::pang() not called as expected");
+
+check::done();
diff --git a/Examples/test-suite/php/director_exception_runme.php b/Examples/test-suite/php/director_exception_runme.php
index dd2d04e..6f33df0 100644
--- a/Examples/test-suite/php/director_exception_runme.php
+++ b/Examples/test-suite/php/director_exception_runme.php
@@ -1,16 +1,17 @@
 <?php
 
 require "tests.php";
-require "director_exception.php";
 
-// No new functions
-check::functions(array('foo_ping','foo_pong','launder','bar_ping','bar_pong','returnalltypes_return_int','returnalltypes_return_double','returnalltypes_return_const_char_star','returnalltypes_return_std_string','returnalltypes_return_bar','returnalltypes_call_int','returnalltypes_call_double','returnalltypes_call_const_char_star','returnalltypes_call_std_string','returnalltypes_call_bar','is_python_builtin'));
-// No new classes
+// New functions
+check::functions(array('launder'));
+// New classes
 check::classes(array('director_exception','Foo','Exception1','Exception2','Base','Bar','ReturnAllTypes'));
-// now new vars
+// No new vars
 check::globals(array());
 
 class MyException extends Exception {
+  public $msg;
+
   function __construct($a, $b) {
     $this->msg = $a . $b;
   }
@@ -38,9 +39,7 @@
 # MyFoo.pong().
 $ok = 0;
 $a = new MyFoo();
-# TODO: Currently we do not track the dynamic type of returned 
-# objects, so we skip the launder() call.
-#$b = director_exception::launder($a);
+$b = director_exception::launder($a);
 $b = $a;
 try {
   $b->pong();
@@ -124,4 +123,3 @@
 }
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/director_extend_runme.php b/Examples/test-suite/php/director_extend_runme.php
index 7aa2e0f..3c6dd6b 100644
--- a/Examples/test-suite/php/director_extend_runme.php
+++ b/Examples/test-suite/php/director_extend_runme.php
@@ -1,13 +1,12 @@
 <?php
 
 require "tests.php";
-require "director_extend.php";
 
 // No new functions
-check::functions(array('spobject_getfoobar','spobject_dummy','spobject_exceptionmethod'));
-// No new classes
+check::functions(array());
+// New classes
 check::classes(array('SpObject'));
-// now new vars
+// No new vars
 check::globals(array());
 
 class MyObject extends SpObject{
@@ -18,7 +17,6 @@
 
 $m = new MyObject();
 check::equal($m->dummy(), 666, "1st call");
-check::equal($m->dummy(), 666, "2st call"); // Locked system
+check::equal($m->dummy(), 666, "2nd call"); // Locked system
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/director_finalizer_runme.php b/Examples/test-suite/php/director_finalizer_runme.php
index 96bb5c1..689f445 100644
--- a/Examples/test-suite/php/director_finalizer_runme.php
+++ b/Examples/test-suite/php/director_finalizer_runme.php
@@ -1,19 +1,23 @@
 <?php
 
 require "tests.php";
-require "director_finalizer.php";
 
-// No new functions
-check::functions(array('foo_orstatus','deletefoo','getstatus','launder','resetstatus'));
-// No new classes
+// New functions
+check::functions(array('deleteFoo','getStatus','launder','resetStatus'));
+// New classes
 check::classes(array('director_finalizer','Foo'));
-// now new vars
+// No new vars
 check::globals(array());
 
 class MyFoo extends Foo {
   function __destruct() {
-    $this->orStatus(2);
-    if (method_exists(get_parent_class(), "__destruct")) {
+    # It's not safe to call methods on the C++ object from the PHP destructor
+    # if the object has been disowned, since the C++ object will already have
+    # been destroyed by the time the PHP destructor runs.
+    if ($this->thisown) {
+      $this->orStatus(2);
+    }
+    if (method_exists(parent::class, "__destruct")) {
       parent::__destruct();
     }
   }
@@ -41,21 +45,24 @@
 
 $a = new MyFoo();
 $a->thisown = 0;
+check::equal(getStatus(), 0, "shadow release does not fire destructor of disowned object");
+
 deleteFoo($a);
 unset($a);
 
-check::equal(getStatus(), 3, "getStatus() failed #4");
+# getStatus() would ideally return 3 here.
+check::equal(getStatus(), 1, "getStatus() failed #4");
 
 resetStatus();
 
 $a = new MyFoo();
 $a->thisown = 0;
-deleteFoo(launder($a));
+$g = launder($a);
 unset($a);
-
-check::equal(getStatus(), 3, "getStatus() failed #5");
+deleteFoo($g);
+# getStatus() would ideally return 3 here.
+check::equal(getStatus(), 1, "getStatus() failed #5");
 
 resetStatus();
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/director_frob_runme.php b/Examples/test-suite/php/director_frob_runme.php
index 450a123..732b9d5 100644
--- a/Examples/test-suite/php/director_frob_runme.php
+++ b/Examples/test-suite/php/director_frob_runme.php
@@ -1,14 +1,13 @@
 <?php
 
 require "tests.php";
-require "director_frob.php";
 
 // No new functions
-check::functions(array('alpha_abs_method','bravo_abs_method','charlie_abs_method','ops_opint','ops_opintstarstarconst','ops_opintamp','ops_opintstar','ops_opconstintintstar','prims_ull','prims_callull','corecallbacks_on3dengineredrawn','corecallbacks_on3dengineredrawn2'));
-// No new classes
+check::functions(array());
+// New classes
 check::classes(array('Alpha','Bravo','Charlie','Delta','Ops','Prims','corePoint3d','coreCallbacks_On3dEngineRedrawnData','coreCallbacksOn3dEngineRedrawnData','coreCallbacks'));
-// now new vars
-check::globals(array('corecallbacks_on3dengineredrawndata__eye','corecallbacks_on3dengineredrawndata__at','corecallbackson3dengineredrawndata__eye','corecallbackson3dengineredrawndata__at'));
+// No new vars
+check::globals(array());
 
 $foo = new Bravo();
 $s = $foo->abs_method();
@@ -16,4 +15,3 @@
 check::equal($s, "Bravo::abs_method()", "s failed");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/director_ignore_runme.php b/Examples/test-suite/php/director_ignore_runme.php
new file mode 100644
index 0000000..87bc475
--- /dev/null
+++ b/Examples/test-suite/php/director_ignore_runme.php
@@ -0,0 +1,24 @@
+<?php
+
+require "tests.php";
+
+// No new functions
+check::functions(array());
+check::classes(array('DAbstractIgnores','DIgnores','DTemplateAbstractIgnoresInt','DIgnoreConstructor','DIgnoreOnlyConstructor','DIgnoreDestructor'));
+// No new vars
+check::globals(array());
+
+class DIgnoresDerived extends DIgnores {
+  function PublicMethod1() {
+    return 18.75;
+  }
+}
+
+class DAbstractIgnoresDerived extends DAbstractIgnores {
+}
+
+$a = new DIgnoresDerived();
+check::equal($a->Triple(5), 15, "Wrong return value");
+
+$b = new DAbstractIgnoresDerived();
+check::equal($b->Quadruple(5), 20, "Wrong return value");
diff --git a/Examples/test-suite/php/director_nested_runme.php b/Examples/test-suite/php/director_nested_runme.php
index 9a094a1..adf9f62 100644
--- a/Examples/test-suite/php/director_nested_runme.php
+++ b/Examples/test-suite/php/director_nested_runme.php
@@ -1,13 +1,12 @@
 <?php
 
 require "tests.php";
-require "director_nested.php";
 
 // No new functions
-check::functions(array('foo_int_advance','foo_int_do_advance','bar_step','bar_do_advance','bar_do_step','foobar_int_get_value','foobar_int_get_name','foobar_int_name','foobar_int_get_self','foobar_int_do_advance','foobar_int_do_step'));
-// No new classes
+check::functions(array());
+// New classes
 check::classes(array('Foo_int','Bar','FooBar_int'));
-// now new vars
+// No new vars
 check::globals(array());
 
 class A extends FooBar_int {
@@ -60,10 +59,7 @@
 }
 
 $cc = new C();
-# TODO: Currently we do not track the dynamic type of returned 
-# objects, so we skip the get_self() call.
-#$c = Foobar_int::get_self($cc);
-$c = $cc;
+$c = Foobar_int::get_self($cc);
 $c->advance();
 
 check::equal($c->get_name(), "FooBar::get_name hello", "get_name failed");
@@ -71,4 +67,3 @@
 check::equal($c->name(), "FooBar::get_name hello", "name failed");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/director_overload_runme.php b/Examples/test-suite/php/director_overload_runme.php
new file mode 100644
index 0000000..07b485d
--- /dev/null
+++ b/Examples/test-suite/php/director_overload_runme.php
@@ -0,0 +1,14 @@
+<?php
+
+require "tests.php";
+
+check::functions(array());
+check::classes(array('OverloadedClass','OverloadedPointers','OverloadedGetSet'));
+check::globals(array());
+
+$o = new OverloadedGetSet;
+check::equal($o->rw(), 42, "get_set() initial value not 42");
+check::equal($o->rw(7), null, "get_set() failed to set");
+check::equal($o->rw(), 7, "get_set() didn't return back set value");
+
+check::done();
diff --git a/Examples/test-suite/php/director_ownership_runme.php b/Examples/test-suite/php/director_ownership_runme.php
new file mode 100644
index 0000000..a78fb9c
--- /dev/null
+++ b/Examples/test-suite/php/director_ownership_runme.php
@@ -0,0 +1,28 @@
+<?php
+require "tests.php";
+
+check::functions(array('make_content'));
+check::classes(array('ContentBase','ContentDerived','Container','director_ownership'));
+// No new vars
+check::globals(array());
+
+function set_content_and_release(Container $container, ContentBase $content) {
+  $content->thisown = false;
+  $container->set_content($content);
+}
+
+$container = new Container();
+
+// make a content in PHP (newobject is 1)
+$content_php = new ContentDerived();
+
+// make a content in C++ (newobject is 1)
+$content_cpp = make_content();
+
+set_content_and_release($container, $content_php);
+check::equal($container->get_content()->get_name(), "ContentDerived", "get_content() not ContentDerived");
+
+set_content_and_release($container, $content_cpp);
+check::equal($container->get_content()->get_name(), "ContentDerived", "get_content() not ContentDerived");
+
+check::done();
diff --git a/Examples/test-suite/php/director_pass_by_value_runme.php b/Examples/test-suite/php/director_pass_by_value_runme.php
index 8a8b84d..b8f1bb9 100644
--- a/Examples/test-suite/php/director_pass_by_value_runme.php
+++ b/Examples/test-suite/php/director_pass_by_value_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "director_pass_by_value.php";
 
 $passByVal = null;
 
@@ -15,10 +14,12 @@
 # bug was the passByVal global object was destroyed after the call to virtualMethod had finished.
 $caller = new Caller();
 $caller->call_virtualMethod(new director_pass_by_value_Derived());
+if (has_cplusplus11()) {
+  Counter::check_counts(1, 0, 0, 1, 0, 1); # check move constructor called and just one destructor
+}
 $ret = $passByVal->getVal();
 if ($ret != 0x12345678) {
   check::fail("Bad return value, got " . dechex($ret));
 }
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/director_profile_runme.php b/Examples/test-suite/php/director_profile_runme.php
index c6f4c3c..219ec81 100644
--- a/Examples/test-suite/php/director_profile_runme.php
+++ b/Examples/test-suite/php/director_profile_runme.php
@@ -1,13 +1,12 @@
 <?php
 
 require "tests.php";
-require "director_profile.php";
 
 // No new functions
-check::functions(array('b_fn','b_vfi','b_fi','b_fj','b_fk','b_fl','b_get_self','b_vfs','b_fs'));
-// No new classes
+check::functions(array());
+// New classes
 check::classes(array('A','B'));
-// now new vars
+// No new vars
 check::globals(array());
 
 class MyB extends B {
@@ -50,4 +49,3 @@
 print $a . "\n";
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/director_protected_runme.php b/Examples/test-suite/php/director_protected_runme.php
index e759fed..b73c8f8 100644
--- a/Examples/test-suite/php/director_protected_runme.php
+++ b/Examples/test-suite/php/director_protected_runme.php
@@ -1,11 +1,12 @@
 <?php
 
 require "tests.php";
-require "director_protected.php";
 
-check::functions(array('foo_pong','foo_s','foo_q','foo_ping','foo_pang','foo_used','foo_cheer','bar_create','bar_callping','bar_callcheer','bar_cheer','bar_pong','bar_used','bar_ping','bar_pang','a_draw','b_draw'));
+// No new functions
+check::functions(array());
 check::classes(array('Foo','Bar','PrivateFoo','A','B','AA','BB'));
-check::globals(array('bar_a'));
+// No new vars
+check::globals(array());
 
 class FooBar extends Bar {
   protected function ping() {
@@ -67,4 +68,3 @@
 check::equal($fb3->callcheer(), "FooBar3::cheer();", "bad fb3::callcheer");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/director_stl_runme.php b/Examples/test-suite/php/director_stl_runme.php
index f7a5c0a..031a87a 100644
--- a/Examples/test-suite/php/director_stl_runme.php
+++ b/Examples/test-suite/php/director_stl_runme.php
@@ -1,13 +1,12 @@
 <?php
 
 require "tests.php";
-require "director_stl.php";
 
 // No new functions
-check::functions(array('foo_bar','foo_ping','foo_pong','foo_tping','foo_tpong','foo_pident','foo_vident','foo_vsecond','foo_tpident','foo_tvident','foo_tvsecond','foo_vidents','foo_tvidents'));
-// No new classes
+check::functions(array());
+// New classes
 check::classes(array('Foo'));
-// now new vars
+// No new vars
 check::globals(array());
 
 class MyFoo extends Foo {
@@ -27,7 +26,7 @@
     return $v;
   }
 
-  function vsecond($v1, $v2) {
+  function vsecond($v1, $v2 = NULL) {
     return $v2;
   }
 }
@@ -57,4 +56,3 @@
 $a->tvidents($vs);*/
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/director_string_runme.php b/Examples/test-suite/php/director_string_runme.php
index 77e84c9..47121e7 100644
--- a/Examples/test-suite/php/director_string_runme.php
+++ b/Examples/test-suite/php/director_string_runme.php
@@ -1,16 +1,17 @@
 <?php
 
 require "tests.php";
-require "director_string.php";
 
 // No new functions
-check::functions(array('a_get_first','a_call_get_first','a_string_length','a_process_text','a_call_process_func','stringvector_size','stringvector_is_empty','stringvector_clear','stringvector_push','stringvector_pop','stringvector_capacity','stringvector_reserve'));
-// No new classes
+check::functions(array());
+// New classes
 check::classes(array('A','StringVector'));
-// now new vars
-check::globals(array('a','a_call','a_m_strings','stringvector'));
+// No new vars
+check::globals(array());
 
 class B extends A {
+  public $smem;
+
   function get_first() {
     return parent::get_first() . " world!";
   }
@@ -23,12 +24,14 @@
 
 $b = new B("hello");
 
-$b->get(0);
-check::equal($b->get_first(),"hello world!", "get_first failed");
+check::equal($b->get(0), "hello", "get(0) failed");
+
+check::equal($b->get_first(), "hello world!", "get_first failed");
+
+check::equal($b->call_get_first(), "hello world!", "call_get_first failed");
 
 $b->call_process_func();
 
 check::equal($b->smem, "hello", "smem failed");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/director_thread_runme.php b/Examples/test-suite/php/director_thread_runme.php
index 2a640a0..e4eb368 100644
--- a/Examples/test-suite/php/director_thread_runme.php
+++ b/Examples/test-suite/php/director_thread_runme.php
@@ -1,18 +1,17 @@
 <?php
 
 require "tests.php";
-require "director_thread.php";
 
 # Fails in a ZTS-build of PHP5 - see: https://github.com/swig/swig/pull/155
-# FIXME: Does this still fail in a threaded build of PHP7?
+# FIXME: Does this still fail in a threaded build of PHP8?
 exit(0);
 
-// No new functions
+// New functions
 check::functions(array('millisecondsleep','foo_stop','foo_run','foo_do_foo'));
-// No new classes
+// New classes
 check::classes(array('director_thread','Foo'));
-// now new vars
-check::globals(array('foo_val'));
+// No new vars
+check::globals(array());
 
 class Derived extends Foo {
   function do_foo() {
@@ -30,4 +29,3 @@
 $d->stop();
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/director_unroll_runme.php b/Examples/test-suite/php/director_unroll_runme.php
index e310188..7f94753 100644
--- a/Examples/test-suite/php/director_unroll_runme.php
+++ b/Examples/test-suite/php/director_unroll_runme.php
@@ -1,14 +1,13 @@
 <?php
 
 require "tests.php";
-require "director_unroll.php";
 
 // No new functions
-check::functions(array('foo_ping','foo_pong'));
-// No new classes
+check::functions(array());
+// New classes
 check::classes(array('Foo','Bar'));
-// now new vars
-check::globals(array('bar'));
+// No new vars
+check::globals(array());
 
 class MyFoo extends Foo {
   function ping() {
@@ -23,10 +22,7 @@
 $b->set($a);
 $c = $b->get();
 
-// FIXME: This doesn't work for checking that they wrap the same C++ object
-// because the two objects have different PHP resources, and we can't easily
-// look inside those resources to see which C++ objects they refer to.
-//check::equal($a->_cPtr, $c->_cPtr, "_cPtr check failed");
+// FIXME: The python version checks that a.this == c.this, but we don't seem
+// to have a way to check this with the PHP bindings we generate.
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/director_wombat_runme.php b/Examples/test-suite/php/director_wombat_runme.php
new file mode 100644
index 0000000..3e30804
--- /dev/null
+++ b/Examples/test-suite/php/director_wombat_runme.php
@@ -0,0 +1,52 @@
+<?php
+
+require "tests.php";
+
+// No new functions
+check::functions(array());
+check::classes(array('Bar', 'Foo_integers'));
+// No new vars
+check::globals(array());
+
+// Test base class functionality
+$barObj = new Bar();
+
+// Bar::meth should return a Foo_integers instance
+$fooIntsObj = $barObj->meth();
+check::equal(get_class($fooIntsObj), "Foo_integers", "wrong class");
+
+check::equal($fooIntsObj->meth(42) , 42, "Foo_integers::meth(n) should return n");
+
+//
+// Now subclass Foo_integers, but override its virtual method
+// meth(n) so that it returns the number plus one.
+//
+class MyFooInts extends Foo_integers {
+  function meth($n) {
+    return $n + 1;
+  }
+}
+
+//
+// Subclass Bar and override its virtual method meth()
+// so that it returns a new MyFooInts instance instead of
+// a Foo_integers instance.
+//
+class MyBar extends Bar {
+  function meth() {
+    return new MyFooInts();
+  }
+}
+
+//
+// Now repeat previous tests:
+//
+// Create a MyBar instance...
+//
+$barObj = new MyBar();
+
+// MyBar::meth should return a MyFooInts instance
+$fooIntsObj = $barObj->meth();
+check::equal(get_class($fooIntsObj), "MyFooInts", "wrong class");
+
+check::equal($fooIntsObj->meth(42) , 43, "MyFooInts::meth(n) should return n + 1");
diff --git a/Examples/test-suite/php/enum_scope_template_runme.php b/Examples/test-suite/php/enum_scope_template_runme.php
index 85ba467..d5aed62 100644
--- a/Examples/test-suite/php/enum_scope_template_runme.php
+++ b/Examples/test-suite/php/enum_scope_template_runme.php
@@ -1,15 +1,16 @@
 <?php
 require "tests.php";
-require "enum_scope_template.php";
 
+check::functions(array("chops"));
 check::classes(array("enum_scope_template", "TreeInt"));
-check::functions(array("chops","treeint_chops"));
-check::equal(0,TreeInt_Oak,"0==TreeInt_Oak");
-check::equal(1,TreeInt_Fir,"1==TreeInt_Fir");
-check::equal(2,TreeInt_Cedar,"2==TreeInt_Cedar");
-check::equal(TreeInt_Oak,chops(TreeInt_Oak),"TreeInt_Oak==chops(TreeInt_Oak)");
-check::equal(TreeInt_Fir,chops(TreeInt_Fir),"TreeInt_Fir==chops(TreeInt_Fir)");
-check::equal(TreeInt_Cedar,chops(TreeInt_Cedar),"TreeInt_Cedar==chops(TreeInt_Cedar)");
+// No new vars
+check::globals(array());
+
+check::equal(0,TreeInt::Oak,"0==TreeInt_Oak");
+check::equal(1,TreeInt::Fir,"1==TreeInt_Fir");
+check::equal(2,TreeInt::Cedar,"2==TreeInt_Cedar");
+check::equal(TreeInt::Oak,chops(TreeInt::Oak),"TreeInt_Oak==chops(TreeInt_Oak)");
+check::equal(TreeInt::Fir,chops(TreeInt::Fir),"TreeInt_Fir==chops(TreeInt_Fir)");
+check::equal(TreeInt::Cedar,chops(TreeInt::Cedar),"TreeInt_Cedar==chops(TreeInt_Cedar)");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/evil_diamond_ns_runme.php b/Examples/test-suite/php/evil_diamond_ns_runme.php
index fcce0f7..f2115bf 100644
--- a/Examples/test-suite/php/evil_diamond_ns_runme.php
+++ b/Examples/test-suite/php/evil_diamond_ns_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "evil_diamond_ns.php";
 
 check::classes(array("evil_diamond_ns","foo","bar","baz","spam"));
 check::functions("test");
@@ -15,4 +14,3 @@
 $_spam=test($spam);
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/evil_diamond_prop_runme.php b/Examples/test-suite/php/evil_diamond_prop_runme.php
index 9bdb743..611f17d 100644
--- a/Examples/test-suite/php/evil_diamond_prop_runme.php
+++ b/Examples/test-suite/php/evil_diamond_prop_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "evil_diamond_prop.php";
 
 check::classes(array("evil_diamond_prop","foo","bar","baz","spam"));
 check::functions("test");
@@ -31,10 +30,7 @@
 check::equal(1,$spam->_foo,"1==spam->_foo");
 check::equal(2,$spam->_bar,"2==spam->_bar");
 // multiple inheritance not supported in PHP
-set_error_handler(NULL, 0); // Don't complain that _baz is unknown.
 check::equal(null,$spam->_baz,"null==spam->_baz");
-restore_error_handler();
 check::equal(4,$spam->_spam,"4==spam->_spam");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/evil_diamond_runme.php b/Examples/test-suite/php/evil_diamond_runme.php
index a587ca3..7d01c98 100644
--- a/Examples/test-suite/php/evil_diamond_runme.php
+++ b/Examples/test-suite/php/evil_diamond_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "evil_diamond.php";
 
 check::classes(array("evil_diamond","foo","bar","baz","spam"));
 check::functions("test");
@@ -13,4 +12,3 @@
 //check::is_a("spam","baz");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/exception_memory_leak_runme.php b/Examples/test-suite/php/exception_memory_leak_runme.php
new file mode 100644
index 0000000..116ab2f
--- /dev/null
+++ b/Examples/test-suite/php/exception_memory_leak_runme.php
@@ -0,0 +1,35 @@
+<?php
+
+require "tests.php";
+
+check::functions(array('trigger_internal_swig_exception'));
+check::classes(array('Foo', 'exception_memory_leak'));
+// No new vars
+check::globals(array());
+
+$a = new Foo();
+check::equal(Foo::get_count(), 1, "Should have 1 Foo objects");
+$b = new Foo();
+check::equal(Foo::get_count(), 2, "Should have 2 Foo objects");
+
+// Normal behaviour
+trigger_internal_swig_exception("no problem", $a);
+check::equal(Foo::get_count(), 2, "Should have 2 Foo objects");
+check::equal(Foo::get_freearg_count(), 1, "freearg should have been used once");
+
+// SWIG exception triggered and handled (return new object case).
+try {
+    trigger_internal_swig_exception("null", $b);
+    check::fail("Expected exception not thrown");
+} catch (Exception $e) {
+}
+check::equal(Foo::get_count(), 2, "Should have 2 Foo objects");
+check::equal(Foo::get_freearg_count(), 2, "freearg should have been used twice");
+
+// SWIG exception triggered and handled (return by value case).
+try {
+    trigger_internal_swig_exception("null");
+    check::fail("Expected exception not thrown");
+} catch (Exception $e) {
+}
+check::equal(Foo::get_count(), 2, "Should have 2 Foo objects");
diff --git a/Examples/test-suite/php/exception_order_runme.php b/Examples/test-suite/php/exception_order_runme.php
index 77f115f..835a83c 100644
--- a/Examples/test-suite/php/exception_order_runme.php
+++ b/Examples/test-suite/php/exception_order_runme.php
@@ -1,10 +1,9 @@
-<?
+<?php
 require "tests.php";
-require "exception_order.php";
 
-check::functions(array('a_foo','a_bar','a_foobar','a_barfoo','is_python_builtin'));
+check::functions(array());
 check::classes(array('A','E1','E2','E3','exception_order','ET_i','ET_d'));
-check::globals(array('efoovar','foovar','cfoovar','a_sfoovar','a_foovar','a_efoovar'));
+check::globals(array('efoovar','foovar','cfoovar'));
 
 $a = new A();
 try {
@@ -36,4 +35,5 @@
 } catch (Exception $e) {
     check::equal($e->getMessage(), 'C++ E2 * exception thrown', '');
 }
-?>
+
+check::done();
diff --git a/Examples/test-suite/php/extend_template_ns_runme.php b/Examples/test-suite/php/extend_template_ns_runme.php
index e6d3e9f..4615867 100644
--- a/Examples/test-suite/php/extend_template_ns_runme.php
+++ b/Examples/test-suite/php/extend_template_ns_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "extend_template_ns.php";
 
 check::classes(array("extend_template_ns","Foo_One"));
 $foo=new Foo_One();
@@ -9,4 +8,3 @@
 check::equal(3,$foo->test2(3),"test2");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/extend_template_runme.php b/Examples/test-suite/php/extend_template_runme.php
index 41bde44..a6579dc 100644
--- a/Examples/test-suite/php/extend_template_runme.php
+++ b/Examples/test-suite/php/extend_template_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "extend_template.php";
 
 check::classes(array("Foo_0"));
 $foo=new Foo_0();
@@ -9,4 +8,3 @@
 check::equal(3,$foo->test2(3),"test2");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/friends_runme.php b/Examples/test-suite/php/friends_runme.php
new file mode 100644
index 0000000..4107817
--- /dev/null
+++ b/Examples/test-suite/php/friends_runme.php
@@ -0,0 +1,51 @@
+<?php
+
+require "tests.php";
+
+check::functions(array('globalscope','mix','get_val2','get_val3','bas','baz','get_val1','set','chum_blah','mate_blah','friend_definition','friend_declaration','friend_args_definition','friend_args_declaration','friend_definition_compiler','friend_declaration_compiler','friend_args_definition_compiler','friend_args_declaration_compiler'));
+check::classes(array('friends','Foe','A','B','D_i','D_d','CModelParameterCompartment','CModelParameterSpecies','Chum','Mate'));
+// No new vars
+check::globals(array());
+
+$a = new A(2);
+
+check::equal(get_val1($a), 2);
+check::equal(get_val2($a), 4);
+check::equal(get_val3($a), 6);
+
+# nice overload working fine
+check::equal(get_val1(1, 2, 3), 1);
+
+$b = new B(3);
+
+# David's case
+check::equal(mix($a, $b), 5);
+
+$di = new D_i(2);
+$dd = new D_d(3.3);
+
+# incredible template overloading working just fine
+check::equal(get_val1($di), 2);
+check::equal(get_val1($dd), 3.3);
+
+set($di, 4);
+set($dd, 1.3);
+
+check::equal(get_val1($di), 4);
+check::equal(get_val1($dd), 1.3);
+
+check::equal(chum_blah(), 1234);
+check::equal(mate_blah(), 4321);
+
+$foe = new Foe(111);
+check::equal(friend_definition(), 10);
+check::equal(friend_declaration(), 11);
+check::equal(friend_args_definition($foe), 111);
+check::equal(friend_args_declaration($foe), 111);
+
+check::equal(friend_definition_compiler(), 20);
+check::equal(friend_declaration_compiler(), 21);
+check::equal(friend_args_definition_compiler($foe), 111);
+check::equal(friend_args_declaration_compiler($foe), 111);
+
+check::done();
diff --git a/Examples/test-suite/php/global_vars_runme.php b/Examples/test-suite/php/global_vars_runme.php
new file mode 100644
index 0000000..c3fe7d8
--- /dev/null
+++ b/Examples/test-suite/php/global_vars_runme.php
@@ -0,0 +1,27 @@
+<?php
+
+require "tests.php";
+
+check::functions(array('init','read_b','read_x'));
+check::classes(array('A','global_vars'));
+check::globals(array('b','a','ap','cap','ar','x','xp','c_member','vp','h','hp','hr'));
+
+$an = new A();
+check::classname('A', $an);
+ap_set($an);
+check::classname('A', ap_get());
+check::equivalent(ap_get(), $an, "global var assignment");
+
+x_set(17);
+check::equal(x_get(), 17, "global var assignment");
+check::equal(read_x(), 17, "PHP global var change visible in C++");
+init();
+check::equal(x_get(), 1234, "C++ global var change visible in PHP");
+
+b_set('test');
+check::equal(b_get(), 'test', "global var assignment");
+check::equal(read_b(), 'test', "PHP global var change visible in C++");
+init();
+check::equal(b_get(), 'string b', "C++ global var change visible in PHP");
+
+check::done();
diff --git a/Examples/test-suite/php/grouping_runme.php b/Examples/test-suite/php/grouping_runme.php
index 8bad7cd..d2b849d 100644
--- a/Examples/test-suite/php/grouping_runme.php
+++ b/Examples/test-suite/php/grouping_runme.php
@@ -1,11 +1,10 @@
 <?php
 
 require "tests.php";
-require "grouping.php";
 
 check::functions(array("test1","test2","do_unary","negate"));
 check::equal(5,test1(5),"5==test1(5)");
-check::resource(test2(7),"_p_int","_p_int==test2(7)");
+check::equal(get_class(test2(7)),"SWIG\\_p_int","test2(7) is _p_int");
 check::globals(array('test3'));
 
 //check::equal(37,test3_get(),'37==test3_get()');
@@ -19,4 +18,3 @@
 check::equal(7,do_unary(-7,NEGATE),"7=do_unary(-7,NEGATE)");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/ignore_parameter_runme.php b/Examples/test-suite/php/ignore_parameter_runme.php
index b9c2b77..90b82d7 100644
--- a/Examples/test-suite/php/ignore_parameter_runme.php
+++ b/Examples/test-suite/php/ignore_parameter_runme.php
@@ -1,14 +1,13 @@
 <?php
 
 require "tests.php";
-require "ignore_parameter.php";
 
 // New functions
-check::functions(array('jaguar','lotus','tvr','ferrari','fiat','sportscars_daimler','sportscars_astonmartin','sportscars_bugatti','sportscars_lamborghini','sportscars_maseratti'));
+check::functions(array('jaguar','lotus','tvr','ferrari','fiat'));
 // New classes
 check::classes(array('ignore_parameter','SportsCars','MiniCooper','MorrisMinor','FordAnglia','AustinAllegro'));
 // No new vars
-check::globals(array());
+check::globals(array('called_argout'));
 
 check::equal(jaguar(2,3.4),"hello",'jaguar(2,3.4)=="hello"');
 check::equal(lotus("eek",3.4),101,'lotus("eek",3.4)==101');
@@ -18,7 +17,7 @@
 $sc=new sportscars();
 check::classname("sportscars",$sc);
 check::equal($sc->daimler(2,3.4),"hello",'$sc->daimler(2,3.4)=="hello"');
-check::equal($sc->astonmartin("eek",3.4),101,'$sc->mastonmartin("eek",3.4)==101');
+check::equal($sc->astonmartin("eek",3.4),101,'$sc->astonmartin("eek",3.4)==101');
 check::equal($sc->bugatti("eek",2),8.8,'$sc->bugatti("eek",2)==8.8');
 check::equal($sc->lamborghini(),101,'$sc->lamborghini(2)==101');
 
@@ -35,4 +34,3 @@
 check::classname("austinallegro",$aa);
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/import_nomodule_runme.php b/Examples/test-suite/php/import_nomodule_runme.php
index e5ea761..3dda18b 100644
--- a/Examples/test-suite/php/import_nomodule_runme.php
+++ b/Examples/test-suite/php/import_nomodule_runme.php
@@ -1,14 +1,17 @@
 <?php
+
 require "tests.php";
-require "import_nomodule.php";
 
 // No new functions
-check::functions(array('create_foo','delete_foo','test1','is_python_builtin'));
-// No new classes
-check::classes(array('import_nomodule','Bar'));
-// now new vars
+check::functions(array());
+check::classes(array('import_nomodule'));
+// No new globals
 check::globals(array());
 
+// SWIGPHP doesn't currently support the "violation of the type system" which
+// is tested by this testcase.
+exit(0);
+
 $f = import_nomodule::create_Foo();
 import_nomodule::test1($f,42);
 import_nomodule::delete_Foo($f);
@@ -17,4 +20,3 @@
 import_nomodule::test1($b,37);
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/li_carrays_cpp_runme.php b/Examples/test-suite/php/li_carrays_cpp_runme.php
index 3e8a443..ccbcf7d 100644
--- a/Examples/test-suite/php/li_carrays_cpp_runme.php
+++ b/Examples/test-suite/php/li_carrays_cpp_runme.php
@@ -1,16 +1,16 @@
 <?php
+
 require "tests.php";
-require "li_carrays_cpp.php";
 
 // Check functions.
-check::functions(array('new_intarray','delete_intarray','intarray_getitem','intarray_setitem','doublearray_getitem','doublearray_setitem','doublearray_cast','doublearray_frompointer','xyarray_getitem','xyarray_setitem','xyarray_cast','xyarray_frompointer','delete_abarray','abarray_getitem','abarray_setitem','shortarray_getitem','shortarray_setitem','shortarray_cast','shortarray_frompointer','sum_array'));
+check::functions(array('new_intArray','delete_intArray','intArray_getitem','intArray_setitem','new_ABArray','delete_ABArray','ABArray_getitem','ABArray_setitem','sum_array'));
 
 // Check classes.
 // NB An "li_carrays_cpp" class is created as a mock namespace.
 check::classes(array('li_carrays_cpp','doubleArray','AB','XY','XYArray','shortArray'));
 
 // Check global variables.
-check::globals(array('xy_x','xy_y','globalxyarray','ab_a','ab_b','globalabarray'));
+check::globals(array('globalXYArray','globalABArray'));
 
 $d = new doubleArray(10);
 
@@ -19,4 +19,3 @@
 check::equal($d->getitem(0) + $d->getitem(5), 17., "7+10==17");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/li_carrays_runme.php b/Examples/test-suite/php/li_carrays_runme.php
index abe3581..df54e04 100644
--- a/Examples/test-suite/php/li_carrays_runme.php
+++ b/Examples/test-suite/php/li_carrays_runme.php
@@ -1,16 +1,16 @@
 <?php
+
 require "tests.php";
-require "li_carrays.php";
 
 // Check functions.
-check::functions(array('new_intarray','delete_intarray','intarray_getitem','intarray_setitem','doublearray_getitem','doublearray_setitem','doublearray_cast','doublearray_frompointer','xyarray_getitem','xyarray_setitem','xyarray_cast','xyarray_frompointer','delete_abarray','abarray_getitem','abarray_setitem','shortarray_getitem','shortarray_setitem','shortarray_cast','shortarray_frompointer','sum_array'));
+check::functions(array('new_intArray','delete_intArray','intArray_getitem','intArray_setitem','new_ABArray','delete_ABArray','ABArray_getitem','ABArray_setitem','sum_array'));
 
 // Check classes.
 // NB An "li_carrays" class is created as a mock namespace.
 check::classes(array('li_carrays','doubleArray','AB','XY','XYArray','shortArray'));
 
 // Check global variables.
-check::globals(array('xy_x','xy_y','globalxyarray','ab_a','ab_b','globalabarray'));
+check::globals(array('globalXYArray','globalABArray'));
 
 $d = new doubleArray(10);
 
@@ -19,4 +19,3 @@
 check::equal($d->getitem(0) + $d->getitem(5), 17., "7+10==17");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/li_constraints_runme.php b/Examples/test-suite/php/li_constraints_runme.php
new file mode 100644
index 0000000..35d523b
--- /dev/null
+++ b/Examples/test-suite/php/li_constraints_runme.php
@@ -0,0 +1,68 @@
+<?php
+
+require "tests.php";
+
+// New functions
+check::functions(array('test_nonnegative', 'test_nonpositive', 'test_positive',
+  'test_negative', 'test_nonzero', 'test_nonnull', 'get_nonnull'));
+// New classes
+check::classes(array('li_constraints'));
+// No new vars
+check::globals(array());
+
+function check_double(bool $except, $fn, string $f, $val) {
+  $actual = true;
+  $d = doubleval($val);
+  try {
+    $fn($d);
+  } catch(ValueError $e) {
+    $actual = false;
+    $msg = $e->getMessage();
+  }
+  $name = "test_" . str_replace("-", "", $f);
+  if($actual) {
+    check::equal($actual, $except, "Test '$name' with $val pass");
+  } else {
+    check::equal($actual, $except, "Test '$name' throw exception with $val");
+    check::equal($msg, "Expected a " . $f . " value.", "'$name' throw proper exception");
+  }
+}
+
+$nonnegative = function ($val) { test_nonnegative($val); };
+check_double(true, $nonnegative, "non-negative", 10);
+check_double(true, $nonnegative, "non-negative", 0);
+check_double(false, $nonnegative, "non-negative", -10);
+
+$nonpositive = function ($val) { test_nonpositive($val); };
+check_double(false, $nonpositive, "non-positive", 10);
+check_double(true, $nonpositive, "non-positive", 0);
+check_double(true, $nonpositive, "non-positive", -10);
+
+$positive = function ($val) { test_positive($val); };
+check_double(true, $positive, "positive", 10);
+check_double(false, $positive, "positive", 0);
+check_double(false, $positive, "positive", -10);
+
+$negative = function ($val) { test_negative($val); };
+check_double(false, $negative, "negative", 10);
+check_double(false, $negative, "negative", 0);
+check_double(true, $negative, "negative", -10);
+
+$nonzero = function ($val) { test_nonzero($val); };
+check_double(true, $nonzero, "nonzero", 10);
+check_double(false, $nonzero, "nonzero", 0);
+check_double(true, $nonzero, "nonzero", -10);
+
+$have_exception = false;
+try {
+  test_nonnull(null);
+} catch(ValueError $e) {
+  $msg = $e->getMessage();
+  $have_exception = strcmp($msg, "Received a NULL pointer.") === 0;
+}
+if (!$have_exception) {
+    throw new Exception("test_nonnull should perform a proper exception with 'null' value");
+}
+
+$non_null = get_nonnull();
+test_nonnull($non_null);
diff --git a/Examples/test-suite/php/li_factory_runme.php b/Examples/test-suite/php/li_factory_runme.php
index 982d7b1..18545fe 100644
--- a/Examples/test-suite/php/li_factory_runme.php
+++ b/Examples/test-suite/php/li_factory_runme.php
@@ -1,13 +1,12 @@
 <?php
 
 require "tests.php";
-require "li_factory.php";
 
 // No new functions
-check::functions(array('geometry_draw','geometry_create','geometry_clone_','point_draw','point_width','point_clone_','circle_draw','circle_radius','circle_clone_'));
-// No new classes
+check::functions(array());
+// New classes
 check::classes(array('Geometry','Point','Circle'));
-// now new vars
+// No new vars
 check::globals(array());
 
 $circle = Geometry::create(Geometry::CIRCLE);
@@ -18,5 +17,7 @@
 $w = $point->width();
 check::equal($w, 1.0, "w failed");
 
+$point = Geometry::create(Geometry::SHAPELESS);
+check::equal($point, NULL, "NULL failed");
+
 check::done();
-?>
diff --git a/Examples/test-suite/php/li_std_auto_ptr_runme.php b/Examples/test-suite/php/li_std_auto_ptr_runme.php
new file mode 100644
index 0000000..7ebcf97
--- /dev/null
+++ b/Examples/test-suite/php/li_std_auto_ptr_runme.php
@@ -0,0 +1,108 @@
+<?php
+
+require "tests.php";
+
+function checkCount($expected_count) {
+    $actual_count = Klass::getTotal_count();
+    check::equal($actual_count, $expected_count, "Counts incorrect");
+}
+
+# Test raw pointer handling involving virtual inheritance
+$kini = new KlassInheritance("KlassInheritanceInput");
+checkCount(1);
+$s = useKlassRawPtr($kini);
+check::equal($s, "KlassInheritanceInput", "Incorrect string: $s");
+$kini = NULL;
+checkCount(0);
+
+
+# auto_ptr as input
+$kin = new Klass("KlassInput");
+checkCount(1);
+$s = takeKlassAutoPtr($kin);
+checkCount(0);
+check::equal($s, "KlassInput", "Incorrect string: $s");
+try {
+    is_nullptr($kin);
+    check::fail("is_nullptr check");
+} catch (TypeError $e) {
+}
+$kin = NULL; # Should not fail, even though already deleted
+checkCount(0);
+
+$kin = new Klass("KlassInput");
+checkCount(1);
+$s = takeKlassAutoPtr($kin);
+checkCount(0);
+check::equal($s, "KlassInput", "Incorrect string: $s");
+try {
+    is_nullptr($kin);
+    check::fail("is_nullptr check");
+} catch (TypeError $e) {
+}
+$exception_thrown = false;
+try {
+  takeKlassAutoPtr($kin);
+} catch (TypeError $e) {
+  check::equal($e->getMessage(), "Cannot release ownership as memory is not owned for argument 1 of SWIGTYPE_p_Klass of takeKlassAutoPtr", "Unexpected exception: {$e->getMessage()}");
+  $exception_thrown = true;
+}
+check::equal($exception_thrown, true, "double usage of takeKlassAutoPtr should have been an error");
+$kin = NULL; # Should not fail, even though already deleted
+checkCount(0);
+
+$kin = new Klass("KlassInput");
+$exception_thrown = false;
+$notowned = get_not_owned_ptr($kin);
+try {
+  takeKlassAutoPtr($notowned);
+} catch (TypeError $e) {
+  check::equal($e->getMessage(), "Cannot release ownership as memory is not owned for argument 1 of SWIGTYPE_p_Klass of takeKlassAutoPtr", "Unexpected exception: {$e->getMessage()}");
+  $exception_thrown = true;
+}
+check::equal($exception_thrown, true, "double usage of takeKlassAutoPtr should have been an error");
+checkCount(1);
+$kin = NULL;
+checkCount(0);
+
+$kini = new KlassInheritance("KlassInheritanceInput");
+checkCount(1);
+$s = takeKlassAutoPtr($kini);
+checkCount(0);
+check::equal($s, "KlassInheritanceInput", "Incorrect string: $s");
+try {
+    is_nullptr($kini);
+    check::fail("is_nullptr check");
+} catch (TypeError $e) {
+}
+
+$kini = NULL; # Should not fail, even though already deleted
+checkCount(0);
+
+takeKlassAutoPtr(NULL);
+takeKlassAutoPtr(make_null());
+checkCount(0);
+
+# overloaded parameters
+check::equal(overloadTest(), 0, "overloadTest failed");
+check::equal(overloadTest(NULL), 1, "overloadTest failed");
+check::equal(overloadTest(new Klass("over")), 1, "overloadTest failed");
+checkCount(0);
+
+
+# auto_ptr as output
+$k1 = makeKlassAutoPtr("first");
+$k2 = makeKlassAutoPtr("second");
+checkCount(2);
+
+$k1 = NULL;
+checkCount(1);
+
+check::equal($k2->getLabel(), "second", "proper label");
+
+$k2 = NULL;
+checkCount(0);
+
+check::equal(makeNullAutoPtr(), NULL);
+
+check::done();
diff --git a/Examples/test-suite/php/li_std_string_runme.php b/Examples/test-suite/php/li_std_string_runme.php
index 04ee3fc..cd04312 100644
--- a/Examples/test-suite/php/li_std_string_runme.php
+++ b/Examples/test-suite/php/li_std_string_runme.php
@@ -1,11 +1,34 @@
 <?php
 
 require "tests.php";
-require "li_std_string.php";
 
-// Global variables
-//$s="initial string";
-//check::equal(GlobalString2_get() ,"global string 2", "GlobalString2 test 1");
+# Checking expected use of %typemap(in) std::string {}
+li_std_string::test_value("Fee");
+
+# Checking expected result of %typemap(out) std::string {}
+check::equal(li_std_string::test_value("Fi"), "Fi", "Test 1");
+
+# Checking expected use of %typemap(in) const std::string & {}
+li_std_string::test_const_reference("Fo");
+
+# Checking expected result of %typemap(out) const std::string& {}
+check::equal(li_std_string::test_const_reference("Fum"), "Fum", "Test 3");
+
+# Input and output typemaps for pointers and non-const references to
+# std::string are *not* supported; the following tests confirm
+# that none of these cases are slipping through.
+
+$stringPtr = li_std_string::test_pointer_out();
+
+li_std_string::test_pointer($stringPtr);
+
+$stringPtr = li_std_string::test_const_pointer_out();
+
+li_std_string::test_const_pointer($stringPtr);
+
+$stringPtr = li_std_string::test_reference_out();
+
+li_std_string::test_reference($stringPtr);
 
 // Global variables
 $s = "initial string";
@@ -24,11 +47,60 @@
 check::equal(Structure::StaticMemberString2(), "static member string 2", "StaticMemberString2 test 1");
 Structure::StaticMemberString2($s);
 check::equal(Structure::StaticMemberString2(), $s, "StaticMemberString2 test 2");
-// below broken ?
-//check::equal(Structure::ConstStaticMemberString(), "const static member string", "ConstStaticMemberString test");
+check::equal(Structure::ConstStaticMemberString(), "const static member string", "ConstStaticMemberString test");
+
+// Test INPUT, INOUT and OUTPUT string& typemaps:
+$input = "hello";
+check::equal(li_std_string::test_reference_input($input), "hello");
+// $input should be unchanged - this check is to catch if we incorrectly used
+// the default string& typemap:
+check::equal($input, "hello");
+$s = li_std_string::test_reference_inout($input);
+check::equal($s, "hellohello");
+// $input should be unchanged - this check is to catch if we incorrectly used
+// the default string& typemap:
+check::equal($input, "hello");
+check::equal(li_std_string::test_reference_output(), "output");
+
+// Test default PHP wrapping of std::string& as a by-ref PHP string parameter:
+$s = "byref";
+check::equal(li_std_string::test_reference_php($s), null);
+check::equal($s, "byref.php");
+
+// Test throwing strings:
+try {
+    test_throw();
+    check::fail("test_throw() didn't throw");
+} catch (Exception $s) {
+    check::equal($s->getMessage(), "test_throw message");
+}
+try {
+    test_const_reference_throw();
+    check::fail("test_const_reference_throw() didn't throw");
+} catch (Exception $s) {
+    check::equal($s->getMessage(), "test_const_reference_throw message");
+}
+try {
+    test_pointer_throw();
+    check::fail("test_pointer_throw() didn't throw");
+} catch (Exception $s) {
+    check::equal($s->getMessage(), "foo");
+}
+try {
+    test_const_pointer_throw();
+    check::fail("test_const_pointer_throw() didn't throw");
+} catch (Exception $s) {
+    check::equal($s->getMessage(), "foo");
+}
+
+check::equal(li_std_string::stdstring_empty(), "", "stdstring_empty test");
+check::equal(li_std_string::c_empty(), "", "c_empty test");
+check::isnull(li_std_string::c_null(), "c_null test");
+check::isnull(li_std_string::get_null(li_std_string::c_null()), "get_null c_null test");
+check::equal(li_std_string::get_null(li_std_string::c_empty()), "non-null", "get_null c_empty test");
+check::equal(li_std_string::get_null(li_std_string::stdstring_empty()), "non-null", "get_null stdstring_empty test");
 
 // This used to give "Undefined variable: r"
 li_std_string::test_const_reference_returning_void("foo");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/li_std_vector_member_var_runme.php b/Examples/test-suite/php/li_std_vector_member_var_runme.php
index 2383503..32ce484 100644
--- a/Examples/test-suite/php/li_std_vector_member_var_runme.php
+++ b/Examples/test-suite/php/li_std_vector_member_var_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "li_std_vector_member_var.php";
 
 $t = new Test();
 
@@ -27,4 +26,3 @@
 check::equal($T->length, 7, "T::length != 7");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/long_long_runme.php b/Examples/test-suite/php/long_long_runme.php
new file mode 100644
index 0000000..544a59c
--- /dev/null
+++ b/Examples/test-suite/php/long_long_runme.php
@@ -0,0 +1,65 @@
+<?php
+// This is the long_long runtime testcase. It checks that the long long and
+// unsigned long long types map correctly to PHP int or string (for values
+// which don't fit in a PHP int).
+
+require "tests.php";
+
+check::functions(array("foo1","foo2","foo3","foo4","foo5","foo6","bar1","bar2","bar3","bar4","bar5","bar6","UnsignedToSigned"));
+check::classes(array("long_long"));
+check::globals(array("ll","ull"));
+
+function check_ll($ll) {
+  long_long::ll_set($ll);
+  check::equivalent($ll, long_long::ll_get(), "Round tripping of long long failed");
+}
+
+function check_ull($ull) {
+  long_long::ull_set($ull);
+  check::equivalent($ull, long_long::ull_get(), "Round tripping of unsigned long long failed");
+}
+
+check_ll("0");
+check_ll(0);
+check_ll("9223372036854775807"); // 0x7FFFFFFFFFFFFFFF
+if ((int)0x100000000 !== 0) {
+  // This check doesn't work if PHP int is 32 bits.
+  check_ll(0x7FFFFFFFFFFFFFFF);
+}
+check_ll(-10);
+
+$testNumber = 0;
+const COUNT = 1025;
+
+for ($i=0; $i<COUNT; $i++) {
+  check_ull($testNumber);
+  $testNumber += 1;
+}
+
+$testNumber = 256*256/2-COUNT;
+for ($i=0; $i<COUNT*2; $i++) {
+  check_ull($testNumber);
+  $testNumber += 1;
+}
+
+$testNumber = 256*256-COUNT;
+for ($i=0; $i<COUNT*2; $i++) {
+  check_ull($testNumber);
+  $testNumber += 1;
+}
+
+$testNumber = 0x7FFFFFFFFFFFFFFF-COUNT;
+for ($i=0; $i<COUNT*2; $i++) {
+  check_ull($testNumber);
+  $testNumber += 1;
+}
+
+// Check that conversion from unsigned long long to long long gives expected
+// value (including negative numbers)
+
+check::equal(long_long::UnsignedToSigned(0), 0, "UnsignedToSigned test failed");
+check::equal(long_long::UnsignedToSigned(0xff), 0xff, "UnsignedToSigned test failed");
+check::equal(long_long::UnsignedToSigned(-0xff), -0xff, "UnsignedToSigned test failed");
+check::equal(long_long::UnsignedToSigned(-1), -1, "UnsignedToSigned test failed");
+
+check::done();
diff --git a/Examples/test-suite/php/member_pointer_const_runme.php b/Examples/test-suite/php/member_pointer_const_runme.php
new file mode 100644
index 0000000..bd8eaa8
--- /dev/null
+++ b/Examples/test-suite/php/member_pointer_const_runme.php
@@ -0,0 +1,61 @@
+<?php
+
+require "tests.php";
+
+// Check functions.
+check::functions(array('do_op','do_op_td','areapt','perimeterpt','perimeterpt_td','call1'));
+
+// Check classes.
+check::classes(array('member_pointer_const','Circle','Funktions','Shape','Square'));
+
+// Check global variables.
+check::globals(array('areavar','perimetervar','perimetervar_td'));
+
+# Get the pointers
+
+$area_pt = member_pointer_const::areapt();
+$perim_pt = member_pointer_const::perimeterpt();
+
+# Create some objects
+
+$s = new Square(10);
+
+# Do some calculations
+
+check::equal(100.0, member_pointer_const::do_op($s, $area_pt), "Square area");
+check::equal(40.0, member_pointer_const::do_op($s, $perim_pt), "Square perim");
+
+
+$memberPtr = member_pointer_const::areavar_get();
+$memberPtr = member_pointer_const::perimetervar_get();
+
+# Try the variables
+check::equal(100.0, member_pointer_const::do_op($s, member_pointer_const::areavar_get()), "Square area");
+check::equal(40.0, member_pointer_const::do_op($s, member_pointer_const::perimetervar_get()), "Square perim");
+
+# Modify one of the variables
+member_pointer_const::areavar_set($perim_pt);
+
+check::equal(40.0, member_pointer_const::do_op($s, member_pointer_const::areavar_get()), "Square perimeter");
+
+# Try the constants
+
+/*
+$memberPtr = member_pointer_const::AREAPT;
+$memberPtr = member_pointer_const::PERIMPT;
+$memberPtr = member_pointer_const::NULLPT;
+
+check::equal(100.0, member_pointer_const::do_op($s, member_pointer_const::AREAPT), "Square area");
+check::equal(40.0, member_pointer_const::do_op($s, member_pointer_const::PERIMPT), "Square perim");
+*/
+
+# Typedefs
+check::equal(40.0, member_pointer_const::do_op_td($s, $perim_pt), "Square perim");
+
+/*
+check::equal(3, member_pointer_const::call1(member_pointer_const::ADD_BY_VALUE, 1, 2), "Add by value");
+check::equal(7, member_pointer_const::call2(member_pointer_const::ADD_BY_VALUE, 3, 4), "Add by pointer");
+check::equal(11, member_pointer_const::call3(member_pointer_const::ADD_BY_VALUE, 5, 6), "Add by reference");
+ */
+
+check::done();
diff --git a/Examples/test-suite/php/mod_runme.php b/Examples/test-suite/php/mod_runme.php
new file mode 100644
index 0000000..6e485ce
--- /dev/null
+++ b/Examples/test-suite/php/mod_runme.php
@@ -0,0 +1,9 @@
+<?php
+
+require "tests.php";
+
+$c = new C();
+$d = new D();
+$d->DoSomething($c);
+
+check::done();
diff --git a/Examples/test-suite/php/multivalue_runme.php b/Examples/test-suite/php/multivalue_runme.php
new file mode 100644
index 0000000..77e1e1a
--- /dev/null
+++ b/Examples/test-suite/php/multivalue_runme.php
@@ -0,0 +1,24 @@
+<?php
+
+require "tests.php";
+
+// New functions
+check::functions(array('divide_l','divide_v','divide_mv'));
+// New classes
+check::classes(array('multivalue'));
+// No new vars
+check::globals(array());
+
+$r = multivalue::divide_l(37, 5);
+check::equal($r[0], 7, "Test divide_l quotient");
+check::equal($r[1], 2, "Test divide_l remainder");
+
+$r = multivalue::divide_v(41, 7);
+check::equal($r[0], 5, "Test divide_v quotient");
+check::equal($r[1], 6, "Test divide_v remainder");
+
+$r = multivalue::divide_mv(91, 13);
+check::equal($r[0], 7, "Test divide_mv quotient");
+check::equal($r[1], 0, "Test divide_mv remainder");
+
+check::done();
diff --git a/Examples/test-suite/php/newobject1_runme.php b/Examples/test-suite/php/newobject1_runme.php
index 863e3e4..464f09b 100644
--- a/Examples/test-suite/php/newobject1_runme.php
+++ b/Examples/test-suite/php/newobject1_runme.php
@@ -1,19 +1,24 @@
 <?php
 
 require "tests.php";
-require "newobject1.php";
 
 // No new functions
-check::functions(array('foo_makefoo','foo_makemore','foo_foocount'));
-// No new classes
+check::functions(array());
+// New classes
 check::classes(array('Foo'));
-// now new vars
+// No new vars
 check::globals(array());
 
+check::equal(Foo::fooCount(), 0, "no Foo objects expected");
 $foo = Foo::makeFoo();
 check::equal(get_class($foo), "Foo", "static failed");
+check::equal(Foo::fooCount(), 1, "1 Foo object expected");
 $bar = $foo->makeMore();
 check::equal(get_class($bar), "Foo", "regular failed");
+check::equal(Foo::fooCount(), 2, "2 Foo objects expected");
+$foo = null;
+check::equal(Foo::fooCount(), 1, "1 Foo object expected");
+$bar = null;
+check::equal(Foo::fooCount(), 0, "no Foo objects expected");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/newobject2_runme.php b/Examples/test-suite/php/newobject2_runme.php
new file mode 100644
index 0000000..f20a6a4
--- /dev/null
+++ b/Examples/test-suite/php/newobject2_runme.php
@@ -0,0 +1,17 @@
+<?php
+
+require "tests.php";
+
+check::equal(fooCount(), 0, "no Foo objects expected");
+$foo = makeFoo();
+check::equal(get_class($foo), "Foo", "static failed");
+check::equal(fooCount(), 1, "1 Foo object expected");
+$bar = makeFoo();
+check::equal(get_class($bar), "Foo", "regular failed");
+check::equal(fooCount(), 2, "2 Foo objects expected");
+$foo = null;
+check::equal(fooCount(), 1, "1 Foo object expected");
+$bar = null;
+check::equal(fooCount(), 0, "no Foo objects expected");
+
+check::done();
diff --git a/Examples/test-suite/php/newobject3_runme.php b/Examples/test-suite/php/newobject3_runme.php
index edd5d86..29e16be 100644
--- a/Examples/test-suite/php/newobject3_runme.php
+++ b/Examples/test-suite/php/newobject3_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "newobject3.php";
 
 $factory = new factory();
 
@@ -15,4 +14,4 @@
 check::isnull($factory->create(0, -1), "create(0, -1) should be NULL");
 check::isnull($factory->create("bad", -1), "create(\"bad\", -1) should be NULL");
 
-?>
+check::done();
diff --git a/Examples/test-suite/php/overload_bool_runme.php b/Examples/test-suite/php/overload_bool_runme.php
new file mode 100644
index 0000000..e477330
--- /dev/null
+++ b/Examples/test-suite/php/overload_bool_runme.php
@@ -0,0 +1,42 @@
+<?php
+require "tests.php";
+
+# Overloading bool, int, string
+check::equal(overloaded(true), "bool", "wrong!");
+check::equal(overloaded(false), "bool", "wrong!");
+
+check::equal(overloaded(0), "int", "wrong!");
+check::equal(overloaded(1), "int", "wrong!");
+check::equal(overloaded(2), "int", "wrong!");
+
+check::equal(overloaded("1234"), "string", "wrong!");
+
+# Test bool masquerading as int
+check::equal(intfunction(true), "int", "wrong!");
+check::equal(intfunction(false), "int", "wrong!");
+
+# Test int masquerading as bool
+check::equal(boolfunction(1), "true", "wrong!");
+check::equal(boolfunction(0), "false", "wrong!");
+
+#############################################
+
+# Overloading bool, int, string
+check::equal(overloaded_ref(true), "bool", "wrong!");
+check::equal(overloaded_ref(false), "bool", "wrong!");
+
+check::equal(overloaded_ref(0), "int", "wrong!");
+check::equal(overloaded_ref(1), "int", "wrong!");
+check::equal(overloaded_ref(2), "int", "wrong!");
+
+check::equal(overloaded_ref("1234"), "string", "wrong!");
+
+# Test bool masquerading as int
+check::equal(intfunction_ref(true), "int", "wrong!");
+check::equal(intfunction_ref(false), "int", "wrong!");
+
+# Test int masquerading as bool
+check::equal(boolfunction(1), "true", "wrong!");
+check::equal(boolfunction(0), "false", "wrong!");
+
+check::done();
diff --git a/Examples/test-suite/php/overload_complicated_runme.php b/Examples/test-suite/php/overload_complicated_runme.php
new file mode 100644
index 0000000..6a5f8b4
--- /dev/null
+++ b/Examples/test-suite/php/overload_complicated_runme.php
@@ -0,0 +1,39 @@
+<?php
+require "tests.php";
+
+$pInt = NULL;
+
+# Check the correct constructors are available
+$p = new Pop($pInt);
+
+$p = new Pop($pInt, false);
+
+# Check overloaded in const only and pointers/references which target
+# languages cannot disambiguate
+check::equal($p->hip(false), 701, "Test 1 failed");
+
+check::equal($p->hip($pInt), 702, "Test 2 failed");
+
+# Reverse the order for the above
+check::equal($p->hop($pInt), 805, "Test 3 failed");
+
+check::equal($p->hop(false), 801, "Test 4 failed");
+
+# Few more variations and order shuffled
+check::equal($p->pop(false), 901, "Test 5 failed");
+
+check::equal($p->pop($pInt), 904, "Test 6 failed");
+
+check::equal($p->pop(), 905, "Test 7 failed");
+
+# Overload on const only
+check::equal($p->bop($pInt), 1001, "Test 8 failed");
+
+check::equal($p->bip($pInt), 2002, "Test 9 failed");
+
+# Globals
+check::equal(muzak(false), 3001, "Test 10 failed");
+
+check::equal(muzak($pInt), 3002, "Test 11 failed");
+
+check::done();
diff --git a/Examples/test-suite/php/overload_copy_runme.php b/Examples/test-suite/php/overload_copy_runme.php
new file mode 100644
index 0000000..893a715
--- /dev/null
+++ b/Examples/test-suite/php/overload_copy_runme.php
@@ -0,0 +1,13 @@
+<?php
+require "tests.php";
+
+// No new functions
+check::functions(array());
+check::classes(array('Foo'));
+// No new vars
+check::globals(array());
+
+$f = new Foo();
+$g = new Foo($f);
+
+check::done();
diff --git a/Examples/test-suite/php/overload_extend2_runme.php b/Examples/test-suite/php/overload_extend2_runme.php
new file mode 100644
index 0000000..6964a0d
--- /dev/null
+++ b/Examples/test-suite/php/overload_extend2_runme.php
@@ -0,0 +1,16 @@
+<?php
+require "tests.php";
+
+$f = new Foo();
+check::equal($f->test(3), 1, '$f->test(3)');
+check::equal($f->test("hello"), 2, '$f->test("hello")');
+check::equal($f->test(3.5, 2.5), 3, '$f->test(3.5, 2.5)');
+check::equal($f->test("hello", 20), 1020, '$f->test("hello", 20)');
+check::equal($f->test("hello", 20, 100), 120, '$f->test("hello", 20, 100)');
+
+// C default args
+check::equal($f->test($f), 30, '$f->test(f)');
+check::equal($f->test($f, 100), 120, '$f->test(f, 100)');
+check::equal($f->test($f, 100, 200), 300, '$f->test(f, 100, 200)');
+
+check::done();
diff --git a/Examples/test-suite/php/overload_extend_c_runme.php b/Examples/test-suite/php/overload_extend_c_runme.php
new file mode 100644
index 0000000..55f426c
--- /dev/null
+++ b/Examples/test-suite/php/overload_extend_c_runme.php
@@ -0,0 +1,11 @@
+<?php
+require "tests.php";
+
+$f = new Foo();
+check::equal($f->test(), 0, '$f->test()');
+check::equal($f->test(3), 1, '$f->test(3)');
+check::equal($f->test("hello"), 2, '$f->test("hello")');
+check::equal($f->test(3.0, 2.0), 5.0, '$f->test(3, 2)');
+check::equal($f->test(3.0), 1003.0, '$f->test(3.0)');
+
+check::done();
diff --git a/Examples/test-suite/php/overload_extend_runme.php b/Examples/test-suite/php/overload_extend_runme.php
new file mode 100644
index 0000000..89c0499
--- /dev/null
+++ b/Examples/test-suite/php/overload_extend_runme.php
@@ -0,0 +1,11 @@
+<?php
+require "tests.php";
+
+$f = new Foo();
+check::equal($f->test(), 0, '$f->test()');
+check::equal($f->test(3), 1, '$f->test(3)');
+check::equal($f->test("hello"), 2, '$f->test("hello")');
+check::equal($f->test(3.0, 2.0), 5.0, '$f->test(3.0, 2.0)');
+check::equal($f->test(3.0), 1003.0, '$f->test(3.0)');
+
+check::done();
diff --git a/Examples/test-suite/php/overload_null_runme.php b/Examples/test-suite/php/overload_null_runme.php
index 22824d4..7afafea 100644
--- a/Examples/test-suite/php/overload_null_runme.php
+++ b/Examples/test-suite/php/overload_null_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "overload_null.php";
 
 $o = new Overload();
 $x = new X();
@@ -31,16 +30,15 @@
 check::equal(15, $o->byval2cpr(null), "test 15");
 check::equal(16, $o->byval2cpr($x), "test 16");
 
-# forward class declaration
-check::equal(17, $o->byval1forwardptr($x), "test 17");
-check::equal(18, $o->byval1forwardptr(null), "test 18");
+# fwd class declaration
+check::equal(17, $o->byval1fwdptr($x), "test 17");
+check::equal(18, $o->byval1fwdptr(null), "test 18");
 
-check::equal(19, $o->byval2forwardptr(null), "test 19");
-check::equal(20, $o->byval2forwardptr($x), "test 20");
+check::equal(19, $o->byval2fwdptr(null), "test 19");
+check::equal(20, $o->byval2fwdptr($x), "test 20");
 
-check::equal(21, $o->byval1forwardref($x), "test 21");
+check::equal(21, $o->byval1fwdref($x), "test 21");
 
-check::equal(22, $o->byval2forwardref($x), "test 22");
+check::equal(22, $o->byval2fwdref($x), "test 22");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/overload_numeric_runme.php b/Examples/test-suite/php/overload_numeric_runme.php
new file mode 100644
index 0000000..a346c0d
--- /dev/null
+++ b/Examples/test-suite/php/overload_numeric_runme.php
@@ -0,0 +1,40 @@
+<?php
+require "tests.php";
+
+$nums = new Nums();
+$limits = new Limits();
+
+check::equal($nums->over(0), "signed char", '$nums->over(0)');
+check::equal($nums->over(0.0), "float", '$nums->over(0.0)');
+
+check::equal($nums->over($limits->schar_min()), "signed char", '$nums->over($limits->schar_min())');
+check::equal($nums->over($limits->schar_max()), "signed char", '$nums->over($limits->schar_max())');
+
+check::equal($nums->over($limits->schar_min() - 1), "short", '$nums->over($limits->schar_min() - 1)');
+check::equal($nums->over($limits->schar_max() + 1), "short", '$nums->over($limits->schar_max() + 1)');
+check::equal($nums->over($limits->shrt_min()), "short", '$nums->over($limits->shrt_min())');
+check::equal($nums->over($limits->shrt_max()), "short", '$nums->over($limits->shrt_max())');
+
+check::equal($nums->over($limits->shrt_min() - 1), "int", '$nums->over($limits->shrt_min() - 1)');
+check::equal($nums->over($limits->shrt_max() + 1), "int", '$nums->over($limits->shrt_max() + 1)');
+check::equal($nums->over($limits->int_min()), "int", '$nums->over($limits->int_min())');
+check::equal($nums->over($limits->int_max()), "int", '$nums->over($limits->int_max())');
+
+check::equal($nums->over($limits->flt_min()), "float", '$nums->over($limits->flt_min())');
+check::equal($nums->over($limits->flt_max()), "float", '$nums->over($limits->flt_max())');
+
+check::equal($nums->over($limits->flt_max() * 10), "double", '$nums->over($limits->flt_max() * 10)');
+check::equal($nums->over(-$limits->flt_max() * 10), "double", '$nums->over(-$limits->flt_max() * 10)');
+check::equal($nums->over($limits->dbl_max()), "double", '$nums->over($limits->dbl_max())');
+check::equal($nums->over(-$limits->dbl_max()), "double", '$nums->over(-$limits->dbl_max())');
+
+check::equal($nums->over(INF), "float", '$nums->over(INF)');
+check::equal($nums->over(-INF), "float", '$nums->over(-INF)');
+check::equal($nums->over(NAN), "float", '$nums->over(NAN)');
+
+// Just check if the following are accepted without exceptions being thrown
+$nums->doublebounce(INF);
+$nums->doublebounce(-INF);
+$nums->doublebounce(NAN);
+
+check::done();
diff --git a/Examples/test-suite/php/overload_polymorphic_runme.php b/Examples/test-suite/php/overload_polymorphic_runme.php
new file mode 100644
index 0000000..9089882
--- /dev/null
+++ b/Examples/test-suite/php/overload_polymorphic_runme.php
@@ -0,0 +1,12 @@
+<?php
+
+require "tests.php";
+
+$t = new Derived();
+
+check::equal(overload_polymorphic::test($t), 0, "test(Derived)");
+check::equal(overload_polymorphic::test(1), 1, "test(1)");
+check::equal(overload_polymorphic::test2($t), 1, "test2(Derived)");
+check::equal(overload_polymorphic::test3($t, null, $t), 1, "test3(Derived, null, Derived)");
+
+check::done();
diff --git a/Examples/test-suite/php/overload_rename_runme.php b/Examples/test-suite/php/overload_rename_runme.php
index 0357f91..c2df990 100644
--- a/Examples/test-suite/php/overload_rename_runme.php
+++ b/Examples/test-suite/php/overload_rename_runme.php
@@ -1,13 +1,12 @@
 <?php
 
 require "tests.php";
-require "overload_rename.php";
 
 // No new functions
 check::functions(array());
-// No new classes
+// New classes
 check::classes(array('Foo'));
-// now new vars
+// No new vars
 check::globals(array());
 
 $f = new Foo(1.0);
@@ -16,4 +15,3 @@
 $f = Foo::Foo_int(1.0,1,1.0);
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/overload_return_type_runme.php b/Examples/test-suite/php/overload_return_type_runme.php
index 4fa19d2..f03a85d 100644
--- a/Examples/test-suite/php/overload_return_type_runme.php
+++ b/Examples/test-suite/php/overload_return_type_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "overload_return_type.php";
 
 $b = new B;
 check::equal($b->foo(1), 0, "");
@@ -10,4 +9,4 @@
 check::equal(overload_return_type::foo(), 1, "overload_return_type::foo() should be 1");
 check::equal(overload_return_type::bar(), 1, "overload_return_type::bar() should be 1");
 
-?>
+check::done();
diff --git a/Examples/test-suite/php/overload_simple_runme.php b/Examples/test-suite/php/overload_simple_runme.php
new file mode 100644
index 0000000..60cd779
--- /dev/null
+++ b/Examples/test-suite/php/overload_simple_runme.php
@@ -0,0 +1,195 @@
+<?php
+require "tests.php";
+
+check::functions(array('foo','blah','fbool','fint','fdouble','num','fid','as_l','as_ll','as_ul','as_ull','malloc_void','free_void','int_object','sizeof_long'));
+check::classes(array('Foo','Bar','overload_simple','Spam','ClassA'));
+// No new vars
+check::globals(array());
+
+$f = new Foo();
+check::classname("Foo", $f);
+$b = new Bar();
+check::classname("Bar", $b);
+$v = overload_simple::malloc_void(32);
+check::classname("SWIG\_p_void", $v);
+
+#
+# 'simple' dispatch (no overload) of int and double arguments
+#
+
+check::equal(overload_simple::fint(3), "fint:int", "fint(int) - int");
+
+check::equal(overload_simple::fint("1"), "fint:int", "fint(int) - string int");
+
+check::equal(overload_simple::fint(3.0), "fint:int", "fint(int) - double");
+
+check::equal(overload_simple::fint("3.0"), "fint:int", "fint(int) - string double");
+
+# Test handling of cases which aren't simple numbers.
+
+check::equal(overload_simple::fint("l"), "fint:int", "fint(int) - int");
+
+check::equal(overload_simple::fdouble("l"), "fdouble:double", "fint(double) - int");
+
+check::equal(overload_simple::fdouble("1.5/2.0"), "fdouble:double", "fint(double) - double");
+
+# adapted from Perl regression testcase
+$n = 3;
+$n = $n + 1;
+check::equal(overload_simple::fint($n), "fint:int", "fint(int) - int var");
+
+check::equal(overload_simple::fint(4/2), "fint:int", "fint(int) - divide int denom");
+
+check::equal(overload_simple::fint(4/2.0), "fint:int", "fint(int) - divide double denom");
+
+check::equal(overload_simple::fdouble(3), "fdouble:double", "fdouble(double) - int");
+
+check::equal(overload_simple::fdouble("3"), "fdouble:double", "fdouble(double) - string int");
+
+check::equal(overload_simple::fdouble(3.0), "fdouble:double", "fdouble(double) - double");
+
+check::equal(overload_simple::fdouble("3.0"), "fdouble:double", "fdouble(double) - string doubl");
+
+#
+# Overload between int and double
+#
+check::equal(overload_simple::num(3), "num:int", "num(int) - int");
+
+check::equal(overload_simple::num(3.0), "num:double", "num(int) - double");
+
+#
+# Overload between int, double, char * and many types.
+#
+check::equal(overload_simple::foo(3), "foo:int", "foo:int - int");
+
+check::equal(overload_simple::foo(3.0), "foo:double", "foo:double - double");
+
+check::equal(overload_simple::foo("3"), "foo:char *", "foo:char * - string int");
+
+check::equal(overload_simple::foo("3.0"), "foo:char *", "foo:char * - string double");
+
+check::equal(overload_simple::foo("hello"), "foo:char *", "foo:char * string");
+
+check::equal(overload_simple::foo($f), "foo:Foo *", "foo:Foo *");
+
+check::equal(overload_simple::foo($b), "foo:Bar *", "foo:Bar *");
+
+check::equal(overload_simple::foo($v), "foo:void *", "foo:void *");
+
+check::equal(overload_simple::blah("hello"), "blah:char *", "blah:char *");
+
+$s = new Spam();
+
+check::equal($s->foo(3), "foo:int", "Spam::foo:int");
+
+check::equal($s->foo(3.0), "foo:double", "Spam::foo(double)");
+
+check::equal($s->foo("hello"), "foo:char *", "Spam::foo:char *");
+
+check::equal($s->foo($f), "foo:Foo *", "Spam::foo(Foo *)");
+
+check::equal($s->foo($b), "foo:Bar *", "Spam::foo(Bar *)");
+
+check::equal($s->foo($v), "foo:void *", "Spam::foo(void *)");
+
+check::equal(Spam::bar(3), "bar:int", "Spam::bar(int)");
+
+check::equal(Spam::bar(3.0), "bar:double", "Spam::bar(double)");
+
+check::equal(Spam::bar("hello"), "bar:char *", "Spam::bar(char *)");
+
+check::equal(Spam::bar($f), "bar:Foo *", "Spam::bar(Foo *)");
+
+check::equal(Spam::bar($b), "bar:Bar *", "Spam::bar(Bar *)");
+
+check::equal(Spam::bar($v), "bar:void *", "Spam::bar(void *)");
+
+# Test constructors
+
+$s = new Spam();
+check::is_a($s, "spam");
+
+check::equal($s->type, "none", "Spam()");
+
+$s = new Spam(3);
+check::is_a($s, "spam");
+
+check::equal($s->type, "int", "Spam(int)");
+
+$s = new Spam(3.0);
+check::is_a($s, "spam");
+check::equal($s->type, "double", "Spam(double)");
+
+$s = new Spam("hello");
+check::is_a($s, "spam");
+check::equal($s->type, "char *", "Spam(char *)");
+
+$s = new Spam($f);
+check::is_a($s, "spam");
+check::equal($s->type, "Foo *", "Spam(Foo *)");
+
+$s = new Spam($b);
+check::is_a($s, "spam");
+check::equal($s->type, "Bar *", "Spam(Bar *)");
+
+$s = new Spam($v);
+check::is_a($s, "spam");
+check::equal($s->type, "void *", "Spam(void *)");
+
+#
+# Combine dispatch
+#
+
+check::equal(overload_simple::fid(3, 3.0), "fid:intdouble", "fid(int,double)");
+
+check::equal(overload_simple::fid(3.0, 3), "fid:doubleint", "fid(double,int)");
+
+check::equal(overload_simple::fid(3.0, 3.0), "fid:doubledouble", "fid(double,double)");
+
+check::equal(overload_simple::fid(3, 3), "fid:intint", "fid(int,int)");
+
+check::equal(false, overload_simple::fbool(false), "fbool(bool)");
+check::equal(true, overload_simple::fbool(true), "fbool(bool)");
+check::equal(2, overload_simple::fbool(2), "fbool(int)");
+
+# int and object overload
+
+check::equal(overload_simple::int_object(1), 1, "int_object(1)");
+check::equal(overload_simple::int_object(0), 0, "int_object(0)");
+check::equal(overload_simple::int_object(NULL), 999, "int_object(Spam*)");
+check::equal(overload_simple::int_object($s), 999, "int_object(Spam*)");
+
+function check($args, $want) {
+  if ($want === NULL) {
+    try {
+      eval("return Spam::bar($args);");
+      check::fail("Expected exception");
+    } catch (TypeError $e) {
+      check::equal(substr($e->getMessage(), 0, 35), "No matching function for overloaded", "Not the expected I expected");
+    }
+    return;
+  }
+  check::equal(eval("return Spam::bar($args);"), "bar:$want", "bar($args) => $want");
+}
+
+# normal use patterns
+check("11", 'int');
+check("11.0", 'double');
+check("'11'", 'char *');
+check("'11.0'", 'char *');
+check("-13", 'int');
+check("-13.0", 'double');
+check("'-13'", 'char *');
+check("'-13.0'", 'char *');
+
+check("' '", 'char *');
+check("' 11 '", 'char *');
+
+# Check TypeError is thrown when the wrong type is passed.
+check("array()", NULL);
+check("function(){}", NULL);
+check("new stdClass()", NULL);
+class NotASwigWrappedClass { };
+check("new NotASwigWrappedClass()", NULL);
+
+check::done();
diff --git a/Examples/test-suite/php/overload_subtype_runme.php b/Examples/test-suite/php/overload_subtype_runme.php
new file mode 100644
index 0000000..f12025c
--- /dev/null
+++ b/Examples/test-suite/php/overload_subtype_runme.php
@@ -0,0 +1,11 @@
+<?php
+require "tests.php";
+
+$f = new Foo();
+$b = new Bar();
+
+check::equal(spam($f), 1, "foo");
+
+check::equal(spam($b), 2, "bar");
+
+check::done();
diff --git a/Examples/test-suite/php/overload_template_fast_runme.php b/Examples/test-suite/php/overload_template_fast_runme.php
new file mode 100644
index 0000000..7aa19f6
--- /dev/null
+++ b/Examples/test-suite/php/overload_template_fast_runme.php
@@ -0,0 +1,110 @@
+<?php
+
+require "tests.php";
+
+$f = foo();
+
+$a = maximum(3, 4);
+$b = maximum(3.4, 5.2);
+
+# mix 1
+check::equal(mix1("hi"), 101, "mix1(const char*)");
+
+check::equal(mix1(1.0, 1.0), 102, "mix1(double, const double &)");
+
+check::equal(mix1(1.0), 103, "mix1(double)");
+
+# mix 2
+check::equal(mix2("hi"), 101, "mix2(const char*)");
+
+check::equal(mix2(1.0, 1.0), 102, "mix2(double, const double &)");
+
+check::equal(mix2(1.0), 103, "mix2(double)");
+
+# mix 3
+check::equal(mix3("hi"), 101, "mix3(const char*)");
+
+check::equal(mix3(1.0, 1.0), 102, "mix3(double, const double &)");
+
+check::equal(mix3(1.0), 103, "mix3(double)");
+
+# Combination 1
+check::equal(overtparams1(100), 10, "overtparams1(int)");
+
+check::equal(overtparams1(100.0, 100), 20, "overtparams1(double, int)");
+
+# Combination 2
+check::equal(overtparams2(100.0, 100), 40, "overtparams2(double, int)");
+
+# Combination 3
+check::equal(overloaded(), 60, "overloaded()");
+
+check::equal(overloaded(100.0, 100), 70, "overloaded(double, int)");
+
+# Combination 4
+check::equal(overloadedagain("hello"), 80, "overloadedagain(const char *)");
+
+check::equal(overloadedagain(), 90, "overloadedagain(double)");
+
+# specializations
+check::equal(specialization(10), 202, "specialization(int)");
+
+check::equal(specialization(10.0), 203, "specialization(double)");
+
+check::equal(specialization(10, 10), 204, "specialization(int, int)");
+
+check::equal(specialization(10.0, 10.0), 205, "specialization(double, double)");
+
+check::equal(specialization("hi", "hi"), 201, "specialization(const char *, const char *)");
+
+# simple specialization
+xyz();
+xyz_int();
+xyz_double();
+
+# a bit of everything
+check::equal(overload("hi"), 0, "overload()");
+
+check::equal(overload(1), 10, "overload(int t)");
+
+check::equal(overload(1, 1), 20, "overload(int t, const int &)");
+
+check::equal(overload(1, "hello"), 30, "overload(int t, const char *)");
+
+$k = new Klass();
+check::equal(overload($k), 10, "overload(Klass t)");
+
+check::equal(overload($k, $k), 20, "overload(Klass t, const Klass &)");
+
+check::equal(overload($k, "hello"), 30, "overload(Klass t, const char *)");
+
+check::equal(overload(10.0, "hi"), 40, "overload(double t, const char *)");
+
+check::equal(overload(), 50, "overload(const char *)");
+
+# everything put in a namespace
+check::equal(nsoverload("hi"), 1000, "nsoverload()");
+
+check::equal(nsoverload(1), 1010, "nsoverload(int t)");
+
+check::equal(nsoverload(1, 1), 1020, "nsoverload(int t, const int &)");
+
+check::equal(nsoverload(1, "hello"), 1030, "nsoverload(int t, const char *)");
+
+check::equal(nsoverload($k), 1010, "nsoverload(Klass t)");
+
+check::equal(nsoverload($k, $k), 1020, "nsoverload(Klass t, const Klass &)");
+
+check::equal(nsoverload($k, "hello"), 1030, "nsoverload(Klass t, const char *)");
+
+check::equal(nsoverload(10.0, "hi"), 1040, "nsoverload(double t, const char *)");
+
+check::equal(nsoverload(), 1050, "nsoverload(const char *)");
+
+
+A::foo(1);
+$b = new B();
+$b->foo(1);
+
+
+check::done();
diff --git a/Examples/test-suite/php/overload_template_runme.php b/Examples/test-suite/php/overload_template_runme.php
new file mode 100644
index 0000000..7aa19f6
--- /dev/null
+++ b/Examples/test-suite/php/overload_template_runme.php
@@ -0,0 +1,110 @@
+<?php
+
+require "tests.php";
+
+$f = foo();
+
+$a = maximum(3, 4);
+$b = maximum(3.4, 5.2);
+
+# mix 1
+check::equal(mix1("hi"), 101, "mix1(const char*)");
+
+check::equal(mix1(1.0, 1.0), 102, "mix1(double, const double &)");
+
+check::equal(mix1(1.0), 103, "mix1(double)");
+
+# mix 2
+check::equal(mix2("hi"), 101, "mix2(const char*)");
+
+check::equal(mix2(1.0, 1.0), 102, "mix2(double, const double &)");
+
+check::equal(mix2(1.0), 103, "mix2(double)");
+
+# mix 3
+check::equal(mix3("hi"), 101, "mix3(const char*)");
+
+check::equal(mix3(1.0, 1.0), 102, "mix3(double, const double &)");
+
+check::equal(mix3(1.0), 103, "mix3(double)");
+
+# Combination 1
+check::equal(overtparams1(100), 10, "overtparams1(int)");
+
+check::equal(overtparams1(100.0, 100), 20, "overtparams1(double, int)");
+
+# Combination 2
+check::equal(overtparams2(100.0, 100), 40, "overtparams2(double, int)");
+
+# Combination 3
+check::equal(overloaded(), 60, "overloaded()");
+
+check::equal(overloaded(100.0, 100), 70, "overloaded(double, int)");
+
+# Combination 4
+check::equal(overloadedagain("hello"), 80, "overloadedagain(const char *)");
+
+check::equal(overloadedagain(), 90, "overloadedagain(double)");
+
+# specializations
+check::equal(specialization(10), 202, "specialization(int)");
+
+check::equal(specialization(10.0), 203, "specialization(double)");
+
+check::equal(specialization(10, 10), 204, "specialization(int, int)");
+
+check::equal(specialization(10.0, 10.0), 205, "specialization(double, double)");
+
+check::equal(specialization("hi", "hi"), 201, "specialization(const char *, const char *)");
+
+# simple specialization
+xyz();
+xyz_int();
+xyz_double();
+
+# a bit of everything
+check::equal(overload("hi"), 0, "overload()");
+
+check::equal(overload(1), 10, "overload(int t)");
+
+check::equal(overload(1, 1), 20, "overload(int t, const int &)");
+
+check::equal(overload(1, "hello"), 30, "overload(int t, const char *)");
+
+$k = new Klass();
+check::equal(overload($k), 10, "overload(Klass t)");
+
+check::equal(overload($k, $k), 20, "overload(Klass t, const Klass &)");
+
+check::equal(overload($k, "hello"), 30, "overload(Klass t, const char *)");
+
+check::equal(overload(10.0, "hi"), 40, "overload(double t, const char *)");
+
+check::equal(overload(), 50, "overload(const char *)");
+
+# everything put in a namespace
+check::equal(nsoverload("hi"), 1000, "nsoverload()");
+
+check::equal(nsoverload(1), 1010, "nsoverload(int t)");
+
+check::equal(nsoverload(1, 1), 1020, "nsoverload(int t, const int &)");
+
+check::equal(nsoverload(1, "hello"), 1030, "nsoverload(int t, const char *)");
+
+check::equal(nsoverload($k), 1010, "nsoverload(Klass t)");
+
+check::equal(nsoverload($k, $k), 1020, "nsoverload(Klass t, const Klass &)");
+
+check::equal(nsoverload($k, "hello"), 1030, "nsoverload(Klass t, const char *)");
+
+check::equal(nsoverload(10.0, "hi"), 1040, "nsoverload(double t, const char *)");
+
+check::equal(nsoverload(), 1050, "nsoverload(const char *)");
+
+
+A::foo(1);
+$b = new B();
+$b->foo(1);
+
+
+check::done();
diff --git a/Examples/test-suite/php/php_iterator_runme.php b/Examples/test-suite/php/php_iterator_runme.php
index fd645cc..76b4757 100644
--- a/Examples/test-suite/php/php_iterator_runme.php
+++ b/Examples/test-suite/php/php_iterator_runme.php
@@ -1,9 +1,9 @@
 <?php
 
 require "tests.php";
-require "php_iterator.php";
 
-check::functions(array('myiterator_rewind','myiterator_key','myiterator_current','myiterator_next','myiterator_valid'));
+// No new functions.
+check::functions(array());
 check::classes(array('MyIterator'));
 // No new global variables.
 check::globals(array());
@@ -21,4 +21,3 @@
 check::equal($s, '(0=>2)(1=>3)(2=>4)', 'Simple iteration failed');
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/php_pragma_runme.php b/Examples/test-suite/php/php_pragma_runme.php
index c76cfc9..cf29770 100644
--- a/Examples/test-suite/php/php_pragma_runme.php
+++ b/Examples/test-suite/php/php_pragma_runme.php
@@ -1,11 +1,14 @@
 <?php
 
 require "tests.php";
-require "php_pragma.php";
 
+// No new functions
+check::functions(array());
+// No new classes
+check::classes(array());
+// No new vars
+check::globals(array());
 
 check::equal('1.5',(new ReflectionExtension('php_pragma'))->getVersion(),"1.5==version(php_pragma)");
 
 check::done();
-
-?>
diff --git a/Examples/test-suite/php/pointer_reference_runme.php b/Examples/test-suite/php/pointer_reference_runme.php
index 5294617..a8a5112 100644
--- a/Examples/test-suite/php/pointer_reference_runme.php
+++ b/Examples/test-suite/php/pointer_reference_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "pointer_reference.php";
 
 $s  = pointer_reference::get();
 check::equal($s->value, 10, "pointer_reference::get() failed");
@@ -15,4 +14,3 @@
 check::equal(pointer_reference::overloading($ss), 222, "overload test 2 failed");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/prefix_runme.php b/Examples/test-suite/php/prefix_runme.php
index fcf7c66..9f83df1 100644
--- a/Examples/test-suite/php/prefix_runme.php
+++ b/Examples/test-suite/php/prefix_runme.php
@@ -1,18 +1,18 @@
 <?php
 
 require "tests.php";
-require "prefix.php";
 
-// No new functions
-check::functions(array('foo_get_self'));
-// No new classes
-check::classes(array('ProjectFoo'));
-// now new vars
+// New functions
+check::functions(array('self'));
+// New classes
+check::classes(array('Project','ProjectBar','ProjectFoo'));
+// No new vars
 check::globals(array());
 
 $f = new ProjectFoo();
 // This resulted in "Fatal error: Class 'Foo' not found"
 $f->get_self();
 
+Project::self(new ProjectBar());
+
 check::done();
-?>
diff --git a/Examples/test-suite/php/preproc_constants_c_runme.php b/Examples/test-suite/php/preproc_constants_c_runme.php
index 20868dc..b48409c 100644
--- a/Examples/test-suite/php/preproc_constants_c_runme.php
+++ b/Examples/test-suite/php/preproc_constants_c_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "preproc_constants_c.php";
 
 // Same as preproc_constants.i testcase, but bool types are int instead
 check::equal(gettype(preproc_constants_c::CONST_INT1), "integer", "preproc_constants.CONST_INT1 has unexpected type");
@@ -27,8 +26,10 @@
 check::equal(gettype(preproc_constants_c::CONST_DOUBLE2), "double", "preproc_constants.CONST_DOUBLE2 has unexpected type");
 check::equal(gettype(preproc_constants_c::CONST_DOUBLE3), "double", "preproc_constants.CONST_DOUBLE3 has unexpected type");
 check::equal(gettype(preproc_constants_c::CONST_DOUBLE4), "double", "preproc_constants.CONST_DOUBLE4 has unexpected type");
-check::equal(gettype(preproc_constants_c::CONST_DOUBLE5), "double", "preproc_constants.CONST_DOUBLE5 has unexpected type");
-check::equal(gettype(preproc_constants_c::CONST_DOUBLE6), "double", "preproc_constants.CONST_DOUBLE6 has unexpected type");
+# C/C++ `float` constants are wrapped as PHP `double` as PHP doesn't have a
+# `float` type.
+check::equal(gettype(preproc_constants_c::CONST_FLOAT1), "double", "preproc_constants.CONST_FLOAT1 has unexpected type");
+check::equal(gettype(preproc_constants_c::CONST_FLOAT2), "double", "preproc_constants.CONST_FLOAT2 has unexpected type");
 check::equal(gettype(preproc_constants_c::CONST_BOOL1), "integer", "preproc_constants.CONST_BOOL1 has unexpected type");
 check::equal(gettype(preproc_constants_c::CONST_BOOL2), "integer", "preproc_constants.CONST_BOOL2 has unexpected type");
 check::equal(gettype(preproc_constants_c::CONST_CHAR), "string", "preproc_constants.CONST_CHAR has unexpected type");
@@ -52,6 +53,8 @@
 check::equal(gettype(preproc_constants_c::EXPR_MINUS), "integer", "preproc_constants.EXPR_MINUS has unexpected type");
 check::equal(gettype(preproc_constants_c::EXPR_LSHIFT), "integer", "preproc_constants.EXPR_LSHIFT has unexpected type");
 check::equal(gettype(preproc_constants_c::EXPR_RSHIFT), "integer", "preproc_constants.EXPR_RSHIFT has unexpected type");
+check::equal(gettype(preproc_constants_c::EXPR_LT), "integer", "preproc_constants.EXPR_LT has unexpected type");
+check::equal(gettype(preproc_constants_c::EXPR_GT), "integer", "preproc_constants.EXPR_GT has unexpected type");
 check::equal(gettype(preproc_constants_c::EXPR_LTE), "integer", "preproc_constants.EXPR_LTE has unexpected type");
 check::equal(gettype(preproc_constants_c::EXPR_GTE), "integer", "preproc_constants.EXPR_GTE has unexpected type");
 check::equal(gettype(preproc_constants_c::EXPR_INEQUALITY), "integer", "preproc_constants.EXPR_INEQUALITY has unexpected type");
@@ -66,4 +69,4 @@
 check::equal(gettype(preproc_constants_c::EXPR_WCHAR_MAX), "integer", "preproc_constants.EXPR_WCHAR_MAX has unexpected type");
 check::equal(gettype(preproc_constants_c::EXPR_WCHAR_MIN), "integer", "preproc_constants.EXPR_WCHAR_MIN has unexpected type");
 
-?>
+check::done();
diff --git a/Examples/test-suite/php/preproc_constants_runme.php b/Examples/test-suite/php/preproc_constants_runme.php
index bd216c2..3d550e1 100644
--- a/Examples/test-suite/php/preproc_constants_runme.php
+++ b/Examples/test-suite/php/preproc_constants_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "preproc_constants.php";
 
 check::equal(gettype(preproc_constants::CONST_INT1), "integer", "preproc_constants.CONST_INT1 has unexpected type");
 check::equal(gettype(preproc_constants::CONST_INT2), "integer", "preproc_constants.CONST_INT2 has unexpected type");
@@ -26,8 +25,10 @@
 check::equal(gettype(preproc_constants::CONST_DOUBLE2), "double", "preproc_constants.CONST_DOUBLE2 has unexpected type");
 check::equal(gettype(preproc_constants::CONST_DOUBLE3), "double", "preproc_constants.CONST_DOUBLE3 has unexpected type");
 check::equal(gettype(preproc_constants::CONST_DOUBLE4), "double", "preproc_constants.CONST_DOUBLE4 has unexpected type");
-check::equal(gettype(preproc_constants::CONST_DOUBLE5), "double", "preproc_constants.CONST_DOUBLE5 has unexpected type");
-check::equal(gettype(preproc_constants::CONST_DOUBLE6), "double", "preproc_constants.CONST_DOUBLE6 has unexpected type");
+# C/C++ `float` constants are wrapped as PHP `double` as PHP doesn't have a
+# `float` type.
+check::equal(gettype(preproc_constants::CONST_FLOAT1), "double", "preproc_constants.CONST_FLOAT1 has unexpected type");
+check::equal(gettype(preproc_constants::CONST_FLOAT2), "double", "preproc_constants.CONST_FLOAT2 has unexpected type");
 check::equal(gettype(preproc_constants::CONST_BOOL1), "boolean", "preproc_constants.CONST_BOOL1 has unexpected type");
 check::equal(gettype(preproc_constants::CONST_BOOL2), "boolean", "preproc_constants.CONST_BOOL2 has unexpected type");
 check::equal(gettype(preproc_constants::CONST_CHAR), "string", "preproc_constants.CONST_CHAR has unexpected type");
@@ -51,6 +52,8 @@
 check::equal(gettype(preproc_constants::EXPR_MINUS), "integer", "preproc_constants.EXPR_MINUS has unexpected type");
 check::equal(gettype(preproc_constants::EXPR_LSHIFT), "integer", "preproc_constants.EXPR_LSHIFT has unexpected type");
 check::equal(gettype(preproc_constants::EXPR_RSHIFT), "integer", "preproc_constants.EXPR_RSHIFT has unexpected type");
+check::equal(gettype(preproc_constants::EXPR_LT), "boolean", "preproc_constants.EXPR_LT has unexpected type");
+check::equal(gettype(preproc_constants::EXPR_GT), "boolean", "preproc_constants.EXPR_GT has unexpected type");
 check::equal(gettype(preproc_constants::EXPR_LTE), "boolean", "preproc_constants.EXPR_LTE has unexpected type");
 check::equal(gettype(preproc_constants::EXPR_GTE), "boolean", "preproc_constants.EXPR_GTE has unexpected type");
 check::equal(gettype(preproc_constants::EXPR_INEQUALITY), "boolean", "preproc_constants.EXPR_INEQUALITY has unexpected type");
@@ -65,4 +68,4 @@
 check::equal(gettype(preproc_constants::EXPR_WCHAR_MAX), "integer", "preproc_constants.EXPR_WCHAR_MAX has unexpected type");
 check::equal(gettype(preproc_constants::EXPR_WCHAR_MIN), "integer", "preproc_constants.EXPR_WCHAR_MIN has unexpected type");
 
-?>
+check::done();
diff --git a/Examples/test-suite/php/primitive_ref_runme.php b/Examples/test-suite/php/primitive_ref_runme.php
index 263a280..9b281cf 100644
--- a/Examples/test-suite/php/primitive_ref_runme.php
+++ b/Examples/test-suite/php/primitive_ref_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "primitive_ref.php";
 
 # A large long long number is too big, so PHP makes treats it as a double, but SWIG opts to return it as a string.
 # The conversion to double can lose precision so this isn't an exact comparison.
@@ -31,4 +30,3 @@
 long_long_equal(ref_ulonglong(0xF23456789ABCDEF0), 0xF23456789ABCDEF0, "ref_ulonglong failed");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/rename_camel_runme.php b/Examples/test-suite/php/rename_camel_runme.php
new file mode 100644
index 0000000..9aaeda0
--- /dev/null
+++ b/Examples/test-suite/php/rename_camel_runme.php
@@ -0,0 +1,13 @@
+<?php
+
+require "tests.php";
+
+// We want to fail if any extra classes/function/constants are defined.
+check::werror(true);
+
+check::classes(array("rename_camel","GeometryFactory","ByteOrderValues"));
+check::functions(array("CamelCase","CamelCase1","CamelCase2","CamelCase3","lowerCamelCase","lowerCamelCase1","lowerCamelCase2","lowerCamelCase3","under_case","under_case1","under_case2","under_case3","Import","foo","hello"));
+check::constants(array("HELLO","HI_THERE","BYE","SEE_YOU"));
+
+
+check::done();
diff --git a/Examples/test-suite/php/rename_scope_runme.php b/Examples/test-suite/php/rename_scope_runme.php
index df620d7..e1db4f5 100644
--- a/Examples/test-suite/php/rename_scope_runme.php
+++ b/Examples/test-suite/php/rename_scope_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "rename_scope.php";
 
 check::classes(array("rename_scope","Interface_UP","Interface_BP","Natural_UP","Natural_BP","Bucket"));
 
@@ -13,4 +12,3 @@
 check::classparent("Natural_BP","Interface_BP");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/skel.php b/Examples/test-suite/php/skel.php
index 780a999..7fdebc7 100644
--- a/Examples/test-suite/php/skel.php
+++ b/Examples/test-suite/php/skel.php
@@ -2,14 +2,12 @@
 // Sample test file
 
 require "tests.php";
-require "____.php";
 
 // No new functions
 check::functions(array());
 // No new classes
 check::classes(array());
-// now new vars
+// No new vars
 check::globals(array());
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/smart_pointer_rename_runme.php b/Examples/test-suite/php/smart_pointer_rename_runme.php
index 26692dd..0948603 100644
--- a/Examples/test-suite/php/smart_pointer_rename_runme.php
+++ b/Examples/test-suite/php/smart_pointer_rename_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "smart_pointer_rename.php";
 
 check::classes(array("Foo","Bar"));
 check::classmethods("foo",array("ftest1","ftest2","__set","__isset","__get","__construct"));
@@ -24,4 +23,3 @@
 check::classname("foo",$bar->__deref__());
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/smart_pointer_static_runme.php b/Examples/test-suite/php/smart_pointer_static_runme.php
new file mode 100644
index 0000000..71f7a74
--- /dev/null
+++ b/Examples/test-suite/php/smart_pointer_static_runme.php
@@ -0,0 +1,18 @@
+<?php
+
+require "tests.php";
+
+check::classes(array("Foo2","MyHandle_Foo2"));
+
+// This doesn't actually test any smart pointer stuff, just that static
+// vs non-static overloading is wrapped suitable (fixed in SWIG 4.2.0).
+//
+// We can't make the same wrapped method both static and non-static in PHP
+// so we make it non-static, and that at least allows the static version
+// to be called via an object.
+$foo2=new Foo2();
+check::classname("foo2",$foo2);
+check::equal($foo2->sum(1,2), 3);
+check::equal($foo2->sum(1,2,3), 6);
+
+check::done();
diff --git a/Examples/test-suite/php/swig_exception_runme.php b/Examples/test-suite/php/swig_exception_runme.php
index 7664199..c218890 100644
--- a/Examples/test-suite/php/swig_exception_runme.php
+++ b/Examples/test-suite/php/swig_exception_runme.php
@@ -1,6 +1,5 @@
 <?php
 
-require("swig_exception.php");
 require("tests.php");
 
 $c = new Circle(10);
@@ -30,4 +29,4 @@
     check::fail("Shape::nshapes() should be 0, actually ".Shape::nshapes());
 }
 
-?>
+check::done();
diff --git a/Examples/test-suite/php/sym_runme.php b/Examples/test-suite/php/sym_runme.php
index 127d28f..7e8f914 100644
--- a/Examples/test-suite/php/sym_runme.php
+++ b/Examples/test-suite/php/sym_runme.php
@@ -1,13 +1,12 @@
 <?php
 
 require "tests.php";
-require "sym.php";
 
 // No new functions
 check::functions(array());
-// No new classes
-check::classes(array('flim','flam'));
-// now new vars
+// New classes
+check::classes(array('Flim','Flam'));
+// No new vars
 check::globals(array());
 
 $flim=new flim();
@@ -19,4 +18,3 @@
 check::equal($flam->jar(),"flam-jar","flam()->jar==flam-jar");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/template_arg_typename_runme.php b/Examples/test-suite/php/template_arg_typename_runme.php
index e609240..c7fcbbd 100644
--- a/Examples/test-suite/php/template_arg_typename_runme.php
+++ b/Examples/test-suite/php/template_arg_typename_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "template_arg_typename.php";
 
 // No new functions
 check::functions(array());
@@ -15,4 +14,3 @@
 check::is_a($bufb,"boolunaryfunction_bool");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/template_construct_runme.php b/Examples/test-suite/php/template_construct_runme.php
index b227d9f..84d6abf 100644
--- a/Examples/test-suite/php/template_construct_runme.php
+++ b/Examples/test-suite/php/template_construct_runme.php
@@ -1,11 +1,9 @@
 <?php
 
 require "tests.php";
-require "template_construct.php";
 
-check::classes(array('Foo_int'));
+check::classes(array('Foo_int','Foo_short'));
 $foo_int=new foo_int(3);
 check::is_a($foo_int,"foo_int","Made a foo_int");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/tests.php b/Examples/test-suite/php/tests.php
index 20fa1ed..1136d7a 100644
--- a/Examples/test-suite/php/tests.php
+++ b/Examples/test-suite/php/tests.php
@@ -1,86 +1,31 @@
 <?php
 
-function die_on_error($errno, $errstr, $file, $line) {
-    if ($file !== Null) {
-        print $file;
-        if ($line !== Null) print ":$line";
-        print ": ";
-    }
-    print "$errstr\n";
-    exit(1);
-}
-set_error_handler("die_on_error", -1);
-
-$_original_functions=get_defined_functions();
-$_original_globals=1;
-$_original_classes=get_declared_classes();
-$_original_globals=array_keys($GLOBALS);
-
 class check {
   // do we have true global vars or just GETSET functions?
   // Used to filter out get/set global functions to fake vars...
   const GETSET = 1;
 
-  static function get_extra_classes($ref=FALSE) {
-    static $extra;
-    global $_original_classes;
-    if ($ref===FALSE) $f=$_original_classes;
-    if (! is_array($extra)) {
-      $df=array_flip(get_declared_classes());
-      foreach($_original_classes as $class) unset($df[$class]);
-      $extra=array_keys($df);
-    }
-    return $extra;
-  }
+  private static $_extension = null;
 
-  static function get_extra_functions($ref=FALSE,$gs=false) {
-    static $extra;
-    static $extrags; // for get/setters
-    global $_original_functions;
-    if ($ref===FALSE) $f=$_original_functions;
-    if (! is_array($extra) || $gs) {
-      $extra=array();
-      $extrags=array();
-      $df=get_defined_functions();
-      $df=array_flip($df['internal']);
-      foreach($_original_functions['internal'] as $func) unset($df[$func]);
-      // Now chop out any get/set accessors
-      foreach(array_keys($df) as $func)
-        if ((self::GETSET && preg_match('/_[gs]et$/', $func)) ||
-            preg_match('/^new_/', $func) ||
-            preg_match('/_(alter|get)_newobject$/', $func))
-          $extrags[]=$func;
-        else $extra[]=$func;
-//      $extra=array_keys($df);
-    }
-    if ($gs) return $extrags;
-    return $extra;
-  }
+  private static $_werror = false;
 
-  static function get_extra_globals($ref=FALSE) {
-    static $extra;
-    global $_original_globals;
-    if (! is_array($extra)) {
-      if (self::GETSET) {
-        $_extra=array();
-        foreach(check::get_extra_functions(false,1) as $global) {
-          if (preg_match('/^(.*)_[sg]et$/', $global, $match))
-            $_extra[$match[1]] = 1;
-        }
-        $extra=array_keys($_extra);
-      } else {
-        if ($ref===FALSE) $ref=$_original_globals;
-        if (! is_array($extra)) {
-          $df=array_flip(array_keys($GLOBALS));
-          foreach($_original_globals as $func) unset($df[$func]);
-          // MASK xxxx_LOADED__ variables
-          foreach(array_keys($df) as $func)
-            if (preg_match('/_LOADED__$/', $func)) unset($df[$func]);
-          $extra=array_keys($df);
-        }
+  static function get_extension() {
+    if (self::$_extension === null) {
+      foreach(get_included_files() as $f) {
+	$module_name = preg_filter('/.*\/([^\/]+)_runme\.php$/', '\1', $f);
+	if ($module_name !== null) break;
       }
+      if ($module_name === null) {
+	print("Failed to determine module name from get_included_files()\n");
+	exit(1);
+      }
+      self::$_extension = new ReflectionExtension($module_name);
     }
-    return $extra;
+    return self::$_extension;
+  }
+
+  static function werror($v) {
+    self::$_werror = $v;
   }
 
   static function classname($string,$object) {
@@ -148,7 +93,8 @@
     if (! is_array($classes)) $classes=array($classes);
     $message=array();
     $missing=array();
-    $extra=array_flip(check::get_extra_classes());
+    $extra = array_flip(array_filter(self::get_extension()->getClassNames(),
+				     function ($e) { return !preg_match('/^SWIG\\\\/', $e); }));
     foreach($classes as $class) {
       if (! class_exists($class)) $missing[]=$class;
       else unset($extra[$class]);
@@ -164,15 +110,16 @@
     if (! is_array($functions)) $functions=array($functions);
     $message=array();
     $missing=array();
-    $extra=array_flip(check::get_extra_functions());
-
+    $extra = self::get_extension()->getFunctions();
     foreach ($functions as $func) {
       if (! function_exists($func)) $missing[]=$func;
       else unset($extra[$func]);
     }
+    $extra = array_filter(array_keys($extra),
+			  function ($e) { return !preg_match('/_[gs]et$|^is_python_/', $e); });
     if ($missing) $message[]=sprintf("Functions missing: %s",join(",",$missing));
     if ($message) return check::fail(join("\n  ",$message));
-    if ($extra) $message[]=sprintf("These extra functions are defined: %s",join(",",array_keys($extra)));
+    if ($extra) $message[]=sprintf("These extra functions are defined: %s",join(",",$extra));
     if ($message) return check::warn(join("\n  ",$message));
     return TRUE;    
   }
@@ -181,64 +128,82 @@
     if (! is_array($globals)) $globals=array($globals);
     $message=array();
     $missing=array();
-    $extra=array_flip(check::get_extra_globals());
+    $extra = self::get_extension()->getFunctions();
     foreach ($globals as $glob) {
-      if (self::GETSET) {
-        if (! isset($extra[$glob])) $missing[]=$glob;
-        else unset($extra[$glob]);
-      } else {
-        if (! isset($GLOBALS[$glob])) $missing[]=$glob;
-        else unset($extra[$glob]);
+      if (! function_exists($glob . "_get") && ! function_exists($glob . "_set")) $missing[]=$glob;
+      else {
+        unset($extra[$glob . "_get"]);
+        unset($extra[$glob . "_set"]);
       }
     }
+    $extra = array_filter(array_keys($extra),
+			  function ($e) { return preg_match('/_[gs]et$/', $e); });
     if ($missing) $message[]=sprintf("Globals missing: %s",join(",",$missing));
     if ($message) return check::fail(join("\n  ",$message));
-    if ($extra) $message[]=sprintf("These extra globals are defined: %s",join(",",array_keys($extra)));
+    if ($extra) $message[]=sprintf("These extra globals are defined: %s",join(",",$extra));
     if ($message) return check::warn(join("\n  ",$message));
     return TRUE;    
 
   }
 
+  static function constants($constants) {
+    if (! is_array($constants)) $constants=array($constants);
+    $message=array();
+    $missing=array();
+    $extra = self::get_extension()->getConstants();
+    unset($extra['swig_runtime_data_type_pointer']);
+    foreach($constants as $constant) {
+      if (! defined($constant)) $missing[]=$constant;
+      else unset($extra[$constant]);
+    }
+    if ($missing) $message[]=sprintf("Constants missing: %s",join(",",$missing));
+    if ($message) return check::fail(join("\n  ",$message));
+    if ($extra) $message[]=sprintf("These extra constants are defined: %s",join(",",array_keys($extra)));
+    if ($message) return check::warn(join("\n  ",$message));
+    return TRUE;
+  }
+
   static function functionref($a,$type,$message) {
     if (! preg_match("/^_[a-f0-9]+$type$/i", $a))
       return check::fail($message);
     return TRUE;
   }
 
-  static function equal($a,$b,$message) {
-    if (! ($a===$b)) return check::fail($message . ": '$a'!=='$b'");
+  static function equal($a,$b,$message=null) {
+    if (! ($a===$b)) return check::fail_($message, "'$a'!=='$b'");
     return TRUE;
   }
 
-  static function resource($a,$b,$message) {
-    $resource=trim(check::var_dump($a));
-    if (! preg_match("/^resource\([0-9]+\) of type \($b\)/i", $resource))
-      return check::fail($message);
+  static function equivalent($a,$b,$message=null) {
+    if (! ($a==$b)) return check::fail_($message, "'$a'!='$b'");
     return TRUE;
   }
 
-  static function isnull($a,$message) {
-    $value=trim(check::var_dump($a));
-    return check::equal($value,"NULL",$message);
+  static function str_contains($a,$b,$message=null) {
+    # Use strpos as PHP function str_contains requires PHP 8
+    return check::equal(strpos($a,$b)!==false,true,$message);
   }
 
-  static function var_dump($arg) {
-    ob_start();
-    var_dump($arg);
-    $result=ob_get_contents();
-    ob_end_clean();
-    return $result;
+  static function isnull($a,$message=null) {
+    return check::equal($a,NULL,$message);
   }
 
-  static function fail($pattern) {
-    $args=func_get_args();
-    print("Failed on: ".call_user_func_array("sprintf",$args)."\n");
+  private static function fail_($message, $pattern, ...$args) {
+    $bt = debug_backtrace(0);
+    $bt = $bt[array_key_last($bt)-1];
+    print("{$bt['file']}:{$bt['line']}: Failed on: ");
+    if ($message !== NULL) print("$message: ");
+    print(sprintf($pattern, ...$args) . "\n");
     exit(1);
   }
 
-  static function warn($pattern) {
-    $args=func_get_args();
-    print("Warning on: ".call_user_func_array("sprintf",$args)."\n");
+  static function fail(...$args) {
+    check::fail_(null, ...$args);
+  }
+
+  static function warn($pattern, ...$args) {
+    if (self::$_werror) self::fail($pattern, ...$args);
+    print("Warning on: " . sprintf($pattern, ...$args) . "\n");
     return FALSE;
   }
 
@@ -246,4 +211,3 @@
 #    print $_SERVER[argv][0]." ok\n";
   }
 }
-?>
diff --git a/Examples/test-suite/php/threads_exception_runme.php b/Examples/test-suite/php/threads_exception_runme.php
index 80717eb..e9103f0 100644
--- a/Examples/test-suite/php/threads_exception_runme.php
+++ b/Examples/test-suite/php/threads_exception_runme.php
@@ -1,14 +1,13 @@
 <?php
 
 require "tests.php";
-require "threads_exception.php";
 
-// Check functions
-check::functions(array('test_simple','test_message','test_hosed','test_unknown','test_multi','is_python_builtin'));
+// No new functions
+check::functions(array());
 // Check classes.
 check::classes(array('Exc','Test','threads_exception'));
-// Check globals.
-check::globals(array('exc_code','exc_msg'));
+// No new vars
+check::globals(array());
 
 $t = new Test();
 try {
@@ -41,3 +40,5 @@
     } catch (Exception $e) {
     }
 }
+
+check::done();
diff --git a/Examples/test-suite/php/typedef_reference_runme.php b/Examples/test-suite/php/typedef_reference_runme.php
index 83e75fb..8309c3c 100644
--- a/Examples/test-suite/php/typedef_reference_runme.php
+++ b/Examples/test-suite/php/typedef_reference_runme.php
@@ -1,7 +1,6 @@
 <?php
 
 require "tests.php";
-require "typedef_reference.php";
 
 check::functions(array('somefunc','otherfunc','new_intp','copy_intp','delete_intp','intp_assign','intp_value'));
 $int2=copy_intp(2);
@@ -10,4 +9,3 @@
 check::equal(3,otherfunc($int3)," test passing intp to otherfunc");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/typemap_ns_using_runme.php b/Examples/test-suite/php/typemap_ns_using_runme.php
index 6a599f0..e154278 100644
--- a/Examples/test-suite/php/typemap_ns_using_runme.php
+++ b/Examples/test-suite/php/typemap_ns_using_runme.php
@@ -1,9 +1,8 @@
 <?php
 
 require "tests.php";
-require "typemap_ns_using.php";
+
 if (! class_exists("_fooimpl")) die("_fooimpl class not found\n");
 if (! 3==spam(3)) die("spam function not working right\n");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/using1_runme.php b/Examples/test-suite/php/using1_runme.php
index 51841bc..e154278 100644
--- a/Examples/test-suite/php/using1_runme.php
+++ b/Examples/test-suite/php/using1_runme.php
@@ -1,9 +1,8 @@
 <?php
 
 require "tests.php";
-require "using1.php";
+
 if (! class_exists("_fooimpl")) die("_fooimpl class not found\n");
 if (! 3==spam(3)) die("spam function not working right\n");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/using2_runme.php b/Examples/test-suite/php/using2_runme.php
index 391a98f..e154278 100644
--- a/Examples/test-suite/php/using2_runme.php
+++ b/Examples/test-suite/php/using2_runme.php
@@ -1,9 +1,8 @@
 <?php
 
 require "tests.php";
-require "using2.php";
+
 if (! class_exists("_fooimpl")) die("_fooimpl class not found\n");
 if (! 3==spam(3)) die("spam function not working right\n");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/valuewrapper_base_runme.php b/Examples/test-suite/php/valuewrapper_base_runme.php
index 6a1abdb..3f4c38e 100644
--- a/Examples/test-suite/php/valuewrapper_base_runme.php
+++ b/Examples/test-suite/php/valuewrapper_base_runme.php
@@ -1,13 +1,11 @@
 <?php
 
 require "tests.php";
-require "valuewrapper_base.php";
 
 check::classes(array("valuewrapper_base","Base","Interface_BP"));
-check::functions("make_interface_bp");
+check::functions("make_Interface_BP");
 
 $ibp=valuewrapper_base::make_interface_bp();
 check::classname("interface_bp",$ibp);
 
 check::done();
-?>
diff --git a/Examples/test-suite/php/virtual_vs_nonvirtual_base_runme.php b/Examples/test-suite/php/virtual_vs_nonvirtual_base_runme.php
index 0d4aa3d..8d8d405 100644
--- a/Examples/test-suite/php/virtual_vs_nonvirtual_base_runme.php
+++ b/Examples/test-suite/php/virtual_vs_nonvirtual_base_runme.php
@@ -1,11 +1,10 @@
-<? 
+<?php
 
 require "tests.php";
-require "virtual_vs_nonvirtual_base.php";
 
 $fail = new SimpleClassFail();
 $work = new SimpleClassWork();
 
 check::equal($work->getInner()->get(), $fail->getInner()->get(), "should both be 10");
 
-?>
+check::done();
diff --git a/Examples/test-suite/php/wrapmacro_runme.php b/Examples/test-suite/php/wrapmacro_runme.php
index f32da99..18b2ef1 100644
--- a/Examples/test-suite/php/wrapmacro_runme.php
+++ b/Examples/test-suite/php/wrapmacro_runme.php
@@ -1,12 +1,10 @@
 <?php
 
 require "tests.php";
-require "wrapmacro.php";
 
-check::functions(array('guint16_swap_le_be_constant', 'maximum'));
+check::functions(array('GUINT16_SWAP_LE_BE_CONSTANT', 'maximum'));
 
 check::equal(maximum(2.3, 2.4), 2.4, "maximum() doesn't work");
 check::equal(guint16_swap_le_be_constant(0x1234), 0x3412, "GUINT16_SWAP_LE_BE_CONSTANT() doesn't work");
 
 check::done();
-?>
diff --git a/Examples/test-suite/php_iterator.i b/Examples/test-suite/php_iterator.i
index 43ab68b..e0b82a5 100644
--- a/Examples/test-suite/php_iterator.i
+++ b/Examples/test-suite/php_iterator.i
@@ -1,7 +1,7 @@
 /* php_iterator.i - PHP-specific testcase for wrapping to a PHP Iterator */
 %module php_iterator
 
-%typemap("phpinterfaces") MyIterator "Iterator";
+%typemap("phpinterfaces") MyIterator "Iterator"
 
 %inline %{
 
diff --git a/Examples/test-suite/php_namewarn_rename.i b/Examples/test-suite/php_namewarn_rename.i
index d84e219..d70cad7 100644
--- a/Examples/test-suite/php_namewarn_rename.i
+++ b/Examples/test-suite/php_namewarn_rename.i
@@ -5,6 +5,10 @@
 %warnfilter(SWIGWARN_PARSE_KEYWORD) stdClass;
 %warnfilter(SWIGWARN_PARSE_KEYWORD) directory;
 %warnfilter(SWIGWARN_PARSE_KEYWORD) Hello::empty();
+%warnfilter(SWIGWARN_PARSE_KEYWORD) null;
+%warnfilter(SWIGWARN_PARSE_KEYWORD) True;
+%warnfilter(SWIGWARN_PARSE_KEYWORD) FALSE;
+%warnfilter(SWIGWARN_PARSE_KEYWORD) ns::readonly;
 #endif
 
 %ignore prev::operator++;
@@ -36,4 +40,28 @@
     prev operator++(int) { return *this; }
   };
 
+  class null
+  {
+  };
+
+  class True
+  {
+  };
+
+  class FALSE
+  {
+  };
+
+  // PHP 8.1 made `readonly` a keyword, but (unlike any other keyword it seems)
+  // it may still be used as a function name.
+  namespace ns {
+  class readonly { };
+  }
+
+  class readonly_should_be_ok_as_method {
+  public:
+    bool readonly() const { return true; }
+  };
+
+  bool readonly() { return false; }
 %}
diff --git a/Examples/test-suite/pike/Makefile.in b/Examples/test-suite/pike/Makefile.in
deleted file mode 100644
index 6e1bdfb..0000000
--- a/Examples/test-suite/pike/Makefile.in
+++ /dev/null
@@ -1,49 +0,0 @@
-#######################################################################
-# Makefile for Pike test-suite
-#######################################################################
-
-LANGUAGE     = pike
-PIKE         = pike
-SCRIPTSUFFIX = _runme.pike
-
-srcdir       = @srcdir@
-top_srcdir   = @top_srcdir@
-top_builddir = @top_builddir@
-
-include $(srcdir)/../common.mk
-
-# Overridden variables here
-# none!
-
-# Custom tests - tests with additional commandline options
-# none!
-
-# Rules for the different types of tests
-%.cpptest:
-	$(setup)
-	+$(swig_and_compile_cpp)
-	$(run_testcase)
-
-%.ctest:
-	$(setup)
-	+$(swig_and_compile_c)
-	$(run_testcase)
-
-%.multicpptest:
-	$(setup)
-	+$(swig_and_compile_multi_cpp)
-	$(run_testcase)
-
-# Runs the testcase. A testcase is only run if
-# a file is found which has _runme.pike appended after the testcase name.
-run_testcase = \
-	if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
-	  env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(PIKE) $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \
-	fi
-
-# Clean: remove the generated .pike file
-%.clean:
-	@rm -f $*.pike;
-
-clean:
-	$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' pike_clean
diff --git a/Examples/test-suite/prefix.i b/Examples/test-suite/prefix.i
index b0cb312..ca9e4c4 100644
--- a/Examples/test-suite/prefix.i
+++ b/Examples/test-suite/prefix.i
@@ -11,4 +11,20 @@
   }
 };
 
+// This failed in git pre 4.1.0 - the calls to the parent class' magic __get,
+// __set and __isset methods weren't getting the prefix.
+class Bar : public Foo {
+public:
+  Bar *get_self() {
+    return this;
+  }
+};
+
+// This failed in git pre 4.1.0 with PHP 8.x because we weren't adding the
+// prefix to class names in type declarations.  Error was at extension load
+// time:
+//
+// Fatal error: Bar must be registered before ProjectBar in Unknown on line 0
+Bar* self(Bar* bar) { return bar->get_self(); }
+
 %}
diff --git a/Examples/test-suite/preproc.i b/Examples/test-suite/preproc.i
index 215fdd0..85c6839 100644
--- a/Examples/test-suite/preproc.i
+++ b/Examples/test-suite/preproc.i
@@ -11,13 +11,29 @@
 #pragma SWIG nowarn=890                                      /* lots of Go name conflicts */
 #pragma SWIG nowarn=206                                      /* Unexpected tokens after #endif directive. */
 
+/* Regression test: in SWIG < 4.1.0 this triggered the two #error cases.
+ * Github issue #1384
+ */
+#if "" != ""
+#endif
+#if 1 && (!0)
+// Should go here
+#else
+# error BUG
+#endif
+#if ((("" == ""))) || (1 && (!1))
+// Should go here
+#else
+# error BUG
+#endif
+
 %{
 #if defined(__clang__)
-//Suppress: warning: use of logical '&&' with constant operand [-Wconstant-logical-operand]
+/*Suppress: warning: use of logical '&&' with constant operand [-Wconstant-logical-operand]*/
 #pragma clang diagnostic ignored "-Wconstant-logical-operand"
 #endif
 #if defined(_MSC_VER)
-  #pragma warning(disable: 4003) // not enough actual parameters for macro 'FOO2'
+  #pragma warning(disable: 4003) /* not enough actual parameters for macro 'FOO2' */
 #endif
 %}
 
@@ -72,14 +88,14 @@
 
 TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(boolean)
 
-// preproc_3
+/* preproc_3 */
 
 #define Sum( A, B, \
              C)    \
         A + B + C 
 
 
-// preproc_4
+/* preproc_4 */
 %{
   int hello0()
   {
@@ -102,33 +118,30 @@
 
 #define HELLO_TYPE(A, B) ARITH_RTYPE(A, ARITH_RTYPE(A,B))
 
-//
-// These two work fine
-//
 int hello0();
 ARITH_RTYPE(double,int) hello1();
 
 
-//
-// This doesn't work with 1.3.17+ ( but it was ok in 1.3.16 )
-// it gets expanded as (using -E)
-// 
-//   ARITH_RTYPE(double,int) hello2();
-//
+/*
+   This doesn't work with 1.3.17+ ( but it was ok in 1.3.16 )
+   it gets expanded as (using -E)
+
+     ARITH_RTYPE(double,int) hello2();
+*/
 HELLO_TYPE(double,int) hello2();
 
 #define min(x,y) ((x) < (y)) ? (x) : (y) 
 int f(int min);
 
-// preproc_5
+/* preproc_5 */
 
-%warnfilter(SWIGWARN_PARSE_REDEFINED) A5;	// Ruby, wrong constant name
-%warnfilter(SWIGWARN_RUBY_WRONG_NAME) a5;	// Ruby, wrong constant name
-%warnfilter(SWIGWARN_RUBY_WRONG_NAME) b5;	// Ruby, wrong constant name
-%warnfilter(SWIGWARN_RUBY_WRONG_NAME) c5;	// Ruby, wrong constant name
-%warnfilter(SWIGWARN_RUBY_WRONG_NAME) d5;	// Ruby, wrong constant name
+%warnfilter(SWIGWARN_PARSE_REDEFINED) A5;	/* Ruby, wrong constant name */
+%warnfilter(SWIGWARN_RUBY_WRONG_NAME) a5;	/* Ruby, wrong constant name */
+%warnfilter(SWIGWARN_RUBY_WRONG_NAME) b5;	/* Ruby, wrong constant name */
+%warnfilter(SWIGWARN_RUBY_WRONG_NAME) c5;	/* Ruby, wrong constant name */
+%warnfilter(SWIGWARN_RUBY_WRONG_NAME) d5;	/* Ruby, wrong constant name */
 
-// Various preprocessor bits of nastiness.
+/* Various preprocessor bits of nastiness. */
 
 
 /* Test argument name substitution */
@@ -138,7 +151,7 @@
 %constant char *a5 = foo(hello,world);
 %constant int   b5 = bar(3,4);
 
-// Wrap your brain around this one ;-)
+/* Wrap your brain around this one ;-) */
 
 %{
 #define cat(x,y) x ## y
@@ -168,7 +181,7 @@
 
 #define C4"Hello"
 
-// preproc_6
+/* preproc_6 */
 
 %warnfilter(SWIGWARN_PARSE_REDEFINED) A6; /* Ruby, wrong constant name */
 %warnfilter(SWIGWARN_RUBY_WRONG_NAME) a6; /* Ruby, wrong constant name */
@@ -206,7 +219,7 @@
 
 MACRO2(int)
 
-// cpp_macro_noarg.  Tests to make sure macros with no arguments work right.
+/* cpp_macro_noarg.  Tests to make sure macros with no arguments work right. */
 #define MACROWITHARG(x) something(x) 
 
 typedef int MACROWITHARG; 
@@ -298,11 +311,6 @@
 /* chiao */
 #endif;
 
-#ifdef SWIGCHICKEN
-/* define is a scheme keyword (and thus an invalid variable name), so SWIG warns about it */
-%warnfilter(SWIGWARN_PARSE_KEYWORD) define; 
-#endif
-
 #ifdef SWIGRUBY
 %rename(ddefined) defined;
 #endif
@@ -378,8 +386,11 @@
 int methodX(int x) { return x+100; }
 %}
 
-// Comma in macro - https://github.com/swig/swig/issues/974 (for /* */)
-// and https://github.com/swig/swig/pull/1166 (for //)
+/*
+   Comma in macro - https://github.com/swig/swig/issues/974 (for C comments)
+   and https://github.com/swig/swig/pull/1166 (for //)
+   Also see preproc_cpp.i
+*/
 %inline %{
 #define swig__attribute__(x)
 #define TCX_PACKED(d) d swig__attribute__ ((__packed__))
@@ -397,21 +408,9 @@
 }) tcxMessageBug;
 
 
-TCX_PACKED (typedef struct tcxMessageTestImpl2
-{
-    int mHeader; ///< comment
-}) tcxMessageTest2;
-
-
-TCX_PACKED (typedef struct tcxMessageBugImpl2
-{
-    int mBid; ///< Bid price and size, check PresentMap if available in message
-}) tcxMessageBug2;
-
-
 %}
 
-// Regression tests for https://github.com/swig/swig/pull/1111
+/* Regression tests for https://github.com/swig/swig/pull/1111 */
 %{
 static int foo_func(int x) { return x; }
 static int foo_func2() { return 0; }
@@ -427,22 +426,22 @@
 #define FOOVAR(...) foo_func(__VA_ARGS__)
 #define BARVAR(...) bar_func(__VA_ARGS__)
 #define BAZVAR(...) baz_func(__VA_ARGS__)
-// This has probably always worked, but make sure that the fix to accept
-// an empty X doesn't cause this case to be incorrectly expanded:
+/* This has probably always worked, but make sure that the fix to accept
+   an empty X doesn't cause this case to be incorrectly expanded:*/
 const int FOO = 7;
-// BAR was incorrectly expanded here, causing:
-// Error: Syntax error in input(1).
+/* BAR was incorrectly expanded here, causing:
+   Error: Syntax error in input(1). */
 const int BAR = 6;
-// This has probably always worked, but make sure that the fix to accept
-// an empty X doesn't stop a non-empty X from working:
+/* This has probably always worked, but make sure that the fix to accept
+   an empty X doesn't stop a non-empty X from working: */
 FOO(int x)
-// FOO() didn't used to get expanded here, causing:
-// Syntax error in input(1).
+/* FOO2() didn't used to get expanded here, causing:
+   Syntax error in input(1). */
 FOO2()
-// Check BAR2() still gets expanded here.
+/* Check BAR2() still gets expanded here. */
 BAR2() {
-    // Regression test - this used to fail with:
-    // Error: Macro 'BAZ' expects 3 arguments
+    /* Regression test - this used to fail with:
+       Error: Macro 'BAZ' expects 3 arguments */
     BAZ(,2,3);
     BARVAR();
     FOOVAR(1);
diff --git a/Examples/test-suite/preproc_constants.i b/Examples/test-suite/preproc_constants.i
index 3050baa..53a2e76 100644
--- a/Examples/test-suite/preproc_constants.i
+++ b/Examples/test-suite/preproc_constants.i
@@ -37,8 +37,9 @@
 #define CONST_DOUBLE2   10E1
 #define CONST_DOUBLE3   12.3
 #define CONST_DOUBLE4   12.
-#define CONST_DOUBLE5   12.3f
-#define CONST_DOUBLE6   12.3F
+
+#define CONST_FLOAT1    12.3f
+#define CONST_FLOAT2    12.3F
 
 #define CONST_BOOL1     true
 #define CONST_BOOL2     false
@@ -65,17 +66,15 @@
 
 #define EXPR_MULTIPLY    0xFF * 2
 #define EXPR_DIVIDE      0xFF / 2
-//FIXME #define EXPR_MOD         0xFF % 2
+#define EXPR_MOD         0xFF % 2
 
 #define EXPR_PLUS        0xFF + 2
 #define EXPR_MINUS       0xFF + 2
 
 #define EXPR_LSHIFT      0xFF << 2
 #define EXPR_RSHIFT      0xFF >> 2
-/* FIXME
-#define EXPR_LT          0xFF < 255
-#define EXPR_GT          0xFF > 255
-*/
+#define EXPR_LT          (0xFF < 255)
+#define EXPR_GT          (0xFF > 255)
 #define EXPR_LTE         0xFF <= 255
 #define EXPR_GTE         0xFF >= 255
 #define EXPR_INEQUALITY  0xFF != 255
@@ -121,3 +120,9 @@
   kValue = BIT(2)
 };
 
+// For detecting when test-suite is run with SWIGWORDSIZE64 defined
+#ifdef SWIGWORDSIZE64
+#define SWIGWORDSIZE64_enabled 1
+#else
+#define SWIGWORDSIZE64_enabled 0
+#endif
diff --git a/Examples/test-suite/preproc_cpp.i b/Examples/test-suite/preproc_cpp.i
new file mode 100644
index 0000000..f0c69d4
--- /dev/null
+++ b/Examples/test-suite/preproc_cpp.i
@@ -0,0 +1,69 @@
+%module preproc_cpp
+
+
+// booleans start
+#if false
+# error "boolean preproc check fail false"
+#else
+#endif
+
+#if !false
+#else
+# error "boolean preproc check fail !false"
+#endif
+
+#if true
+#else
+# error "boolean preproc check fail true"
+#endif
+
+#if !true
+# error "boolean preproc check fail !true"
+#else
+#endif
+
+#if (true)
+#else
+# error "boolean preproc check fail (true)"
+#endif
+
+#if (0 || true)
+#else
+# error "boolean preproc check fail (0 || true)"
+#endif
+// booleans end
+
+
+// Comma in macro - https://github.com/swig/swig/issues/974 (for /* */)
+// and https://github.com/swig/swig/pull/1166 (for //)
+// Also see preproc.i
+%inline %{
+#define swig__attribute__(x)
+#define TCX_PACKED(d) d swig__attribute__ ((__packed__))
+
+
+TCX_PACKED (typedef struct tcxMessageTestImpl
+{
+    int mHeader; /**< comment */
+}) tcxMessageTest;
+
+
+TCX_PACKED (typedef struct tcxMessageBugImpl
+{
+    int mBid; /**< Bid price and size, check PresentMap if available in message */
+}) tcxMessageBug;
+
+
+TCX_PACKED (typedef struct tcxMessageTestImpl2
+{
+    int mHeader; ///< comment
+}) tcxMessageTest2;
+
+
+TCX_PACKED (typedef struct tcxMessageBugImpl2
+{
+    int mBid; ///< Bid price and size, check PresentMap if available in message
+}) tcxMessageBug2;
+
+
+%}
diff --git a/Examples/test-suite/preproc_defined.i b/Examples/test-suite/preproc_defined.i
index e195851..4e09b31 100644
--- a/Examples/test-suite/preproc_defined.i
+++ b/Examples/test-suite/preproc_defined.i
@@ -86,7 +86,7 @@
 void defined_not(TYPE);
 #endif
 
-#if !( defined(AAA) \
+#if !( defined(AAA) &&\
  defined(BBB) \\
 && defined(CCC) )
 void bumpf_not(TYPE);
@@ -123,3 +123,93 @@
 #if 0
 # wobble wobble
 #endif
+
+/* Check that #error is ignored inside an inactive conditional. */
+#ifdef THIS_IS_NOT_DEFINED
+# error should not trigger 1
+#endif
+#ifdef AAA
+# define B
+#else
+# error should not trigger 2
+#endif
+#if 0
+# error should not trigger 3
+#endif
+
+/* Check that #warning is ignored inside an inactive conditional. */
+#ifdef THIS_IS_NOT_DEFINED
+# warning should not trigger 1
+#endif
+#ifdef AAA
+# define B
+#else
+# warning should not trigger 2
+#endif
+#if 0
+# warning should not trigger 3
+#endif
+
+
+/* Regression test for https://sourceforge.net/p/swig/bugs/1163/
+ * ONE(1)(2) should expand to `2` but SWIG was expanding it to `TWO(2)`
+ * which results in the generated C wrapper failing to compile.
+ */
+#define ONE(X) TWO
+#define TWO(X) X
+%constant int a = ONE(1)(2);
+#define XXX TWO
+%constant int b = XXX(42);
+#undef ONE
+#undef TWO
+
+/*
+ * The behaviour of Self-Referential Macros is defined
+ * https://gcc.gnu.org/onlinedocs/gcc-4.8.5/cpp/Self-Referential-Macros.html
+ */
+%inline %{
+const int y = 0;
+%}
+
+#define x (4 + y)
+#define y (2 * x)
+
+%constant int z = y;
+
+#undef y
+#undef x
+
+/* Regression test for #ifdef and #ifndef not working inside a %define.
+ * https://github.com/swig/swig/issues/2183
+ */
+#undef THISMACROISNOTDEFINED /* Make sure! */
+#define THISMACROISDEFINED
+
+%define %test()
+
+#ifdef THISMACROISNOTDEFINED
+# error #ifdef inside percent-define failed
+#endif
+#ifndef THISMACROISDEFINED
+# error #ifndef inside percent-define failed
+#endif
+/* Check pre-defined macro too. */
+#ifndef SWIG
+# error #ifndef inside percent-define failed
+#endif
+
+/* These cases already worked, but should still have test coverage. */
+#if defined THISMACROISNOTDEFINED
+# error #if defined inside percent-define failed
+#endif
+#if !defined THISMACROISDEFINED
+# error #if !defined inside percent-define failed
+#endif
+/* Check pre-defined macro too. */
+#if !defined SWIG
+# error #if !defined inside percent-define failed
+#endif
+
+%enddef
+
+%test()
diff --git a/Examples/test-suite/preproc_expr.i b/Examples/test-suite/preproc_expr.i
new file mode 100644
index 0000000..a24f771
--- /dev/null
+++ b/Examples/test-suite/preproc_expr.i
@@ -0,0 +1,34 @@
+%module preproc_expr
+
+// Check expressions which suffered from incorrect operator precedence prior
+// to SWIG 4.1.0.
+
+%inline %{
+// `!` should have higher precedence than binary `+`.
+#if !0 + 1
+#else
+# error Bad preprocessor expression operator precedence
+#endif
+
+// `!=` should have higher precedence than bitwise and.
+#if 1 & 2 != 0
+#else
+# error Bad preprocessor expression operator precedence
+#endif
+
+// `==` should have higher precedence than bitwise or.
+#if (2 | 1 == 3) != 2
+# error Bad preprocessor expression operator precedence
+#endif
+
+// `!=` should have higher precedence than bitwise xor.
+#if 1 ^ 2 != 4
+# error Bad preprocessor expression operator precedence
+#endif
+
+// `<` should have higher precedence than '=='.
+#if 2 == 2 < 2
+# error Bad preprocessor expression operator precedence
+#endif
+
+%}
diff --git a/Examples/test-suite/preproc_predefined.h b/Examples/test-suite/preproc_predefined.h
new file mode 100644
index 0000000..8d6b6ee
--- /dev/null
+++ b/Examples/test-suite/preproc_predefined.h
@@ -0,0 +1,27 @@
+/* This list will need updating when new target languages are added. */
+#if (0\
+  +defined(SWIGCSHARP)\
+  +defined(SWIGD)\
+  +defined(SWIGGO)\
+  +defined(SWIGGUILE)\
+  +defined(SWIGJAVA)\
+  +defined(SWIGJAVASCRIPT)\
+  +defined(SWIGLUA)\
+  +defined(SWIGMZSCHEME)\
+  +defined(SWIGOCAML)\
+  +defined(SWIGOCTAVE)\
+  +defined(SWIGPERL)\
+  +defined(SWIGPHP)\
+  +defined(SWIGPYTHON)\
+  +defined(SWIGR)\
+  +defined(SWIGRUBY)\
+  +defined(SWIGSCILAB)\
+  +defined(SWIGTCL)\
+  +defined(SWIGXML)\
+  ) != 1
+# ifdef SWIG
+#  error Did not detect exactly one target-language-specific macro defined at SWIG time.
+# else
+#  error Did not detect exactly one target-language-specific macro defined in the generated wrapper.
+# endif
+#endif
diff --git a/Examples/test-suite/preproc_predefined.i b/Examples/test-suite/preproc_predefined.i
new file mode 100644
index 0000000..75ca75c
--- /dev/null
+++ b/Examples/test-suite/preproc_predefined.i
@@ -0,0 +1,77 @@
+%module preproc_predefined
+
+/* Test that SWIG_VERSION is defined at SWIG-time and in the wrapper. */
+#ifndef SWIG_VERSION
+# error SWIG_VERSION not defined at SWIG-time
+#endif
+%{
+#ifndef SWIG_VERSION
+# error SWIG_VERSION not defined in the generated wrapper
+#endif
+%}
+
+/* Test that SWIG_VERSION has a plausible value - in particular catch if
+ * it isn't defined to a numeric value (which will get replaced by 0).
+ */
+#if SWIG_VERSION < 0x040100
+# error SWIG_VERSION value not plausible at SWIG-time
+#endif
+%{
+#if SWIG_VERSION < 0x040100
+# error SWIG_VERSION value not plausible in the generated wrapper
+#endif
+%}
+
+%define %generate_swig_version_from_preprocessor()%#define SWIG_VERSION_FROM_SWIG_PREPROCESSOR SWIG_VERSION %enddef
+%insert("header") {
+%generate_swig_version_from_preprocessor()
+}
+%insert("header") %{
+#if SWIG_VERSION != SWIG_VERSION_FROM_SWIG_PREPROCESSOR
+# error SWIG_VERSION in SWIG preprocessor does not match SWIG_VERSION from C preprocessor
+#endif
+%}
+
+/* Test that SWIGVERSION is NOT defined at SWIG-time or in the wrapper.
+ * It used to be defined in the wrapper as a side-effect of how SWIG_VERSION
+ * was defined in the wrapper but was never documented and is redundant.
+ */
+#ifdef SWIGVERSION
+# error SWIGVERSION should not be defined at SWIG-time
+#endif
+%{
+#ifdef SWIGVERSION
+# error SWIGVERSION should not be defined in the generated wrapper
+#endif
+%}
+
+/* Test that SWIG is defined at SWIG-time but not in the wrapper. */
+#ifndef SWIG
+# error SWIG not defined at SWIG-time
+#endif
+%{
+#ifdef SWIG
+# error SWIG should not be defined in the generated wrapper
+#endif
+%}
+
+/* Test that __STDC__ is defined by SWIG with value 1 (in SWIG < 4.2.0
+ * it was defined but with an empty value.
+ */
+#ifndef __STDC__
+# error __STDC__ not defined at SWIG-time
+#endif
+#if __STDC__-0 != 1
+# error __STDC__ value not 1 at SWIG-time
+#endif
+
+/* Test that __cplusplus isn't defined (this testcase is processed as C). */
+#ifdef __cplusplus
+# error __cplusplus defined in C mode
+#endif
+
+/* Test that SWIGxxx is defined at SWIG-time and in the wrapper. */
+%include "preproc_predefined.h"
+%{
+#include "preproc_predefined.h"
+%}
diff --git a/Examples/test-suite/preproc_predefined_stdc.i b/Examples/test-suite/preproc_predefined_stdc.i
new file mode 100644
index 0000000..4149611
--- /dev/null
+++ b/Examples/test-suite/preproc_predefined_stdc.i
@@ -0,0 +1,24 @@
+%module preproc_predefined_stdc
+
+// Test handling of -std=c23
+
+// __STDC__ should still have value 1.
+#ifndef __STDC__
+# error __STDC__ not defined at SWIG-time
+#endif
+#if __STDC__-0 != 1
+# error __STDC__ value not 1 at SWIG-time
+#endif
+
+// __cplusplus should not be defined.
+#ifdef __cplusplus
+# error __cplusplus defined at SWIG-time but should not be
+#endif
+
+// __STDC_VERSION__ should be suitably defined.
+#ifndef __STDC_VERSION__
+# error __STDC_VERSION__ not defined at SWIG-time
+#endif
+#if __STDC_VERSION__ != 202311L
+# error __STDC_VERSION__ value not 202311L at SWIG-time
+#endif
diff --git a/Examples/test-suite/preproc_predefined_stdcpp.i b/Examples/test-suite/preproc_predefined_stdcpp.i
new file mode 100644
index 0000000..41aa061
--- /dev/null
+++ b/Examples/test-suite/preproc_predefined_stdcpp.i
@@ -0,0 +1,24 @@
+%module preproc_predefined_stdcpp
+
+// Test handling of -std=c++23
+
+// __STDC__ should still have value 1.
+#ifndef __STDC__
+# error __STDC__ not defined at SWIG-time
+#endif
+#if __STDC__-0 != 1
+# error __STDC__ value not 1 at SWIG-time
+#endif
+
+// __STDC_VERSION__ should not be defined.
+#ifdef __STDC_VERSION__
+# error __STDC_VERSION__ defined at SWIG-time but should not be
+#endif
+
+// __cplusplus should be suitably defined.
+#ifndef __cplusplus
+# error __cplusplus not defined at SWIG-time
+#endif
+#if __cplusplus != 202302L
+# error __cplusplus value not 202302L at SWIG-time
+#endif
diff --git a/Examples/test-suite/private_assign.i b/Examples/test-suite/private_assign.i
index acc4d0b..bcc2143 100644
--- a/Examples/test-suite/private_assign.i
+++ b/Examples/test-suite/private_assign.i
@@ -14,6 +14,8 @@
            return *this;
        }
    public:
+       Foo() { }
+       Foo(const Foo &f) { } // copy ctor can still be public, however.
        void bar() { }
    };
 
@@ -52,20 +54,41 @@
   class A : protected TROOT
   {
   };
-  
 %}
 
-#ifdef SWIGPYTHON
-
-// This case only works in python
 %inline %{
+   Foo foo_global;
+   Foo foo_global_array[1];
+   Foo foo_global_array_2d[2][2];
+
    struct FooBar : Foo 
    {
    };
    
    FooBar bar;
-   
+   FooBar bar_array[1];
+   FooBar bar_array_2d[2][2];
 %}
 
+// https://sourceforge.net/p/swig/bugs/1006/
+%rename(Assign) TwoIsAssignableCopyable::operator=;
+%inline %{
+struct nocopy {
+  nocopy() {}
+private:
+  nocopy(const nocopy&);
+  nocopy& operator=(const nocopy&);
+};
 
-#endif
+struct One: public nocopy {};
+struct TwoNotAssignableCopyable: public One {};
+struct TwoIsAssignableCopyable: public One {
+  TwoIsAssignableCopyable() {}
+  TwoIsAssignableCopyable(const TwoIsAssignableCopyable&) {}
+  TwoIsAssignableCopyable& operator=(const TwoIsAssignableCopyable&) { return *this; }
+};
+struct Three {
+  TwoNotAssignableCopyable TwoNot; // getter only should be generated
+  TwoIsAssignableCopyable TwoIs; // setter and getter should be generated
+};
+%}
diff --git a/Examples/test-suite/python/Makefile.in b/Examples/test-suite/python/Makefile.in
index be06f7e..fca2d3f 100644
--- a/Examples/test-suite/python/Makefile.in
+++ b/Examples/test-suite/python/Makefile.in
@@ -2,7 +2,7 @@
 # Makefile for python test-suite
 #######################################################################
 
-ifeq (,$(PY3))
+ifneq (,$(PY2))
   PYBIN = @PYTHON@
 else
   PYBIN = @PYTHON3@
@@ -10,26 +10,30 @@
 
 LANGUAGE     = python
 PYTHON       = $(PYBIN)
+SCRIPTSUFFIX = _runme.py
 PYCODESTYLE       = @PYCODESTYLE@
-PYCODESTYLE_FLAGS = --ignore=E252,E30,E402,E501,E731,W291,W391
+PYCODESTYLE_FLAGS = --ignore=E252,E30,E402,E501,E731,E741,W291,W391
 
-#*_runme.py for Python 2.x, *_runme3.py for Python 3.x
-PY2SCRIPTSUFFIX = _runme.py
-PY3SCRIPTSUFFIX = _runme3.py
-PY2TO3       = @PY2TO3@ -x import
-
-ifeq (,$(PY3))
-  SCRIPTSUFFIX = $(PY2SCRIPTSUFFIX)
-else
-  SCRIPTSUFFIX = $(PY3SCRIPTSUFFIX)
-endif
-
+HAVE_CXX11   = @HAVE_CXX11@
+HAVE_CXX14   = @HAVE_CXX14@
+HAVE_CXX17   = @HAVE_CXX17@
+HAVE_CXX20   = @HAVE_CXX20@
 srcdir       = @srcdir@
 top_srcdir   = @top_srcdir@
 top_builddir = @top_builddir@
 
+FAILING_CPP_TESTS = \
+	cpp17_map_no_default_ctor \
+
+ifneq (,$(PY2))
+# std_string_view.i is not implemented for Python2 so don't try to run tests needing it.
+FAILING_CPP_TESTS += \
+	cpp17_director_string_view \
+	cpp17_string_view \
+
+endif
+
 CPP_TEST_CASES += \
-	argcargvtest \
 	callback \
 	complextest \
 	director_stl \
@@ -58,12 +62,15 @@
 	li_std_wstring_inherit \
 	primitive_types \
 	python_abstractbase \
+	python_annotations_c \
+	python_annotations_variable_c \
 	python_append \
 	python_builtin \
 	python_destructor_exception \
 	python_director \
 	python_docstring \
 	python_extranative \
+	python_flatstaticmethod \
 	python_moduleimport \
 	python_overload_simple_cast \
 	python_pickle \
@@ -72,79 +79,78 @@
 	python_richcompare \
 	python_strict_unicode \
 	python_threads \
+	python_typemap_macro \
 	simutry \
 	std_containers \
 	swigobject \
 	template_matrix \
 
-#	li_std_carray
 #	director_profile
 
 CPP11_TEST_CASES = \
 	cpp11_hash_tables \
 	cpp11_shared_ptr_const \
+	cpp11_shared_ptr_crtp_upcast \
 	cpp11_shared_ptr_nullptr_in_containers \
 	cpp11_shared_ptr_overload \
+	cpp11_shared_ptr_template_upcast \
 	cpp11_shared_ptr_upcast \
 	cpp11_std_unordered_map \
 	cpp11_std_unordered_multimap \
 	cpp11_std_unordered_multiset \
 	cpp11_std_unordered_set \
 
+CPP17_TEST_CASES = \
+	cpp17_std_filesystem
+
 C_TEST_CASES += \
+	ccomplextest \
 	file_test \
 	li_cstring \
 	li_cwstring \
 	python_nondynamic \
 	python_varargs_typemap \
 
-#
-# This test only works with modern C compilers
-#
-#C_TEST_CASES += \
-#	complextest
+MULTI_CPP_TEST_CASES += \
+	python_runtime_data \
 
 include $(srcdir)/../common.mk
 
 # Overridden variables here
-SCRIPTDIR    = .
 LIBS         = -L.
 VALGRIND_OPT += --suppressions=pythonswig.supp
 
 # Custom tests - tests with additional commandline options
-# none!
+python_flatstaticmethod.cpptest: SWIGOPT += -flatstaticmethod
+
+# Make sure just python_runtime_data_builtin.i uses the -builtin option. Note: does not use python_runtime_data.list for all steps.
+python_runtime_data.multicpptest: override SWIG_FEATURES := $(filter-out -builtin,$(SWIG_FEATURES))
+python_runtime_data.multicpptest: override SWIGOPT := $(filter-out -builtin,$(SWIGOPT))
+python_runtime_data.multicpptest: swig_and_compile_multi_cpp = \
+	$(call swig_and_compile_cpp_helper,python_runtime_data_builtin,'$(SWIGOPT) -builtin') && \
+	$(call swig_and_compile_cpp_helper,python_runtime_data_nobuiltin,'$(SWIGOPT)')
 
 # Rules for the different types of tests
 %.cpptest:
-	+$(convert_testcase)
 	$(setup)
 	+$(swig_and_compile_cpp)
 	$(check_pep8)
 	$(run_testcase)
 
 %.ctest:
-	+$(convert_testcase)
 	$(setup)
 	+$(swig_and_compile_c)
 	$(check_pep8)
 	$(run_testcase)
 
 %.multicpptest:
-	+$(convert_testcase)
 	$(setup)
 	+$(swig_and_compile_multi_cpp)
 	$(check_pep8_multi_cpp)
 	$(run_testcase)
 
 
-
-# Runs the testcase. A testcase is only run if
-# a file is found which has _runme.py (or _runme3.py for Python 3) appended after the testcase name.
-
-py_runme  = $(SCRIPTPREFIX)$*$(SCRIPTSUFFIX)
-py2_runme = $(SCRIPTPREFIX)$*$(PY2SCRIPTSUFFIX)
-py3_runme = $(SCRIPTPREFIX)$*$(PY3SCRIPTSUFFIX)
-
+# Python code style checking
 ifneq (,$(PYCODESTYLE))
 check_pep8 = $(COMPILETOOL) $(PYCODESTYLE) $(PYCODESTYLE_FLAGS) $(SCRIPTPREFIX)$*.py
 
@@ -154,77 +160,24 @@
 	done
 endif
 
-run_python = env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH PYTHONPATH=.:$(srcdir):$$PYTHONPATH $(RUNTOOL) $(PYTHON) $(py_runme)
-
+# Runs the testcase. A testcase is only run if
+# a file is found which has _runme.py appended after the testcase name.
 run_testcase = \
-	if [ -f $(SCRIPTDIR)/$(py_runme) ]; then \
-	  $(run_python);\
+	if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
+	  env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH PYTHONPATH=.:$(srcdir):$$PYTHONPATH $(RUNTOOL) $(PYTHON) $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \
 	fi
 
-# Grab runme file ready for running: copied for out of source tree builds, and/or run 2to3
-# Note terminal (double colon) rules creating runme files to fix possible infinite recursion,
-# see https://github.com/swig/swig/pull/688
-ifeq ($(SCRIPTDIR),$(srcdir))
-  # in source tree build
-  ifeq (,$(PY3))
-    convert_testcase =
-  else
-    convert_testcase = \
-	if [ -f $(srcdir)/$(py2_runme) ]; then \
-	  $(MAKE) $(SCRIPTDIR)/$(py_runme); \
-	fi
-
-# For converting python 2 tests into Python 3 tests
-$(SCRIPTDIR)/$(SCRIPTPREFIX)%$(SCRIPTSUFFIX):: $(srcdir)/$(SCRIPTPREFIX)%$(PY2SCRIPTSUFFIX)
-	cp $< $@
-	$(PY2TO3) -w $@ >/dev/null 2>&1
-
-  endif
-else
-  # out of source tree build
-  ifeq (,$(PY3))
-    convert_testcase = \
-	if [ -f $(srcdir)/$(py2_runme) ]; then \
-	  $(MAKE) $(SCRIPTDIR)/$(py_runme); \
-	fi
-
-$(SCRIPTDIR)/$(SCRIPTPREFIX)%$(SCRIPTSUFFIX):: $(srcdir)/$(SCRIPTPREFIX)%$(PY2SCRIPTSUFFIX)
-	cp $< $@
-
-  else
-    convert_testcase = \
-	if [ -f $(srcdir)/$(py2_runme) ]; then \
-	  $(MAKE) $(SCRIPTDIR)/$(py_runme); \
-	elif [ -f $(srcdir)/$(py3_runme) ]; then \
-	  $(MAKE) $(SCRIPTDIR)/$(py3_runme); \
-	fi
-
-# For when there is a _runme3.py instead of a _runme.py, ie a Python 3 only run test
-$(SCRIPTDIR)/$(SCRIPTPREFIX)%$(SCRIPTSUFFIX):: $(srcdir)/$(SCRIPTPREFIX)%$(PY3SCRIPTSUFFIX)
-	cp $< $@
-
-# For converting python 2 tests into Python 3 tests
-$(SCRIPTDIR)/$(SCRIPTPREFIX)%$(SCRIPTSUFFIX):: $(srcdir)/$(SCRIPTPREFIX)%$(PY2SCRIPTSUFFIX)
-	cp $< $@
-	$(PY2TO3) -w $@ >/dev/null 2>&1
-
-  endif
-
-endif
-
 # Clean: remove the generated .py file
-# We only remove the _runme3.py if it is generated by 2to3 from a _runme.py.
 %.clean:
 	@rm -f $*.py
-	@if test -f $(srcdir)/$(py2_runme); then rm -f $(SCRIPTDIR)/$(py3_runme) $(SCRIPTDIR)/$(py3_runme).bak; fi
-	@if test "x$(SCRIPTDIR)" != "x$(srcdir)"; then rm -f $(SCRIPTDIR)/$(py_runme); fi
 
 clean:
 	$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' python_clean
-	rm -f hugemod.h hugemod_a.i hugemod_b.i hugemod_a.py hugemod_b.py hugemod_runme.py
 	rm -f clientdata_prop_a.py clientdata_prop_b.py import_stl_a.py import_stl_b.py
+	rm -f hugemod.h hugemod_a.i hugemod_b.i hugemod_a.py hugemod_b.py hugemod_runme.py
 	rm -f imports_a.py imports_b.py mod_a.py mod_b.py multi_import_a.py
-	rm -f multi_import_b.py packageoption_a.py packageoption_b.py packageoption_c.py
+	rm -f multi_import_b.py multi_import_d.py packageoption_a.py packageoption_b.py packageoption_c.py
+	rm -f template_typedef_cplx2.py python_runtime_data_builtin.py python_runtime_data_nobuiltin.py
 
 hugemod_runme = hugemod$(SCRIPTPREFIX)
 
diff --git a/Examples/test-suite/python/README b/Examples/test-suite/python/README
index 71db759..402724c 100644
--- a/Examples/test-suite/python/README
+++ b/Examples/test-suite/python/README
@@ -1,8 +1,9 @@
 See ../README for common README file.
 
-Any testcases which have _runme.py (or _runme3.py for Python 3) appended after the testcase name will be detected and run.
+Any testcases which have _runme.py appended after the testcase name will be detected and run.
 
-If you intend to write a testcase for both Python 2.x and 3.x, do *not* directly put the _runme3.py in this directory. Just write Python 2.x's _runme.py testcase and it will be automatically converted to Python 3 code during test.
+The _runme.py files needs to work for both Python 2.x and 3.x.
 
-You can run make with PY3=y to run test case with Python 3.x, eg.
-  $ make voidtest.cpptest PY3=y
+By default testcases are run with Python 3.  You can run make with PY2=1 to run test case with Python 2, eg.
+
+  $ make voidtest.cpptest PY2=1
diff --git a/Examples/test-suite/python/abstract_basecast_runme.py b/Examples/test-suite/python/abstract_basecast_runme.py
new file mode 100644
index 0000000..4a3f4a9
--- /dev/null
+++ b/Examples/test-suite/python/abstract_basecast_runme.py
@@ -0,0 +1,15 @@
+from abstract_basecast import *
+
+def check(flag):
+    if not flag:
+        raise RuntimeError("Test failed")
+
+derived = DerivedClass()
+derived.g()
+check(isinstance(derived, BaseClass))
+check(isinstance(derived, DerivedClass))
+
+base = derived.f()
+base.g()
+check(isinstance(base, BaseClass))
+check(not isinstance(base, DerivedClass))
diff --git a/Examples/test-suite/python/argcargvtest_runme.py b/Examples/test-suite/python/argcargvtest_runme.py
index b034574..52d428b 100644
--- a/Examples/test-suite/python/argcargvtest_runme.py
+++ b/Examples/test-suite/python/argcargvtest_runme.py
@@ -6,12 +6,15 @@
 
 targs = ("hi", "hola")
 if mainv(targs, 1) != "hola":
-    print(mainv(targs, 1))
     raise RuntimeError("bad main typemap")
 
 targs = ("hi", "hola")
+if mainv(targs, 0) != "hi":
+    raise RuntimeError("bad main typemap")
 if mainv(targs, 1) != "hola":
     raise RuntimeError("bad main typemap")
+if mainv(targs, 2) != "<<NULL>>":
+    raise RuntimeError("bad main typemap")
 
 try:
     error = 0
@@ -24,3 +27,28 @@
 
 
 initializeApp(largs)
+
+# Check that an empty array works.
+empty_args = []
+if mainc(empty_args) != 0:
+    raise RuntimeError("bad main typemap")
+if mainv(empty_args, 0) != "<<NULL>>":
+    raise RuntimeError("bad main typemap")
+empty_tuple = ()
+if mainc(empty_tuple) != 0:
+    raise RuntimeError("bad main typemap")
+if mainv(empty_tuple, 0) != "<<NULL>>":
+    raise RuntimeError("bad main typemap")
+
+# Check that empty strings are handled.
+empty_string = ["hello", "", "world"]
+if mainc(empty_string) != 3:
+    raise RuntimeError("bad main typemap")
+if mainv(empty_string, 0) != "hello":
+    raise RuntimeError("bad main typemap")
+if mainv(empty_string, 1) != "":
+    raise RuntimeError("bad main typemap")
+if mainv(empty_string, 2) != "world":
+    raise RuntimeError("bad main typemap")
+if mainv(empty_string, 3) != "<<NULL>>":
+    raise RuntimeError("bad main typemap")
diff --git a/Examples/test-suite/python/array_member_runme.py b/Examples/test-suite/python/array_member_runme.py
index de6e0f3..2708a6f 100644
--- a/Examples/test-suite/python/array_member_runme.py
+++ b/Examples/test-suite/python/array_member_runme.py
@@ -5,7 +5,7 @@
 
 for i in range(0, 8):
     if get_value(f.data, i) != get_value(cvar.global_data, i):
-        raise RuntimeError, "Bad array assignment"
+        raise RuntimeError("Bad array assignment")
 
 
 for i in range(0, 8):
@@ -15,4 +15,4 @@
 
 for i in range(0, 8):
     if get_value(f.data, i) != get_value(cvar.global_data, i):
-        raise RuntimeError, "Bad array assignment"
+        raise RuntimeError("Bad array assignment")
diff --git a/Examples/test-suite/python/autodoc_runme.py b/Examples/test-suite/python/autodoc_runme.py
index 6002d49..18330f7 100644
--- a/Examples/test-suite/python/autodoc_runme.py
+++ b/Examples/test-suite/python/autodoc_runme.py
@@ -63,16 +63,8 @@
 
 check(inspect.getdoc(A.func0static),
       "func0static(e, arg2, hello, f=2) -> int")
-check(inspect.getdoc(_autodoc.A_func0static),
-      "A_func0static(e, arg2, hello, f=2) -> int")
-check(inspect.getdoc(A_func0static),
-      "A_func0static(e, arg2, hello, f=2) -> int")
 check(inspect.getdoc(A.func1static),
       "func1static(A e, short arg2, Tuple hello, double f=2) -> int")
-check(inspect.getdoc(_autodoc.A_func1static),
-      "A_func1static(A e, short arg2, Tuple hello, double f=2) -> int")
-check(inspect.getdoc(A_func1static),
-      "A_func1static(A e, short arg2, Tuple hello, double f=2) -> int")
 check(inspect.getdoc(A.func2static),
       "func2static(e, arg2, hello, f=2) -> int\n"
       "\n"
@@ -82,24 +74,6 @@
       "arg2: short\n"
       "hello: int tuple[2]\n"
       "f: double")
-check(inspect.getdoc(_autodoc.A_func2static),
-      "A_func2static(e, arg2, hello, f=2) -> int\n"
-      "\n"
-      "Parameters\n"
-      "----------\n"
-      "e: A *\n"
-      "arg2: short\n"
-      "hello: int tuple[2]\n"
-      "f: double")
-check(inspect.getdoc(A_func2static),
-      "A_func2static(e, arg2, hello, f=2) -> int\n"
-      "\n"
-      "Parameters\n"
-      "----------\n"
-      "e: A *\n"
-      "arg2: short\n"
-      "hello: int tuple[2]\n"
-      "f: double")
 check(inspect.getdoc(A.func3static),
       "func3static(A e, short arg2, Tuple hello, double f=2) -> int\n"
       "\n"
@@ -109,24 +83,6 @@
       "arg2: short\n"
       "hello: int tuple[2]\n"
       "f: double")
-check(inspect.getdoc(_autodoc.A_func3static),
-      "A_func3static(A e, short arg2, Tuple hello, double f=2) -> int\n"
-      "\n"
-      "Parameters\n"
-      "----------\n"
-      "e: A *\n"
-      "arg2: short\n"
-      "hello: int tuple[2]\n"
-      "f: double")
-check(inspect.getdoc(A_func3static),
-      "A_func3static(A e, short arg2, Tuple hello, double f=2) -> int\n"
-      "\n"
-      "Parameters\n"
-      "----------\n"
-      "e: A *\n"
-      "arg2: short\n"
-      "hello: int tuple[2]\n"
-      "f: double")
 
 check(inspect.getdoc(A.variable_a),
       "variable_a"
@@ -141,7 +97,7 @@
       "variable_d : int"
       )
 
-# Check the low-level functions (not present when using -builtin except for the static ones)
+# Check the low-level functions (not present when using -builtin)
 if not is_python_builtin():
     check(inspect.getdoc(_autodoc.A_funk), "just a string.")
     check(inspect.getdoc(_autodoc.A_func0),
@@ -184,6 +140,28 @@
           "arg3: short\n"
           "hello: int tuple[2]\n"
           "f: double")
+    check(inspect.getdoc(_autodoc.A_func0static),
+          "A_func0static(e, arg2, hello, f=2) -> int")
+    check(inspect.getdoc(_autodoc.A_func1static),
+          "A_func1static(A e, short arg2, Tuple hello, double f=2) -> int")
+    check(inspect.getdoc(_autodoc.A_func2static),
+          "A_func2static(e, arg2, hello, f=2) -> int\n"
+          "\n"
+          "Parameters\n"
+          "----------\n"
+          "e: A *\n"
+          "arg2: short\n"
+          "hello: int tuple[2]\n"
+          "f: double")
+    check(inspect.getdoc(_autodoc.A_func3static),
+          "A_func3static(A e, short arg2, Tuple hello, double f=2) -> int\n"
+          "\n"
+          "Parameters\n"
+          "----------\n"
+          "e: A *\n"
+          "arg2: short\n"
+          "hello: int tuple[2]\n"
+          "f: double")
     check(inspect.getdoc(_autodoc.A_variable_a_set), "A_variable_a_set(self, variable_a)")
     check(inspect.getdoc(_autodoc.A_variable_a_get), "A_variable_a_get(self) -> int" )
     check(inspect.getdoc(_autodoc.A_variable_b_set), "A_variable_b_set(A self, int variable_b)")
@@ -279,3 +257,5 @@
 check(inspect.getdoc(process4), "process4(int _from=0, int _in=1, int var=2) -> int")
 
 check(inspect.getdoc(process_complex_defval), "process_complex_defval(val=PROCESS_DEFAULT_VALUE, factor=some_type(-1)) -> int")
+
+check(inspect.getdoc(a_structure.__init__), "__init__(a_structure self) -> a_structure", None, skip)
diff --git a/Examples/test-suite/python/callback_runme.py b/Examples/test-suite/python/callback_runme.py
index de8a372..93883e0 100644
--- a/Examples/test-suite/python/callback_runme.py
+++ b/Examples/test-suite/python/callback_runme.py
@@ -1,10 +1,13 @@
 import _callback
 from callback import *
 
+# callbacks are implemented by modifying docstrings, useful for debugging:
+# print("A.bar doc: {}".format(A.bar.__doc__))
+
 if foo(2) != 2:
     raise RuntimeError
 
-if A_bar(2) != 4:
+if A.bar(2) != 4:
     raise RuntimeError
 
 if foobar(3, _callback.foo) != foo(3):
@@ -13,11 +16,7 @@
 if foobar(3, foo) != foo(3):
     raise RuntimeError
 
-# Needs some more work for -builtin
-# if foobar(3, A.bar) != A.bar(3):
-#     raise RuntimeError
-
-if foobar(3, A_bar) != A_bar(3):
+if foobar(3, A.bar) != A.bar(3):
     raise RuntimeError
 
 if foobar(3, foof) != foof(3):
diff --git a/Examples/test-suite/python/catches_strings_runme.py b/Examples/test-suite/python/catches_strings_runme.py
new file mode 100644
index 0000000..95b55a2
--- /dev/null
+++ b/Examples/test-suite/python/catches_strings_runme.py
@@ -0,0 +1,21 @@
+from catches_strings import *
+
+exception_thrown = False
+try:
+    StringsThrower.charstring()
+except RuntimeError as e:
+    if "charstring message" not in str(e):
+        raise RuntimeError("incorrect exception message:" + str(e))
+    exception_thrown = True
+if not exception_thrown:
+    raise RuntimeError("Should have thrown an exception")
+
+exception_thrown = False
+try:
+    StringsThrower.stdstring()
+except RuntimeError as e:
+    if "stdstring message" not in str(e):
+        raise RuntimeError("incorrect exception message:" + str(e))
+    exception_thrown = True
+if not exception_thrown:
+    raise RuntimeError("Should have thrown an exception")
diff --git a/Examples/test-suite/python/ccomplextest_runme.py b/Examples/test-suite/python/ccomplextest_runme.py
new file mode 100644
index 0000000..63a663f
--- /dev/null
+++ b/Examples/test-suite/python/ccomplextest_runme.py
@@ -0,0 +1,22 @@
+import ccomplextest
+
+a = complex(-1, 2)
+
+if ccomplextest.has_c99_complex():
+    if ccomplextest.Conj(a) != a.conjugate():
+        raise RuntimeError("bad complex mapping")
+
+    if ccomplextest.Conjf(a) != a.conjugate():
+        raise RuntimeError("bad complex mapping")
+
+    if ccomplextest.Conj2(a) != a.conjugate():
+        raise RuntimeError("bad complex mapping")
+
+    if ccomplextest.Conjf2(a) != a.conjugate():
+        raise RuntimeError("bad complex mapping")
+
+    if ccomplextest.Conj3(a) != a.conjugate():
+        raise RuntimeError("bad complex mapping")
+
+    if ccomplextest.Conjf3(a) != a.conjugate():
+        raise RuntimeError("bad complex mapping")
diff --git a/Examples/test-suite/python/char_binary_runme.py b/Examples/test-suite/python/char_binary_runme.py
index 0425fe1..0f1629f 100644
--- a/Examples/test-suite/python/char_binary_runme.py
+++ b/Examples/test-suite/python/char_binary_runme.py
@@ -2,16 +2,14 @@
 
 t = Test()
 if t.strlen("hile") != 4:
-    print t.strlen("hile")
-    raise RuntimeError, "bad multi-arg typemap"
+    raise RuntimeError("bad multi-arg typemap {}".format(t.strlen("hile")))
 if t.ustrlen("hile") != 4:
-    print t.ustrlen("hile")
-    raise RuntimeError, "bad multi-arg typemap"
+    raise RuntimeError("bad multi-arg typemap {}".format(t.ustrlen("hile")))
 
 if t.strlen("hil\0") != 4:
-    raise RuntimeError, "bad multi-arg typemap"
+    raise RuntimeError("bad multi-arg typemap")
 if t.ustrlen("hil\0") != 4:
-    raise RuntimeError, "bad multi-arg typemap"
+    raise RuntimeError("bad multi-arg typemap")
 
 #
 # creating a raw char*
@@ -25,18 +23,16 @@
 
 
 if t.strlen(pc) != 4:
-    raise RuntimeError, "bad multi-arg typemap"
+    raise RuntimeError("bad multi-arg typemap")
 if t.ustrlen(pc) != 4:
-    raise RuntimeError, "bad multi-arg typemap"
+    raise RuntimeError("bad multi-arg typemap")
 
 cvar.var_pchar = pc
 if cvar.var_pchar != "hola":
-    print cvar.var_pchar
-    raise RuntimeError, "bad pointer case"
+    raise RuntimeError("bad pointer case {}".format(cvar.var_pchar))
 
 cvar.var_namet = pc
-# if cvar.var_namet != "hola\0":
 if cvar.var_namet != "hola":
-    raise RuntimeError, "bad pointer case"
+    raise RuntimeError("bad pointer case")
 
 delete_pchar(pc)
diff --git a/Examples/test-suite/python/complextest_runme.py b/Examples/test-suite/python/complextest_runme.py
index 5cfc7cc..1b9ad66 100644
--- a/Examples/test-suite/python/complextest_runme.py
+++ b/Examples/test-suite/python/complextest_runme.py
@@ -3,17 +3,16 @@
 a = complex(-1, 2)
 
 if complextest.Conj(a) != a.conjugate():
-    raise RuntimeError, "bad complex mapping"
+    raise RuntimeError("bad complex mapping")
 
 if complextest.Conjf(a) != a.conjugate():
-    raise RuntimeError, "bad complex mapping"
+    raise RuntimeError("bad complex mapping")
 
 if complextest.Conj2(a) != a.conjugate():
-    raise RuntimeError, "bad complex mapping"
+    raise RuntimeError("bad complex mapping")
 
 if complextest.Conjf2(a) != a.conjugate():
-    raise RuntimeError, "bad complex mapping"
-
+    raise RuntimeError("bad complex mapping")
 
 v = (complex(1, 2), complex(2, 3), complex(4, 3), 1)
 
@@ -27,4 +26,4 @@
 p.z1 = complex(0, 1)
 p.z2 = complex(0, -1)
 if complextest.Conj(p.z2) != p.z1:
-    raise RuntimeError, "bad complex mapping"
+    raise RuntimeError("bad complex mapping")
diff --git a/Examples/test-suite/python/constover_runme.py b/Examples/test-suite/python/constover_runme.py
index 2d28a55..0c03967 100644
--- a/Examples/test-suite/python/constover_runme.py
+++ b/Examples/test-suite/python/constover_runme.py
@@ -4,33 +4,26 @@
 
 p = constover.test("test")
 if p != "test":
-    print "test failed!"
-    error = 1
+    raise RuntimeError("test failed!")
 
 p = constover.test_pconst("test")
 if p != "test_pconst":
-    print "test_pconst failed!"
-    error = 1
+    raise RuntimeError("test_pconst failed!")
 
 f = constover.Foo()
 p = f.test("test")
 if p != "test":
-    print "member-test failed!"
-    error = 1
+    raise RuntimeError("member-test failed!")
 
 p = f.test_pconst("test")
 if p != "test_pconst":
-    print "member-test_pconst failed!"
-    error = 1
+    raise RuntimeError("member-test_pconst failed!")
 
 p = f.test_constm("test")
 if p != "test_constmethod":
-    print "member-test_constm failed!"
-    error = 1
+    raise RuntimeError("member-test_constm failed!")
 
 p = f.test_pconstm("test")
 if p != "test_pconstmethod":
-    print "member-test_pconstm failed!"
-    error = 1
+    raise RuntimeError("member-test_pconstm failed!")
 
-sys.exit(error)
diff --git a/Examples/test-suite/python/constructor_copy_non_const_runme.py b/Examples/test-suite/python/constructor_copy_non_const_runme.py
new file mode 100644
index 0000000..7a29d89
--- /dev/null
+++ b/Examples/test-suite/python/constructor_copy_non_const_runme.py
@@ -0,0 +1,13 @@
+from constructor_copy_non_const import *
+
+ccb2 = CCBase2(CCBase2())
+ccd = CCDerived(CCDerived())
+ccmd = CCMoreDerived(CCMoreDerived())
+ccmd2 = CCMoreDerived2(CCMoreDerived2())
+ccmmd2 = CCMoreMoreDerived2(CCMoreMoreDerived2())
+
+# no copy ctor CCProtectedBase2
+ccd = CCProtectedDerived(CCProtectedDerived())
+ccmd = CCProtectedMoreDerived(CCProtectedMoreDerived())
+ccmd2 = CCProtectedMoreDerived2(CCProtectedMoreDerived2())
+ccmmd2 = CCProtectedMoreMoreDerived2(CCProtectedMoreMoreDerived2())
diff --git a/Examples/test-suite/python/contract_runme.py b/Examples/test-suite/python/contract_runme.py
index cd75a51..3194b6a 100644
--- a/Examples/test-suite/python/contract_runme.py
+++ b/Examples/test-suite/python/contract_runme.py
@@ -2,141 +2,141 @@
 
 contract.test_preassert(1, 2)
 try:
-    contract.test_preassert(-1)
-    print "Failed! Preassertions are broken"
-except:
+    contract.test_preassert(-1, 3)
+    raise Exception("Failed! Preassertions are broken")
+except RuntimeError:
     pass
 
 contract.test_postassert(3)
 try:
     contract.test_postassert(-3)
-    print "Failed! Postassertions are broken"
-except:
+    raise Exception("Failed! Postassertions are broken")
+except RuntimeError:
     pass
 
 contract.test_prepost(2, 3)
 contract.test_prepost(5, -4)
 try:
     contract.test_prepost(-3, 4)
-    print "Failed! Preassertions are broken"
-except:
+    raise Exception("Failed! Preassertions are broken")
+except RuntimeError:
     pass
 
 try:
     contract.test_prepost(4, -10)
-    print "Failed! Postassertions are broken"
+    raise Exception("Failed! Postassertions are broken")
 
-except:
+except RuntimeError:
     pass
 
 f = contract.Foo()
 f.test_preassert(4, 5)
 try:
     f.test_preassert(-2, 3)
-    print "Failed! Method preassertion."
-except:
+    raise Exception("Failed! Method preassertion.")
+except RuntimeError:
     pass
 
 f.test_postassert(4)
 try:
     f.test_postassert(-4)
-    print "Failed! Method postassertion"
-except:
+    raise Exception("Failed! Method postassertion")
+except RuntimeError:
     pass
 
 f.test_prepost(3, 4)
 f.test_prepost(4, -3)
 try:
     f.test_prepost(-4, 2)
-    print "Failed! Method preassertion."
-except:
+    raise Exception("Failed! Method preassertion.")
+except RuntimeError:
     pass
 
 try:
     f.test_prepost(4, -10)
-    print "Failed! Method postassertion."
-except:
+    raise Exception("Failed! Method postassertion.")
+except RuntimeError:
     pass
 
-contract.Foo_stest_prepost(4, 0)
+contract.Foo.stest_prepost(4, 0)
 try:
-    contract.Foo_stest_prepost(-4, 2)
-    print "Failed! Static method preassertion"
-except:
+    contract.Foo.stest_prepost(-4, 2)
+    raise Exception("Failed! Static method preassertion")
+except RuntimeError:
     pass
 
 try:
-    contract.Foo_stest_prepost(4, -10)
-    print "Failed! Static method posteassertion"
-except:
+    contract.Foo.stest_prepost(4, -10)
+    raise Exception("Failed! Static method posteassertion")
+except RuntimeError:
     pass
 
 b = contract.Bar()
 try:
     b.test_prepost(2, -4)
-    print "Failed! Inherited preassertion."
-except:
+    raise Exception("Failed! Inherited preassertion.")
+except RuntimeError:
     pass
 
 
 d = contract.D()
 try:
     d.foo(-1, 1, 1, 1, 1)
-    print "Failed! Inherited preassertion (D)."
-except:
+    raise Exception("Failed! Inherited preassertion (D).")
+except RuntimeError:
     pass
 try:
     d.foo(1, -1, 1, 1, 1)
-    print "Failed! Inherited preassertion (D)."
-except:
+    raise Exception("Failed! Inherited preassertion (D).")
+except RuntimeError:
     pass
 try:
     d.foo(1, 1, -1, 1, 1)
-    print "Failed! Inherited preassertion (D)."
-except:
+    raise Exception("Failed! Inherited preassertion (D).")
+except RuntimeError:
     pass
 try:
     d.foo(1, 1, 1, -1, 1)
-    print "Failed! Inherited preassertion (D)."
-except:
+    raise Exception("Failed! Inherited preassertion (D).")
+except RuntimeError:
     pass
 try:
     d.foo(1, 1, 1, 1, -1)
-    print "Failed! Inherited preassertion (D)."
-except:
+    raise Exception("Failed! Inherited preassertion (D).")
+except RuntimeError:
     pass
 
 
 try:
     d.bar(-1, 1, 1, 1, 1)
-    print "Failed! Inherited preassertion (D)."
-except:
+    raise Exception("Failed! Inherited preassertion (D).")
+except RuntimeError:
     pass
 try:
     d.bar(1, -1, 1, 1, 1)
-    print "Failed! Inherited preassertion (D)."
-except:
+    raise Exception("Failed! Inherited preassertion (D).")
+except RuntimeError:
     pass
 try:
     d.bar(1, 1, -1, 1, 1)
-    print "Failed! Inherited preassertion (D)."
-except:
+    raise Exception("Failed! Inherited preassertion (D).")
+except RuntimeError:
     pass
 try:
     d.bar(1, 1, 1, -1, 1)
-    print "Failed! Inherited preassertion (D)."
-except:
+    raise Exception("Failed! Inherited preassertion (D).")
+except RuntimeError:
     pass
 try:
     d.bar(1, 1, 1, 1, -1)
-    print "Failed! Inherited preassertion (D)."
-except:
+    raise Exception("Failed! Inherited preassertion (D).")
+except RuntimeError:
     pass
 
 # Namespace
 my = contract.myClass(1)
 try:
     my = contract.myClass(0)
-    print "Failed! constructor preassertion"
-except:
+    raise Exception("Failed! constructor preassertion")
+except RuntimeError:
     pass
diff --git a/Examples/test-suite/python/copyctor_runme.py b/Examples/test-suite/python/copyctor_runme.py
new file mode 100644
index 0000000..3a16fc2
--- /dev/null
+++ b/Examples/test-suite/python/copyctor_runme.py
@@ -0,0 +1,13 @@
+from copyctor import *
+
+bar = Bar()
+bar = Bar(bar)
+
+foo = Foo()
+foo = Foo(bar)
+
+car = Car()
+
+hoo = Hoo()
+hoo = Hoo(bar)
+hoo = Hoo(car)
diff --git a/Examples/test-suite/python/cpp11_alternate_function_syntax_runme.py b/Examples/test-suite/python/cpp11_alternate_function_syntax_runme.py
index cc7b5cd..e46a477 100644
--- a/Examples/test-suite/python/cpp11_alternate_function_syntax_runme.py
+++ b/Examples/test-suite/python/cpp11_alternate_function_syntax_runme.py
@@ -4,20 +4,20 @@
 
 res = a.addNormal(4, 5)
 if res != 9:
-    raise RuntimeError, ("SomeStruct::addNormal(4,5) returns ", res, " should be 9.")
+    raise RuntimeError("SomeStruct::addNormal(4,5) returns ", res, " should be 9.")
 
 res = a.addAlternate(4, 5)
 if res != 9:
-    raise RuntimeError, ("SomeStruct::addAlternate(4,5) returns ", res, " should be 9.")
+    raise RuntimeError("SomeStruct::addAlternate(4,5) returns ", res, " should be 9.")
 
 res = a.addAlternateConst(4, 5)
 if res != 9:
-    raise RuntimeError, ("SomeStruct::addAlternateConst(4,5) returns ", res, " should be 9.")
+    raise RuntimeError("SomeStruct::addAlternateConst(4,5) returns ", res, " should be 9.")
 
 res = a.addAlternateNoExcept(4, 5)
 if res != 9:
-    raise RuntimeError, ("SomeStruct::addAlternateNoExcept(4,5) returns ", res, " should be 9.")
+    raise RuntimeError("SomeStruct::addAlternateNoExcept(4,5) returns ", res, " should be 9.")
 
 res = a.addAlternateConstNoExcept(4, 5)
 if res != 9:
-    raise RuntimeError, ("SomeStruct::addAlternateConstNoExcept(4,5) returns ", res, " should be 9.")
+    raise RuntimeError("SomeStruct::addAlternateConstNoExcept(4,5) returns ", res, " should be 9.")
diff --git a/Examples/test-suite/python/cpp11_decltype_runme.py b/Examples/test-suite/python/cpp11_decltype_runme.py
index 1650d90..b5792d1 100644
--- a/Examples/test-suite/python/cpp11_decltype_runme.py
+++ b/Examples/test-suite/python/cpp11_decltype_runme.py
@@ -3,16 +3,30 @@
 a = cpp11_decltype.A()
 a.i = 5
 if a.i != 5:
-    raise RuntimeError, "Assignment to a.i failed."
+    raise RuntimeError("Assignment to a.i failed.")
 
 a.j = 10
 if a.j != 10:
-    raise RuntimeError, "Assignment to a.j failed."
+    raise RuntimeError("Assignment to a.j failed.")
 
-b = a.foo(5)
-if b != 10:
-    raise RuntimeError, "foo(5) should return 10."
+n = a.get_number(5)
+if n != 10:
+    raise RuntimeError("get_number(5) should return 10.")
 
-b = a.foo(6)
-if b != 0:
-    raise RuntimeError, "foo(6) should return 0."
+n = a.get_number(6)
+if n != 0:
+    raise RuntimeError("get_number(6) should return 0.")
+
+b = cpp11_decltype.B()
+
+if b.a != False:
+    raise RuntimeError("b.a should be False")
+
+if b.b != True:
+    raise RuntimeError("b.b should be True")
+
+if b.negate(True) != False:
+    raise RuntimeError("b.negate(True) should return False")
+
+if b.negate(False) != True:
+    raise RuntimeError("b.negate(False) should return True")
diff --git a/Examples/test-suite/python/cpp11_director_using_constructor_runme.py b/Examples/test-suite/python/cpp11_director_using_constructor_runme.py
new file mode 100644
index 0000000..84238a2
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_director_using_constructor_runme.py
@@ -0,0 +1,145 @@
+from cpp11_director_using_constructor import *
+
+
+# Public base constructors
+a = PublicDerived1(0, "hi").meth()
+a = PublicDerived2().meth()
+a = PublicDerived2(0, "hi").meth()
+a = PublicDerived3().meth()
+a = PublicDerived3(0, "hi").meth()
+a = PublicDerived4().meth()
+a = PublicDerived5().meth()
+
+# Protected base constructors
+# Cannot test most of these as the constructors are protected
+ProtectedDerived5()
+
+# Mix of public and overloaded constructors
+MixedDerived1a(0, "hi").meth()
+MixedDerived1a().meth()
+MixedDerived1b(0, "hi").meth()
+MixedDerived1b().meth()
+
+MixedDerived2a(0, "hi").meth()
+MixedDerived2a().meth()
+MixedDerived2b(0, "hi").meth()
+MixedDerived2b().meth()
+
+MixedDerived2c(0, "hi").meth()
+MixedDerived2c().meth()
+MixedDerived2c(0).meth()
+
+MixedDerived2d(0, "hi").meth()
+MixedDerived2d().meth()
+MixedDerived2d(0).meth()
+
+MixedDerived3a(0, "hi").meth()
+MixedDerived3a().meth()
+MixedDerived3b(0, "hi").meth()
+MixedDerived3b().meth()
+
+MixedDerived3c(0, "hi").meth()
+MixedDerived3c().meth()
+MixedDerived3c(0).meth()
+
+MixedDerived3d(0, "hi").meth()
+MixedDerived3d().meth()
+MixedDerived3d(0).meth()
+
+MixedDerived4a(0, "hi").meth()
+MixedDerived4a().meth()
+MixedDerived4b(0, "hi").meth()
+MixedDerived4b().meth()
+
+MixedDerived4c().meth()
+MixedDerived4c(0).meth()
+
+MixedDerived4d().meth()
+MixedDerived4d(0).meth()
+
+MixedDerived4e().meth()
+
+MixedDerived4f().meth()
+
+# Mix of protected base constructors and overloading
+ProotDerived1a().meth()
+
+ProotDerived1b(0, "hi").meth()
+ProotDerived1b().meth()
+
+ProotDerived1c(0, "hi").meth()
+ProotDerived1c().meth()
+
+ProotDerived1d(0).meth()
+ProotDerived1d().meth()
+
+ProotDerived1e(0).meth()
+ProotDerived1e().meth()
+
+ProotDerived2a(0, "hi").meth()
+
+ProotDerived2b(0, "hi").meth()
+
+ProotDerived2c(0, "hi").meth()
+ProotDerived2c().meth()
+
+ProotDerived2d(0, "hi").meth()
+ProotDerived2d().meth()
+
+ProotDerived2e(0, "hi").meth()
+ProotDerived2e().meth()
+
+ProotDerived2f(0, "hi").meth()
+ProotDerived2f().meth()
+ProotDerived2f(0).meth()
+
+# Deeper inheritance chain
+db3 = DeepBase3(11)
+db3 = DeepBase3(11, 22)
+db3 = DeepBase3(11, 22, 33)
+dbp3 = DeepProtectedBase3(11, 22, 33)
+
+# Missing base
+HiddenDerived1()
+
+# Templates and public base constructors (derive from non-template)
+TemplatePublicDerived1Int(0, "hi").meth()
+TemplatePublicDerived2Int().meth()
+TemplatePublicDerived2Int(0, "hi").meth()
+TemplatePublicDerived3Int().meth()
+TemplatePublicDerived3Int(0, "hi").meth()
+TemplatePublicDerived4Int().meth()
+TemplatePublicDerived5Int().meth()
+
+# Templates and public base constructors (derive from template)
+TemplPublicDerived1Int(0, "hi").meth()
+TemplPublicDerived2Int().meth()
+TemplPublicDerived2Int(0, "hi").meth()
+TemplPublicDerived3Int().meth()
+TemplPublicDerived3Int(0, "hi").meth()
+TemplPublicDerived4Int().meth()
+TemplPublicDerived5Int().meth()
+TemplPublicDerived6Int(0, "hi").meth()
+TemplPublicDerived6Int().meth()
+
+# Templated constructors (public)
+tcb = TemplateConstructor1Base(0, "hi")
+tcb = TemplateConstructor1Base("hi", "hi")
+tcb = TemplateConstructor1Base(11.1, "hi")
+tcb.normal_method()
+tcb.template_method(0, "hi")
+tcb.template_method("hey", "ho")
+
+tcd1 = TemplateConstructor1Derived(0, "hi")
+tcd1 = TemplateConstructor1Derived("hi", "hi")
+tcd1 = TemplateConstructor1Derived(11.1, "hi")
+# Not the best test as these are also in the base class, (should use introspection to check)
+tcd1.normal_method()
+tcd1.template_method(0, "hi")
+tcd1.template_method("hey", "ho")
+
+# Templated constructors (protected)
+tcd2 = TemplateConstructor2Derived()
+tcd2.normal_method()
+tcd2.template_method(0, "hi")
+tcd2.template_method("hey", "ho")
diff --git a/Examples/test-suite/python/cpp11_final_class_runme.py b/Examples/test-suite/python/cpp11_final_class_runme.py
new file mode 100644
index 0000000..54e2890
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_final_class_runme.py
@@ -0,0 +1,65 @@
+from cpp11_final_class import *
+
+fc1 = FinalClass1()
+fc1.method1()
+
+fc2 = FinalClass2()
+fc2.method2()
+
+fc3 = FinalClass3()
+fc3.method3()
+
+fc4 = FinalClass4()
+fc4.method4()
+fc4final = cvar.final
+cvar.final.method4()
+
+fc5 = FinalClass5()
+fc5.method5()
+fc5.final_member_var.finalmethod()
+fc5final = fc5.get_final_member()
+fc5final.finalmethod()
+fc5final = fc5.get_final_member2()
+fc5final.finalmethod()
+
+fc6 = FinalClass6()
+fc6.method6()
+fc6.final()
+
+o = override()
+o.omethod();
+
+y = Y()
+fv4 = FinalVar4()
+yy = fv4.final
+
+fv5 = FinalVar5()
+yy = fv5.final
+
+fv6 = FinalVar6()
+yy = fv6.final
+
+fv7 = FinalVar7()
+yy = fv7.final
+
+fv8 = FinalVar8()
+yy = fv8.final
+
+fv9 = FinalVar9()
+yy = fv9.final
+
+fv10 = FinalVar10()
+fv10.b10(y)
+
+# Removed due to Visual C++ compiler limitations
+# fv11 = FinalVar11()
+# fv11.a11(y)
+#
+# fe1 = FinalEnum1()
+# fe1.enum_in(FinalEnum1.final)
+#
+# fe2 = FinalEnum2()
+# fe2f = fe2.final
+
+s3f = Space3_final()
+s3f.fmethod();
diff --git a/Examples/test-suite/python/cpp11_hash_tables_runme.py b/Examples/test-suite/python/cpp11_hash_tables_runme.py
index 7b772ff..3e7be49 100644
--- a/Examples/test-suite/python/cpp11_hash_tables_runme.py
+++ b/Examples/test-suite/python/cpp11_hash_tables_runme.py
@@ -10,14 +10,14 @@
 		  cpp11_hash_tables.UnorderedMultiMapIntInt({1:7})
          ]:
 
-	swig_assert_equal([(k, v) for k, v in x.iteritems()], [(1, 7)])
-	swig_assert_equal(x.keys(), [1])
-	swig_assert_equal(x.values(), [7])
-	swig_assert_equal(x.items(), [(1, 7)])
+	swig_assert_equal([(k, v) for k, v in x.items()], [(1, 7)])
+	swig_assert_equal(list(x.keys()), [1])
+	swig_assert_equal(list(x.values()), [7])
+	swig_assert_equal(list(x.items()), [(1, 7)])
 	swig_assert_equal([k for k in x], [1])
-	swig_assert_equal([i for i in x.iterkeys()], [1])
-	swig_assert_equal([i for i in x.itervalues()], [7])
-	swig_assert_equal([i for i in x.iteritems()], [(1, 7)])
+	swig_assert_equal([i for i in x.keys()], [1])
+	swig_assert_equal([i for i in x.values()], [7])
+	swig_assert_equal([i for i in x.items()], [(1, 7)])
 
 	swig_assert_equal(x[1], 7)
 	swig_assert_equal(2 in x, False)
@@ -33,7 +33,7 @@
 for x in [cpp11_hash_tables.MultiMapIntInt({1:7}),
 		  cpp11_hash_tables.UnorderedMultiMapIntInt({1:7})]:
 	x[1] = 9
-	swig_assert_equal(sorted([v for k, v in x.iteritems()]), [7, 9])
+	swig_assert_equal(sorted([v for k, v in x.items()]), [7, 9])
 	swig_assert_equal(len(x), 2)
 
 for x in [cpp11_hash_tables.SetInt([1]),
diff --git a/Examples/test-suite/python/cpp11_inheriting_constructors_runme.py b/Examples/test-suite/python/cpp11_inheriting_constructors_runme.py
new file mode 100644
index 0000000..28fb52d
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_inheriting_constructors_runme.py
@@ -0,0 +1,11 @@
+from cpp11_inheriting_constructors import *
+
+# Constructor inheritance via using declaration
+d = DerivedClass(10)
+if d.retrieveValue() != 10:
+    raise RuntimeError("retrieveValue() failed");
+
+# Member initialization at the site of the declaration
+s = SomeClass()
+if s.value != 5:
+    raise RuntimeError("s.value failed");
diff --git a/Examples/test-suite/python/cpp11_move_only_runme.py b/Examples/test-suite/python/cpp11_move_only_runme.py
new file mode 100644
index 0000000..9727f3f
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_move_only_runme.py
@@ -0,0 +1,27 @@
+from cpp11_move_only import *
+
+# Output
+Counter.reset_counts()
+mo = MoveOnly.create()
+del mo
+Counter.check_counts(1, 0, 0, 2, 0, 3)
+
+Counter.reset_counts()
+mo = MovableCopyable.create()
+del mo
+Counter.check_counts(2, 1, 0, 0, 1, 3)
+
+# Move semantics not used
+Counter.reset_counts()
+mo = MovableCopyable.createConst()
+del mo
+Counter.check_counts(2, 1, 1, 0, 0, 3)
+
+# Input
+Counter.reset_counts()
+mo = MovableCopyable(222)
+Counter.check_counts(1, 0, 0, 0, 0, 0)
+MovableCopyable.take(mo)
+Counter.check_counts(2, 0, 1, 1, 0, 2)
+del mo
+Counter.check_counts(2, 0, 1, 1, 0, 3)
diff --git a/Examples/test-suite/python/cpp11_move_typemaps_runme.py b/Examples/test-suite/python/cpp11_move_typemaps_runme.py
new file mode 100644
index 0000000..e4cf06c
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_move_typemaps_runme.py
@@ -0,0 +1,29 @@
+from cpp11_move_typemaps import *
+
+Counter.reset_counts()
+mo = MoveOnly(111)
+Counter.check_counts(1, 0, 0, 0, 0, 0)
+MoveOnly.take(mo)
+Counter.check_counts(1, 0, 0, 1, 0, 2)
+del mo
+Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+Counter.reset_counts()
+mo = MovableCopyable(111)
+Counter.check_counts(1, 0, 0, 0, 0, 0)
+MovableCopyable.take(mo)
+Counter.check_counts(1, 0, 0, 1, 0, 2)
+del mo
+Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+mo = MoveOnly(222)
+MoveOnly.take(mo)
+exception_thrown = False
+try:
+  MoveOnly.take(mo)
+except RuntimeError as e:
+    if "cannot release ownership as memory is not owned" not in str(e):
+        raise RuntimeError("incorrect exception message:" + str(e))
+    exception_thrown = True
+if not exception_thrown:
+    raise RuntimeError("Should have thrown 'Cannot release ownership as memory is not owned' error")
diff --git a/Examples/test-suite/python/cpp11_null_pointer_constant_runme.py b/Examples/test-suite/python/cpp11_null_pointer_constant_runme.py
index 54a8fe0..c397603 100644
--- a/Examples/test-suite/python/cpp11_null_pointer_constant_runme.py
+++ b/Examples/test-suite/python/cpp11_null_pointer_constant_runme.py
@@ -3,15 +3,15 @@
 a = cpp11_null_pointer_constant.A()
 
 if a._myA != None:
-    raise RuntimeError, (
+    raise RuntimeError(
         "cpp11_null_pointer_constant: _myA should be None, but is ", a._myA)
 
 b = cpp11_null_pointer_constant.A()
 if a._myA != b._myA:
-    raise RuntimeError, (
+    raise RuntimeError(
         "cpp11_null_pointer_constant: a._myA should be the same as b._myA, but ", a._myA, "!=", b._myA)
 
 a._myA = cpp11_null_pointer_constant.A()
 if a._myA == None:
-    raise RuntimeError, (
-        "cpp11_null_pointer_constant: _myA should be object, but is None")
+    raise RuntimeError((
+        "cpp11_null_pointer_constant: _myA should be object, but is None"))
diff --git a/Examples/test-suite/python/cpp11_raw_string_literals_runme.py b/Examples/test-suite/python/cpp11_raw_string_literals_runme.py
index 6a587b8..196bd4e 100644
--- a/Examples/test-suite/python/cpp11_raw_string_literals_runme.py
+++ b/Examples/test-suite/python/cpp11_raw_string_literals_runme.py
@@ -34,19 +34,19 @@
     raise RuntimeError
 
 if cvar.bb != "UTF-8 string":
-    raise RuntimeError, cvar.wide
+    raise RuntimeError(cvar.wide)
 
 if cvar.xx != ")I'm an \"ascii\" \\ string.":
-    raise RuntimeError, cvar.xx
+    raise RuntimeError(cvar.xx)
 
 if cvar.ee != ")I'm an \"ascii\" \\ string.":
-    raise RuntimeError, cvar.ee
+    raise RuntimeError(cvar.ee)
 
 if cvar.ff != "I'm a \"raw wide\" \\ string.":
-    raise RuntimeError, cvar.ff
+    raise RuntimeError(cvar.ff)
 
 if cvar.gg != "I'm a \"raw UTF-8\" \\ string.":
-    raise RuntimeError, cvar.gg
+    raise RuntimeError(cvar.gg)
 
 
 def check(got, expected):
@@ -65,11 +65,11 @@
 comment""")
 check(inspect.getdoc(RawStringDoc.YY), """Single line "raw string" documentation comment""")
 check(inspect.getdoc(RawStringDoc.ZZ),
-"""Documentation comment
+r"""Documentation comment
 
 as a "raw string"
 on multiple lines including a \ backslash""")
 
-check(mm, """)I'm an "ascii" \ string constant with multiple
+check(mm, r""")I'm an "ascii" \ string constant with multiple
 
 lines.""")
diff --git a/Examples/test-suite/python/cpp11_result_of_runme.py b/Examples/test-suite/python/cpp11_result_of_runme.py
index 4469efd..691d2a2 100644
--- a/Examples/test-suite/python/cpp11_result_of_runme.py
+++ b/Examples/test-suite/python/cpp11_result_of_runme.py
@@ -2,10 +2,10 @@
 
 result = cpp11_result_of.test_result(cpp11_result_of.SQUARE, 3.0)
 if result != 9.0:
-    raise RuntimeError, "test_result(square, 3.0) is not 9.0. Got: " + str(
-        result)
+    raise RuntimeError("test_result(square, 3.0) is not 9.0. Got: " + str(
+        result))
 
 result = cpp11_result_of.test_result_alternative1(cpp11_result_of.SQUARE, 3.0)
 if result != 9.0:
-    raise RuntimeError, "test_result_alternative1(square, 3.0) is not 9.0. Got: " + str(
-        result)
+    raise RuntimeError("test_result_alternative1(square, 3.0) is not 9.0. Got: " + str(
+        result))
diff --git a/Examples/test-suite/python/cpp11_rvalue_reference_move_runme.py b/Examples/test-suite/python/cpp11_rvalue_reference_move_runme.py
new file mode 100644
index 0000000..43e586f
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_rvalue_reference_move_runme.py
@@ -0,0 +1,69 @@
+from cpp11_rvalue_reference_move import *
+
+# Function containing rvalue reference parameter
+Counter.reset_counts()
+mo = MovableCopyable(222)
+Counter.check_counts(1, 0, 0, 0, 0, 0)
+MovableCopyable.movein(mo)
+Counter.check_counts(1, 0, 0, 1, 0, 2)
+if not MovableCopyable.is_nullptr(mo):
+    raise RuntimeError("is_nullptr check")
+del mo
+Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+# Move constructor test
+Counter.reset_counts()
+mo = MovableCopyable(222)
+Counter.check_counts(1, 0, 0, 0, 0, 0)
+mo_moved = MovableCopyable(mo)
+Counter.check_counts(1, 0, 0, 1, 0, 1)
+if not MovableCopyable.is_nullptr(mo):
+    raise RuntimeError("is_nullptr check")
+del mo
+Counter.check_counts(1, 0, 0, 1, 0, 1)
+del mo_moved
+Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+# Move assignment operator test
+Counter.reset_counts()
+mo111 = MovableCopyable(111)
+mo222 = MovableCopyable(222)
+Counter.check_counts(2, 0, 0, 0, 0, 0)
+mo111.MoveAssign(mo222)
+Counter.check_counts(2, 0, 0, 0, 1, 1)
+if not MovableCopyable.is_nullptr(mo222):
+    raise RuntimeError("is_nullptr check")
+del mo222
+Counter.check_counts(2, 0, 0, 0, 1, 1)
+del mo111
+Counter.check_counts(2, 0, 0, 0, 1, 2)
+
+# null check
+Counter.reset_counts()
+exception_thrown = False
+try:
+    MovableCopyable.movein(None)
+except ValueError as e:
+    if "invalid null reference" not in str(e):
+        raise RuntimeError("incorrect exception message:" + str(e))
+    exception_thrown = True
+if not exception_thrown:
+    raise RuntimeError("Should have thrown null error")
+Counter.check_counts(0, 0, 0, 0, 0, 0)
+
+# output
+Counter.reset_counts()
+mc = MovableCopyable.moveout(1234)
+Counter.check_counts(2, 0, 0, 0, 1, 1)
+MovableCopyable.check_numbers_match(mc, 1234)
+
+exception_thrown = False
+try:
+    MovableCopyable.movein(mc)
+except RuntimeError as e:
+    if "cannot release ownership as memory is not owned" not in str(e):
+        raise RuntimeError("incorrect exception message:" + str(e))
+    exception_thrown = True
+if not exception_thrown:
+    raise RuntimeError("Should have thrown 'Cannot release ownership as memory is not owned' error")
+Counter.check_counts(2, 0, 0, 0, 1, 1)
diff --git a/Examples/test-suite/python/cpp11_rvalue_reference_runme.py b/Examples/test-suite/python/cpp11_rvalue_reference_runme.py
index c1cd3bf..fad8b76 100644
--- a/Examples/test-suite/python/cpp11_rvalue_reference_runme.py
+++ b/Examples/test-suite/python/cpp11_rvalue_reference_runme.py
@@ -4,24 +4,24 @@
 
 a.setAcopy(5)
 if a.getAcopy() != 5:
-    raise RunTimeError, ("int A::getAcopy() value is ",
+    raise RuntimeError("int A::getAcopy() value is ",
                          a.getAcopy(), " should be 5")
 
 ptr = a.getAptr()
 
 a.setAptr(ptr)
 if a.getAcopy() != 5:
-    raise RunTimeError, ("after A::setAptr(): int A::getAcopy() value is ", a.getAcopy(
+    raise RuntimeError("after A::setAptr(): int A::getAcopy() value is ", a.getAcopy(
     ), " should be 5")
 
 a.setAref(ptr)
 if a.getAcopy() != 5:
-    raise RunTimeError, ("after A::setAref(): int A::getAcopy() value is ", a.getAcopy(
+    raise RuntimeError("after A::setAref(): int A::getAcopy() value is ", a.getAcopy(
     ), " should be 5")
 
 rvalueref = a.getAmove()
 
-a.setAmove(rvalueref)
+a.setAref(rvalueref)
 if a.getAcopy() != 5:
-    raise RunTimeError, ("after A::setAmove(): int A::getAcopy() value is ", a.getAcopy(
+    raise RuntimeError("after A::setAmove(): int A::getAcopy() value is ", a.getAcopy(
     ), " should be 5")
diff --git a/Examples/test-suite/python/cpp11_shared_ptr_template_upcast_runme.py b/Examples/test-suite/python/cpp11_shared_ptr_template_upcast_runme.py
new file mode 100644
index 0000000..08a95c2
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_shared_ptr_template_upcast_runme.py
@@ -0,0 +1,5 @@
+from cpp11_shared_ptr_template_upcast import *
+
+pd = MakePrintableDerived(20)
+pd.GetResult()
+pd.GetFormatted()
diff --git a/Examples/test-suite/python/cpp11_shared_ptr_upcast_runme.py b/Examples/test-suite/python/cpp11_shared_ptr_upcast_runme.py
new file mode 100644
index 0000000..08546a4
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_shared_ptr_upcast_runme.py
@@ -0,0 +1,63 @@
+from cpp11_shared_ptr_upcast import *
+
+# This is a port from the Ruby equivalent test and some tests ported from
+# Examples/test-suite/ruby/cpp11_shared_ptr_upcast_runme.rb are not working and commented out with:
+# not working:
+
+def swig_assert_equal_simple(expected, got):
+    if expected != got:
+        raise RuntimeError("Expected: {}. Got: {}")
+
+# non-overloaded
+swig_assert_equal_simple(7, derived_num1(Derived(7)))
+swig_assert_equal_simple(7, derived_num2([Derived(7)]))
+swig_assert_equal_simple(7, derived_num3({0: Derived(7)}))
+
+swig_assert_equal_simple(-1, base_num1(Derived(7)))
+swig_assert_equal_simple(-1, base_num2([Derived(7)]))
+swig_assert_equal_simple(-1, base_num3({0: Derived(7)}))
+
+swig_assert_equal_simple(999, derived_num1(None))
+# not working: swig_assert_equal_simple(999, derived_num2([None]))
+# not working: swig_assert_equal_simple(999, derived_num3({0: None}))
+
+swig_assert_equal_simple(999, base_num1(None))
+# not working: swig_assert_equal_simple(999, base_num2([None]))
+# not working: swig_assert_equal_simple(999, base_num3({0: None}))
+
+# overloaded
+swig_assert_equal_simple(7, derived_num(Derived(7)))
+swig_assert_equal_simple(7, derived_num([Derived(7)]))
+swig_assert_equal_simple(7, derived_num({0: Derived(7)}))
+
+swig_assert_equal_simple(-1, base_num(Derived(7)))
+swig_assert_equal_simple(-1, base_num([Derived(7)]))
+swig_assert_equal_simple(-1, base_num({0: Derived(7)}))
+
+# ptr to shared_ptr
+swig_assert_equal_simple(7, derived2_num1(Derived2(7)))
+swig_assert_equal_simple(7, derived2_num2([Derived2(7)]))
+swig_assert_equal_simple(7, derived2_num3({0: Derived2(7)}))
+
+swig_assert_equal_simple(-1, base2_num1(Derived2(7)))
+
+# not working: try:
+# not working:     # Upcast for pointers to shared_ptr in this generic framework has not been implemented
+# not working:     swig_assert_equal_simple(-1, base2_num2([Derived2(7)]))
+# not working:     raise RuntimeError, "Failed to catch TypeError"
+# not working: except TypeError:
+# not working:     pass
+# not working: try:
+# not working:     # Upcast for pointers to shared_ptr in this generic framework has not been implemented
+# not working:     swig_assert_equal_simple(-1, base2_num3({0: Derived2(7)}))
+# not working:     raise RuntimeError, "Failed to catch TypeError"
+# not working: except TypeError:
+# not working:     pass
+
+swig_assert_equal_simple(888, derived2_num1(None))
+swig_assert_equal_simple(999, derived2_num2([None])) # although 888 would be more consistent
+swig_assert_equal_simple(999, derived2_num3({0: None})) # although 888 would be more consistent
+
+swig_assert_equal_simple(888, base2_num1(None))
+swig_assert_equal_simple(999, base2_num2([None])) # although 888 would be more consistent
+swig_assert_equal_simple(999, base2_num3({0: None})) # although 888 would be more consistent
diff --git a/Examples/test-suite/python/cpp11_std_array_runme.py b/Examples/test-suite/python/cpp11_std_array_runme.py
index e5e7373..dbf9bce 100644
--- a/Examples/test-suite/python/cpp11_std_array_runme.py
+++ b/Examples/test-suite/python/cpp11_std_array_runme.py
@@ -3,7 +3,7 @@
 
 
 def failed(a, b, msg):
-    raise RuntimeError, msg + " " + str(list(a)) + " " + str(list(b))
+    raise RuntimeError(msg + " " + str(list(a)) + " " + str(list(b)))
 
 
 def compare_sequences(a, b):
@@ -26,8 +26,8 @@
             a = swigarray[i::step]
         else:
             a = swigarray[i:j:step]
-        raise RuntimeError, "swigarray[" + str(i) + ":" + str(j) + ":" + str(step) + "] missed steps exception for " + str(list(swigarray))
-    except ValueError, e:
+        raise RuntimeError("swigarray[" + str(i) + ":" + str(j) + ":" + str(step) + "] missed steps exception for " + str(list(swigarray)))
+    except ValueError as e:
 #        print("exception: {}".format(e))
         pass
 
@@ -43,16 +43,24 @@
             del swigarray[i::step]
         else:
             del swigarray[i:j:step]
-        raise RuntimeError, "swigarray[" + str(i) + ":" + str(j) + ":" + str(step) + "] missed del exception for " + str(list(swigarray))
-    except ValueError, e:
+        raise RuntimeError("swigarray[" + str(i) + ":" + str(j) + ":" + str(step) + "] missed del exception for " + str(list(swigarray)))
+    except ValueError as e:
 #        print("exception: {}".format(e))
         pass
 
 def setslice_exception(swigarray, newval):
     try:
         swigarray[::] = newval
-        raise RuntimeError, "swigarray[::] = " + str(newval) + " missed set exception for swigarray:" + str(list(swigarray))
-    except TypeError, e:
+        raise RuntimeError("swigarray[::] = " + str(newval) + " missed set exception for swigarray:" + str(list(swigarray)))
+    except TypeError as e:
+#        print("exception: {}".format(e))
+        pass
+
+def overload_type_exception(pythonlist):
+    try:
+        overloadFunc(pythonlist)
+        raise RuntimeError("overloadFunc({}) missed raising TypeError exception".format(pythonlist))
+    except TypeError as e:
 #        print("exception: {}".format(e))
         pass
 
@@ -161,3 +169,21 @@
 # fill
 ai.fill(111)
 compare_containers(ai, [111, 111, 111, 111, 111, 111])
+
+# Overloading
+newarray = overloadFunc([9, 8, 7, 6, 5, 4])
+compare_containers(newarray, [900, 800, 700, 600, 500, 400])
+
+ai = ArrayInt6([9, 8, 7, 6, 5, 4])
+newarray = overloadFunc([9, 8, 7, 6, 5, 4])
+compare_containers(newarray, [900, 800, 700, 600, 500, 400])
+
+overloadFunc(1, 2)
+overload_type_exception([1, 2, 3, 4, 5, "6"])
+overload_type_exception([1, 2, 3, 4, 5])
+overload_type_exception([1, 2, 3, 4, 5, 6, 7])
+
+# Construct from Python set
+myset = {11, 12, 13, 14, 15, 16}
+ai = ArrayInt6(myset)
+compare_containers(ai, list(myset))
diff --git a/Examples/test-suite/python/cpp11_std_unique_ptr_runme.py b/Examples/test-suite/python/cpp11_std_unique_ptr_runme.py
new file mode 100644
index 0000000..9548fc2
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_std_unique_ptr_runme.py
@@ -0,0 +1,109 @@
+from cpp11_std_unique_ptr import *
+
+def checkCount(expected_count):
+    actual_count = Klass.getTotal_count()
+    if (actual_count != expected_count):
+        raise RuntimeError("Counts incorrect, expected:" + expected_count + " actual:" + actual_count)
+
+# Test raw pointer handling involving virtual inheritance
+kini = KlassInheritance("KlassInheritanceInput")
+checkCount(1)
+s = useKlassRawPtr(kini)
+if s != "KlassInheritanceInput":
+    raise RuntimeError("Incorrect string: " + s)
+del kini
+checkCount(0)
+
+
+# unique_ptr as input
+kin = Klass("KlassInput")
+checkCount(1)
+s = takeKlassUniquePtr(kin)
+checkCount(0)
+if kin.thisown:
+    raise RuntimeError("thisown should be false")
+if s != "KlassInput":
+    raise RuntimeError("Incorrect string: " + s)
+if not is_nullptr(kin):
+    raise RuntimeError("is_nullptr failed")
+del kin # Should not fail, even though already deleted
+checkCount(0)
+
+kin = Klass("KlassInput")
+checkCount(1)
+s = takeKlassUniquePtr(kin)
+checkCount(0)
+if kin.thisown:
+    raise RuntimeError("thisown should be false")
+if s != "KlassInput":
+    raise RuntimeError("Incorrect string: " + s)
+if not is_nullptr(kin):
+    raise RuntimeError("is_nullptr failed")
+exception_thrown = False
+try:
+    s = takeKlassUniquePtr(kin)
+except RuntimeError as e:
+    if "cannot release ownership as memory is not owned" not in str(e):
+        raise RuntimeError("incorrect exception message");
+    exception_thrown = True
+if not exception_thrown:
+    raise RuntimeError("double usage of takeKlassUniquePtr should have been an error")
+del kin # Should not fail, even though already deleted
+checkCount(0)
+
+kin = Klass("KlassInput")
+exception_thrown = False
+notowned = get_not_owned_ptr(kin)
+try:
+    takeKlassUniquePtr(notowned)
+except RuntimeError as e:
+    exception_thrown = True
+if not exception_thrown:
+  raise RuntimeError("Should have thrown 'Cannot release ownership as memory is not owned' error")
+checkCount(1)
+del kin
+checkCount(0)
+
+kini = KlassInheritance("KlassInheritanceInput")
+checkCount(1)
+s = takeKlassUniquePtr(kini)
+checkCount(0)
+if kini.thisown:
+    raise RuntimeError("thisown should be false")
+if s != "KlassInheritanceInput":
+    raise RuntimeError("Incorrect string: " + s)
+if not is_nullptr(kini):
+    raise RuntimeError("is_nullptr failed")
+del kini # Should not fail, even though already deleted
+checkCount(0)
+
+takeKlassUniquePtr(None)
+takeKlassUniquePtr(make_null())
+checkCount(0)
+
+# overloaded parameters
+if overloadTest() != 0:
+  raise RuntimeError("overloadTest failed")
+if overloadTest(None) != 1:
+  raise RuntimeError("overloadTest failed")
+if overloadTest(Klass("over")) != 1:
+  raise RuntimeError("overloadTest failed")
+checkCount(0);
+
+
+# unique_ptr as output
+k1 = makeKlassUniquePtr("first")
+k2 = makeKlassUniquePtr("second")
+checkCount(2)
+
+del k1
+checkCount(1)
+
+if k2.getLabel() != "second":
+    raise "wrong object label"
+
+del k2
+checkCount(0)
+
+if (makeNullUniquePtr() != None):
+  raise RuntimeError("null failure")
diff --git a/Examples/test-suite/python/cpp11_template_explicit_runme.py b/Examples/test-suite/python/cpp11_template_explicit_runme.py
new file mode 100644
index 0000000..dacfb74
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_template_explicit_runme.py
@@ -0,0 +1,15 @@
+import cpp11_template_explicit
+
+def swig_assert_isinstance(a, b):
+	if not isinstance(a, b):
+		raise RuntimeError(str(a) + " not an instance of " + str(b))
+
+# Call variants of the same templated function
+t1 = cpp11_template_explicit.my_templated_function_int      (1,1.0)
+t2 = cpp11_template_explicit.my_templated_function_A        (2,2.0)
+t3 = cpp11_template_explicit.my_templated_function_TemperInt(3,3.0)
+
+# Check return types
+swig_assert_isinstance(t1,int)
+swig_assert_isinstance(t2,cpp11_template_explicit.A)
+swig_assert_isinstance(t3,cpp11_template_explicit.TemperInt)
diff --git a/Examples/test-suite/python/cpp11_uniform_initialization_runme.py b/Examples/test-suite/python/cpp11_uniform_initialization_runme.py
index ecb468c..b01557a 100644
--- a/Examples/test-suite/python/cpp11_uniform_initialization_runme.py
+++ b/Examples/test-suite/python/cpp11_uniform_initialization_runme.py
@@ -9,13 +9,13 @@
 
 m = cpp11_uniform_initialization.MoreInit()
 if m.charptr != None:
-    raise RuntimeError, m.charptr
+    raise RuntimeError(m.charptr)
 m.charptr = "hello sir"
 if m.charptr != "hello sir":
-    raise RuntimeError, m.charptr
+    raise RuntimeError(m.charptr)
 if m.more1(m.vi) != 15:
-    raise RuntimeError, m.vi
+    raise RuntimeError(m.vi)
 if m.more1([-1, 1, 2]) != 2:
-    raise RuntimeError, m.vi
+    raise RuntimeError(m.vi)
 if m.more1() != 10:
     raise RuntimeError
diff --git a/Examples/test-suite/python/cpp11_using_constructor_runme.py b/Examples/test-suite/python/cpp11_using_constructor_runme.py
new file mode 100644
index 0000000..06f8f9a
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_using_constructor_runme.py
@@ -0,0 +1,145 @@
+from cpp11_using_constructor import *
+
+
+# Public base constructors
+a = PublicDerived1(0, "hi").meth()
+a = PublicDerived2().meth()
+a = PublicDerived2(0, "hi").meth()
+a = PublicDerived3().meth()
+a = PublicDerived3(0, "hi").meth()
+a = PublicDerived4().meth()
+a = PublicDerived5().meth()
+
+# Protected base constructors
+# Cannot test most of these as the constructors are protected
+ProtectedDerived5()
+
+# Mix of public and overloaded constructors
+MixedDerived1a(0, "hi").meth()
+MixedDerived1a().meth()
+MixedDerived1b(0, "hi").meth()
+MixedDerived1b().meth()
+
+MixedDerived2a(0, "hi").meth()
+MixedDerived2a().meth()
+MixedDerived2b(0, "hi").meth()
+MixedDerived2b().meth()
+
+MixedDerived2c(0, "hi").meth()
+MixedDerived2c().meth()
+MixedDerived2c(0).meth()
+
+MixedDerived2d(0, "hi").meth()
+MixedDerived2d().meth()
+MixedDerived2d(0).meth()
+
+MixedDerived3a(0, "hi").meth()
+MixedDerived3a().meth()
+MixedDerived3b(0, "hi").meth()
+MixedDerived3b().meth()
+
+MixedDerived3c(0, "hi").meth()
+MixedDerived3c().meth()
+MixedDerived3c(0).meth()
+
+MixedDerived3d(0, "hi").meth()
+MixedDerived3d().meth()
+MixedDerived3d(0).meth()
+
+MixedDerived4a(0, "hi").meth()
+MixedDerived4a().meth()
+MixedDerived4b(0, "hi").meth()
+MixedDerived4b().meth()
+
+MixedDerived4c().meth()
+MixedDerived4c(0).meth()
+
+MixedDerived4d().meth()
+MixedDerived4d(0).meth()
+
+MixedDerived4e().meth()
+
+MixedDerived4f().meth()
+
+# Mix of protected base constructors and overloading
+ProotDerived1a().meth()
+
+ProotDerived1b(0, "hi").meth()
+ProotDerived1b().meth()
+
+ProotDerived1c(0, "hi").meth()
+ProotDerived1c().meth()
+
+ProotDerived1d(0).meth()
+ProotDerived1d().meth()
+
+ProotDerived1e(0).meth()
+ProotDerived1e().meth()
+
+ProotDerived2a(0, "hi").meth()
+
+ProotDerived2b(0, "hi").meth()
+
+ProotDerived2c(0, "hi").meth()
+ProotDerived2c().meth()
+
+ProotDerived2d(0, "hi").meth()
+ProotDerived2d().meth()
+
+ProotDerived2e(0, "hi").meth()
+ProotDerived2e().meth()
+
+ProotDerived2f(0, "hi").meth()
+ProotDerived2f().meth()
+ProotDerived2f(0).meth()
+
+# Deeper inheritance chain
+db3 = DeepBase3(11)
+db3 = DeepBase3(11, 22)
+db3 = DeepBase3(11, 22, 33)
+dbp3 = DeepProtectedBase3(11, 22, 33)
+
+# Missing base
+HiddenDerived1()
+
+# Templates and public base constructors (derive from non-template)
+TemplatePublicDerived1Int(0, "hi").meth()
+TemplatePublicDerived2Int().meth()
+TemplatePublicDerived2Int(0, "hi").meth()
+TemplatePublicDerived3Int().meth()
+TemplatePublicDerived3Int(0, "hi").meth()
+TemplatePublicDerived4Int().meth()
+TemplatePublicDerived5Int().meth()
+
+# Templates and public base constructors (derive from template)
+TemplPublicDerived1Int(0, "hi").meth()
+TemplPublicDerived2Int().meth()
+TemplPublicDerived2Int(0, "hi").meth()
+TemplPublicDerived3Int().meth()
+TemplPublicDerived3Int(0, "hi").meth()
+TemplPublicDerived4Int().meth()
+TemplPublicDerived5Int().meth()
+TemplPublicDerived6Int(0, "hi").meth()
+TemplPublicDerived6Int().meth()
+
+# Templated constructors (public)
+tcb = TemplateConstructor1Base(0, "hi")
+tcb = TemplateConstructor1Base("hi", "hi")
+tcb = TemplateConstructor1Base(11.1, "hi")
+tcb.normal_method()
+tcb.template_method(0, "hi")
+tcb.template_method("hey", "ho")
+
+tcd1 = TemplateConstructor1Derived(0, "hi")
+tcd1 = TemplateConstructor1Derived("hi", "hi")
+tcd1 = TemplateConstructor1Derived(11.1, "hi")
+# Not the best test as these are also in the base class, (should use introspection to check)
+tcd1.normal_method()
+tcd1.template_method(0, "hi")
+tcd1.template_method("hey", "ho")
+
+# Templated constructors (protected)
+tcd2 = TemplateConstructor2Derived()
+tcd2.normal_method()
+tcd2.template_method(0, "hi")
+tcd2.template_method("hey", "ho")
diff --git a/Examples/test-suite/python/cpp11_variadic_function_templates_runme.py b/Examples/test-suite/python/cpp11_variadic_function_templates_runme.py
new file mode 100644
index 0000000..ae1febb
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_variadic_function_templates_runme.py
@@ -0,0 +1,20 @@
+from cpp11_variadic_function_templates import *
+
+ec = EmplaceContainer()
+ec.emplace(A())
+ec.emplace(A(), B())
+ec.emplace(A(), B(), C())
+ec.emplace(A(), B(), C(), D())
+
+def check(expected, got):
+    if expected != got:
+        raise RuntimeError("failed: {} != {}".format(expected, got))
+
+a = A()
+b = B()
+c = C()
+check(variadicmix1(), 20)
+check(variadicmix1(a), 20)
+check(variadicmix1(a, b), 10)
+check(variadicmix1(a, b, c), 20)
+check(variadicmix1(11, 22), 10)
diff --git a/Examples/test-suite/python/cpp11_variadic_templates_runme.py b/Examples/test-suite/python/cpp11_variadic_templates_runme.py
new file mode 100644
index 0000000..ac14743
--- /dev/null
+++ b/Examples/test-suite/python/cpp11_variadic_templates_runme.py
@@ -0,0 +1,158 @@
+from cpp11_variadic_templates import *
+
+ma = MultiArgs1()
+
+# SizeOf testing
+so0 = SizeOf0()
+if so0.size != 0:
+    raise RuntimeError("so0.size")
+so1 = SizeOf1()
+if so1.size != 1:
+    raise RuntimeError("so1.size")
+so2 = SizeOf2()
+if so2.size != 2:
+    raise RuntimeError("so2.size")
+so3 = SizeOf3()
+if so3.size != 3:
+    raise RuntimeError("so3.size")
+
+a = A()
+b = B()
+c = C()
+d = D()
+
+# MultiInherit0
+mi0 = MultiInherit0()
+mi0.MultiInstanceMethod()
+MultiInherit0.MultiStaticMethod()
+mi0.InstanceMethod()
+MultiInherit0.StaticMethod()
+
+# MultiInherit1
+mi1 = MultiInherit1(a)
+if mi1.a != 100:
+    raise RuntimeError("fail mi1.a")
+mi1.MultiInstanceMethod(a)
+MultiInherit1.MultiStaticMethod(a)
+mi1.InstanceMethod()
+MultiInherit1.StaticMethod()
+
+# MultiInherit2
+mi2 = MultiInherit2(a, b)
+if mi2.a != 100:
+    raise RuntimeError("fail mi2.a")
+if mi2.b != 200:
+    raise RuntimeError("fail mi2.b")
+mi2.MultiInstanceMethod(a, b)
+MultiInherit2.MultiStaticMethod(a, b)
+mi2.InstanceMethod()
+MultiInherit2.StaticMethod()
+
+# MultiInherit3
+mi3 = MultiInherit3(a, b, c)
+if mi3.a != 100:
+    raise RuntimeError("fail mi3.a")
+if mi3.b != 200:
+    raise RuntimeError("fail mi3.b")
+if mi3.c != 300:
+    raise RuntimeError("fail mi3.c")
+mi3.MultiInstanceMethod(a, b, c)
+MultiInherit3.MultiStaticMethod(a, b, c)
+mi3.InstanceMethod()
+MultiInherit3.StaticMethod()
+
+# NumerousInherit0
+num = 123
+ni0 = NumerousInherit0(num)
+ni0.NumerousInstanceMethod(num)
+NumerousInherit0.NumerousStaticMethod(num)
+ni0.InstanceMethod()
+NumerousInherit0.StaticMethod()
+
+# NumerousInherit1
+ni1 = NumerousInherit1(num, a)
+if ni1.a != 100:
+    raise RuntimeError("fail ni1.a")
+ni1.NumerousInstanceMethod(num, a)
+NumerousInherit1.NumerousStaticMethod(num, a)
+ni1.InstanceMethod()
+NumerousInherit1.StaticMethod()
+
+# NumerousInherit2
+ni2 = NumerousInherit2(num, a, b)
+if ni2.a != 100:
+    raise RuntimeError("fail ni2.a")
+if ni2.b != 200:
+    raise RuntimeError("fail ni2.b")
+ni2.NumerousInstanceMethod(num, a, b)
+NumerousInherit2.NumerousStaticMethod(num, a, b)
+ni2.InstanceMethod()
+NumerousInherit2.StaticMethod()
+
+# NumerousInherit3
+ni3 = NumerousInherit3(num, a, b, c)
+if ni3.a != 100:
+    raise RuntimeError("fail ni3.a")
+if ni3.b != 200:
+    raise RuntimeError("fail ni3.b")
+if ni3.c != 300:
+    raise RuntimeError("fail ni3.c")
+ni3.NumerousInstanceMethod(num, a, b, c)
+NumerousInherit3.NumerousStaticMethod(num, a, b, c)
+ni3.InstanceMethod()
+NumerousInherit3.StaticMethod()
+
+LotsInherit1
+lots1 = LotsInherit1(a)
+if lots1.a != 100:
+    raise RuntimeError("fail lots1.a")
+lots1.LotsInstanceMethod(a)
+LotsInherit1.LotsStaticMethod(a)
+lots1.InstanceMethod()
+LotsInherit1.StaticMethod()
+
+# LotsInherit2
+lots2 = LotsInherit2(a, b)
+if lots2.a != 100:
+    raise RuntimeError("fail lots2.a")
+if lots2.b != 200:
+    raise RuntimeError("fail lots2.b")
+lots2.LotsInstanceMethod(a, b)
+LotsInherit2.LotsStaticMethod(a, b)
+lots2.InstanceMethod()
+LotsInherit2.StaticMethod()
+
+# LotsInherit3
+lots3 = LotsInherit3(a, b, c)
+if lots3.a != 100:
+    raise RuntimeError("fail lots3.a")
+if lots3.b != 200:
+    raise RuntimeError("fail lots3.b")
+if lots3.c != 300:
+    raise RuntimeError("fail lots3.c")
+lots3.LotsInstanceMethod(a, b, c)
+LotsInherit3.LotsStaticMethod(a, b, c)
+lots3.InstanceMethod()
+LotsInherit3.StaticMethod()
+
+# LotsInherit4
+lots4 = LotsInherit4(a, b, c, d)
+if lots4.a != 100:
+    raise RuntimeError("fail lots4.a")
+if lots4.b != 200:
+    raise RuntimeError("fail lots4.b")
+if lots4.c != 300:
+    raise RuntimeError("fail lots4.c")
+if lots4.d != 400:
+    raise RuntimeError("fail lots4.c")
+lots4.LotsInstanceMethod(a, b, c, d)
+LotsInherit4.LotsStaticMethod(a, b, c, d)
+lots4.InstanceMethod()
+LotsInherit4.StaticMethod()
+
+# PlainStruct
+ps = PlainStruct()
+ps.PlainStructParms0()
+ps.PlainStructParms1(a)
+ps.PlainStructParms2(a, b)
+ps.PlainStructParms3(a, b, c)
diff --git a/Examples/test-suite/python/cpp14_auto_return_type_runme.py b/Examples/test-suite/python/cpp14_auto_return_type_runme.py
new file mode 100644
index 0000000..5efa0e5
--- /dev/null
+++ b/Examples/test-suite/python/cpp14_auto_return_type_runme.py
@@ -0,0 +1,10 @@
+from cpp14_auto_return_type import *
+
+sc = va_static_cast()
+if sc != 42:
+    raise RuntimeError("va_static_cast fail {}".format(sc))
+
+x = X()
+a = x.a()
+if a != "a string":
+    raise RuntimeError("x.a fail {}".format(a))
diff --git a/Examples/test-suite/python/cpp14_binary_integer_literals_runme.py b/Examples/test-suite/python/cpp14_binary_integer_literals_runme.py
index 8274ec6..ee308aa 100644
--- a/Examples/test-suite/python/cpp14_binary_integer_literals_runme.py
+++ b/Examples/test-suite/python/cpp14_binary_integer_literals_runme.py
@@ -14,3 +14,12 @@
 
 if cvar.b5 != 5:
     raise RuntimeError
+
+if b6 != 6:
+    raise RuntimeError
+
+if b7 != 7:
+    raise RuntimeError
+
+if b8 != 8:
+    raise RuntimeError
diff --git a/Examples/test-suite/python/cpp17_director_string_view_runme.py b/Examples/test-suite/python/cpp17_director_string_view_runme.py
new file mode 100644
index 0000000..f9791b3
--- /dev/null
+++ b/Examples/test-suite/python/cpp17_director_string_view_runme.py
@@ -0,0 +1,34 @@
+from cpp17_director_string_view import *
+
+
+class B(A):
+
+    def __init__(self, string):
+        A.__init__(self, string)
+
+    def get_first(self):
+        # Since std::string_view contains a pointer into a string, the string
+        # cannot be a temporary in order to avoid undefined behaviour.
+        self.cached_string = A.get_first(self) + " world!"
+        return self.cached_string
+
+    def process_text(self, string):
+        A.process_text(self, string)
+        self.smem = "hello"
+
+
+b = B("hello")
+
+if b.get(0) != "hello":
+    raise RuntimeError("b.get(0): {}".format(b.get(0)))
+
+if b.get_first() != "hello world!":
+    raise RuntimeError("b.get_first(): {}".format(b.get_first()))
+
+if b.call_get_first() != "hello world!":
+    raise RuntimeError("b.call_get_first(): {}".format(b.call_get_first()))
+
+b.call_process_func()
+
+if b.smem != "hello":
+    raise RuntimeError("smem: {}".format(smem))
diff --git a/Examples/test-suite/python/cpp17_std_filesystem_runme.py b/Examples/test-suite/python/cpp17_std_filesystem_runme.py
new file mode 100644
index 0000000..2192ac1
--- /dev/null
+++ b/Examples/test-suite/python/cpp17_std_filesystem_runme.py
@@ -0,0 +1,64 @@
+import pathlib
+
+from cpp17_std_filesystem import *
+
+
+def check_flag(flag):
+    if not flag:
+        raise RuntimeError("Check failed")
+
+
+def format_msg(p, p2):
+    return "'{p}' != '{p2}', repr(p)={r}, repr(p2)={r2}".format(p=p, p2=p2, r=repr(p), r2=repr(p2))
+
+
+def check(p, p2):
+    assert p == p2, format_msg(p, p2)
+
+
+# Test the output typemap. The wrapped C++ functions
+# makePath is expected to return a std::filesystem::path object
+# (see li_std_filesystem.i). The output typemap should be in place to
+# convert this std::filesystem::path object into a pathlib.Path object.
+path = makePath("foo")
+check_flag(isinstance(path, pathlib.Path))
+check(str(path), "foo")
+
+pathConstRef = makePathConstRef("foo")
+check_flag(isinstance(pathConstRef, pathlib.Path))
+check(str(pathConstRef), "foo")
+
+# Each of these should return a reference to a wrapped
+# std::filesystem::path object.
+pathPtr = makePathPtr("foo")
+check_flag(not isinstance(pathPtr, pathlib.Path))
+
+pathRef = makePathRef("foo")
+check_flag(not isinstance(pathRef, pathlib.Path))
+
+# Now test various input typemaps. Each of the wrapped C++ functions
+# (pathToStr, pathConstRefToStr) is expecting an argument of a
+# different type (see li_std_filesystem.i). Typemaps should be in place to
+# convert this pathlib.Path into the expected argument type.
+check(pathToStr(path), "foo")
+check(pathConstRefToStr(path), "foo")
+
+# Similarly, each of the input typemaps should know what to do with a string.
+check(pathToStr("foo"), "foo")
+check(pathConstRefToStr("foo"), "foo")
+
+# Similarly, each of the input typemaps should know what to do with a std::filesystem::path instance.
+check(pathToStr(pathPtr), "foo")
+check(pathConstRefToStr(pathPtr), "foo")
+
+specialPath = pathlib.Path("/家/屋")
+roundTripped = roundTrip(specialPath)
+roundTrippedSquared = roundTrip(roundTripped)
+lines = []
+if specialPath != roundTripped:
+    lines.append("specialPath, roundTripped: " + format_msg(specialPath, roundTripped))
+if roundTripped != roundTrippedSquared:
+    lines.append("roundTripped, roundTrippedSquared: " + format_msg(roundTripped, roundTrippedSquared))
+if specialPath != roundTrippedSquared:
+    lines.append("specialPath, roundTrippedSquared: " + format_msg(specialPath, roundTrippedSquared))
+assert not lines, "\n".join(lines)
diff --git a/Examples/test-suite/python/cpp17_string_view_runme.py b/Examples/test-suite/python/cpp17_string_view_runme.py
new file mode 100644
index 0000000..0f1be15
--- /dev/null
+++ b/Examples/test-suite/python/cpp17_string_view_runme.py
@@ -0,0 +1,51 @@
+import cpp17_string_view
+
+import sys
+if sys.version_info[0:1] < (3, 0):
+    # string_view.i only supported for Python3
+    sys.exit(0)
+
+# Checking expected use of %typemap(in) std::string_view {}
+cpp17_string_view.test_value("Fee")
+
+# Checking expected result of %typemap(out) std::string_view {}
+if cpp17_string_view.test_value("Fi") != "Fi":
+    raise RuntimeError("Test 1: "+cpp17_string_view.test_value("Fi"))
+
+# Checking expected use of %typemap(in) const std::string_view & {}
+cpp17_string_view.test_const_reference("Fo")
+
+# Checking expected result of %typemap(out) const std.string_view& {}
+if cpp17_string_view.test_const_reference("Fum") != "Fum":
+    raise RuntimeError("Test 3")
+
+# Input and output typemaps for pointers and non-const references to
+# std::string_view are *not* supported; the following tests confirm
+# that none of these cases are slipping through.
+
+stringPtr = cpp17_string_view.test_pointer_out()
+
+cpp17_string_view.test_pointer(stringPtr)
+
+stringPtr = cpp17_string_view.test_const_pointer_out()
+
+cpp17_string_view.test_const_pointer(stringPtr)
+
+stringPtr = cpp17_string_view.test_reference_out()
+
+cpp17_string_view.test_reference(stringPtr)
+
+# Global variables
+s = "initial string"
+if cpp17_string_view.ConstGlobalString != "const global string":
+    raise RuntimeError("ConstGlobalString test")
+
+# Member variables
+myStructure = cpp17_string_view.Structure()
+if myStructure.ConstMemberString != "const member string":
+    raise RuntimeError("ConstMemberString test")
+
+if cpp17_string_view.Structure.ConstStaticMemberString != "const static member string":
+    raise RuntimeError("ConstStaticMemberString test")
+
+cpp17_string_view.test_const_reference_returning_void("foo")
diff --git a/Examples/test-suite/python/cpp20_spaceship_operator_runme.py b/Examples/test-suite/python/cpp20_spaceship_operator_runme.py
new file mode 100644
index 0000000..f13fd48
--- /dev/null
+++ b/Examples/test-suite/python/cpp20_spaceship_operator_runme.py
@@ -0,0 +1,19 @@
+from cpp20_spaceship_operator import *
+
+def check_equal(a, b):
+    if a != b:
+        raise RuntimeError("{} is not equal to {}".format(a, b))
+
+check_equal(ALIEN, 1)
+check_equal(SPACE, 1)
+check_equal(COMET, 1)
+check_equal(cvar.v, 42)
+
+x = A(1)
+y = A(2)
+
+check_equal(spaceship(x, y) < 0, True)
+check_equal(spaceship(x, x), 0)
+check_equal(spaceship(y, x) > 0, True)
+
+check_equal(f(), 42)
diff --git a/Examples/test-suite/python/cpp_enum_runme.py b/Examples/test-suite/python/cpp_enum_runme.py
index 5f1e91c..910d378 100644
--- a/Examples/test-suite/python/cpp_enum_runme.py
+++ b/Examples/test-suite/python/cpp_enum_runme.py
@@ -3,21 +3,17 @@
 f = cpp_enum.Foo()
 
 if f.hola != f.Hello:
-    print f.hola
-    raise RuntimeError
+    raise RuntimeError("f.hola: {}".format(f.hola))
 
 f.hola = f.Hi
 if f.hola != f.Hi:
-    print f.hola
-    raise RuntimeError
+    raise RuntimeError("f.hola: {}".format(f.hola))
 
 f.hola = f.Hello
 
 if f.hola != f.Hello:
-    print f.hola
-    raise RuntimeError
+    raise RuntimeError("f.hola: {}".format(f.hola))
 
 cpp_enum.cvar.hi = cpp_enum.Hello
 if cpp_enum.cvar.hi != cpp_enum.Hello:
-    print cpp_enum.cvar.hi
-    raise RuntimeError
+    raise RuntimeError("cpp_enum.cvar.hi: {}".format(cpp_enum.cvar.hi))
diff --git a/Examples/test-suite/python/cpp_parameters_runme.py b/Examples/test-suite/python/cpp_parameters_runme.py
new file mode 100644
index 0000000..99d14ad
--- /dev/null
+++ b/Examples/test-suite/python/cpp_parameters_runme.py
@@ -0,0 +1,296 @@
+from cpp_parameters import *
+
+# Testing correct and incorrect parameter counts being passed (kwargs and non-kwargs)
+# Note that the implementation depends a lot on whether zero, one, two or more args are being wrapped
+
+def is_python_fastproxy():
+    """Return True if SWIG is generating Python code using -fastproxy."""
+    import cpp_parameters
+    # Note: _swig_new_instance_method is only generated when using -fastproxy
+    return hasattr(cpp_parameters, "_swig_new_instance_method")
+
+# Zero parameters expected
+x = Zero()
+try:
+    x = Zero(z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    x = Zero(0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    x.zero(z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    x.zero(0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    Zero.stat_zero(z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    Zero.stat_zero(0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    global_zero(z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    global_zero(0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+# One mandatory parameter expected
+x = One(1)
+try:
+    x = One(a=1, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    x = One(1, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    x.one(a=1, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    x.one(1, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    One.stat_one(a=1, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    One.stat_one(1, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    global_one(a=1, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    global_one(1, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+# Two mandatory parameters expected
+x = Two(1, 2)
+try:
+    x = Two(a=1, b=2, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    x = Two(1, 2, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    x.two(a=1, b=2, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    x.two(1, 2, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    Two.stat_two(a=1, b=2, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    Two.stat_two(1, 2, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    global_two(a=1, b=2, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    global_two(1, 2, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+# Single optional parameter expected
+x = Single(1)
+try:
+    x = Single(a=1, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    x = Single(1, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    x.single(a=1, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    x.single(1, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    Single.stat_single(a=1, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    Single.stat_single(1, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+try:
+    global_single(a=1, z=0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+try:
+    global_single(1, 0)
+    raise RuntimeError("Missed throw")
+except TypeError:
+    pass
+
+# Test that -builtin option throws TypeError if kwargs are used even when they look like they should work, kwargs are not supported unless using -keyword.
+# Also same for -fastproxy option except that kwargs are supported by default for constructors. TODO: Fix inconsistency.
+
+if is_python_builtin() or is_python_fastproxy():
+    # One mandatory parameter in API
+    x = One(1)
+    if is_python_fastproxy():
+        x = One(a=1)
+    else:
+        try:
+            x = One(a=1)
+            raise RuntimeError("Missed throw")
+        except TypeError:
+            pass
+    try:
+        x.one(a=1)
+        raise RuntimeError("Missed throw")
+    except TypeError:
+        pass
+    try:
+        One.stat_one(a=1)
+        raise RuntimeError("Missed throw")
+    except TypeError:
+        pass
+    try:
+        global_one(a=1)
+        raise RuntimeError("Missed throw")
+    except TypeError:
+        pass
+
+    # Two mandatory parameters in API
+    x = Two(1, 2)
+    if is_python_fastproxy():
+        x = Two(a=1, b=2)
+    else:
+        try:
+            x = Two(a=1, b=2)
+            raise RuntimeError("Missed throw")
+        except TypeError:
+            pass
+    try:
+        x.two(a=1, b=2)
+        raise RuntimeError("Missed throw")
+    except TypeError:
+        pass
+    try:
+        Two.stat_two(a=1, b=2)
+        raise RuntimeError("Missed throw")
+    except TypeError:
+        pass
+    try:
+        global_two(a=1, b=2)
+        raise RuntimeError("Missed throw")
+    except TypeError:
+        pass
+
+    # Single optional parameter in API
+    x = Single(1)
+    if is_python_fastproxy():
+        x = Single(a=1)
+    else:
+        try:
+            x = Single(a=1)
+            raise RuntimeError("Missed throw")
+        except TypeError:
+            pass
+    try:
+        x.single(a=1)
+        raise RuntimeError("Missed throw")
+    except TypeError:
+        pass
+    try:
+        Single.stat_single(a=1)
+        raise RuntimeError("Missed throw")
+    except TypeError:
+        pass
+    try:
+        global_single(a=1)
+        raise RuntimeError("Missed throw")
+    except TypeError:
+        pass
+
+else:
+    # Non-builtin should work as expected
+    # One mandatory parameter in API
+    x = One(a=1)
+    x.one(a=1)
+    One.stat_one(a=1)
+    global_one(a=1)
+
+    # Two mandatory parameters in API
+    x = Two(a=1, b=2)
+    x.two(a=1, b=2)
+    Two.stat_two(a=1, b=2)
+    global_two(a=1, b=2)
+
+    # Single optional parameter in API
+    x = Single(a=1)
+    x.single(a=1)
+    Single.stat_single(a=1)
+    global_single(a=1)
diff --git a/Examples/test-suite/python/default_args_runme.py b/Examples/test-suite/python/default_args_runme.py
index 14ef8c5..b8077cc 100644
--- a/Examples/test-suite/python/default_args_runme.py
+++ b/Examples/test-suite/python/default_args_runme.py
@@ -12,7 +12,7 @@
     de.accelerate()
     de.accelerate(default_args.EnumClass.SLOW)
 
-    if default_args.Statics_staticMethod() != 60:
+    if default_args.Statics.staticMethod() != 60:
         raise RuntimeError
 
     if default_args.cfunc1(1) != 2:
@@ -108,48 +108,34 @@
     if Klass_inc().val != 0:
         raise RuntimeError("Klass::inc failed")
 
-    tricky_failure = False
     tricky = default_args.TrickyInPython()
     if tricky.value_m1(10) != -1:
-        print "trickyvalue_m1 failed"
-        tricky_failure = True
+        raise RuntimeError("trickyvalue_m1 failed")
     if tricky.value_m1(10, 10) != 10:
-        print "trickyvalue_m1 failed"
-        tricky_failure = True
+        raise RuntimeError("trickyvalue_m1 failed")
     if tricky.value_0xabcdef(10) != 0xabcdef:
-        print "trickyvalue_0xabcdef failed"
-        tricky_failure = True
+        raise RuntimeError("trickyvalue_0xabcdef failed")
     if tricky.value_0644(10) != 420:
-        print "trickyvalue_0644 failed"
-        tricky_failure = True
+        raise RuntimeError("trickyvalue_0644 failed")
     if tricky.value_perm(10) != 420:
-        print "trickyvalue_perm failed"
-        tricky_failure = True
+        raise RuntimeError("trickyvalue_perm failed")
     if tricky.value_m01(10) != -1:
-        print "trickyvalue_m01 failed"
-        tricky_failure = True
+        raise RuntimeError("trickyvalue_m01 failed")
     if not tricky.booltest2():
-        print "booltest2 failed"
-        tricky_failure = True
+        raise RuntimeError("booltest2 failed")
 
     if tricky.max_32bit_int1() != 0x7FFFFFFF:
-        print "max_32bit_int1 failed"
-        tricky_failure = True
+        raise RuntimeError("max_32bit_int1 failed")
     if tricky.min_32bit_int1() != -2147483648:
-        print "min_32bit_int1 failed"
-        tricky_failure = True
+        raise RuntimeError("min_32bit_int1 failed")
     if tricky.max_32bit_int2() != 0x7FFFFFFF:
-        print "max_32bit_int2 failed"
-        tricky_failure = True
+        raise RuntimeError("max_32bit_int2 failed")
 
     tricky.too_big_32bit_int1()
     tricky.too_small_32bit_int1()
     tricky.too_big_32bit_int2()
     tricky.too_small_32bit_int2()
 
-    if tricky_failure:
-        raise RuntimeError
-
     default_args.seek()
     default_args.seek(10)
 
diff --git a/Examples/test-suite/python/default_constructor_runme.py b/Examples/test-suite/python/default_constructor_runme.py
index 1e877ad..2943dc9 100644
--- a/Examples/test-suite/python/default_constructor_runme.py
+++ b/Examples/test-suite/python/default_constructor_runme.py
@@ -16,24 +16,24 @@
 
 try:
     b = dc.new_B()
-    print "Whoa. new_BB created."
-except:
+    raise RuntimeError("Whoa. new_BB created.")
+except TypeError:
     pass
 
 del_b = dc.delete_B
 
 try:
     bb = dc.new_BB()
-    print "Whoa. new_BB created."
-except:
+    raise RuntimeError("Whoa. new_BB created.")
+except AttributeError:
     pass
 
 del_bb = dc.delete_BB
 
 try:
     c = dc.new_C()
-    print "Whoa. new_C created."
-except:
+    raise RuntimeError("Whoa. new_C created.")
+except AttributeError:
     pass
 
 del_c = dc.delete_C
@@ -43,24 +43,24 @@
 
 try:
     d = dc.new_D()
-    print "Whoa. new_D created"
-except:
+    raise RuntimeError("Whoa. new_D created")
+except AttributeError:
     pass
 
 del_d = dc.delete_D
 
 try:
     dd = dc.new_DD()
-    print "Whoa. new_DD created"
-except:
+    raise RuntimeError("Whoa. new_DD created")
+except AttributeError:
     pass
 
 dd = dc.delete_DD
 
 try:
     ad = dc.new_AD()
-    print "Whoa. new_AD created"
-except:
+    raise RuntimeError("Whoa. new_AD created")
+except AttributeError:
     pass
 
 del_ad = dc.delete_AD
@@ -73,8 +73,8 @@
 
 try:
     eb = dc.new_EB()
-    print "Whoa. new_EB created"
-except:
+    raise RuntimeError("Whoa. new_EB created")
+except AttributeError:
     pass
 
 del_eb = dc.delete_EB
@@ -83,7 +83,7 @@
 
 try:
     del_f = dc.delete_F
-    print "Whoa. delete_F created"
+    raise RuntimeError("Whoa. delete_F created")
 except AttributeError:
     pass
 
@@ -93,7 +93,7 @@
 
 try:
     del_g = dc.delete_G
-    print "Whoa. delete_G created"
+    raise RuntimeError("Whoa. delete_G created")
 except AttributeError:
     pass
 
diff --git a/Examples/test-suite/python/director_abstract_runme.py b/Examples/test-suite/python/director_abstract_runme.py
index 333b75f..fbc5480 100644
--- a/Examples/test-suite/python/director_abstract_runme.py
+++ b/Examples/test-suite/python/director_abstract_runme.py
@@ -13,10 +13,10 @@
 a = MyFoo()
 
 if a.ping() != "MyFoo::ping()":
-    raise RuntimeError, a.ping()
+    raise RuntimeError(a.ping())
 
 if a.pong() != "Foo::pong();MyFoo::ping()":
-    raise RuntimeError, a.pong()
+    raise RuntimeError(a.pong())
 
 
 class MyExample1(director_abstract.Example1):
@@ -37,7 +37,7 @@
         return b
 
 me1 = MyExample1()
-if director_abstract.Example1_get_color(me1, 1, 2, 3) != 1:
+if director_abstract.Example1.get_color(me1, 1, 2, 3) != 1:
     raise RuntimeError
 
 me2 = MyExample2(1, 2)
diff --git a/Examples/test-suite/python/director_alternating_runme.py b/Examples/test-suite/python/director_alternating_runme.py
index a93ffec..dc85351 100644
--- a/Examples/test-suite/python/director_alternating_runme.py
+++ b/Examples/test-suite/python/director_alternating_runme.py
@@ -2,4 +2,4 @@
 
 id = getBar().id()
 if id != idFromGetBar():
-    raise RuntimeError, "Got wrong id: " + str(id)
+    raise RuntimeError("Got wrong id: " + str(id))
diff --git a/Examples/test-suite/python/director_basic_runme.py b/Examples/test-suite/python/director_basic_runme.py
index 6564c95..2d07c3a 100644
--- a/Examples/test-suite/python/director_basic_runme.py
+++ b/Examples/test-suite/python/director_basic_runme.py
@@ -10,18 +10,18 @@
 a = PyFoo()
 
 if a.ping() != "PyFoo::ping()":
-    raise RuntimeError, a.ping()
+    raise RuntimeError(a.ping())
 
 if a.pong() != "Foo::pong();PyFoo::ping()":
-    raise RuntimeError, a.pong()
+    raise RuntimeError(a.pong())
 
 b = director_basic.Foo()
 
 if b.ping() != "Foo::ping()":
-    raise RuntimeError, b.ping()
+    raise RuntimeError(b.ping())
 
 if b.pong() != "Foo::pong();Foo::ping()":
-    raise RuntimeError, b.pong()
+    raise RuntimeError(b.pong())
 
 a = director_basic.A1(1)
 
@@ -44,8 +44,8 @@
 d = director_basic.MyClass()
 c = PyClass()
 
-cc = director_basic.MyClass_get_self(c)
-dd = director_basic.MyClass_get_self(d)
+cc = director_basic.MyClass.get_self(c)
+dd = director_basic.MyClass.get_self(d)
 
 bc = cc.cmethod(b)
 bd = dd.cmethod(b)
@@ -86,8 +86,8 @@
 pymult = PyMulti()
 
 
-p1 = director_basic.Foo_get_self(pymult)
-p2 = director_basic.MyClass_get_self(pymult)
+p1 = director_basic.Foo.get_self(pymult)
+p2 = director_basic.MyClass.get_self(pymult)
 
 p1.ping()
 p2.vmethod(bc)
diff --git a/Examples/test-suite/python/director_comparison_operators_runme.py b/Examples/test-suite/python/director_comparison_operators_runme.py
new file mode 100644
index 0000000..e9bf943
--- /dev/null
+++ b/Examples/test-suite/python/director_comparison_operators_runme.py
@@ -0,0 +1,11 @@
+import director_comparison_operators
+
+
+class PyFoo(director_comparison_operators.Foo):
+    pass
+
+
+a = PyFoo()
+
+if a.test() != "a=1,b=2":
+    raise RuntimeError(a.test())
diff --git a/Examples/test-suite/python/director_detect_runme.py b/Examples/test-suite/python/director_detect_runme.py
index 3450519..b9c73eb 100644
--- a/Examples/test-suite/python/director_detect_runme.py
+++ b/Examples/test-suite/python/director_detect_runme.py
@@ -35,4 +35,4 @@
 vc = c.get_value()
 
 if (v != 3) or (b.val != 5) or (vc != 6):
-    raise RuntimeError, "Bad virtual detection"
+    raise RuntimeError("Bad virtual detection")
diff --git a/Examples/test-suite/python/director_exception_runme.py b/Examples/test-suite/python/director_exception_runme.py
index 06856f3..458983c 100644
--- a/Examples/test-suite/python/director_exception_runme.py
+++ b/Examples/test-suite/python/director_exception_runme.py
@@ -10,7 +10,7 @@
 class MyFoo(Foo):
 
     def ping(self):
-        raise NotImplementedError, "MyFoo::ping() EXCEPTION"
+        raise NotImplementedError("MyFoo::ping() EXCEPTION")
 
 
 class MyFoo2(Foo):
@@ -28,74 +28,58 @@
 class MyFoo4(Foo):
 
     def ping(self, *args):
-        print(type("bad", "call")) # throws TypeError message: type() takes 1 or 3 arguments
+        t = type("bad", "call") # throws TypeError message: type() takes 1 or 3 arguments
         return "Foo4.ping"
 
 
 # Check that the NotImplementedError raised by MyFoo.ping() is returned by
 # MyFoo.pong().
-ok = 0
 a = MyFoo()
 b = launder(a)
 try:
     b.pong()
-except NotImplementedError, e:
-    if str(e) == "MyFoo::ping() EXCEPTION":
-        ok = 1
-    else:
-        print "Unexpected error message: %s" % str(e)
-except:
+    raise RuntimeError("Exception was not thrown")
+except NotImplementedError as e:
+    if not str(e) == "MyFoo::ping() EXCEPTION":
+        raise RuntimeError("Unexpected error message: %s" % str(e))
+except TypeError:
     pass
-if not ok:
-    raise RuntimeError
 
 
 # Check that the director returns the appropriate TypeError if the return type
 # is wrong.
-ok = 0
 a = MyFoo2()
 b = launder(a)
 try:
     b.pong()
-except TypeError, e:
+    raise RuntimeError("Exception was not thrown")
+except TypeError as e:
     # fastdispatch mode adds on Additional Information to the exception message - just check the main exception message exists
-    if str(e).startswith("SWIG director type mismatch in output value of type 'std::string'"):
-        ok = 1
-    else:
-        print "Unexpected error message: %s" % str(e)
-if not ok:
-    raise RuntimeError
+    if not str(e).startswith("SWIG director type mismatch in output value of type 'std::string'"):
+        raise RuntimeError("Unexpected error message: %s" % str(e))
 
 
 # Check that the director can return an exception which requires two arguments
 # to the constructor, without mangling it.
-ok = 0
 a = MyFoo3()
 b = launder(a)
 try:
     b.pong()
-except MyException, e:
-    if e.msg == "foobar":
-        ok = 1
-    else:
-        print "Unexpected error message: %s" % str(e)
-if not ok:
-    raise RuntimeError
+    raise RuntimeError("Exception was not thrown")
+except MyException as e:
+    if e.msg != "foobar":
+        raise RuntimeError("Unexpected error message: %s" % str(e))
 
 
 # Check that the director returns the appropriate TypeError thrown in a director method
-ok = 0
 a = MyFoo4()
 b = launder(a)
 try:
     b.pong()
+    raise RuntimeError("Exception was not thrown")
 except TypeError as e:
-    if str(e).startswith("type() takes 1 or 3 arguments"):
-        ok = 1
-    else:
-        print "Unexpected error message: %s" % str(e)
-if not ok:
-    raise RuntimeError
+    if not str(e).startswith("type() takes 1 or 3 arguments"):
+        raise RuntimeError("Unexpected error message: %s" % str(e))
 
 
 # This is expected to fail with -builtin option
diff --git a/Examples/test-suite/python/director_extend_runme.py b/Examples/test-suite/python/director_extend_runme.py
index a5aad82..870443d 100644
--- a/Examples/test-suite/python/director_extend_runme.py
+++ b/Examples/test-suite/python/director_extend_runme.py
@@ -17,6 +17,6 @@
 
 m = MyObject()
 if m.dummy() != 666:
-    raise RuntimeError, "1st call"
+    raise RuntimeError("1st call")
 if m.dummy() != 666:                        # Locked system
-    raise RuntimeError, "2nd call"
+    raise RuntimeError("2nd call")
diff --git a/Examples/test-suite/python/director_frob_runme.py b/Examples/test-suite/python/director_frob_runme.py
index 0ef4ad9..6c8fcad 100644
--- a/Examples/test-suite/python/director_frob_runme.py
+++ b/Examples/test-suite/python/director_frob_runme.py
@@ -4,4 +4,4 @@
 s = foo.abs_method()
 
 if s != "Bravo::abs_method()":
-    raise RuntimeError, s
+    raise RuntimeError(s)
diff --git a/Examples/test-suite/python/director_multiple_inheritance_runme.py b/Examples/test-suite/python/director_multiple_inheritance_runme.py
new file mode 100644
index 0000000..8c8ea0b
--- /dev/null
+++ b/Examples/test-suite/python/director_multiple_inheritance_runme.py
@@ -0,0 +1,36 @@
+import director_multiple_inheritance as st
+
+class TestBCD(st.B, st.C, st.D):
+    def __init__(self):
+        st.B.__init__(self)
+        st.C.__init__(self)
+        st.D.__init__(self)
+
+class TestBDC(st.B, st.C, st.D):
+    def __init__(self):
+        st.B.__init__(self)
+        st.D.__init__(self)
+        st.C.__init__(self)
+
+class TestCBD(st.B, st.C, st.D):
+    def __init__(self):
+        st.C.__init__(self)
+        st.B.__init__(self)
+        st.D.__init__(self)
+
+def dotest(test):
+    e = st.E()
+    if e.testE(test) != 5:
+        raise RuntimeError(e.testE(test))
+
+    f = st.F()
+    if f.testF(test) != 6:
+        raise RuntimeError(f.testF(test))
+
+    t = st.T()
+    if t.testT(test) != 20:
+        raise RuntimeError(t.testT(test))
+
+dotest(TestBCD())
+dotest(TestCBD())
+dotest(TestBDC())
diff --git a/Examples/test-suite/python/director_nested_runme.py b/Examples/test-suite/python/director_nested_runme.py
index f3d9736..24216f9 100644
--- a/Examples/test-suite/python/director_nested_runme.py
+++ b/Examples/test-suite/python/director_nested_runme.py
@@ -14,7 +14,7 @@
 
 a = A()
 if a.step() != "Bar::step;Foo::advance;Bar::do_advance;A::do_step;":
-    raise RuntimeError, "Bad A virtual resolution"
+    raise RuntimeError("Bad A virtual resolution")
 
 
 class B(FooBar_int):
@@ -34,7 +34,7 @@
 b = B()
 
 if b.step() != "Bar::step;Foo::advance;B::do_advance;B::do_step;":
-    raise RuntimeError, "Bad B virtual resolution"
+    raise RuntimeError("Bad B virtual resolution")
 
 
 class C(FooBar_int):
@@ -54,7 +54,7 @@
     pass
 
 cc = C()
-c = FooBar_int_get_self(cc)
+c = FooBar_int.get_self(cc)
 c.advance()
 
 if c.get_name() != "FooBar::get_name hello":
diff --git a/Examples/test-suite/python/director_pass_by_value_runme.py b/Examples/test-suite/python/director_pass_by_value_runme.py
index 7744db9..9dbd64a 100644
--- a/Examples/test-suite/python/director_pass_by_value_runme.py
+++ b/Examples/test-suite/python/director_pass_by_value_runme.py
@@ -8,6 +8,8 @@
 
 # bug was the passByVal global object was destroyed after the call to virtualMethod had finished.
 director_pass_by_value.Caller().call_virtualMethod(director_pass_by_value_Derived())
+if director_pass_by_value.has_cplusplus11():
+    director_pass_by_value.Counter.check_counts(1, 0, 0, 1, 0, 1) # check move constructor called and just one destructor
 ret = passByVal.getVal();
 if ret != 0x12345678:
   raise RuntimeError("Bad return value, got " + hex(ret))
diff --git a/Examples/test-suite/python/director_profile_runme.py b/Examples/test-suite/python/director_profile_runme.py
index 035007c..7c269c3 100644
--- a/Examples/test-suite/python/director_profile_runme.py
+++ b/Examples/test-suite/python/director_profile_runme.py
@@ -38,4 +38,4 @@
     a = fi(a)  # 20
     i -= 1
 
-print a
+print("a: {}".format(a))
diff --git a/Examples/test-suite/python/director_property_runme.py b/Examples/test-suite/python/director_property_runme.py
index 5d713c2..2fa4196 100644
--- a/Examples/test-suite/python/director_property_runme.py
+++ b/Examples/test-suite/python/director_property_runme.py
@@ -14,6 +14,43 @@
 if foo.getA() != "BLABLA":
     raise RuntimeError
 
+# test property addition in PyFoo
+if foo.a != "BLABLA":
+    raise RuntimeError
+
 foo.a = "BIBI"
 if foo.a != "BIBI":
     raise RuntimeError
+if foo.getA() != "BIBI":
+    raise RuntimeError
+
+
+
+class MyFoo(director_property.Foo):
+    def setA(self, a):
+        director_property.Foo.setA(self, a + " set from MyFoo")
+    def setAByRef(self, a):
+        director_property.Foo.setA(self, a + " setAByRef from MyFoo")
+
+a = MyFoo()
+if (a.getA() != ""):
+    raise RuntimeError("Test failed")
+a.setA("Hello")
+if (a.getA() != "Hello set from MyFoo"):
+    raise RuntimeError("Test failed")
+a.setAByRef("Hello")
+if (a.getA() != "Hello setAByRef from MyFoo"):
+    raise RuntimeError("Test failed")
+del a
+
+a_original = MyFoo()
+a = director_property.Foo.get_self(a_original)
+if (a.getA() != ""):
+    raise RuntimeError("Test failed")
+a.setA("Hello")
+if (a.getA() != "Hello set from MyFoo"):
+    raise RuntimeError("Test failed")
+a.setAByRef("Hello")
+if (a.getA() != "Hello setAByRef from MyFoo"):
+    raise RuntimeError("Test failed")
+del a
diff --git a/Examples/test-suite/python/director_protected_runme.py b/Examples/test-suite/python/director_protected_runme.py
index c3118a7..94eab69 100644
--- a/Examples/test-suite/python/director_protected_runme.py
+++ b/Examples/test-suite/python/director_protected_runme.py
@@ -35,7 +35,7 @@
         raise RuntimeError
     pass
 except:
-    raise RuntimeError, "bad FooBar::used"
+    raise RuntimeError("bad FooBar::used")
 
 try:
     s = fb2.used()
@@ -43,7 +43,7 @@
         raise RuntimeError
     pass
 except:
-    raise RuntimeError, "bad FooBar2::used"
+    raise RuntimeError("bad FooBar2::used")
 
 try:
     s = b.pong()
@@ -51,7 +51,7 @@
         raise RuntimeError
     pass
 except:
-    raise RuntimeError, "bad Bar::pong"
+    raise RuntimeError("bad Bar::pong")
 
 try:
     s = f.pong()
@@ -59,7 +59,7 @@
         raise RuntimeError
     pass
 except:
-    raise RuntimeError, " bad Foo::pong"
+    raise RuntimeError(" bad Foo::pong")
 
 try:
     s = fb.pong()
@@ -67,7 +67,7 @@
         raise RuntimeError
     pass
 except:
-    raise RuntimeError, " bad FooBar::pong"
+    raise RuntimeError(" bad FooBar::pong")
 
 protected = 1
 try:
@@ -76,7 +76,7 @@
 except:
     pass
 if not protected:
-    raise RuntimeError, "Foo::ping is protected"
+    raise RuntimeError("Foo::ping is protected")
 
 protected = 1
 try:
@@ -85,7 +85,7 @@
 except:
     pass
 if not protected:
-    raise RuntimeError, "Foo::ping is protected"
+    raise RuntimeError("Foo::ping is protected")
 
 
 protected = 1
@@ -95,7 +95,7 @@
 except:
     pass
 if not protected:
-    raise RuntimeError, "FooBar::pang is protected"
+    raise RuntimeError("FooBar::pang is protected")
 
 
 protected = 1
@@ -105,7 +105,7 @@
 except:
     pass
 if not protected:
-    raise RuntimeError, "Bar::cheer is protected"
+    raise RuntimeError("Bar::cheer is protected")
 
 protected = 1
 try:
@@ -114,19 +114,19 @@
 except:
     pass
 if not protected:
-    raise RuntimeError, "Foo::cheer is protected"
+    raise RuntimeError("Foo::cheer is protected")
 
 if fb3.cheer() != "FooBar3::cheer();":
-    raise RuntimeError, "bad fb3::cheer"
+    raise RuntimeError("bad fb3::cheer")
 
 if fb2.callping() != "FooBar2::ping();":
-    raise RuntimeError, "bad fb2.callping"
+    raise RuntimeError("bad fb2.callping")
 
 if fb2.callcheer() != "FooBar2::pang();Bar::pong();Foo::pong();FooBar2::ping();":
-    raise RuntimeError, "bad fb2.callcheer"
+    raise RuntimeError("bad fb2.callcheer")
 
 if fb3.callping() != "Bar::ping();":
-    raise RuntimeError, "bad fb3.callping"
+    raise RuntimeError("bad fb3.callping")
 
 if fb3.callcheer() != "FooBar3::cheer();":
-    raise RuntimeError, "bad fb3.callcheer"
+    raise RuntimeError("bad fb3.callcheer")
diff --git a/Examples/test-suite/python/director_smartptr_runme.py b/Examples/test-suite/python/director_smartptr_runme.py
index 23e22d0..b4cbafe 100644
--- a/Examples/test-suite/python/director_smartptr_runme.py
+++ b/Examples/test-suite/python/director_smartptr_runme.py
@@ -31,7 +31,7 @@
 
 def check(got, expected):
   if (got != expected):
-    raise RuntimeError, "Failed, got: " + got + " expected: " + expected
+    raise RuntimeError("Failed, got: " + got + " expected: " + expected)
 
 fooBar = FooBar()
 
diff --git a/Examples/test-suite/python/director_string_runme.py b/Examples/test-suite/python/director_string_runme.py
index dcd47d6..74d2edb 100644
--- a/Examples/test-suite/python/director_string_runme.py
+++ b/Examples/test-suite/python/director_string_runme.py
@@ -16,14 +16,16 @@
 
 b = B("hello")
 
-b.get(0)
-if b.get_first() != "hello world!":
-    print b.get_first()
-    raise RuntimeError
+if b.get(0) != "hello":
+    raise RuntimeError("b.get(0): {}".format(b.get(0)))
 
+if b.get_first() != "hello world!":
+    raise RuntimeError("b.get_first(): {}".format(b.get_first()))
+
+if b.call_get_first() != "hello world!":
+    raise RuntimeError("b.call_get_first(): {}".format(b.call_get_first()))
 
 b.call_process_func()
 
 if b.smem != "hello":
-    print smem
-    raise RuntimeError
+    raise RuntimeError("smem: {}".format(smem))
diff --git a/Examples/test-suite/python/director_thread_runme.py b/Examples/test-suite/python/director_thread_runme.py
index 4fcf3bf..21a8ce1 100644
--- a/Examples/test-suite/python/director_thread_runme.py
+++ b/Examples/test-suite/python/director_thread_runme.py
@@ -14,7 +14,6 @@
 d.run()
 
 if d.val >= 0:
-    print d.val
-    raise RuntimeError
+    raise RuntimeError("d.val: {}".format(d.val))
 
 d.stop()
diff --git a/Examples/test-suite/python/director_unroll_runme.py b/Examples/test-suite/python/director_unroll_runme.py
index 60bc055..ea602d8 100644
--- a/Examples/test-suite/python/director_unroll_runme.py
+++ b/Examples/test-suite/python/director_unroll_runme.py
@@ -16,5 +16,4 @@
 
 
 if not (a.this == c.this):
-    print a, c
-    raise RuntimeError
+    raise RuntimeError("{} {}".format(a, c))
diff --git a/Examples/test-suite/python/director_wstring_runme.py b/Examples/test-suite/python/director_wstring_runme.py
index 242b275..659cf18 100644
--- a/Examples/test-suite/python/director_wstring_runme.py
+++ b/Examples/test-suite/python/director_wstring_runme.py
@@ -7,22 +7,36 @@
         A.__init__(self, string)
 
     def get_first(self):
-        return A.get_first(self) + u" world!"
+        return A.get_first(self) + " world!"
 
-    def process_text(self, string):
-        self.smem = u"hello"
+    def process_text(self, s):
+        self.smem = s
+
+    def process_wstring_text(self, s):
+        self.smem = s + " (wstring)"
+
+    def process_wstring_ref_text(self, s):
+        self.smem = s + " (wstring ref)"
 
 
-b = B(u"hello")
+b = B("hello")
 
 b.get(0)
-if b.get_first() != u"hello world!":
-    print b.get_first()
-    raise RuntimeError
+if b.get_first() != "hello world!":
+    raise RuntimeError("b.get_first(): {}".format(b.get_first()))
 
 
 b.call_process_func()
 
-if b.smem != u"hello":
-    print smem
-    raise RuntimeError
+if b.smem != "hello":
+    raise RuntimeError("smem: {}".format(smem))
+
+b.call_process_wstring_func()
+
+if b.smem != "hello (wstring)":
+    raise RuntimeError("smem: {}".format(smem))
+
+b.call_process_wstring_ref_func()
+
+if b.smem != "hello (wstring ref)":
+    raise RuntimeError("smem: {}".format(smem))
diff --git a/Examples/test-suite/python/doxygen_autodoc_docstring_runme.py b/Examples/test-suite/python/doxygen_autodoc_docstring_runme.py
new file mode 100644
index 0000000..9780516
--- /dev/null
+++ b/Examples/test-suite/python/doxygen_autodoc_docstring_runme.py
@@ -0,0 +1,44 @@
+from doxygen_autodoc_docstring import *
+import inspect
+import string
+import os
+import sys
+import comment_verifier
+
+# documentation from autogenerated 'feature:autodoc'
+comment_verifier.check(inspect.getdoc(ClassWithoutDoxygenComment),
+    "::ClassWithoutDoxygenComment" if is_python_builtin() else "Proxy of C++ ClassWithoutDoxygenComment class.")
+comment_verifier.check(inspect.getdoc(functionWithoutDoxygenComment),
+    "functionWithoutDoxygenComment(int number)")
+
+# documentation from doxygen comments
+comment_verifier.check(inspect.getdoc(ClassWithDoxygenComment),
+    "Class doxygen comment")
+comment_verifier.check(inspect.getdoc(functionWithDoxygenComment),
+    "Function doxygen comment")
+
+# documentation from 'feature:docstring'
+comment_verifier.check(inspect.getdoc(ClassWithDocString),
+    "Class doc from docstring")
+comment_verifier.check(inspect.getdoc(functionWithDocString),
+    "functionWithDocString(int number)\n"
+    "Function doc from docstring")
+
+# documentation from 'feature:docstring' + autodoc (overriding doxycomment)
+comment_verifier.check(inspect.getdoc(ClassWithDocStringAndDoxygenComment),
+    "Class doc from docstring overriding doxycomment")
+comment_verifier.check(inspect.getdoc(functionWithDocStringAndDoxygenComment),
+    "functionWithDocStringAndDoxygenComment(int number)\n"
+    "Function doc from docstring overriding doxycomment")
+
+# documentation from 'feature:docstring' (overriding doxycomment)
+comment_verifier.check(inspect.getdoc(ClassWithDocStringAndDoxygenCommentNoAutodoc),
+    "Class doc from docstring overriding doxycomment (no autodoc)")
+comment_verifier.check(inspect.getdoc(functionWithDocStringAndDoxygenCommentNoAutodoc),
+    "Function doc from docstring overriding doxycomment (no autodoc)")
+
+# documentation from doxygen comments (2) no autodoc feature present
+comment_verifier.check(inspect.getdoc(ClassWithDoxygenComment2),
+    "Class doxygen comment 2")
+comment_verifier.check(inspect.getdoc(functionWithDoxygenComment2),
+    "Function doxygen comment 2")
diff --git a/Examples/test-suite/python/doxygen_basic_translate_runme.py b/Examples/test-suite/python/doxygen_basic_translate_runme.py
index 9ef8dbd..4cd5001 100644
--- a/Examples/test-suite/python/doxygen_basic_translate_runme.py
+++ b/Examples/test-suite/python/doxygen_basic_translate_runme.py
@@ -60,7 +60,7 @@
 comment_verifier.check(inspect.getdoc(doxygen_basic_translate.function6),
     """\
 Test for default args
-:type a: int
+:type a: int, optional
 :param a: Some parameter, default is 42"""
 )
 comment_verifier.check(inspect.getdoc(doxygen_basic_translate.function7),
@@ -70,6 +70,16 @@
 :type a: :py:class:`Shape`
 :param a: Very strange param"""
 )
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate.function8),
+    """\
+Test variadic function
+:param ...: extra args"""
+)
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate.function9),
+    """\
+Test unnamed argument
+:param baz: Description of baz"""
+)
 
 comment_verifier.check(inspect.getdoc(doxygen_basic_translate.Atan2),
     """\
diff --git a/Examples/test-suite/python/doxygen_basic_translate_style2_runme.py b/Examples/test-suite/python/doxygen_basic_translate_style2_runme.py
index b75045d..a24f5de 100644
--- a/Examples/test-suite/python/doxygen_basic_translate_style2_runme.py
+++ b/Examples/test-suite/python/doxygen_basic_translate_style2_runme.py
@@ -58,7 +58,7 @@
 comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style2.function6),
     """\
 Test for default args
-:type a: int
+:type a: int, optional
 :param a: Some parameter, default is 42"""
 )
 comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style2.function7),
diff --git a/Examples/test-suite/python/doxygen_basic_translate_style3_runme.py b/Examples/test-suite/python/doxygen_basic_translate_style3_runme.py
new file mode 100644
index 0000000..6872703
--- /dev/null
+++ b/Examples/test-suite/python/doxygen_basic_translate_style3_runme.py
@@ -0,0 +1,82 @@
+import doxygen_basic_translate_style3
+import inspect
+import string
+import sys
+import comment_verifier
+
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style3.function),
+    """\
+Brief description.
+
+The comment text.
+
+Author: Some author
+
+:rtype: int
+:return: Some number
+
+See also: function2"""
+)
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style3.function2),
+    """\
+A test of a very very very very very very very very very very very very very very very very
+very very very very very long comment string."""
+)
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style3.function3),
+    """*Overload 1:*
+A test for overloaded functions
+This is function **one**
+
+|
+
+*Overload 2:*
+A test for overloaded functions
+This is function **two**"""
+)
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style3.function4),
+    """\
+A test of some mixed tag usage
+If: CONDITION {
+This *code* fragment shows us something .
+Title: Minuses:
+* it\'s senseless
+* it\'s stupid
+* it\'s null
+
+Warning: This may not work as expected
+
+.. code-block:: c++
+
+    int main() { while(true); }
+
+    int testBlankLine() {}
+}"""
+)
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style3.function5),
+    """This is a post comment."""
+)
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style3.function6),
+    """\
+Test for default args
+:type a: int, optional
+:param a: Some parameter, default is 42"""
+)
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style3.function7),
+    """\
+Test for a parameter with difficult type
+(mostly for python)
+:type a: :py:class:`Shape`
+:param a: Very strange param"""
+)
+
+comment_verifier.check(inspect.getdoc(doxygen_basic_translate_style3.Atan2),
+    """\
+Multiple parameters test.
+
+:type y: float
+:param y: Vertical coordinate.
+:type x: float
+:param x: Horizontal coordinate.
+:rtype: float
+:return: Arc tangent of ``y/x``."""
+)
diff --git a/Examples/test-suite/python/doxygen_code_blocks_runme.py b/Examples/test-suite/python/doxygen_code_blocks_runme.py
new file mode 100644
index 0000000..46a0a3d
--- /dev/null
+++ b/Examples/test-suite/python/doxygen_code_blocks_runme.py
@@ -0,0 +1,58 @@
+import doxygen_code_blocks
+import inspect
+import string
+import sys
+import comment_verifier
+
+comment_verifier.check(inspect.getdoc(doxygen_code_blocks.function),
+    """\
+Test for code blocks
+
+.. code-block:: c++
+
+    simple code block
+
+More advanced usage with C++ characters:
+
+.. code-block:: c++
+
+    std::vector<int> first;                                // empty vector of ints
+    std::vector<int> second (4,100);                       // four ints with value 100
+    std::vector<int> third (second.begin(),second.end());  // iterating through second
+    std::vector<int> fourth (third);                       // a copy of third
+     // the iterator constructor can also be used to construct from arrays:
+    int myints[] = {16,2,77,29};
+    std::vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );
+
+    std::cout << "The contents of fifth are:";
+    for (std::vector<int>::iterator it = fifth.begin(); it != fifth.end(); ++it)
+      std::cout << ' ' << *it;
+    std::cout << '\\n';
+
+A code block for C:
+
+.. code-block:: c
+
+    printf("hello world");
+
+A code block for Java:
+
+.. code-block:: java
+
+    public class HelloWorld {
+        public static void main(String[] args) {
+            // Prints "Hello, World" to the terminal window.
+            System.out.println("Hello, World");
+        }
+    }
+
+A code block for python:
+
+.. code-block:: python
+
+    print('hello world')
+
+A python doctest example:
+
+>>> 1 + 1
+2""")
diff --git a/Examples/test-suite/python/doxygen_misc_constructs_runme.py b/Examples/test-suite/python/doxygen_misc_constructs_runme.py
index 11aa53b..44f607f 100644
--- a/Examples/test-suite/python/doxygen_misc_constructs_runme.py
+++ b/Examples/test-suite/python/doxygen_misc_constructs_runme.py
@@ -12,7 +12,7 @@
 :param fileName: name of the file, where the source line is located
 :type line: int
 :param line: line number
-:type isGetSize: boolean
+:type isGetSize: boolean, optional
 :param isGetSize: if set, for every object location both address and size are returned
 
 Connection::getId() """)
@@ -131,3 +131,13 @@
 :type fileName: string
 :param fileName: name of the log file"""
 );
+
+comment_verifier.check(inspect.getdoc(doxygen_misc_constructs.doc_ends_with_quote),
+    r'''This doc comment ends with a quote: "and that's ok"'''
+);
+
+comment_verifier.check(inspect.getdoc(doxygen_misc_constructs.doc_with_triple_quotes),
+    r'''This comment contains embedded triple-quoted string:
+
+    """How quaint"""'''
+);
diff --git a/Examples/test-suite/python/doxygen_translate_all_tags_runme.py b/Examples/test-suite/python/doxygen_translate_all_tags_runme.py
index df1c0eb..e884cf9 100644
--- a/Examples/test-suite/python/doxygen_translate_all_tags_runme.py
+++ b/Examples/test-suite/python/doxygen_translate_all_tags_runme.py
@@ -82,7 +82,7 @@
 
 *italicword*
 
-emphazedWord
+*emphazedWord*
 
 
 
@@ -175,7 +175,7 @@
 
 
 
-someMember Some description follows
+someMember Some description follows with text after
 
 
 
@@ -196,7 +196,7 @@
 This is an overloaded member function, provided for convenience.
 It differs from the above function only in what argument(s) it accepts.
 
-someword
+``someword``
 
 
 
@@ -209,7 +209,13 @@
 
 
 :type a: int
-:param a: the first param""")
+:param a: the first param
+:type b: int, in
+:param b: parameter with intent(in)
+:type c: int, out
+:param c: parameter with intent(out)
+:type d: int, in/out
+:param d: parameter with intent(in,out)""")
 
 comment_verifier.check(inspect.getdoc(doxygen_translate_all_tags.func08),
 r"""Text after anchor.
diff --git a/Examples/test-suite/python/doxygen_translate_runme.py b/Examples/test-suite/python/doxygen_translate_runme.py
index d698ba8..a62df4a 100644
--- a/Examples/test-suite/python/doxygen_translate_runme.py
+++ b/Examples/test-suite/python/doxygen_translate_runme.py
@@ -58,6 +58,7 @@
 }
 
 Image: testImage.bmp("Hello, world!")
+Image: "test image.jpg"("Test jpeg")
 
 
 
@@ -80,7 +81,7 @@
 This is an overloaded member function, provided for convenience.
 It differs from the above function only in what argument(s) it accepts.
 
-someword
+``someword``
 
 
 
diff --git a/Examples/test-suite/python/dynamic_cast_runme.py b/Examples/test-suite/python/dynamic_cast_runme.py
index 59e86d3..ae08083 100644
--- a/Examples/test-suite/python/dynamic_cast_runme.py
+++ b/Examples/test-suite/python/dynamic_cast_runme.py
@@ -8,4 +8,4 @@
 
 a = dynamic_cast.do_test(y)
 if a != "Bar::test":
-    print "Failed!!"
+    raise RuntimeError("Failed!!")
diff --git a/Examples/test-suite/python/exception_order_runme.py b/Examples/test-suite/python/exception_order_runme.py
index c53521e..5c15299 100644
--- a/Examples/test-suite/python/exception_order_runme.py
+++ b/Examples/test-suite/python/exception_order_runme.py
@@ -9,36 +9,35 @@
 
 try:
     a.foo()
-except E1, e:
+except E1 as e:
     pass
 except:
-    raise RuntimeError, "bad exception order"
+    raise RuntimeError("bad exception order")
 
 try:
     a.bar()
-except E2, e:
+except E2 as e:
     pass
 except:
-    raise RuntimeError, "bad exception order"
+    raise RuntimeError("bad exception order")
 
 try:
     a.foobar()
-except RuntimeError, e:
+except RuntimeError as e:
     if e.args[0] != "postcatch unknown":
-        print "bad exception order",
-        raise RuntimeError, e.args
+        raise RuntimeError("bad exception order {}".format(e.args))
 
 
 try:
     a.barfoo(1)
-except E1, e:
+except E1 as e:
     pass
 except:
-    raise RuntimeError, "bad exception order"
+    raise RuntimeError("bad exception order")
 
 try:
     a.barfoo(2)
-except E2, e:
+except E2 as e:
     pass
 except:
-    raise RuntimeError, "bad exception order"
+    raise RuntimeError("bad exception order")
diff --git a/Examples/test-suite/python/extern_c_runme.py b/Examples/test-suite/python/extern_c_runme.py
index 91a218a..c30509d 100644
--- a/Examples/test-suite/python/extern_c_runme.py
+++ b/Examples/test-suite/python/extern_c_runme.py
@@ -1,3 +1,10 @@
 import extern_c
 
+def check(flag):
+    if not flag:
+        raise RuntimeError("Test failed")
+
 extern_c.RealFunction(2)
+check(extern_c.cvar.int2 == 123)
+check(extern_c.cvar.int3 == 456)
+check(extern_c.cvar.int4 == 789)
diff --git a/Examples/test-suite/python/final_c_runme.py b/Examples/test-suite/python/final_c_runme.py
new file mode 100644
index 0000000..9ef4ded
--- /dev/null
+++ b/Examples/test-suite/python/final_c_runme.py
@@ -0,0 +1,6 @@
+import final_c
+
+final_c.init()
+f = final_c.cvar.final
+if (f.yval != 123):
+  raise RuntimeError("f.yval fail")
diff --git a/Examples/test-suite/python/friends_operator_overloading_runme.py b/Examples/test-suite/python/friends_operator_overloading_runme.py
new file mode 100644
index 0000000..2b09755
--- /dev/null
+++ b/Examples/test-suite/python/friends_operator_overloading_runme.py
@@ -0,0 +1,41 @@
+import friends_operator_overloading
+
+friends_operator_overloading.sanity_checker_ShiftA()
+friends_operator_overloading.sanity_checker_ShiftB()
+
+sa1 = friends_operator_overloading.ShiftA(200)
+sa2 = friends_operator_overloading.ShiftA(1000)
+sb1 = friends_operator_overloading.ShiftB(200)
+sb2 = friends_operator_overloading.ShiftB(1000)
+
+# Shift operator via members
+sa3 = sa2 << sa1
+val = sa3.getVal()
+if val != 800:
+    raise RuntimeError("Wrong val: {}".format(val))
+
+sa4 = sa2 << 300
+val = sa4.getVal()
+if val != 700:
+    raise RuntimeError("Wrong val: {}".format(val))
+
+sb3 = sb2 << sb1
+val = sb3.getVal()
+if val != 800:
+    raise RuntimeError("Wrong val: {}".format(val))
+
+sb4 = sb2 << 300
+val = sb4.getVal()
+if val != 700:
+    raise RuntimeError("Wrong val: {}".format(val))
+
+# Shift operator via global wrapper
+shift = friends_operator_overloading.__lshift__(sa2, sa1)
+val = shift.getVal()
+if val != 800:
+    raise RuntimeError("Wrong val: {}".format(val))
+
+shift = friends_operator_overloading.__lshift__(sb2, sb1)
+val = shift.getVal()
+if val != 800:
+    raise RuntimeError("Wrong val: {}".format(val))
diff --git a/Examples/test-suite/python/friends_runme.py b/Examples/test-suite/python/friends_runme.py
index 2d377fd..29a385b 100644
--- a/Examples/test-suite/python/friends_runme.py
+++ b/Examples/test-suite/python/friends_runme.py
@@ -1,5 +1,9 @@
 import friends
 
+def check_equal(a, b):
+    if a != b:
+        raise RuntimeError("Not equal {} != {}".format(a, b))
+
 a = friends.A(2)
 
 if friends.get_val1(a) != 2:
@@ -19,7 +23,7 @@
 if friends.mix(a, b) != 5:
     raise RuntimeError
 
-di = friends.D_d(2)
+di = friends.D_i(2)
 dd = friends.D_d(3.3)
 
 # incredible template overloading working just fine
@@ -35,3 +39,19 @@
     raise RuntimeError
 if friends.get_val1(dd) != 1.3:
     raise RuntimeError
+
+if friends.chum_blah() != 1234:
+  raise RuntimeError("failed")
+if friends.mate_blah() != 4321:
+  raise RuntimeError("failed")
+
+foe = friends.Foe(111)
+check_equal(friends.friend_definition(), 10)
+check_equal(friends.friend_declaration(), 11)
+check_equal(friends.friend_args_definition(foe), 111)
+check_equal(friends.friend_args_declaration(foe), 111)
+
+check_equal(friends.friend_definition_compiler(), 20)
+check_equal(friends.friend_declaration_compiler(), 21)
+check_equal(friends.friend_args_definition_compiler(foe), 111)
+check_equal(friends.friend_args_declaration_compiler(foe), 111)
diff --git a/Examples/test-suite/python/fvirtual_runme.py b/Examples/test-suite/python/fvirtual_runme.py
index 99f5dc6..fe211b4 100644
--- a/Examples/test-suite/python/fvirtual_runme.py
+++ b/Examples/test-suite/python/fvirtual_runme.py
@@ -5,4 +5,4 @@
 i = sw.addChild(n)
 
 if i != 2:
-    raise RuntimeError, "addChild"
+    raise RuntimeError("addChild")
diff --git a/Examples/test-suite/python/global_functions_runme.py b/Examples/test-suite/python/global_functions_runme.py
index f411261..4aab1b0 100644
--- a/Examples/test-suite/python/global_functions_runme.py
+++ b/Examples/test-suite/python/global_functions_runme.py
@@ -11,7 +11,7 @@
 fail = True
 try:
     global_void(1)
-except TypeError, e:
+except TypeError as e:
     fail = False
 if fail:
     raise RuntimeError("argument count check failed")
@@ -19,7 +19,7 @@
 fail = True
 try:
     global_one()
-except TypeError, e:
+except TypeError as e:
     fail = False
 if fail:
     raise RuntimeError("argument count check failed")
@@ -27,7 +27,7 @@
 fail = True
 try:
     global_one(2, 2)
-except TypeError, e:
+except TypeError as e:
     fail = False
 
 if fail:
@@ -36,7 +36,7 @@
 fail = True
 try:
     global_two(1)
-except TypeError, e:
+except TypeError as e:
     fail = False
 
 if fail:
@@ -45,7 +45,7 @@
 fail = True
 try:
     global_two(3, 3, 3)
-except TypeError, e:
+except TypeError as e:
     fail = False
 
 if fail:
diff --git a/Examples/test-suite/python/global_vars_runme.py b/Examples/test-suite/python/global_vars_runme.py
index 3ef0b49..015519e 100644
--- a/Examples/test-suite/python/global_vars_runme.py
+++ b/Examples/test-suite/python/global_vars_runme.py
@@ -20,7 +20,7 @@
 fail = True
 try:
     global_vars.cvar.notexist = "something"
-except AttributeError, e:
+except AttributeError as e:
     fail = False
 if fail:
     raise RuntimeError("AttributeError should have been thrown")
@@ -28,7 +28,7 @@
 fail = True
 try:
     g = global_vars.cvar.notexist
-except AttributeError, e:
+except AttributeError as e:
     fail = False
 if fail:
     raise RuntimeError("AttributeError should have been thrown")
diff --git a/Examples/test-suite/python/ignore_parameter_runme.py b/Examples/test-suite/python/ignore_parameter_runme.py
index 2b5c212..0f40f96 100644
--- a/Examples/test-suite/python/ignore_parameter_runme.py
+++ b/Examples/test-suite/python/ignore_parameter_runme.py
@@ -16,6 +16,7 @@
 check(car.bugatti("bar", 2), 8.8)
 check(car.lamborghini(), 101)
 check(car.maseratti(289), 289)
+check(car.audi(), 8.8)  # Typemap overrides default argument
 
 MiniCooper(200, 0)
 MorrisMinor("baz", 0)
diff --git a/Examples/test-suite/python/import_stl_runme.py b/Examples/test-suite/python/import_stl_runme.py
index 69fe812..d0efbd0 100644
--- a/Examples/test-suite/python/import_stl_runme.py
+++ b/Examples/test-suite/python/import_stl_runme.py
@@ -3,4 +3,4 @@
 
 v_new = import_stl_b.process_vector([1, 2, 3])
 if v_new != (1, 2, 3, 4):
-    raise RuntimeError, v_new
+    raise RuntimeError(v_new)
diff --git a/Examples/test-suite/python/inctest_runme.py b/Examples/test-suite/python/inctest_runme.py
index fa34929..c274656 100644
--- a/Examples/test-suite/python/inctest_runme.py
+++ b/Examples/test-suite/python/inctest_runme.py
@@ -1,31 +1,21 @@
 import inctest
 
-error = 0
 try:
     a = inctest.A()
 except:
-    print "didn't find A"
-    print "therefore, I didn't include 'testdir/subdir1/hello.i'"
-    error = 1
+    raise RuntimeError("didn't find A, therefore, I didn't include 'testdir/subdir1/hello.i'")
 pass
 
 
 try:
     b = inctest.B()
 except:
-    print "didn't find B"
-    print "therefore, I didn't include 'testdir/subdir2/hello.i'"
-    error = 1
+    raise RuntimeError("didn't find B, therefore, I didn't include 'testdir/subdir2/hello.i'")
 pass
 
-if error == 1:
-    raise RuntimeError
-
 # Check the import in subdirectory worked
 if inctest.importtest1(5) != 15:
-    print "import test 1 failed"
-    raise RuntimeError
+    raise RuntimeError("import test 1 failed")
 
 if inctest.importtest2("black") != "white":
-    print "import test 2 failed"
-    raise RuntimeError
+    raise RuntimeError("import test 2 failed")
diff --git a/Examples/test-suite/python/inherit_missing_runme.py b/Examples/test-suite/python/inherit_missing_runme.py
index 044c166..57a245e 100644
--- a/Examples/test-suite/python/inherit_missing_runme.py
+++ b/Examples/test-suite/python/inherit_missing_runme.py
@@ -6,14 +6,14 @@
 
 x = inherit_missing.do_blah(a)
 if x != "Foo::blah":
-    print "Whoa! Bad return", x
+    raise RuntimeError("Whoa! Bad return {}".format(x))
 
 x = inherit_missing.do_blah(b)
 if x != "Bar::blah":
-    print "Whoa! Bad return", x
+    raise RuntimeError("Whoa! Bad return {}".format(x))
 
 x = inherit_missing.do_blah(c)
 if x != "Spam::blah":
-    print "Whoa! Bad return", x
+    raise RuntimeError("Whoa! Bad return {}".format(x))
 
 inherit_missing.delete_Foo(a)
diff --git a/Examples/test-suite/python/inplaceadd_runme.py b/Examples/test-suite/python/inplaceadd_runme.py
index 7f292cb..3d5a1fd 100644
--- a/Examples/test-suite/python/inplaceadd_runme.py
+++ b/Examples/test-suite/python/inplaceadd_runme.py
@@ -3,8 +3,7 @@
 
 a += 5
 if a.val != 12:
-    print a.val
-    raise RuntimeError
+    raise RuntimeError("a.val: {}".format(a.val))
 
 a -= 5
 if a.val != 7:
diff --git a/Examples/test-suite/python/kwargs_feature_runme.py b/Examples/test-suite/python/kwargs_feature_runme.py
index a2d4731..677c9eb 100644
--- a/Examples/test-suite/python/kwargs_feature_runme.py
+++ b/Examples/test-suite/python/kwargs_feature_runme.py
@@ -15,13 +15,16 @@
 if f.foo(b=1, a=2) != 3:
     raise RuntimeError
 
-if Foo_statfoo(b=2) != 3:
+if Foo.statfoo(b=2) != 3:
+    raise RuntimeError
+
+if Foo.statfoo_onearg(x=4) != 8:
     raise RuntimeError
 
 if f.efoo(b=2) != 3:
     raise RuntimeError
 
-if Foo_sfoo(b=2) != 3:
+if Foo.sfoo(b=2) != 3:
     raise RuntimeError
 
 
@@ -31,13 +34,13 @@
 if b.bar(b=1, a=2) != 3:
     raise RuntimeError
 
-if BarInt_statbar(b=2) != 3:
+if BarInt.statbar(b=2) != 3:
     raise RuntimeError
 
 if b.ebar(b=2) != 3:
     raise RuntimeError
 
-if BarInt_sbar(b=2) != 3:
+if BarInt.sbar(b=2) != 3:
     raise RuntimeError
 
 
@@ -79,3 +82,61 @@
 
 if rfoo(x=11, n=22) != 11:
     raise RuntimeError
+
+# Extended constructors
+e = Extending0()
+e = Extending1(one=1)
+e = Extending1(1)
+e = Extending2(1, "two")
+e = Extending2(1, two="two")
+e = Extending2(two="two", one=1)
+e = ExtendingOptArgs1()
+e = ExtendingOptArgs1(1)
+e = ExtendingOptArgs2(one=1)
+e = ExtendingOptArgs2()
+e = ExtendingOptArgs2(one=1)
+e = ExtendingOptArgs2(two="two")
+e = ExtendingOptArgs2(two="two", one=1)
+
+# Invalid kwargs test
+h = Hello()
+try:
+    h = Hello(nonexistent=10)
+    raise RuntimeError("missed exception")
+except TypeError as e:
+    pass
+
+f = Foo(1)
+f = Foo(a=1)
+try:
+    f = Foo(nonexistent=10)
+    raise RuntimeError("missed exception")
+except TypeError as e:
+    pass
+
+try:
+    f = Foo(a=1, nonexistent=10)
+    raise RuntimeError("missed exception")
+except TypeError as e:
+    pass
+
+try:
+    f = Foo(1, nonexistent=10)
+    raise RuntimeError("missed exception")
+except TypeError as e:
+    pass
+
+# Varargs
+f = VarargConstructor(fmt="Ciao")
+f.vararg_method(fmt="Bonjour")
+try:
+    f = VarargConstructor(nonexistent="Ciao")
+    raise RuntimeError("missed exception")
+except TypeError as e:
+    pass
+
+try:
+    f.vararg_method(nonexistent="Bonjour")
+    raise RuntimeError("missed exception")
+except TypeError as e:
+    pass
diff --git a/Examples/test-suite/python/langobj_runme.py b/Examples/test-suite/python/langobj_runme.py
index b32d5a1..ce1c9cd 100644
--- a/Examples/test-suite/python/langobj_runme.py
+++ b/Examples/test-suite/python/langobj_runme.py
@@ -2,7 +2,7 @@
 from langobj import *
 
 
-x = "hello"
+x = 256*256+1
 rx = sys.getrefcount(x)
 v = identity(x)
 rv = sys.getrefcount(v)
diff --git a/Examples/test-suite/python/li_attribute_runme.py b/Examples/test-suite/python/li_attribute_runme.py
index 80e7936..d26bf0b 100644
--- a/Examples/test-suite/python/li_attribute_runme.py
+++ b/Examples/test-suite/python/li_attribute_runme.py
@@ -8,12 +8,10 @@
     raise RuntimeError
 aa.a = 3
 if aa.a != 3:
-    print aa.a
-    raise RuntimeError
+    raise RuntimeError("aa.a: {}".format(aa.a))
 
 if aa.b != 2:
-    print aa.b
-    raise RuntimeError
+    raise RuntimeError("aa.b: {}".format(aa.b))
 aa.b = 5
 if aa.b != 5:
     raise RuntimeError
@@ -47,6 +45,9 @@
 myClass.Foo = myFoo
 if myClass.Foo.x != 8:
     raise RuntimeError
+myClass.Foo2 = myFoo
+if myClass.Foo2.x != 8:
+    raise RuntimeError
 
 # class/struct attribute with get/set methods using return/pass by value
 myClassVal = li_attribute.MyClassVal()
@@ -77,7 +78,7 @@
 try:
     x = myFoo.does_not_exist
     raise RuntimeError
-except AttributeError, e:
+except AttributeError as e:
     if str(e).find("does_not_exist") == -1:
         raise RuntimeError
 
diff --git a/Examples/test-suite/python/li_attribute_template_runme.py b/Examples/test-suite/python/li_attribute_template_runme.py
index d33b123..f0a7749 100644
--- a/Examples/test-suite/python/li_attribute_template_runme.py
+++ b/Examples/test-suite/python/li_attribute_template_runme.py
@@ -7,8 +7,7 @@
 
 def rassert(what, master):
     if what != master:
-        print what
-        raise RuntimeError
+        raise RuntimeError("what: {}".format(what))
 
 # Testing primitive by value attribute
 rassert(chell.a, 1)
diff --git a/Examples/test-suite/python/li_boost_shared_ptr_director_runme.py b/Examples/test-suite/python/li_boost_shared_ptr_director_runme.py
index 52868ea..b4382ca 100644
--- a/Examples/test-suite/python/li_boost_shared_ptr_director_runme.py
+++ b/Examples/test-suite/python/li_boost_shared_ptr_director_runme.py
@@ -1,5 +1,9 @@
 from li_boost_shared_ptr_director import *
 
+def swig_assert_equal(a, b):
+	if a != b:
+		raise RuntimeError(str(a) + " != " + str(b))
+
 class Derived(Base):
     def __init__(self, flag):
         self.return_none = flag
@@ -59,22 +63,22 @@
 a = Derived(False)
 b = Derived(True)
 
-assert call_ret_c_shared_ptr(a) ==  1
-assert call_ret_c_shared_ptr(b) == -1
-assert call_ret_c_by_value(a)   ==  1
+swig_assert_equal(call_ret_c_shared_ptr(a), 1)
+swig_assert_equal(call_ret_c_shared_ptr(b), -1)
+swig_assert_equal(call_ret_c_by_value(a),   1)
 
-assert call_take_c_by_value(a)                  == 5
-assert call_take_c_by_ref(a)                    == 6
-assert call_take_c_by_pointer(a)                == 7
-assert call_take_c_by_pointer_ref(a)            == 8
-assert call_take_c_shared_ptr_by_value(a)       == 9
-assert call_take_c_shared_ptr_by_ref(a)         == 10
-assert call_take_c_shared_ptr_by_pointer(a)     == 11
-assert call_take_c_shared_ptr_by_pointer_ref(a) == 12
+swig_assert_equal(call_take_c_by_value(a),                  5)
+swig_assert_equal(call_take_c_by_ref(a),                    6)
+swig_assert_equal(call_take_c_by_pointer(a),                7)
+swig_assert_equal(call_take_c_by_pointer_ref(a),            8)
+swig_assert_equal(call_take_c_shared_ptr_by_value(a),       9)
+swig_assert_equal(call_take_c_shared_ptr_by_ref(a),         10)
+swig_assert_equal(call_take_c_shared_ptr_by_pointer(a),     11)
+swig_assert_equal(call_take_c_shared_ptr_by_pointer_ref(a), 12)
 
-assert call_take_c_by_pointer_with_null(a)                == -2
-assert call_take_c_by_pointer_ref_with_null(a)            == -3
-assert call_take_c_shared_ptr_by_value_with_null(a)       == -4
-assert call_take_c_shared_ptr_by_ref_with_null(a)         == -5
-assert call_take_c_shared_ptr_by_pointer_with_null(a)     == -6
-assert call_take_c_shared_ptr_by_pointer_ref_with_null(a) == -7
+swig_assert_equal(call_take_c_by_pointer_with_null(a),                -2)
+swig_assert_equal(call_take_c_by_pointer_ref_with_null(a),            -3)
+swig_assert_equal(call_take_c_shared_ptr_by_value_with_null(a),       -4)
+swig_assert_equal(call_take_c_shared_ptr_by_ref_with_null(a),         -5)
+swig_assert_equal(call_take_c_shared_ptr_by_pointer_with_null(a),     -6)
+swig_assert_equal(call_take_c_shared_ptr_by_pointer_ref_with_null(a), -7)
diff --git a/Examples/test-suite/python/li_boost_shared_ptr_runme.py b/Examples/test-suite/python/li_boost_shared_ptr_runme.py
index c960625..bde79fd 100644
--- a/Examples/test-suite/python/li_boost_shared_ptr_runme.py
+++ b/Examples/test-suite/python/li_boost_shared_ptr_runme.py
@@ -10,7 +10,7 @@
 
     def main(self):
         if (debug):
-            print "Started"
+            print("Started")
 
         li_boost_shared_ptr.cvar.debug_shared = debug
 
@@ -20,7 +20,7 @@
             self.runtest()
 
         # Expect 1 instance - the one global variable (GlobalValue)
-        if (li_boost_shared_ptr.Klass_getTotal_count() != 1):
+        if (li_boost_shared_ptr.Klass.getTotal_count() != 1):
             raise RuntimeError("Klass.total_count=%s" %
                                li_boost_shared_ptr.Klass.getTotal_count())
 
@@ -32,7 +32,7 @@
                     "shared_ptr wrapper count=%s" % wrapper_count)
 
         if (debug):
-            print "Finished"
+            print("Finished")
 
     def runtest(self):
         # simple shared_ptr usage - created in C++
@@ -168,6 +168,19 @@
         except ValueError:
             pass
 
+        # test null pointers emitted from C++
+        k = li_boost_shared_ptr.sp_pointer_null()
+        if (li_boost_shared_ptr.smartpointertest(k) != None):
+            raise RuntimeError("return was not null")
+
+        k = li_boost_shared_ptr.null_sp_pointer()
+        if (li_boost_shared_ptr.smartpointertest(k) != None):
+            raise RuntimeError("return was not null")
+
+        k = li_boost_shared_ptr.sp_value_null()
+        if (li_boost_shared_ptr.smartpointertest(k) != None):
+            raise RuntimeError("return was not null")
+
         # $owner
         k = li_boost_shared_ptr.pointerownertest()
         val = k.getValue()
diff --git a/Examples/test-suite/python/li_constraints_runme.py b/Examples/test-suite/python/li_constraints_runme.py
new file mode 100644
index 0000000..72ba22d
--- /dev/null
+++ b/Examples/test-suite/python/li_constraints_runme.py
@@ -0,0 +1,54 @@
+import li_constraints
+
+def check_double(et, fn, f, val):
+    actual = True
+    proper = False
+    try:
+      fn(val)
+    except ValueError as e:
+      actual = False
+      proper = "Expected a " + f + " value." == "%s"%(e)
+    if actual:
+      if not et:
+        raise Exception("function '%s' with %d should perform an exception"%(f, val))
+    else:
+      if et:
+        raise Exception("function '%s' with %d should not perform an exception"%(f, val))
+      elif not proper:
+        raise Exception("function '%s' with %d should perform a proper exception"%(f, val))
+    pass
+
+nonnegative = lambda v : li_constraints.test_nonnegative(v)
+check_double(True, nonnegative, "non-negative", 10)
+check_double(True, nonnegative, "non-negative", 0)
+check_double(False, nonnegative, "non-negative", -10)
+
+nonpositive = lambda v : li_constraints.test_nonpositive(v)
+check_double(False, nonpositive, "non-positive", 10)
+check_double(True, nonpositive, "non-positive", 0)
+check_double(True, nonpositive, "non-positive", -10)
+
+positive = lambda v : li_constraints.test_positive(v)
+check_double(True, positive, "positive", 10)
+check_double(False, positive, "positive", 0)
+check_double(False, positive, "positive", -10)
+
+negative = lambda v : li_constraints.test_negative(v)
+check_double(False, negative, "negative", 10)
+check_double(False, negative, "negative", 0)
+check_double(True, negative, "negative", -10)
+
+nonzero = lambda v : li_constraints.test_nonzero(v)
+check_double(True, nonzero, "nonzero", 10)
+check_double(False, nonzero, "nonzero", 0)
+check_double(True, nonzero, "nonzero", -10)
+
+have_exception = False
+try:
+   li_constraints.test_nonnull(None)
+except ValueError as e:
+   have_exception = "Received a NULL pointer." == "%s"%(e)
+if not have_exception:
+   raise Exception("test_nonnull should perform exception with 'null' value")
+nonnull = li_constraints.get_nonnull()
+li_constraints.test_nonnull(nonnull)
diff --git a/Examples/test-suite/python/li_cstring_runme.py b/Examples/test-suite/python/li_cstring_runme.py
index b718f13..d22fc26 100644
--- a/Examples/test-suite/python/li_cstring_runme.py
+++ b/Examples/test-suite/python/li_cstring_runme.py
@@ -11,12 +11,10 @@
     raise RuntimeError
 
 if test3("hello") != "hello-suffix":
-    print test3("hello")
-    raise RuntimeError
+    raise RuntimeError("test3(\"hello\")")
 
 if test4("hello") != "hello-suffix":
-    print test4("hello")
-    raise RuntimeError
+    raise RuntimeError("test4(\"hello\")")
 
 if test5(4) != "xxxx":
     raise RuntimeError
diff --git a/Examples/test-suite/python/li_cwstring_runme.py b/Examples/test-suite/python/li_cwstring_runme.py
index 5dd7b9b..9216445 100644
--- a/Examples/test-suite/python/li_cwstring_runme.py
+++ b/Examples/test-suite/python/li_cwstring_runme.py
@@ -1,28 +1,28 @@
 from li_cwstring import *
 
-if count(u"ab\0ab\0ab\0", 0) != 3:
+if count("ab\0ab\0ab\0", 0) != 3:
     raise RuntimeError
 
-if test1() != u"Hello World":
+if test1() != "Hello World":
     raise RuntimeError
 
-if test2() != u" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_":
+if test2() != " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_":
     raise RuntimeError
 
-if test3("hello") != u"hello-suffix":
+if test3("hello") != "hello-suffix":
     raise RuntimeError
 
-if test4("hello") != u"hello-suffix":
+if test4("hello") != "hello-suffix":
     raise RuntimeError
 
-if test5(4) != u"xxxx":
+if test5(4) != "xxxx":
     raise RuntimeError
 
-if test6(10) != u"xxxxx":
+if test6(10) != "xxxxx":
     raise RuntimeError
 
-if test7() != u"Hello world!":
+if test7() != "Hello world!":
     raise RuntimeError
 
-if test8() != u" !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_":
+if test8() != " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_":
     raise RuntimeError
diff --git a/Examples/test-suite/python/li_factory_runme.py b/Examples/test-suite/python/li_factory_runme.py
index fb2c81e..ce0e3ca 100644
--- a/Examples/test-suite/python/li_factory_runme.py
+++ b/Examples/test-suite/python/li_factory_runme.py
@@ -1,11 +1,11 @@
 from li_factory import *
 
-circle = Geometry_create(Geometry.CIRCLE)
+circle = Geometry.create(Geometry.CIRCLE)
 r = circle.radius()
 if (r != 1.5):
     raise RuntimeError
 
-point = Geometry_create(Geometry.POINT)
+point = Geometry.create(Geometry.POINT)
 w = point.width()
 if (w != 1.0):
     raise RuntimeError
diff --git a/Examples/test-suite/python/li_implicit_runme.py b/Examples/test-suite/python/li_implicit_runme.py
index d8dd0fd..5d5c6ca 100644
--- a/Examples/test-suite/python/li_implicit_runme.py
+++ b/Examples/test-suite/python/li_implicit_runme.py
@@ -9,8 +9,8 @@
 ab, get(ab)
 
 if get(ai) != get(1):
-    raise RuntimeError, "bad implicit type"
+    raise RuntimeError("bad implicit type")
 if get(ad) != get(2.0):
-    raise RuntimeError, "bad implicit type"
+    raise RuntimeError("bad implicit type")
 if get(ab) != get(b):
-    raise RuntimeError, "bad implicit type"
+    raise RuntimeError("bad implicit type")
diff --git a/Examples/test-suite/python/li_std_auto_ptr_runme.py b/Examples/test-suite/python/li_std_auto_ptr_runme.py
index 6d2479f..dd8893f 100644
--- a/Examples/test-suite/python/li_std_auto_ptr_runme.py
+++ b/Examples/test-suite/python/li_std_auto_ptr_runme.py
@@ -1,17 +1,109 @@
 from li_std_auto_ptr import *
 
+def checkCount(expected_count):
+    actual_count = Klass.getTotal_count()
+    if (actual_count != expected_count):
+        raise RuntimeError("Counts incorrect, expected:" + expected_count + " actual:" + actual_count)
+
+# Test raw pointer handling involving virtual inheritance
+kini = KlassInheritance("KlassInheritanceInput")
+checkCount(1)
+s = useKlassRawPtr(kini)
+if s != "KlassInheritanceInput":
+    raise RuntimeError("Incorrect string: " + s)
+del kini
+checkCount(0)
+
+
+# auto_ptr as input
+kin = Klass("KlassInput")
+checkCount(1)
+s = takeKlassAutoPtr(kin)
+checkCount(0)
+if kin.thisown:
+    raise RuntimeError("thisown should be false")
+if s != "KlassInput":
+    raise RuntimeError("Incorrect string: " + s)
+if not is_nullptr(kin):
+    raise RuntimeError("is_nullptr failed")
+del kin # Should not fail, even though already deleted
+checkCount(0)
+
+kin = Klass("KlassInput")
+checkCount(1)
+s = takeKlassAutoPtr(kin)
+checkCount(0)
+if kin.thisown:
+    raise RuntimeError("thisown should be false")
+if s != "KlassInput":
+    raise RuntimeError("Incorrect string: " + s)
+if not is_nullptr(kin):
+    raise RuntimeError("is_nullptr failed")
+exception_thrown = False
+try:
+    s = takeKlassAutoPtr(kin)
+except RuntimeError as e:
+    if "cannot release ownership as memory is not owned" not in str(e):
+        raise RuntimeError("incorrect exception message");
+    exception_thrown = True
+if not exception_thrown:
+    raise RuntimeError("double usage of takeKlassAutoPtr should have been an error")
+del kin # Should not fail, even though already deleted
+checkCount(0)
+
+kin = Klass("KlassInput")
+exception_thrown = False
+notowned = get_not_owned_ptr(kin)
+try:
+    takeKlassAutoPtr(notowned)
+except RuntimeError as e:
+    exception_thrown = True
+if not exception_thrown:
+  raise RuntimeError("Should have thrown 'Cannot release ownership as memory is not owned' error")
+checkCount(1)
+del kin
+checkCount(0)
+
+kini = KlassInheritance("KlassInheritanceInput")
+checkCount(1)
+s = takeKlassAutoPtr(kini)
+checkCount(0)
+if kini.thisown:
+    raise RuntimeError("thisown should be false")
+if s != "KlassInheritanceInput":
+    raise RuntimeError("Incorrect string: " + s)
+if not is_nullptr(kini):
+    raise RuntimeError("is_nullptr failed")
+del kini # Should not fail, even though already deleted
+checkCount(0)
+
+takeKlassAutoPtr(None)
+takeKlassAutoPtr(make_null())
+checkCount(0)
+
+# overloaded parameters
+if overloadTest() != 0:
+  raise RuntimeError("overloadTest failed")
+if overloadTest(None) != 1:
+  raise RuntimeError("overloadTest failed")
+if overloadTest(Klass("over")) != 1:
+  raise RuntimeError("overloadTest failed")
+checkCount(0);
+
+
+# auto_ptr as output
 k1 = makeKlassAutoPtr("first")
 k2 = makeKlassAutoPtr("second")
-if Klass_getTotal_count() != 2:
-    raise "number of objects should be 2"
+checkCount(2)
 
 del k1
-if Klass_getTotal_count() != 1:
-    raise "number of objects should be 1"
+checkCount(1)
 
 if k2.getLabel() != "second":
     raise "wrong object label"
 
 del k2
-if Klass_getTotal_count() != 0:
-    raise "no objects should be left"
+checkCount(0)
+
+if (makeNullAutoPtr() != None):
+  raise RuntimeError("null failure")
diff --git a/Examples/test-suite/python/li_std_carray_runme.py b/Examples/test-suite/python/li_std_carray_runme.py
deleted file mode 100644
index 36eeaf1..0000000
--- a/Examples/test-suite/python/li_std_carray_runme.py
+++ /dev/null
@@ -1,39 +0,0 @@
-from li_std_carray import *
-
-
-v3 = Vector3()
-for i in range(0, len(v3)):
-    v3[i] = i
-
-i = 0
-for d in v3:
-    if d != i:
-        raise RuntimeError
-    i = i + 1
-
-
-m3 = Matrix3()
-
-for i in range(0, len(m3)):
-    v3 = m3[i]
-    for j in range(0, len(v3)):
-        v3[j] = i + j
-
-i = 0
-for v3 in m3:
-    j = 0
-    for d in v3:
-        if d != i + j:
-            raise RuntimeError
-        j = j + 1
-        pass
-    i = i + 1
-    pass
-
-for i in range(0, len(m3)):
-    for j in range(0, len(m3)):
-        if m3[i][j] != i + j:
-            raise RuntimeError
-
-da = Vector3((1, 2, 3))
-ma = Matrix3(((1, 2, 3), (4, 5, 6), (7, 8, 9)))
diff --git a/Examples/test-suite/python/li_std_containers_int_runme.py b/Examples/test-suite/python/li_std_containers_int_runme.py
index 941838a..13c76d3 100644
--- a/Examples/test-suite/python/li_std_containers_int_runme.py
+++ b/Examples/test-suite/python/li_std_containers_int_runme.py
@@ -6,7 +6,7 @@
 
 
 def failed(a, b, msg):
-    raise RuntimeError, msg + " " + str(list(a)) + " " + str(list(b))
+    raise RuntimeError(msg + " " + str(list(a)) + " " + str(list(b)))
 
 
 def compare_sequences(a, b):
@@ -26,7 +26,7 @@
 
 
 def container_insert_step(i, j, step, newval):
-    ps = range(6)
+    ps = list(range(6))
     iv = vector_int(ps)
     il = list_int(ps)
 
@@ -43,9 +43,9 @@
             else:
                 ps[i:j:step] = newval
         ps_error = None
-    except ValueError, e:
+    except ValueError as e:
         ps_error = e
-    except IndexError, e:
+    except IndexError as e:
         ps_error = e
 
     # std::vector<int>
@@ -61,9 +61,9 @@
             else:
                 iv[i:j:step] = newval
         iv_error = None
-    except ValueError, e:
+    except ValueError as e:
         iv_error = e
-    except IndexError, e:
+    except IndexError as e:
         iv_error = e
 
     # std::list<int>
@@ -79,14 +79,14 @@
             else:
                 il[i:j:step] = newval
         il_error = None
-    except ValueError, e:
+    except ValueError as e:
         il_error = e
-    except IndexError, e:
+    except IndexError as e:
         il_error = e
 
     if not((type(ps_error) == type(iv_error)) and (type(ps_error) == type(il_error))):
-        raise RuntimeError, "ValueError exception not consistently thrown: " + \
-            str(ps_error) + " " + str(iv_error) + " " + str(il_error)
+        raise RuntimeError("ValueError exception not consistently thrown: " + \
+            str(ps_error) + " " + str(iv_error) + " " + str(il_error))
 
     compare_containers(ps, iv, il)
 
@@ -94,7 +94,7 @@
 # Check std::vector and std::list delete behaves same as Python list
 # delete including exceptions
 def container_delete_step(i, j, step):
-    ps = range(6)
+    ps = list(range(6))
     iv = vector_int(ps)
     il = list_int(ps)
 
@@ -111,9 +111,9 @@
             else:
                 del ps[i:j:step]
         ps_error = None
-    except ValueError, e:
+    except ValueError as e:
         ps_error = e
-    except IndexError, e:
+    except IndexError as e:
         ps_error = e
 
     # std::vector<int>
@@ -129,9 +129,9 @@
             else:
                 del iv[i:j:step]
         iv_error = None
-    except ValueError, e:
+    except ValueError as e:
         iv_error = e
-    except IndexError, e:
+    except IndexError as e:
         iv_error = e
 
     # std::list<int>
@@ -147,14 +147,14 @@
             else:
                 del il[i:j:step]
         il_error = None
-    except ValueError, e:
+    except ValueError as e:
         il_error = e
-    except IndexError, e:
+    except IndexError as e:
         il_error = e
 
     if not((type(ps_error) == type(iv_error)) and (type(ps_error) == type(il_error))):
-        raise RuntimeError, "ValueError exception not consistently thrown: " + \
-            str(ps_error) + " " + str(iv_error) + " " + str(il_error)
+        raise RuntimeError("ValueError exception not consistently thrown: " + \
+            str(ps_error) + " " + str(iv_error) + " " + str(il_error))
 
     compare_containers(ps, iv, il)
 
@@ -252,7 +252,7 @@
         for step in range(-7, 7):
             container_delete_step(start, end, step)
 
-ps = range(6)
+ps = list(range(6))
 iv = vector_int(ps)
 il = list_int(ps)
 del ps[:]
@@ -279,3 +279,9 @@
     raise RuntimeError("Zero step not caught")
 except ValueError:
     pass
+
+# Construct from set (Iterator protocol, not Sequence protocol)
+ps = {11, 22, 33}
+iv = vector_int(ps)
+il = vector_int(ps)
+compare_containers(list(ps), iv, il)
diff --git a/Examples/test-suite/python/li_std_map_runme.py b/Examples/test-suite/python/li_std_map_runme.py
index ac214dd..0d9416e 100644
--- a/Examples/test-suite/python/li_std_map_runme.py
+++ b/Examples/test-suite/python/li_std_map_runme.py
@@ -25,8 +25,7 @@
 
 for k in m:
     if pm[k].this != m[k].this:
-        print pm[k], m[k]
-        raise RuntimeError
+        raise RuntimeError("Not equal {} {}".format(pm[k], m[k]))
 
 
 m = {}
@@ -51,31 +50,43 @@
 if mii[1] != 2:
     raise RuntimeError
 
-if mii.keys() != [1]:
+if list(mii.keys()) != [1]:
     raise RuntimeError("keys")
-if mii.values() != [2]:
+if list(mii.values()) != [2]:
     raise RuntimeError("values")
-if mii.items() != [(1, 2)]:
+if list(mii.items()) != [(1, 2)]:
     raise RuntimeError("items")
 
 if [k for k in mii] != [1]:
     raise RuntimeError("iteration")
 
-if [i for i in mii.iterkeys()] != [1]:
+if [i for i in mii.keys()] != [1]:
     raise RuntimeError("iterkeys")
-if [i for i in mii.itervalues()] != [2]:
+if [i for i in mii.values()] != [2]:
     raise RuntimeError("itervalues")
-if [i for i in mii.iteritems()] != [(1, 2)]:
+if [i for i in mii.items()] != [(1, 2)]:
     raise RuntimeError("iteritems")
 
 
+# map global variable
+li_std_map.populate(li_std_map.cvar.MyMap)
+li_std_map.cvar.MyMap["eeeeee"] = 6
+keys = " ".join([k for k in list(li_std_map.cvar.MyMap.keys())])
+if keys != "a aa zzz xxxx aaaaa eeeeee":
+    raise RuntimeError("Keys are wrong or in wrong order: " + keys)
+
+values = " ".join([str(v) for v in list(li_std_map.cvar.MyMap.values())])
+if values != "1 2 3 4 5 6":
+    raise RuntimeError("Values are wrong or in wrong order: " + values)
+
+
 slmap = li_std_map.StringLengthNumberMap()
 li_std_map.populate(slmap)
 
-keys = " ".join([k for k in slmap.keys()])
+keys = " ".join([k for k in list(slmap.keys())])
 if keys != "a aa zzz xxxx aaaaa":
     raise RuntimeError("Keys are wrong or in wrong order: " + keys)
 
-values = " ".join([str(v) for v in slmap.values()])
+values = " ".join([str(v) for v in list(slmap.values())])
 if values != "1 2 3 4 5":
     raise RuntimeError("Values are wrong or in wrong order: " + values)
diff --git a/Examples/test-suite/python/li_std_pair_runme.py b/Examples/test-suite/python/li_std_pair_runme.py
new file mode 100644
index 0000000..4150e5c
--- /dev/null
+++ b/Examples/test-suite/python/li_std_pair_runme.py
@@ -0,0 +1,47 @@
+from li_std_pair import *
+
+def check(flag):
+    if not flag:
+        raise RuntimeError("Check failed")
+
+intPair = makeIntPair(7, 6)
+check(isinstance(intPair, tuple))
+check(len(intPair) == 2)
+check(intPair[0] == 7)
+check(intPair[1] == 6)
+
+intPairConstRef = makeIntPairConstRef(7, 6)
+check(isinstance(intPairConstRef, tuple))
+check(intPairConstRef[0] == 7)
+check(intPairConstRef[1] == 6)
+
+#
+# Each of these should return a reference to a wrapped
+# std::pair<int, int> object (i.e. an IntPair instance).
+#
+intPairPtr = makeIntPairPtr(7, 6)
+check(isinstance(intPairPtr, IntPair))
+check(intPairPtr[0] == 7)
+check(intPairPtr[1] == 6)
+
+intPairRef = makeIntPairRef(7, 6)
+check(isinstance(intPairRef, IntPair))
+check(intPairRef[0] == 7)
+check(intPairRef[1] == 6)
+#
+# Now test various input typemaps. Each of the wrapped C++ functions
+# (product1, product2 and product3) is expecting an argument of a
+# different type (see li_std_pair.i). Typemaps should be in place to
+# convert this tuple into the expected argument type.
+#
+check(product1(intPair) == 42)
+check(product2(intPair) == 42)
+# check(product3(intPair) == 42) # TODO, if desirable to match Ruby wrappers behaviour. Requires equivalent to typemap(in) std::pair* in Lib/ruby/std_pair.i and further fixes to stop recursive calls to swig::asptr which this testcase shows. Plus further changes for any type of sequence type (including other STL containers) to be accepted by all methods taking an STL container to match Ruby behaviour.
+
+#
+# Similarly, each of the input typemaps should know what to do
+# with an IntPair instance.
+#
+check(product1(intPairPtr) == 42)
+check(product2(intPairPtr) == 42)
+check(product3(intPairPtr) == 42)
diff --git a/Examples/test-suite/python/li_std_set_runme.py b/Examples/test-suite/python/li_std_set_runme.py
index 5e5b724..7618f7d 100644
--- a/Examples/test-suite/python/li_std_set_runme.py
+++ b/Examples/test-suite/python/li_std_set_runme.py
@@ -14,11 +14,11 @@
     raise RuntimeError
 
 i = s.__iter__()
-if i.next() != "a":
+if next(i) != "a":
     raise RuntimeError
-if i.next() != "b":
+if next(i) != "b":
     raise RuntimeError
-if i.next() != "c":
+if next(i) != "c":
     raise RuntimeError
 
 
@@ -26,7 +26,7 @@
 e = s.end()
 sum = ""
 while (b != e):
-    sum = sum + b.next()
+    sum = sum + next(b)
 if sum != "abc":
     raise RuntimeError
 
@@ -34,7 +34,7 @@
 e = s.rend()
 sum = ""
 while (b != e):
-    sum = sum + b.next()
+    sum = sum + next(b)
 
 if sum != "cba":
     raise RuntimeError
@@ -47,25 +47,25 @@
 si.append(3)
 i = si.__iter__()
 
-if i.next() != 1:
+if next(i) != 1:
     raise RuntimeError
-if i.next() != 2:
+if next(i) != 2:
     raise RuntimeError
-if i.next() != 3:
+if next(i) != 3:
     raise RuntimeError
 
 if si[0] != 1:
     raise RuntimeError
 
 i = s.begin()
-i.next()
+next(i)
 s.erase(i)
 
 b = s.begin()
 e = s.end()
 sum = ""
 while (b != e):
-    sum = sum + b.next()
+    sum = sum + next(b)
 if sum != "ac":
     raise RuntimeError
 
@@ -92,3 +92,13 @@
 
 if (len(sum) != 3 or (not 1 in sum) or (not "hello" in sum) or (not (1, 2) in sum)):
     raise RuntimeError
+
+# Create from Python set
+s = set_string({"x", "y", "z"})
+sum = ""
+for i in s:
+    sum = sum + i
+
+if sum != "xyz":
+    raise RuntimeError
+
diff --git a/Examples/test-suite/python/li_std_stream_runme.py b/Examples/test-suite/python/li_std_stream_runme.py
index 08c3088..a4526f0 100644
--- a/Examples/test-suite/python/li_std_stream_runme.py
+++ b/Examples/test-suite/python/li_std_stream_runme.py
@@ -9,5 +9,4 @@
 
 
 if o.str() != "A class 2345 1.435":
-    print "\"%s\"" % (o.str(),)
-    raise RuntimeError
+    raise RuntimeError("str failed: \"%s\"".format(o.str()))
diff --git a/Examples/test-suite/python/li_std_string_extra_runme.py b/Examples/test-suite/python/li_std_string_extra_runme.py
index 087d92b..71620e7 100644
--- a/Examples/test-suite/python/li_std_string_extra_runme.py
+++ b/Examples/test-suite/python/li_std_string_extra_runme.py
@@ -4,18 +4,22 @@
 
 
 if li_std_string_extra.test_ccvalue(x) != x:
-    raise RuntimeError, "bad string mapping"
+    raise RuntimeError("bad string mapping")
 
 if li_std_string_extra.test_cvalue(x) != x:
-    raise RuntimeError, "bad string mapping"
+    raise RuntimeError("bad string mapping")
 
 if li_std_string_extra.test_value(x) != x:
-    print x, li_std_string_extra.test_value(x)
-    raise RuntimeError, "bad string mapping"
+    raise RuntimeError("bad string mapping {} {}".format(x, li_std_string_extra.test_value(x)))
 
 if li_std_string_extra.test_const_reference(x) != x:
-    raise RuntimeError, "bad string mapping"
+    raise RuntimeError("bad string mapping")
 
+s = li_std_string_extra.string("1234567890")
+size = s.size()
+if size != 10:
+    raise "Incorrect size"
+s.shrink_to_fit()
 
 s = li_std_string_extra.string("he")
 #s += "ll"
@@ -23,45 +27,43 @@
 s = s + "llo"
 
 if s != x:
-    print s, x
-    raise RuntimeError, "bad string mapping"
+    raise RuntimeError("bad string mapping {} {}".format(s, x))
 
 if s[1:4] != x[1:4]:
-    raise RuntimeError, "bad string mapping"
+    raise RuntimeError("bad string mapping")
 
 if li_std_string_extra.test_value(s) != x:
-    raise RuntimeError, "bad string mapping"
+    raise RuntimeError("bad string mapping")
 
 if li_std_string_extra.test_const_reference(s) != x:
-    raise RuntimeError, "bad string mapping"
+    raise RuntimeError("bad string mapping")
 
 a = li_std_string_extra.A(s)
 
 if li_std_string_extra.test_value(a) != x:
-    raise RuntimeError, "bad string mapping"
+    raise RuntimeError("bad string mapping")
 
 if li_std_string_extra.test_const_reference(a) != x:
-    raise RuntimeError, "bad string mapping"
+    raise RuntimeError("bad string mapping")
 
 b = li_std_string_extra.string(" world")
 
 s = a + b
 if a + b != "hello world":
-    print a + b
-    raise RuntimeError, "bad string mapping"
+    raise RuntimeError("bad string mapping {}".format(a + b))
 
 if a + " world" != "hello world":
-    raise RuntimeError, "bad string mapping"
+    raise RuntimeError("bad string mapping")
 
 # This is expected to fail with -builtin option
 # Reverse operators not supported in builtin types
 if not li_std_string_extra.is_python_builtin():
     if "hello" + b != "hello world":
-        raise RuntimeError, "bad string mapping"
+        raise RuntimeError("bad string mapping")
 
     c = "hello" + b
     if c.find_last_of("l") != 9:
-        raise RuntimeError, "bad string mapping"
+        raise RuntimeError("bad string mapping")
 
 s = "hello world"
 
@@ -69,33 +71,33 @@
 
 b.name = li_std_string_extra.string("hello")
 if b.name != "hello":
-    raise RuntimeError, "bad string mapping"
+    raise RuntimeError("bad string mapping")
 
 
 b.a = li_std_string_extra.A("hello")
 if b.a != "hello":
-    raise RuntimeError, "bad string mapping"
+    raise RuntimeError("bad string mapping")
 
 
 if li_std_string_extra.test_value_basic1(x) != x:
-    raise RuntimeError, "bad string mapping"
+    raise RuntimeError("bad string mapping")
 
 if li_std_string_extra.test_value_basic2(x) != x:
-    raise RuntimeError, "bad string mapping"
+    raise RuntimeError("bad string mapping")
 
 
 if li_std_string_extra.test_value_basic3(x) != x:
-    raise RuntimeError, "bad string mapping"
+    raise RuntimeError("bad string mapping")
 
 if li_std_string_extra.test_value_basic_overload(x) != x:
-    raise RuntimeError, "bad overload string"
+    raise RuntimeError("bad overload string")
 
 if li_std_string_extra.test_value_basic_overload(123) != "int":
-    raise RuntimeError, "bad overload int"
+    raise RuntimeError("bad overload int")
 
 try:
     li_std_string_extra.test_value_basic_overload([x])
-    raise RuntimeError, "should throw TypeError"
+    raise RuntimeError("should throw TypeError")
 except TypeError as e:
     if str(e).find("Possible C/C++ prototypes are:") == -1:
         raise RuntimeError("Incorrect error message text:\n{}".format(e))
@@ -103,7 +105,7 @@
 
 try:
     li_std_string_extra.test_value_basic_overload([123])
-    raise RuntimeError, "should throw TypeError"
+    raise RuntimeError("should throw TypeError")
 except TypeError as e:
     if str(e).find("Possible C/C++ prototypes are:") == -1:
         raise RuntimeError("Incorrect error message text:\n{}".format(e))
@@ -112,30 +114,30 @@
 # Global variables
 s = "initial string"
 if li_std_string_extra.cvar.GlobalString2 != "global string 2":
-    raise RuntimeError, "GlobalString2 test 1"
+    raise RuntimeError("GlobalString2 test 1")
 li_std_string_extra.cvar.GlobalString2 = s
 if li_std_string_extra.cvar.GlobalString2 != s:
-    raise RuntimeError, "GlobalString2 test 2"
+    raise RuntimeError("GlobalString2 test 2")
 if li_std_string_extra.cvar.ConstGlobalString != "const global string":
-    raise RuntimeError, "ConstGlobalString test"
+    raise RuntimeError("ConstGlobalString test")
 
 # Member variables
 myStructure = li_std_string_extra.Structure()
 if myStructure.MemberString2 != "member string 2":
-    raise RuntimeError, "MemberString2 test 1"
+    raise RuntimeError("MemberString2 test 1")
 myStructure.MemberString2 = s
 if myStructure.MemberString2 != s:
-    raise RuntimeError, "MemberString2 test 2"
+    raise RuntimeError("MemberString2 test 2")
 if myStructure.ConstMemberString != "const member string":
-    raise RuntimeError, "ConstMemberString test"
+    raise RuntimeError("ConstMemberString test")
 
 if li_std_string_extra.cvar.Structure_StaticMemberString2 != "static member string 2":
-    raise RuntimeError, "StaticMemberString2 test 1"
+    raise RuntimeError("StaticMemberString2 test 1")
 li_std_string_extra.cvar.Structure_StaticMemberString2 = s
 if li_std_string_extra.cvar.Structure_StaticMemberString2 != s:
-    raise RuntimeError, "StaticMemberString2 test 2"
+    raise RuntimeError("StaticMemberString2 test 2")
 if li_std_string_extra.cvar.Structure_ConstStaticMemberString != "const static member string":
-    raise RuntimeError, "ConstStaticMemberString test"
+    raise RuntimeError("ConstStaticMemberString test")
 
 
 if li_std_string_extra.test_reference_input("hello") != "hello":
diff --git a/Examples/test-suite/python/li_std_vector_enum_runme.py b/Examples/test-suite/python/li_std_vector_enum_runme.py
index 318d1bf..587f20b 100644
--- a/Examples/test-suite/python/li_std_vector_enum_runme.py
+++ b/Examples/test-suite/python/li_std_vector_enum_runme.py
@@ -14,7 +14,7 @@
 it = ev.nums.iterator()
 v = it.value()
 check(v, 10)
-it.next()
+next(it)
 v = it.value()
 check(v, 20)
 
diff --git a/Examples/test-suite/python/li_std_vector_extra_runme.py b/Examples/test-suite/python/li_std_vector_extra_runme.py
index 59e729a..4044455 100644
--- a/Examples/test-suite/python/li_std_vector_extra_runme.py
+++ b/Examples/test-suite/python/li_std_vector_extra_runme.py
@@ -23,20 +23,20 @@
 bv[3] = bool(0)
 
 if bv[0] != bv[2]:
-    raise RuntimeError, "bad std::vector<bool> mapping"
+    raise RuntimeError("bad std::vector<bool> mapping")
 
 b = B(5)
 va = VecA([b, None, b, b])
 
 if va[0].f(1) != 6:
-    raise RuntimeError, "bad std::vector<A*> mapping"
+    raise RuntimeError("bad std::vector<A*> mapping")
 
 if vecAptr(va) != 6:
-    raise RuntimeError, "bad std::vector<A*> mapping"
+    raise RuntimeError("bad std::vector<A*> mapping")
 
 b.val = 7
 if va[3].f(1) != 8:
-    raise RuntimeError, "bad std::vector<A*> mapping"
+    raise RuntimeError("bad std::vector<A*> mapping")
 
 
 ip = PtrInt()
@@ -47,7 +47,7 @@
 
 vi = IntPtrVector((ip, ap, None))
 if ArrInt_getitem(vi[0], 0) != ArrInt_getitem(vi[1], 2):
-    raise RuntimeError, "bad std::vector<int*> mapping"
+    raise RuntimeError("bad std::vector<int*> mapping")
 
 delete_ArrInt(ap)
 
@@ -57,42 +57,42 @@
 v = IntVector()
 v[0:2] = [1, 2]
 if v[0] != 1 or v[1] != 2:
-    raise RuntimeError, "bad setslice"
+    raise RuntimeError("bad setslice")
 
 if v[0:-1][0] != 1:
-    raise RuntimeError, "bad getslice"
+    raise RuntimeError("bad getslice")
 
 if v[0:-2].size() != 0:
-    raise RuntimeError, "bad getslice"
+    raise RuntimeError("bad getslice")
 
 v[0:1] = [2]
 if v[0] != 2:
-    raise RuntimeError, "bad setslice"
+    raise RuntimeError("bad setslice")
 
 v[1:] = [3]
 if v[1] != 3:
-    raise RuntimeError, "bad setslice"
+    raise RuntimeError("bad setslice")
 
 v[2:] = [3]
 if v[2] != 3:
-    raise RuntimeError, "bad setslice"
+    raise RuntimeError("bad setslice")
 
 if v[0:][0] != v[0]:
-    raise RuntimeError, "bad getslice"
+    raise RuntimeError("bad getslice")
 
 
 del v[:]
 if v.size() != 0:
-    raise RuntimeError, "bad getslice"
+    raise RuntimeError("bad getslice")
 
 del v[:]
 if v.size() != 0:
-    raise RuntimeError, "bad getslice"
+    raise RuntimeError("bad getslice")
 
 
 v = vecStr(["hello ", "world"])
 if v[0] != "hello world":
-    raise RuntimeError, "bad std::string+std::vector"
+    raise RuntimeError("bad std::string+std::vector")
 
 
 pv = pyvector([1, "hello", (1, 2)])
diff --git a/Examples/test-suite/python/li_std_vector_runme.py b/Examples/test-suite/python/li_std_vector_runme.py
index 7146051..728fc35 100644
--- a/Examples/test-suite/python/li_std_vector_runme.py
+++ b/Examples/test-suite/python/li_std_vector_runme.py
@@ -8,3 +8,27 @@
   raise RuntimeError("Using None should result in a TypeError")
 except TypeError:
   pass
+
+
+# Variables
+vh = VariableHolder()
+vector_append(vh.instance_variable, 10)
+if vh.instance_variable[0] != 10:
+    raise RuntimeError("instance_variable check")
+vh.instance_variable.clear()
+if len(vh.instance_variable) != 0:
+    raise RuntimeError("instance_variable clear")
+
+vector_append(cvar.VariableHolder_static_variable, 20)
+if cvar.VariableHolder_static_variable[0] != 20:
+    raise RuntimeError("static_variable check")
+cvar.VariableHolder_static_variable.clear()
+if len(cvar.VariableHolder_static_variable) != 0:
+    raise RuntimeError("static_variable clear")
+
+vector_append(cvar.global_variable, 30)
+if cvar.global_variable[0] != 30:
+    raise RuntimeError("global_variable check")
+cvar.global_variable.clear()
+if len(cvar.global_variable) != 0:
+    raise RuntimeError("global_variable clear")
diff --git a/Examples/test-suite/python/li_std_wstream_runme.py b/Examples/test-suite/python/li_std_wstream_runme.py
index 045645b..0ecdddb 100644
--- a/Examples/test-suite/python/li_std_wstream_runme.py
+++ b/Examples/test-suite/python/li_std_wstream_runme.py
@@ -5,8 +5,7 @@
 
 o = wostringstream()
 
-o << a << u" " << 2345 << u" " << 1.435 << wends
+o << a << " " << 2345 << " " << 1.435 << wends
 
 if o.str() != "A class 2345 1.435\0":
-    print "\"%s\"" % (o.str(),)
-    raise RuntimeError
+    raise RuntimeError("str failed: \"%s\"".format(o.str()))
diff --git a/Examples/test-suite/python/li_std_wstring_inherit_runme.py b/Examples/test-suite/python/li_std_wstring_inherit_runme.py
index 558914e..bd58589 100644
--- a/Examples/test-suite/python/li_std_wstring_inherit_runme.py
+++ b/Examples/test-suite/python/li_std_wstring_inherit_runme.py
@@ -1,14 +1,13 @@
 import li_std_wstring_inherit
 import sys
 
-x = u"hello"
+x = "hello"
 
-s = li_std_wstring_inherit.wstring(u"he")
-s = s + u"llo"
+s = li_std_wstring_inherit.wstring("he")
+s = s + "llo"
 
 if s != x:
-    print s, x
-    raise RuntimeError("bad string mapping")
+    raise RuntimeError("bad string mapping {} {}".format(s, x))
 
 if s[1:4] != x[1:4]:
     raise RuntimeError("bad string mapping")
@@ -34,12 +33,12 @@
 
 b = li_std_wstring_inherit.B("hi")
 
-b.name = li_std_wstring_inherit.wstring(u"hello")
+b.name = li_std_wstring_inherit.wstring("hello")
 if b.name != "hello":
     raise RuntimeError("bad string mapping")
 
 
 b.a = li_std_wstring_inherit.A("hello")
-if b.a != u"hello":
+if b.a != "hello":
     raise RuntimeError("bad string mapping")
 
diff --git a/Examples/test-suite/python/li_std_wstring_runme.py b/Examples/test-suite/python/li_std_wstring_runme.py
index c6210e2..ca8dc31 100644
--- a/Examples/test-suite/python/li_std_wstring_runme.py
+++ b/Examples/test-suite/python/li_std_wstring_runme.py
@@ -5,10 +5,10 @@
     if a != b:
         raise RuntimeError("failed {} {}".format(a, b))
 
-h = u"h"
+h = "h"
 check_equal(li_std_wstring.test_wcvalue(h), h)
 
-x = u"abc"
+x = "abc"
 check_equal(li_std_wstring.test_ccvalue(x), x)
 check_equal(li_std_wstring.test_cvalue(x), x)
 
@@ -54,6 +54,12 @@
 check_equal(li_std_wstring.test_ccvalue(x), "abc")
 check_equal(li_std_wstring.test_wchar_overload(x), "abc")
 
+ts = li_std_wstring.wchar_test_struct()
+ts.wchar_t_member = h
+check_equal(ts.wchar_t_member, h)
+ts.wchar_t_ptr_member = s
+check_equal(ts.wchar_t_ptr_member, s)
+
 ################### Python specific
 
 # Byte strings only converted in Python 2
@@ -72,7 +78,7 @@
 
 # Check surrogateescape
 if sys.version_info[0:2] > (3, 1):
-    x = u"h\udce9llo"  # surrogate escaped representation of C char*: "h\xe9llo"
+    x = "h\udce9llo"  # surrogate escaped representation of C char*: "h\xe9llo"
     if li_std_wstring.non_utf8_c_str() != x:
         raise RuntimeError("surrogateescape not working")
     if li_std_wstring.size_wstring(x) != 5 and len(x) != 5:
diff --git a/Examples/test-suite/python/minherit_runme.py b/Examples/test-suite/python/minherit_runme.py
index b7e7d01..8638d23 100644
--- a/Examples/test-suite/python/minherit_runme.py
+++ b/Examples/test-suite/python/minherit_runme.py
@@ -7,31 +7,31 @@
 d = minherit.Spam()
 
 if a.xget() != 1:
-    raise RuntimeError, "Bad attribute value"
+    raise RuntimeError("Bad attribute value")
 
 if b.yget() != 2:
-    raise RuntimeError, "Bad attribute value"
+    raise RuntimeError("Bad attribute value")
 
 if c.xget() != 1 or c.yget() != 2 or c.zget() != 3:
-    raise RuntimeError, "Bad attribute value"
+    raise RuntimeError("Bad attribute value")
 
 if d.xget() != 1 or d.yget() != 2 or d.zget() != 3 or d.wget() != 4:
-    raise RuntimeError, "Bad attribute value"
+    raise RuntimeError("Bad attribute value")
 
 
 if minherit.xget(a) != 1:
-    raise RuntimeError, "Bad attribute value %d" % (minherit.xget(a))
+    raise RuntimeError("Bad attribute value %d" % (minherit.xget(a)))
 
 if minherit.yget(b) != 2:
-    raise RuntimeError, "Bad attribute value %d" % (minherit.yget(b))
+    raise RuntimeError("Bad attribute value %d" % (minherit.yget(b)))
 
 if minherit.xget(c) != 1 or minherit.yget(c) != 2 or minherit.zget(c) != 3:
-    raise RuntimeError, "Bad attribute value %d %d %d" % (
-        minherit.xget(c), minherit.yget(c), minherit.zget(c))
+    raise RuntimeError("Bad attribute value %d %d %d" % (
+        minherit.xget(c), minherit.yget(c), minherit.zget(c)))
 
 if minherit.xget(d) != 1 or minherit.yget(d) != 2 or minherit.zget(d) != 3 or minherit.wget(d) != 4:
-    raise RuntimeError, "Bad attribute value %d %d %d %d" % (
-        minherit.xget(d), minherit.yget(d), minherit.zget(d), minherit.wget(d))
+    raise RuntimeError("Bad attribute value %d %d %d %d" % (
+        minherit.xget(d), minherit.yget(d), minherit.zget(d), minherit.wget(d)))
 
 # Cleanse all of the pointers and see what happens
 
@@ -41,27 +41,27 @@
 dd = minherit.toSpamPtr(d)
 
 if aa.xget() != 1:
-    raise RuntimeError, "Bad attribute value"
+    raise RuntimeError("Bad attribute value")
 
 if bb.yget() != 2:
-    raise RuntimeError, "Bad attribute value"
+    raise RuntimeError("Bad attribute value")
 
 if cc.xget() != 1 or cc.yget() != 2 or cc.zget() != 3:
-    raise RuntimeError, "Bad attribute value"
+    raise RuntimeError("Bad attribute value")
 
 if dd.xget() != 1 or dd.yget() != 2 or dd.zget() != 3 or dd.wget() != 4:
-    raise RuntimeError, "Bad attribute value"
+    raise RuntimeError("Bad attribute value")
 
 if minherit.xget(aa) != 1:
-    raise RuntimeError, "Bad attribute value %d" % (minherit.xget(aa))
+    raise RuntimeError("Bad attribute value %d" % (minherit.xget(aa)))
 
 if minherit.yget(bb) != 2:
-    raise RuntimeError, "Bad attribute value %d" % (minherit.yget(bb))
+    raise RuntimeError("Bad attribute value %d" % (minherit.yget(bb)))
 
 if minherit.xget(cc) != 1 or minherit.yget(cc) != 2 or minherit.zget(cc) != 3:
-    raise RuntimeError, "Bad attribute value %d %d %d" % (
-        minherit.xget(cc), minherit.yget(cc), minherit.zget(cc))
+    raise RuntimeError("Bad attribute value %d %d %d" % (
+        minherit.xget(cc), minherit.yget(cc), minherit.zget(cc)))
 
 if minherit.xget(dd) != 1 or minherit.yget(dd) != 2 or minherit.zget(dd) != 3 or minherit.wget(dd) != 4:
-    raise RuntimeError, "Bad attribute value %d %d %d %d" % (
-        minherit.xget(dd), minherit.yget(dd), minherit.zget(dd), minherit.wget(dd))
+    raise RuntimeError("Bad attribute value %d %d %d %d" % (
+        minherit.xget(dd), minherit.yget(dd), minherit.zget(dd), minherit.wget(dd)))
diff --git a/Examples/test-suite/python/multivalue_runme.py b/Examples/test-suite/python/multivalue_runme.py
new file mode 100644
index 0000000..ba83272
--- /dev/null
+++ b/Examples/test-suite/python/multivalue_runme.py
@@ -0,0 +1,19 @@
+import multivalue
+
+q, r = multivalue.divide_l(37, 5);
+if q != 7:
+    raise RuntimeError("Test divide_l quotient")
+if r != 2:
+    raise RuntimeError("Test divide_l remainder")
+
+q, r = multivalue.divide_v(41, 7);
+if q != 5:
+    raise RuntimeError("Test divide_v quotient")
+if r != 6:
+    raise RuntimeError("Test divide_v remainder")
+
+q, r = multivalue.divide_l(91, 13);
+if q != 7:
+    raise RuntimeError("Test divide_mv quotient")
+if r != 0:
+    raise RuntimeError("Test divide_mv remainder")
diff --git a/Examples/test-suite/python/name_warnings_runme.py b/Examples/test-suite/python/name_warnings_runme.py
new file mode 100644
index 0000000..0387436
--- /dev/null
+++ b/Examples/test-suite/python/name_warnings_runme.py
@@ -0,0 +1,9 @@
+from name_warnings import *
+
+def check(flag):
+    if not flag:
+        raise RuntimeError("Test failed")
+
+four = double_an_int(2)
+check(four == 4)
+
diff --git a/Examples/test-suite/python/namespace_class_runme.py b/Examples/test-suite/python/namespace_class_runme.py
index aa51655..9349f24 100644
--- a/Examples/test-suite/python/namespace_class_runme.py
+++ b/Examples/test-suite/python/namespace_class_runme.py
@@ -7,7 +7,7 @@
     error = 0
 
 if (error):
-    raise RuntimeError, "Private1 is private"
+    raise RuntimeError("Private1 is private")
 
 try:
     p = Private2()
@@ -16,7 +16,7 @@
     error = 0
 
 if (error):
-    raise RuntimeError, "Private2 is private"
+    raise RuntimeError("Private2 is private")
 
 EulerT3D.toFrame(1, 1, 1)
 
diff --git a/Examples/test-suite/python/not_c_keywords_runme.py b/Examples/test-suite/python/not_c_keywords_runme.py
new file mode 100644
index 0000000..7f07724
--- /dev/null
+++ b/Examples/test-suite/python/not_c_keywords_runme.py
@@ -0,0 +1,7 @@
+from not_c_keywords import *
+
+cs = ComplexStruct()
+cs.init()
+if cs.complex != 123:
+    raise RuntimeError("complex not correct")
+cs.complex = 456
diff --git a/Examples/test-suite/python/operator_overload_runme.py b/Examples/test-suite/python/operator_overload_runme.py
index 31c4905..cd565f6 100644
--- a/Examples/test-suite/python/operator_overload_runme.py
+++ b/Examples/test-suite/python/operator_overload_runme.py
@@ -1,7 +1,7 @@
 from operator_overload import *
 
 # first check all the operators are implemented correctly from pure C++ code
-Op_sanity_check()
+Op.sanity_check()
 
 pop = Op(6)/Op(3)
 
diff --git a/Examples/test-suite/python/overload_complicated_runme.py b/Examples/test-suite/python/overload_complicated_runme.py
index 2593c4f..8794da1 100644
--- a/Examples/test-suite/python/overload_complicated_runme.py
+++ b/Examples/test-suite/python/overload_complicated_runme.py
@@ -10,38 +10,38 @@
 # Check overloaded in const only and pointers/references which target
 # languages cannot disambiguate
 if p.hip(False) != 701:
-    raise RuntimeError, "Test 1 failed"
+    raise RuntimeError("Test 1 failed")
 
 if p.hip(pInt) != 702:
-    raise RuntimeError, "Test 2 failed"
+    raise RuntimeError("Test 2 failed")
 
 # Reverse the order for the above
 if p.hop(pInt) != 805:
-    raise RuntimeError, "Test 3 failed"
+    raise RuntimeError("Test 3 failed")
 
 if p.hop(False) != 801:
-    raise RuntimeError, "Test 4 failed"
+    raise RuntimeError("Test 4 failed")
 
 # Few more variations and order shuffled
 if p.pop(False) != 901:
-    raise RuntimeError, "Test 5 failed"
+    raise RuntimeError("Test 5 failed")
 
 if p.pop(pInt) != 904:
-    raise RuntimeError, "Test 6 failed"
+    raise RuntimeError("Test 6 failed")
 
 if p.pop() != 905:
-    raise RuntimeError, "Test 7 failed"
+    raise RuntimeError("Test 7 failed")
 
 # Overload on const only
 if p.bop(pInt) != 1001:
-    raise RuntimeError, "Test 8 failed"
+    raise RuntimeError("Test 8 failed")
 
 if p.bip(pInt) != 2002:
-    raise RuntimeError, "Test 9 failed"
+    raise RuntimeError("Test 9 failed")
 
 # Globals
 if muzak(False) != 3001:
-    raise RuntimeError, "Test 10 failed"
+    raise RuntimeError("Test 10 failed")
 
 if muzak(pInt) != 3002:
-    raise RuntimeError, "Test 11 failed"
+    raise RuntimeError("Test 11 failed")
diff --git a/Examples/test-suite/python/overload_null_runme.py b/Examples/test-suite/python/overload_null_runme.py
index a345242..4b69b5c 100644
--- a/Examples/test-suite/python/overload_null_runme.py
+++ b/Examples/test-suite/python/overload_null_runme.py
@@ -32,13 +32,13 @@
 check(15, o.byval2cpr(None))
 check(16, o.byval2cpr(x))
 
-# forward class declaration
-check(17, o.byval1forwardptr(x))
-check(18, o.byval1forwardptr(None))
+# fwd class declaration
+check(17, o.byval1fwdptr(x))
+check(18, o.byval1fwdptr(None))
 
-check(19, o.byval2forwardptr(None))
-check(20, o.byval2forwardptr(x))
+check(19, o.byval2fwdptr(None))
+check(20, o.byval2fwdptr(x))
 
-check(21, o.byval1forwardref(x))
+check(21, o.byval1fwdref(x))
 
-check(22, o.byval2forwardref(x))
+check(22, o.byval2fwdref(x))
diff --git a/Examples/test-suite/python/overload_simple_runme.py b/Examples/test-suite/python/overload_simple_runme.py
index 6d72ec0..5676382 100644
--- a/Examples/test-suite/python/overload_simple_runme.py
+++ b/Examples/test-suite/python/overload_simple_runme.py
@@ -1,95 +1,95 @@
 from overload_simple import *
 
 if foo(3) != "foo:int":
-    raise RuntimeError, "foo(int)"
+    raise RuntimeError("foo(int)")
 
 if foo(3.0) != "foo:double":
-    raise RuntimeError, "foo(double)"
+    raise RuntimeError("foo(double)")
 
 if foo("hello") != "foo:char *":
-    raise RuntimeError, "foo(char *)"
+    raise RuntimeError("foo(char *)")
 
 f = Foo()
 b = Bar()
 
 if foo(f) != "foo:Foo *":
-    raise RuntimeError, "foo(Foo *)"
+    raise RuntimeError("foo(Foo *)")
 
 if foo(b) != "foo:Bar *":
-    raise RuntimeError, "foo(Bar *)"
+    raise RuntimeError("foo(Bar *)")
 
 v = malloc_void(32)
 
 if foo(v) != "foo:void *":
-    raise RuntimeError, "foo(void *)"
+    raise RuntimeError("foo(void *)")
 
 s = Spam()
 
 if s.foo(3) != "foo:int":
-    raise RuntimeError, "Spam::foo(int)"
+    raise RuntimeError("Spam::foo(int)")
 
 if s.foo(3.0) != "foo:double":
-    raise RuntimeError, "Spam::foo(double)"
+    raise RuntimeError("Spam::foo(double)")
 
 if s.foo("hello") != "foo:char *":
-    raise RuntimeError, "Spam::foo(char *)"
+    raise RuntimeError("Spam::foo(char *)")
 
 if s.foo(f) != "foo:Foo *":
-    raise RuntimeError, "Spam::foo(Foo *)"
+    raise RuntimeError("Spam::foo(Foo *)")
 
 if s.foo(b) != "foo:Bar *":
-    raise RuntimeError, "Spam::foo(Bar *)"
+    raise RuntimeError("Spam::foo(Bar *)")
 
 if s.foo(v) != "foo:void *":
-    raise RuntimeError, "Spam::foo(void *)"
+    raise RuntimeError("Spam::foo(void *)")
 
-if Spam_bar(3) != "bar:int":
-    raise RuntimeError, "Spam::bar(int)"
+if Spam.bar(3) != "bar:int":
+    raise RuntimeError("Spam::bar(int)")
 
-if Spam_bar(3.0) != "bar:double":
-    raise RuntimeError, "Spam::bar(double)"
+if Spam.bar(3.0) != "bar:double":
+    raise RuntimeError("Spam::bar(double)")
 
-if Spam_bar("hello") != "bar:char *":
-    raise RuntimeError, "Spam::bar(char *)"
+if Spam.bar("hello") != "bar:char *":
+    raise RuntimeError("Spam::bar(char *)")
 
-if Spam_bar(f) != "bar:Foo *":
-    raise RuntimeError, "Spam::bar(Foo *)"
+if Spam.bar(f) != "bar:Foo *":
+    raise RuntimeError("Spam::bar(Foo *)")
 
-if Spam_bar(b) != "bar:Bar *":
-    raise RuntimeError, "Spam::bar(Bar *)"
+if Spam.bar(b) != "bar:Bar *":
+    raise RuntimeError("Spam::bar(Bar *)")
 
-if Spam_bar(v) != "bar:void *":
-    raise RuntimeError, "Spam::bar(void *)"
+if Spam.bar(v) != "bar:void *":
+    raise RuntimeError("Spam::bar(void *)")
 
 # Test constructors
 
 s = Spam()
 if s.type != "none":
-    raise RuntimeError, "Spam()"
+    raise RuntimeError("Spam()")
 
 s = Spam(3)
 if s.type != "int":
-    raise RuntimeError, "Spam(int)"
+    raise RuntimeError("Spam(int)")
 
 s = Spam(3.4)
 if s.type != "double":
-    raise RuntimeError, "Spam(double)"
+    raise RuntimeError("Spam(double)")
 
 s = Spam("hello")
 if s.type != "char *":
-    raise RuntimeError, "Spam(char *)"
+    raise RuntimeError("Spam(char *)")
 
 s = Spam(f)
 if s.type != "Foo *":
-    raise RuntimeError, "Spam(Foo *)"
+    raise RuntimeError("Spam(Foo *)")
 
 s = Spam(b)
 if s.type != "Bar *":
-    raise RuntimeError, "Spam(Bar *)"
+    raise RuntimeError("Spam(Bar *)")
 
 s = Spam(v)
 if s.type != "void *":
-    raise RuntimeError, "Spam(void *)"
+    raise RuntimeError("Spam(void *)")
 
 
 free_void(v)
diff --git a/Examples/test-suite/python/overload_subtype_runme.py b/Examples/test-suite/python/overload_subtype_runme.py
index 3f32a55..b02e62f 100644
--- a/Examples/test-suite/python/overload_subtype_runme.py
+++ b/Examples/test-suite/python/overload_subtype_runme.py
@@ -4,7 +4,7 @@
 b = Bar()
 
 if spam(f) != 1:
-    raise RuntimeError, "foo"
+    raise RuntimeError("foo")
 
 if spam(b) != 2:
-    raise RuntimeError, "bar"
+    raise RuntimeError("bar")
diff --git a/Examples/test-suite/python/overload_template_fast_runme.py b/Examples/test-suite/python/overload_template_fast_runme.py
index ca3cac9..e4eb332 100644
--- a/Examples/test-suite/python/overload_template_fast_runme.py
+++ b/Examples/test-suite/python/overload_template_fast_runme.py
@@ -7,74 +7,74 @@
 
 # mix 1
 if (mix1("hi") != 101):
-    raise RuntimeError, ("mix1(const char*)")
+    raise RuntimeError(("mix1(const char*)"))
 
 if (mix1(1.0, 1.0) != 102):
-    raise RuntimeError, ("mix1(double, const double &)")
+    raise RuntimeError(("mix1(double, const double &)"))
 
 if (mix1(1.0) != 103):
-    raise RuntimeError, ("mix1(double)")
+    raise RuntimeError(("mix1(double)"))
 
 # mix 2
 if (mix2("hi") != 101):
-    raise RuntimeError, ("mix2(const char*)")
+    raise RuntimeError(("mix2(const char*)"))
 
 if (mix2(1.0, 1.0) != 102):
-    raise RuntimeError, ("mix2(double, const double &)")
+    raise RuntimeError(("mix2(double, const double &)"))
 
 if (mix2(1.0) != 103):
-    raise RuntimeError, ("mix2(double)")
+    raise RuntimeError(("mix2(double)"))
 
 # mix 3
 if (mix3("hi") != 101):
-    raise RuntimeError, ("mix3(const char*)")
+    raise RuntimeError(("mix3(const char*)"))
 
 if (mix3(1.0, 1.0) != 102):
-    raise RuntimeError, ("mix3(double, const double &)")
+    raise RuntimeError(("mix3(double, const double &)"))
 
 if (mix3(1.0) != 103):
-    raise RuntimeError, ("mix3(double)")
+    raise RuntimeError(("mix3(double)"))
 
 # Combination 1
 if (overtparams1(100) != 10):
-    raise RuntimeError, ("overtparams1(int)")
+    raise RuntimeError(("overtparams1(int)"))
 
 if (overtparams1(100.0, 100) != 20):
-    raise RuntimeError, ("overtparams1(double, int)")
+    raise RuntimeError(("overtparams1(double, int)"))
 
 # Combination 2
 if (overtparams2(100.0, 100) != 40):
-    raise RuntimeError, ("overtparams2(double, int)")
+    raise RuntimeError(("overtparams2(double, int)"))
 
 # Combination 3
 if (overloaded() != 60):
-    raise RuntimeError, ("overloaded()")
+    raise RuntimeError(("overloaded()"))
 
 if (overloaded(100.0, 100) != 70):
-    raise RuntimeError, ("overloaded(double, int)")
+    raise RuntimeError(("overloaded(double, int)"))
 
 # Combination 4
 if (overloadedagain("hello") != 80):
-    raise RuntimeError, ("overloadedagain(const char *)")
+    raise RuntimeError(("overloadedagain(const char *)"))
 
 if (overloadedagain() != 90):
-    raise RuntimeError, ("overloadedagain(double)")
+    raise RuntimeError(("overloadedagain(double)"))
 
 # specializations
 if (specialization(10) != 202):
-    raise RuntimeError, ("specialization(int)")
+    raise RuntimeError(("specialization(int)"))
 
 if (specialization(10.0) != 203):
-    raise RuntimeError, ("specialization(double)")
+    raise RuntimeError(("specialization(double)"))
 
 if (specialization(10, 10) != 204):
-    raise RuntimeError, ("specialization(int, int)")
+    raise RuntimeError(("specialization(int, int)"))
 
 if (specialization(10.0, 10.0) != 205):
-    raise RuntimeError, ("specialization(double, double)")
+    raise RuntimeError(("specialization(double, double)"))
 
 if (specialization("hi", "hi") != 201):
-    raise RuntimeError, ("specialization(const char *, const char *)")
+    raise RuntimeError(("specialization(const char *, const char *)"))
 
 
 # simple specialization
@@ -84,61 +84,61 @@
 
 # a bit of everything
 if (overload("hi") != 0):
-    raise RuntimeError, ("overload()")
+    raise RuntimeError(("overload()"))
 
 if (overload(1) != 10):
-    raise RuntimeError, ("overload(int t)")
+    raise RuntimeError(("overload(int t)"))
 
 if (overload(1, 1) != 20):
-    raise RuntimeError, ("overload(int t, const int &)")
+    raise RuntimeError(("overload(int t, const int &)"))
 
 if (overload(1, "hello") != 30):
-    raise RuntimeError, ("overload(int t, const char *)")
+    raise RuntimeError(("overload(int t, const char *)"))
 
 k = Klass()
 if (overload(k) != 10):
-    raise RuntimeError, ("overload(Klass t)")
+    raise RuntimeError(("overload(Klass t)"))
 
 if (overload(k, k) != 20):
-    raise RuntimeError, ("overload(Klass t, const Klass &)")
+    raise RuntimeError(("overload(Klass t, const Klass &)"))
 
 if (overload(k, "hello") != 30):
-    raise RuntimeError, ("overload(Klass t, const char *)")
+    raise RuntimeError(("overload(Klass t, const char *)"))
 
 if (overload(10.0, "hi") != 40):
-    raise RuntimeError, ("overload(double t, const char *)")
+    raise RuntimeError(("overload(double t, const char *)"))
 
 if (overload() != 50):
-    raise RuntimeError, ("overload(const char *)")
+    raise RuntimeError(("overload(const char *)"))
 
 
 # everything put in a namespace
 if (nsoverload("hi") != 1000):
-    raise RuntimeError, ("nsoverload()")
+    raise RuntimeError(("nsoverload()"))
 
 if (nsoverload(1) != 1010):
-    raise RuntimeError, ("nsoverload(int t)")
+    raise RuntimeError(("nsoverload(int t)"))
 
 if (nsoverload(1, 1) != 1020):
-    raise RuntimeError, ("nsoverload(int t, const int &)")
+    raise RuntimeError(("nsoverload(int t, const int &)"))
 
 if (nsoverload(1, "hello") != 1030):
-    raise RuntimeError, ("nsoverload(int t, const char *)")
+    raise RuntimeError(("nsoverload(int t, const char *)"))
 
 if (nsoverload(k) != 1010):
-    raise RuntimeError, ("nsoverload(Klass t)")
+    raise RuntimeError(("nsoverload(Klass t)"))
 
 if (nsoverload(k, k) != 1020):
-    raise RuntimeError, ("nsoverload(Klass t, const Klass &)")
+    raise RuntimeError(("nsoverload(Klass t, const Klass &)"))
 
 if (nsoverload(k, "hello") != 1030):
-    raise RuntimeError, ("nsoverload(Klass t, const char *)")
+    raise RuntimeError(("nsoverload(Klass t, const char *)"))
 
 if (nsoverload(10.0, "hi") != 1040):
-    raise RuntimeError, ("nsoverload(double t, const char *)")
+    raise RuntimeError(("nsoverload(double t, const char *)"))
 
 if (nsoverload() != 1050):
-    raise RuntimeError, ("nsoverload(const char *)")
+    raise RuntimeError(("nsoverload(const char *)"))
 
 
 A.foo(1)
diff --git a/Examples/test-suite/python/overload_template_runme.py b/Examples/test-suite/python/overload_template_runme.py
index 014ec71..8bd105a 100644
--- a/Examples/test-suite/python/overload_template_runme.py
+++ b/Examples/test-suite/python/overload_template_runme.py
@@ -6,74 +6,74 @@
 
 # mix 1
 if (mix1("hi") != 101):
-    raise RuntimeError, ("mix1(const char*)")
+    raise RuntimeError(("mix1(const char*)"))
 
 if (mix1(1.0, 1.0) != 102):
-    raise RuntimeError, ("mix1(double, const double &)")
+    raise RuntimeError(("mix1(double, const double &)"))
 
 if (mix1(1.0) != 103):
-    raise RuntimeError, ("mix1(double)")
+    raise RuntimeError(("mix1(double)"))
 
 # mix 2
 if (mix2("hi") != 101):
-    raise RuntimeError, ("mix2(const char*)")
+    raise RuntimeError(("mix2(const char*)"))
 
 if (mix2(1.0, 1.0) != 102):
-    raise RuntimeError, ("mix2(double, const double &)")
+    raise RuntimeError(("mix2(double, const double &)"))
 
 if (mix2(1.0) != 103):
-    raise RuntimeError, ("mix2(double)")
+    raise RuntimeError(("mix2(double)"))
 
 # mix 3
 if (mix3("hi") != 101):
-    raise RuntimeError, ("mix3(const char*)")
+    raise RuntimeError(("mix3(const char*)"))
 
 if (mix3(1.0, 1.0) != 102):
-    raise RuntimeError, ("mix3(double, const double &)")
+    raise RuntimeError(("mix3(double, const double &)"))
 
 if (mix3(1.0) != 103):
-    raise RuntimeError, ("mix3(double)")
+    raise RuntimeError(("mix3(double)"))
 
 # Combination 1
 if (overtparams1(100) != 10):
-    raise RuntimeError, ("overtparams1(int)")
+    raise RuntimeError(("overtparams1(int)"))
 
 if (overtparams1(100.0, 100) != 20):
-    raise RuntimeError, ("overtparams1(double, int)")
+    raise RuntimeError(("overtparams1(double, int)"))
 
 # Combination 2
 if (overtparams2(100.0, 100) != 40):
-    raise RuntimeError, ("overtparams2(double, int)")
+    raise RuntimeError(("overtparams2(double, int)"))
 
 # Combination 3
 if (overloaded() != 60):
-    raise RuntimeError, ("overloaded()")
+    raise RuntimeError(("overloaded()"))
 
 if (overloaded(100.0, 100) != 70):
-    raise RuntimeError, ("overloaded(double, int)")
+    raise RuntimeError(("overloaded(double, int)"))
 
 # Combination 4
 if (overloadedagain("hello") != 80):
-    raise RuntimeError, ("overloadedagain(const char *)")
+    raise RuntimeError(("overloadedagain(const char *)"))
 
 if (overloadedagain() != 90):
-    raise RuntimeError, ("overloadedagain(double)")
+    raise RuntimeError(("overloadedagain(double)"))
 
 # specializations
 if (specialization(10) != 202):
-    raise RuntimeError, ("specialization(int)")
+    raise RuntimeError(("specialization(int)"))
 
 if (specialization(10.0) != 203):
-    raise RuntimeError, ("specialization(double)")
+    raise RuntimeError(("specialization(double)"))
 
 if (specialization(10, 10) != 204):
-    raise RuntimeError, ("specialization(int, int)")
+    raise RuntimeError(("specialization(int, int)"))
 
 if (specialization(10.0, 10.0) != 205):
-    raise RuntimeError, ("specialization(double, double)")
+    raise RuntimeError(("specialization(double, double)"))
 
 if (specialization("hi", "hi") != 201):
-    raise RuntimeError, ("specialization(const char *, const char *)")
+    raise RuntimeError(("specialization(const char *, const char *)"))
 
 
 # simple specialization
@@ -83,63 +83,63 @@
 
 # a bit of everything
 if (overload("hi") != 0):
-    raise RuntimeError, ("overload()")
+    raise RuntimeError(("overload()"))
 
 if (overload(1) != 10):
-    raise RuntimeError, ("overload(int t)")
+    raise RuntimeError(("overload(int t)"))
 
 if (overload(1, 1) != 20):
-    raise RuntimeError, ("overload(int t, const int &)")
+    raise RuntimeError(("overload(int t, const int &)"))
 
 if (overload(1, "hello") != 30):
-    raise RuntimeError, ("overload(int t, const char *)")
+    raise RuntimeError(("overload(int t, const char *)"))
 
 k = Klass()
 if (overload(k) != 10):
-    raise RuntimeError, ("overload(Klass t)")
+    raise RuntimeError(("overload(Klass t)"))
 
 if (overload(k, k) != 20):
-    raise RuntimeError, ("overload(Klass t, const Klass &)")
+    raise RuntimeError(("overload(Klass t, const Klass &)"))
 
 if (overload(k, "hello") != 30):
-    raise RuntimeError, ("overload(Klass t, const char *)")
+    raise RuntimeError(("overload(Klass t, const char *)"))
 
 if (overload(10.0, "hi") != 40):
-    raise RuntimeError, ("overload(double t, const char *)")
+    raise RuntimeError(("overload(double t, const char *)"))
 
 if (overload() != 50):
-    raise RuntimeError, ("overload(const char *)")
+    raise RuntimeError(("overload(const char *)"))
 
 
 # everything put in a namespace
 if (nsoverload("hi") != 1000):
-    raise RuntimeError, ("nsoverload()")
+    raise RuntimeError(("nsoverload()"))
 
 if (nsoverload(1) != 1010):
-    raise RuntimeError, ("nsoverload(int t)")
+    raise RuntimeError(("nsoverload(int t)"))
 
 if (nsoverload(1, 1) != 1020):
-    raise RuntimeError, ("nsoverload(int t, const int &)")
+    raise RuntimeError(("nsoverload(int t, const int &)"))
 
 if (nsoverload(1, "hello") != 1030):
-    raise RuntimeError, ("nsoverload(int t, const char *)")
+    raise RuntimeError(("nsoverload(int t, const char *)"))
 
 if (nsoverload(k) != 1010):
-    raise RuntimeError, ("nsoverload(Klass t)")
+    raise RuntimeError(("nsoverload(Klass t)"))
 
 if (nsoverload(k, k) != 1020):
-    raise RuntimeError, ("nsoverload(Klass t, const Klass &)")
+    raise RuntimeError(("nsoverload(Klass t, const Klass &)"))
 
 if (nsoverload(k, "hello") != 1030):
-    raise RuntimeError, ("nsoverload(Klass t, const char *)")
+    raise RuntimeError(("nsoverload(Klass t, const char *)"))
 
 if (nsoverload(10.0, "hi") != 1040):
-    raise RuntimeError, ("nsoverload(double t, const char *)")
+    raise RuntimeError(("nsoverload(double t, const char *)"))
 
 if (nsoverload() != 1050):
-    raise RuntimeError, ("nsoverload(const char *)")
+    raise RuntimeError(("nsoverload(const char *)"))
 
 
-A_foo(1)
+A.foo(1)
 b = B()
 b.foo(1)
diff --git a/Examples/test-suite/python/pointer_reference_runme.py b/Examples/test-suite/python/pointer_reference_runme.py
index b9b4788..f126486 100644
--- a/Examples/test-suite/python/pointer_reference_runme.py
+++ b/Examples/test-suite/python/pointer_reference_runme.py
@@ -2,15 +2,15 @@
 
 s = pointer_reference.get()
 if s.value != 10:
-    raise RuntimeError, "get test failed"
+    raise RuntimeError("get test failed")
 
 ss = pointer_reference.Struct(20)
 pointer_reference.set(ss)
 if pointer_reference.cvar.Struct_instance.value != 20:
-    raise RuntimeError, "set test failed"
+    raise RuntimeError("set test failed")
 
 if pointer_reference.overloading(1) != 111:
-    raise RuntimeError, "overload test 1 failed"
+    raise RuntimeError("overload test 1 failed")
 
 if pointer_reference.overloading(ss) != 222:
-    raise RuntimeError, "overload test 2 failed"
+    raise RuntimeError("overload test 2 failed")
diff --git a/Examples/test-suite/python/preproc_cpp_runme.py b/Examples/test-suite/python/preproc_cpp_runme.py
new file mode 100644
index 0000000..8c3e212
--- /dev/null
+++ b/Examples/test-suite/python/preproc_cpp_runme.py
@@ -0,0 +1,4 @@
+import preproc_cpp
+
+t1 = preproc_cpp.tcxMessageTest()
+t2 = preproc_cpp.tcxMessageBug()
diff --git a/Examples/test-suite/python/preproc_defined_runme.py b/Examples/test-suite/python/preproc_defined_runme.py
index af46816..37441db 100644
--- a/Examples/test-suite/python/preproc_defined_runme.py
+++ b/Examples/test-suite/python/preproc_defined_runme.py
@@ -9,3 +9,12 @@
 preproc_defined.thing(10)
 preproc_defined.stuff(10)
 preproc_defined.bumpf(10)
+
+if preproc_defined.a != 2:
+    raise RuntimeError
+
+if preproc_defined.b != 42:
+    raise RuntimeError
+
+if preproc_defined.z != 8:
+    raise RuntimeError
diff --git a/Examples/test-suite/python/primitive_types_runme.py b/Examples/test-suite/python/primitive_types_runme.py
index 04588dd..e397c11 100644
--- a/Examples/test-suite/python/primitive_types_runme.py
+++ b/Examples/test-suite/python/primitive_types_runme.py
@@ -31,8 +31,7 @@
 
 
 def pyerror(name, val, cte):
-    print "bad val/cte", name, val, cte
-    raise RuntimeError
+    raise RuntimeError("bad val/cte {} {} {}".format(name, val, cte))
     pass
 
 if cvar.var_bool != cct_bool:
@@ -173,7 +172,7 @@
 
 # internal call check
 if t.c_check() != p.c_check():
-    raise RuntimeError, "bad director"
+    raise RuntimeError("bad director")
 
 p.var_bool = p.stc_bool
 p.var_schar = p.stc_schar
@@ -228,63 +227,57 @@
 
 # this value contains a '0' char!
 if def_namet != "hola":
-    print "bad namet", def_namet
-    raise RuntimeError
+    raise RuntimeError("bad namet {}".format(def_namet))
 
 t.var_namet = def_namet
 if t.var_namet != def_namet:
-    print "bad namet", t.var_namet, def_namet
-    raise RuntimeError
+    raise RuntimeError("bad namet {} {}".format(t.var_namet, def_namet))
 
 t.var_namet = "hola"
 
 if t.var_namet != "hola":
-    print "bad namet", t.var_namet
-    raise RuntimeError
+    raise RuntimeError("bad namet {}".format(t.var_namet))
 
 t.var_namet = "hol"
 
 if t.var_namet != "hol":
     # if t.var_namet != "hol\0\0":
-    print "bad namet", t.var_namet
-    raise RuntimeError
+    raise RuntimeError("bad namet {}".format(t.var_namet))
 
 
 cvar.var_char = "\0"
 if cvar.var_char != "\0":
-    raise RuntimeError, "bad char '0' case"
+    raise RuntimeError("bad char '0' case")
 
 cvar.var_char = 0
 if cvar.var_char != "\0":
-    raise RuntimeError, "bad char '0' case"
+    raise RuntimeError("bad char '0' case")
 
 cvar.var_namet = "\0"
 # if cvar.var_namet != "\0\0\0\0\0":
 if cvar.var_namet != "":
-    print "hola", "", cvar.var_namet
-    raise RuntimeError, "bad char '\0' case"
+    raise RuntimeError("bad char '\0' case hola {}".format(cvar.var_namet))
 
 cvar.var_namet = ""
 # if cvar.var_namet != "\0\0\0\0\0":
 if cvar.var_namet != "":
-    raise RuntimeError, "bad char empty case"
+    raise RuntimeError("bad char empty case")
 
 cvar.var_pchar = None
 if cvar.var_pchar != None:
-    raise RuntimeError, "bad None case"
+    raise RuntimeError("bad None case")
 
 cvar.var_pchar = ""
 if cvar.var_pchar != "":
-    print "%c" % (cvar.var_pchar[0],)
-    raise RuntimeError, "bad char empty case"
+    raise RuntimeError("bad char empty case %c" % (cvar.var_pchar[0],))
 
 cvar.var_pcharc = None
 if cvar.var_pcharc != None:
-    raise RuntimeError, "bad None case"
+    raise RuntimeError("bad None case")
 
 cvar.var_pcharc = ""
 if cvar.var_pcharc != "":
-    raise RuntimeError, "bad char empty case"
+    raise RuntimeError("bad char empty case")
 
 
 #
@@ -300,13 +293,12 @@
 
 cvar.var_pchar = pc
 if cvar.var_pchar != "hola":
-    print cvar.var_pchar
-    raise RuntimeError, "bad pointer case"
+    raise RuntimeError("bad pointer case {}".format(cvar.var_pchar))
 
 cvar.var_namet = pc
 # if cvar.var_namet != "hola\0":
 if cvar.var_namet != "hola":
-    raise RuntimeError, "bad pointer case"
+    raise RuntimeError("bad pointer case")
 
 delete_pchar(pc)
 
@@ -325,7 +317,7 @@
         error = 1
     pass
 if error:
-    raise RuntimeError, "bad uchar typemap"
+    raise RuntimeError("bad uchar typemap")
 
 
 try:
@@ -338,7 +330,7 @@
         error = 1
     pass
 if error:
-    raise RuntimeError, "bad char typemap"
+    raise RuntimeError("bad char typemap")
 
 try:
     error = 0
@@ -350,7 +342,7 @@
         error = 1
     pass
 if error:
-    raise RuntimeError, "bad ushort typemap"
+    raise RuntimeError("bad ushort typemap")
 
 try:
     error = 0
@@ -362,7 +354,7 @@
         error = 1
     pass
 if error:
-    raise RuntimeError, "bad uint typemap"
+    raise RuntimeError("bad uint typemap")
 
 try:
     error = 0
@@ -374,7 +366,7 @@
         error = 1
     pass
 if error:
-    raise RuntimeError, "bad sizet typemap"
+    raise RuntimeError("bad sizet typemap")
 
 try:
     error = 0
@@ -386,7 +378,7 @@
         error = 1
     pass
 if error:
-    raise RuntimeError, "bad ulong typemap"
+    raise RuntimeError("bad ulong typemap")
 
 #
 #
@@ -400,51 +392,48 @@
         error = 1
     pass
 if error:
-    raise RuntimeError, "bad namet typemap"
+    raise RuntimeError("bad namet typemap")
 
 #
 #
 #
 t2 = p.vtest(t)
 if t.var_namet != t2.var_namet:
-    raise RuntimeError, "bad SWIGTYPE* typemap"
+    raise RuntimeError("bad SWIGTYPE* typemap")
 
 
 if cvar.fixsize != "ho\0la\0\0\0":
-    raise RuntimeError, "bad FIXSIZE typemap"
+    raise RuntimeError("bad FIXSIZE typemap")
 
 cvar.fixsize = "ho"
 if cvar.fixsize != "ho\0\0\0\0\0\0":
-    raise RuntimeError, "bad FIXSIZE typemap"
+    raise RuntimeError("bad FIXSIZE typemap")
 
 
 f = Foo(3)
 f1 = fptr_val(f)
 f2 = fptr_ref(f)
 if f1._a != f2._a:
-    raise RuntimeError, "bad const ptr& typemap"
+    raise RuntimeError("bad const ptr& typemap")
 
 
 v = char_foo(1, 3)
 if v != 3:
-    raise RuntimeError, "bad int typemap"
+    raise RuntimeError("bad int typemap")
 
 s = char_foo(1, "hello")
 if s != "hello":
-    raise RuntimeError, "bad char* typemap"
+    raise RuntimeError("bad char* typemap")
 
 
 v = SetPos(1, 3)
 if v != 4:
-    raise RuntimeError, "bad int typemap"
+    raise RuntimeError("bad int typemap")
 
 #
 # Check the bounds for converting various types
 #
 
-# ctypes not available until 2.5
-if sys.version_info[0:2] <= (2, 4):
-    sys.exit(0)
 import ctypes
 
 # Get the minimum and maximum values that fit in signed char, short, int, long, and long long
@@ -481,7 +470,7 @@
 
 # Make sure Python 2's sys.maxint is the same as the maxlong we calculated
 if sys.version_info[0] <= 2 and maxlong != sys.maxint:
-    raise RuntimeError, "sys.maxint is not the maximum value of a signed long"
+    raise RuntimeError("sys.maxint is not the maximum value of a signed long")
 
 def checkType(t, e, val, delta):
     """t = Test object, e = type name (e.g. ulong), val = max or min allowed value, delta = +1 for max, -1 for min"""
@@ -511,7 +500,7 @@
     except OverflowError:
         pass
     if error:
-        raise RuntimeError, "bad " + e + " typemap"
+        raise RuntimeError("bad " + e + " typemap")
 
 def checkFull(t, e, maxval, minval):
     """Check the maximum and minimum bounds for the type given by e"""
@@ -543,17 +532,17 @@
     if val != prevval:
         # Make sure the most extreme value of this type gives the name of this type
         if t.ovr_str(val) != name:
-            raise RuntimeError, "bad " + name + " typemap"
+            raise RuntimeError("bad " + name + " typemap")
         # Make sure a more extreme value doesn't give the name of this type
         try:
             if t.ovr_str(val + delta) == name:
-                raise RuntimeError, "bad " + name + " typemap"
+                raise RuntimeError("bad " + name + " typemap")
             if val == limit:
                 # Should raise TypeError here since this is the largest integral type
-                raise RuntimeError, "bad " + name + " typemap"
+                raise RuntimeError("bad " + name + " typemap")
         except TypeError:
             if val != limit:
-                raise RuntimeError, "bad " + name + " typemap"
+                raise RuntimeError("bad " + name + " typemap")
 
 # Check that overloading works: uchar > schar > ushort > short > uint > int > ulong > long > ullong > llong
 checkOverload(t, "uchar",  maxuchar,  +1, 0,         maxullong)
@@ -568,22 +557,22 @@
 checkOverload(t, "llong",  minllong,  -1, minlong,   minllong)
 
 # Make sure that large ints can be converted to doubles properly
-if val_double(sys.maxint + 1) != float(sys.maxint + 1):
-    raise RuntimeError, "bad double typemap"
-if val_double(-sys.maxint - 2) != float(-sys.maxint - 2):
-    raise RuntimeError, "bad double typemap"
+if val_double(sys.maxsize + 1) != float(sys.maxsize + 1):
+    raise RuntimeError("bad double typemap")
+if val_double(-sys.maxsize - 2) != float(-sys.maxsize - 2):
+    raise RuntimeError("bad double typemap")
 
 
 # Check the minimum and maximum values that fit in ptrdiff_t and size_t
 def checkType(name, maxfunc, maxval, minfunc, minval, echofunc):
     if maxfunc() != maxval:
-        raise RuntimeError, "bad " + name + " typemap"
+        raise RuntimeError("bad " + name + " typemap")
     if minfunc() != minval:
-        raise RuntimeError, "bad " + name + " typemap"
+        raise RuntimeError("bad " + name + " typemap")
     if echofunc(maxval) != maxval:
-        raise RuntimeError, "bad " + name + " typemap"
+        raise RuntimeError("bad " + name + " typemap")
     if echofunc(minval) != minval:
-        raise RuntimeError, "bad " + name + " typemap"
+        raise RuntimeError("bad " + name + " typemap")
     error = 0
     try:
         echofunc(maxval + 1)
@@ -591,16 +580,15 @@
     except OverflowError:
         pass
     if error == 1:
-        raise RuntimeError, "bad " + name + " typemap"
+        raise RuntimeError("bad " + name + " typemap")
     try:
         echofunc(minval - 1)
         error = 1
     except OverflowError:
         pass
     if error == 1:
-        raise RuntimeError, "bad " + name + " typemap"
+        raise RuntimeError("bad " + name + " typemap")
 
 # sys.maxsize is the largest value supported by Py_ssize_t, which should be the same as ptrdiff_t
-if sys.version_info[0:2] >= (2, 6):
-    checkType("ptrdiff_t", get_ptrdiff_max, sys.maxsize,           get_ptrdiff_min, -(sys.maxsize + 1), ptrdiff_echo)
-    checkType("size_t",    get_size_max,    (2 * sys.maxsize) + 1, get_size_min,    0,                  size_echo)
+checkType("ptrdiff_t", get_ptrdiff_max, sys.maxsize,           get_ptrdiff_min, -(sys.maxsize + 1), ptrdiff_echo)
+checkType("size_t",    get_size_max,    (2 * sys.maxsize) + 1, get_size_min,    0,                  size_echo)
diff --git a/Examples/test-suite/python/python_abstractbase_runme.py b/Examples/test-suite/python/python_abstractbase_runme.py
new file mode 100644
index 0000000..0790c5c
--- /dev/null
+++ b/Examples/test-suite/python/python_abstractbase_runme.py
@@ -0,0 +1,40 @@
+import sys
+
+# collections.abc requires Python 3.3+
+
+from python_abstractbase import *
+if sys.version_info[0:2] >= (3, 3):
+    import collections.abc
+else:
+    import collections
+
+# This is expected to fail with -builtin option
+# Builtin types can't inherit from pure-python abstract bases
+if is_python_builtin():
+    exit(0)
+
+def check_issubclass(derived, base):
+    if not issubclass(derived, base):
+        raise RuntimeError("{} is not a subclass of {}".format(derived, base))
+
+if sys.version_info[0:2] >= (3, 3):
+    check_issubclass(Mapii, collections.abc.MutableMapping)
+    check_issubclass(Multimapii, collections.abc.MutableMapping)
+    check_issubclass(IntSet, collections.abc.MutableSet)
+    check_issubclass(IntMultiset, collections.abc.MutableSet)
+    check_issubclass(IntVector, collections.abc.MutableSequence)
+    check_issubclass(IntList, collections.abc.MutableSequence)
+else:
+    check_issubclass(Mapii, collections.MutableMapping)
+    check_issubclass(Multimapii, collections.MutableMapping)
+    check_issubclass(IntSet, collections.MutableSet)
+    check_issubclass(IntMultiset, collections.MutableSet)
+    check_issubclass(IntVector, collections.MutableSequence)
+    check_issubclass(IntList, collections.MutableSequence)
+
+mapii = Mapii()
+multimapii = Multimapii()
+intset = IntSet()
+intmultiset = IntMultiset()
+intvector = IntVector()
+intlist = IntList()
diff --git a/Examples/test-suite/python/python_abstractbase_runme3.py b/Examples/test-suite/python/python_abstractbase_runme3.py
deleted file mode 100644
index 9f99dcb..0000000
--- a/Examples/test-suite/python/python_abstractbase_runme3.py
+++ /dev/null
@@ -1,35 +0,0 @@
-import sys
-
-# collections.abc requires Python 3.3+
-if sys.version_info[0:2] < (3, 3):
-    exit(0)
-
-from python_abstractbase import *
-import collections.abc
-
-# This is expected to fail with -builtin option
-# Builtin types can't inherit from pure-python abstract bases
-if is_python_builtin():
-    exit(0)
-
-# Python abc is only turned on when -py3 option is passed to SWIG
-if not is_swig_py3:
-    exit(0)
-
-def check_issubclass(derived, base):
-    if not issubclass(derived, base):
-        raise RuntimeError("{} is not a subclass of {}".format(derived, base))
-
-check_issubclass(Mapii, collections.abc.MutableMapping)
-check_issubclass(Multimapii, collections.abc.MutableMapping)
-check_issubclass(IntSet, collections.abc.MutableSet)
-check_issubclass(IntMultiset, collections.abc.MutableSet)
-check_issubclass(IntVector, collections.abc.MutableSequence)
-check_issubclass(IntList, collections.abc.MutableSequence)
-
-mapii = Mapii()
-multimapii = Multimapii()
-intset = IntSet()
-intmultiset = IntMultiset()
-intvector = IntVector()
-intlist = IntList()
diff --git a/Examples/test-suite/python/python_annotations_c_runme.py b/Examples/test-suite/python/python_annotations_c_runme.py
new file mode 100644
index 0000000..3110d8f
--- /dev/null
+++ b/Examples/test-suite/python/python_annotations_c_runme.py
@@ -0,0 +1,31 @@
+import sys
+
+if sys.version_info[0:2] >= (3, 2):
+    from python_annotations_c import *
+
+    # No __annotations__ support with -builtin or -fastproxy
+    annotations_supported = not(is_python_builtin() or is_python_fastproxy())
+
+    if annotations_supported:
+        anno = MakeShort.__annotations__
+        if anno != {'x': 'int', 'return': 'Space::Template< short >'}:
+            raise RuntimeError("annotations mismatch: {}".format(anno))
+
+        anno = global_ints.__annotations__
+        if anno != {'ri': 'int &', 't': 'TemplateShort', 'return': 'int *'}:
+            raise RuntimeError("annotations mismatch: {}".format(anno))
+
+        ts = MakeShort(10)
+
+        anno = MakeShort.__annotations__
+        if anno != {'x': 'int', 'return': 'Space::Template< short >'}:
+            raise RuntimeError("annotations mismatch: {}".format(anno))
+
+        anno = ts.mymethod.__annotations__
+        if anno != {'arg2': 'int', 'tt': 'TemplateShort', 'return': 'void'}:
+            raise RuntimeError("annotations mismatch: {}".format(anno))
+
+        # No annotations
+        anno = no_annotations.__annotations__
+        if anno != {}:
+            raise RuntimeError("annotations mismatch: {}".format(anno))
diff --git a/Examples/test-suite/python/python_annotations_variable_c_runme.py b/Examples/test-suite/python/python_annotations_variable_c_runme.py
new file mode 100644
index 0000000..153852d
--- /dev/null
+++ b/Examples/test-suite/python/python_annotations_variable_c_runme.py
@@ -0,0 +1,24 @@
+import sys
+
+# Variable annotations for properties is only supported in python-3.6 and later (PEP 526)
+if sys.version_info[0:2] >= (3, 6):
+    from python_annotations_variable_c import *
+
+    # No SWIG __annotations__ support with -builtin or -fastproxy
+    annotations_supported = not(is_python_builtin() or is_python_fastproxy())
+
+    if annotations_supported:
+        ts = TemplateShort()
+        anno = ts.__annotations__
+        if anno != {'member_variable': 'int'}:
+            raise RuntimeError("annotations mismatch: {}".format(anno))
+
+        ts = StructWithVar()
+        anno = ts.__annotations__
+        if anno != {'member_variable': 'int'}:
+            raise RuntimeError("annotations mismatch: {}".format(anno))
+
+        ts = StructWithVarNotAnnotated()
+        if getattr(ts, "__annotations__", None) != None:
+            anno = ts.__annotations__
+            raise RuntimeError("annotations mismatch: {}".format(anno))
diff --git a/Examples/test-suite/python/python_append_runme.py b/Examples/test-suite/python/python_append_runme.py
index eddda53..e5f6b07 100644
--- a/Examples/test-suite/python/python_append_runme.py
+++ b/Examples/test-suite/python/python_append_runme.py
@@ -21,3 +21,16 @@
 Test.static_func()
 if grabstaticpath() != os.path.basename(mypath):
     raise RuntimeError("grabstaticpath failed")
+
+# slots test
+fs = ForSlots()
+if fs.ValidVariable != 99:
+    raise RuntimeError("ValidVariable failed")
+fs.ValidVariable = 11
+if fs.ValidVariable != 11:
+    raise RuntimeError("ValidVariable failed")
+try:
+    fs.Invalid = 22
+    raise RuntimeError("It should not be possible to set a random variable name")
+except AttributeError:
+    pass
diff --git a/Examples/test-suite/python/python_builtin_runme.py b/Examples/test-suite/python/python_builtin_runme.py
index 26e757c..5476c45 100644
--- a/Examples/test-suite/python/python_builtin_runme.py
+++ b/Examples/test-suite/python/python_builtin_runme.py
@@ -32,7 +32,7 @@
   passed = False
   try:
     h = hash(ExceptionHashFunction())
-  except RuntimeError, e:
+  except RuntimeError as e:
     passed = str(e).find("oops") != -1
     pass
 
@@ -111,3 +111,26 @@
 z = pow(x, y, z)
 if z.Value() != 7:
   raise RuntimeError("pow(x, y, z) wrong")
+
+# Test 8 https://github.com/swig/swig/pull/2771 __setitem__ for deleting item, uses C NULL
+def check_gsi(gsi, idx, value, args_count, kw_count):
+  if gsi.idx != idx:
+    raise RuntimeError("idx wrong {}".format(idx))
+  if gsi.value != value:
+    raise RuntimeError("value wrong {}".format(value))
+  if gsi.args_count != args_count:
+    raise RuntimeError("args_count wrong {}".format(args_count))
+  if gsi.kw_count != kw_count:
+    raise RuntimeError("kw_count wrong {}".format(kw_count))
+  gsi.reset()
+
+if is_python_builtin():
+  gsi = GetSetItem()
+  gsi[0] = 111
+  check_gsi(gsi, 0, 111, -100, -100)
+  del gsi[0]
+  check_gsi(gsi, 0, -11, -100, -100)
+  gsi(222, fred = 333, jack = 444)
+  check_gsi(gsi, -100, -100, 1, 2)
+  gsi(333)
+  check_gsi(gsi, -100, -100, 1, -11)
diff --git a/Examples/test-suite/python/python_destructor_exception_runme.py b/Examples/test-suite/python/python_destructor_exception_runme.py
index ee71ab3..4765953 100644
--- a/Examples/test-suite/python/python_destructor_exception_runme.py
+++ b/Examples/test-suite/python/python_destructor_exception_runme.py
@@ -1,7 +1,11 @@
 import python_destructor_exception
-from StringIO import StringIO
 import sys
 
+if sys.version_info[0:2] < (3, 0):
+    import StringIO as io
+else:
+    import io
+
 def error_function():
     python_destructor_exception.ClassWithThrowingDestructor().GetBlah()
 
@@ -9,13 +13,13 @@
     attributeErrorOccurred = False
     try:
         error_function()
-    except AttributeError, e:
+    except AttributeError:
         attributeErrorOccurred = True
     return attributeErrorOccurred
 
 def test1():
     stderr_saved = sys.stderr
-    buffer = StringIO()
+    buffer = io.StringIO()
     attributeErrorOccurred = False
     try:
         # Suppress stderr while making this call to suppress the output shown by PyErr_WriteUnraisable
diff --git a/Examples/test-suite/python/python_flatstaticmethod_runme.py b/Examples/test-suite/python/python_flatstaticmethod_runme.py
new file mode 100644
index 0000000..13d935f
--- /dev/null
+++ b/Examples/test-suite/python/python_flatstaticmethod_runme.py
@@ -0,0 +1,92 @@
+from python_flatstaticmethod import *
+import inspect
+
+# This testcase tests C++ class static functions when using legacy "flattened"
+# staticmethod access, A_bar, as well as the normal staticmethod access, A.bar.
+
+
+def check(got, expected):
+    if got != expected:
+        raise RuntimeError("\ngot :{}\nwant:{}\n".format(got, expected))
+
+if A_bar(2) != 4:
+    raise RuntimeError
+
+if A.bar(2) != 4:
+    raise RuntimeError
+
+# %callback
+if foobar(3, A_bar) != A_bar(3):
+    raise RuntimeError
+
+if foobar(3, A.bar) != A_bar(3):
+    raise RuntimeError
+
+# kwargs
+if A_pub() != 1:
+    raise RuntimeError
+
+if A_pub(b=2) != 3:
+    raise RuntimeError
+
+if A_pub(b=10,a=20) != 30:
+    raise RuntimeError
+
+if A.pub() != 1:
+    raise RuntimeError
+
+if A.pub(b=2) != 3:
+    raise RuntimeError
+
+if A.pub(b=10,a=20) != 30:
+    raise RuntimeError
+
+check(inspect.getdoc(A_func0static),
+    "A_func0static(e, arg2, hello, f=2) -> int")
+check(inspect.getdoc(A_func1static),
+    "A_func1static(A e, short arg2, Tuple hello, double f=2) -> int")
+
+# overloaded static functions
+if A_over(3) != "over:int":
+    raise RuntimeError("A::over(int)")
+
+if A_over(3.0) != "over:double":
+    raise RuntimeError("A::over(double)")
+
+if A_over("hello") != "over:char *":
+    raise RuntimeError("A::over(char *)")
+
+if A.over(3) != "over:int":
+    raise RuntimeError("A::over(int)")
+
+if A.over(3.0) != "over:double":
+    raise RuntimeError("A::over(double)")
+
+if A.over("hello") != "over:char *":
+    raise RuntimeError("A::over(char *)")
+
+# default args
+if A_defargs() != 30:
+    raise RuntimeError
+
+if A_defargs(1) != 21:
+    raise RuntimeError
+
+if A_defargs(1, 2) != 3:
+    raise RuntimeError
+
+if A.defargs() != 30:
+    raise RuntimeError
+
+if A.defargs(1) != 21:
+    raise RuntimeError
+
+if A.defargs(1, 2) != 3:
+    raise RuntimeError
+
+# %extend
+if A_staticextended(11) != 11:
+    raise RuntimeError
+
+if A.staticextended(11) != 11:
+    raise RuntimeError
diff --git a/Examples/test-suite/python/python_nondynamic_runme.py b/Examples/test-suite/python/python_nondynamic_runme.py
index fbb60ad..870c70b 100644
--- a/Examples/test-suite/python/python_nondynamic_runme.py
+++ b/Examples/test-suite/python/python_nondynamic_runme.py
@@ -1,9 +1,5 @@
 import python_nondynamic
 
-def is_python_modern():
-    """Return True if SWIG is generating Python code using -modern. Works only if %python_nondynamic has been used."""
-    return hasattr(python_nondynamic, "_swig_setattr_nondynamic_class_variable")
-
 def debug_print(s):
     show_debug = False
     if show_debug:
@@ -51,9 +47,7 @@
 
 try:
     bb.c = 3
-    print("bb.c = {}".format(bb.c))
-    print("B.c = {}".format(B.c))
-    raise RuntimeError("B.c class variable messes up nondynamic-ness of B")
+    raise RuntimeError("B.c class variable messes up nondynamic-ness of B bb.c={} B.c={}".format(bb.c, B.c))
 except AttributeError as e:
     debug_print(e)
     pass
@@ -68,7 +62,7 @@
 cc = python_nondynamic.C()
 cc.d = 3
 
-# An inconsistency between builtin and (non-builtin/modern).
+# An inconsistency between builtin and non-builtin.
 # Class variables cannot be set on builtin types, like other Python builtins, eg list.classvar=111 fails
 if python_nondynamic.is_python_builtin():
     try:
@@ -80,8 +74,8 @@
 else:
     python_nondynamic.C.classvar = 111
 
-if is_python_modern() and not python_nondynamic.is_python_builtin():
-    # Not working with builtin or non-modern :(
+if not python_nondynamic.is_python_builtin():
+    # Not working with builtin :(
     try:
         B.a = 10
         raise RuntimeError("B should not allow adding a class variable by setting it as an instance variable")
@@ -99,9 +93,7 @@
 if not python_nondynamic.is_python_builtin():
     try:
         bb.cc = 3
-        print("bb.cc = {}".format(bb.cc))
-        print("B.cc = {}".format(B.cc))
-        raise RuntimeError("B.cc class variable messes up nondynamic-ness of B")
+        raise RuntimeError("B.cc class variable messes up nondynamic-ness of B bb.cc={} B.cc={}".format(bb.cc, B.cc))
     except AttributeError as e:
         debug_print(e)
         pass
diff --git a/Examples/test-suite/python/python_overload_simple_cast_runme.py b/Examples/test-suite/python/python_overload_simple_cast_runme.py
index d4cb8a3..e40a34a 100644
--- a/Examples/test-suite/python/python_overload_simple_cast_runme.py
+++ b/Examples/test-suite/python/python_overload_simple_cast_runme.py
@@ -1,5 +1,6 @@
 from python_overload_simple_cast import *
 
+import sys
 
 class Ai:
 
@@ -9,6 +10,8 @@
     def __int__(self):
         return self.x
 
+    def __index__(self):
+        return self.x
 
 class Ad:
 
@@ -30,166 +33,264 @@
     good = 1
 
 if not good:
-    raise RuntimeError, "fint(int)"
+    raise RuntimeError("fint(int)")
 
 
 if fint(ad) != "fint:int":
-    raise RuntimeError, "fint(int)"
+    raise RuntimeError("fint(int)")
 
 if fdouble(ad) != "fdouble:double":
-    raise RuntimeError, "fdouble(double)"
+    raise RuntimeError("fdouble(double)")
 
 if fint(ai) != "fint:int":
-    raise RuntimeError, "fint(int)"
+    raise RuntimeError("fint(int)")
 
 if fint(5.0) != "fint:int":
-    raise RuntimeError, "fint(int)"
+    raise RuntimeError("fint(int)")
 
 if fint(3) != "fint:int":
-    raise RuntimeError, "fint(int)"
+    raise RuntimeError("fint(int)")
 if fint(3.0) != "fint:int":
-    raise RuntimeError, "fint(int)"
+    raise RuntimeError("fint(int)")
 
 if fdouble(ad) != "fdouble:double":
-    raise RuntimeError, "fdouble(double)"
+    raise RuntimeError("fdouble(double)")
 if fdouble(3) != "fdouble:double":
-    raise RuntimeError, "fdouble(double)"
+    raise RuntimeError("fdouble(double)")
 if fdouble(3.0) != "fdouble:double":
-    raise RuntimeError, "fdouble(double)"
+    raise RuntimeError("fdouble(double)")
 
 if fid(3, 3.0) != "fid:intdouble":
-    raise RuntimeError, "fid:intdouble"
+    raise RuntimeError("fid:intdouble")
 
 if fid(3.0, 3) != "fid:doubleint":
-    raise RuntimeError, "fid:doubleint"
+    raise RuntimeError("fid:doubleint")
 
 if fid(ad, ai) != "fid:doubleint":
-    raise RuntimeError, "fid:doubleint"
+    raise RuntimeError("fid:doubleint")
 
 if fid(ai, ad) != "fid:intdouble":
-    raise RuntimeError, "fid:intdouble"
+    raise RuntimeError("fid:intdouble")
 
 
 if foo(3) != "foo:int":
-    raise RuntimeError, "foo(int)"
+    raise RuntimeError("foo(int)")
 
 if foo(3.0) != "foo:double":
-    raise RuntimeError, "foo(double)"
+    raise RuntimeError("foo(double)")
 
 if foo("hello") != "foo:char *":
-    raise RuntimeError, "foo(char *)"
+    raise RuntimeError("foo(char *)")
 
 f = Foo()
 b = Bar()
 
 if foo(f) != "foo:Foo *":
-    raise RuntimeError, "foo(Foo *)"
+    raise RuntimeError("foo(Foo *)")
 
 if foo(b) != "foo:Bar *":
-    raise RuntimeError, "foo(Bar *)"
+    raise RuntimeError("foo(Bar *)")
 
 v = malloc_void(32)
 
 if foo(v) != "foo:void *":
-    raise RuntimeError, "foo(void *)"
+    raise RuntimeError("foo(void *)")
 
 s = Spam()
 
 if s.foo(3) != "foo:int":
-    raise RuntimeError, "Spam::foo(int)"
+    raise RuntimeError("Spam::foo(int)")
 
 if s.foo(3.0) != "foo:double":
-    raise RuntimeError, "Spam::foo(double)"
+    raise RuntimeError("Spam::foo(double)")
 
 if s.foo("hello") != "foo:char *":
-    raise RuntimeError, "Spam::foo(char *)"
+    raise RuntimeError("Spam::foo(char *)")
 
 if s.foo(f) != "foo:Foo *":
-    raise RuntimeError, "Spam::foo(Foo *)"
+    raise RuntimeError("Spam::foo(Foo *)")
 
 if s.foo(b) != "foo:Bar *":
-    raise RuntimeError, "Spam::foo(Bar *)"
+    raise RuntimeError("Spam::foo(Bar *)")
 
 if s.foo(v) != "foo:void *":
-    raise RuntimeError, "Spam::foo(void *)"
+    raise RuntimeError("Spam::foo(void *)")
 
-if Spam_bar(3) != "bar:int":
-    raise RuntimeError, "Spam::bar(int)"
+if Spam.bar(3) != "bar:int":
+    raise RuntimeError("Spam::bar(int)")
 
-if Spam_bar(3.0) != "bar:double":
-    raise RuntimeError, "Spam::bar(double)"
+if Spam.bar(3.0) != "bar:double":
+    raise RuntimeError("Spam::bar(double)")
 
-if Spam_bar("hello") != "bar:char *":
-    raise RuntimeError, "Spam::bar(char *)"
+if Spam.bar("hello") != "bar:char *":
+    raise RuntimeError("Spam::bar(char *)")
 
-if Spam_bar(f) != "bar:Foo *":
-    raise RuntimeError, "Spam::bar(Foo *)"
+if Spam.bar(f) != "bar:Foo *":
+    raise RuntimeError("Spam::bar(Foo *)")
 
-if Spam_bar(b) != "bar:Bar *":
-    raise RuntimeError, "Spam::bar(Bar *)"
+if Spam.bar(b) != "bar:Bar *":
+    raise RuntimeError("Spam::bar(Bar *)")
 
-if Spam_bar(v) != "bar:void *":
-    raise RuntimeError, "Spam::bar(void *)"
+if Spam.bar(v) != "bar:void *":
+    raise RuntimeError("Spam::bar(void *)")
 
 # Test constructors
 
 s = Spam()
 if s.type != "none":
-    raise RuntimeError, "Spam()"
+    raise RuntimeError("Spam()")
 
 s = Spam(3)
 if s.type != "int":
-    raise RuntimeError, "Spam(int)"
+    raise RuntimeError("Spam(int)")
 
 s = Spam(3.4)
 if s.type != "double":
-    raise RuntimeError, "Spam(double)"
+    raise RuntimeError("Spam(double)")
 
 s = Spam("hello")
 if s.type != "char *":
-    raise RuntimeError, "Spam(char *)"
+    raise RuntimeError("Spam(char *)")
 
 s = Spam(f)
 if s.type != "Foo *":
-    raise RuntimeError, "Spam(Foo *)"
+    raise RuntimeError("Spam(Foo *)")
 
 s = Spam(b)
 if s.type != "Bar *":
-    raise RuntimeError, "Spam(Bar *)"
+    raise RuntimeError("Spam(Bar *)")
 
 s = Spam(v)
 if s.type != "void *":
-    raise RuntimeError, "Spam(void *)"
+    raise RuntimeError("Spam(void *)")
 
 
+# nextafter: ++ and -- operators for float, off by one LSB
+# nextafter was released in Python 3.9
+if sys.version_info[0:2] >= (3, 9):
+    from math import inf, nextafter
+else:
+    # workaround: try to load nextafter from numpy if available
+    try:
+        # Skip numpy workaround for consistency in testing
+        if True:
+            raise RuntimeError("skip test")
+        from numpy import nextafter
+    except:
+        # else just disable this tests
+        def nextafter(x, y):
+            return None
+
+    # math.inf was added in Python 3.5
+    inf = float('inf')
+
+def exceptMatch(fun, arg, res, msg):
+    if arg is None or res is None:
+        # nextafter is missing, so skipping this test
+        return
+    if fun(arg) != res:
+        raise RuntimeError(msg)
+
+def exceptTypeError(fun, arg, msg):
+    if arg is None:
+        # nextafter is missing, so skipping this test
+        return
+    try:
+        fun(arg)
+        raise RuntimeError(msg)
+    except TypeError:
+        pass
+
+# x86_64: long is 32bit on MSVC but 64bit on *nix
+if not(sizeof_long() in [4, 8]):
+    raise RuntimeError("Unexpected size for long")
+
+# unsigned long
+ulmax = 2**32 - 1
+ulmin = 0
+ulmaxd = float(2**32 - 1)
+ulmind = 0.0
+if sizeof_long() == 8:
+    ulmax = 2**64 - 1
+    ulmaxd = nextafter(float(2**64), 0.0)
+
+exceptMatch(as_ul, ulmin, ulmin, "as_ul(ulmin)")
+exceptMatch(as_ul, ulmax, ulmax, "as_ul(ulmax)")
+exceptMatch(as_ul, ulmind, ulmind, "as_ul(ulmind)")
+exceptMatch(as_ul, ulmaxd, ulmaxd, "as_ul(ulmaxd)")
+
+exceptTypeError(as_ul, ulmin - 1, "as_ul(ulmin - 1)")
+exceptTypeError(as_ul, ulmax + 1, "as_ul(ulmax + 1)")
+exceptTypeError(as_ul, nextafter(ulmind, -inf), "as_ul(ulmind - LSB)")
+exceptTypeError(as_ul, nextafter(ulmaxd, inf), "as_ul(ulmaxd + LSB)")
+
+# long
+lmax = 2**31 - 1
+lmin = -2**31
+lmaxd = float(2**31 - 1)
+lmind = float(-2**31)
+lmaxd_v = lmaxd # expected value after the cast
+lmind_v = lmind
+if sys.version_info[0:2] < (3, 10):
+    # PyLong_AsLong(float) truncated the input before 3.10
+    lmaxd = nextafter(float(2**31), 0.0)
+    lmind = nextafter(float(-2**31 - 1), 0.0)
+    lmaxd_v = float(2**31 - 1)
+    lmind_v = float(-2**31)
+if sizeof_long() == 8:
+    lmax = 2**63 - 1
+    lmin = -2**63
+    lmaxd = nextafter(float(2**63), 0.0)
+    lmind = float(-2**63)
+    lmaxd_v = lmaxd
+    lmind_v = lmind
+
+exceptMatch(as_l, lmin, lmin, "as_l(lmin)")
+exceptMatch(as_l, lmax, lmax, "as_l(lmax)")
+exceptMatch(as_l, lmind, lmind_v, "as_l(lmind)")
+exceptMatch(as_l, lmaxd, lmaxd_v, "as_l(lmaxd)")
+
+exceptTypeError(as_l, lmin - 1, "as_l(lmin - 1)")
+exceptTypeError(as_l, lmax + 1, "as_l(lmax + 1)")
+exceptTypeError(as_l, nextafter(lmind, -inf), "as_l(lmind - LSB)")
+exceptTypeError(as_l, nextafter(lmaxd, inf), "as_l(lmaxd + LSB)")
+
 # unsigned long long
-ullmax = 9223372036854775807  # 0xffffffffffffffff
-ullmaxd = 9007199254740992.0
+ullmax = 2**64 - 1
 ullmin = 0
+ullmaxd = float(2**53) # 64 bit double significand
 ullmind = 0.0
-if ull(ullmin) != ullmin:
-    raise RuntimeError, "ull(ullmin)"
-if ull(ullmax) != ullmax:
-    raise RuntimeError, "ull(ullmax)"
-if ull(ullmind) != ullmind:
-    raise RuntimeError, "ull(ullmind)"
-if ull(ullmaxd) != ullmaxd:
-    raise RuntimeError, "ull(ullmaxd)"
+if sizeof_long() == 8:
+    ullmaxd = nextafter(float(2**64), 0.0)
+
+exceptMatch(as_ull, ullmin, ullmin, "as_ull(ullmin)")
+exceptMatch(as_ull, ullmax, ullmax, "as_ull(ullmax)")
+exceptMatch(as_ull, ullmind, ullmind, "as_ull(ullmind)")
+exceptMatch(as_ull, ullmaxd, ullmaxd, "as_ull(ullmaxd)")
+
+exceptTypeError(as_ull, ullmin - 1, "as_ull(ullmin - 1)")
+exceptTypeError(as_ull, ullmax + 1, "as_ull(ullmax + 1)")
+exceptTypeError(as_ull, nextafter(ullmind, -inf), "as_ull(ullmind - LSB)")
+exceptTypeError(as_ull, nextafter(ullmaxd, inf), "as_ull(ullmaxd + LSB)")
 
 # long long
-llmax = 9223372036854775807  # 0x7fffffffffffffff
-llmin = -9223372036854775808
-# these are near the largest  floats we can still convert into long long
-llmaxd = 9007199254740992.0
-llmind = -9007199254740992.0
-if ll(llmin) != llmin:
-    raise RuntimeError, "ll(llmin)"
-if ll(llmax) != llmax:
-    raise RuntimeError, "ll(llmax)"
-if ll(llmind) != llmind:
-    raise RuntimeError, "ll(llmind)"
-if ll(llmaxd) != llmaxd:
-    raise RuntimeError, "ll(llmaxd)"
+llmax = 2**63 - 1
+llmin = -2**63
+llmaxd = float(2**53) # 64 bit double significand
+llmind = float(-2**53)
+if sizeof_long() == 8:
+    llmaxd = nextafter(float(2**63), 0.0)
+    llmind = float(-2**63)
+
+exceptMatch(as_ll, llmin, llmin, "as_ll(llmin)")
+exceptMatch(as_ll, llmax, llmax, "as_ll(llmax)")
+exceptMatch(as_ll, llmind, llmind, "as_ll(llmind)")
+exceptMatch(as_ll, llmaxd, llmaxd, "as_ll(llmaxd)")
+
+exceptTypeError(as_ll, llmin - 1, "as_ll(llmin - 1)")
+exceptTypeError(as_ll, llmax + 1, "as_ll(llmax + 1)")
+exceptTypeError(as_ll, nextafter(llmind, -inf), "as_ll(llmind - LSB)")
+exceptTypeError(as_ll, nextafter(llmaxd, inf), "as_ll(llmaxd + LSB)")
 
 
 free_void(v)
diff --git a/Examples/test-suite/python/python_pickle_runme.py b/Examples/test-suite/python/python_pickle_runme.py
index 27c67ae..7cb07ef 100644
--- a/Examples/test-suite/python/python_pickle_runme.py
+++ b/Examples/test-suite/python/python_pickle_runme.py
@@ -8,22 +8,22 @@
     if msg != "hi there":
         raise RuntimeError("Bad, got: " + msg)
 
-python_pickle.cvar.debug = False
+python_pickle.cvar.trace = False
 
 p = python_pickle.PickleMe("hi there")
 check(p)
 
 r = p.__reduce__()
-if python_pickle.cvar.debug:
-    print "__reduce__ returned:", r
+if python_pickle.cvar.trace:
+    print("__reduce__ returned: {}".format(r))
 pickle_string = pickle.dumps(p)
 newp = pickle.loads(pickle_string)
 check(newp)
 
 # Not yet working... some crash and others are not producing a sensible "can't be pickled" error
 #nfp = python_pickle.NotForPickling("no no")
-#print nfp.__reduce__()
+#print("{}".format(nfp.__reduce__()))
 #pickle_string = pickle.dumps(nfp)
-#print pickle_string
+#print("{}".format(pickle_string))
 #newp = pickle.loads(pickle_string)
-#print newp.msg
+#print("{}".format(newp.msg))
diff --git a/Examples/test-suite/python/python_pybuffer_runme.py b/Examples/test-suite/python/python_pybuffer_runme.py
index 8ecdb52..6507920 100644
--- a/Examples/test-suite/python/python_pybuffer_runme.py
+++ b/Examples/test-suite/python/python_pybuffer_runme.py
@@ -17,13 +17,13 @@
     a = bytearray(b"hello world")
     for i in range(k):
         python_pybuffer.title1(a)
-    print "Time used by bytearray:", time.time() - t
+    print("Time used by bytearray: {}".format(time.time() - t))
 
     t = time.time()
     b = "hello world"
     for i in range(k):
         python_pybuffer.title2(b)
-    print "Time used by string:", time.time() - t
+    print("Time used by string: {}".format(time.time() - t))
 else:
     # run the test case
     buf1 = bytearray(10)
@@ -44,3 +44,27 @@
     buf3 = bytearray(b"hello")
     python_pybuffer.title1(buf3)
     check(buf3 == b"Hello")
+
+    try:
+        python_pybuffer.func1(1)
+        raise RuntimeError("should throw TypeError")
+    except TypeError as e:
+        check("(char *buf1, int len)" in str(e))
+
+    try:
+        python_pybuffer.func2(1)
+        raise RuntimeError("should throw TypeError")
+    except TypeError as e:
+        check("(char *buf2)" in str(e))
+
+    try:
+        python_pybuffer.func3(1)
+        raise RuntimeError("should throw TypeError")
+    except TypeError as e:
+        check("(const char *buf3, int len)" in str(e))
+
+    try:
+        python_pybuffer.func4(1)
+        raise RuntimeError("should throw TypeError")
+    except TypeError as e:
+        check("(const char *buf4)" in str(e))
diff --git a/Examples/test-suite/python/python_richcompare_runme.py b/Examples/test-suite/python/python_richcompare_runme.py
index 724d1d7..09af8a4 100644
--- a/Examples/test-suite/python/python_richcompare_runme.py
+++ b/Examples/test-suite/python/python_richcompare_runme.py
@@ -114,22 +114,22 @@
     try:
         res = base1 < 42
         raise RuntimeError("Failed to throw")
-    except TypeError,e:
+    except TypeError as e:
         check_unorderable_types(e)
     try:
         res = base1 <= 42
         raise RuntimeError("Failed to throw")
-    except TypeError,e:
+    except TypeError as e:
         check_unorderable_types(e)
     try:
         res = base1 > 42
         raise RuntimeError("Failed to throw")
-    except TypeError,e:
+    except TypeError as e:
         check_unorderable_types(e)
     try:
         res = base1 >= 42
         raise RuntimeError("Failed to throw")
-    except TypeError,e:
+    except TypeError as e:
         check_unorderable_types(e)
 
 # Check inequalities used for ordering
@@ -156,3 +156,83 @@
 
 if not (x[2] is a3):
     raise RuntimeError("Ordering failed")
+
+
+# Test custom exceptions can still be thrown in operators which use %pythonmaybecall
+et0 = python_richcompare.ExceptionThrower(0)
+et1 = python_richcompare.ExceptionThrower(1)
+et2 = python_richcompare.ExceptionThrower(2)
+
+if not(et1 < et2):
+    raise RuntimeError("ExceptionThrower (a) failed")
+
+if et2 < et1:
+    raise RuntimeError("ExceptionThrower (b) failed")
+
+try:
+    x = et2 < et0
+    raise RuntimeError("ExceptionThrower failed to throw ValueError (A)")
+except ValueError:
+    pass
+
+try:
+    x = et0 < et2
+    raise RuntimeError("ExceptionThrower failed to throw ValueError (B)")
+except ValueError:
+    pass
+
+if sys.version_info[0:2] >= (3, 0):
+    try:
+        x = et2 < 99
+        raise RuntimeError("ExceptionThrower (d) failed")
+    except TypeError:
+        pass
+
+    try:
+        x = 99 < et2
+        raise RuntimeError("ExceptionThrower (e) failed")
+    except TypeError:
+        pass
+
+    try:
+        x = et0 < 99
+        raise RuntimeError("ExceptionThrower (f) failed")
+    except TypeError:
+        pass
+
+    try:
+        x = 99 < et0
+        raise RuntimeError("ExceptionThrower (g) failed")
+    except TypeError:
+        pass
+
+
+# Overloaded operators and custom exceptions
+c0 = python_richcompare.SubClassCThrower(0)
+c1 = python_richcompare.SubClassCThrower(1)
+c1b = python_richcompare.SubClassCThrower(1)
+c2 = python_richcompare.SubClassCThrower(2)
+
+if c1 == c2:
+    raise RuntimeError("SubClassCThrower failed (a)")
+
+if not(c1 == c1b):
+    raise RuntimeError("SubClassCThrower failed (b)")
+
+if c0 == 99:
+    raise RuntimeError("SubClassCThrower failed (c)")
+
+if 99 == c0:
+    raise RuntimeError("SubClassCThrower failed (d)")
+
+try:
+    x = c0 == c1
+    raise RuntimeError("SubClassCThrower failed to throw (A)")
+except ValueError:
+    pass
+
+try:
+    x = c1 == c0
+    raise RuntimeError("SubClassCThrower failed to throw (B)")
+except ValueError:
+    pass
diff --git a/Examples/test-suite/python/python_runtime_data_runme.py b/Examples/test-suite/python/python_runtime_data_runme.py
new file mode 100644
index 0000000..063bf82
--- /dev/null
+++ b/Examples/test-suite/python/python_runtime_data_runme.py
@@ -0,0 +1,15 @@
+import python_runtime_data_builtin as builtin
+import python_runtime_data_nobuiltin as nobuiltin
+
+def swig_assert(a):
+    if not a:
+        raise RuntimeError("Failed")
+
+swig_assert(builtin.is_python_builtin())
+swig_assert(not nobuiltin.is_python_builtin())
+
+for i in range(1, 5):
+    v1 = builtin.vectord([1.] * i)
+    swig_assert(len(v1) == i)
+    v2 = nobuiltin.vectord([1.] * i)
+    swig_assert(len(v2) == i)
diff --git a/Examples/test-suite/python/python_strict_unicode_runme.py b/Examples/test-suite/python/python_strict_unicode_runme.py
index e7fae25..79c768d 100644
--- a/Examples/test-suite/python/python_strict_unicode_runme.py
+++ b/Examples/test-suite/python/python_strict_unicode_runme.py
@@ -1,8 +1,20 @@
 import python_strict_unicode
+import sys
 
 test_bytes   = b"hello \x01world\x99"
 BYTES        = b"BYTES"
-test_unicode = u"h\udce9llo w\u00f6rld"
+
+if sys.version_info[0:2] < (3, 0):
+    # Python 3.0-3.2 results in a SyntaxError when using u"" string literals, so we use a
+    # convoluted unicode string construction using unicode() and unichr().
+    # Conventional Python 2 syntax shown in comments.
+    test_unicode = unicode("h" + unichr(0xdce9) + "llo w" + unichr(0x00f6) + "rld") # u"h\udce9llo w\u00f6rld"
+    UNICODE      = unicode("UNICODE")
+    type_unicode_string = type(UNICODE)
+else:
+    test_unicode = "h\udce9llo w\u00f6rld"
+    UNICODE      = "UNICODE"
+    type_unicode_string = type(UNICODE)
 
 # Test that byte string inputs and outputs work as expected
 bdbl = python_strict_unicode.double_str(test_bytes)
@@ -20,12 +32,12 @@
 udbl = python_strict_unicode.double_wstr(test_unicode)
 if udbl != test_unicode + test_unicode:
     raise RuntimeError("Failed to double wide string")
-if type(udbl) != type(u""):
+if type(udbl) != type_unicode_string:
     raise RuntimeError("Wrong type output for wide string")
 uout = python_strict_unicode.same_wstr(test_unicode)
 if uout != test_unicode:
     raise RuntimeError("Failed to copy wchar_t*")
-if type(uout) != type(u""):
+if type(uout) != type_unicode_string:
     raise RuntimeError("Wrong type output for wchar_t*")
 
 # Test that overloading is handled properly
@@ -35,9 +47,9 @@
 if type(bovr) != type(BYTES):
     raise RuntimeError("Wrong type output from overload")
 uovr = python_strict_unicode.overload(test_unicode)
-if uovr != u"UNICODE":
+if uovr != UNICODE:
     raise RuntimeError("Failed to return unicode from overload")
-if type(uovr) != type(u""):
+if type(uovr) != type_unicode_string:
     raise RuntimeERror("Wrong type output from overload")
 
 # Test that bytes aren't accepted as wide strings and unicode isn't accepted as narrow strings
diff --git a/Examples/test-suite/python/python_typemap_macro_runme.py b/Examples/test-suite/python/python_typemap_macro_runme.py
new file mode 100644
index 0000000..ec494e0
--- /dev/null
+++ b/Examples/test-suite/python/python_typemap_macro_runme.py
@@ -0,0 +1,27 @@
+from python_typemap_macro import *
+
+psi = PairStringInt(["i am a string", 5])
+psi = PairStringInt(psi)
+pcpsi = PairCharPairStringInt(['a', psi])
+pcpsi = PairCharPairStringInt(['b', ["i am a string", 5]])
+
+psi = PairInputOutput(["list item 1", 55])
+PairInputOutput(psi)
+PairInputOutput(PairStringInt())
+
+pcpsi = MakePair()
+if pcpsi != ('x', ('outstring', 111)):
+    raise RuntimeError("failed {}".format(pcpsi))
+
+pcpsi = PairInputOutput2(['c', ["list item 1", 55]])
+if pcpsi != ('c', ('list item 1', 55)):
+    raise RuntimeError("failed {}".format(pcpsi))
+
+pcpsi = PairInputOutput2(pcpsi)
+pcpsi = PairInputOutput2(['c', ["list item 1", 55]])
+if pcpsi != ('c', ('list item 1', 55)):
+    raise RuntimeError("failed {}".format(pcpsi))
+
+pcpsi = PairInputOutput2(PairCharPairStringInt())
+if pcpsi != ('\x00', ('', 0)):
+    raise RuntimeError("failed {}".format(pcpsi))
diff --git a/Examples/test-suite/python/refcount_runme.py b/Examples/test-suite/python/refcount_runme.py
index 2cab6a7..5bea25f 100644
--- a/Examples/test-suite/python/refcount_runme.py
+++ b/Examples/test-suite/python/refcount_runme.py
@@ -5,7 +5,7 @@
 
 a = A3()
 b1 = B(a)
-b2 = B_create(a)
+b2 = B.create(a)
 
 
 if a.ref_count() != 3:
@@ -13,7 +13,7 @@
 
 
 rca = b2.get_rca()
-b3 = B_create(rca)
+b3 = B.create(rca)
 
 if a.ref_count() != 5:
     raise RuntimeError("Count = %d" % a.ref_count())
@@ -38,7 +38,7 @@
 if b5.ref_count() != 1:
     raise RuntimeError
 
-b6 = Factory_create(a)
+b6 = Factory.create(a)
 if b6.ref_count() != 1:
     raise RuntimeError
 
diff --git a/Examples/test-suite/python/return_const_value_runme.py b/Examples/test-suite/python/return_const_value_runme.py
index ff3bd5f..8cbac12 100644
--- a/Examples/test-suite/python/return_const_value_runme.py
+++ b/Examples/test-suite/python/return_const_value_runme.py
@@ -1,12 +1,10 @@
 import return_const_value
 import sys
 
-p = return_const_value.Foo_ptr_getPtr()
+p = return_const_value.Foo_ptr.getPtr()
 if (p.getVal() != 17):
-    print "Runtime test1 failed. p.getVal()=", p.getVal()
-    sys.exit(1)
+    raise RuntimeError("Runtime test1 failed. p.getVal()={}".format(p.getVal()))
 
-p = return_const_value.Foo_ptr_getConstPtr()
+p = return_const_value.Foo_ptr.getConstPtr()
 if (p.getVal() != 17):
-    print "Runtime test2 failed. p.getVal()=", p.getVal()
-    sys.exit(1)
+    raise RuntimeError("Runtime test2 failed. p.getVal()={}".format(p.getVal()))
diff --git a/Examples/test-suite/python/smart_pointer_member_runme.py b/Examples/test-suite/python/smart_pointer_member_runme.py
index d2ed87e..9758b0b 100644
--- a/Examples/test-suite/python/smart_pointer_member_runme.py
+++ b/Examples/test-suite/python/smart_pointer_member_runme.py
@@ -11,9 +11,7 @@
 b.y = 2
 
 if f.y != 2:
-    print f.y
-    print b.y
-    raise RuntimeError
+    raise RuntimeError("Failed {} {}".format(f.y, b.y))
 
 if b.x != f.x:
     raise RuntimeError
diff --git a/Examples/test-suite/python/smart_pointer_not_runme.py b/Examples/test-suite/python/smart_pointer_not_runme.py
index 69704c4..8cd9f11 100644
--- a/Examples/test-suite/python/smart_pointer_not_runme.py
+++ b/Examples/test-suite/python/smart_pointer_not_runme.py
@@ -7,36 +7,36 @@
 
 try:
     x = b.x
-    print "Error! b.x"
-except:
+    raise RuntimeError("Error! b.x")
+except AttributeError:
     pass
 
 try:
     x = s.x
-    print "Error! s.x"
-except:
+    raise RuntimeError("Error! s.x")
+except AttributeError:
     pass
 
 try:
     x = g.x
-    print "Error! g.x"
-except:
+    raise RuntimeError("Error! g.x")
+except AttributeError:
     pass
 
 try:
     x = b.getx()
-    print "Error! b.getx()"
-except:
+    raise RuntimeError("Error! b.getx()")
+except AttributeError:
     pass
 
 try:
     x = s.getx()
-    print "Error! s.getx()"
-except:
+    raise RuntimeError("Error! s.getx()")
+except AttributeError:
     pass
 
 try:
     x = g.getx()
-    print "Error! g.getx()"
-except:
+    raise RuntimeError("Error! g.getx()")
+except AttributeError:
     pass
diff --git a/Examples/test-suite/python/special_variable_macros_runme.py b/Examples/test-suite/python/special_variable_macros_runme.py
index e487f9a..d06b879 100644
--- a/Examples/test-suite/python/special_variable_macros_runme.py
+++ b/Examples/test-suite/python/special_variable_macros_runme.py
@@ -1,10 +1,15 @@
 import special_variable_macros
 
+cvar = special_variable_macros.cvar
 name = special_variable_macros.Name()
 if special_variable_macros.testFred(name) != "none":
     raise "test failed"
+if cvar.accessed_examplekw != 0:
+    raise "Precondition failed"
 if special_variable_macros.testJack(name) != "$specialname":
     raise "test failed"
+if cvar.accessed_examplekw != 1:
+    raise "Postcondition failed"
 if special_variable_macros.testJill(name) != "jilly":
     raise "test failed"
 if special_variable_macros.testMary(name) != "SWIGTYPE_p_NameWrap":
@@ -15,3 +20,7 @@
     raise "test failed"
 if special_variable_macros.testJohn(special_variable_macros.PairIntBool(10, False)) != 123:
     raise "test failed"
+if special_variable_macros.makeStringInt("stringint", 999) != "stringint":
+    raise "test failed"
+if special_variable_macros.provideStringInt(999) != "1000":
+    raise "test failed"
diff --git a/Examples/test-suite/python/std_containers_runme.py b/Examples/test-suite/python/std_containers_runme.py
index 7404cd5..820c8f4 100644
--- a/Examples/test-suite/python/std_containers_runme.py
+++ b/Examples/test-suite/python/std_containers_runme.py
@@ -7,34 +7,33 @@
 icube = std_containers.cident(cube)
 for i in range(0, len(cube)):
     if cube[i] != icube[i]:
-        raise RuntimeError, "bad cident"
+        raise RuntimeError("bad cident")
 
 
 p = (1, 2)
 if p != std_containers.pident(p):
-    raise RuntimeError, "bad pident"
+    raise RuntimeError("bad pident")
 
 v = (1, 2, 3, 4, 5, 6)
 iv = std_containers.vident(v)
 for i in range(0, len(v)):
     if v[i] != iv[i]:
-        raise RuntimeError, "bad vident"
+        raise RuntimeError("bad vident")
 
 
 iv = std_containers.videntu(v)
 for i in range(0, len(v)):
     if v[i] != iv[i]:
-        raise RuntimeError, "bad videntu"
+        raise RuntimeError("bad videntu")
 
 
 vu = std_containers.vector_ui(v)
 if vu[2] != std_containers.videntu(vu)[2]:
-    raise RuntimeError, "bad videntu"
+    raise RuntimeError("bad videntu")
 
 
 if v[0:3][1] != vu[0:3][1]:
-    print v[0:3][1], vu[0:3][1]
-    raise RuntimeError, "bad getslice"
+    raise RuntimeError("bad getslice {} {}".format(v[0:3][1], vu[0:3][1]))
 
 
 m = ((1, 2, 3), (2, 3), (3, 4))
@@ -43,20 +42,20 @@
 for i in range(0, len(m)):
     for j in range(0, len(m[i])):
         if m[i][j] != im[i][j]:
-            raise RuntimeError, "bad getslice"
+            raise RuntimeError("bad getslice")
 
 m = ((True, False, True), (True, True), (True, True))
 im = std_containers.midentb(m)
 for i in range(0, len(m)):
     for j in range(0, len(m[i])):
         if m[i][j] != im[i][j]:
-            raise RuntimeError, "bad getslice"
+            raise RuntimeError("bad getslice")
 
 
 mi = std_containers.imatrix(m)
 mc = std_containers.cmatrix(m)
 if mi[0][1] != mc[0][1]:
-    raise RuntimeError, "bad matrix"
+    raise RuntimeError("bad matrix")
 
 
 map = {}
@@ -67,7 +66,7 @@
 imap = std_containers.mapident(map)
 for k in map:
     if map[k] != imap[k]:
-        raise RuntimeError, "bad map"
+        raise RuntimeError("bad map")
 
 # Test __contains__ (required for 'x in y' to work)
 if not imap.__contains__("hello"):
diff --git a/Examples/test-suite/python/struct_value_runme.py b/Examples/test-suite/python/struct_value_runme.py
index aa3ece3..9fe5c81 100644
--- a/Examples/test-suite/python/struct_value_runme.py
+++ b/Examples/test-suite/python/struct_value_runme.py
@@ -17,7 +17,7 @@
 if b.added != 123:
     raise RuntimeError("Wrong attribute value")
 
-if not b.__dict__.has_key("added"):
+if "added" not in b.__dict__:
     raise RuntimeError("Missing added attribute in __dict__")
 
 
@@ -28,7 +28,7 @@
         struct_value.Bar.__init__(self)
 
 pybar = PyBar()
-if not pybar.__dict__.has_key("extra"):
+if "extra" not in pybar.__dict__:
     raise RuntimeError("Missing extra attribute in __dict__")
 if pybar.extra != "hi":
     raise RuntimeError("Incorrect attribute value for extra")
diff --git a/Examples/test-suite/python/swigobject_runme.py b/Examples/test-suite/python/swigobject_runme.py
index de232f5..e28e187 100644
--- a/Examples/test-suite/python/swigobject_runme.py
+++ b/Examples/test-suite/python/swigobject_runme.py
@@ -1,5 +1,5 @@
-
 from swigobject import *
+import sys
 
 a = A()
 
@@ -11,7 +11,11 @@
     raise RuntimeError
 
 
-lthis = long(a.this)
+if sys.version_info[0:2] < (3, 0):
+    lthis = long(a.this)
+else:
+    lthis = int(a.this)
+
 # match pointer value, but deal with leading zeros on 8/16 bit systems and
 # different C++ compilers interpretation of %p
 xstr1 = "%016X" % (lthis,)
@@ -23,13 +27,17 @@
 xstr2 = str.upper(xstr2)
 
 if xstr1 != xstr2:
-    print xstr1, xstr2
-    raise RuntimeError
+    raise RuntimeError("Not equal failed {} {}".format(xstr1, xstr2))
 
 s = str(a.this)
 r = repr(a.this)
 
 v1 = v_ptr(a)
 v2 = v_ptr(a)
-if long(v1) != long(v2):
-    raise RuntimeError
+
+if sys.version_info[0:2] < (3, 0):
+    if long(v1) != long(v2):
+        raise RuntimeError
+else:
+    if int(v1) != int(v2):
+        raise RuntimeError
diff --git a/Examples/test-suite/python/template_classes_runme.py b/Examples/test-suite/python/template_classes_runme.py
index 38b2d7a..1bd1339 100644
--- a/Examples/test-suite/python/template_classes_runme.py
+++ b/Examples/test-suite/python/template_classes_runme.py
@@ -13,7 +13,7 @@
 fail = True
 try:
     rectangle.setPoint()
-except TypeError, e:
+except TypeError as e:
     fail = False
 if fail:
     raise RuntimeError("argument count check failed")
@@ -22,7 +22,7 @@
 fail = True
 try:
     rectangle.getPoint(0)
-except TypeError, e:
+except TypeError as e:
     fail = False
 if fail:
     raise RuntimeError("argument count check failed")
@@ -30,7 +30,7 @@
 fail = True
 try:
     RectangleInt.static_noargs(0)
-except TypeError, e:
+except TypeError as e:
     fail = False
 if fail:
     raise RuntimeError("argument count check failed")
@@ -38,7 +38,7 @@
 fail = True
 try:
     RectangleInt.static_onearg()
-except TypeError, e:
+except TypeError as e:
     fail = False
 if fail:
     raise RuntimeError("argument count check failed")
diff --git a/Examples/test-suite/python/template_default_arg_runme.py b/Examples/test-suite/python/template_default_arg_runme.py
index 91b1e0e..e9ef00f 100644
--- a/Examples/test-suite/python/template_default_arg_runme.py
+++ b/Examples/test-suite/python/template_default_arg_runme.py
@@ -7,25 +7,25 @@
 
 x = template_default_arg.X_int()
 if (x.meth(20.0, 200) != 200):
-    raise RuntimeError, ("X_int test 1 failed")
+    raise RuntimeError(("X_int test 1 failed"))
 if (x.meth(20) != 20):
-    raise RuntimeError, ("X_int test 2 failed")
+    raise RuntimeError(("X_int test 2 failed"))
 if (x.meth() != 0):
-    raise RuntimeError, ("X_int test 3 failed")
+    raise RuntimeError(("X_int test 3 failed"))
 
 
 y = template_default_arg.Y_unsigned()
 if (y.meth(20.0, 200) != 200):
-    raise RuntimeError, ("Y_unsigned test 1 failed")
+    raise RuntimeError(("Y_unsigned test 1 failed"))
 if (y.meth(20) != 20):
-    raise RuntimeError, ("Y_unsigned test 2 failed")
+    raise RuntimeError(("Y_unsigned test 2 failed"))
 if (y.meth() != 0):
-    raise RuntimeError, ("Y_unsigned test 3 failed")
+    raise RuntimeError(("Y_unsigned test 3 failed"))
 
 
 x = template_default_arg.X_longlong()
 x = template_default_arg.X_longlong(20.0)
-x = template_default_arg.X_longlong(20.0, 200L)
+x = template_default_arg.X_longlong(20.0, 200)
 
 
 x = template_default_arg.X_int()
@@ -54,40 +54,40 @@
 
 # plain function: int ott(Foo<int>)
 if (template_default_arg.ott(template_default_arg.Foo_int()) != 30):
-    raise RuntimeError, ("ott test 1 failed")
+    raise RuntimeError(("ott test 1 failed"))
 
 # %template(ott) ott<int, int>
 if (template_default_arg.ott() != 10):
-    raise RuntimeError, ("ott test 2 failed")
+    raise RuntimeError(("ott test 2 failed"))
 if (template_default_arg.ott(1) != 10):
-    raise RuntimeError, ("ott test 3 failed")
+    raise RuntimeError(("ott test 3 failed"))
 if (template_default_arg.ott(1, 1) != 10):
-    raise RuntimeError, ("ott test 4 failed")
+    raise RuntimeError(("ott test 4 failed"))
 
 if (template_default_arg.ott("hi") != 20):
-    raise RuntimeError, ("ott test 5 failed")
+    raise RuntimeError(("ott test 5 failed"))
 if (template_default_arg.ott("hi", 1) != 20):
-    raise RuntimeError, ("ott test 6 failed")
+    raise RuntimeError(("ott test 6 failed"))
 if (template_default_arg.ott("hi", 1, 1) != 20):
-    raise RuntimeError, ("ott test 7 failed")
+    raise RuntimeError(("ott test 7 failed"))
 
 # %template(ott) ott<const char *>
 if (template_default_arg.ottstring(template_default_arg.Hello_int(), "hi") != 40):
-    raise RuntimeError, ("ott test 8 failed")
+    raise RuntimeError(("ott test 8 failed"))
 
 if (template_default_arg.ottstring(template_default_arg.Hello_int()) != 40):
-    raise RuntimeError, ("ott test 9 failed")
+    raise RuntimeError(("ott test 9 failed"))
 
 # %template(ott) ott<int>
 if (template_default_arg.ottint(template_default_arg.Hello_int(), 1) != 50):
-    raise RuntimeError, ("ott test 10 failed")
+    raise RuntimeError(("ott test 10 failed"))
 
 if (template_default_arg.ottint(template_default_arg.Hello_int()) != 50):
-    raise RuntimeError, ("ott test 11 failed")
+    raise RuntimeError(("ott test 11 failed"))
 
 # %template(ott) ott<double>
 if (template_default_arg.ott(template_default_arg.Hello_int(), 1.0) != 60):
-    raise RuntimeError, ("ott test 12 failed")
+    raise RuntimeError(("ott test 12 failed"))
 
 if (template_default_arg.ott(template_default_arg.Hello_int()) != 60):
-    raise RuntimeError, ("ott test 13 failed")
+    raise RuntimeError(("ott test 13 failed"))
diff --git a/Examples/test-suite/python/template_static_runme.py b/Examples/test-suite/python/template_static_runme.py
index c87a524..84da284 100644
--- a/Examples/test-suite/python/template_static_runme.py
+++ b/Examples/test-suite/python/template_static_runme.py
@@ -1,3 +1,3 @@
 from template_static import *
 
-Foo_bar_double(1)
+Foo.bar_double(1)
diff --git a/Examples/test-suite/python/template_template_parameters_runme.py b/Examples/test-suite/python/template_template_parameters_runme.py
new file mode 100644
index 0000000..3129359
--- /dev/null
+++ b/Examples/test-suite/python/template_template_parameters_runme.py
@@ -0,0 +1,33 @@
+from template_template_parameters import *
+
+# Test part 1
+listBool = ListFastBool()
+listBool.item = True
+x_boolean = listBool.allotype
+if listBool.item != True:
+  raise RuntimeError("Failed")
+
+listDouble = ListDefaultDouble()
+listDouble.item = 10.2
+x_double = listDouble.allotype
+if listDouble.item != 10.2:
+  raise RuntimeError("Failed")
+
+# Test part 2
+floatTestStruct = FloatTestStruct()
+floatContainer2 = floatTestStruct.x
+floatContainer2.x = 8.1
+intTestStruct = IntTestStruct()
+intContainer1 = intTestStruct.x
+intContainer1.x = 91
+if intContainer1.x != 91:
+  raise RuntimeError("Failed")
+if intTestStruct.x.x != 91:
+  raise RuntimeError("Failed")
+intTestStructReturned = TestStructContainer1Method(intTestStruct)
+if intTestStructReturned.x.x != 101:
+  raise RuntimeError("Failed")
+
+# Test part 3
+mfi99 = MyFootInt99()
+mfi99 += mfi99 # __iadd__
diff --git a/Examples/test-suite/python/template_templated_constructors_runme.py b/Examples/test-suite/python/template_templated_constructors_runme.py
new file mode 100644
index 0000000..c3fbda0
--- /dev/null
+++ b/Examples/test-suite/python/template_templated_constructors_runme.py
@@ -0,0 +1,20 @@
+from template_templated_constructors import *
+
+t1 = TConstructor1(123)
+t2a = TConstructor2()
+t2b = TConstructor2(123)
+
+tc1 = TClass1Int(123.4)
+tc2a = TClass2Int()
+tc2b = TClass2Int(123.4)
+
+double_pair = DoublePair(1.1, 2.2)
+short_pair = ShortPair(0, 1)
+string_pair = StringPair("10", "11")
+ip1 = IntPair()
+ip2 = IntPair(20, 21)
+ip3 = IntPair(ip1)
+ip4 = IntPair(short_pair)
+# These next two create an IntPair from factory function calls in Python, unlike Java which calls the IntPair constructor
+ip5 = Pair(double_pair)
+ip6 = MakeStringPair(string_pair)
diff --git a/Examples/test-suite/python/template_typedef_cplx2_runme.py b/Examples/test-suite/python/template_typedef_cplx2_runme.py
index 161bd51..23f19ef 100644
--- a/Examples/test-suite/python/template_typedef_cplx2_runme.py
+++ b/Examples/test-suite/python/template_typedef_cplx2_runme.py
@@ -8,25 +8,21 @@
     d = make_Identity_double()
     a = d.this
 except:
-    print d, "is not an instance"
-    raise RuntimeError
+    raise RuntimeError("{} is not an instance".format(d))
 
 s = "%s" % d
 if str.find(s, "ArithUnaryFunction") == -1:
-    print d, "is not an ArithUnaryFunction"
-    raise RuntimeError
+    raise RuntimeError("{} is not an ArithUnaryFunction".format(d))
 
 try:
     e = make_Multiplies_double_double_double_double(d, d)
     a = e.this
 except:
-    print e, "is not an instance"
-    raise RuntimeError
+    raise RuntimeError("{} is not an instance".format(e))
 
 s = "%s" % e
 if str.find(s, "ArithUnaryFunction") == -1:
-    print e, "is not an ArithUnaryFunction"
-    raise RuntimeError
+    raise RuntimeError("{} is not an ArithUnaryFunction".format(e))
 
 
 #
@@ -37,25 +33,21 @@
     c = make_Identity_complex()
     a = c.this
 except:
-    print c, "is not an instance"
-    raise RuntimeError
+    raise RuntimeError("{} is not an instance".format(c))
 
 s = "%s" % c
 if str.find(s, "ArithUnaryFunction") == -1:
-    print c, "is not an ArithUnaryFunction"
-    raise RuntimeError
+    raise RuntimeError("{} is not an ArithUnaryFunction".format(c))
 
 try:
     f = make_Multiplies_complex_complex_complex_complex(c, c)
     a = f.this
 except:
-    print f, "is not an instance"
-    raise RuntimeError
+    raise RuntimeError("{} is not an instance".format(f))
 
 s = "%s" % f
 if str.find(s, "ArithUnaryFunction") == -1:
-    print f, "is not an ArithUnaryFunction"
-    raise RuntimeError
+    raise RuntimeError("{} is not an ArithUnaryFunction".format(f))
 
 #
 # Mix case
@@ -65,29 +57,24 @@
     g = make_Multiplies_double_double_complex_complex(d, c)
     a = g.this
 except:
-    print g, "is not an instance"
-    raise RuntimeError
+    raise RuntimeError("{} is not an instance".format(g))
 
 s = "%s" % g
 if str.find(s, "ArithUnaryFunction") == -1:
-    print g, "is not an ArithUnaryFunction"
-    raise RuntimeError
+    raise RuntimeError("{} is not an ArithUnaryFunction".format(g))
 
 
 try:
     h = make_Multiplies_complex_complex_double_double(c, d)
     a = h.this
 except:
-    print h, "is not an instance"
-    raise RuntimeError
+    raise RuntimeError("{} is not an instance".format(h))
 
 s = "%s" % h
 if str.find(s, "ArithUnaryFunction") == -1:
-    print h, "is not an ArithUnaryFunction"
-    raise RuntimeError
+    raise RuntimeError("{} is not an ArithUnaryFunction".format(h))
 
 try:
     a = g.get_value()
 except:
-    print g, "has not get_value() method"
-    raise RuntimeError
+    raise RuntimeError("{}, has not get_value() method".format(g))
diff --git a/Examples/test-suite/python/template_typedef_cplx_runme.py b/Examples/test-suite/python/template_typedef_cplx_runme.py
index 1846739..69d5642 100644
--- a/Examples/test-suite/python/template_typedef_cplx_runme.py
+++ b/Examples/test-suite/python/template_typedef_cplx_runme.py
@@ -8,25 +8,21 @@
     d = make_Identity_double()
     a = d.this
 except:
-    print d, "is not an instance"
-    raise RuntimeError
+    raise RuntimeError("{} is not an instance".format(d))
 
 s = "%s" % d
 if str.find(s, "ArithUnaryFunction") == -1:
-    print d, "is not an ArithUnaryFunction"
-    raise RuntimeError
+    raise RuntimeError("{} is not an ArithUnaryFunction".format(d))
 
 try:
     e = make_Multiplies_double_double_double_double(d, d)
     a = e.this
 except:
-    print e, "is not an instance"
-    raise RuntimeError
+    raise RuntimeError("{} is not an instance".format(e))
 
 s = "%s" % e
 if str.find(s, "ArithUnaryFunction") == -1:
-    print e, "is not an ArithUnaryFunction"
-    raise RuntimeError
+    raise RuntimeError("{} is not an ArithUnaryFunction".format(e))
 
 
 #
@@ -37,25 +33,21 @@
     c = make_Identity_complex()
     a = c.this
 except:
-    print c, "is not an instance"
-    raise RuntimeError
+    raise RuntimeError("{} is not an instance".format(c))
 
 s = "%s" % c
 if str.find(s, "ArithUnaryFunction") == -1:
-    print c, "is not an ArithUnaryFunction"
-    raise RuntimeError
+    raise RuntimeError("{} is not an ArithUnaryFunction".format(c))
 
 try:
     f = make_Multiplies_complex_complex_complex_complex(c, c)
     a = f.this
 except:
-    print f, "is not an instance"
-    raise RuntimeError
+    raise RuntimeError("{} is not an instance".format(f))
 
 s = "%s" % f
 if str.find(s, "ArithUnaryFunction") == -1:
-    print f, "is not an ArithUnaryFunction"
-    raise RuntimeError
+    raise RuntimeError("{} is not an ArithUnaryFunction".format(f))
 
 #
 # Mix case
@@ -65,23 +57,19 @@
     g = make_Multiplies_double_double_complex_complex(d, c)
     a = g.this
 except:
-    print g, "is not an instance"
-    raise RuntimeError
+    raise RuntimeError("{} is not an instance".format(g))
 
 s = "%s" % g
 if str.find(s, "ArithUnaryFunction") == -1:
-    print g, "is not an ArithUnaryFunction"
-    raise RuntimeError
+    raise RuntimeError("{} is not an ArithUnaryFunction".format(g))
 
 
 try:
     h = make_Multiplies_complex_complex_double_double(c, d)
     a = h.this
 except:
-    print h, "is not an instance"
-    raise RuntimeError
+    raise RuntimeError("{} is not an instance".format(h))
 
 s = "%s" % h
 if str.find(s, "ArithUnaryFunction") == -1:
-    print h, "is not an ArithUnaryFunction"
-    raise RuntimeError
+    raise RuntimeError("{} is not an ArithUnaryFunction".format(h))
diff --git a/Examples/test-suite/python/template_typedef_runme.py b/Examples/test-suite/python/template_typedef_runme.py
index 16695ba..5723e4f 100644
--- a/Examples/test-suite/python/template_typedef_runme.py
+++ b/Examples/test-suite/python/template_typedef_runme.py
@@ -14,22 +14,19 @@
     e = make_Multiplies_float_float_float_float(d, d)
     a = e.this
 except:
-    print e, "is not an instance"
-    raise RuntimeError
+    raise RuntimeError("{} is not an instance".format(e))
 
 try:
     f = make_Multiplies_reald_reald_reald_reald(c, c)
     a = f.this
 except:
-    print f, "is not an instance"
-    raise RuntimeError
+    raise RuntimeError("{} is not an instance".format(f))
 
 try:
     g = make_Multiplies_float_float_reald_reald(d, c)
     a = g.this
 except:
-    print g, "is not an instance"
-    raise RuntimeError
+    raise RuntimeError("{} is not an instance".format(g))
 
 
 # the old large format
diff --git a/Examples/test-suite/python/template_typemaps_typedef2_runme.py b/Examples/test-suite/python/template_typemaps_typedef2_runme.py
index 258f443..da26a9f 100644
--- a/Examples/test-suite/python/template_typemaps_typedef2_runme.py
+++ b/Examples/test-suite/python/template_typemaps_typedef2_runme.py
@@ -5,7 +5,7 @@
 dummy_pair = m1.make_dummy_pair()
 val = m1.typemap_test(dummy_pair).val
 if val != 1234:
-    raise RuntimeError, "typemaps not working"
+    raise RuntimeError("typemaps not working")
 
 m2 = MultimapAInt()
 
@@ -13,24 +13,24 @@
 #dummy_pair = m2.make_dummy_pair()
 #val = m2.typemap_test(dummy_pair)
 
-# print val
+# print("{}".format(val))
 # if val != 4321:
 #    raise RuntimeError, "typemaps not working"
 
 if typedef_test1(dummy_pair).val != 1234:
-    raise RuntimeError, "typedef_test1 not working"
+    raise RuntimeError("typedef_test1 not working")
 
 if typedef_test2(dummy_pair).val != 1234:
-    raise RuntimeError, "typedef_test2 not working"
+    raise RuntimeError("typedef_test2 not working")
 
 if typedef_test3(dummy_pair).val != 1234:
-    raise RuntimeError, "typedef_test3 not working"
+    raise RuntimeError("typedef_test3 not working")
 
 if typedef_test4(dummy_pair).val != 1234:
-    raise RuntimeError, "typedef_test4 not working"
+    raise RuntimeError("typedef_test4 not working")
 
 if typedef_test5(dummy_pair).val != 1234:
-    raise RuntimeError, "typedef_test5 not working"
+    raise RuntimeError("typedef_test5 not working")
 
 if typedef_test6(dummy_pair).val != 1234:
-    raise RuntimeError, "typedef_test6 not working"
+    raise RuntimeError("typedef_test6 not working")
diff --git a/Examples/test-suite/python/template_typemaps_typedef_runme.py b/Examples/test-suite/python/template_typemaps_typedef_runme.py
index 1ca3f83..a5209b7 100644
--- a/Examples/test-suite/python/template_typemaps_typedef_runme.py
+++ b/Examples/test-suite/python/template_typemaps_typedef_runme.py
@@ -5,7 +5,7 @@
 dummy_pair = m1.make_dummy_pair()
 val = m1.typemap_test(dummy_pair).val
 if val != 1234:
-    raise RuntimeError, "typemaps not working"
+    raise RuntimeError("typemaps not working")
 
 m2 = MultimapAInt()
 
@@ -13,24 +13,24 @@
 #dummy_pair = m2.make_dummy_pair()
 #val = m2.typemap_test(dummy_pair)
 
-# print val
+# print("{}".format(val))
 # if val != 4321:
 #    raise RuntimeError, "typemaps not working"
 
 if typedef_test1(dummy_pair).val != 1234:
-    raise RuntimeError, "typedef_test1 not working"
+    raise RuntimeError("typedef_test1 not working")
 
 if typedef_test2(dummy_pair).val != 1234:
-    raise RuntimeError, "typedef_test2 not working"
+    raise RuntimeError("typedef_test2 not working")
 
 if typedef_test3(dummy_pair).val != 1234:
-    raise RuntimeError, "typedef_test3 not working"
+    raise RuntimeError("typedef_test3 not working")
 
 if typedef_test4(dummy_pair).val != 1234:
-    raise RuntimeError, "typedef_test4 not working"
+    raise RuntimeError("typedef_test4 not working")
 
 if typedef_test5(dummy_pair).val != 1234:
-    raise RuntimeError, "typedef_test5 not working"
+    raise RuntimeError("typedef_test5 not working")
 
 if typedef_test6(dummy_pair).val != 1234:
-    raise RuntimeError, "typedef_test6 not working"
+    raise RuntimeError("typedef_test6 not working")
diff --git a/Examples/test-suite/python/template_using_member_default_arg_runme.py b/Examples/test-suite/python/template_using_member_default_arg_runme.py
new file mode 100644
index 0000000..432306a
--- /dev/null
+++ b/Examples/test-suite/python/template_using_member_default_arg_runme.py
@@ -0,0 +1,6 @@
+from template_using_member_default_arg import *
+
+a = ThingADerivedInt()
+a.describeA()
+b = ThingBDerivedInt()
+b.describeB()
diff --git a/Examples/test-suite/python/threads_exception_runme.py b/Examples/test-suite/python/threads_exception_runme.py
index 056bd84..e3f6299 100644
--- a/Examples/test-suite/python/threads_exception_runme.py
+++ b/Examples/test-suite/python/threads_exception_runme.py
@@ -3,18 +3,18 @@
 t = threads_exception.Test()
 try:
     t.unknown()
-except RuntimeError, e:
+except RuntimeError as e:
     pass
 
 try:
     t.simple()
-except RuntimeError, e:
+except RuntimeError as e:
     if e.args[0] != 37:
         raise RuntimeError
 
 try:
     t.message()
-except RuntimeError, e:
+except RuntimeError as e:
     if e.args[0] != "I died.":
         raise RuntimeError
 
@@ -23,18 +23,18 @@
 if not threads_exception.is_python_builtin():
     try:
         t.hosed()
-    except threads_exception.Exc, e:
+    except threads_exception.Exc as e:
         code = e.code
         if code != 42:
-            raise RuntimeError, "bad... code: %d" % code
+            raise RuntimeError("bad... code: %d" % code)
         msg = e.msg
         if msg != "Hosed":
-            raise RuntimeError, "bad... msg: '%s' len: %d" % (msg, len(msg))
+            raise RuntimeError("bad... msg: '%s' len: %d" % (msg, len(msg)))
 
 for i in range(1, 4):
     try:
         t.multi(i)
-    except RuntimeError, e:
+    except RuntimeError as e:
         pass
-    except threads_exception.Exc, e:
+    except threads_exception.Exc as e:
         pass
diff --git a/Examples/test-suite/python/typedef_inherit_runme.py b/Examples/test-suite/python/typedef_inherit_runme.py
index 6b7f2d8..020e4cc 100644
--- a/Examples/test-suite/python/typedef_inherit_runme.py
+++ b/Examples/test-suite/python/typedef_inherit_runme.py
@@ -5,19 +5,23 @@
 
 x = typedef_inherit.do_blah(a)
 if x != "Foo::blah":
-    print "Whoa! Bad return", x
+    raise RuntimeError("Whoa! Bad return {}".format(x))
 
 x = typedef_inherit.do_blah(b)
 if x != "Bar::blah":
-    print "Whoa! Bad return", x
+    raise RuntimeError("Whoa! Bad return {}".format(x))
 
 c = typedef_inherit.Spam()
 d = typedef_inherit.Grok()
 
 x = typedef_inherit.do_blah2(c)
 if x != "Spam::blah":
-    print "Whoa! Bad return", x
+    raise RuntimeError("Whoa! Bad return {}".format(x))
 
 x = typedef_inherit.do_blah2(d)
 if x != "Grok::blah":
-    print "Whoa! Bad return", x
+    raise RuntimeError("Whoa! Bad return {}".format(x))
+
+x = d.far()
+if x != "Spam::far":
+    raise RuntimeError("Whoa! Bad return {}".format(x))
diff --git a/Examples/test-suite/python/typedef_scope_runme.py b/Examples/test-suite/python/typedef_scope_runme.py
index edd3e9f..0294c4a 100644
--- a/Examples/test-suite/python/typedef_scope_runme.py
+++ b/Examples/test-suite/python/typedef_scope_runme.py
@@ -3,8 +3,8 @@
 b = typedef_scope.Bar()
 x = b.test1(42, "hello")
 if x != 42:
-    print "Failed!!"
+    raise RuntimeError("Failed!!")
 
 x = b.test2(42, "hello")
 if x != "hello":
-    print "Failed!!"
+    raise RuntimeError("Failed!!")
diff --git a/Examples/test-suite/python/typemap_arrays_runme.py b/Examples/test-suite/python/typemap_arrays_runme.py
index ea0f08d..7bc45f9 100644
--- a/Examples/test-suite/python/typemap_arrays_runme.py
+++ b/Examples/test-suite/python/typemap_arrays_runme.py
@@ -1,4 +1,4 @@
 from typemap_arrays import *
 
 if sumA(None) != 60:
-    raise RuntimeError, "Sum is wrong"
+    raise RuntimeError("Sum is wrong")
diff --git a/Examples/test-suite/python/typemap_out_optimal_runme.py b/Examples/test-suite/python/typemap_out_optimal_runme.py
index c7a3430..6f6cc54 100644
--- a/Examples/test-suite/python/typemap_out_optimal_runme.py
+++ b/Examples/test-suite/python/typemap_out_optimal_runme.py
@@ -1,4 +1,7 @@
 from typemap_out_optimal import *
 
-cvar.XX_debug = False
-x = XX_create()
+cvar.XX_trace = False
+x = XX.create()
+del x
+x = XX.createConst()
+del x
diff --git a/Examples/test-suite/python/typename_runme.py b/Examples/test-suite/python/typename_runme.py
index aac936f..a4f76fc 100644
--- a/Examples/test-suite/python/typename_runme.py
+++ b/Examples/test-suite/python/typename_runme.py
@@ -4,8 +4,8 @@
 b = typename.Bar()
 
 x = typename.twoFoo(f)
-if not isinstance(x, types.FloatType):
-    raise RuntimeError, "Wrong return type (FloatType) !"
+if not isinstance(x, float):
+    raise RuntimeError("Wrong return type (FloatType) !")
 y = typename.twoBar(b)
-if not isinstance(y, types.IntType):
-    raise RuntimeError, "Wrong return type (IntType)!"
+if not isinstance(y, int):
+    raise RuntimeError("Wrong return type (IntType)!")
diff --git a/Examples/test-suite/python/unicode_strings_runme.py b/Examples/test-suite/python/unicode_strings_runme.py
index 4e661f0..57bd7ab 100644
--- a/Examples/test-suite/python/unicode_strings_runme.py
+++ b/Examples/test-suite/python/unicode_strings_runme.py
@@ -2,12 +2,8 @@
 
 import unicode_strings
 
-# The 'u' string prefix isn't valid in Python 3.0 - 3.2 and is redundant
-# in 3.3+. Since this file is run through 2to3 before testing, though,
-# mark this as a unicode string in 2.x so it'll become a str in 3.x.
-test_string = u"h\udce9llo w\u00f6rld"
-
 if sys.version_info[0:2] >= (3, 1):
+    test_string = "h\udce9llo w\u00f6rld"
     if unicode_strings.non_utf8_c_str() != test_string:
         raise ValueError("Test comparison mismatch")
     if unicode_strings.non_utf8_std_string() != test_string:
@@ -19,19 +15,24 @@
 
 # Testing SWIG_PYTHON_2_UNICODE flag which allows unicode strings to be passed to C
 if sys.version_info[0:2] < (3, 0):
+    # Python 3.0-3.2 results in a SyntaxError when using u"" string literals, so we use a
+    # convoluted unicode string construction using unicode() and unichr().
+    # Conventional Python 2 syntax shown in comments.
     check(unicode_strings.charstring("hello1"), "hello1")
-    check(unicode_strings.charstring(str(u"hello2")), "hello2")
-    check(unicode_strings.charstring(u"hello3"), "hello3")
-    check(unicode_strings.charstring(unicode("hello4")), "hello4")
-    unicode_strings.charstring(u"hell\xb05")
-    unicode_strings.charstring(u"hell\u00f66")
-
-low_surrogate_string = u"\udcff"
-try:
+    check(unicode_strings.charstring(str(unicode("hello2"))), "hello2") # u"hello2"
+    check(unicode_strings.charstring(unicode("hello3")), "hello3") # u"hello3"
+    check(unicode_strings.charstring(str("hello4")), "hello4")
+    unicode_strings.charstring(unicode("hell" + unichr(0xb0) + "5")) # u"hell\xb05"
+    unicode_strings.charstring(unicode("hell" + unichr(0x00f6) +"6")) # u"hell\u00f66"
+    low_surrogate_string = unichr(0xdcff) # u"\udcff"
     unicode_strings.instring(low_surrogate_string)
-    # Will succeed with Python 2
-except TypeError, e:
-    # Python 3 will fail the PyUnicode_AsUTF8String conversion resulting in a TypeError.
-    # The real error is actually:
-    # UnicodeEncodeError: 'utf-8' codec can't encode character '\udcff' in position 0: surrogates not allowed
-    pass
+else:
+    low_surrogate_string = "\udcff"
+    try:
+        unicode_strings.instring(low_surrogate_string)
+        raise RuntimeError("Exception should have been thrown")
+    except TypeError as e:
+        # Python 3 will fail the PyUnicode_AsUTF8String conversion resulting in a TypeError.
+        # The real error is actually:
+        # UnicodeEncodeError: 'utf-8' codec can't encode character '\udcff' in position 0: surrogates not allowed
+        pass
diff --git a/Examples/test-suite/python/unions_runme.py b/Examples/test-suite/python/unions_runme.py
index 387a048..5a3ee3b 100644
--- a/Examples/test-suite/python/unions_runme.py
+++ b/Examples/test-suite/python/unions_runme.py
@@ -3,7 +3,6 @@
 # union embedded within a struct can be set and read correctly.
 
 import unions
-import sys
 import string
 
 # Create new instances of SmallStruct and BigStruct for later use
@@ -23,28 +22,23 @@
 eut.uni.small = small
 Jill1 = eut.uni.small.jill
 if (Jill1 != 200):
-    print "Runtime test1 failed. eut.uni.small.jill=", Jill1
-    sys.exit(1)
+    raise RuntimeError("Runtime test1 failed. eut.uni.small.jill={}".format(Jill1))
 
 Num1 = eut.number
 if (Num1 != 1):
-    print "Runtime test2 failed. eut.number=", Num1
-    sys.exit(1)
+    raise RuntimeError("Runtime test2 failed. eut.number=".format(Num1))
 
 # Secondly check the BigStruct in EmbeddedUnionTest
 eut.number = 2
 eut.uni.big = big
 Jack1 = eut.uni.big.jack
 if (Jack1 != 300):
-    print "Runtime test3 failed. eut.uni.big.jack=", Jack1
-    sys.exit(1)
+    raise RuntimeError("Runtime test3 failed. eut.uni.big.jack={}".format(Jack1))
 
 Jill2 = eut.uni.big.smallstruct.jill
 if (Jill2 != 200):
-    print "Runtime test4 failed. eut.uni.big.smallstruct.jill=", Jill2
-    sys.exit(1)
+    raise RuntimeError("Runtime test4 failed. eut.uni.big.smallstruct.jill={}".format(Jill2))
 
 Num2 = eut.number
 if (Num2 != 2):
-    print "Runtime test5 failed. eut.number=", Num2
-    sys.exit(1)
+    raise RuntimeError("Runtime test5 failed. eut.number={}".format(Num2))
diff --git a/Examples/test-suite/python/using_composition_runme.py b/Examples/test-suite/python/using_composition_runme.py
index c4f3390..67f72bc 100644
--- a/Examples/test-suite/python/using_composition_runme.py
+++ b/Examples/test-suite/python/using_composition_runme.py
@@ -2,32 +2,32 @@
 
 f = FooBar()
 if f.blah(3) != 3:
-    raise RuntimeError, "FooBar::blah(int)"
+    raise RuntimeError("FooBar::blah(int)")
 
 if f.blah(3.5) != 3.5:
-    raise RuntimeError, "FooBar::blah(double)"
+    raise RuntimeError("FooBar::blah(double)")
 
 if f.blah("hello") != "hello":
-    raise RuntimeError, "FooBar::blah(char *)"
+    raise RuntimeError("FooBar::blah(char *)")
 
 
 f = FooBar2()
 if f.blah(3) != 3:
-    raise RuntimeError, "FooBar2::blah(int)"
+    raise RuntimeError("FooBar2::blah(int)")
 
 if f.blah(3.5) != 3.5:
-    raise RuntimeError, "FooBar2::blah(double)"
+    raise RuntimeError("FooBar2::blah(double)")
 
 if f.blah("hello") != "hello":
-    raise RuntimeError, "FooBar2::blah(char *)"
+    raise RuntimeError("FooBar2::blah(char *)")
 
 
 f = FooBar3()
 if f.blah(3) != 3:
-    raise RuntimeError, "FooBar3::blah(int)"
+    raise RuntimeError("FooBar3::blah(int)")
 
 if f.blah(3.5) != 3.5:
-    raise RuntimeError, "FooBar3::blah(double)"
+    raise RuntimeError("FooBar3::blah(double)")
 
 if f.blah("hello") != "hello":
-    raise RuntimeError, "FooBar3::blah(char *)"
+    raise RuntimeError("FooBar3::blah(char *)")
diff --git a/Examples/test-suite/python/using_extend_runme.py b/Examples/test-suite/python/using_extend_runme.py
index 038a168..7e09129 100644
--- a/Examples/test-suite/python/using_extend_runme.py
+++ b/Examples/test-suite/python/using_extend_runme.py
@@ -2,20 +2,20 @@
 
 f = FooBar()
 if f.blah(3) != 3:
-    raise RuntimeError, "blah(int)"
+    raise RuntimeError("blah(int)")
 
 if f.blah(3.5) != 3.5:
-    raise RuntimeError, "blah(double)"
+    raise RuntimeError("blah(double)")
 
 if f.blah("hello") != "hello":
-    raise RuntimeError, "blah(char *)"
+    raise RuntimeError("blah(char *)")
 
 if f.blah(3, 4) != 7:
-    raise RuntimeError, "blah(int,int)"
+    raise RuntimeError("blah(int,int)")
 
 if f.blah(3.5, 7.5) != (3.5 + 7.5):
-    raise RuntimeError, "blah(double,double)"
+    raise RuntimeError("blah(double,double)")
 
 
 if f.duh(3) != 3:
-    raise RuntimeError, "duh(int)"
+    raise RuntimeError("duh(int)")
diff --git a/Examples/test-suite/python/using_inherit_runme.py b/Examples/test-suite/python/using_inherit_runme.py
index 4fd5959..ccdeece 100644
--- a/Examples/test-suite/python/using_inherit_runme.py
+++ b/Examples/test-suite/python/using_inherit_runme.py
@@ -2,47 +2,47 @@
 
 b = Bar()
 if b.test(3) != 3:
-    raise RuntimeError, "Bar::test(int)"
+    raise RuntimeError("Bar::test(int)")
 
 if b.test(3.5) != 3.5:
-    raise RuntimeError, "Bar::test(double)"
+    raise RuntimeError("Bar::test(double)")
 
 
 b = Bar2()
 if b.test(3) != 6:
-    raise RuntimeError, "Bar2::test(int)"
+    raise RuntimeError("Bar2::test(int)")
 
 if b.test(3.5) != 7.0:
-    raise RuntimeError, "Bar2::test(double)"
+    raise RuntimeError("Bar2::test(double)")
 
 
 b = Bar3()
 if b.test(3) != 6:
-    raise RuntimeError, "Bar3::test(int)"
+    raise RuntimeError("Bar3::test(int)")
 
 if b.test(3.5) != 7.0:
-    raise RuntimeError, "Bar3::test(double)"
+    raise RuntimeError("Bar3::test(double)")
 
 
 b = Bar4()
 if b.test(3) != 6:
-    raise RuntimeError, "Bar4::test(int)"
+    raise RuntimeError("Bar4::test(int)")
 
 if b.test(3.5) != 7.0:
-    raise RuntimeError, "Bar4::test(double)"
+    raise RuntimeError("Bar4::test(double)")
 
 
 b = Fred1()
 if b.test(3) != 3:
-    raise RuntimeError, "Fred1::test(int)"
+    raise RuntimeError("Fred1::test(int)")
 
 if b.test(3.5) != 7.0:
-    raise RuntimeError, "Fred1::test(double)"
+    raise RuntimeError("Fred1::test(double)")
 
 
 b = Fred2()
 if b.test(3) != 3:
-    raise RuntimeError, "Fred2::test(int)"
+    raise RuntimeError("Fred2::test(int)")
 
 if b.test(3.5) != 7.0:
-    raise RuntimeError, "Fred2::test(double)"
+    raise RuntimeError("Fred2::test(double)")
diff --git a/Examples/test-suite/python/using_member_multiple_inherit_runme.py b/Examples/test-suite/python/using_member_multiple_inherit_runme.py
new file mode 100644
index 0000000..c7d8109
--- /dev/null
+++ b/Examples/test-suite/python/using_member_multiple_inherit_runme.py
@@ -0,0 +1,32 @@
+from using_member_multiple_inherit import *
+
+# Single inheritance three deep, only using declarations
+s3 = Susing3()
+s3.usingmethod(11)
+
+# Single inheritance three deep, overload using and methods
+u3 = Using3()
+u3.usingmethod(11)
+u3.usingmethod(11, 22)
+u3.usingmethod(11, 22, 33)
+
+m3 = Musing3()
+m3.usingmethod(11)
+m3.usingmethod(11, 22)
+m3.usingmethod(11, 22, 33)
+
+d3 = Dusing3()
+d3.usingmethod(11)
+d3.usingmethod(11, 22)
+
+# Multiple inheritance, multiple using declarations
+ma = MultMiddleA()
+ma.multmethod(123)
+ma.multmethod("hi")
+ma.multmethod(123, 234)
+
+mb = MultBottomB()
+mb.multmethod(123)
+mb.multmethod("hi")
+mb.multmethod(123, 234)
+mb.multmethod(123, 345, 567)
diff --git a/Examples/test-suite/python/using_member_runme.py b/Examples/test-suite/python/using_member_runme.py
new file mode 100644
index 0000000..a0ea648
--- /dev/null
+++ b/Examples/test-suite/python/using_member_runme.py
@@ -0,0 +1,24 @@
+from using_member import *
+
+def swig_assert_equal(a, b):
+	if a != b:
+		raise RuntimeError(str(a) + " != " + str(b))
+
+b = B()
+swig_assert_equal(b.get(int(1)), 10)
+swig_assert_equal(b.get(float(1)), 20)
+
+bb = BB()
+swig_assert_equal(bb.greater(int(1)), 0)
+swig_assert_equal(bb.greater(float(1)), 1)
+swig_assert_equal(bb.great(True), 2)
+
+cc = CC()
+swig_assert_equal(cc.greater(int(10)), 0)
+swig_assert_equal(cc.greater(float(10)), 1)
+swig_assert_equal(cc.greater(True), 20)
+
+dd = DD()
+swig_assert_equal(dd.greater(int(10)), 0)
+swig_assert_equal(dd.greater(float(10)), 1)
+swig_assert_equal(dd.greaterstill(True), 30)
diff --git a/Examples/test-suite/python/using_private_runme.py b/Examples/test-suite/python/using_private_runme.py
index 00c9a8d..9e0a15f 100644
--- a/Examples/test-suite/python/using_private_runme.py
+++ b/Examples/test-suite/python/using_private_runme.py
@@ -4,10 +4,10 @@
 f.x = 3
 
 if f.blah(4) != 4:
-    raise RuntimeError, "blah(int)"
+    raise RuntimeError("blah(int)")
 
 if f.defaulted() != -1:
-    raise RuntimeError, "defaulted()"
+    raise RuntimeError("defaulted()")
 
 if f.defaulted(222) != 222:
-    raise RuntimeError, "defaulted(222)"
+    raise RuntimeError("defaulted(222)")
diff --git a/Examples/test-suite/python/using_protected_runme.py b/Examples/test-suite/python/using_protected_runme.py
index 525a1cd..dd47723 100644
--- a/Examples/test-suite/python/using_protected_runme.py
+++ b/Examples/test-suite/python/using_protected_runme.py
@@ -4,4 +4,4 @@
 f.x = 3
 
 if f.blah(4) != 4:
-    raise RuntimeError, "blah(int)"
+    raise RuntimeError("blah(int)")
diff --git a/Examples/test-suite/python/varargs_overload_runme.py b/Examples/test-suite/python/varargs_overload_runme.py
index 6f5a702..ffa7634 100644
--- a/Examples/test-suite/python/varargs_overload_runme.py
+++ b/Examples/test-suite/python/varargs_overload_runme.py
@@ -1,62 +1,62 @@
 import varargs_overload
 
 if varargs_overload.vararg_over1("Hello") != "Hello":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 if varargs_overload.vararg_over1(2) != "2":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 
 if varargs_overload.vararg_over2("Hello") != "Hello":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 if varargs_overload.vararg_over2(2, 2.2) != "2 2.2":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 
 if varargs_overload.vararg_over3("Hello") != "Hello":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 if varargs_overload.vararg_over3(2, 2.2, "hey") != "2 2.2 hey":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 if varargs_overload.vararg_over4("Hello") != "Hello":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 if varargs_overload.vararg_over4(123) != "123":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 if varargs_overload.vararg_over4("Hello", 123) != "Hello":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 
 # Same as above but non-vararg function declared first
 
 if varargs_overload.vararg_over6("Hello") != "Hello":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 if varargs_overload.vararg_over6(2) != "2":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 
 if varargs_overload.vararg_over7("Hello") != "Hello":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 if varargs_overload.vararg_over7(2, 2.2) != "2 2.2":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 
 if varargs_overload.vararg_over8("Hello") != "Hello":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 if varargs_overload.vararg_over8(2, 2.2, "hey") != "2 2.2 hey":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 if varargs_overload.vararg_over9("Hello") != "Hello":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 if varargs_overload.vararg_over9(123) != "123":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 if varargs_overload.vararg_over9("Hello", 123) != "Hello":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
diff --git a/Examples/test-suite/python/varargs_runme.py b/Examples/test-suite/python/varargs_runme.py
index 277ea75..13f85a7 100644
--- a/Examples/test-suite/python/varargs_runme.py
+++ b/Examples/test-suite/python/varargs_runme.py
@@ -1,31 +1,35 @@
 import varargs
 
 if varargs.test("Hello") != "Hello":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
+
+vc = varargs.VarargConstructor("Hey there")
+if vc.str != "Hey there":
+    raise RuntimeError("Failed")
 
 f = varargs.Foo("Greetings")
 if f.str != "Greetings":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 if f.test("Hello") != "Hello":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 
 if varargs.test_def("Hello", 1) != "Hello":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 if varargs.test_def("Hello") != "Hello":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 ###
 if varargs.test_plenty("Hello") != "Hello":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 if varargs.test_plenty("Hello", 1) != "Hello":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 if varargs.test_plenty("Hello", 1, 2) != "Hello":
-    raise RuntimeError, "Failed"
+    raise RuntimeError("Failed")
 
 try:
     varargs.test_plenty("Hello", 1, 2, 3)
diff --git a/Examples/test-suite/python/virtual_derivation_runme.py b/Examples/test-suite/python/virtual_derivation_runme.py
index 68546c6..21014bd 100644
--- a/Examples/test-suite/python/virtual_derivation_runme.py
+++ b/Examples/test-suite/python/virtual_derivation_runme.py
@@ -4,4 +4,4 @@
 #
 b = B(3)
 if b.get_a() != b.get_b():
-    raise RuntimeError, "something is really wrong"
+    raise RuntimeError("something is really wrong")
diff --git a/Examples/test-suite/python/virtual_poly_runme.py b/Examples/test-suite/python/virtual_poly_runme.py
index 0df6271..6708b6f 100644
--- a/Examples/test-suite/python/virtual_poly_runme.py
+++ b/Examples/test-suite/python/virtual_poly_runme.py
@@ -29,10 +29,10 @@
 #
 # 'narrowing' also works
 #
-ddc = virtual_poly.NDouble_narrow(d.nnumber())
+ddc = virtual_poly.NDouble.narrow(d.nnumber())
 if d.get() != ddc.get():
     raise RuntimeError
 
-dic = virtual_poly.NInt_narrow(i.nnumber())
+dic = virtual_poly.NInt.narrow(i.nnumber())
 if i.get() != dic.get():
     raise RuntimeError
diff --git a/Examples/test-suite/python/voidtest_runme.py b/Examples/test-suite/python/voidtest_runme.py
index b16cacf..dd25b4c 100644
--- a/Examples/test-suite/python/voidtest_runme.py
+++ b/Examples/test-suite/python/voidtest_runme.py
@@ -4,7 +4,7 @@
 f = voidtest.Foo()
 f.memberfunc()
 
-voidtest.Foo_staticmemberfunc()
+voidtest.Foo.staticmemberfunc()
 
 
 def fvoid():
diff --git a/Examples/test-suite/python_abstractbase.i b/Examples/test-suite/python_abstractbase.i
index 2146e75..65f3d99 100644
--- a/Examples/test-suite/python_abstractbase.i
+++ b/Examples/test-suite/python_abstractbase.i
@@ -24,9 +24,3 @@
 bool is_python_builtin() { return false; }
 #endif
 %}
-
-#ifdef SWIGPYTHON_PY3 // set when using -py3
-#define is_swig_py3 1
-#else
-#define is_swig_py3 0
-#endif
diff --git a/Examples/test-suite/python_annotations_c.i b/Examples/test-suite/python_annotations_c.i
new file mode 100644
index 0000000..c023e4d
--- /dev/null
+++ b/Examples/test-suite/python_annotations_c.i
@@ -0,0 +1,40 @@
+%module python_annotations_c
+
+// Tests the C/C++ annotations that were automatically added by using -py3 before swig-4.1.0
+// In swig-4.1.0 and later, the feature below is needed as the -py3 option was dropped
+%feature("python:annotations", "c") mymethod;
+%feature("python:annotations", "c") makeT<short>;
+%feature("python:annotations", "c") global_ints;
+
+%inline %{
+namespace Space {
+template<class T>
+struct Template {
+  void mymethod(int, Template* tt) {}
+};
+}
+template<typename T>
+Space::Template<T> makeT(int x) {
+  return Space::Template<T>();
+};
+int *global_ints(int &ri, Space::Template<short> t) { return &ri; }
+int *global_overloaded(int &ri) { return &ri; }
+int *global_overloaded() { return NULL; }
+int *no_annotations(int &ri, const char *c) { return NULL; }
+%}
+%template(TemplateShort) Space::Template<short>;
+%template(MakeShort) makeT<short>;
+
+%inline %{
+#ifdef SWIGPYTHON_BUILTIN
+int is_python_builtin() { return 1; }
+#else
+int is_python_builtin() { return 0; }
+#endif
+
+#if defined SWIGPYTHON_FASTPROXY
+int is_python_fastproxy() { return 1; }
+#else
+int is_python_fastproxy() { return 0; }
+#endif
+%}
diff --git a/Examples/test-suite/python_annotations_variable_c.i b/Examples/test-suite/python_annotations_variable_c.i
new file mode 100644
index 0000000..876bbee
--- /dev/null
+++ b/Examples/test-suite/python_annotations_variable_c.i
@@ -0,0 +1,44 @@
+%module python_annotations_variable_c
+
+// Tests Python variable annotations, containing C/C++ types, in C++ member variables wrappers.
+// Member variables are wrapped using Python properties.
+// This is in a separate test to python_annotations_c.i (which tests function annotations) so that runtime testing
+// of variable annotations can be done which requires Python 3.6 and later. A syntax error occurs in earlier
+// versions of Python when importing code containing variable annotations.
+
+%feature("python:annotations", "c");
+%feature("python:annotations:novar") member_variable_not_annotated;
+
+
+%inline %{
+namespace Space {
+template<class T>
+struct Template {
+  int member_variable;
+  int member_variable_not_annotated;
+};
+struct StructWithVar{
+  int member_variable;
+};
+struct StructWithVarNotAnnotated {
+  int member_variable_not_annotated;
+};
+short global_variable;
+}
+%}
+%template(TemplateShort) Space::Template<short>;
+
+%inline %{
+#ifdef SWIGPYTHON_BUILTIN
+int is_python_builtin() { return 1; }
+#else
+int is_python_builtin() { return 0; }
+#endif
+
+#if defined SWIGPYTHON_FASTPROXY
+int is_python_fastproxy() { return 1; }
+#else
+int is_python_fastproxy() { return 0; }
+#endif
+%}
+
diff --git a/Examples/test-suite/python_append.i b/Examples/test-suite/python_append.i
index 0494943..883097e 100644
--- a/Examples/test-suite/python_append.i
+++ b/Examples/test-suite/python_append.i
@@ -42,13 +42,31 @@
 %}
 
 %inline %{
-
 class Test {
 public:
   static void static_func() {};
   void funk() {};
 };
+%}
 
+// Github issue #1674
+%extend ForSlots {
+  %pythoncode %{
+        __slots__ = ["this"]
+    %}
+}
+// While __slots__ does not contain 'ValidVariable' in the list, it is still possible
+// to set 'ValidVariable'. A little odd, but the whole attribute setting is bypassed
+// for setting C/C++ member variables.
+// Not sure how to test the equivalent for -builtin.
+%inline %{
+struct ForSlots {
+  int ValidVariable;
+  ForSlots() : ValidVariable(99) {}
+};
+%}
+
+%inline %{
 #ifdef SWIGPYTHON_BUILTIN
 bool is_python_builtin() { return true; }
 #else
diff --git a/Examples/test-suite/python_builtin.i b/Examples/test-suite/python_builtin.i
index 994c625..944cbbe 100644
--- a/Examples/test-suite/python_builtin.i
+++ b/Examples/test-suite/python_builtin.i
@@ -245,3 +245,34 @@
 };
 %}
 
+// Test 8 https://github.com/swig/swig/pull/2771 __setitem__ for deleting item, uses C NULL
+%feature("python:slot", "sq_item", functype="ssizeargfunc") GetSetItem::__getitem__;
+%feature("python:slot", "sq_ass_item", functype="ssizeobjargproc") GetSetItem::__setitem__;
+%feature("python:slot", "tp_call", functype="ternaryfunc") GetSetItem::__call__;
+%typemap(default) PyObject* value {$1 = NULL;}
+
+%inline %{
+class GetSetItem {
+public:
+  int idx, value, args_count, kw_count;
+  GetSetItem() : idx(), value(), args_count(), kw_count() { reset(); }
+  int __getitem__(int idx) {
+    this->idx = idx;
+    return 123;
+  }
+  void __setitem__(int idx, PyObject* value) {
+    this->idx = idx;
+    this->value = value ? (int)PyInt_AsLong(value) : -11;
+  }
+  void __call__(PyObject* args, PyObject* kw) {
+    this->args_count = args ? (int)PyTuple_Size(args) : -11;
+    this->kw_count = kw ? (int)PyDict_Size(kw) : -11;
+  }
+  void reset() {
+    idx = -100;
+    value = -100;
+    args_count = -100;
+    kw_count = -100;
+  }
+};
+%}
diff --git a/Examples/test-suite/python_flatstaticmethod.i b/Examples/test-suite/python_flatstaticmethod.i
new file mode 100644
index 0000000..0e131d6
--- /dev/null
+++ b/Examples/test-suite/python_flatstaticmethod.i
@@ -0,0 +1,40 @@
+%module python_flatstaticmethod
+
+// This testcase tests C++ class static functions when using legacy "flattened"
+// staticmethod access, A_bar, as well as the normal staticmethod access, A.bar.
+
+%callback(1) A::bar;
+%feature("kwargs") A::pub;
+%feature("autodoc","0") A::func0static; // names
+%feature("autodoc","1") A::func1static; // names + types
+// special typemap and its docs
+%typemap(in) (int c, int d) "$1 = 0; $2 = 0;"
+%typemap(doc,name="hello",type="Tuple") (int c, int d) "hello: int tuple[2]"
+
+%extend A {
+static int staticextended(int i) { return i; }
+}
+
+%inline %{
+  struct A {
+    static int bar(int a) {
+      return 2*a;
+    }
+    static int pub(int a = 1, int b = 0) {
+      return a + b;
+    }
+    static int func0static(A *e, short, int c, int d, double f = 2) { return 0; }
+    static int func1static(A *e, short, int c, int d, double f = 2) { return 0; }
+
+    static const char *over(int) { return "over:int"; }
+    static const char *over(double) { return "over:double"; }
+    static const char *over(char *) { return "over:char *"; }
+
+    static int defargs(int xx = 10, int yy = 20) { return xx + yy; }
+  };
+
+  extern "C" int foobar(int a, int (*pf)(int a)) {
+    return pf(a);
+  }
+%}
+
diff --git a/Examples/test-suite/python_pickle.i b/Examples/test-suite/python_pickle.i
index fbb3d05..10be972 100644
--- a/Examples/test-suite/python_pickle.i
+++ b/Examples/test-suite/python_pickle.i
@@ -14,7 +14,7 @@
 #else
   // Equivalent to Python code above
   PyObject *__reduce__() {
-    if (debug)
+    if (trace)
       std::cout << "In C++ __reduce__" << std::endl;
     PyObject *args = PyTuple_New(1);
     PyTuple_SetItem(args, 0, SWIG_From_std_string(self->msg));
@@ -39,12 +39,12 @@
 %inline %{
 #include <iostream>
 
-bool debug = false;
+bool trace = false;
 
 struct PickleMe {
   std::string msg;
   PickleMe(const std::string& msg) : msg(msg) {
-    if (debug)
+    if (trace)
       std::cout << "In C++ constructor " << " [" << msg << "]" << std::endl;
   }
 };
diff --git a/Examples/test-suite/python_richcompare.i b/Examples/test-suite/python_richcompare.i
index 142d059..a396009 100644
--- a/Examples/test-suite/python_richcompare.i
+++ b/Examples/test-suite/python_richcompare.i
@@ -56,5 +56,67 @@
     bool operator== (const SubClassA& x) const
     { return false; }
 };
+}
 
+// Test custom exceptions can still be thrown in operators which use %pythonmaybecall
+%{
+struct ZeroValueProblem {
+    ZeroValueProblem() {}
+};
+%}
+
+%exception ExceptionThrower::operator< {
+    try
+    {
+        $action
+    }
+    catch(const ZeroValueProblem&)
+    {
+        PyErr_SetString(PyExc_ValueError, "Zero not liked in operator<");
+        SWIG_fail;
+    }
+}
+
+%inline {
+class ExceptionThrower {
+    int i;
+public:
+    ExceptionThrower (int i_) : i(i_) {}
+    bool operator< (const ExceptionThrower& rhs) const {
+        if (rhs.i == 0 || i == 0)
+            throw ZeroValueProblem();
+        return this->i < rhs.i;
+    }
+};
+}
+
+%exception SubClassCThrower::operator== {
+    try
+    {
+        $action
+    }
+    catch(const ZeroValueProblem&)
+    {
+        PyErr_SetString(PyExc_ValueError, "Zero not liked in operator==");
+        SWIG_fail;
+    }
+}
+
+// Overloaded operators and custom exceptions
+%inline {
+class SubClassCThrower : public BaseClass {
+public:
+    SubClassCThrower (int i_) : BaseClass(i_) {}
+    ~SubClassCThrower () {}
+
+    bool operator== (const SubClassCThrower& rhs) const
+    {
+        if (rhs.i == 0 || i == 0)
+            throw ZeroValueProblem();
+        return rhs.i == i;
+    }
+
+    bool operator== (const SubClassA& rhs) const
+    { return rhs.i == i; }
+};
 }
diff --git a/Examples/test-suite/python_runtime_data.list b/Examples/test-suite/python_runtime_data.list
new file mode 100644
index 0000000..e88ef0c
--- /dev/null
+++ b/Examples/test-suite/python_runtime_data.list
@@ -0,0 +1,2 @@
+python_runtime_data_builtin
+python_runtime_data_nobuiltin
diff --git a/Examples/test-suite/python_runtime_data_builtin.i b/Examples/test-suite/python_runtime_data_builtin.i
new file mode 100644
index 0000000..546ccda
--- /dev/null
+++ b/Examples/test-suite/python_runtime_data_builtin.i
@@ -0,0 +1,21 @@
+// Test swig_runtime_data with and without -builtin
+
+%module python_runtime_data_builtin
+
+%begin %{
+#if defined(Py_LIMITED_API)
+#undef Py_LIMITED_API // not yet supported by builtin
+#endif
+%}
+
+%inline %{
+#ifdef SWIGPYTHON_BUILTIN
+bool is_python_builtin() { return true; }
+#else
+bool is_python_builtin() { return false; }
+#endif
+%}
+
+%include std_vector.i
+
+%template(vectord) std::vector<double>;
diff --git a/Examples/test-suite/python_runtime_data_nobuiltin.i b/Examples/test-suite/python_runtime_data_nobuiltin.i
new file mode 100644
index 0000000..18c0414
--- /dev/null
+++ b/Examples/test-suite/python_runtime_data_nobuiltin.i
@@ -0,0 +1,3 @@
+%module python_runtime_data_nobuiltin
+
+%include "python_runtime_data_builtin.i"
diff --git a/Examples/test-suite/python_typemap_macro.i b/Examples/test-suite/python_typemap_macro.i
new file mode 100644
index 0000000..15d78e3
--- /dev/null
+++ b/Examples/test-suite/python_typemap_macro.i
@@ -0,0 +1,125 @@
+%module python_typemap_macro
+
+/*
+This testcase pushes $typemap() to the limit, but does show how the UTL could be replaced with a different approach.
+
+It results in very bloated code as all the typemaps expanded by $typemap() are inline and recursive use such as with
+containers of containers or pairs of pairs demonstrated here.
+The other gotcha using this approach is using local variables declared within the typemap body does not usually work
+if the typemaps are recursively called and the temporary variables are used for typemap outputs, such as $1 or $result.
+Using typemap temporary variables does work around this, such as temp in:
+  %typemap(out) (int temp) { ... }
+This works as each typemap temporary is renamed and given a unique numeric suffix, for example temp1, temp2.
+
+Consider this approach to using typemaps experimental and use at your own risk!
+*/
+
+
+%include <std_string.i>
+
+#if 0
+%include <std_pair.i>
+#else
+namespace std {
+  template <class T, class U > struct pair {
+
+// Adaption of PyObject *swig::traits_from<std::pair<T,U> >::from((const std::pair<T,U>& val)) in Lib/python/std_pair.i
+%typemap(out) pair(PyObject *resultobj_pair_first, PyObject *resultobj_pair_second) {
+  /* pair out $1_type start */
+  $result = PyTuple_New(2);
+
+  $typemap(out, T, 1=$1.first, result=resultobj_pair_first)
+  PyTuple_SetItem($result, 0, resultobj_pair_first);
+
+  $typemap(out, U, 1=$1.second, result=resultobj_pair_second)
+  PyTuple_SetItem($result, 1, resultobj_pair_second);
+  /* pair out $1_type end */
+}
+
+// Adaption of int traits_asptr<std::pair<T,U> >::asptr(PyObject *obj, std::pair<T,U> **val) in Lib/python/std_pair.i
+%typemap(in) pair {
+  /* pair in $1_type start */
+  PyObject *obj = $input;
+  if (PyTuple_Check(obj) && PyTuple_GET_SIZE(obj) == 2) {
+    PyObject *first = PyTuple_GET_ITEM(obj, 0);
+    PyObject *second = PyTuple_GET_ITEM(obj, 1);
+    $typemap(in, T, input=first, 1=$1.first)
+    $typemap(in, U, input=second, 1=$1.second)
+  } else if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
+    swig::SwigVar_PyObject first = PySequence_GetItem(obj, 0);
+    swig::SwigVar_PyObject second = PySequence_GetItem(obj, 1);
+    $typemap(in, T, input=(PyObject*)first, 1=$1.first)
+    $typemap(in, U, input=(PyObject*)second, 1=$1.second)
+  } else {
+    void *argp;
+    int res = SWIG_ConvertPtr($input, &argp, $&descriptor, 0);
+    if (!SWIG_IsOK(res)) {
+      %argument_fail(res, "$type", $symname, $argnum);
+    }
+    if (!argp) {
+      %argument_nullref("$type", $symname, $argnum);
+    } else {
+      $&ltype temp = %reinterpret_cast(argp, $&ltype);
+      $1 = *temp;
+      if (SWIG_IsNewObj(res)) %delete(temp);
+    }
+  }
+  /* pair in $1_type end */
+}
+
+%typemap(typecheck) pair {
+  /* pair typecheck $1_type start */
+  PyObject *obj = $input;
+  if (PyTuple_Check(obj) && PyTuple_GET_SIZE(obj) == 2) {
+    PyObject *first = PyTuple_GET_ITEM(obj, 0);
+    PyObject *second = PyTuple_GET_ITEM(obj, 1);
+    $typemap(typecheck, T, input=first)
+    if ($1) {
+      $typemap(typecheck, U, input=second)
+    }
+  } else if (PySequence_Check(obj) && PySequence_Size(obj) == 2) {
+    swig::SwigVar_PyObject first = PySequence_GetItem(obj, 0);
+    swig::SwigVar_PyObject second = PySequence_GetItem(obj, 1);
+    $typemap(typecheck, T, input=(PyObject*)first)
+    if ($1) {
+      $typemap(typecheck, U, input=(PyObject*)second)
+    }
+  } else {
+    void *vptr = 0;
+    int res = SWIG_ConvertPtr($input, &vptr, $&descriptor, SWIG_POINTER_NO_NULL);
+    $1 = SWIG_CheckState(res);
+  }
+  /* pair typecheck $1_type end */
+}
+
+    typedef T first_type;
+    typedef U second_type;
+    pair();
+    pair(T first, U second);
+//    pair(const pair& other); // TODO: similar typemaps for pair&
+    pair(pair other);
+
+    template <class U1, class U2> pair(const pair< U1, U2 > &other);
+
+    T first;
+    U second;
+};
+}
+#endif
+
+%template(PairStringInt) std::pair<std::string, int>;
+%template(PairCharPairStringInt) std::pair<char, std::pair<std::string, int> >;
+
+%inline %{
+std::pair<std::string, int> PairInputOutput(std::pair<std::string, int> ppp) {
+  return ppp;
+}
+std::pair<char, std::pair<std::string, int> > PairInputOutput2(std::pair<char, std::pair<std::string, int> > p) {
+  return p;
+}
+std::pair<char, std::pair<std::string, int> > MakePair() {
+  return std::pair<char, std::pair<std::string, int> >('x', std::pair<std::string, int>("outstring", 111));
+}
+/*
+*/
+%}
diff --git a/Examples/test-suite/python_varargs_typemap.i b/Examples/test-suite/python_varargs_typemap.i
index d809bf1..65ce72f 100644
--- a/Examples/test-suite/python_varargs_typemap.i
+++ b/Examples/test-suite/python_varargs_typemap.i
@@ -17,21 +17,25 @@
     PyObject *pyobj = PyTuple_GetItem(varargs, i);
     char *str = 0;
 %#if PY_VERSION_HEX>=0x03000000
+    const char *strtmp = 0;
     PyObject *pystr;
     if (!PyUnicode_Check(pyobj)) {
-       PyErr_SetString(PyExc_ValueError, "Expected a string");
-       SWIG_fail;
+      PyErr_SetString(PyExc_ValueError, "Expected a string");
+      SWIG_fail;
     }
     pystr = PyUnicode_AsUTF8String(pyobj);
     if (!pystr) {
       SWIG_fail;
     }
-    str = strdup(PyBytes_AsString(pystr));
+    strtmp = PyBytes_AsString(pystr);
+    str = (char *)malloc(strlen(strtmp) + 1);
+    if (str)
+      strcpy(str, strtmp);
     Py_DECREF(pystr);
 %#else  
     if (!PyString_Check(pyobj)) {
-       PyErr_SetString(PyExc_ValueError, "Expected a string");
-       SWIG_fail;
+      PyErr_SetString(PyExc_ValueError, "Expected a string");
+      SWIG_fail;
     }
     str = PyString_AsString(pyobj);
 %#endif
diff --git a/Examples/test-suite/r/Makefile.in b/Examples/test-suite/r/Makefile.in
index 33e9d90..78cc4bb 100644
--- a/Examples/test-suite/r/Makefile.in
+++ b/Examples/test-suite/r/Makefile.in
@@ -8,6 +8,10 @@
 R_OPT        = --quiet --no-save --no-restore
 RUNR         = R CMD BATCH $(R_OPT) '--args $(SCRIPTDIR)'
 
+HAVE_CXX11   = @HAVE_CXX11@
+HAVE_CXX14   = @HAVE_CXX14@
+HAVE_CXX17   = @HAVE_CXX17@
+HAVE_CXX20   = @HAVE_CXX20@
 srcdir       = @srcdir@
 top_srcdir   = @top_srcdir@
 top_builddir = @top_builddir@
diff --git a/Examples/test-suite/r/abstract_access_runme.R b/Examples/test-suite/r/abstract_access_runme.R
new file mode 100644
index 0000000..f6fb409
--- /dev/null
+++ b/Examples/test-suite/r/abstract_access_runme.R
@@ -0,0 +1,74 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+
+dyn.load(paste("abstract_access", .Platform$dynlib.ext, sep=""))
+source("abstract_access.R")
+
+dd <- D()
+unittest(1, dd$z())
+unittest(1, dd$do_x())
+
+## Original version allowed dd$z <- 2
+tryCatch({
+    dd$z <- 2
+    # force an error if the previous line doesn't raise an exception
+    stop("Test Failure A")
+}, error = function(e) {
+    if (e$message == "Test Failure A") {
+      # Raise the error again to cause a failed test
+      stop(e)
+    }
+    message("Correct - no dollar assignment method found")
+}
+)
+
+tryCatch({
+    dd[["z"]] <- 2
+    # force an error if the previous line doesn't raise an exception
+    stop("Test Failure B")
+}, error = function(e) {
+  if (e$message == "Test Failure B") {
+    # Raise the error again to cause a failed test
+    stop(e)
+  }
+  message("Correct - no dollar assignment method found")
+}
+)
+
+## The methods are attached to the parent class - see if we can get
+## them
+tryCatch({
+    m1 <- getMethod('$', "_p_A")
+}, error = function(e) {
+    stop("No $ method found - there should be one")
+}
+)
+
+## These methods should not be present
+## They correspond to the tests that are expected
+## to fail above.
+tryCatch({
+    m2 <- getMethod('$<-', "_p_A")
+    # force an error if the previous line doesn't raise an exception
+    stop("Test Failure C")
+}, error = function(e) {
+  if (e$message == "Test Failure C") {
+    # Raise the error again to cause a failed test
+    stop(e)
+  }
+  message("Correct - no dollar assignment method found")
+}
+)
+
+tryCatch({
+    m3 <- getMethod('[[<-', "_p_A")
+    # force an error if the previous line doesn't raise an exception
+    stop("Test Failure D")
+}, error = function(e) {
+  if (e$message == "Test Failure D") {
+    # Raise the error again to cause a failed test
+    stop(e)
+  }
+  message("Correct - no list assignment method found")
+}
+)
diff --git a/Examples/test-suite/r/argcargvtest_runme.R b/Examples/test-suite/r/argcargvtest_runme.R
new file mode 100644
index 0000000..bbb4747
--- /dev/null
+++ b/Examples/test-suite/r/argcargvtest_runme.R
@@ -0,0 +1,49 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+dyn.load(paste("argcargvtest", .Platform$dynlib.ext, sep=""))
+source("argcargvtest.R")
+cacheMetaData(1)
+
+largs = c("hi", "hola", "hello")
+unittest(3, mainc(largs))
+
+targs = c("hi", "hola")
+unittest("hi", mainv(targs, 0))
+unittest("hola", mainv(targs, 1))
+unittest("<<NULL>>", mainv(targs, 2))
+
+# R convert the string to a string vector with a single string.
+# So instead of exception we simply get null
+unittest(NULL, mainv("hello", 1))
+
+tryCatch({
+    mainv(c(1, 2, 3), 1)
+    # force an error if the previous line doesn't raise an exception
+    stop("Test Failure A")
+}, error = function(e) {
+    if (e$message == "Test Failure A") {
+      # Raise the error again to cause a failed test
+      stop(e)
+    }
+    message("PASS")
+})
+
+initializeApp(largs)
+initializeApp(largs, TRUE)
+
+# Check that an empty array works.
+empty_args = c()
+unittest(0, mainc(empty_args))
+unittest("<<NULL>>", mainv(empty_args, 0))
+
+# check dispatcher with empty array.
+initializeApp(empty_args)
+initializeApp(empty_args, FALSE, TRUE)
+
+# Check that empty strings are handled.
+empty_string = c("hello", "", "world")
+unittest(3, mainc(empty_string))
+unittest("hello", mainv(empty_string, 0))
+unittest("", mainv(empty_string, 1))
+unittest("world", mainv(empty_string, 2))
+unittest("<<NULL>>", mainv(empty_string, 3))
diff --git a/Examples/test-suite/r/catches_strings_runme.R b/Examples/test-suite/r/catches_strings_runme.R
new file mode 100644
index 0000000..db6783d
--- /dev/null
+++ b/Examples/test-suite/r/catches_strings_runme.R
@@ -0,0 +1,24 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+
+dyn.load(paste("catches_strings", .Platform$dynlib.ext, sep=""))
+source("catches_strings.R")
+cacheMetaData(1)
+
+exception_thrown = FALSE
+tryCatch({
+    StringsThrower_charstring()
+}, error = function(e) {
+    exception_thrown <<- grepl(e$message, "charstring message", fixed=TRUE)
+}
+)
+unittest(exception_thrown, TRUE)
+
+exception_thrown = FALSE
+tryCatch({
+    StringsThrower_stdstring()
+}, error = function(e) {
+    exception_thrown <<- grepl(e$message, "stdstring message", fixed=TRUE)
+}
+)
+unittest(exception_thrown, TRUE)
diff --git a/Examples/test-suite/r/constant_pointers_runme.R b/Examples/test-suite/r/constant_pointers_runme.R
new file mode 100644
index 0000000..d6f1c94
--- /dev/null
+++ b/Examples/test-suite/r/constant_pointers_runme.R
@@ -0,0 +1,13 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+
+dyn.load(paste("constant_pointers", .Platform$dynlib.ext, sep=""))
+source("constant_pointers.R")
+cacheMetaData(1)
+
+myb <- B()
+bret = bar(myb)
+bret2 = cbar(myb)
+bret3 = bar(bret2)
+
+q(save="no")
diff --git a/Examples/test-suite/r/exception_memory_leak_runme.R b/Examples/test-suite/r/exception_memory_leak_runme.R
new file mode 100644
index 0000000..889fbed
--- /dev/null
+++ b/Examples/test-suite/r/exception_memory_leak_runme.R
@@ -0,0 +1,39 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+
+dyn.load(paste("exception_memory_leak", .Platform$dynlib.ext, sep=""))
+source("exception_memory_leak.R")
+cacheMetaData(1)
+
+a <- Foo();
+unittest(Foo_get_count(), 1);
+b <- Foo();
+unittest(Foo_get_count(), 2);
+
+# Normal behaviour
+invisible(trigger_internal_swig_exception("no problem", a));
+unittest(Foo_get_count(), 2);
+unittest(Foo_get_freearg_count(), 1);
+# SWIG exception introduced (return new object case).
+result <- tryCatch({
+  trigger_internal_swig_exception("null", b);
+}, warning = function(w) {
+  # print("        Hum... We received a warning, but this should be an error");
+  unittest(1,0);
+}, error = function(e) {
+  # print("        Gotcha!");
+  unittest(1,1);
+})
+unittest(Foo_get_count(), 2);
+unittest(Foo_get_freearg_count(), 2);
+# SWIG exception introduced (return by value case).
+result <- tryCatch({
+  trigger_internal_swig_exception("null");
+}, warning = function(w) {
+  # print("        Hum... We received a warning, but this should be an error");
+  unittest(1,0);
+}, error = function(e) {
+  # print("        Gotcha!");
+  unittest(1,1);
+})
+unittest(Foo_get_count(), 2);
diff --git a/Examples/test-suite/r/extend_template_method_runme.R b/Examples/test-suite/r/extend_template_method_runme.R
new file mode 100644
index 0000000..eaeb69a
--- /dev/null
+++ b/Examples/test-suite/r/extend_template_method_runme.R
@@ -0,0 +1,50 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+#source("unittest.R")
+
+dyn.load(paste("extend_template_method", .Platform$dynlib.ext, sep=""))
+source("extend_template_method.R")
+cacheMetaData(1)
+
+
+em = ExtendMe()
+
+ret_double = em$do_stuff_double(1, 1.1)
+unittest(ret_double, 1.1)
+
+ret_string = em$do_stuff_string(1, "hello there")
+unittest(ret_string, "hello there")
+
+ret_double = em$do_overloaded_stuff(1.1)
+unittest(ret_double, 1.1)
+
+ret_string = em$do_overloaded_stuff("hello there")
+unittest(ret_string, "hello there")
+
+
+unittest(ExtendMe_static_method(123), 123)
+
+em2 = ExtendMe(123)
+
+em = TemplateExtend()
+
+ret_double = em$do_template_stuff_double(1, 1.1)
+unittest(ret_double, 1.1)
+
+ret_string = em$do_template_stuff_string(1, "hello there")
+unittest(ret_string, "hello there")
+
+
+ret_double = em$do_template_overloaded_stuff(1.1)
+unittest(ret_double, 1.1)
+
+ret_string = em$do_template_overloaded_stuff("hello there")
+unittest(ret_string, "hello there")
+
+unittest(TemplateExtend_static_template_method(123), 123)
+
+
+em2 = TemplateExtend(123)
+
+
+q(save="no")
diff --git a/Examples/test-suite/r/li_attribute_template_runme.R b/Examples/test-suite/r/li_attribute_template_runme.R
new file mode 100644
index 0000000..2f1510e
--- /dev/null
+++ b/Examples/test-suite/r/li_attribute_template_runme.R
@@ -0,0 +1,68 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+#source("unittest.R")
+
+dyn.load(paste("li_attribute_template", .Platform$dynlib.ext, sep=""))
+source("li_attribute_template.R")
+cacheMetaData(1)
+
+
+# Check usage of template attributes
+chell = Cintint(1, 2, 3)
+
+# Testing primitive by value attribute
+unittest(chell$a, 1)
+
+chell$a = 3
+unittest(chell$a, 3)
+
+# Testing primitive by ref attribute
+unittest(chell$b, 2)
+
+chell$b = 5
+unittest(chell$b, 5)
+
+# Testing string
+chell$str = "abc"
+unittest(chell$str, "abc")
+
+# Testing class by value
+unittest(chell$d$value, 1)
+
+chell$d = Foo(2)
+unittest(chell$d$value, 2)
+
+# Testing class by reference
+unittest(chell$e$value, 2)
+
+chell$e = Foo(3)
+unittest(chell$e$value, 3)
+
+chell$e$value = 4
+unittest(chell$e$value, 4)
+
+
+# Testing moderately complex template by value
+unittest(chell$f$first, 1)
+unittest(chell$f$second, 2)
+
+pair = pair_intint(3, 4)
+chell$f = pair
+unittest(chell$f$first, 3)
+unittest(chell$f$second, 4)
+
+# Testing moderately complex template by ref
+unittest(chell$g$first, 2)
+unittest(chell$g$second, 3)
+
+pair = pair_intint(4, 5)
+chell$g = pair
+unittest(chell$g$first, 4)
+unittest(chell$g$second, 5)
+
+chell$g$first = 6
+chell$g$second = 7
+unittest(chell$g$first, 6)
+unittest(chell$g$second, 7)
+
+q(save="no")
diff --git a/Examples/test-suite/r/li_boost_shared_ptr_runme.R b/Examples/test-suite/r/li_boost_shared_ptr_runme.R
new file mode 100644
index 0000000..0b0a0b7
--- /dev/null
+++ b/Examples/test-suite/r/li_boost_shared_ptr_runme.R
@@ -0,0 +1,720 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+#source("unittest.R")
+
+dyn.load(paste("li_boost_shared_ptr", .Platform$dynlib.ext, sep=""))
+source("li_boost_shared_ptr.R")
+cacheMetaData(1)
+
+# simple shared_ptr usage - created in C++
+
+invisible(debug_shared(TRUE))
+unittest(debug_shared(), TRUE)
+
+
+# Expect 1 instance - the one global variable (GlobalValue)
+unittest(Klass_getTotal_count(), 1)
+
+# Change loop count to run for a long time to monitor memory
+unittest(shared_ptr_wrapper_count(), NOT_COUNTING())
+
+
+#
+# test suite to be run in a loop
+#
+
+testSuite_verifyCount <- function(expected, k) {
+  got = use_count(k)
+  unittest(expected, got);
+}
+
+testSuite <- function() {
+
+  #
+  # Reference Implementation is li_boost_shared_ptr_runme.py
+  #
+
+  # simple shared_ptr usage - created in C++
+  {
+    k = Klass("me oh my")
+    val = k$getValue()
+    unittest("me oh my", val)
+    testSuite_verifyCount(1, k)
+  }
+
+  # simple shared_ptr usage - not created in C++
+  {
+    k = factorycreate()
+    val = k$getValue()
+    unittest("factorycreate", val)
+    testSuite_verifyCount(1, k)
+  }
+
+  # pass by shared_ptr
+  {
+    k = Klass("me oh my")
+    kret = smartpointertest(k)
+    val = kret$getValue()
+    unittest("me oh my smartpointertest", val)
+    testSuite_verifyCount(2, k)
+    testSuite_verifyCount(2, kret)
+  }
+
+  # pass by shared_ptr pointer
+  {
+    k = Klass("me oh my")
+    kret = smartpointerpointertest(k)
+    val = kret$getValue()
+    unittest("me oh my smartpointerpointertest", val)
+    testSuite_verifyCount(2, k)
+    testSuite_verifyCount(2, kret)
+  }
+
+  # pass by shared_ptr reference
+  {
+    k = Klass("me oh my")
+    kret = smartpointerreftest(k)
+    val = kret$getValue()
+    unittest("me oh my smartpointerreftest", val)
+    testSuite_verifyCount(2, k)
+    testSuite_verifyCount(2, kret)
+  }
+
+  # pass by shared_ptr pointer reference
+  {
+    k = Klass("me oh my")
+    kret = smartpointerpointerreftest(k)
+    val = kret$getValue()
+    unittest("me oh my smartpointerpointerreftest", val)
+    testSuite_verifyCount(2, k)
+    testSuite_verifyCount(2, kret)
+  }
+
+  # const pass by shared_ptr
+  {
+    k = Klass("me oh my");
+    kret = constsmartpointertest(k);
+    val = Klass_getValue(kret);
+    unittest("me oh my", val);
+    testSuite_verifyCount(2, k);
+    testSuite_verifyCount(2, kret);
+  }
+
+  # const pass by shared_ptr pointer
+  {
+    k = Klass("me oh my")
+    kret = constsmartpointerpointertest(k)
+    val = Klass_getValue(kret)
+    unittest("me oh my", val)
+    testSuite_verifyCount(2, k)
+    testSuite_verifyCount(2, kret)
+  }
+
+  # const pass by shared_ptr reference
+  {
+    k = Klass("me oh my")
+    kret = constsmartpointerreftest(k)
+    val = Klass_getValue(kret)
+    unittest("me oh my", val)
+    testSuite_verifyCount(2, k)
+    testSuite_verifyCount(2, kret)
+  }
+
+  # pass by value
+  {
+    k = Klass("me oh my");
+    kret = valuetest(k);
+    val = kret$getValue();
+    unittest("me oh my valuetest", val);
+    testSuite_verifyCount(1, k);
+    testSuite_verifyCount(1, kret);
+  }
+
+  # pass by pointer
+  {
+    k = Klass("me oh my");
+    kret = pointertest(k);
+    val = kret$getValue();
+    unittest("me oh my pointertest", val);
+    testSuite_verifyCount(1, k);
+    testSuite_verifyCount(1, kret);
+  }
+
+  # pass by reference
+  {
+    k = Klass("me oh my");
+    kret = reftest(k);
+    val = kret$getValue();
+    unittest("me oh my reftest", val);
+    testSuite_verifyCount(1, k);
+    testSuite_verifyCount(1, kret);
+  }
+
+  # pass by pointer reference
+  {
+    k = Klass("me oh my");
+    kret = pointerreftest(k);
+    val = kret$getValue();
+    unittest("me oh my pointerreftest", val);
+    testSuite_verifyCount(1, k);
+    testSuite_verifyCount(1, kret);
+  }
+
+  # null tests
+  {
+    k = NULL
+
+    if (!is.null(smartpointertest(k))) {
+      stop("return was not null");
+    }
+
+    if (!is.null(smartpointerpointertest(k))) {
+      stop("return was not null");
+    }
+
+    if (!is.null(smartpointerreftest(k))) {
+      stop("return was not null");
+    }
+
+    if (!is.null(smartpointerpointerreftest(k))) {
+      stop("return was not null");
+    }
+
+    if (nullsmartpointerpointertest(k) != "null pointer") {
+      stop("not null smartpointer pointer");
+    }
+
+    bNotCatched = F
+    try({
+      valuetest(k);
+      bNotCatched = T
+    }, silent = T)
+    if (bNotCatched) {
+      stop("Failed to catch null pointer");
+    }
+
+   if (!is.null(pointertest(k))) {
+      stop("return was not null");
+    }
+
+    bNotCatched = F
+    try({
+      reftest(k);
+      bNotCatched = T
+    }, silent = T)
+    if (bNotCatched) {
+      stop("Failed to catch null pointer");
+    }
+
+    # test null pointers emitted from C++
+
+    k = sp_pointer_null()
+    if (!is.null(k)) {
+      stop("return was not null")
+    }
+
+    k = null_sp_pointer()
+    if (!is.null(k)) {
+      stop("return was not null")
+    }
+
+    k = sp_value_null()
+    if (!is.null(k)) {
+      stop("return was not null")
+    }
+  }
+
+  # $owner
+  {
+    k = pointerownertest();
+    val = k$getValue();
+    unittest("pointerownertest", val);
+    testSuite_verifyCount(1, k);
+  }
+
+  {
+    k = smartpointerpointerownertest();
+    val = k$getValue();
+    unittest("smartpointerpointerownertest", val);
+    testSuite_verifyCount(1, k);
+  }
+
+  #
+  # ###################### Derived class ######################
+  #
+
+  # derived pass by shared_ptr
+  {
+    k = KlassDerived("me oh my")
+    kret = derivedsmartptrtest(k)
+    val = kret$getValue()
+    unittest("me oh my derivedsmartptrtest-Derived", val)
+    testSuite_verifyCount(2, k)
+    testSuite_verifyCount(2, kret)
+  }
+
+  # derived pass by shared_ptr pointer
+  {
+    k = KlassDerived("me oh my")
+    kret = derivedsmartptrpointertest(k)
+    val = kret$getValue()
+    unittest("me oh my derivedsmartptrpointertest-Derived", val)
+    testSuite_verifyCount(2, k)
+    testSuite_verifyCount(2, kret)
+  }
+
+  # derived pass by shared_ptr ref
+  {
+    k = KlassDerived("me oh my")
+    kret = derivedsmartptrreftest(k)
+    val = kret$getValue()
+    unittest("me oh my derivedsmartptrreftest-Derived", val)
+    testSuite_verifyCount(2, k)
+    testSuite_verifyCount(2, kret)
+  }
+
+  # derived pass by shared_ptr pointer ref
+  {
+    k = KlassDerived("me oh my")
+    kret = derivedsmartptrpointerreftest(k)
+    val = kret$getValue()
+    unittest("me oh my derivedsmartptrpointerreftest-Derived", val)
+    testSuite_verifyCount(2, k)
+    testSuite_verifyCount(2, kret)
+  }
+
+  # derived pass by pointer
+  {
+    k = KlassDerived("me oh my")
+    kret = derivedpointertest(k)
+    val = kret$getValue()
+    unittest("me oh my derivedpointertest-Derived", val)
+    testSuite_verifyCount(1, k)
+    testSuite_verifyCount(1, kret)
+  }
+
+  # derived pass by ref
+  {
+    k = KlassDerived("me oh my")
+    kret = derivedreftest(k)
+    val = kret$getValue()
+    unittest("me oh my derivedreftest-Derived", val)
+    testSuite_verifyCount(1, k)
+    testSuite_verifyCount(1, kret)
+  }
+
+  #
+  # ###################### Derived and base class mixed ######################
+  #
+  # pass by shared_ptr (mixed)
+  {
+    k = KlassDerived("me oh my")
+    kret = smartpointertest(k)
+    val = kret$getValue()
+    unittest("me oh my smartpointertest-Derived", val)
+    testSuite_verifyCount(2, k)
+    testSuite_verifyCount(2, kret)
+  }
+
+  # pass by shared_ptr pointer (mixed)
+  {
+    k = KlassDerived("me oh my")
+    kret = smartpointerpointertest(k)
+    val = kret$getValue()
+    unittest("me oh my smartpointerpointertest-Derived", val)
+    testSuite_verifyCount(2, k)
+    testSuite_verifyCount(2, kret)
+  }
+
+  # pass by shared_ptr reference (mixed)
+  {
+    k = KlassDerived("me oh my")
+    kret = smartpointerreftest(k)
+    val = kret$getValue()
+    unittest("me oh my smartpointerreftest-Derived", val)
+    testSuite_verifyCount(2, k)
+    testSuite_verifyCount(2, kret)
+  }
+
+  # pass by shared_ptr pointer reference (mixed)
+  {
+    k = KlassDerived("me oh my")
+    kret = smartpointerpointerreftest(k)
+    val = kret$getValue()
+    unittest("me oh my smartpointerpointerreftest-Derived", val)
+    testSuite_verifyCount(2, k)
+    testSuite_verifyCount(2, kret)
+  }
+
+  # pass by value (mixed)
+  {
+    k = KlassDerived("me oh my")
+    kret = valuetest(k)
+    val = kret$getValue()
+    unittest("me oh my valuetest", val)  # note slicing
+    testSuite_verifyCount(1, k)
+    testSuite_verifyCount(1, kret)
+  }
+
+  # pass by pointer (mixed)
+  {
+    k = KlassDerived("me oh my")
+    kret = pointertest(k)
+    val = kret$getValue()
+    unittest("me oh my pointertest-Derived", val)
+    testSuite_verifyCount(1, k)
+    testSuite_verifyCount(1, kret)
+  }
+
+  # pass by ref (mixed)
+  {
+    k = KlassDerived("me oh my")
+    kret = reftest(k)
+    val = kret$getValue()
+    unittest("me oh my reftest-Derived", val)
+    testSuite_verifyCount(1, k)
+    testSuite_verifyCount(1, kret)
+  }
+
+
+  #
+  # ################# Overloading tests ##################
+  #
+
+  # Base class
+  {
+    k = Klass("me oh my");
+
+    unittest(overload_rawbyval(k), "rawbyval")
+    unittest(overload_rawbyref(k), "rawbyref")
+    unittest(overload_rawbyptr(k), "rawbyptr")
+    unittest(overload_rawbyptrref(k), "rawbyptrref")
+
+    unittest(overload_smartbyval(k), "smartbyval")
+    unittest(overload_smartbyref(k), "smartbyref")
+    unittest(overload_smartbyptr(k), "smartbyptr")
+    unittest(overload_smartbyptrref(k), "smartbyptrref")
+  }
+
+  # Derived class
+  {
+    k = KlassDerived("me oh my")
+
+    unittest(overload_rawbyval(k), "rawbyval")
+    unittest(overload_rawbyref(k), "rawbyref")
+    unittest(overload_rawbyptr(k), "rawbyptr")
+    unittest(overload_rawbyptrref(k), "rawbyptrref")
+
+    unittest(overload_smartbyval(k), "smartbyval")
+    unittest(overload_smartbyref(k), "smartbyref")
+    unittest(overload_smartbyptr(k), "smartbyptr")
+    unittest(overload_smartbyptrref(k), "smartbyptrref")
+  }
+
+  # 3rd derived class
+  {
+    k = Klass3rdDerived("me oh my")
+
+    val = k$getValue()
+    unittest("me oh my-3rdDerived", val)
+    testSuite_verifyCount(1, k)
+    val = test3rdupcast(k)
+    unittest("me oh my-3rdDerived", val)
+    testSuite_verifyCount(1, k)
+  }
+
+  #
+  # ################ Member variables ####################
+  #
+
+  # smart pointer by value
+  {
+    m = MemberVariables();
+    k = Klass("smart member value");
+    m$SmartMemberValue = k;
+
+    val = k$getValue();
+    unittest("smart member value", val);
+    testSuite_verifyCount(2, k);
+
+    kmember = m$SmartMemberValue;
+    val = kmember$getValue();
+    unittest("smart member value", val);
+    testSuite_verifyCount(3, kmember);
+    testSuite_verifyCount(3, k);
+
+    delete_MemberVariables(m)
+    testSuite_verifyCount(2, kmember);
+    testSuite_verifyCount(2, k);
+  }
+
+  # smart pointer by pointer
+  {
+    m = MemberVariables();
+    k = Klass("smart member pointer");
+    m$SmartMemberPointer = k;
+    val = k$getValue();
+    unittest("smart member pointer", val);
+    testSuite_verifyCount(1, k);
+
+    kmember = m$SmartMemberPointer;
+    val = kmember$getValue();
+    unittest("smart member pointer", val);
+    testSuite_verifyCount(2, kmember);
+    testSuite_verifyCount(2, k);
+
+    delete_MemberVariables(m);
+    testSuite_verifyCount(2, kmember);
+    testSuite_verifyCount(2, k);
+  }
+
+  # smart pointer by reference
+  {
+    m = MemberVariables();
+    k = Klass("smart member reference");
+    m$SmartMemberReference = k;
+    val = k$getValue();
+    unittest("smart member reference", val);
+    testSuite_verifyCount(2, k);
+
+    kmember = m$SmartMemberReference;
+    val = kmember$getValue();
+    unittest("smart member reference", val);
+    testSuite_verifyCount(3, kmember);
+    testSuite_verifyCount(3, k);
+
+    # The C++ reference refers to SmartMemberValue...
+    kmemberVal = m$SmartMemberValue;
+    val = kmember$getValue();
+    unittest("smart member reference", val);
+    testSuite_verifyCount(4, kmemberVal);
+    testSuite_verifyCount(4, kmember);
+    testSuite_verifyCount(4, k);
+
+    delete_MemberVariables(m);
+    testSuite_verifyCount(3, kmemberVal);
+    testSuite_verifyCount(3, kmember);
+    testSuite_verifyCount(3, k);
+  }
+
+  # plain by value
+  {
+    m = MemberVariables();
+    k = Klass("plain member value");
+    m$MemberValue = k;
+    val = k$getValue();
+    unittest("plain member value", val);
+    testSuite_verifyCount(1, k);
+
+    kmember = m$MemberValue;
+    val = kmember$getValue();
+    unittest("plain member value", val);
+    testSuite_verifyCount(1, kmember);
+    testSuite_verifyCount(1, k);
+
+    delete_MemberVariables(m);
+    testSuite_verifyCount(1, kmember);
+    testSuite_verifyCount(1, k);
+  }
+
+  # plain by pointer
+  {
+    m = MemberVariables();
+    k = Klass("plain member pointer");
+    m$MemberPointer = k;
+    val = k$getValue();
+    unittest("plain member pointer", val);
+    testSuite_verifyCount(1, k);
+
+    kmember = m$MemberPointer;
+    val = kmember$getValue();
+    unittest("plain member pointer", val);
+    testSuite_verifyCount(1, kmember);
+    testSuite_verifyCount(1, k);
+
+    delete_MemberVariables(m);
+    testSuite_verifyCount(1, kmember);
+    testSuite_verifyCount(1, k);
+  }
+
+  # plain by reference
+  {
+    m = MemberVariables();
+    k = Klass("plain member reference");
+    m$MemberReference = k;
+    val = k$getValue();
+    unittest("plain member reference", val);
+    testSuite_verifyCount(1, k);
+
+    kmember = m$MemberReference;
+    val = kmember$getValue();
+    unittest("plain member reference", val);
+    testSuite_verifyCount(1, kmember);
+    testSuite_verifyCount(1, k);
+
+    delete_MemberVariables(m);
+    testSuite_verifyCount(1, kmember);
+    testSuite_verifyCount(1, k);
+  }
+
+  # null member variables
+  {
+    m = MemberVariables();
+
+    # shared_ptr by value
+    k = m$SmartMemberValue;
+    if (!is.null(k))
+      stop("expected null");
+
+    m$SmartMemberValue = NULL;
+    k = m$SmartMemberValue;
+    if (!is.null(k))
+      stop("expected null");
+    testSuite_verifyCount(0, k);
+
+    # plain by value
+    bNotCatched = F
+    try({
+      m$MemberValue = NULL
+      bNotCatched = T
+    }, silent = T)
+    if (bNotCatched) {
+      stop("Failed to catch null pointer")
+    }
+  }
+
+
+  #
+  # ################ Global variables ####################
+  #
+
+  # smart pointer
+  {
+    kglobal = GlobalSmartValue_get();
+    if (!is.null(kglobal))
+      stop("expected null");
+
+    k = Klass("smart global value");
+    GlobalSmartValue_set(k);
+    testSuite_verifyCount(2, k);
+
+    kglobal = GlobalSmartValue_get();
+    val = kglobal$getValue();
+    unittest("smart global value", val);
+    testSuite_verifyCount(3, kglobal);
+    testSuite_verifyCount(3, k);
+    unittest("smart global value", GlobalSmartValue_get()$getValue());
+
+    GlobalSmartValue_set(NULL);
+  }
+
+  # plain value
+  {
+    k = Klass("global value");
+    GlobalValue_set(k);
+    testSuite_verifyCount(1, k);
+
+    kglobal = GlobalValue_get();
+    val = kglobal$getValue();
+    unittest("global value", val);
+    testSuite_verifyCount(1, kglobal);
+    testSuite_verifyCount(1, k);
+    unittest("global value", GlobalValue_get()$getValue());
+
+    bNotCatched = F
+    try({
+      GlobalValue_set(NULL)
+      bNotCatched = T
+    }, silent = T)
+    if (bNotCatched) {
+      stop("Failed to catch null pointer")
+    }
+  }
+
+  # plain pointer
+  {
+    kglobal = GlobalPointer_get();
+    if (!is.null(kglobal))
+      stop("expected null");
+
+    k = Klass("global pointer");
+    GlobalPointer_set(k);
+    testSuite_verifyCount(1, k);
+
+    kglobal = GlobalPointer_get();
+    val = kglobal$getValue();
+    unittest("global pointer", val);
+    testSuite_verifyCount(1, kglobal);
+    testSuite_verifyCount(1, k);
+    GlobalPointer_set(NULL);
+  }
+
+  # plain reference
+  {
+    k = Klass("global reference");
+    GlobalReference_set(k);
+    testSuite_verifyCount(1, k);
+
+    kglobal = GlobalReference_get();
+    val = kglobal$getValue();
+    unittest("global reference", val);
+    testSuite_verifyCount(1, kglobal);
+    testSuite_verifyCount(1, k);
+
+    bNotCatched = F
+    try({
+      GlobalReference_set(NULL)
+      bNotCatched = T
+    }, silent = T)
+    if (bNotCatched) {
+      stop("Failed to catch null pointer")
+    }
+  }
+
+
+  #
+  # ###################### Templates ######################
+  #
+  {
+    pid = PairIntDouble(10, 20.2);
+    if (pid$baseVal1 != 20 || pid$baseVal2 != 40.4)
+      stop("Base values wrong");
+    if (pid$val1 != 10 || pid$val2 != 20.2)
+      stop("Derived Values wrong");
+  }
+
+}
+
+
+# actually do the tests
+for (i in 1:10) {
+  print(paste("Start Loop: ", i))
+  testSuite()
+  print(paste("End Loop: ", i))
+}
+
+
+# wait for the GC to collect unused objects
+
+#for (i in 1:10) {
+#  invisible(gc(verbose = F, full = T))
+#
+#  if (Klass_getTotal_count() == 1) {
+#    break
+#  }
+#
+#  print(paste("Still waiting for GC to collect ", Klass_getTotal_count()-1, " objects, ", i))
+#  Sys.sleep(1)
+#}
+
+# Expect
+unittest(shared_ptr_wrapper_count(), NOT_COUNTING())
+
+# Expect 1 instance - the one global variable (GlobalValue)
+# -> documented bug - gc does not work on some objects - https://www.swig.org/Doc4.0/SWIGDocumentation.html#R_nn2
+if (FALSE) {
+  unittest(Klass_getTotal_count(), 1)
+}
+
+
+q(save="no")
diff --git a/Examples/test-suite/r/li_boost_shared_ptr_template_runme.R b/Examples/test-suite/r/li_boost_shared_ptr_template_runme.R
new file mode 100644
index 0000000..8391b31
--- /dev/null
+++ b/Examples/test-suite/r/li_boost_shared_ptr_template_runme.R
@@ -0,0 +1,37 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+#source("unittest.R")
+
+dyn.load(paste("li_boost_shared_ptr_template", .Platform$dynlib.ext, sep=""))
+source("li_boost_shared_ptr_template.R")
+cacheMetaData(1)
+
+b = BaseINTEGER()
+d = DerivedINTEGER()
+
+unittest(BaseINTEGER_bar(b), 1)
+unittest(b$bar(), 1)
+
+unittest(DerivedINTEGER_bar(d), 2)
+unittest(d$bar(), 2)
+
+unittest(bar_getter(b), 1)
+unittest(bar_getter(d), 2)
+
+
+b = BaseDefaultInt()
+d = DerivedDefaultInt()
+d2 = DerivedDefaultInt2()
+
+unittest(BaseDefaultInt_bar2(b), 3)
+unittest(b$bar2(), 3)
+
+unittest(DerivedDefaultInt_bar2(d), 4)
+unittest(d$bar2(), 4)
+
+unittest(bar2_getter(b), 3)
+unittest(bar2_getter(d), 4)
+unittest(bar2_getter(d2), 4)
+
+
+q(save="no")
diff --git a/Examples/test-suite/r/li_std_vector_vector_runme.R b/Examples/test-suite/r/li_std_vector_vector_runme.R
new file mode 100644
index 0000000..59977c2
--- /dev/null
+++ b/Examples/test-suite/r/li_std_vector_vector_runme.R
@@ -0,0 +1,29 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+
+dyn.load(paste("li_std_vector_vector", .Platform$dynlib.ext, sep=""))
+source("li_std_vector_vector.R")
+cacheMetaData(1)
+
+v = make_vector_int()
+unittest_sequence(v, as.integer(c(1, 2, 3, 4, 5)))
+
+v = make_vector_vector_int()
+unittest(length(v), 1)
+unittest_sequence(v[[1]], as.integer(c(1, 2, 3, 4, 5)))
+
+v = make_vector_bool()
+unittest_sequence(v, c(TRUE, FALSE, FALSE, FALSE, TRUE))
+print(v)
+v = make_vector_vector_bool()
+unittest(length(v), 1)
+print(v)
+unittest_sequence(v[[1]], c(FALSE, TRUE, TRUE, TRUE, FALSE))
+
+v = make_vector_string()
+unittest_sequence(v, c("aa", "bb", "cc", "dd", "ee"))
+v = make_vector_vector_string()
+unittest(length(v), 1)
+unittest_sequence(v[[1]], c("1", "2", "3", "4", "5"))
+
+q(save="no")
diff --git a/Examples/test-suite/r/namespace_struct_runme.R b/Examples/test-suite/r/namespace_struct_runme.R
new file mode 100644
index 0000000..f84ef30
--- /dev/null
+++ b/Examples/test-suite/r/namespace_struct_runme.R
@@ -0,0 +1,11 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+
+dyn.load(paste("namespace_struct", .Platform$dynlib.ext, sep=""))
+source("namespace_struct.R")
+cacheMetaData(1)
+
+xy = Y()
+xy$x = as.integer(2)
+xy$y = as.integer(4)
+copyToR(xy)
diff --git a/Examples/test-suite/r/overload_null_runme.R b/Examples/test-suite/r/overload_null_runme.R
index d187a1f..13dc0c6 100644
--- a/Examples/test-suite/r/overload_null_runme.R
+++ b/Examples/test-suite/r/overload_null_runme.R
@@ -34,16 +34,16 @@
 #unittest(15, o$byval2cpr(NULL))
 #unittest(16, o$byval2cpr(x))
 
-# forward class declaration
-unittest(17, o$byval1forwardptr(x))
-unittest(18, o$byval1forwardptr(NULL))
+# fwd class declaration
+unittest(17, o$byval1fwdptr(x))
+unittest(18, o$byval1fwdptr(NULL))
 
-unittest(19, o$byval2forwardptr(NULL))
-unittest(20, o$byval2forwardptr(x))
+unittest(19, o$byval2fwdptr(NULL))
+unittest(20, o$byval2fwdptr(x))
 
-unittest(21, o$byval1forwardref(x))
+unittest(21, o$byval1fwdref(x))
 
-unittest(22, o$byval2forwardref(x))
+unittest(22, o$byval2fwdref(x))
 
 q(save="no")
 
diff --git a/Examples/test-suite/r/pointer_reference_runme.R b/Examples/test-suite/r/pointer_reference_runme.R
new file mode 100644
index 0000000..4a2a7ea
--- /dev/null
+++ b/Examples/test-suite/r/pointer_reference_runme.R
@@ -0,0 +1,24 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+#source("unittest.R")
+
+dyn.load(paste("pointer_reference", .Platform$dynlib.ext, sep=""))
+source("pointer_reference.R")
+cacheMetaData(1)
+
+
+s = Struct_value_get(Struct_pInstance_get())
+unittest(s, 10)
+
+ss = Struct(20)
+Struct_pInstance_set(ss)
+s = Struct_value_get(Struct_pInstance_get())
+unittest(s, 20)
+
+s = overloading(1)
+unittest(s, 111)
+
+s = overloading(ss)
+unittest(s, 222)
+
+
diff --git a/Examples/test-suite/r/smart_pointer_templatevariables_runme.R b/Examples/test-suite/r/smart_pointer_templatevariables_runme.R
new file mode 100644
index 0000000..11b9f2e
--- /dev/null
+++ b/Examples/test-suite/r/smart_pointer_templatevariables_runme.R
@@ -0,0 +1,16 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+#source("unittest.R")
+
+dyn.load(paste("smart_pointer_templatevariables", .Platform$dynlib.ext, sep=""))
+source("smart_pointer_templatevariables.R")
+cacheMetaData(1)
+
+
+d = DiffImContainerPtr_D(create(1234, 5678))
+unittest(d$id, 1234)
+
+d$id = 4321
+unittest(d$id, 4321)
+
+q(save="no")
diff --git a/Examples/test-suite/r/template_class_reuse_name_runme.R b/Examples/test-suite/r/template_class_reuse_name_runme.R
new file mode 100644
index 0000000..2564822
--- /dev/null
+++ b/Examples/test-suite/r/template_class_reuse_name_runme.R
@@ -0,0 +1,52 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+#source("unittest.R")
+
+dyn.load(paste("template_class_reuse_name", .Platform$dynlib.ext, sep=""))
+source("template_class_reuse_name.R")
+cacheMetaData(1)
+
+
+
+
+
+Bool1()$tt()
+Bool1False()$ff()
+
+Bool2()$tt()
+Bool2False()$ff()
+
+Bool3()$tt()
+Bool3False()$ff()
+
+Bool4()$tt()
+Bool4False()$ff()
+
+
+BoolForward1()$tt()
+BoolForward1False()$ff()
+
+BoolForward2()$tt()
+BoolForward2False()$ff()
+
+BoolForward3()$tt()
+BoolForward3False()$ff()
+
+BoolForward4()$tt()
+BoolForward4False()$ff()
+
+
+IntBool1()$tt()
+IntBool1False()$ff()
+
+IntBool2()$tt()
+IntBool2False()$ff()
+
+IntBool3()$tt()
+IntBool3False()$ff()
+
+IntBool4()$tt()
+IntBool4False()$ff()
+
+Duplicate2_0_n(Duplicate2_0())
+Duplicate3_n(Duplicate3())
diff --git a/Examples/test-suite/r/template_classes_runme.R b/Examples/test-suite/r/template_classes_runme.R
new file mode 100644
index 0000000..e40dfd4
--- /dev/null
+++ b/Examples/test-suite/r/template_classes_runme.R
@@ -0,0 +1,57 @@
+
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+#source("unittest.R")
+
+dyn.load(paste("template_classes", .Platform$dynlib.ext, sep=""))
+source("template_classes.R")
+cacheMetaData(1)
+
+
+# This test is just testing incorrect number of arguments/parameters checking
+
+point = PointInt()
+rectangle = RectangleInt()
+
+p = RectangleInt_getPoint(rectangle)
+unittest(PointInt_getX(p), 0)
+
+RectangleInt_setPoint(rectangle, point)
+
+unittest(RectangleInt_static_noargs(), 0)
+unittest(RectangleInt_static_onearg(12), 12)
+
+
+argCheckFailed = F
+try({
+  RectangleInt_setPoint(rectangle)
+  argCheckFailed = T
+}, silent=T)  
+unittest(argCheckFailed, F)
+
+
+argCheckFailed = F
+try({
+  RectangleInt_getPoint(rectangle, 0, .copy = F)
+  argCheckFailed = T
+}, silent=T)  
+unittest(argCheckFailed, F)
+
+
+argCheckFailed = F
+try({
+  RectangleInt_static_noargs(123, .copy = F)
+  argCheckFailed = T
+}, silent=T)  
+unittest(argCheckFailed, F)
+
+
+
+argCheckFailed = F
+try({
+  RectangleInt_static_onearg()
+  argCheckFailed = T
+}, silent=T)  
+unittest(argCheckFailed, F)
+
+
diff --git a/Examples/test-suite/r/template_default_arg_overloaded_extend_runme.R b/Examples/test-suite/r/template_default_arg_overloaded_extend_runme.R
new file mode 100644
index 0000000..3ec4eb3
--- /dev/null
+++ b/Examples/test-suite/r/template_default_arg_overloaded_extend_runme.R
@@ -0,0 +1,25 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+#source("unittest.R")
+
+dyn.load(paste("template_default_arg_overloaded_extend", .Platform$dynlib.ext, sep=""))
+source("template_default_arg_overloaded_extend.R")
+cacheMetaData(1)
+
+
+
+
+rs = ResultSet()
+
+unittest(rs$go_get_method(0, SearchPoint()), -1)
+unittest(rs$go_get_method(0, SearchPoint(), 100), 100)
+
+unittest(rs$go_get_template(0, SearchPoint()), -2)
+unittest(rs$go_get_template(0, SearchPoint(), 100), 100)
+
+unittest(rs$over(), "over(int)")
+unittest(rs$over(10), "over(int)")
+unittest(rs$over(SearchPoint()), "over(giai2::SearchPoint, int)")
+unittest(rs$over(SearchPoint(), 10), "over(giai2::SearchPoint, int)")
+unittest(rs$over(T, SearchPoint()), "over(bool, gaia2::SearchPoint, int)")
+unittest(rs$over(T, SearchPoint(), 10), "over(bool, gaia2::SearchPoint, int)")
diff --git a/Examples/test-suite/r/template_default_arg_overloaded_runme.R b/Examples/test-suite/r/template_default_arg_overloaded_runme.R
new file mode 100644
index 0000000..bf9272d
--- /dev/null
+++ b/Examples/test-suite/r/template_default_arg_overloaded_runme.R
@@ -0,0 +1,53 @@
+
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+#source("unittest.R")
+
+dyn.load(paste("template_default_arg_overloaded", .Platform$dynlib.ext, sep=""))
+source("template_default_arg_overloaded.R")
+cacheMetaData(1)
+
+
+
+
+pl = PropertyList()
+unittest(1, pl$setInt("int", 10))
+unittest(1, pl$setInt("int", 10, F))
+
+unittest(2, pl$set("int", pl))
+unittest(2, pl$set("int", pl, F))
+
+unittest(3, pl$setInt("int", 10, "int"))
+unittest(3, pl$setInt("int", 10, "int", F))
+
+
+pl = PropertyListGlobal()
+unittest(1, pl$setIntGlobal("int", 10))
+unittest(1, pl$setIntGlobal("int", 10, F))
+
+unittest(2, pl$set("int", pl))
+unittest(2, pl$set("int", pl, F))
+
+unittest(3, pl$setIntGlobal("int", 10, "int"))
+unittest(3, pl$setIntGlobal("int", 10, "int", F))
+
+
+unittest(1, GoopIntGlobal(10))
+unittest(1, GoopIntGlobal(10, T))
+
+unittest(2, goopGlobal(3))
+unittest(2, goopGlobal())
+
+unittest(3, GoopIntGlobal("int", F))
+unittest(3, GoopIntGlobal("int"))
+
+
+unittest(1, GoopInt(10))
+unittest(1, GoopInt(10, T))
+
+unittest(2, goop(3))
+unittest(2, goop())
+
+unittest(3, GoopInt("int", F))
+unittest(3, GoopInt("int"))
+
diff --git a/Examples/test-suite/r/template_ref_type_runme.R b/Examples/test-suite/r/template_ref_type_runme.R
new file mode 100644
index 0000000..2565019
--- /dev/null
+++ b/Examples/test-suite/r/template_ref_type_runme.R
@@ -0,0 +1,14 @@
+
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+#source("unittest.R")
+
+dyn.load(paste("template_ref_type", .Platform$dynlib.ext, sep=""))
+source("template_ref_type.R")
+cacheMetaData(1)
+
+xr = XC()
+y = Y()
+
+unittest(Y_find(y, xr), FALSE)
+
diff --git a/Examples/test-suite/r/typedef_inherit_runme.R b/Examples/test-suite/r/typedef_inherit_runme.R
new file mode 100644
index 0000000..3589f93
--- /dev/null
+++ b/Examples/test-suite/r/typedef_inherit_runme.R
@@ -0,0 +1,29 @@
+clargs <- commandArgs(trailing=TRUE)
+source(file.path(clargs[1], "unittest.R"))
+
+dyn.load(paste("typedef_inherit", .Platform$dynlib.ext, sep=""))
+source("typedef_inherit.R")
+cacheMetaData(1)
+
+
+a <- Foo()
+b <- Bar()
+
+x <- do_blah(a)
+unittest(x, "Foo::blah")
+
+x <- do_blah(b)
+unittest(x, "Bar::blah")
+
+c <- Spam()
+d <- Grok()
+
+x <- do_blah2(c)
+unittest(x, "Spam::blah")
+
+x <- do_blah2(d)
+unittest(x, "Grok::blah")
+
+unittest(d$far(), "Spam::far")
+
+q(save="no")
diff --git a/Examples/test-suite/r/unittest.R b/Examples/test-suite/r/unittest.R
index b55b4a3..35258f9 100644
--- a/Examples/test-suite/r/unittest.R
+++ b/Examples/test-suite/r/unittest.R
@@ -1,8 +1,9 @@
 unittest <- function (x,y) {
   if (all(x==y)) {
-    print("PASS") 
+    print("PASS")
   } else {
-    print("FAIL") 
+    print("FAIL")
+    print(paste(x, " != ", y))
     stop("Test failed")
   }
 }
@@ -15,3 +16,28 @@
     stop("Test failed")
   }
 }
+
+unittest_sequence <- function (x,y) {
+  x = as.vector(x)
+  y = as.vector(y)
+  
+  if (length(x) == 0 && length(y) == 0) {
+    print("PASS")
+    return()
+  }
+  
+  if (class(x[1]) != class(y[1])) {
+    print("FAILED")
+    stop(paste("Test failed: ", class(x[1]), " != ", class(y[1])))
+  }
+  
+  try(expr = {
+    if (!any(x != y)) {
+      print("PASS")
+      return()
+    }
+  }, silent = T)
+  
+  print("FAIL")
+  stop("Test failed")
+}
diff --git a/Examples/test-suite/redefined_not.i b/Examples/test-suite/redefined_not.i
index fde5994..22169ff 100644
--- a/Examples/test-suite/redefined_not.i
+++ b/Examples/test-suite/redefined_not.i
@@ -1,6 +1,6 @@
 %module redefined_not
 
-// These should not emit an Identifier redefined warning
+// These should not emit a 'Redefinition of identifier' warning
 %inline %{
 typedef unsigned int my_size_t;
 namespace Std {
diff --git a/Examples/test-suite/refcount.h b/Examples/test-suite/refcount.h
index 7d07e72..f3ebbf2 100644
--- a/Examples/test-suite/refcount.h
+++ b/Examples/test-suite/refcount.h
@@ -1,5 +1,5 @@
-#ifndef TEST_SUITE_REFCOUNT_H__
-#define TEST_SUITE_REFCOUNT_H__
+#ifndef TEST_SUITE_REFCOUNT_H
+#define TEST_SUITE_REFCOUNT_H
 
 struct RCObjBase  {
   /*!
@@ -195,4 +195,4 @@
 
 
 
-#endif //TEST_SUITE_REFCOUNT_H__
+#endif // TEST_SUITE_REFCOUNT_H
diff --git a/Examples/test-suite/register_par.i b/Examples/test-suite/register_par.i
index 6438414..3be1c7e 100644
--- a/Examples/test-suite/register_par.i
+++ b/Examples/test-suite/register_par.i
@@ -4,6 +4,18 @@
 struct swig_tree;
 %}
 
+%{
+#if defined(__cplusplus)
+#if __cplusplus >= 201703L
+/*
+Fix for languages that compile C tests as C++:
+  error: ISO C++17 does not allow ‘register’ storage class specifier [-Werror=register]
+*/
+#define register
+#endif
+#endif
+%}
+
 // bug # 924413
 %inline {
   void clear_tree_flags(register struct swig_tree *tp, register int i) {}
diff --git a/Examples/test-suite/rename_camel.i b/Examples/test-suite/rename_camel.i
index 970bb92..466f179 100644
--- a/Examples/test-suite/rename_camel.i
+++ b/Examples/test-suite/rename_camel.i
@@ -4,65 +4,72 @@
 %rename("%(ctitle)s",%$isvariable,%$ismember) ""; 
 
 %inline {
-  struct GeometryFactory 
-  {
-    void createPointFromInternalCoord(int);
-    void BIG_METHOD(int);
+  struct GeometryFactory {
+    void createPointFromInternalCoord(int) {}
+    void BIG_METHOD(int) {}
   };  
 
   class ByteOrderValues {
     
   public:
-    void readHEX();
+    void readHEX() {}
     static int ENDIAN_BIG;
   };
   
+  int ByteOrderValues::ENDIAN_BIG = 4321;
 }
 
-
-%define SedCmd "%(command:sed -e 's/\([a-z]\)/\U\\1/' -e 's/\(_\)\([a-z]\)/\U\\2/g' <<<)s" %enddef
-
 %rename(CamelCase1) camel_case_1;
-%rename(SedCmd)     camel_case_2;
+%rename("%(camelcase)s") camel_case_2;
+// ctitle is an alias for camelcase.
 %rename("%(ctitle)s") camel_case_3;
 
+%rename(lowerCamelCase1) Lower_camel_case_1;
+%rename("%(lowercamelcase)s") Lower_camel_case_2;
+// lctitle is an alias for lowercamelcase.
+%rename("%(lctitle)s") Lower_camel_case_3;
 
-%rename("%(utitle)s") CamelCase_5;
+%rename(under_case1) UnderCase1;
+%rename("%(undercase)s") UnderCase2;
+// utitle is an alias for undercase.
+%rename("%(utitle)s") UnderCase3;
 
-%define awk_cmd "%(command:awk '/^i/{print toupper($1)}' <<<)s" %enddef
+// This should change "import" to "Import", but "hi_there" should be handled by
+// the rule below and become "HI_THERE".
+%rename("%(regex:/(.*i.*)/\\u\\1/)s") "";
 
-%rename(awk_cmd) "";
-
-%rename("%(title)s",regexmatch$parentNode$type="enum .*") "";
+%rename("%(upper)s",regexmatch$parentNode$type="enum .*") "";
 
 %inline 
 {
-  int camel_case_1(int);
-  int camel_case_2(int);
-  int camel_case_3(int);
-  int camel_case_4(int);
-  int camel_case(int);
-  int CamelCase_5(int);
-  int also_works_here(int);
+  void CamelCase(int) {}
+  void camel_case_1(int) {}
+  void camel_case_2(int) {}
+  void camel_case_3(int) {}
+
+  void under_case(int) {}
+  void UnderCase1(int) {}
+  void UnderCase2(int) {}
+  void UnderCase3(int) {}
+
+  void lowerCamelCase(int) {}
+  void Lower_camel_case_1(int) {}
+  void Lower_camel_case_2(int) {}
+  void Lower_camel_case_3(int) {}
 
   enum HelloEnum {
     hello, hi_there
   };
-  
 
   enum ChaoEnum {
     bye, see_you
   };
 
-  int import(int);
-  int foo(int);
-  
+  void import(int) {}
+  void foo(int) {}
 }
 
 %rename("%(lowercase)s",sourcefmt="%(regex:/GSL_(.*)/\\1/)s",%$isfunction) "";
 %inline {
   void GSL_Hello() {}
 }
-
-
-
diff --git a/Examples/test-suite/rename_scope.i b/Examples/test-suite/rename_scope.i
index 9a09949..0692927 100644
--- a/Examples/test-suite/rename_scope.i
+++ b/Examples/test-suite/rename_scope.i
@@ -48,9 +48,16 @@
   } 
 } 
 
-%rename("equals") operator==;
+// Note not: Utilities::Bucket::operator==
+%rename("equals") Utilities::operator==;
+
+%ignore Utilities::operator<<;
+namespace Utilities {
+  %ignore operator>>;
+}
 
 %inline %{
+#include <iostream>
 
   namespace Utilities {
     class Bucket
@@ -60,6 +67,8 @@
       friend bool operator==(const Bucket& lhs, const Bucket& rhs){
 	return ( rhs.m_left == lhs.m_left );
       }
+      friend std::ostream& operator<<(std::ostream&, const Bucket &);
+      friend std::ostream& operator>>(std::ostream&, const Bucket &);
     private:
       int m_left;
     };
diff --git a/Examples/test-suite/rname.i b/Examples/test-suite/rname.i
index 09d6e3e..b7cf5d2 100644
--- a/Examples/test-suite/rname.i
+++ b/Examples/test-suite/rname.i
@@ -22,7 +22,7 @@
 %rename (newname) Space::Base::oldname(double d) const;
 
 /* Rename derived class method only */
-%rename (Xfunc) Space::Derived::fn(Base baseValue, Base* basePtr, Base& baseRef);
+%rename (Xfunc) Space::Derived::fn1(Base baseValue, Base* basePtr, Base& baseRef);
 
 %inline %{
 class Bar {
@@ -43,14 +43,14 @@
 public: 
   Base(){}; 
   virtual ~Base(){};
-  void fn(Base baseValue, Base* basePtr, Base& baseRef){}
+  void fn1(Base baseValue, Base* basePtr, Base& baseRef){}
   virtual const char * oldname(double d) const { return "Base"; }
 };
 class Derived : public Base {
 public:
   Derived(){}
   ~Derived(){}
-  void fn(Base baseValue, Base* basePtr, Base& baseRef){}
+  void fn1(Base baseValue, Base* basePtr, Base& baseRef){}
   virtual const char * oldname(double d) const { return "Derived"; }
 };
 }
diff --git a/Examples/test-suite/ruby/Makefile.in b/Examples/test-suite/ruby/Makefile.in
index d75cdb0..20ed68c 100644
--- a/Examples/test-suite/ruby/Makefile.in
+++ b/Examples/test-suite/ruby/Makefile.in
@@ -6,13 +6,21 @@
 RUBY         = @RUBY@
 SCRIPTSUFFIX = _runme.rb
 
+HAVE_CXX11   = @HAVE_CXX11@
+HAVE_CXX14   = @HAVE_CXX14@
+HAVE_CXX17   = @HAVE_CXX17@
+HAVE_CXX20   = @HAVE_CXX20@
 srcdir       = @srcdir@
 top_srcdir   = @top_srcdir@
 top_builddir = @top_builddir@
 
+FAILING_CPP_TESTS = \
+	cpp17_map_no_default_ctor \
+
 CPP_TEST_CASES = \
 	li_cstring \
 	li_factory \
+	li_std_containers_int \
 	li_std_functors \
 	li_std_list \
 	li_std_multimap \
@@ -23,6 +31,7 @@
 	li_std_wstring_inherit \
 	primitive_types \
 	ruby_alias_method \
+	ruby_global_immutable_vars_cpp \
 	ruby_keywords \
 	ruby_minherit_shared_ptr \
 	ruby_naming \
@@ -36,6 +45,7 @@
 CPP11_TEST_CASES = \
 	cpp11_hash_tables \
 	cpp11_shared_ptr_const \
+	cpp11_shared_ptr_crtp_upcast \
 	cpp11_shared_ptr_nullptr_in_containers \
 	cpp11_shared_ptr_overload \
 	cpp11_shared_ptr_upcast \
@@ -48,6 +58,7 @@
 	li_cstring \
 	ruby_alias_global_function \
 	ruby_alias_module_function \
+	ruby_global_immutable_vars \
 	ruby_manual_proxy \
 
 include $(srcdir)/../common.mk
@@ -57,6 +68,8 @@
 
 # Custom tests - tests with additional commandline options
 ruby_alias_global_function.ctest: SWIGOPT += -globalmodule
+ruby_global_immutable_vars.ctest: SWIGOPT += -globalmodule
+ruby_global_immutable_vars_cpp.cpptest: SWIGOPT += -globalmodule
 ruby_naming.cpptest: SWIGOPT += -autorename
 
 # Rules for the different types of tests
@@ -80,6 +93,8 @@
 run_testcase = \
 	if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
 	  env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(RUBY) $(RUBYFLAGS) -I$(srcdir):. $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \
+	elif [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*.so ] ; then \
+	  env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(RUBY) $(RUBYFLAGS) -I$(srcdir):. -r$(SCRIPTDIR)/$(SCRIPTPREFIX)$*.so -e '' ; \
 	fi
 
 # Clean
diff --git a/Examples/test-suite/ruby/argcargvtest_runme.rb b/Examples/test-suite/ruby/argcargvtest_runme.rb
new file mode 100644
index 0000000..da65365
--- /dev/null
+++ b/Examples/test-suite/ruby/argcargvtest_runme.rb
@@ -0,0 +1,65 @@
+#!/usr/bin/env ruby
+
+require 'swig_assert'
+require 'argcargvtest'
+
+include Argcargvtest
+
+
+$largs = ["hi", "hola", "hello"]
+if mainc($largs) != 3
+    raise RuntimeError, "bad main typemap"
+end
+
+$targs = ["hi", "hola"]
+if mainv($targs, 0) != "hi"
+    raise RuntimeError, "bad main typemap"
+end
+if mainv($targs, 1) != "hola"
+    raise RuntimeError, "bad main typemap"
+end
+if mainv($targs, 2) != "<<NULL>>"
+    raise RuntimeError, "bad main typemap"
+end
+
+$error = 0
+$ret = 0
+begin
+    mainv("hello", 1)
+    $error = 1
+rescue => e
+    $ret = 1
+end
+
+if $error == 1 or $ret != 1
+    raise RuntimeError, "bad main typemap"
+end
+
+initializeApp($largs)
+
+# Check that an empty array works.
+$empty_args = []
+if mainc($empty_args) != 0
+    raise RuntimeError, "bad main typemap"
+end
+if mainv($empty_args, 0) != "<<NULL>>"
+    raise RuntimeError, "bad main typemap"
+end
+
+# Check that empty strings are handled.
+$empty_string = ["hello", "", "world"]
+if mainc($empty_string) != 3
+    raise RuntimeError, "bad main typemap"
+end
+if mainv($empty_string, 0) != "hello"
+    raise RuntimeError, "bad main typemap"
+end
+if mainv($empty_string, 1) != ""
+    raise RuntimeError, "bad main typemap"
+end
+if mainv($empty_string, 2) != "world"
+    raise RuntimeError, "bad main typemap"
+end
+if mainv($empty_string, 3) != "<<NULL>>"
+    raise RuntimeError, "bad main typemap"
+end
diff --git a/Examples/test-suite/ruby/catches_strings_runme.rb b/Examples/test-suite/ruby/catches_strings_runme.rb
new file mode 100644
index 0000000..fb74667
--- /dev/null
+++ b/Examples/test-suite/ruby/catches_strings_runme.rb
@@ -0,0 +1,31 @@
+#!/usr/bin/env ruby
+
+require 'swig_assert'
+
+require 'catches_strings'
+
+exception_thrown = false
+begin
+  Catches_strings::StringsThrower.charstring()
+rescue RuntimeError => e
+  if (!e.to_s.include? "charstring message")
+    raise RuntimeError, "incorrect exception message: #{e.to_s}"
+  end
+  exception_thrown = true
+end
+if (!exception_thrown)
+  raise RuntimeError, "Should have thrown an exception"
+end
+
+exception_thrown = false
+begin
+  Catches_strings::StringsThrower.stdstring()
+rescue RuntimeError => e
+  if (!e.to_s.include? "stdstring message")
+    raise RuntimeError, "incorrect exception message: #{e.to_s}"
+  end
+  exception_thrown = true
+end
+if (!exception_thrown)
+  raise RuntimeError, "Should have thrown an exception"
+end
diff --git a/Examples/test-suite/ruby/char_binary_runme.rb b/Examples/test-suite/ruby/char_binary_runme.rb
new file mode 100644
index 0000000..c40738f
--- /dev/null
+++ b/Examples/test-suite/ruby/char_binary_runme.rb
@@ -0,0 +1,35 @@
+#!/usr/bin/env ruby
+#
+# Put description here
+#
+
+require 'swig_assert'
+require 'char_binary'
+
+include Char_binary
+
+t = Test.new
+str = 'hile'
+swig_assert(t.strlen(str) == 4, binding, 'bad multi-arg typemap')
+swig_assert(t.ustrlen(str) == 4, binding, 'bad multi-arg typemap')
+swig_assert(t.strlen("hil\000") == 4, binding, 'bad multi-arg typemap')
+swig_assert(t.ustrlen("hil\000") == 4, binding, 'bad multi-arg typemap')
+
+# creating a raw char*
+pc = new_pchar(5)
+pchar_setitem(pc, 0, 'h')
+pchar_setitem(pc, 1, 'o')
+pchar_setitem(pc, 2, 'l')
+pchar_setitem(pc, 3, 'a')
+pchar_setitem(pc, 4, 0)
+
+swig_assert(t.strlen(pc) == 4, binding, 'bad multi-arg typemap')
+swig_assert(t.ustrlen(pc) == 4, binding, 'bad multi-arg typemap')
+
+Char_binary.var_pchar = pc
+swig_assert(Char_binary.var_pchar == 'hola', binding, 'bad pointer case')
+
+Char_binary.var_namet = pc
+swig_assert(Char_binary.var_namet == 'hola', binding, 'bad pointer case')
+
+delete_pchar(pc)
diff --git a/Examples/test-suite/ruby/constant_directive_runme.rb b/Examples/test-suite/ruby/constant_directive_runme.rb
new file mode 100644
index 0000000..ae6cf4f
--- /dev/null
+++ b/Examples/test-suite/ruby/constant_directive_runme.rb
@@ -0,0 +1,16 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is directly derived from its Python counterpart.
+#
+
+require 'swig_assert'
+require 'constant_directive'
+
+swig_assert("Constant_directive::TYPE1_CONSTANT1.is_a?(Constant_directive::Type1)", binding)
+swig_assert("Constant_directive::getType1Instance().is_a?(Constant_directive::Type1)", binding)
+
+swig_assert_equal('Constant_directive::TYPE1_CONSTANT1.val', '1', binding)
+swig_assert_equal('Constant_directive::TYPE1_CONSTANT2.val', '2', binding)
+swig_assert_equal('Constant_directive::TYPE1_CONSTANT3.val', '3', binding)
+swig_assert_equal('Constant_directive::TYPE1CONST_CONSTANT1.val', '1', binding)
+swig_assert_equal('Constant_directive::TYPE1CPTR_CONSTANT1.val', '1', binding)
diff --git a/Examples/test-suite/ruby/contract_runme.rb b/Examples/test-suite/ruby/contract_runme.rb
new file mode 100644
index 0000000..df7fd3d
--- /dev/null
+++ b/Examples/test-suite/ruby/contract_runme.rb
@@ -0,0 +1,69 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is directly derived from its Python counterpart.
+#
+
+require 'swig_assert'
+require 'contract'
+
+def swig_assert_runtime_error(msg, type, &block)
+  begin
+    yield(block)
+    raise SwigRubyError.new("#{msg} failed")
+  rescue RuntimeError => e
+    reason = e.to_s
+    if reason =~ /\bcontract violation\b/i && reason =~ /\b#{type}\b/i
+      # OK
+    else
+      raise e
+    end
+  end
+end
+
+Contract::test_preassert(1, 2)
+swig_assert_runtime_error("Preassertions", "require") { Contract::test_preassert(-1, 3) }
+
+Contract::test_postassert(3)
+swig_assert_runtime_error("Postassertions", "ensure") { Contract::test_postassert(-3) }
+
+Contract::test_prepost(2, 3)
+Contract::test_prepost(5, -4)
+swig_assert_runtime_error("Preassertions", "require") { Contract::test_prepost(-3, 4) }
+swig_assert_runtime_error("Postassertions", "ensure") { Contract::test_prepost(4, -10) }
+
+f = Contract::Foo.new
+f.test_preassert(4, 5)
+swig_assert_runtime_error("Method preassertion", "require") { f.test_preassert(-2, 3) }
+
+f.test_postassert(4)
+swig_assert_runtime_error("Method postassertion", "ensure") { f.test_postassert(-4) }
+
+f.test_prepost(3, 4)
+f.test_prepost(4, -3)
+swig_assert_runtime_error("Method preassertion", "require") { f.test_prepost(-4, 2) }
+swig_assert_runtime_error("Method postassertion", "ensure") { f.test_prepost(4, -10) }
+
+Contract::Foo.stest_prepost(4, 0)
+swig_assert_runtime_error("Static method preassertion", "require") { Contract::Foo.stest_prepost(-4, 2) }
+swig_assert_runtime_error("Static method postassertion", "ensure") { Contract::Foo.stest_prepost(4, -10) }
+
+b = Contract::Bar.new
+swig_assert_runtime_error("Inherited preassertion", "require") { b.test_prepost(2, -4) }
+
+d = Contract::D.new
+swig_assert_runtime_error("Inherited preassertion (D)", "require") { d.foo(-1, 1, 1, 1, 1) }
+swig_assert_runtime_error("Inherited preassertion (D)", "require") { d.foo(1, -1, 1, 1, 1) }
+swig_assert_runtime_error("Inherited preassertion (D)", "require") { d.foo(1, 1, -1, 1, 1) }
+swig_assert_runtime_error("Inherited preassertion (D)", "require") { d.foo(1, 1, 1, -1, 1) }
+swig_assert_runtime_error("Inherited preassertion (D)", "require") { d.foo(1, 1, 1, 1, -1) }
+
+swig_assert_runtime_error("Inherited preassertion (D)", "require") { d.bar(-1, 1, 1, 1, 1) }
+swig_assert_runtime_error("Inherited preassertion (D)", "require") { d.bar(1, -1, 1, 1, 1) }
+swig_assert_runtime_error("Inherited preassertion (D)", "require") { d.bar(1, 1, -1, 1, 1) }
+swig_assert_runtime_error("Inherited preassertion (D)", "require") { d.bar(1, 1, 1, -1, 1) }
+swig_assert_runtime_error("Inherited preassertion (D)", "require") { d.bar(1, 1, 1, 1, -1) }
+
+# namespace
+Contract::MyClass.new(1)
+swig_assert_runtime_error("Constructor preassertion", "require") { Contract::MyClass.new(0) }
+
diff --git a/Examples/test-suite/ruby/cpp11_alias_nested_template_scoping_runme.rb b/Examples/test-suite/ruby/cpp11_alias_nested_template_scoping_runme.rb
new file mode 100644
index 0000000..c6e2b85
--- /dev/null
+++ b/Examples/test-suite/ruby/cpp11_alias_nested_template_scoping_runme.rb
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is directly derived from its Java counterpart.
+#
+
+require 'swig_assert'
+require 'cpp11_alias_nested_template_scoping'
+
+ys = Cpp11_alias_nested_template_scoping::Yshort.new
+val = ys.create1
+val = ys.create2
+val = ys.create3
+val = ys.create4
+val = ys.create5
+val = ys.create6
+val = ys.create7
+
+val = ys.create13
+
+val = ys.create15
+val = ys.create16
+val = ys.create17
+
diff --git a/Examples/test-suite/ruby/cpp11_director_using_constructor_runme.rb b/Examples/test-suite/ruby/cpp11_director_using_constructor_runme.rb
new file mode 100644
index 0000000..272fc05
--- /dev/null
+++ b/Examples/test-suite/ruby/cpp11_director_using_constructor_runme.rb
@@ -0,0 +1,129 @@
+#!/usr/bin/env ruby
+#
+# Put description here
+#
+# 
+# 
+# 
+#
+
+require 'swig_assert'
+
+require 'cpp11_director_using_constructor'
+
+include Cpp11_director_using_constructor
+
+# Public base constructors
+a = PublicDerived1.new(0, "hi").meth()
+a = PublicDerived2.new().meth()
+a = PublicDerived2.new(0, "hi").meth()
+a = PublicDerived3.new().meth()
+a = PublicDerived3.new(0, "hi").meth()
+a = PublicDerived4.new().meth()
+a = PublicDerived5.new().meth()
+
+# Protected base constructors
+# Cannot test most of these as the constructors are protected
+ProtectedDerived5.new()
+
+# Mix of public and overloaded constructors
+MixedDerived1a.new(0, "hi").meth()
+MixedDerived1a.new().meth()
+MixedDerived1b.new(0, "hi").meth()
+MixedDerived1b.new().meth()
+
+MixedDerived2a.new(0, "hi").meth()
+MixedDerived2a.new().meth()
+MixedDerived2b.new(0, "hi").meth()
+MixedDerived2b.new().meth()
+
+MixedDerived2c.new(0, "hi").meth()
+MixedDerived2c.new().meth()
+MixedDerived2c.new(0).meth()
+
+MixedDerived2d.new(0, "hi").meth()
+MixedDerived2d.new().meth()
+MixedDerived2d.new(0).meth()
+
+MixedDerived3a.new(0, "hi").meth()
+MixedDerived3a.new().meth()
+MixedDerived3b.new(0, "hi").meth()
+MixedDerived3b.new().meth()
+
+MixedDerived3c.new(0, "hi").meth()
+MixedDerived3c.new().meth()
+MixedDerived3c.new(0).meth()
+
+MixedDerived3d.new(0, "hi").meth()
+MixedDerived3d.new().meth()
+MixedDerived3d.new(0).meth()
+
+MixedDerived4a.new(0, "hi").meth()
+MixedDerived4a.new().meth()
+MixedDerived4b.new(0, "hi").meth()
+MixedDerived4b.new().meth()
+
+MixedDerived4c.new().meth()
+MixedDerived4c.new(0).meth()
+
+MixedDerived4d.new().meth()
+MixedDerived4d.new(0).meth()
+
+MixedDerived4e.new().meth()
+
+MixedDerived4f.new().meth()
+
+# Mix of protected base constructors and overloading
+ProotDerived1a.new().meth()
+
+ProotDerived1b.new(0, "hi").meth()
+ProotDerived1b.new().meth()
+
+ProotDerived1c.new(0, "hi").meth()
+ProotDerived1c.new().meth()
+
+ProotDerived1d.new(0).meth()
+ProotDerived1d.new().meth()
+
+ProotDerived1e.new(0).meth()
+ProotDerived1e.new().meth()
+
+ProotDerived2a.new(0, "hi").meth()
+
+ProotDerived2b.new(0, "hi").meth()
+
+ProotDerived2c.new(0, "hi").meth()
+ProotDerived2c.new().meth()
+
+ProotDerived2d.new(0, "hi").meth()
+ProotDerived2d.new().meth()
+
+ProotDerived2e.new(0, "hi").meth()
+ProotDerived2e.new().meth()
+
+ProotDerived2f.new(0, "hi").meth()
+ProotDerived2f.new().meth()
+ProotDerived2f.new(0).meth()
+
+# Missing base
+# HiddenDerived1()
+
+# Templates and public base constructors (derive from non-template)
+TemplatePublicDerived1Int.new(0, "hi").meth()
+TemplatePublicDerived2Int.new().meth()
+TemplatePublicDerived2Int.new(0, "hi").meth()
+TemplatePublicDerived3Int.new().meth()
+TemplatePublicDerived3Int.new(0, "hi").meth()
+TemplatePublicDerived4Int.new().meth()
+TemplatePublicDerived5Int.new().meth()
+
+# Templates and public base constructors (derive from template)
+TemplPublicDerived1Int.new(0, "hi").meth()
+TemplPublicDerived2Int.new().meth()
+TemplPublicDerived2Int.new(0, "hi").meth()
+TemplPublicDerived3Int.new().meth()
+TemplPublicDerived3Int.new(0, "hi").meth()
+TemplPublicDerived4Int.new().meth()
+TemplPublicDerived5Int.new().meth()
+TemplPublicDerived6Int.new(0, "hi").meth()
+TemplPublicDerived6Int.new().meth()
diff --git a/Examples/test-suite/ruby/cpp11_move_typemaps_runme.rb b/Examples/test-suite/ruby/cpp11_move_typemaps_runme.rb
new file mode 100644
index 0000000..d2c9fe3
--- /dev/null
+++ b/Examples/test-suite/ruby/cpp11_move_typemaps_runme.rb
@@ -0,0 +1,36 @@
+#!/usr/bin/env ruby
+
+require 'swig_assert'
+
+require 'cpp11_move_typemaps'
+
+Cpp11_move_typemaps::Counter.reset_counts()
+mo = Cpp11_move_typemaps::MoveOnly.new(111)
+Cpp11_move_typemaps::Counter.check_counts(1, 0, 0, 0, 0, 0)
+Cpp11_move_typemaps::MoveOnly.take(mo)
+Cpp11_move_typemaps::Counter.check_counts(1, 0, 0, 1, 0, 2)
+mo = nil
+Cpp11_move_typemaps::Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+Cpp11_move_typemaps::Counter.reset_counts()
+mo = Cpp11_move_typemaps::MovableCopyable.new(111)
+Cpp11_move_typemaps::Counter.check_counts(1, 0, 0, 0, 0, 0)
+Cpp11_move_typemaps::MovableCopyable.take(mo)
+Cpp11_move_typemaps::Counter.check_counts(1, 0, 0, 1, 0, 2)
+mo = nil
+Cpp11_move_typemaps::Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+mo = Cpp11_move_typemaps::MoveOnly.new(222)
+Cpp11_move_typemaps::MoveOnly.take(mo)
+exception_thrown = false
+begin
+  Cpp11_move_typemaps::MoveOnly.take(mo)
+rescue RuntimeError => e
+  if (!e.to_s.include? "cannot release ownership as memory is not owned")
+    raise RuntimeError, "incorrect exception message: #{e.to_s}"
+  end
+  exception_thrown = true
+end
+if (!exception_thrown)
+  raise RuntimeError, "Should have thrown 'Cannot release ownership as memory is not owned' error"
+end
diff --git a/Examples/test-suite/ruby/cpp11_rvalue_reference_move_runme.rb b/Examples/test-suite/ruby/cpp11_rvalue_reference_move_runme.rb
new file mode 100644
index 0000000..0a423d6
--- /dev/null
+++ b/Examples/test-suite/ruby/cpp11_rvalue_reference_move_runme.rb
@@ -0,0 +1,106 @@
+#!/usr/bin/env ruby
+
+require 'swig_assert'
+
+require 'cpp11_rvalue_reference_move'
+
+# Function containing rvalue reference parameter
+Cpp11_rvalue_reference_move::Counter.reset_counts()
+mo = Cpp11_rvalue_reference_move::MovableCopyable.new(222)
+Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 0, 0, 0)
+Cpp11_rvalue_reference_move::MovableCopyable.movein(mo)
+Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 1, 0, 2)
+exception_thrown = false
+begin
+    Cpp11_rvalue_reference_move::MovableCopyable.is_nullptr(mo)
+rescue ObjectPreviouslyDeleted
+    exception_thrown = true
+end
+if (!exception_thrown)
+    raise RuntimeError, "is_nullptr failed to throw"
+end
+mo = nil
+Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 1, 0, 2)
+
+# Move constructor test
+Cpp11_rvalue_reference_move::Counter.reset_counts()
+mo = Cpp11_rvalue_reference_move::MovableCopyable.new(222)
+Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 0, 0, 0)
+mo_moved = Cpp11_rvalue_reference_move::MovableCopyable.new(mo)
+Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 1, 0, 1)
+exception_thrown = false
+begin
+    Cpp11_rvalue_reference_move::MovableCopyable.is_nullptr(mo)
+rescue ObjectPreviouslyDeleted
+    exception_thrown = true
+end
+if (!exception_thrown)
+    raise RuntimeError, "is_nullptr failed to throw"
+end
+mo = nil
+Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 1, 0, 1)
+# mo_moved = nil
+# Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 1, 0, 2)
+# Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete
+Cpp11_rvalue_reference_move::MovableCopyable.movein(mo_moved)
+Cpp11_rvalue_reference_move::Counter.check_counts(1, 0, 0, 2, 0, 3)
+
+# Move assignment operator test
+Cpp11_rvalue_reference_move::Counter.reset_counts()
+mo111 = Cpp11_rvalue_reference_move::MovableCopyable.new(111)
+mo222 = Cpp11_rvalue_reference_move::MovableCopyable.new(222)
+Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 0, 0, 0)
+mo111.MoveAssign(mo222)
+Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 0, 1, 1)
+exception_thrown = false
+begin
+    Cpp11_rvalue_reference_move::MovableCopyable.is_nullptr(mo222)
+rescue ObjectPreviouslyDeleted
+    exception_thrown = true
+end
+if (!exception_thrown)
+    raise RuntimeError, "is_nullptr failed to throw"
+end
+mo222 = nil
+Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 0, 1, 1)
+# mo111 = nil
+# Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 0, 1, 2)
+# Above not deleting the C++ object(node v12) - can't reliably control GC - use the movein function instead to delete
+Cpp11_rvalue_reference_move::MovableCopyable.movein(mo111)
+Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 1, 1, 3)
+
+# null check
+Cpp11_rvalue_reference_move::Counter.reset_counts()
+exception_thrown = false
+begin
+  Cpp11_rvalue_reference_move::MovableCopyable.movein(nil)
+rescue ArgumentError => e
+  if (!e.to_s.include? "invalid null reference")
+    raise RuntimeError, "incorrect exception message: #{e.to_s}"
+  end
+  exception_thrown = true
+end
+if (!exception_thrown)
+  raise RuntimeError, "Should have thrown null error"
+end
+Cpp11_rvalue_reference_move::Counter.check_counts(0, 0, 0, 0, 0, 0)
+
+# output
+Cpp11_rvalue_reference_move::Counter.reset_counts()
+mc = Cpp11_rvalue_reference_move::MovableCopyable.moveout(1234)
+Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 0, 1, 1)
+Cpp11_rvalue_reference_move::MovableCopyable.check_numbers_match(mc, 1234)
+
+exception_thrown = false
+begin
+  Cpp11_rvalue_reference_move::MovableCopyable.movein(mc)
+rescue RuntimeError => e
+  if (!e.to_s.include? "cannot release ownership as memory is not owned")
+    raise RuntimeError, "incorrect exception message: #{e.to_s}"
+  end
+  exception_thrown = true
+end
+if (!exception_thrown)
+  raise RuntimeError, "Should have thrown 'Cannot release ownership as memory is not owned' error"
+end
+Cpp11_rvalue_reference_move::Counter.check_counts(2, 0, 0, 0, 1, 1)
diff --git a/Examples/test-suite/ruby/cpp11_std_unique_ptr_runme.rb b/Examples/test-suite/ruby/cpp11_std_unique_ptr_runme.rb
new file mode 100644
index 0000000..59e9691
--- /dev/null
+++ b/Examples/test-suite/ruby/cpp11_std_unique_ptr_runme.rb
@@ -0,0 +1,151 @@
+#!/usr/bin/env ruby
+
+require 'swig_assert'
+
+require 'cpp11_std_unique_ptr'
+
+def gc_check(expected_count)
+#  GC.start(full_mark: true, immediate_sweep: true)
+  GC.start
+# GC is not reliably run, skip check
+#  swig_assert_equal_simple(expected_count, Cpp11_std_unique_ptr::Klass::getTotal_count())
+end
+
+def checkCount(expected_count)
+    actual_count = Cpp11_std_unique_ptr::Klass.getTotal_count()
+    if (actual_count != expected_count)
+        raise RuntimeError, "Counts incorrect, expected:" + expected_count + " actual:" + actual_count
+    end
+end
+
+# Test raw pointer handling involving virtual inheritance
+kini = Cpp11_std_unique_ptr::KlassInheritance.new("KlassInheritanceInput")
+checkCount(1)
+s = Cpp11_std_unique_ptr.useKlassRawPtr(kini)
+if (s != "KlassInheritanceInput")
+    raise RuntimeError, "Incorrect string: " + s
+end
+# kini = nil
+Cpp11_std_unique_ptr.takeKlassUniquePtr(kini) # Ensure object is deleted (can't rely on GC)
+checkCount(0)
+
+
+# unique_ptr as input
+kin = Cpp11_std_unique_ptr::Klass.new("KlassInput")
+checkCount(1)
+s = Cpp11_std_unique_ptr.takeKlassUniquePtr(kin)
+checkCount(0)
+if (s != "KlassInput")
+    raise RuntimeError, "Incorrect string: " + s
+end
+exception_thrown = false
+begin
+    Cpp11_std_unique_ptr.is_nullptr(kin)
+rescue ObjectPreviouslyDeleted
+    exception_thrown = true
+end
+if (!exception_thrown)
+    raise RuntimeError, "is_nullptr failed to throw"
+end
+kin = nil
+checkCount(0)
+
+kin = Cpp11_std_unique_ptr::Klass.new("KlassInput")
+checkCount(1)
+s = Cpp11_std_unique_ptr.takeKlassUniquePtr(kin)
+checkCount(0)
+if (s != "KlassInput")
+    raise RuntimeError, "Incorrect string: " + s
+end
+exception_thrown = false
+begin
+    Cpp11_std_unique_ptr.is_nullptr(kin)
+rescue ObjectPreviouslyDeleted
+    exception_thrown = true
+end
+if (!exception_thrown)
+    raise RuntimeError, "is_nullptr failed to throw"
+end
+exception_thrown = false
+begin
+    Cpp11_std_unique_ptr.takeKlassUniquePtr(kin)
+rescue RuntimeError => e
+    # puts e.message
+    exception_thrown = true
+end
+if (!exception_thrown)
+    raise RuntimeError, "double usage of takeKlassUniquePtr should have been an error"
+end
+kin = nil
+checkCount(0)
+
+kin = Cpp11_std_unique_ptr::Klass.new("KlassInput")
+exception_thrown = false
+notowned = Cpp11_std_unique_ptr::get_not_owned_ptr(kin)
+begin
+    Cpp11_std_unique_ptr::takeKlassUniquePtr(notowned)
+rescue RuntimeError => e
+    if (!e.to_s.include? "cannot release ownership as memory is not owned")
+      raise RuntimeError, "incorrect exception message"
+    end
+    exception_thrown = true
+end
+if (!exception_thrown)
+  raise RuntimeError, "Should have thrown 'Cannot release ownership as memory is not owned' error"
+end
+checkCount(1)
+Cpp11_std_unique_ptr.takeKlassUniquePtr(kin) # Ensure object is deleted (can't rely on GC)
+checkCount(0)
+
+kini = Cpp11_std_unique_ptr::KlassInheritance.new("KlassInheritanceInput")
+checkCount(1)
+s = Cpp11_std_unique_ptr.takeKlassUniquePtr(kini)
+checkCount(0)
+if (s != "KlassInheritanceInput")
+    raise RuntimeError, "Incorrect string: " + s
+end
+exception_thrown = false
+begin
+    Cpp11_std_unique_ptr.is_nullptr(kini)
+rescue ObjectPreviouslyDeleted
+    exception_thrown = true
+end
+if (!exception_thrown)
+    raise RuntimeError, "is_nullptr failed to throw"
+end
+kini = nil
+checkCount(0)
+
+Cpp11_std_unique_ptr::takeKlassUniquePtr(nil)
+Cpp11_std_unique_ptr::takeKlassUniquePtr(Cpp11_std_unique_ptr::make_null())
+checkCount(0)
+
+# overloaded parameters
+if (Cpp11_std_unique_ptr::overloadTest() != 0)
+  raise RuntimeError, "overloadTest failed"
+end
+if (Cpp11_std_unique_ptr::overloadTest(nil) != 1)
+  raise RuntimeError, "overloadTest failed"
+end
+if (Cpp11_std_unique_ptr::overloadTest(Cpp11_std_unique_ptr::Klass.new("over")) != 1)
+  raise RuntimeError, "overloadTest failed"
+end
+checkCount(0);
+
+
+# unique_ptr as output
+k1 = Cpp11_std_unique_ptr::makeKlassUniquePtr("first")
+k2 = Cpp11_std_unique_ptr::makeKlassUniquePtr("second")
+swig_assert_equal_simple(2, Cpp11_std_unique_ptr::Klass::getTotal_count())
+
+gc_check(2)
+k1 = nil
+gc_check(1)
+
+swig_assert_equal_simple(k2.getLabel(), "second")
+gc_check(1)
+
+k2 = nil
+gc_check(0)
+
+swig_assert_equal_simple(Cpp11_std_unique_ptr::makeNullUniquePtr(), nil)
diff --git a/Examples/test-suite/ruby/cpp11_using_constructor_runme.rb b/Examples/test-suite/ruby/cpp11_using_constructor_runme.rb
new file mode 100644
index 0000000..b38a0ec
--- /dev/null
+++ b/Examples/test-suite/ruby/cpp11_using_constructor_runme.rb
@@ -0,0 +1,129 @@
+#!/usr/bin/env ruby
+#
+# Put description here
+#
+# 
+# 
+# 
+#
+
+require 'swig_assert'
+
+require 'cpp11_using_constructor'
+
+include Cpp11_using_constructor
+
+# Public base constructors
+a = PublicDerived1.new(0, "hi").meth()
+a = PublicDerived2.new().meth()
+a = PublicDerived2.new(0, "hi").meth()
+a = PublicDerived3.new().meth()
+a = PublicDerived3.new(0, "hi").meth()
+a = PublicDerived4.new().meth()
+a = PublicDerived5.new().meth()
+
+# Protected base constructors
+# Cannot test most of these as the constructors are protected
+ProtectedDerived5.new()
+
+# Mix of public and overloaded constructors
+MixedDerived1a.new(0, "hi").meth()
+MixedDerived1a.new().meth()
+MixedDerived1b.new(0, "hi").meth()
+MixedDerived1b.new().meth()
+
+MixedDerived2a.new(0, "hi").meth()
+MixedDerived2a.new().meth()
+MixedDerived2b.new(0, "hi").meth()
+MixedDerived2b.new().meth()
+
+MixedDerived2c.new(0, "hi").meth()
+MixedDerived2c.new().meth()
+MixedDerived2c.new(0).meth()
+
+MixedDerived2d.new(0, "hi").meth()
+MixedDerived2d.new().meth()
+MixedDerived2d.new(0).meth()
+
+MixedDerived3a.new(0, "hi").meth()
+MixedDerived3a.new().meth()
+MixedDerived3b.new(0, "hi").meth()
+MixedDerived3b.new().meth()
+
+MixedDerived3c.new(0, "hi").meth()
+MixedDerived3c.new().meth()
+MixedDerived3c.new(0).meth()
+
+MixedDerived3d.new(0, "hi").meth()
+MixedDerived3d.new().meth()
+MixedDerived3d.new(0).meth()
+
+MixedDerived4a.new(0, "hi").meth()
+MixedDerived4a.new().meth()
+MixedDerived4b.new(0, "hi").meth()
+MixedDerived4b.new().meth()
+
+MixedDerived4c.new().meth()
+MixedDerived4c.new(0).meth()
+
+MixedDerived4d.new().meth()
+MixedDerived4d.new(0).meth()
+
+MixedDerived4e.new().meth()
+
+MixedDerived4f.new().meth()
+
+# Mix of protected base constructors and overloading
+ProotDerived1a.new().meth()
+
+ProotDerived1b.new(0, "hi").meth()
+ProotDerived1b.new().meth()
+
+ProotDerived1c.new(0, "hi").meth()
+ProotDerived1c.new().meth()
+
+ProotDerived1d.new(0).meth()
+ProotDerived1d.new().meth()
+
+ProotDerived1e.new(0).meth()
+ProotDerived1e.new().meth()
+
+ProotDerived2a.new(0, "hi").meth()
+
+ProotDerived2b.new(0, "hi").meth()
+
+ProotDerived2c.new(0, "hi").meth()
+ProotDerived2c.new().meth()
+
+ProotDerived2d.new(0, "hi").meth()
+ProotDerived2d.new().meth()
+
+ProotDerived2e.new(0, "hi").meth()
+ProotDerived2e.new().meth()
+
+ProotDerived2f.new(0, "hi").meth()
+ProotDerived2f.new().meth()
+ProotDerived2f.new(0).meth()
+
+# Missing base
+# HiddenDerived1()
+
+# Templates and public base constructors (derive from non-template)
+TemplatePublicDerived1Int.new(0, "hi").meth()
+TemplatePublicDerived2Int.new().meth()
+TemplatePublicDerived2Int.new(0, "hi").meth()
+TemplatePublicDerived3Int.new().meth()
+TemplatePublicDerived3Int.new(0, "hi").meth()
+TemplatePublicDerived4Int.new().meth()
+TemplatePublicDerived5Int.new().meth()
+
+# Templates and public base constructors (derive from template)
+TemplPublicDerived1Int.new(0, "hi").meth()
+TemplPublicDerived2Int.new().meth()
+TemplPublicDerived2Int.new(0, "hi").meth()
+TemplPublicDerived3Int.new().meth()
+TemplPublicDerived3Int.new(0, "hi").meth()
+TemplPublicDerived4Int.new().meth()
+TemplPublicDerived5Int.new().meth()
+TemplPublicDerived6Int.new(0, "hi").meth()
+TemplPublicDerived6Int.new().meth()
diff --git a/Examples/test-suite/ruby/cpp17_director_string_view_runme.rb b/Examples/test-suite/ruby/cpp17_director_string_view_runme.rb
new file mode 100644
index 0000000..911d9f7
--- /dev/null
+++ b/Examples/test-suite/ruby/cpp17_director_string_view_runme.rb
@@ -0,0 +1,42 @@
+#!/usr/bin/env ruby
+#
+# Put description here
+#
+# 
+# 
+# 
+#
+
+require 'swig_assert'
+
+require 'cpp17_director_string_view'
+
+class B < Cpp17_director_string_view::A
+ attr_accessor :smem
+
+ def initialize(some_string)
+  super(some_string)
+ end
+
+ def get_first()
+  # Since std::string_view contains a pointer into a string, the string
+  # cannot be a temporary in order to avoid undefined behaviour.
+  @cached_string = super() + " world!"
+  return @cached_string
+ end
+
+ def process_text(string)
+  super(string)
+  @smem = "hello"
+ end
+
+end
+
+
+b = B.new("hello")
+raise RuntimeError if b.get(0) != "hello"
+raise RuntimeError if b.get_first() != "hello world!"
+raise RuntimeError if b.call_get_first() != "hello world!"
+
+b.call_process_func()
+raise RuntimeError if b.smem != "hello"
diff --git a/Examples/test-suite/ruby/cpp17_nested_namespaces_runme.rb b/Examples/test-suite/ruby/cpp17_nested_namespaces_runme.rb
new file mode 100644
index 0000000..e9e8411
--- /dev/null
+++ b/Examples/test-suite/ruby/cpp17_nested_namespaces_runme.rb
@@ -0,0 +1,24 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is directly derived from its Java counterpart.
+#
+
+require 'cpp17_nested_namespaces'
+
+Cpp17_nested_namespaces::A1Struct.new.A1Method
+Cpp17_nested_namespaces::B1Struct.new.B1Method
+Cpp17_nested_namespaces::C1Struct.new.C1Method
+
+Cpp17_nested_namespaces.createA1Struct().A1Method
+Cpp17_nested_namespaces.createB1Struct().B1Method
+Cpp17_nested_namespaces.createC1Struct().C1Method
+
+Cpp17_nested_namespaces::B2Struct.new.B2Method
+Cpp17_nested_namespaces::C2Struct.new.C2Method
+Cpp17_nested_namespaces.createB2Struct().B2Method
+Cpp17_nested_namespaces.createC2Struct().C2Method
+
+Cpp17_nested_namespaces::B3Struct.new.B3Method
+Cpp17_nested_namespaces::C3Struct.new.C3Method
+Cpp17_nested_namespaces.createB3Struct().B3Method
+Cpp17_nested_namespaces.createC3Struct().C3Method
diff --git a/Examples/test-suite/ruby/cpp17_string_view_runme.rb b/Examples/test-suite/ruby/cpp17_string_view_runme.rb
new file mode 100644
index 0000000..3c071e5
--- /dev/null
+++ b/Examples/test-suite/ruby/cpp17_string_view_runme.rb
@@ -0,0 +1,119 @@
+#!/usr/bin/env ruby
+#
+# Put description here
+#
+# 
+# 
+# 
+#
+
+require 'swig_assert'
+
+require 'cpp17_string_view'
+
+include Cpp17_string_view
+
+# Checking expected use of %typemap(in) std::string_view {}
+test_value("Fee")
+
+# Checking expected result of %typemap(out) std::string_view {}
+raise RuntimeError unless test_value("Fi") == "Fi"
+
+# Verify type-checking for %typemap(in) std::string_view {}
+exceptionRaised = false
+begin
+  test_value(0)
+rescue TypeError
+  exceptionRaised = true
+ensure
+  raise RuntimeError unless exceptionRaised
+end
+
+# Checking expected use of %typemap(in) const std::string_view & {}
+test_const_reference("Fo")
+
+# Checking expected result of %typemap(out) const std::string_view& {}
+raise RuntimeError unless test_const_reference("Fum") == "Fum"
+
+# Verify type-checking for %typemap(in) const std::string_view & {}
+exceptionRaised = false
+begin
+  test_const_reference(0)
+rescue TypeError
+  exceptionRaised = true
+ensure
+  raise RuntimeError unless exceptionRaised
+end
+
+#
+# Input and output typemaps for pointers and non-const references to
+# std::string_view are *not* supported; the following tests confirm
+# that none of these cases are slipping through.
+#
+
+exceptionRaised = false
+begin
+  test_pointer("foo")
+rescue TypeError
+  exceptionRaised = true
+ensure
+  raise RuntimeError unless exceptionRaised
+end
+
+result = test_pointer_out()
+raise RuntimeError if result.is_a? String
+
+exceptionRaised = false
+begin
+  test_const_pointer("bar")
+rescue TypeError
+  exceptionRaised = true
+ensure
+  raise RuntimeError unless exceptionRaised
+end
+
+result = test_const_pointer_out()
+raise RuntimeError if result.is_a? String
+
+result = test_reference_out()
+raise RuntimeError if result.is_a? String
+
+
+# Member Strings
+myStructure = Structure.new
+if (myStructure.ConstMemberString != "const member string")
+  raise RuntimeError 
+end
+
+
+if (Structure.ConstStaticMemberString != "const static member string")
+  raise RuntimeError
+end
+
+
+if (stdstringview_empty() != "")
+  puts "raise RuntimeError"
+end
+
+if (c_empty() != "")
+  raise RuntimeError
+end
+
+
+if (c_null() != nil)
+  raise RuntimeError
+end
+
+
+if (get_null(c_null()) != nil)
+  raise RuntimeError
+end
+
+
+if (get_null(c_empty()) != "non-null")
+  raise RuntimeError
+end
+
+if (get_null(stdstringview_empty()) != "non-null")
+  raise RuntimeError
+end
diff --git a/Examples/test-suite/ruby/cpp_enum_runme.rb b/Examples/test-suite/ruby/cpp_enum_runme.rb
new file mode 100644
index 0000000..0a395e0
--- /dev/null
+++ b/Examples/test-suite/ruby/cpp_enum_runme.rb
@@ -0,0 +1,19 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is directly derived from its Python counterpart.
+#
+
+require 'swig_assert'
+require 'cpp_enum'
+
+f = Cpp_enum::Foo.new
+swig_assert_equal('f.hola', 'Cpp_enum::Foo::Hello', binding)
+
+f.hola = Cpp_enum::Foo::Hi
+swig_assert_equal('f.hola', 'Cpp_enum::Foo::Hi', binding)
+
+f.hola = Cpp_enum::Foo::Hello
+swig_assert_equal('f.hola', 'Cpp_enum::Foo::Hello', binding)
+
+Cpp_enum::hi = Cpp_enum::Hello
+swig_assert_equal('Cpp_enum::hi', 'Cpp_enum::Hello', binding)
diff --git a/Examples/test-suite/ruby/cpp_static_runme.rb b/Examples/test-suite/ruby/cpp_static_runme.rb
new file mode 100644
index 0000000..85bdb70
--- /dev/null
+++ b/Examples/test-suite/ruby/cpp_static_runme.rb
@@ -0,0 +1,26 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is derived from its Python counterpart.
+#
+
+require 'swig_assert'
+require 'cpp_static'
+
+Cpp_static::StaticFunctionTest.static_func()
+Cpp_static::StaticFunctionTest.static_func_2(1)
+Cpp_static::StaticFunctionTest.static_func_3(1, 2)
+
+swig_assert_equal("Cpp_static::StaticMemberTest.static_int", "99", binding)
+Cpp_static::StaticMemberTest.static_int = 10
+swig_assert_equal("Cpp_static::StaticMemberTest.static_int", "10", binding)
+
+swig_assert_equal("Cpp_static::StaticBase.statty", "11", binding)
+swig_assert_equal("Cpp_static::StaticBase.grab_statty_base", "11", binding)
+swig_assert_equal("Cpp_static::StaticDerived.statty", "111", binding)
+swig_assert_equal("Cpp_static::StaticDerived.grab_statty_derived", "111", binding)
+Cpp_static::StaticBase.statty = 22
+Cpp_static::StaticDerived.statty = 222
+swig_assert_equal("Cpp_static::StaticBase.statty", "22", binding)
+swig_assert_equal("Cpp_static::StaticBase.grab_statty_base", "22", binding)
+swig_assert_equal("Cpp_static::StaticDerived.statty", "222", binding)
+swig_assert_equal("Cpp_static::StaticDerived.grab_statty_derived", "222", binding)
diff --git a/Examples/test-suite/ruby/director_string_runme.rb b/Examples/test-suite/ruby/director_string_runme.rb
index a18feac..f3f65f4 100644
--- a/Examples/test-suite/ruby/director_string_runme.rb
+++ b/Examples/test-suite/ruby/director_string_runme.rb
@@ -12,13 +12,28 @@
 require 'director_string'
 
 class B < Director_string::A
+ attr_accessor :smem
 
  def initialize(some_string)
   super(some_string)
  end
+
+ def get_first()
+  return super() + " world!"
+ end
+
+ def process_text(string)
+  super(string)
+  @smem = "hello"
+ end
+
 end
 
 
 b = B.new("hello")
-b.get_first
-b.get(0)
+raise RuntimeError if b.get(0) != "hello"
+raise RuntimeError if b.get_first() != "hello world!"
+raise RuntimeError if b.call_get_first() != "hello world!"
+
+b.call_process_func()
+raise RuntimeError if b.smem != "hello"
diff --git a/Examples/test-suite/ruby/director_unwrap_result_runme.rb b/Examples/test-suite/ruby/director_unwrap_result_runme.rb
new file mode 100644
index 0000000..26206ae
--- /dev/null
+++ b/Examples/test-suite/ruby/director_unwrap_result_runme.rb
@@ -0,0 +1,120 @@
+#!/usr/bin/env ruby
+#
+# This test checks the proper unwrapping of director objects before returning
+# a pointer to the (wrapped) instance.
+# Unwrapping must not happen for return-by-value and returning higher
+# reference levels (pointer to pointer, reference to pointer, etc.), but this
+# is already checked by the C++ compiler.
+#
+
+require 'swig_assert'
+
+require 'director_unwrap_result'
+
+############################
+# test with a regular (non-template) class
+
+class MyElement < Director_unwrap_result::Element
+end
+
+class MyStorage < Director_unwrap_result::Storage
+  def initialize(e)
+    super()
+    @elem = e
+  end
+  def getIt
+    @elem.getPtrPtr
+  end
+end
+
+e = MyElement.new
+s = MyStorage.new(e)
+
+swig_assert_equal('s.getElement.class', 'Director_unwrap_result::Element', binding)
+swig_assert('s.getElement != e', binding)
+
+# this shows that the director class was unwrapped:
+swig_assert_equal('s.getElementPtr.class', 'MyElement', binding)
+swig_assert_equal('s.getElementPtr', 'e', binding)
+
+# this shows that the director class was unwrapped:
+swig_assert_equal('s.getElementRef.class', 'MyElement', binding)
+swig_assert_equal('s.getElementRef', 'e', binding)
+
+# this shows that the director class was unwrapped:
+swig_assert_equal('s.getElementPtrTypedef.class', 'MyElement', binding)
+swig_assert_equal('s.getElementPtrTypedef', 'e', binding)
+
+# this shows that the director class was unwrapped:
+swig_assert_equal('s.getElementRefTypedef.class', 'MyElement', binding)
+swig_assert_equal('s.getElementRefTypedef', 'e', binding)
+
+# this is not unwrapped:
+swig_assert_equal('s.getElementPtrPtr.class', 'SWIG::TYPE_p_p_Element', binding)
+swig_assert_equal('s.getElementPtrPtr.class', 'SWIG::TYPE_p_p_Element', binding)
+
+# this is not unwrapped:
+swig_assert_equal('s.getElementPtrRef.class', 'SWIG::TYPE_p_p_Element', binding)
+swig_assert_equal('s.getElementPtrRef.class', 'SWIG::TYPE_p_p_Element', binding)
+
+# this is not unwrapped:
+swig_assert_equal('s.getElementPtrRefTypedef.class', 'SWIG::TYPE_p_p_Element', binding)
+swig_assert_equal('s.getElementPtrRefTypedef.class', 'SWIG::TYPE_p_p_Element', binding)
+
+############################
+# test with a template class
+
+class MyElementStorage < Director_unwrap_result::ElementStorage
+  def initialize(e)
+    super()
+    @elem = e
+  end
+  def getIt
+    @elem
+  end
+end
+
+class MyElementPtrStorage < Director_unwrap_result::ElementPtrStorage
+  def initialize(e)
+    super()
+    @elem = e
+  end
+  def getIt
+    @elem.getPtrPtr
+  end
+end
+
+class MyElementPtrPtrStorage < Director_unwrap_result::ElementPtrPtrStorage
+  def initialize(e)
+    super()
+    @elem = e
+  end
+  def getIt
+    @elem.getPtrPtrPtr
+  end
+end
+
+e = MyElement.new
+
+s = MyElementStorage.new(e)
+swig_assert_equal('s.getVal.class', 'Director_unwrap_result::Element', binding)
+swig_assert('s.getVal != e', binding)
+# this shows that the director class was unwrapped:
+swig_assert_equal('s.getPtr.class', 'MyElement', binding)
+swig_assert_equal('s.getPtr', 'e', binding)
+# this shows that the director class was unwrapped:
+swig_assert_equal('s.getRef.class', 'MyElement', binding)
+swig_assert_equal('s.getRef', 'e', binding)
+
+s = MyElementPtrStorage.new(e)
+# this shows that the director class was unwrapped:
+swig_assert_equal('s.getVal.class', 'MyElement', binding)
+swig_assert_equal('s.getVal', 'e', binding)
+swig_assert_equal('s.getPtr.class', 'SWIG::TYPE_p_p_Element', binding)
+swig_assert_equal('s.getRef.class', 'SWIG::TYPE_p_p_Element', binding)
+
+s = MyElementPtrPtrStorage.new(e)
+swig_assert_equal('s.getVal.class', 'SWIG::TYPE_p_p_Element', binding)
+swig_assert_equal('s.getPtr.class', 'SWIG::TYPE_p_p_p_Element', binding)
+swig_assert_equal('s.getRef.class', 'SWIG::TYPE_p_p_p_Element', binding)
+
diff --git a/Examples/test-suite/ruby/enums_runme.rb b/Examples/test-suite/ruby/enums_runme.rb
index cafac25..274d595 100644
--- a/Examples/test-suite/ruby/enums_runme.rb
+++ b/Examples/test-suite/ruby/enums_runme.rb
@@ -25,10 +25,7 @@
 Enums::BAR2 == 1
 EOF
 
-#
-# @bug: 
-#
-# swig_assert_each_line( <<EOF )
-# Enums::IFoo::Phoo == 50
-# Enums::IFoo::Char == 'a'[0]
-# EOF
+swig_assert_each_line( <<EOF )
+Enums::Phoo == 50
+Enums::Char == 'a'[0]
+EOF
diff --git a/Examples/test-suite/ruby/friends_runme.rb b/Examples/test-suite/ruby/friends_runme.rb
index c5c1caa..232bb68 100644
--- a/Examples/test-suite/ruby/friends_runme.rb
+++ b/Examples/test-suite/ruby/friends_runme.rb
@@ -17,3 +17,6 @@
 raise RuntimeError if Friends::get_val1(a) != 2
 raise RuntimeError if Friends::get_val2(a) != 4
 raise RuntimeError if Friends::get_val3(a) != 6
+
+raise RuntimeError if Friends.chum_blah() != 1234
+raise RuntimeError if Friends.mate_blah() != 4321
diff --git a/Examples/test-suite/ruby/global_immutable_vars_cpp_runme.rb b/Examples/test-suite/ruby/global_immutable_vars_cpp_runme.rb
new file mode 100644
index 0000000..7897f7d
--- /dev/null
+++ b/Examples/test-suite/ruby/global_immutable_vars_cpp_runme.rb
@@ -0,0 +1,48 @@
+#!/usr/bin/env ruby
+#
+# C++ version of global_immutable_vars_runme.rb
+#
+
+require 'swig_assert'
+
+require 'global_immutable_vars_cpp'
+
+# first check if all variables can be read
+swig_assert_each_line( <<EOF )
+Global_immutable_vars_cpp::default_mutable_var == 40
+Global_immutable_vars_cpp::global_immutable_var == 41
+Global_immutable_vars_cpp::specific_mutable_var == 42
+Global_immutable_vars_cpp::global_mutable_var == 43
+Global_immutable_vars_cpp::specific_immutable_var == 44
+EOF
+
+# check that all mutable variables can be modified
+swig_assert_each_line( <<EOF )
+Global_immutable_vars_cpp::default_mutable_var = 80
+Global_immutable_vars_cpp::default_mutable_var == 80
+Global_immutable_vars_cpp::specific_mutable_var = 82
+Global_immutable_vars_cpp::specific_mutable_var == 82
+Global_immutable_vars_cpp::global_mutable_var = 83
+Global_immutable_vars_cpp::global_mutable_var == 83
+EOF
+
+# now check that immutable variables cannot be modified
+had_exception = false
+begin
+  Global_immutable_vars_cpp::global_immutable_var = 81
+rescue NoMethodError => e
+  had_exception = true
+end
+swig_assert(had_exception, nil,
+            "Global_immutable_vars_cpp::global_immutable_var is writable (expected to be immutable)")
+
+had_exception = false
+begin
+  Global_immutable_vars_cpp::specific_immutable_var = 81
+rescue NoMethodError => e
+  had_exception = true
+end
+swig_assert(had_exception, nil,
+            "Global_immutable_vars_cpp::specific_immutable_var is writable (expected to be immutable)")
+
+swig_assert(Global_immutable_vars_cpp::check_values(80, 41, 82, 83, 44) == 1, nil, "Check values failed")
diff --git a/Examples/test-suite/ruby/global_immutable_vars_runme.rb b/Examples/test-suite/ruby/global_immutable_vars_runme.rb
new file mode 100644
index 0000000..ffbea27
--- /dev/null
+++ b/Examples/test-suite/ruby/global_immutable_vars_runme.rb
@@ -0,0 +1,52 @@
+#!/usr/bin/env ruby
+#
+# Here the proper generation of mutable and immutable variables is tested
+# in the target language.
+# Immutable variables do not have "<var>=" methods generated by SWIG,
+# therefore trying to assign these variables shall throw a NoMethodError
+# exception.
+#
+
+require 'swig_assert'
+
+require 'global_immutable_vars'
+
+# first check if all variables can be read
+swig_assert_each_line( <<EOF )
+Global_immutable_vars::default_mutable_var == 40
+Global_immutable_vars::global_immutable_var == 41
+Global_immutable_vars::specific_mutable_var == 42
+Global_immutable_vars::global_mutable_var == 43
+Global_immutable_vars::specific_immutable_var == 44
+EOF
+
+# check that all mutable variables can be modified
+swig_assert_each_line( <<EOF )
+Global_immutable_vars::default_mutable_var = 80
+Global_immutable_vars::default_mutable_var == 80
+Global_immutable_vars::specific_mutable_var = 82
+Global_immutable_vars::specific_mutable_var == 82
+Global_immutable_vars::global_mutable_var = 83
+Global_immutable_vars::global_mutable_var == 83
+EOF
+
+# now check that immutable variables cannot be modified
+had_exception = false
+begin
+  Global_immutable_vars::global_immutable_var = 81
+rescue NoMethodError => e
+  had_exception = true
+end
+swig_assert(had_exception, nil,
+            "Global_immutable_vars::global_immutable_var is writable (expected to be immutable)")
+
+had_exception = false
+begin
+  Global_immutable_vars::specific_immutable_var = 81
+rescue NoMethodError => e
+  had_exception = true
+end
+swig_assert(had_exception, nil,
+            "Global_immutable_vars::specific_immutable_var is writable (expected to be immutable)")
+
+swig_assert(Global_immutable_vars::check_values(80, 41, 82, 83, 44) == 1, nil, "Check values failed")
diff --git a/Examples/test-suite/ruby/ignore_parameter_runme.rb b/Examples/test-suite/ruby/ignore_parameter_runme.rb
index c5466a2..1d1e0ba 100644
--- a/Examples/test-suite/ruby/ignore_parameter_runme.rb
+++ b/Examples/test-suite/ruby/ignore_parameter_runme.rb
@@ -25,6 +25,7 @@
 raise RuntimeError unless sc.astonmartin("foo", 1.0) == 101
 raise RuntimeError unless sc.bugatti("foo", 0) == 8.8
 raise RuntimeError unless sc.lamborghini() == 101
+raise RuntimeError unless sc.audi() == 8.8
 
 # Constructor tests
 MiniCooper.new(0, 1.0)
diff --git a/Examples/test-suite/ruby/import_fragments_runme.rb b/Examples/test-suite/ruby/import_fragments_runme.rb
new file mode 100644
index 0000000..a529980
--- /dev/null
+++ b/Examples/test-suite/ruby/import_fragments_runme.rb
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# Put description here
+#
+# 
+# 
+# 
+#
+
+require 'swig_assert'
+
+exception_file = nil
+
+begin
+  require 'import_fragments'
+rescue LoadError => e
+  # due to missing import_fragments_a
+  exception_file = e.respond_to?(:path) ? e.path : e.to_s.sub(/.* -- /, '')
+end
+
+swig_assert(exception_file == "import_fragments_a",
+            msg: "Loading should have failed due to missing 'import_fragments_a'")
+
diff --git a/Examples/test-suite/ruby/li_constraints_runme.rb b/Examples/test-suite/ruby/li_constraints_runme.rb
new file mode 100644
index 0000000..a4dcd68
--- /dev/null
+++ b/Examples/test-suite/ruby/li_constraints_runme.rb
@@ -0,0 +1,63 @@
+#!/usr/bin/env ruby
+
+require 'li_constraints'
+include Li_constraints
+
+def check_double(except, fn, f, val)
+  actual = true
+  proper = false
+  begin
+    fn.call(val)
+  rescue => e
+    actual = false
+    proper = e.class == ArgumentError && e.message == "Expected a #{f} value."
+  end
+  if actual
+    if !except
+      raise RuntimeError, "function '#{f}' with #{val} should perform an exception"
+    end
+  else
+    if except
+      raise RuntimeError, "function '#{f}' with #{val} should not perform an exception"
+    elsif !proper
+      raise RuntimeError, "function '#{f}' with #{val} should perform a proper exception"
+    end
+  end
+end
+
+nonnegative = -> (v) { test_nonnegative(v) }
+check_double(true, nonnegative, "non-negative", 10)
+check_double(true, nonnegative, "non-negative", 0)
+check_double(false, nonnegative, "non-negative", -10)
+
+nonpositive = -> (v) { test_nonpositive(v) }
+check_double(false, nonpositive, "non-positive", 10)
+check_double(true, nonpositive, "non-positive", 0)
+check_double(true, nonpositive, "non-positive", -10)
+
+positive = -> (v) { test_positive(v) }
+check_double(true, positive, "positive", 10)
+check_double(false, positive, "positive", 0)
+check_double(false, positive, "positive", -10)
+
+negative = -> (v) { test_negative(v) }
+check_double(false, negative, "negative", 10)
+check_double(false, negative, "negative", 0)
+check_double(true, negative, "negative", -10)
+
+nonzero = -> (v) { test_nonzero(v) }
+check_double(true, nonzero, "nonzero", 10)
+check_double(false, nonzero, "nonzero", 0)
+check_double(true, nonzero, "nonzero", -10)
+
+have_exception = false
+begin
+  test_nonnull(nil)
+rescue => e
+  have_exception = e.class == ArgumentError && e.message == "Received a NULL pointer."
+end
+if not have_exception
+  raise RuntimeError, "test_nonnull should perform exception with 'null' value"
+end
+nonnull = get_nonnull()
+test_nonnull(nonnull)
diff --git a/Examples/test-suite/ruby/li_std_auto_ptr_runme.rb b/Examples/test-suite/ruby/li_std_auto_ptr_runme.rb
new file mode 100644
index 0000000..48276a8
--- /dev/null
+++ b/Examples/test-suite/ruby/li_std_auto_ptr_runme.rb
@@ -0,0 +1,151 @@
+#!/usr/bin/env ruby
+
+require 'swig_assert'
+
+require 'li_std_auto_ptr'
+
+def gc_check(expected_count)
+#  GC.start(full_mark: true, immediate_sweep: true)
+  GC.start
+# GC is not reliably run, skip check
+#  swig_assert_equal_simple(expected_count, Li_std_auto_ptr::Klass::getTotal_count())
+end
+
+def checkCount(expected_count)
+    actual_count = Li_std_auto_ptr::Klass.getTotal_count()
+    if (actual_count != expected_count)
+        raise RuntimeError, "Counts incorrect, expected:" + expected_count + " actual:" + actual_count
+    end
+end
+
+# Test raw pointer handling involving virtual inheritance
+kini = Li_std_auto_ptr::KlassInheritance.new("KlassInheritanceInput")
+checkCount(1)
+s = Li_std_auto_ptr.useKlassRawPtr(kini)
+if (s != "KlassInheritanceInput")
+    raise RuntimeError, "Incorrect string: " + s
+end
+# kini = nil
+Li_std_auto_ptr.takeKlassAutoPtr(kini) # Ensure object is deleted (can't rely on GC)
+checkCount(0)
+
+
+# auto_ptr as input
+kin = Li_std_auto_ptr::Klass.new("KlassInput")
+checkCount(1)
+s = Li_std_auto_ptr.takeKlassAutoPtr(kin)
+checkCount(0)
+if (s != "KlassInput")
+    raise RuntimeError, "Incorrect string: " + s
+end
+exception_thrown = false
+begin
+    Li_std_auto_ptr.is_nullptr(kin)
+rescue ObjectPreviouslyDeleted
+    exception_thrown = true
+end
+if (!exception_thrown)
+    raise RuntimeError, "is_nullptr failed to throw"
+end
+kin = nil
+checkCount(0)
+
+kin = Li_std_auto_ptr::Klass.new("KlassInput")
+checkCount(1)
+s = Li_std_auto_ptr.takeKlassAutoPtr(kin)
+checkCount(0)
+if (s != "KlassInput")
+    raise RuntimeError, "Incorrect string: " + s
+end
+exception_thrown = false
+begin
+    Li_std_auto_ptr.is_nullptr(kin)
+rescue ObjectPreviouslyDeleted
+    exception_thrown = true
+end
+if (!exception_thrown)
+    raise RuntimeError, "is_nullptr failed to throw"
+end
+exception_thrown = false
+begin
+    Li_std_auto_ptr.takeKlassAutoPtr(kin)
+rescue RuntimeError => e
+    # puts e.message
+    exception_thrown = true
+end
+if (!exception_thrown)
+    raise RuntimeError, "double usage of takeKlassAutoPtr should have been an error"
+end
+kin = nil
+checkCount(0)
+
+kin = Li_std_auto_ptr::Klass.new("KlassInput")
+exception_thrown = false
+notowned = Li_std_auto_ptr::get_not_owned_ptr(kin)
+begin
+    Li_std_auto_ptr::takeKlassAutoPtr(notowned)
+rescue RuntimeError
+    if (!e.to_s.include? "cannot release ownership as memory is not owned")
+      raise RuntimeError, "incorrect exception message"
+    end
+    exception_thrown = true
+end
+if (!exception_thrown)
+  raise RuntimeError, "Should have thrown 'Cannot release ownership as memory is not owned' error"
+end
+checkCount(1)
+Li_std_auto_ptr.takeKlassAutoPtr(kin) # Ensure object is deleted (can't rely on GC)
+checkCount(0)
+
+kini = Li_std_auto_ptr::KlassInheritance.new("KlassInheritanceInput")
+checkCount(1)
+s = Li_std_auto_ptr.takeKlassAutoPtr(kini)
+checkCount(0)
+if (s != "KlassInheritanceInput")
+    raise RuntimeError, "Incorrect string: " + s
+end
+exception_thrown = false
+begin
+    Li_std_auto_ptr.is_nullptr(kini)
+rescue ObjectPreviouslyDeleted
+    exception_thrown = true
+end
+if (!exception_thrown)
+    raise RuntimeError, "is_nullptr failed to throw"
+end
+kini = nil
+checkCount(0)
+
+Li_std_auto_ptr::takeKlassAutoPtr(nil)
+Li_std_auto_ptr::takeKlassAutoPtr(Li_std_auto_ptr::make_null())
+checkCount(0)
+
+# overloaded parameters
+if (Li_std_auto_ptr::overloadTest() != 0)
+  raise RuntimeError, "overloadTest failed"
+end
+if (Li_std_auto_ptr::overloadTest(nil) != 1)
+  raise RuntimeError, "overloadTest failed"
+end
+if (Li_std_auto_ptr::overloadTest(Li_std_auto_ptr::Klass.new("over")) != 1)
+  raise RuntimeError, "overloadTest failed"
+end
+checkCount(0);
+
+
+# auto_ptr as output
+k1 = Li_std_auto_ptr::makeKlassAutoPtr("first")
+k2 = Li_std_auto_ptr::makeKlassAutoPtr("second")
+swig_assert_equal_simple(2, Li_std_auto_ptr::Klass::getTotal_count())
+
+gc_check(2)
+k1 = nil
+gc_check(1)
+
+swig_assert_equal_simple(k2.getLabel(), "second")
+gc_check(1)
+
+k2 = nil
+gc_check(0)
+
+swig_assert_equal_simple(Li_std_auto_ptr::makeNullAutoPtr(), nil)
diff --git a/Examples/test-suite/ruby/li_std_containers_int_runme.rb b/Examples/test-suite/ruby/li_std_containers_int_runme.rb
new file mode 100644
index 0000000..7359417
--- /dev/null
+++ b/Examples/test-suite/ruby/li_std_containers_int_runme.rb
@@ -0,0 +1,203 @@
+#!/usr/bin/env ruby
+
+# Check std::vector and std::list behaves the same as Ruby iterable
+# types (list)
+
+require 'swig_assert'
+require 'li_std_containers_int'
+
+def failed(a, b, msg)
+    # to_a() convert to array
+    # convert to array, so we can call join().
+    # join() join array element to string with a seperator.
+    raise RuntimeError, msg+" ["+a.to_a().join(", ")+"] ["+b.to_a().join(", ")+"]"
+end
+
+def compare_sequences(a, b)
+    # A start, out of range, may produce nil value
+    # As long as vector behave as list, we do not care :-)
+    if a == nil and b == nil then
+        return
+    end
+    if a.size != b.size then
+        failed(a, b, "different sizes")
+    end
+    a.each_index do |i|
+        if a[i] != b[i] then
+            failed(a, b, "elements are different")
+        end
+    end
+end
+
+def compare_containers(pythonlist, swigvector, swiglist)
+    compare_sequences(pythonlist, swigvector)
+    compare_sequences(pythonlist, swiglist)
+end
+
+# Check std::vector and std::list assignment behaves same as Ruby list
+# assignment including exceptions
+def container_insert_step(i, l, newval)
+    ps = (1..6).to_a
+    iv = Li_std_containers_int::Vector_int.new(ps)
+    il = Li_std_containers_int::List_int.new(ps)
+
+    # Ruby slice
+    begin
+        if l == nil then
+            ps[i] = newval
+        else
+            ps[i,l] = newval
+        end
+        ps_error = nil
+    rescue => e
+        ps_error = e
+    end
+
+    begin
+        if l == nil then
+            iv[i] = newval
+        else
+            iv[i,l] = newval
+        end
+        iv_error = nil
+    rescue => e
+        iv_error = e
+    end
+
+    begin
+        if l == nil then
+            il[i] = newval
+        else
+            il[i,l] = newval
+        end
+        il_error = nil
+    rescue => e
+        il_error = e
+    end
+
+    if iv_error != nil and il_error == nil then
+        raise RuntimeError, "ValueError std::vector<> fails while std::list<> pass: " + iv_error.to_s
+    end
+    if iv_error == nil and il_error != nil then
+        raise RuntimeError, "ValueError std::vector<> pass while std::list<> fail: " + il_error.to_s
+    end
+    if ps_error != nil and iv_error == nil then
+        raise RuntimeError, "ValueError C++ wrapper should fail like ruby: " + ps_error.to_s
+    end
+    if ps_error != nil and iv_error != nil and il_error != nil then
+        compare_containers(ps, iv, il)
+    end
+end
+
+# Check std::vector and std::list delete behaves same as Ruby list
+# delete including exceptions
+def container_delete(i, j)
+    ps = (1..6).to_a
+    iv = Li_std_containers_int::Vector_int.new(ps)
+    il = Li_std_containers_int::List_int.new(ps)
+
+    # Ruby slice
+    begin
+        if j == nil then
+            ps[i] = nil
+        else
+            ps[i,(j - i)] = nil
+        end
+        ps_error = nil
+    rescue => e
+        ps_error = e
+    end
+
+    # std::vector<int>
+    begin
+        if j == nil then
+            iv[i] = nil
+        else
+            iv[i,(j - i)] = nil
+        end
+        iv_error = nil
+    rescue => e
+        iv_error = e
+    end
+
+    # std::list<int>
+    begin
+        if j == nil then
+            il[i] = nil
+        else
+            il[i,(j - i)] = nil
+        end
+        il_error = nil
+    rescue => e
+        il_error = e
+    end
+
+    if iv_error != nil and il_error == nil then
+        raise RuntimeError, "ValueError std::vector<> fails while std::list<> pass: " + iv_error.to_s
+    end
+    if iv_error == nil and il_error != nil then
+        raise RuntimeError, "ValueError std::vector<> pass while std::list<> fail: " + il_error.to_s
+    end
+    if ps_error != nil and iv_error == nil then
+        raise RuntimeError, "ValueError C++ wrapper should fail like ruby: " + ps_error.to_s
+    end
+    if ps_error != nil and iv_error != nil and il_error != nil then
+        compare_containers(ps, iv, il)
+    end
+end
+
+ps = [0, 1, 2, 3, 4, 5]
+iv = Li_std_containers_int::Vector_int.new(ps)
+il = Li_std_containers_int::List_int.new(ps)
+
+# Ruby use array[start, length]
+# slices
+compare_containers(ps[0,0], iv[0,0], il[0,0])
+compare_containers(ps[1,0], iv[1,0], il[1,0])
+compare_containers(ps[1,2], iv[1,2], il[1,2])
+compare_containers(ps[2,2], iv[2,2], il[2,2])
+compare_containers(ps[0,3], iv[0,3], il[0,3])
+compare_containers(ps[3,3], iv[3,3], il[3,3])
+compare_containers(ps[3,7], iv[3,7], il[3,7]) # beyond end of range
+
+# before beginning of range (negative indexing)
+compare_containers(ps[-1,6], iv[-1,6], il[-1,6])
+compare_containers(ps[-2,6], iv[-2,6], il[-2,6])
+compare_containers(ps[-5,6], iv[-5,6], il[-5,6])
+compare_containers(ps[-6,6], iv[-6,6], il[-6,6])
+
+# before beginning of range (negative indexing, negative index is >
+# container size)
+compare_containers(ps[-7,7], iv[-7,7], il[-7,7])
+compare_containers(ps[-100,7], iv[-100,7], il[-100,7])
+
+compare_containers(ps[3,9], iv[3,9], il[3,9])
+compare_containers(ps[0,3], iv[0,3], il[0,3])
+compare_containers(ps, iv, il)
+compare_containers(ps[-3,9], iv[-3,9], il[-3,9])
+compare_containers(ps[-6,9], iv[-6,9], il[-6,9])
+
+# insert sequences (growing, shrinking and staying same size)
+(-6..6).step do |start|
+    # single element set/replace
+    container_insert_step(start, nil, 111)
+    (0..6).step do |len|
+        container_insert_step(start, len, [111, 222, 333, 444, 555, 666, 777])
+        container_insert_step(start, len, [111, 222, 333, 444, 555, 666])
+        container_insert_step(start, len, [111, 222, 333, 444, 555])
+        container_insert_step(start, len, [111, 222, 333, 444])
+        container_insert_step(start, len, [111, 222, 333])
+        container_insert_step(start, len, [111, 222])
+        container_insert_step(start, len, [111])
+        container_insert_step(start, len, [])
+    end
+end
+
+# delete sequences (growing, shrinking and staying same size)
+for start in [-102, -100, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 100, 102]
+    # single element delete
+    container_delete(start, nil)
+    for vend in [-102, -100, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 100, 102]
+        container_delete(start, vend)
+    end
+end
diff --git a/Examples/test-suite/ruby/li_std_functors_runme.rb b/Examples/test-suite/ruby/li_std_functors_runme.rb
index 5623d49..a2a7c6f 100644
--- a/Examples/test-suite/ruby/li_std_functors_runme.rb
+++ b/Examples/test-suite/ruby/li_std_functors_runme.rb
@@ -63,7 +63,9 @@
   yield method(:_map), Li_std_functors::Map
 end
 
-# these should fail and not segfault
+# these should fail and not segfault but currently do segfault with Ruby 2.6
+# in GitHub Actions environment
+if RUBY_VERSION != '2.6.6'
 begin
   Li_std_functors::Set.new('sd')
 rescue
@@ -72,5 +74,4 @@
 test do |proc, container|
   proc.call(container)
 end
-
-
+end
diff --git a/Examples/test-suite/ruby/li_std_map_runme.rb b/Examples/test-suite/ruby/li_std_map_runme.rb
index 0ec8cac..9661e4c 100644
--- a/Examples/test-suite/ruby/li_std_map_runme.rb
+++ b/Examples/test-suite/ruby/li_std_map_runme.rb
@@ -43,6 +43,16 @@
 m.each_key { |k| swig_assert_equal("pm[#{k.inspect}]", "m[#{k.inspect}]", binding) }
 EOF
 
+
+Li_std_map::populate(Li_std_map.MyMap)
+Li_std_map.MyMap["eeeeee"] = 6
+swig_assert( "Li_std_map.MyMap['a'] == 1", binding )
+swig_assert( "Li_std_map.MyMap['aa'] == 2", binding )
+swig_assert( "Li_std_map.MyMap['zzz'] == 3", binding )
+swig_assert( "Li_std_map.MyMap['xxxx'] == 4", binding )
+swig_assert( "Li_std_map.MyMap['aaaaa'] == 5", binding )
+swig_assert( "Li_std_map.MyMap['eeeeee'] == 6", binding )
+
 mii = Li_std_map::IntIntMap.new
 
 mii[1] = 1
diff --git a/Examples/test-suite/ruby/li_std_set_runme.rb b/Examples/test-suite/ruby/li_std_set_runme.rb
index efc163b..455a170 100644
--- a/Examples/test-suite/ruby/li_std_set_runme.rb
+++ b/Examples/test-suite/ruby/li_std_set_runme.rb
@@ -56,11 +56,15 @@
 s = LanguageSet.new
 s.insert([1,2])
 s.insert(1)
-s.insert("hello")
+# There is a reference count issue that needs fixing, see https://github.com/swig/swig/issues/2115
+# Workaround is to create hello variable containing a string and use it instead of just "hello"
+hello = "hello"
+s.insert(hello)
 #s.to_a == [1,[1,2],'hello']  # sort order: s.sort {|a,b| a.hash <=> b.hash}
 # Test above is flawed as LanguageSet sorts by each element's hash, so the order will change from one invocation to the next. Sort a conversion to array instead.
+GC.start
 sa = s.to_a.sort { |x, y| x.to_s <=> y.to_s }
-sa == [1,[1,2],'hello']
+sa == [1,[1,2],hello]
 
 EOF
 
diff --git a/Examples/test-suite/ruby/li_std_string_runme.rb b/Examples/test-suite/ruby/li_std_string_runme.rb
index dc85b5d..36824a4 100644
--- a/Examples/test-suite/ruby/li_std_string_runme.rb
+++ b/Examples/test-suite/ruby/li_std_string_runme.rb
@@ -122,23 +122,34 @@
 if (s != "hellohello")
   raise RuntimeError
 end
+if (test_reference_output() != "output")
+  raise RuntimeError
+end
 
 
 if (stdstring_empty() != "")
   raise RuntimeError
 end
 
-if (c_empty() != "") 
+if (c_empty() != "")
   raise RuntimeError
 end
 
 
-if (c_null() != nil) 
+if (c_null() != nil)
   raise RuntimeError
 end
 
 
-if (get_null(c_null()) != nil) 
+if (get_null(c_null()) != nil)
   raise RuntimeError
 end
 
+
+if (get_null(c_empty()) != "non-null")
+  raise RuntimeError
+end
+
+if (get_null(stdstring_empty()) != "non-null")
+  raise RuntimeError
+end
diff --git a/Examples/test-suite/ruby/li_std_vector_runme.rb b/Examples/test-suite/ruby/li_std_vector_runme.rb
index 68feb8f..dfcf285 100644
--- a/Examples/test-suite/ruby/li_std_vector_runme.rb
+++ b/Examples/test-suite/ruby/li_std_vector_runme.rb
@@ -260,3 +260,20 @@
   lv = LanguageVector.new('crapola')
 rescue
 end
+
+# Variables
+vh = VariableHolder.new
+vector_append(vh.instance_variable, 10)
+swig_assert_equal("vh.instance_variable[0]", "10", binding)
+vh.instance_variable.clear
+swig_assert_equal("vh.instance_variable.empty?", "true", binding)
+
+vector_append(VariableHolder.static_variable, 20)
+swig_assert_equal("VariableHolder.static_variable[0]", "20", binding)
+VariableHolder.static_variable.clear
+swig_assert_equal("VariableHolder.static_variable.empty?", "true", binding)
+
+vector_append(Li_std_vector::global_variable, 30)
+swig_assert_equal("Li_std_vector::global_variable[0]", "30", binding)
+Li_std_vector::global_variable.clear
+swig_assert_equal("Li_std_vector::global_variable.empty?", "true", binding)
diff --git a/Examples/test-suite/ruby/li_std_wstring_runme.rb b/Examples/test-suite/ruby/li_std_wstring_runme.rb
index 4922d8d..170f80e 100644
--- a/Examples/test-suite/ruby/li_std_wstring_runme.rb
+++ b/Examples/test-suite/ruby/li_std_wstring_runme.rb
@@ -50,3 +50,10 @@
 swig_assert_equal("Li_std_wstring.test_value(x)", "x", binding)
 swig_assert_equal("Li_std_wstring.test_ccvalue(x)", '"abc"', binding)
 swig_assert_equal("Li_std_wstring.test_wchar_overload(x)", '"abc"', binding)
+
+ts = Li_std_wstring::Wchar_test_struct.new
+ts.wchar_t_member = h
+swig_assert_equal("ts.wchar_t_member", "h", binding)
+ts.wchar_t_ptr_member = s
+swig_assert_equal("ts.wchar_t_ptr_member", "s", binding)
+
diff --git a/Examples/test-suite/ruby/multiple_inheritance_abstract_runme.rb b/Examples/test-suite/ruby/multiple_inheritance_abstract_runme.rb
new file mode 100644
index 0000000..01e9e6e
--- /dev/null
+++ b/Examples/test-suite/ruby/multiple_inheritance_abstract_runme.rb
@@ -0,0 +1,243 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is directly derived from its Java counterpart.
+#
+
+require 'swig_assert'
+require 'multiple_inheritance_abstract'
+
+# Test base class as a parameter in Ruby
+
+def jcbase1b(cb1)
+  cb1.cbase1y
+end
+
+def jabase1(ab1)
+  ab1.abase1
+end
+
+def jcbase2(cb2)
+  cb2.cbase2
+end
+
+# test Derived1
+d1 = Multiple_inheritance_abstract::Derived1.new
+swig_assert_equal('d1.cbase1y', '3', binding, 'Derived1::cbase1y() failed')
+swig_assert_equal('d1.cbase2', '4', binding, 'Derived1::cbase2() failed')
+
+# test Derived2
+d2 = Multiple_inheritance_abstract::Derived2.new
+swig_assert_equal('d2.cbase1y', '6', binding, 'Derived2::cbase1y() failed')
+swig_assert_equal('d2.abase1', '5', binding, 'Derived2::cbase1y() failed')
+
+# test Derived3
+d3 = Multiple_inheritance_abstract::Derived3.new
+swig_assert_equal('d3.cbase1y', '7', binding, 'Derived3::cbase1y() failed')
+swig_assert_equal('d3.cbase2', '8', binding, 'Derived3::cbase2() failed')
+swig_assert_equal('d3.abase1', '9', binding, 'Derived3::abase1() failed')
+
+# test Bottom1
+b1 = Multiple_inheritance_abstract::Bottom1.new
+swig_assert_equal('b1.cbase1y', '103', binding, 'Bottom1::cbase1y() failed')
+swig_assert_equal('b1.cbase2', '104', binding, 'Bottom1::cbase2() failed')
+
+# test Bottom2
+b2 = Multiple_inheritance_abstract::Bottom2.new
+swig_assert_equal('b2.cbase1y', '206', binding, 'Bottom2::cbase1y() failed')
+swig_assert_equal('b2.abase1', '205', binding, 'Bottom2::abase1() failed')
+
+# test Bottom3
+b3 = Multiple_inheritance_abstract::Bottom3.new
+swig_assert_equal('b3.cbase1y', '307', binding, 'Bottom3::cbase1y() failed')
+swig_assert_equal('b3.cbase2', '308', binding, 'Bottom3::cbase2() failed')
+swig_assert_equal('b3.abase1', '309', binding, 'Bottom3::abase1() failed')
+
+# test interfaces from C++ classes
+cb1 = Multiple_inheritance_abstract::CBase1.new
+cb2 = Multiple_inheritance_abstract::CBase2.new
+swig_assert_equal('cb1.cbase1y', '1', binding, 'CBase1::cbase1y() failed')
+swig_assert_equal('cb2.cbase2', '2', binding, 'CBase2::cbase2() failed')
+
+# test nspace class as return value
+ab1 = d3.cloneit
+swig_assert_equal('ab1.abase1', '9', binding, 'Derived3::abase1() through ABase1 failed')
+
+# test concrete base class as return value
+cb6 = d2.cloneit
+cb7 = d1.cloneit
+swig_assert_equal('cb6.cbase1y', '6', binding, 'Derived2::cbase1y() through CBase1 failed')
+swig_assert_equal('cb7.cbase2', '4', binding, 'Derived1:cbase2() through ABase1 failed')
+
+# test multi inheritance
+cb3 = Multiple_inheritance_abstract::Derived1.new
+cb4 = Multiple_inheritance_abstract::Derived3.new
+cb5 = Multiple_inheritance_abstract::Derived3.new
+ab6 = Multiple_inheritance_abstract::Derived2.new
+swig_assert_equal('cb3.cbase1y', '3', binding, 'Derived1::cbase1y() through CBase1 failed')
+swig_assert_equal('cb4.cbase1y', '7', binding, 'Derived3::cbase1y() through CBase1 failed')
+swig_assert_equal('cb5.cbase2', '8', binding, 'Derived3::cbase2() through CBase2 failed')
+swig_assert_equal('ab6.abase1', '5', binding, 'Derived2::abase1() through ABase1 failed')  
+
+# test base classes as parameter in Ruby
+swig_assert_equal('jcbase1b(d1)', '3', binding, 'jcbase1b() through Derived1 as parameter failed')
+swig_assert_equal('jcbase1b(d2)', '6', binding, 'jcbase1b() through Derived2 as parameter failed')
+swig_assert_equal('jcbase1b(d3)', '7', binding, 'jcbase1b() through Derived3 as parameter failed')
+swig_assert_equal('jcbase2(d1)', '4', binding, 'jcbase2() through Derived1 as parameter failed')
+swig_assert_equal('jcbase2(d3)', '8', binding, 'jcbase2() through Derived3 as parameter failed')
+swig_assert_equal('jabase1(d2)', '5', binding, 'jabase1() through Derived2 as parameter failed')
+swig_assert_equal('jabase1(d3)', '9', binding, 'jabase1() through Derived3 as parameter failed')
+
+# value parameters
+# test CBase1 CBase2 as parameters (note slicing for Derived and Bottom classes)
+swig_assert_equal('Multiple_inheritance_abstract::InputValCBase1(d1)', '1', binding, 'InputValCBase1(), Derived1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputValCBase1(d2)', '1', binding, 'InputValCBase1(), Derived2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputValCBase1(d3)', '1', binding, 'InputValCBase1(), Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputValCBase2(d3)', '2', binding, 'InputValCBase2(), Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputValCBase2(d1)', '2', binding, 'InputValCBase2(), Derived1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputValCBase1(cb1)', '1', binding, 'InputValCBase1(), CBase1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputValCBase2(cb2)', '2', binding, 'InputValCBase2(), CBase2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputValCBase1(b1)', '1', binding, 'InputValCBase1(), Bottom1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputValCBase1(b2)', '1', binding, 'InputValCBase1(), Bottom2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputValCBase1(b3)', '1', binding, 'InputValCBase1(), Bottom3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputValCBase2(b3)', '2', binding, 'InputValCBase2(), Bottom3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputValCBase2(b1)', '2', binding, 'InputValCBase2(), Bottom1 as a parameter failed')
+
+# pointer parameters
+# test ABase1 as a parameter
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrABase1(d2)', '5', binding, 'InputPtrABase1() through Derived2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrABase1(d3)', '9', binding, 'InputPtrABase1() through Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrABase1(b2)', '205', binding, 'InputPtrABase1() through Bottom2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrABase1(b3)', '309', binding, 'InputPtrABase1() through Bottom3 as a parameter failed')
+
+# test CBase1 CBase2 as parameters
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrCBase1(d1)', '3', binding, 'InputPtrCBase1(), Derived1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrCBase1(d2)', '6', binding, 'InputPtrCBase1(), Derived2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrCBase1(d3)', '7', binding, 'InputPtrCBase1(), Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrCBase2(d3)', '8', binding, 'InputPtrCBase2(), Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrCBase2(d1)', '4', binding, 'InputPtrCBase2(), Derived1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrCBase1(cb1)', '1', binding, 'InputPtrCBase1(), CBase1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrCBase2(cb2)', '2', binding, 'InputPtrCBase2(), CBase2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrCBase1(b1)', '103', binding, 'InputPtrCBase1(), Bottom1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrCBase1(b2)', '206', binding, 'InputPtrCBase1(), Bottom2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrCBase1(b3)', '307', binding, 'InputPtrCBase1(), Bottom3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrCBase2(b3)', '308', binding, 'InputPtrCBase2(), Bottom3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrCBase2(b1)', '104', binding, 'InputPtrCBase2(), Bottom1 as a parameter failed')
+
+# reference parameters
+# test ABase1 as a parameter
+swig_assert_equal('Multiple_inheritance_abstract::InputRefABase1(d2)', '5', binding, 'InputRefABase1() through Derived2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefABase1(d3)', '9', binding, 'InputRefABase1() through Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefABase1(b2)', '205', binding, 'InputRefABase1() through Bottom2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefABase1(b3)', '309', binding, 'InputRefABase1() through Bottom3 as a parameter failed')
+
+# test CBase1 CBase2 as parameters
+swig_assert_equal('Multiple_inheritance_abstract::InputRefCBase1(d1)', '3', binding, 'InputRefCBase1(), Derived1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefCBase1(d2)', '6', binding, 'InputRefCBase1(), Derived2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefCBase1(d3)', '7', binding, 'InputRefCBase1(), Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefCBase2(d3)', '8', binding, 'InputRefCBase2(), Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefCBase2(d1)', '4', binding, 'InputRefCBase2(), Derived1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefCBase1(cb1)', '1', binding, 'InputRefCBase1(), CBase1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefCBase2(cb2)', '2', binding, 'InputRefCBase2(), CBase2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefCBase1(b1)', '103', binding, 'InputRefCBase1(), Bottom1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefCBase1(b2)', '206', binding, 'InputRefCBase1(), Bottom2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefCBase1(b3)', '307', binding, 'InputRefCBase1(), Bottom3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefCBase2(b3)', '308', binding, 'InputRefCBase2(), Bottom3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefCBase2(b1)', '104', binding, 'InputRefCBase2(), Bottom1 as a parameter failed')
+
+# const reference pointer parameters
+# test ABase1 as a parameter
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefABase1(d2)', '5', binding, 'InputCPtrRefABase1() through Derived2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefABase1(d3)', '9', binding, 'InputCPtrRefABase1() through Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefABase1(b2)', '205', binding, 'InputCPtrRefABase1() through Bottom2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefABase1(b3)', '309', binding, 'InputCPtrRefABase1() through Bottom3 as a parameter failed')
+
+# test CBase1 CBase2 as parameters
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefCBase1(d1)', '3', binding, 'InputCPtrRefCBase1(), Derived1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefCBase1(d2)', '6', binding, 'InputCPtrRefCBase1(), Derived2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefCBase1(d3)', '7', binding, 'InputCPtrRefCBase1(), Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefCBase2(d3)', '8', binding, 'InputCPtrRefCBase2(), Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefCBase2(d1)', '4', binding, 'InputCPtrRefCBase2(), Derived1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefCBase1(cb1)', '1', binding, 'InputCPtrRefCBase1(), CBase1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefCBase2(cb2)', '2', binding, 'InputCPtrRefCBase2(), CBase2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefCBase1(b1)', '103', binding, 'InputCPtrRefCBase1(), Bottom1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefCBase1(b2)', '206', binding, 'InputCPtrRefCBase1(), Bottom2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefCBase1(b3)', '307', binding, 'InputCPtrRefCBase1(), Bottom3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefCBase2(b3)', '308', binding, 'InputCPtrRefCBase2(), Bottom3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefCBase2(b1)', '104', binding, 'InputCPtrRefCBase2(), Bottom1 as a parameter failed')
+
+# derived classes as parameters
+swig_assert_equal('Multiple_inheritance_abstract::InputValDerived1(d1)', '3+4', binding, 'InputValDerived1() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputValDerived2(d2)', '6+5', binding, 'InputValDerived2() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputValDerived3(d3)', '7+8+9', binding, 'InputValDerived3() failed')
+
+swig_assert_equal('Multiple_inheritance_abstract::InputRefDerived1(d1)', '3+4', binding, 'InputRefDerived1() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefDerived2(d2)', '6+5', binding, 'InputRefDerived2() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefDerived3(d3)', '7+8+9', binding, 'InputRefDerived3() failed')
+
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrDerived1(d1)', '3+4', binding, 'InputPtrDerived1() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrDerived2(d2)', '6+5', binding, 'InputPtrDerived2() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrDerived3(d3)', '7+8+9', binding, 'InputPtrDerived3() failed')
+
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefDerived1(d1)', '3+4', binding, 'InputCPtrRefDerived1() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefDerived2(d2)', '6+5', binding, 'InputCPtrRefDerived2() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefDerived3(d3)', '7+8+9', binding, 'InputCPtrRefDerived3() failed')
+
+# bottom classes as Derived parameters
+swig_assert_equal('Multiple_inheritance_abstract::InputValDerived1(b1)', '3+4', binding, 'InputValDerived1() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputValDerived2(b2)', '6+5', binding, 'InputValDerived2() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputValDerived3(b3)', '7+8+9', binding, 'InputValDerived3() failed')
+
+swig_assert_equal('Multiple_inheritance_abstract::InputRefDerived1(b1)', '103+104', binding, 'InputRefDerived1() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefDerived2(b2)', '206+205', binding, 'InputRefDerived2() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefDerived3(b3)', '307+308+309', binding, 'InputRefDerived3() failed')
+
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrDerived1(b1)', '103+104', binding, 'InputPtrDerived1() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrDerived2(b2)', '206+205', binding, 'InputPtrDerived2() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrDerived3(b3)', '307+308+309', binding, 'InputPtrDerived3() failed')
+
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefDerived1(b1)', '103+104', binding, 'InputCPtrRefDerived1() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefDerived2(b2)', '206+205', binding, 'InputCPtrRefDerived2() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefDerived3(b3)', '307+308+309', binding, 'InputCPtrRefDerived3() failed')
+
+# bottom classes as Bottom parameters
+swig_assert_equal('Multiple_inheritance_abstract::InputValBottom1(b1)', '103+104', binding, 'InputValBottom1() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputValBottom2(b2)', '206+205', binding, 'InputValBottom2() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputValBottom3(b3)', '307+308+309', binding, 'InputValBottom3() failed')
+
+swig_assert_equal('Multiple_inheritance_abstract::InputRefBottom1(b1)', '103+104', binding, 'InputRefBottom1() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefBottom2(b2)', '206+205', binding, 'InputRefBottom2() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputRefBottom3(b3)', '307+308+309', binding, 'InputRefBottom3() failed')
+
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrBottom1(b1)', '103+104', binding, 'InputPtrBottom1() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrBottom2(b2)', '206+205', binding, 'InputPtrBottom2() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputPtrBottom3(b3)', '307+308+309', binding, 'InputPtrBottom3() failed')
+
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefBottom1(b1)', '103+104', binding, 'InputCPtrRefBottom1() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefBottom2(b2)', '206+205', binding, 'InputCPtrRefBottom2() failed')
+swig_assert_equal('Multiple_inheritance_abstract::InputCPtrRefBottom3(b3)', '307+308+309', binding, 'InputCPtrRefBottom3() failed')
+
+# return pointers
+swig_assert_equal('Multiple_inheritance_abstract::MakePtrDerived1_CBase1().cbase1y', '3', binding, 'MakePtrDerived1_CBase1 failed')
+swig_assert_equal('Multiple_inheritance_abstract::MakePtrDerived1_CBase2().cbase2', '4', binding, 'MakePtrDerived1_CBase2 failed')
+swig_assert_equal('Multiple_inheritance_abstract::MakePtrDerived2_CBase1().cbase1y', '6', binding, 'MakePtrDerived2_CBase1 failed')
+swig_assert_equal('Multiple_inheritance_abstract::MakePtrDerived2_ABase1().abase1', '5', binding, 'MakePtrDerived2_ABase1 failed')
+swig_assert_equal('Multiple_inheritance_abstract::MakePtrDerived3_ABase1().abase1', '9', binding, 'MakePtrDerived3_ABase1 failed')
+swig_assert_equal('Multiple_inheritance_abstract::MakePtrDerived3_CBase1().cbase1y', '7', binding, 'MakePtrDerived3_CBase1 failed')
+swig_assert_equal('Multiple_inheritance_abstract::MakePtrDerived3_CBase2().cbase2', '8', binding, 'MakePtrDerived3_CBase2 failed')
+
+# return references
+swig_assert_equal('Multiple_inheritance_abstract::MakeRefDerived1_CBase1().cbase1y', '3', binding, 'MakeRefDerived1_CBase1 failed')
+swig_assert_equal('Multiple_inheritance_abstract::MakeRefDerived1_CBase2().cbase2', '4', binding, 'MakeRefDerived1_CBase2 failed')
+swig_assert_equal('Multiple_inheritance_abstract::MakeRefDerived2_CBase1().cbase1y', '6', binding, 'MakeRefDerived2_CBase1 failed')
+swig_assert_equal('Multiple_inheritance_abstract::MakeRefDerived2_ABase1().abase1', '5', binding, 'MakeRefDerived2_ABase1 failed')
+swig_assert_equal('Multiple_inheritance_abstract::MakeRefDerived3_ABase1().abase1', '9', binding, 'MakeRefDerived3_ABase1 failed')
+swig_assert_equal('Multiple_inheritance_abstract::MakeRefDerived3_CBase1().cbase1y', '7', binding, 'MakeRefDerived3_CBase1 failed')
+swig_assert_equal('Multiple_inheritance_abstract::MakeRefDerived3_CBase2().cbase2', '8', binding, 'MakeRefDerived3_CBase2 failed')
+
+# return by value (sliced objects)
+swig_assert_equal('Multiple_inheritance_abstract::MakeValDerived1_CBase1().cbase1y', '1', binding, 'MakeValDerived1_CBase1 failed')
+swig_assert_equal('Multiple_inheritance_abstract::MakeValDerived1_CBase2().cbase2', '2', binding, 'MakeValDerived1_CBase2 failed')
+swig_assert_equal('Multiple_inheritance_abstract::MakeValDerived2_CBase1().cbase1y', '1', binding, 'MakeValDerived2_CBase1 failed')
+swig_assert_equal('Multiple_inheritance_abstract::MakeValDerived3_CBase1().cbase1y', '1', binding, 'MakeValDerived3_CBase1 failed')
+swig_assert_equal('Multiple_inheritance_abstract::MakeValDerived3_CBase2().cbase2', '2', binding, 'MakeValDerived3_CBase2 failed')
+
diff --git a/Examples/test-suite/ruby/multiple_inheritance_nspace_runme.rb b/Examples/test-suite/ruby/multiple_inheritance_nspace_runme.rb
new file mode 100644
index 0000000..fb28a0f
--- /dev/null
+++ b/Examples/test-suite/ruby/multiple_inheritance_nspace_runme.rb
@@ -0,0 +1,243 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is directly derived from its Java counterpart.
+#
+
+require 'swig_assert'
+require 'multiple_inheritance_nspace'
+
+# Test base class as a parameter in Ruby
+
+def jcbase1b(cb1)
+  cb1.cbase1y
+end
+
+def jabase1(ab1)
+  ab1.abase1
+end
+
+def jcbase2(cb2)
+  cb2.cbase2
+end
+
+# test Derived1
+d1 = Multiple_inheritance_nspace::Derived1.new
+swig_assert_equal('d1.cbase1y', '3', binding, 'Derived1::cbase1y() failed')
+swig_assert_equal('d1.cbase2', '4', binding, 'Derived1::cbase2() failed')
+
+# test Derived2
+d2 = Multiple_inheritance_nspace::Derived2.new
+swig_assert_equal('d2.cbase1y', '6', binding, 'Derived2::cbase1y() failed')
+swig_assert_equal('d2.abase1', '5', binding, 'Derived2::cbase1y() failed')
+
+# test Derived3
+d3 = Multiple_inheritance_nspace::Derived3.new
+swig_assert_equal('d3.cbase1y', '7', binding, 'Derived3::cbase1y() failed')
+swig_assert_equal('d3.cbase2', '8', binding, 'Derived3::cbase2() failed')
+swig_assert_equal('d3.abase1', '9', binding, 'Derived3::abase1() failed')
+
+# test Bottom1
+b1 = Multiple_inheritance_nspace::Bottom1.new
+swig_assert_equal('b1.cbase1y', '103', binding, 'Bottom1::cbase1y() failed')
+swig_assert_equal('b1.cbase2', '104', binding, 'Bottom1::cbase2() failed')
+
+# test Bottom2
+b2 = Multiple_inheritance_nspace::Bottom2.new
+swig_assert_equal('b2.cbase1y', '206', binding, 'Bottom2::cbase1y() failed')
+swig_assert_equal('b2.abase1', '205', binding, 'Bottom2::abase1() failed')
+
+# test Bottom3
+b3 = Multiple_inheritance_nspace::Bottom3.new
+swig_assert_equal('b3.cbase1y', '307', binding, 'Bottom3::cbase1y() failed')
+swig_assert_equal('b3.cbase2', '308', binding, 'Bottom3::cbase2() failed')
+swig_assert_equal('b3.abase1', '309', binding, 'Bottom3::abase1() failed')
+
+# test interfaces from C++ classes
+cb1 = Multiple_inheritance_nspace::CBase1.new
+cb2 = Multiple_inheritance_nspace::CBase2.new
+swig_assert_equal('cb1.cbase1y', '1', binding, 'CBase1::cbase1y() failed')
+swig_assert_equal('cb2.cbase2', '2', binding, 'CBase2::cbase2() failed')
+
+# test nspace class as return value
+ab1 = d3.cloneit
+swig_assert_equal('ab1.abase1', '9', binding, 'Derived3::abase1() through ABase1 failed')
+
+# test concrete base class as return value
+cb6 = d2.cloneit
+cb7 = d1.cloneit
+swig_assert_equal('cb6.cbase1y', '6', binding, 'Derived2::cbase1y() through CBase1 failed')
+swig_assert_equal('cb7.cbase2', '4', binding, 'Derived1:cbase2() through ABase1 failed')
+
+# test multi inheritance
+cb3 = Multiple_inheritance_nspace::Derived1.new
+cb4 = Multiple_inheritance_nspace::Derived3.new
+cb5 = Multiple_inheritance_nspace::Derived3.new
+ab6 = Multiple_inheritance_nspace::Derived2.new
+swig_assert_equal('cb3.cbase1y', '3', binding, 'Derived1::cbase1y() through CBase1 failed')
+swig_assert_equal('cb4.cbase1y', '7', binding, 'Derived3::cbase1y() through CBase1 failed')
+swig_assert_equal('cb5.cbase2', '8', binding, 'Derived3::cbase2() through CBase2 failed')
+swig_assert_equal('ab6.abase1', '5', binding, 'Derived2::abase1() through ABase1 failed')
+
+# test base classes as parameter in Ruby
+swig_assert_equal('jcbase1b(d1)', '3', binding, 'jcbase1b() through Derived1 as parameter failed')
+swig_assert_equal('jcbase1b(d2)', '6', binding, 'jcbase1b() through Derived2 as parameter failed')
+swig_assert_equal('jcbase1b(d3)', '7', binding, 'jcbase1b() through Derived3 as parameter failed')
+swig_assert_equal('jcbase2(d1)', '4', binding, 'jcbase2() through Derived1 as parameter failed')
+swig_assert_equal('jcbase2(d3)', '8', binding, 'jcbase2() through Derived3 as parameter failed')
+swig_assert_equal('jabase1(d2)', '5', binding, 'jabase1() through Derived2 as parameter failed')
+swig_assert_equal('jabase1(d3)', '9', binding, 'jabase1() through Derived3 as parameter failed')
+
+# value parameters
+# test CBase1 CBase2 as parameters (note slicing for Derived and Bottom classes)
+swig_assert_equal('Multiple_inheritance_nspace::InputValCBase1(d1)', '1', binding, 'InputValCBase1(), Derived1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputValCBase1(d2)', '1', binding, 'InputValCBase1(), Derived2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputValCBase1(d3)', '1', binding, 'InputValCBase1(), Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputValCBase2(d3)', '2', binding, 'InputValCBase2(), Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputValCBase2(d1)', '2', binding, 'InputValCBase2(), Derived1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputValCBase1(cb1)', '1', binding, 'InputValCBase1(), CBase1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputValCBase2(cb2)', '2', binding, 'InputValCBase2(), CBase2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputValCBase1(b1)', '1', binding, 'InputValCBase1(), Bottom1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputValCBase1(b2)', '1', binding, 'InputValCBase1(), Bottom2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputValCBase1(b3)', '1', binding, 'InputValCBase1(), Bottom3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputValCBase2(b3)', '2', binding, 'InputValCBase2(), Bottom3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputValCBase2(b1)', '2', binding, 'InputValCBase2(), Bottom1 as a parameter failed')
+
+# pointer parameters
+# test ABase1 as a parameter
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrABase1(d2)', '5', binding, 'InputPtrABase1() through Derived2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrABase1(d3)', '9', binding, 'InputPtrABase1() through Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrABase1(b2)', '205', binding, 'InputPtrABase1() through Bottom2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrABase1(b3)', '309', binding, 'InputPtrABase1() through Bottom3 as a parameter failed')
+
+# test CBase1 CBase2 as parameters
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrCBase1(d1)', '3', binding, 'InputPtrCBase1(), Derived1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrCBase1(d2)', '6', binding, 'InputPtrCBase1(), Derived2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrCBase1(d3)', '7', binding, 'InputPtrCBase1(), Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrCBase2(d3)', '8', binding, 'InputPtrCBase2(), Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrCBase2(d1)', '4', binding, 'InputPtrCBase2(), Derived1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrCBase1(cb1)', '1', binding, 'InputPtrCBase1(), CBase1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrCBase2(cb2)', '2', binding, 'InputPtrCBase2(), CBase2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrCBase1(b1)', '103', binding, 'InputPtrCBase1(), Bottom1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrCBase1(b2)', '206', binding, 'InputPtrCBase1(), Bottom2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrCBase1(b3)', '307', binding, 'InputPtrCBase1(), Bottom3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrCBase2(b3)', '308', binding, 'InputPtrCBase2(), Bottom3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrCBase2(b1)', '104', binding, 'InputPtrCBase2(), Bottom1 as a parameter failed')
+
+# reference parameters
+# test ABase1 as a parameter
+swig_assert_equal('Multiple_inheritance_nspace::InputRefABase1(d2)', '5', binding, 'InputRefABase1() through Derived2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefABase1(d3)', '9', binding, 'InputRefABase1() through Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefABase1(b2)', '205', binding, 'InputRefABase1() through Bottom2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefABase1(b3)', '309', binding, 'InputRefABase1() through Bottom3 as a parameter failed')
+
+# test CBase1 CBase2 as parameters
+swig_assert_equal('Multiple_inheritance_nspace::InputRefCBase1(d1)', '3', binding, 'InputRefCBase1(), Derived1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefCBase1(d2)', '6', binding, 'InputRefCBase1(), Derived2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefCBase1(d3)', '7', binding, 'InputRefCBase1(), Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefCBase2(d3)', '8', binding, 'InputRefCBase2(), Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefCBase2(d1)', '4', binding, 'InputRefCBase2(), Derived1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefCBase1(cb1)', '1', binding, 'InputRefCBase1(), CBase1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefCBase2(cb2)', '2', binding, 'InputRefCBase2(), CBase2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefCBase1(b1)', '103', binding, 'InputRefCBase1(), Bottom1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefCBase1(b2)', '206', binding, 'InputRefCBase1(), Bottom2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefCBase1(b3)', '307', binding, 'InputRefCBase1(), Bottom3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefCBase2(b3)', '308', binding, 'InputRefCBase2(), Bottom3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefCBase2(b1)', '104', binding, 'InputRefCBase2(), Bottom1 as a parameter failed')
+
+# const reference pointer parameters
+# test ABase1 as a parameter
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefABase1(d2)', '5', binding, 'InputCPtrRefABase1() through Derived2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefABase1(d3)', '9', binding, 'InputCPtrRefABase1() through Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefABase1(b2)', '205', binding, 'InputCPtrRefABase1() through Bottom2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefABase1(b3)', '309', binding, 'InputCPtrRefABase1() through Bottom3 as a parameter failed')
+
+# test CBase1 CBase2 as parameters
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefCBase1(d1)', '3', binding, 'InputCPtrRefCBase1(), Derived1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefCBase1(d2)', '6', binding, 'InputCPtrRefCBase1(), Derived2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefCBase1(d3)', '7', binding, 'InputCPtrRefCBase1(), Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefCBase2(d3)', '8', binding, 'InputCPtrRefCBase2(), Derived3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefCBase2(d1)', '4', binding, 'InputCPtrRefCBase2(), Derived1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefCBase1(cb1)', '1', binding, 'InputCPtrRefCBase1(), CBase1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefCBase2(cb2)', '2', binding, 'InputCPtrRefCBase2(), CBase2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefCBase1(b1)', '103', binding, 'InputCPtrRefCBase1(), Bottom1 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefCBase1(b2)', '206', binding, 'InputCPtrRefCBase1(), Bottom2 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefCBase1(b3)', '307', binding, 'InputCPtrRefCBase1(), Bottom3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefCBase2(b3)', '308', binding, 'InputCPtrRefCBase2(), Bottom3 as a parameter failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefCBase2(b1)', '104', binding, 'InputCPtrRefCBase2(), Bottom1 as a parameter failed')
+
+# derived classes as parameters
+swig_assert_equal('Multiple_inheritance_nspace::InputValDerived1(d1)', '3+4', binding, 'InputValDerived1() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputValDerived2(d2)', '6+5', binding, 'InputValDerived2() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputValDerived3(d3)', '7+8+9', binding, 'InputValDerived3() failed')
+
+swig_assert_equal('Multiple_inheritance_nspace::InputRefDerived1(d1)', '3+4', binding, 'InputRefDerived1() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefDerived2(d2)', '6+5', binding, 'InputRefDerived2() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefDerived3(d3)', '7+8+9', binding, 'InputRefDerived3() failed')
+
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrDerived1(d1)', '3+4', binding, 'InputPtrDerived1() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrDerived2(d2)', '6+5', binding, 'InputPtrDerived2() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrDerived3(d3)', '7+8+9', binding, 'InputPtrDerived3() failed')
+
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefDerived1(d1)', '3+4', binding, 'InputCPtrRefDerived1() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefDerived2(d2)', '6+5', binding, 'InputCPtrRefDerived2() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefDerived3(d3)', '7+8+9', binding, 'InputCPtrRefDerived3() failed')
+
+# bottom classes as Derived parameters
+swig_assert_equal('Multiple_inheritance_nspace::InputValDerived1(b1)', '3+4', binding, 'InputValDerived1() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputValDerived2(b2)', '6+5', binding, 'InputValDerived2() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputValDerived3(b3)', '7+8+9', binding, 'InputValDerived3() failed')
+
+swig_assert_equal('Multiple_inheritance_nspace::InputRefDerived1(b1)', '103+104', binding, 'InputRefDerived1() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefDerived2(b2)', '206+205', binding, 'InputRefDerived2() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefDerived3(b3)', '307+308+309', binding, 'InputRefDerived3() failed')
+
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrDerived1(b1)', '103+104', binding, 'InputPtrDerived1() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrDerived2(b2)', '206+205', binding, 'InputPtrDerived2() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrDerived3(b3)', '307+308+309', binding, 'InputPtrDerived3() failed')
+
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefDerived1(b1)', '103+104', binding, 'InputCPtrRefDerived1() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefDerived2(b2)', '206+205', binding, 'InputCPtrRefDerived2() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefDerived3(b3)', '307+308+309', binding, 'InputCPtrRefDerived3() failed')
+
+# bottom classes as Bottom parameters
+swig_assert_equal('Multiple_inheritance_nspace::InputValBottom1(b1)', '103+104', binding, 'InputValBottom1() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputValBottom2(b2)', '206+205', binding, 'InputValBottom2() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputValBottom3(b3)', '307+308+309', binding, 'InputValBottom3() failed')
+
+swig_assert_equal('Multiple_inheritance_nspace::InputRefBottom1(b1)', '103+104', binding, 'InputRefBottom1() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefBottom2(b2)', '206+205', binding, 'InputRefBottom2() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputRefBottom3(b3)', '307+308+309', binding, 'InputRefBottom3() failed')
+
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrBottom1(b1)', '103+104', binding, 'InputPtrBottom1() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrBottom2(b2)', '206+205', binding, 'InputPtrBottom2() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputPtrBottom3(b3)', '307+308+309', binding, 'InputPtrBottom3() failed')
+
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefBottom1(b1)', '103+104', binding, 'InputCPtrRefBottom1() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefBottom2(b2)', '206+205', binding, 'InputCPtrRefBottom2() failed')
+swig_assert_equal('Multiple_inheritance_nspace::InputCPtrRefBottom3(b3)', '307+308+309', binding, 'InputCPtrRefBottom3() failed')
+
+# return pointers
+swig_assert_equal('Multiple_inheritance_nspace::MakePtrDerived1_CBase1().cbase1y', '3', binding, 'MakePtrDerived1_CBase1 failed')
+swig_assert_equal('Multiple_inheritance_nspace::MakePtrDerived1_CBase2().cbase2', '4', binding, 'MakePtrDerived1_CBase2 failed')
+swig_assert_equal('Multiple_inheritance_nspace::MakePtrDerived2_CBase1().cbase1y', '6', binding, 'MakePtrDerived2_CBase1 failed')
+swig_assert_equal('Multiple_inheritance_nspace::MakePtrDerived2_ABase1().abase1', '5', binding, 'MakePtrDerived2_ABase1 failed')
+swig_assert_equal('Multiple_inheritance_nspace::MakePtrDerived3_ABase1().abase1', '9', binding, 'MakePtrDerived3_ABase1 failed')
+swig_assert_equal('Multiple_inheritance_nspace::MakePtrDerived3_CBase1().cbase1y', '7', binding, 'MakePtrDerived3_CBase1 failed')
+swig_assert_equal('Multiple_inheritance_nspace::MakePtrDerived3_CBase2().cbase2', '8', binding, 'MakePtrDerived3_CBase2 failed')
+
+# return references
+swig_assert_equal('Multiple_inheritance_nspace::MakeRefDerived1_CBase1().cbase1y', '3', binding, 'MakeRefDerived1_CBase1 failed')
+swig_assert_equal('Multiple_inheritance_nspace::MakeRefDerived1_CBase2().cbase2', '4', binding, 'MakeRefDerived1_CBase2 failed')
+swig_assert_equal('Multiple_inheritance_nspace::MakeRefDerived2_CBase1().cbase1y', '6', binding, 'MakeRefDerived2_CBase1 failed')
+swig_assert_equal('Multiple_inheritance_nspace::MakeRefDerived2_ABase1().abase1', '5', binding, 'MakeRefDerived2_ABase1 failed')
+swig_assert_equal('Multiple_inheritance_nspace::MakeRefDerived3_ABase1().abase1', '9', binding, 'MakeRefDerived3_ABase1 failed')
+swig_assert_equal('Multiple_inheritance_nspace::MakeRefDerived3_CBase1().cbase1y', '7', binding, 'MakeRefDerived3_CBase1 failed')
+swig_assert_equal('Multiple_inheritance_nspace::MakeRefDerived3_CBase2().cbase2', '8', binding, 'MakeRefDerived3_CBase2 failed')
+
+# return by value (sliced objects)
+swig_assert_equal('Multiple_inheritance_nspace::MakeValDerived1_CBase1().cbase1y', '1', binding, 'MakeValDerived1_CBase1 failed')
+swig_assert_equal('Multiple_inheritance_nspace::MakeValDerived1_CBase2().cbase2', '2', binding, 'MakeValDerived1_CBase2 failed')
+swig_assert_equal('Multiple_inheritance_nspace::MakeValDerived2_CBase1().cbase1y', '1', binding, 'MakeValDerived2_CBase1 failed')
+swig_assert_equal('Multiple_inheritance_nspace::MakeValDerived3_CBase1().cbase1y', '1', binding, 'MakeValDerived3_CBase1 failed')
+swig_assert_equal('Multiple_inheritance_nspace::MakeValDerived3_CBase2().cbase2', '2', binding, 'MakeValDerived3_CBase2 failed')
+
diff --git a/Examples/test-suite/ruby/namespace_chase_runme.rb b/Examples/test-suite/ruby/namespace_chase_runme.rb
new file mode 100644
index 0000000..c5f227d
--- /dev/null
+++ b/Examples/test-suite/ruby/namespace_chase_runme.rb
@@ -0,0 +1,14 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is directly derived from its Java counterpart.
+#
+
+require 'swig_assert'
+require 'namespace_chase'
+
+s1a = Namespace_chase::Struct1A.new
+s1b = Namespace_chase::Struct1B.new
+s1c = Namespace_chase::Struct1C.new
+
+Namespace_chase.sss3a(s1a, s1b, s1c)
+Namespace_chase.sss3b(s1a, s1b, s1c)
diff --git a/Examples/test-suite/ruby/namespace_class_runme.rb b/Examples/test-suite/ruby/namespace_class_runme.rb
new file mode 100644
index 0000000..fd93458
--- /dev/null
+++ b/Examples/test-suite/ruby/namespace_class_runme.rb
@@ -0,0 +1,40 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is directly derived from its Python counterpart.
+#
+
+require 'swig_assert'
+require 'namespace_class'
+
+begin
+  p = Namespace_class::Private1.new
+  raise SwigRubyError.new("Private1 is private")
+rescue NameError => e
+  # OK
+end
+
+begin
+  p = Namespace_class::Private2.new
+  raise SwigRubyError.new("Private2 is private")
+rescue NameError => e
+  # OK
+end
+
+Namespace_class::EulerT3D.toFrame(1, 1, 1)
+
+b = Namespace_class::BooT_i.new
+b = Namespace_class::BooT_H.new
+
+
+f = Namespace_class::FooT_i.new
+f.quack(1)
+
+f = Namespace_class::FooT_d.new
+f.moo(1)
+
+f = Namespace_class::FooT_H.new
+f.foo(Namespace_class::Hi)
+
+f_type = f.class.to_s
+swig_assert_equal('f_type', '"Namespace_class::FooT_H"', binding)
+
diff --git a/Examples/test-suite/ruby/namespace_forward_declaration_runme.rb b/Examples/test-suite/ruby/namespace_forward_declaration_runme.rb
new file mode 100644
index 0000000..0e6b50e
--- /dev/null
+++ b/Examples/test-suite/ruby/namespace_forward_declaration_runme.rb
@@ -0,0 +1,16 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is directly derived from its Java counterpart.
+#
+
+require 'swig_assert'
+require 'namespace_forward_declaration'
+
+xxx = Namespace_forward_declaration::XXX.new
+Namespace_forward_declaration.testXXX1(xxx)
+Namespace_forward_declaration.testXXX2(xxx)
+Namespace_forward_declaration.testXXX3(xxx)
+yyy = Namespace_forward_declaration::YYY.new
+Namespace_forward_declaration.testYYY1(yyy)
+Namespace_forward_declaration.testYYY2(yyy)
+Namespace_forward_declaration.testYYY3(yyy)
diff --git a/Examples/test-suite/ruby/namespace_virtual_method_runme.rb b/Examples/test-suite/ruby/namespace_virtual_method_runme.rb
new file mode 100644
index 0000000..54e4a7a
--- /dev/null
+++ b/Examples/test-suite/ruby/namespace_virtual_method_runme.rb
@@ -0,0 +1,8 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is directly derived from its Python counterpart.
+#
+
+require 'namespace_virtual_method'
+
+x = Namespace_virtual_method::Spam.new
diff --git a/Examples/test-suite/ruby/nested_class_runme.rb b/Examples/test-suite/ruby/nested_class_runme.rb
new file mode 100644
index 0000000..2cf3bf9
--- /dev/null
+++ b/Examples/test-suite/ruby/nested_class_runme.rb
@@ -0,0 +1,54 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is directly derived from its Java counterpart.
+#
+
+require 'swig_assert'
+require 'nested_class'
+
+outer = Nested_class::Outer.new
+is1 = outer.makeInnerStruct1
+ic1 = outer.makeInnerClass1
+iu1 = outer.makeInnerUnion1
+
+is2 = outer.makeInnerStruct2
+ic2 = outer.makeInnerClass2
+iu2 = outer.makeInnerUnion2
+
+ic4 = outer.makeInnerClass4Typedef
+is4 = outer.makeInnerStruct4Typedef
+iu4 = outer.makeInnerUnion4Typedef
+
+ic5 = outer.makeInnerClass5
+is5 = outer.makeInnerStruct5
+iu5 = outer.makeInnerUnion5
+
+ic5 = outer.makeInnerClass5Typedef
+is5 = outer.makeInnerStruct5Typedef
+iu5 = outer.makeInnerUnion5Typedef
+
+im1 = outer.MultipleInstance1
+im2 = outer.MultipleInstance2
+im3 = outer.MultipleInstance3
+im4 = outer.MultipleInstance4
+
+im1 = outer.MultipleDerivedInstance1
+im2 = outer.MultipleDerivedInstance2
+im3 = outer.MultipleDerivedInstance3
+im4 = outer.MultipleDerivedInstance4
+
+im1 = outer.MultipleDerivedInstance1
+im2 = outer.MultipleDerivedInstance2
+im3 = outer.MultipleDerivedInstance3
+im4 = outer.MultipleDerivedInstance4
+
+mat1 = outer.makeInnerMultipleAnonTypedef1
+mat2 = outer.makeInnerMultipleAnonTypedef2
+mat3 = outer.makeInnerMultipleAnonTypedef3
+
+mnt = outer.makeInnerMultipleNamedTypedef
+mnt1 = outer.makeInnerMultipleNamedTypedef1
+mnt2 = outer.makeInnerMultipleNamedTypedef2
+mnt3 = outer.makeInnerMultipleNamedTypedef3
+
+isn = outer.makeInnerSameName
diff --git a/Examples/test-suite/ruby/nested_directors_runme.rb b/Examples/test-suite/ruby/nested_directors_runme.rb
new file mode 100644
index 0000000..b2020b3
--- /dev/null
+++ b/Examples/test-suite/ruby/nested_directors_runme.rb
@@ -0,0 +1,29 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is directly derived from its C# counterpart.
+#
+
+require 'swig_assert'
+require 'nested_directors'
+
+# nested classes not yet supported
+#class CNested < Nested_directors::Base::Nest
+#  def GetValue
+#    true
+#  end
+#end
+
+class CSub < Nested_directors::Sub
+  def GetValue
+    super
+  end
+  def Test
+    GetValue()
+  end
+end
+
+#n = CNested.new
+#swig_assert('n.GetValue()', binding)
+
+s = CSub.new
+swig_assert('s.Test()', binding)
diff --git a/Examples/test-suite/ruby/nested_in_template_runme.rb b/Examples/test-suite/ruby/nested_in_template_runme.rb
new file mode 100644
index 0000000..4d3b721
--- /dev/null
+++ b/Examples/test-suite/ruby/nested_in_template_runme.rb
@@ -0,0 +1,11 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is directly derived from its Python counterpart.
+#
+
+require 'swig_assert'
+require 'nested_in_template'
+
+
+cd = Nested_in_template::ConcreteDerived.new(88)
+swig_assert_equal('cd.m_value', '88', binding, 'ConcreteDerived not created correctly')
diff --git a/Examples/test-suite/ruby/nested_scope_flat_runme.rb b/Examples/test-suite/ruby/nested_scope_flat_runme.rb
new file mode 100644
index 0000000..bd7ee7c
--- /dev/null
+++ b/Examples/test-suite/ruby/nested_scope_flat_runme.rb
@@ -0,0 +1,25 @@
+#!/usr/bin/env ruby
+#
+# Check the availability of expected classes and their member variables.
+#
+
+require 'swig_assert'
+require 'nested_scope_flat'
+
+Nested_scope_flat::Global_.new
+Nested_scope_flat::Outer1.new
+nested2 = Nested_scope_flat::Nested2.new
+nested2.data = 42
+swig_assert_equal("nested2.data", "42", binding)
+Nested_scope_flat::Klass.new
+
+Nested_scope_flat::Abstract_int
+cannot_instantiate = false
+begin
+  Nested_scope_flat::Abstract_int.new
+rescue TypeError
+  cannot_instantiate = true
+end
+swig_assert_simple(cannot_instantiate)
+
+Nested_scope_flat::Real.new.Method()
diff --git a/Examples/test-suite/ruby/nested_template_base_runme.rb b/Examples/test-suite/ruby/nested_template_base_runme.rb
new file mode 100644
index 0000000..a4f2933
--- /dev/null
+++ b/Examples/test-suite/ruby/nested_template_base_runme.rb
@@ -0,0 +1,16 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is directly derived from its Python counterpart.
+#
+
+require 'swig_assert'
+require 'nested_template_base'
+
+ois = Nested_template_base::InnerS.new(123)
+oic = Nested_template_base::InnerC.new
+
+# Check base method is available
+swig_assert_equal('oic.outer(ois).val', '123', binding, 'Wrong value calling outer')
+
+# Check non-derived class using base class
+swig_assert_equal('oic.innerc().outer(ois).val', '123', binding, 'Wrong value calling innerc')
diff --git a/Examples/test-suite/ruby/nested_workaround_runme.rb b/Examples/test-suite/ruby/nested_workaround_runme.rb
new file mode 100644
index 0000000..645bdd3
--- /dev/null
+++ b/Examples/test-suite/ruby/nested_workaround_runme.rb
@@ -0,0 +1,21 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is derived from its Java counterpart.
+#
+
+require 'swig_assert'
+require 'nested_workaround'
+
+begin
+  inner = Nested_workaround::Inner.new(5)
+  outer = Nested_workaround::Outer.new
+  newInner = outer.doubleInnerValue(inner)
+  swig_assert_equal("newInner.getValue", "10", binding)
+end
+
+begin
+  outer = Nested_workaround::Outer.new
+  inner = outer.createInner(3)
+  newInner = outer.doubleInnerValue(inner)
+  swig_assert_equal("outer.getInnerValue(newInner)", "6", binding)
+end
diff --git a/Examples/test-suite/ruby/newobject2_runme.rb b/Examples/test-suite/ruby/newobject2_runme.rb
index 04129f4..b7ebea0 100644
--- a/Examples/test-suite/ruby/newobject2_runme.rb
+++ b/Examples/test-suite/ruby/newobject2_runme.rb
@@ -18,10 +18,12 @@
 include Newobject2
 
 GC.track_class = Foo
+GC.disable
 GC.stats if $VERBOSE
 100.times { foo1 = makeFoo }
 GC.stats if $VERBOSE
 swig_assert( 'fooCount == 100', nil, "but is #{fooCount}" )
+GC.enable
 GC.start
 swig_assert( 'fooCount <= 1', nil, "but is #{fooCount}" )
 
diff --git a/Examples/test-suite/ruby/numeric_bounds_checking_runme.rb b/Examples/test-suite/ruby/numeric_bounds_checking_runme.rb
new file mode 100644
index 0000000..1db51be
--- /dev/null
+++ b/Examples/test-suite/ruby/numeric_bounds_checking_runme.rb
@@ -0,0 +1,42 @@
+#!/usr/bin/env ruby
+#
+# Tests the bounds checking for integral parameters passed to wrapped functions.
+#
+
+require 'swig_assert'
+require 'numeric_bounds_checking'
+
+limits = Numeric_bounds_checking::Limits.new
+checker = Numeric_bounds_checking::Checker.new
+
+all_ok = true
+
+types = %w(schar uchar
+           shrt  ushrt
+           int   uint
+           long  ulong)
+types += %w(llong ullong) if limits.respond_to?(:llong_min)
+
+types.each do |t|
+  min = limits.send("#{t}_min")
+  max = limits.send("#{t}_max")
+
+  meth = "pass_#{t}"
+
+  # check within bounds
+  swig_assert_equal("checker.#{meth}(#{min})", "#{min}", binding)
+  swig_assert_equal("checker.#{meth}(#{max})", "#{max}", binding)
+
+  # check outside bounds
+  [ min - 1, max + 1 ].each do |val|
+    ok = false
+    begin
+      ret = checker.send("#{meth}", val)
+    rescue RangeError, TypeError
+      ok = true
+    end
+    $stderr.puts "\n#{meth}(#{val}): Expected exception but got #{ret} for #{val} (type '#{t}')  " unless ok
+    all_ok = all_ok && ok
+  end
+  raise SwigRubyError.new("\nAt least one bounds check failed  ") unless all_ok
+end
diff --git a/Examples/test-suite/ruby/overload_null_runme.rb b/Examples/test-suite/ruby/overload_null_runme.rb
index eabea5e..e84851a 100644
--- a/Examples/test-suite/ruby/overload_null_runme.rb
+++ b/Examples/test-suite/ruby/overload_null_runme.rb
@@ -40,13 +40,13 @@
 swig_assert(15 == o.byval2cpr(nil))
 swig_assert(16 == o.byval2cpr(x))
 
-# forward class declaration
-swig_assert(17 == o.byval1forwardptr(x))
-swig_assert(18 == o.byval1forwardptr(nil))
+# fwd class declaration
+swig_assert(17 == o.byval1fwdptr(x))
+swig_assert(18 == o.byval1fwdptr(nil))
 
-swig_assert(19 == o.byval2forwardptr(nil))
-swig_assert(20 == o.byval2forwardptr(x))
+swig_assert(19 == o.byval2fwdptr(nil))
+swig_assert(20 == o.byval2fwdptr(x))
 
-swig_assert(21 == o.byval1forwardref(x))
+swig_assert(21 == o.byval1fwdref(x))
 
-swig_assert(22 == o.byval2forwardref(x))
+swig_assert(22 == o.byval2fwdref(x))
diff --git a/Examples/test-suite/ruby/preproc_runme.rb b/Examples/test-suite/ruby/preproc_runme.rb
new file mode 100644
index 0000000..4b4a915
--- /dev/null
+++ b/Examples/test-suite/ruby/preproc_runme.rb
@@ -0,0 +1,40 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is directly derived from its Python counterpart.
+#
+
+require 'swig_assert'
+
+# This extension to the Warning class is intended for suppressing expected
+# Ruby warning messages about invalid or redefined Ruby constants - basically
+# the equivalent of %warnfilter(SWIGWARN_RUBY_WRONG_NAME) but for the moment
+# the wrapper library is loaded by the Ruby interpreter.
+# Note: This only works for Ruby 2.4 and later
+if Object.const_defined?(:Warning) && Warning.respond_to?(:warn)
+  module CustomWarningFilter
+    def warn(*args)
+      msg = args[0]
+      if msg =~ /[Aa]lready initialized constant Preproc::A[56]/ ||
+         msg =~ /invalid name .?__GMP_HAVE_/
+        # ignore
+      else
+        super
+      end
+    end
+  end
+  Warning.extend CustomWarningFilter
+end
+
+require 'preproc'
+
+swig_assert_equal('Preproc::endif', '1', binding)
+swig_assert_equal('Preproc::define', '1', binding)
+swig_assert_equal('Preproc::ddefined', '1', binding)
+
+swig_assert_equal('2 * Preproc::One', 'Preproc::Two', binding)
+
+swig_assert_equal('Preproc::methodX(99)', '199', binding)
+
+t1 = Preproc::TcxMessageTest
+t2 = Preproc::TcxMessageBug
+
diff --git a/Examples/test-suite/ruby/ruby_global_immutable_vars_cpp_runme.rb b/Examples/test-suite/ruby/ruby_global_immutable_vars_cpp_runme.rb
new file mode 100644
index 0000000..5523b59
--- /dev/null
+++ b/Examples/test-suite/ruby/ruby_global_immutable_vars_cpp_runme.rb
@@ -0,0 +1,48 @@
+#!/usr/bin/env ruby
+#
+# C++ version of ruby_global_immutable_vars_runme.rb.
+#
+
+require 'swig_assert'
+
+require 'ruby_global_immutable_vars_cpp'
+
+# first check if all variables can be read
+swig_assert_each_line( <<EOF )
+$default_mutable_var == 40
+$global_immutable_var == 41
+$specific_mutable_var == 42
+$global_mutable_var == 43
+$specific_immutable_var == 44
+EOF
+
+# check that all mutable variables can be modified
+swig_assert_each_line( <<EOF )
+$default_mutable_var = 80
+$default_mutable_var == 80
+$specific_mutable_var = 82
+$specific_mutable_var == 82
+$global_mutable_var = 83
+$global_mutable_var == 83
+EOF
+
+# now check that immutable variables cannot be modified
+had_exception = false
+begin
+  $global_immutable_var = 81
+rescue NameError => e
+  had_exception = true
+end
+swig_assert(had_exception, nil,
+            "$global_immutable_var is writable (expected to be immutable)")
+
+had_exception = false
+begin
+  $specific_immutable_var = 81
+rescue NameError => e
+  had_exception = true
+end
+swig_assert(had_exception, nil,
+            "$specific_immutable_var is writable (expected to be immutable)")
+
+swig_assert(check_values(80, 41, 82, 83, 44) == 1, nil, "Check values failed")
diff --git a/Examples/test-suite/ruby/ruby_global_immutable_vars_runme.rb b/Examples/test-suite/ruby/ruby_global_immutable_vars_runme.rb
new file mode 100644
index 0000000..45a8506
--- /dev/null
+++ b/Examples/test-suite/ruby/ruby_global_immutable_vars_runme.rb
@@ -0,0 +1,52 @@
+#!/usr/bin/env ruby
+#
+# This test program is similar to global_immutable_vars_runme.rb
+# with the difference that the global variables to check are also
+# Ruby global variables (SWIG Ruby option "-globalmodule").
+#
+# Immutable global variables shall throw a NameError exception.
+#
+
+require 'swig_assert'
+
+require 'ruby_global_immutable_vars'
+
+# first check if all variables can be read
+swig_assert_each_line( <<EOF )
+$default_mutable_var == 40
+$global_immutable_var == 41
+$specific_mutable_var == 42
+$global_mutable_var == 43
+$specific_immutable_var == 44
+EOF
+
+# check that all mutable variables can be modified
+swig_assert_each_line( <<EOF )
+$default_mutable_var = 80
+$default_mutable_var == 80
+$specific_mutable_var = 82
+$specific_mutable_var == 82
+$global_mutable_var = 83
+$global_mutable_var == 83
+EOF
+
+# now check that immutable variables cannot be modified
+had_exception = false
+begin
+  $global_immutable_var = 81
+rescue NameError => e
+  had_exception = true
+end
+swig_assert(had_exception, nil,
+            "$global_immutable_var is writable (expected to be immutable)")
+
+had_exception = false
+begin
+  $specific_immutable_var = 81
+rescue NameError => e
+  had_exception = true
+end
+swig_assert(had_exception, nil,
+            "$specific_immutable_var is writable (expected to be immutable)")
+
+swig_assert(check_values(80, 41, 82, 83, 44) == 1, nil, "Check values failed")
diff --git a/Examples/test-suite/ruby/ruby_naming_bugs_runme.rb b/Examples/test-suite/ruby/ruby_naming_bugs_runme.rb
new file mode 100644
index 0000000..4931135
--- /dev/null
+++ b/Examples/test-suite/ruby/ruby_naming_bugs_runme.rb
@@ -0,0 +1,16 @@
+#!/usr/bin/env ruby
+#
+# Regression tests for Ruby naming bugs
+#
+
+require 'swig_assert'
+
+require 'ruby_naming_bugs'
+
+# Prior to SWIG 4.1.0 the "Cool_" here was overzealously removed
+# while trying to remove a class name prefix, so this method would be
+# named "somethingFast" in Ruby instead.
+c = Ruby_naming_bugs::Cool.new()
+if c.somethingCool_Fast != 42
+  raise RuntimeError, "Incorrect value for somethingCool_Fast"
+end
diff --git a/Examples/test-suite/ruby/template_nested_flat_runme.rb b/Examples/test-suite/ruby/template_nested_flat_runme.rb
new file mode 100644
index 0000000..5d0907f
--- /dev/null
+++ b/Examples/test-suite/ruby/template_nested_flat_runme.rb
@@ -0,0 +1,23 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is directly derived from its Java counterpart.
+#
+
+require 'swig_assert'
+require 'template_nested_flat'
+
+Template_nested_flat::T_NormalTemplateNormalClass.new.tmethod(Template_nested_flat::NormalClass.new)
+Template_nested_flat::OuterClass.new.T_OuterTMethodNormalClass(Template_nested_flat::NormalClass.new)
+
+tf = Template_nested_flat::TemplateFuncs.new
+swig_assert_equal("tf.T_TemplateFuncs1Int(-10)", "-10", binding)
+swig_assert_equal("tf.T_TemplateFuncs2Double(-12.3)", "-12.3", binding)
+
+tn = Template_nested_flat::T_NestedOuterTemplateDouble.new
+swig_assert_equal("tn.hohum(-12.3)", "-12.3", binding)
+
+inner1 = Template_nested_flat::OuterClass.new.useInner1(Template_nested_flat::T_OuterClassInner1Int.new)
+inner2 = Template_nested_flat::T_OuterClassInner2NormalClass.new
+inner2.embeddedVar = 2
+inner22 = Template_nested_flat::OuterClass.new.useInner2Again(inner2)
+inner3 = Template_nested_flat::T_OuterClassInner1Double.new
diff --git a/Examples/test-suite/ruby/template_static_runme.rb b/Examples/test-suite/ruby/template_static_runme.rb
new file mode 100644
index 0000000..83c40e1
--- /dev/null
+++ b/Examples/test-suite/ruby/template_static_runme.rb
@@ -0,0 +1,12 @@
+#!/usr/bin/env ruby
+#
+# This test implementation is directly derived from its Python counterpart.
+#
+
+require 'template_static'
+
+Template_static::Foo_i.test
+Template_static::Foo_d.test
+Template_static::Foo::test
+Template_static::Foo::bar_double(1)
+
diff --git a/Examples/test-suite/ruby/typedef_inherit_runme.rb b/Examples/test-suite/ruby/typedef_inherit_runme.rb
index 029b80c..10f155b 100644
--- a/Examples/test-suite/ruby/typedef_inherit_runme.rb
+++ b/Examples/test-suite/ruby/typedef_inherit_runme.rb
@@ -36,3 +36,9 @@
 if x != "Grok::blah"
   puts "Whoa! Bad return #{x}"
 end
+
+x = d.far
+if x != "Spam::far"
+  puts "Whoa! Bad return #{x}"
+end
+
diff --git a/Examples/test-suite/ruby_global_immutable_vars.i b/Examples/test-suite/ruby_global_immutable_vars.i
new file mode 100644
index 0000000..6f067d2
--- /dev/null
+++ b/Examples/test-suite/ruby_global_immutable_vars.i
@@ -0,0 +1,34 @@
+%module ruby_global_immutable_vars
+
+// This copy of global_immutable_vars.i shall be compiled with the
+// SWIG Ruby option "-globalmodule" in order to check the code path
+// for registering global methods (in contrast to module methods).
+
+%inline %{
+  int default_mutable_var = 40;
+%}
+
+%immutable;
+%feature("immutable", "0") specific_mutable_var;
+
+%inline %{
+  int global_immutable_var = 41;
+  int specific_mutable_var = 42;
+%}
+
+%mutable;
+%immutable specific_immutable_var;
+%inline %{
+  int global_mutable_var = 43;
+  int specific_immutable_var = 44;
+
+  int check_values(int default_mutable, int global_immutable, int specific_mutable, int global_mutable, int specific_immutable) {
+    return
+      default_mutable    == default_mutable_var &&
+      global_immutable   == global_immutable_var &&
+      specific_mutable   == specific_mutable_var &&
+      global_mutable     == global_mutable_var &&
+      specific_immutable == specific_immutable_var;
+  }
+%}
+
diff --git a/Examples/test-suite/ruby_global_immutable_vars_cpp.i b/Examples/test-suite/ruby_global_immutable_vars_cpp.i
new file mode 100644
index 0000000..511390e
--- /dev/null
+++ b/Examples/test-suite/ruby_global_immutable_vars_cpp.i
@@ -0,0 +1,32 @@
+%module ruby_global_immutable_vars_cpp
+
+// C++ version of ruby_global_immutable_vars.i
+
+%inline %{
+  int default_mutable_var = 40;
+%}
+
+%immutable;
+%feature("immutable", "0") specific_mutable_var;
+
+%inline %{
+  int global_immutable_var = 41;
+  int specific_mutable_var = 42;
+%}
+
+%mutable;
+%immutable specific_immutable_var;
+%inline %{
+  int global_mutable_var = 43;
+  int specific_immutable_var = 44;
+
+  int check_values(int default_mutable, int global_immutable, int specific_mutable, int global_mutable, int specific_immutable) {
+    return
+      default_mutable    == default_mutable_var &&
+      global_immutable   == global_immutable_var &&
+      specific_mutable   == specific_mutable_var &&
+      global_mutable     == global_mutable_var &&
+      specific_immutable == specific_immutable_var;
+  }
+%}
+
diff --git a/Examples/test-suite/ruby_manual_proxy.i b/Examples/test-suite/ruby_manual_proxy.i
index 2cb154e..7cfbfb1 100644
--- a/Examples/test-suite/ruby_manual_proxy.i
+++ b/Examples/test-suite/ruby_manual_proxy.i
@@ -1,7 +1,7 @@
 %module ruby_manual_proxy
 
 
-%typemap(in, numinputs=0) SWIGTYPE ** ($*1_ltype temp) "$1 = &temp;";
+%typemap(in, numinputs=0) SWIGTYPE ** ($*1_ltype temp) "$1 = &temp;"
 
 %typemap(argout) SWIGTYPE **OUTPARAM {
   $result = SWIG_Ruby_AppendOutput($result, SWIG_NewPointerObj(*$1, $*1_descriptor, 0));
diff --git a/Examples/test-suite/ruby_naming_bugs.i b/Examples/test-suite/ruby_naming_bugs.i
new file mode 100644
index 0000000..6449add
--- /dev/null
+++ b/Examples/test-suite/ruby_naming_bugs.i
@@ -0,0 +1,9 @@
+%module ruby_naming_bugs
+
+%inline %{
+  // Prior to SWIG 4.1.0 the "Cool_" here was overzealously removed while
+  // trying to remove a class name prefix.
+  struct Cool {
+    int somethingCool_Fast() { return 42; }
+  };
+%}
diff --git a/Examples/test-suite/schemerunme/argcargvtest.scm b/Examples/test-suite/schemerunme/argcargvtest.scm
new file mode 100644
index 0000000..bf7d90b
--- /dev/null
+++ b/Examples/test-suite/schemerunme/argcargvtest.scm
@@ -0,0 +1,38 @@
+(define largs #("hi" "hola" "hello"))
+(when (not (= (mainc largs) 3))
+    (error "calling mainc failed"))
+
+(define targs #("hi" "hola"))
+(when (not (string=? (mainv targs 0) "hi"))
+    (error "calling mainv failed"))
+(when (not (string=? (mainv targs 1) "hola"))
+    (error "calling mainv failed"))
+(when (not (string=? (mainv targs 2) "<<NULL>>"))
+    (error "calling mainv failed"))
+
+(expect-throw 'swig-contract-assertion-failed
+    (mainv "hello"  1))
+
+(initializeApp largs)
+
+; Check that an empty array works.
+(define empty_args #())
+(when (not (= (mainc empty_args) 0))
+    (error "calling mainc failed"))
+(when (not (string=? (mainv empty_args 0) "<<NULL>>"))
+    (error "calling mainv failed"))
+
+; Check that empty strings are handled.
+(define empty_string #("hello" "" "world"))
+(when (not (= (mainc empty_string) 3))
+    (error "calling mainc failed"))
+(when (not (string=? (mainv empty_string 0) "hello"))
+    (error "calling mainv 0 failed"))
+(when (not (string=? (mainv empty_string 1) ""))
+    (error "calling mainv 1 failed"))
+(when (not (string=? (mainv empty_string 2) "world"))
+    (error "calling mainv 2 failed"))
+(when (not (string=? (mainv empty_string 3) "<<NULL>>"))
+    (error "calling mainv 3 failed"))
+
+(exit 0)
diff --git a/Examples/test-suite/schemerunme/catches_strings.scm b/Examples/test-suite/schemerunme/catches_strings.scm
new file mode 100644
index 0000000..8a83db0
--- /dev/null
+++ b/Examples/test-suite/schemerunme/catches_strings.scm
@@ -0,0 +1,9 @@
+(expect-throw 'swig-exception
+              (StringsThrower-charstring))
+; TODO: check the exception message
+
+(expect-throw 'swig-exception
+              (StringsThrower-stdstring))
+; TODO: check the exception message
+
+(exit 0)
diff --git a/Examples/test-suite/schemerunme/cpp11_move_typemaps.scm b/Examples/test-suite/schemerunme/cpp11_move_typemaps.scm
new file mode 100644
index 0000000..0a8b85a
--- /dev/null
+++ b/Examples/test-suite/schemerunme/cpp11_move_typemaps.scm
@@ -0,0 +1,23 @@
+(Counter-reset-counts)
+(define mo (new-MoveOnly 111))
+(Counter-check-counts 1 0 0 0 0 0)
+(MoveOnly-take mo)
+(Counter-check-counts 1 0 0 1 0 2)
+(delete-MoveOnly mo)
+(Counter-check-counts 1 0 0 1 0 2)
+
+(Counter-reset-counts)
+(define mo (new-MovableCopyable 111))
+(Counter-check-counts 1 0 0 0 0 0)
+(MovableCopyable-take mo)
+(Counter-check-counts 1 0 0 1 0 2)
+(delete-MovableCopyable mo)
+(Counter-check-counts 1 0 0 1 0 2)
+
+(define mo (new-MoveOnly 222))
+(MoveOnly-take mo)
+(expect-throw 'misc-error
+              (MoveOnly-take mo))
+; TODO: check the exception message
+
+(exit 0)
diff --git a/Examples/test-suite/schemerunme/cpp11_rvalue_reference_move.scm b/Examples/test-suite/schemerunme/cpp11_rvalue_reference_move.scm
new file mode 100644
index 0000000..1cbb611
--- /dev/null
+++ b/Examples/test-suite/schemerunme/cpp11_rvalue_reference_move.scm
@@ -0,0 +1,57 @@
+; Function containing rvalue reference parameter
+(Counter-reset-counts)
+(define mo (new-MovableCopyable 222))
+(Counter-check-counts 1 0 0 0 0 0)
+(MovableCopyable-movein mo)
+(Counter-check-counts 1 0 0 1 0 2)
+(unless (MovableCopyable-is-nullptr mo)
+  (error "is_nullptr failed"))
+(delete-MovableCopyable mo)
+(Counter-check-counts 1 0 0 1 0 2)
+
+; Move constructor test
+(Counter-reset-counts)
+(define mo (new-MovableCopyable 222))
+(Counter-check-counts 1 0 0 0 0 0)
+(define mo_moved (new-MovableCopyable mo))
+(Counter-check-counts 1 0 0 1 0 1)
+(unless (MovableCopyable-is-nullptr mo)
+  (error "is_nullptr failed"))
+(delete-MovableCopyable mo)
+(Counter-check-counts 1 0 0 1 0 1)
+(delete-MovableCopyable mo_moved)
+(Counter-check-counts 1 0 0 1 0 2)
+
+; Move assignment operator test
+(Counter-reset-counts)
+(define mo111 (new-MovableCopyable 111))
+(define mo222 (new-MovableCopyable 222))
+(Counter-check-counts 2 0 0 0 0 0)
+(MovableCopyable-MoveAssign mo111 mo222)
+(Counter-check-counts 2 0 0 0 1 1)
+(unless (MovableCopyable-is-nullptr mo222)
+  (error "is_nullptr failed"))
+(delete-MovableCopyable mo222)
+(Counter-check-counts 2 0 0 0 1 1)
+(delete-MovableCopyable mo111)
+(Counter-check-counts 2 0 0 0 1 2)
+
+; null check
+(Counter-reset-counts)
+(expect-throw 'misc-error
+              (MovableCopyable-movein '()))
+; TODO: check the exception message
+(Counter-check-counts 0 0 0 0 0 0)
+
+; output
+(Counter-reset-counts)
+(define mc (MovableCopyable-moveout 1234))
+(Counter-check-counts 2 0 0 0 1 1)
+(MovableCopyable-check-numbers-match mc 1234)
+
+(expect-throw 'misc-error
+              (MovableCopyable-movein mc))
+; TODO: check the exception message
+(Counter-check-counts 2 0 0 0 1 1)
+
+(exit 0)
diff --git a/Examples/test-suite/schemerunme/cpp11_std_unique_ptr.scm b/Examples/test-suite/schemerunme/cpp11_std_unique_ptr.scm
new file mode 100644
index 0000000..5e6d0df
--- /dev/null
+++ b/Examples/test-suite/schemerunme/cpp11_std_unique_ptr.scm
@@ -0,0 +1,95 @@
+(define checkCount
+  (lambda (expected-count)
+    (define actual-count (Klass-getTotal-count))
+    (unless (= actual-count expected-count) (error (format "Counts incorrect, expected:~a actual:~a" expected-count  actual-count)))))
+
+; Test raw pointer handling involving virtual inheritance
+(define kini (new-KlassInheritance "KlassInheritanceInput"))
+(checkCount 1)
+(define s (useKlassRawPtr kini))
+(unless (string=? s "KlassInheritanceInput")
+  (error "Incorrect string: " s))
+(set! kini '()) (gc)
+(checkCount 0)
+
+; unique_ptr as input
+(define kin (new-Klass "KlassInput"))
+(checkCount 1)
+(define s (takeKlassUniquePtr kin))
+(checkCount 0)
+(unless (string=? s "KlassInput")
+  (error "Incorrect string: " s))
+(unless (is-nullptr kin)
+  (error "is_nullptr failed"))
+(set! kini '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define kin (new-Klass "KlassInput"))
+(checkCount 1)
+(define s (takeKlassUniquePtr kin))
+(checkCount 0)
+(unless (string=? s "KlassInput")
+  (error "Incorrect string: " s))
+(unless (is-nullptr kin)
+  (error "is_nullptr failed"))
+(expect-throw 'misc-error 
+              (takeKlassUniquePtr kin))
+; TODO: check the exception message
+(set! kin '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define kin (new-Klass "KlassInput"))
+(define notowned (get-not-owned-ptr kin))
+(expect-throw 'misc-error 
+              (takeKlassUniquePtr notowned))
+; TODO: check the exception message
+(checkCount 1)
+(set! kin '()) (gc)
+(checkCount 0)
+
+(define kini (new-KlassInheritance "KlassInheritanceInput"))
+(checkCount 1)
+(define s (takeKlassUniquePtr kini))
+(checkCount 0)
+(unless (string=? s "KlassInheritanceInput")
+  (error "Incorrect string: " s))
+(unless (is-nullptr kini)
+  (error "is_nullptr failed"))
+(set! kini '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define null '())
+(takeKlassUniquePtr null)
+(define nullnil #nil)
+(takeKlassUniquePtr nullnil)
+(takeKlassUniquePtr (make-null))
+(checkCount 0)
+
+; overloaded parameters
+(unless (= (overloadTest) 0)
+  (error "overloadTest failed"))
+(unless (= (overloadTest nullnil) 1)
+  (error "overloadTest failed"))
+(unless (= (overloadTest (new-Klass "over")) 1)
+  (error "overloadTest failed"))
+(checkCount 0)
+
+
+; unique_ptr as output
+(define k1 (makeKlassUniquePtr "first"))
+(define k2 (makeKlassUniquePtr "second"))
+(checkCount 2)
+
+(set! k1 '()) (gc)
+(checkCount 1)
+
+(unless (string=? (Klass-getLabel k2) "second")
+  (error "wrong object label" ))
+
+(set! k2 '()) (gc)
+(checkCount 0)
+
+(unless (null? (makeNullUniquePtr))
+  (error "null failure"))
+
+(exit 0)
diff --git a/Examples/test-suite/schemerunme/li_std_auto_ptr.scm b/Examples/test-suite/schemerunme/li_std_auto_ptr.scm
new file mode 100644
index 0000000..3ccd83f
--- /dev/null
+++ b/Examples/test-suite/schemerunme/li_std_auto_ptr.scm
@@ -0,0 +1,95 @@
+(define checkCount
+  (lambda (expected-count)
+    (define actual-count (Klass-getTotal-count))
+    (unless (= actual-count expected-count) (error (format "Counts incorrect, expected:~a actual:~a" expected-count  actual-count)))))
+
+; Test raw pointer handling involving virtual inheritance
+(define kini (new-KlassInheritance "KlassInheritanceInput"))
+(checkCount 1)
+(define s (useKlassRawPtr kini))
+(unless (string=? s "KlassInheritanceInput")
+  (error "Incorrect string: " s))
+(set! kini '()) (gc)
+(checkCount 0)
+
+; auto_ptr as input
+(define kin (new-Klass "KlassInput"))
+(checkCount 1)
+(define s (takeKlassAutoPtr kin))
+(checkCount 0)
+(unless (string=? s "KlassInput")
+  (error "Incorrect string: " s))
+(unless (is-nullptr kin)
+  (error "is_nullptr failed"))
+(set! kini '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define kin (new-Klass "KlassInput"))
+(checkCount 1)
+(define s (takeKlassAutoPtr kin))
+(checkCount 0)
+(unless (string=? s "KlassInput")
+  (error "Incorrect string: " s))
+(unless (is-nullptr kin)
+  (error "is_nullptr failed"))
+(expect-throw 'misc-error 
+              (takeKlassAutoPtr kin))
+; TODO: check the exception message
+(set! kin '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define kin (new-Klass "KlassInput"))
+(define notowned (get-not-owned-ptr kin))
+(expect-throw 'misc-error 
+              (takeKlassAutoPtr notowned))
+; TODO: check the exception message
+(checkCount 1)
+(set! kin '()) (gc)
+(checkCount 0)
+
+(define kini (new-KlassInheritance "KlassInheritanceInput"))
+(checkCount 1)
+(define s (takeKlassAutoPtr kini))
+(checkCount 0)
+(unless (string=? s "KlassInheritanceInput")
+  (error "Incorrect string: " s))
+(unless (is-nullptr kini)
+  (error "is_nullptr failed"))
+(set! kini '()) (gc) ; Should not fail, even though already deleted
+(checkCount 0)
+
+(define null '())
+(takeKlassAutoPtr null)
+(define nullnil #nil)
+(takeKlassAutoPtr nullnil)
+(takeKlassAutoPtr (make-null))
+(checkCount 0)
+
+; overloaded parameters
+(unless (= (overloadTest) 0)
+  (error "overloadTest failed"))
+(unless (= (overloadTest nullnil) 1)
+  (error "overloadTest failed"))
+(unless (= (overloadTest (new-Klass "over")) 1)
+  (error "overloadTest failed"))
+(checkCount 0)
+
+
+; auto_ptr as output
+(define k1 (makeKlassAutoPtr "first"))
+(define k2 (makeKlassAutoPtr "second"))
+(checkCount 2)
+
+(set! k1 '()) (gc)
+(checkCount 1)
+
+(unless (string=? (Klass-getLabel k2) "second")
+  (error "wrong object label" ))
+
+(set! k2 '()) (gc)
+(checkCount 0)
+
+(unless (null? (makeNullAutoPtr))
+  (error "null failure"))
+
+(exit 0)
diff --git a/Examples/test-suite/schemerunme/li_std_string.scm b/Examples/test-suite/schemerunme/li_std_string.scm
index 343b9b8..c598de9 100644
--- a/Examples/test-suite/schemerunme/li_std_string.scm
+++ b/Examples/test-suite/schemerunme/li_std_string.scm
@@ -45,4 +45,20 @@
 (if (not (string=? (Structure-ConstStaticMemberString) "const static member string"))
   (error "Error 10"))
 
+(if (not (string=? (stdstring-empty) ""))
+  (error "stdstring-empty test"))
+(if (not (string=? (c-empty) ""))
+  (error "c-empty test"))
+; C++ NULL is mapped to #f (false) here rather than null.  I don't know guile
+; enough to know if that makes sense or not.
+(if (c-null)
+  (error "c-null test"))
+; FIXME: However, #f doesn't round-trip, so something seems wrong.
+; (if (get-null (c-null))
+;   (error "get-null c-empty test"))
+(if (not (string=? (get-null (c-empty)) "non-null"))
+  (error "get-null c-empty test"))
+(if (not (string=? (get-null (stdstring-empty)) "non-null"))
+  (error "get-null stdstring-empty test"))
+
 (exit 0)
diff --git a/Examples/test-suite/schemerunme/li_typemaps.scm b/Examples/test-suite/schemerunme/li_typemaps.scm
index 161e803..a24bbda 100644
--- a/Examples/test-suite/schemerunme/li_typemaps.scm
+++ b/Examples/test-suite/schemerunme/li_typemaps.scm
@@ -24,8 +24,8 @@
 ;(check "ulonglong" 6432 =)
 
 ;; The checking of inoutr-int2 and out-foo is done in the individual
-;; language runme scripts, since chicken returns multiple values
-;; and must be checked with call-with-values, while guile just returns a list
+;; language runme scripts, since how multiple values are returned
+;; differs between scheme variants.
 
 ;(call-with-values (lambda () (inoutr-int2 3 -2))
 ;		  (lambda (a b)
diff --git a/Examples/test-suite/schemerunme/li_typemaps_proxy.scm b/Examples/test-suite/schemerunme/li_typemaps_proxy.scm
index f61d4fe..07bb855 100644
--- a/Examples/test-suite/schemerunme/li_typemaps_proxy.scm
+++ b/Examples/test-suite/schemerunme/li_typemaps_proxy.scm
@@ -24,8 +24,8 @@
 (check "ulonglong" 6432 =)
 
 ;; The checking of inoutr-int2 and out-foo is done in the individual
-;; language runme scripts, since chicken returns multiple values
-;; and must be checked with call-with-values, while guile just returns a list
+;; language runme scripts, since how multiple values are returned
+;; differs between scheme variants.
 
 ;(call-with-values (lambda () (inoutr-int2 3 -2))
 ;		  (lambda (a b)
diff --git a/Examples/test-suite/schemerunme/newobject1.scm b/Examples/test-suite/schemerunme/newobject1.scm
new file mode 100644
index 0000000..9d9d43a
--- /dev/null
+++ b/Examples/test-suite/schemerunme/newobject1.scm
@@ -0,0 +1,18 @@
+(define-macro (check test)
+  `(unless ,test (error "Error in test" ',test)))
+
+(define foo1 (Foo-makeFoo))
+(check (= (Foo-fooCount) 1))
+
+(define foo2 (Foo-makeMore foo1))
+(check (= (Foo-fooCount) 2))
+
+(set! foo1 '())
+(gc)
+(check (= (Foo-fooCount) 1))
+
+(set! foo2 '())
+(gc)
+(check (= (Foo-fooCount) 0))
+
+(exit 0)
diff --git a/Examples/test-suite/schemerunme/null_pointer.scm b/Examples/test-suite/schemerunme/null_pointer.scm
new file mode 100644
index 0000000..5b249ff
--- /dev/null
+++ b/Examples/test-suite/schemerunme/null_pointer.scm
@@ -0,0 +1,8 @@
+(define null '())
+(unless (funk null)
+  (error "funk(null) does not return true"))
+
+(unless (null? (getnull))
+  (error "NULL pointer should be null"))
+
+(exit 0)
diff --git a/Examples/test-suite/scilab/Makefile.in b/Examples/test-suite/scilab/Makefile.in
index f873b86..cf36794 100644
--- a/Examples/test-suite/scilab/Makefile.in
+++ b/Examples/test-suite/scilab/Makefile.in
@@ -7,6 +7,10 @@
 SCILAB_OPT   = @SCILABOPT@
 SCRIPTSUFFIX = _runme.sci
 
+HAVE_CXX11   = @HAVE_CXX11@
+HAVE_CXX14   = @HAVE_CXX14@
+HAVE_CXX17   = @HAVE_CXX17@
+HAVE_CXX20   = @HAVE_CXX20@
 srcdir       = @srcdir@
 top_srcdir   = ../@top_srcdir@
 top_builddir = ../@top_builddir@
diff --git a/Examples/test-suite/scilab/allprotected_runme.sci b/Examples/test-suite/scilab/allprotected_runme.sci
index 7bc74fa..b76bd7c 100644
--- a/Examples/test-suite/scilab/allprotected_runme.sci
+++ b/Examples/test-suite/scilab/allprotected_runme.sci
@@ -21,10 +21,10 @@
 class = PubBase_instanceMethod(pubBase, klass);
 checkequal(Klass_getName(class), "allprotected_klass", "Klass_getName(PubBase_instanceMethod(pubBase, klass))");
 
-class = PubBase_instanceOverload(pubBase, klass);
+class = PubBase_instanceOverloaded(pubBase, klass);
 checkequal(Klass_getName(class), "allprotected_klass", "Klass_getName(PubBase_instanceOverloaded(pubBase, klass))");
 
-class = PubBase_instanceOverload(pubBase, klass, "allprotected_klass2");
+class = PubBase_instanceOverloaded(pubBase, klass, "allprotected_klass2");
 checkequal(Klass_getName(class), "allprotected_klass2", "Klass_getName(PubBase_instanceOverloaded(pubBase, klass, ""allprotected_klass2""))");
 
 class = PubBase_staticMethod(klass);
@@ -40,12 +40,22 @@
 checkequal(PubBase_EnumVal1_get(), 0, "PubBase_EnumVal1_get()");
 checkequal(PubBase_EnumVal2_get(), 1, "(PubBase_EnumVal2_get()");
 
+v=getversion("scilab");
+if v(1) < 6 then
+    PubBase_instanceMemb_set(pubBase, 12);
+    checkequal(PubBase_instanceMemb_get(pubBase), 12, "PubBase_instanceMemb_get(pubBase)");
+else
+    PubBase_instanceMemberVariable_set(pubBase, 12);
+    checkequal(PubBase_instanceMemberVariable_get(pubBase), 12, "PubBase_instanceMemberVariable_get(pubBase)");
+end
 
-PubBase_instanceMemb_set(pubBase, 12);
-checkequal(PubBase_instanceMemb_get(pubBase), 12, "PubBase_instanceMemb_get(pubBase)");
-
-checkequal(PubBase_staticConstM_get(), 20, "PubBase_staticConstM_get()");
-checkequal(PubBase_staticMember_get(), 10, "PubBase_staticMember_get()")
+if v(1) < 6 then
+    checkequal(PubBase_staticConstM_get(), 20, "PubBase_staticConstMemberVariable_get()");
+    checkequal(PubBase_staticMember_get(), 10, "PubBase_staticMemberVariable_get()")
+else
+    checkequal(PubBase_staticConstMemberVariable_get(), 20, "PubBase_staticConstMemberVariable_get()");
+    checkequal(PubBase_staticMemberVariable_get(), 10, "PubBase_staticMemberVariable_get()")
+end
 
 PubBase_stringMember_set(pubBase, "dummy");
 checkequal(PubBase_stringMember_get(pubBase), "dummy", "PubBase_stringMember_get()");
diff --git a/Examples/test-suite/scilab/argcargvtest_runme.sci b/Examples/test-suite/scilab/argcargvtest_runme.sci
new file mode 100644
index 0000000..b72f849
--- /dev/null
+++ b/Examples/test-suite/scilab/argcargvtest_runme.sci
@@ -0,0 +1,34 @@
+exec("swigtest.start", -1);
+
+largs = ["hi" "hola" "hello"];
+checkequal(mainc(largs), 3, "calling mainc");
+
+targs = ["hi" "hola"]
+checkequal(mainv(targs, 0), "hi", "calling mainv");
+checkequal(mainv(targs, 1), "hola", "calling mainv");
+checkequal(mainv(targs, 2), "<<NULL>>", "calling mainv");
+
+checkequal(mainv("hi", 0), "hi", "calling mainv with a single string");
+
+try
+  mainv(1, 1);
+  swigtesterror();
+catch
+end
+
+initializeApp(largs);
+
+// Check that an empty array works.
+empty_args = [];
+checkequal(mainc(empty_args), 0, "calling mainc");
+checkequal(mainv(empty_args, 0), "<<NULL>>", "calling mainv");
+
+// Check that empty strings are handled.
+empty_string = ["hello", "", "world"];
+checkequal(mainc(empty_string), 3, "calling mainc");
+checkequal(mainv(empty_string, 0), "hello", "calling mainv");
+checkequal(mainv(empty_string, 1), "", "calling mainv");
+checkequal(mainv(empty_string, 2), "world", "calling mainv");
+checkequal(mainv(empty_string, 3), "<<NULL>>", "calling mainv");
+
+exec("swigtest.quit", -1);
diff --git a/Examples/test-suite/scilab/catches_strings_runme.sci b/Examples/test-suite/scilab/catches_strings_runme.sci
new file mode 100644
index 0000000..f9226c7
--- /dev/null
+++ b/Examples/test-suite/scilab/catches_strings_runme.sci
@@ -0,0 +1,17 @@
+exec("swigtest.start", -1);
+
+ierr = execstr("StringsThrower_charstring()", 'errcatch');
+checkequal(ierr, 20000, "wrong/no exception thrown")
+if (strstr(lasterror(), "charstring message") == '')
+  printf("Should have thrown an exception")
+  exit(1)
+end
+
+ierr = execstr("StringsThrower_stdstring()", 'errcatch');
+checkequal(ierr, 20000, "wrong/no exception thrown")
+if (strstr(lasterror(), "stdstring message") == '')
+  printf("Should have thrown an exception")
+  exit(1)
+end
+
+exec("swigtest.quit", -1);
diff --git a/Examples/test-suite/scilab/li_std_except_runme.sci b/Examples/test-suite/scilab/li_std_except_runme.sci
index 3b6522f..272f032 100644
--- a/Examples/test-suite/scilab/li_std_except_runme.sci
+++ b/Examples/test-suite/scilab/li_std_except_runme.sci
@@ -14,7 +14,7 @@
 
 checkException('Test_throw_exception(t)', 20010, 'SystemError: std::exception');
 
-checkException('Test_throw_invalid_argum(t)', 20009, 'ValueError: oops');
+checkException('Test_throw_invalid_argument(t)', 20009, 'ValueError: oops');
 
 checkException('Test_throw_length_error(t)', 20004, 'IndexError: oops');
 
@@ -22,7 +22,7 @@
 
 checkException('Test_throw_out_of_range(t)', 20004, 'IndexError: oops');
 
-checkException('Test_throw_overflow_erro(t)', 20007, 'OverflowError: oops');
+checkException('Test_throw_overflow_error(t)', 20007, 'OverflowError: oops');
 
 checkException('Test_throw_range_error(t)', 20007, 'OverflowError: oops');
 
diff --git a/Examples/test-suite/scilab/li_std_string_extra_runme.sci b/Examples/test-suite/scilab/li_std_string_extra_runme.sci
index b96b07e..c4f2544 100644
--- a/Examples/test-suite/scilab/li_std_string_extra_runme.sci
+++ b/Examples/test-suite/scilab/li_std_string_extra_runme.sci
@@ -42,8 +42,12 @@
 Structure_StaticStr2_set(s);
 checkequal(Structure_StaticStr2_get(), s, "Structure_StaticStr2_get()");
 
-checkequal(Structure_ConstStati_get(), "const static member string", "Structure_ConstStaticStr_get()");
-
+v = getversion("scilab");
+if v(1) < 6 then
+    checkequal(Structure_ConstStati_get(), "const static member string", "Structure_ConstStati_get()");
+else
+    checkequal(Structure_ConstStaticStr_get(), "const static member string", "Structure_ConstStaticStr_get()");
+end
 
 checkequal(stdstring_empty(), "", "stdstring_empty()");
 checkequal(c_empty(), "", "c_empty()");
diff --git a/Examples/test-suite/scilab/overload_null_runme.sci b/Examples/test-suite/scilab/overload_null_runme.sci
index e3939ac..72a2b7e 100644
--- a/Examples/test-suite/scilab/overload_null_runme.sci
+++ b/Examples/test-suite/scilab/overload_null_runme.sci
@@ -30,16 +30,16 @@
 checkequal(15, Overload_byval2cpr(o, NULL), "test 15");
 checkequal(16, Overload_byval2cpr(o, x), "test 16");
 
-// forward class declaration
-checkequal(17, Overload_byval1forwardptr(o, x), "test 17");
-checkequal(18, Overload_byval1forwardptr(o, NULL), "test 18");
+// fwd class declaration
+checkequal(17, Overload_byval1fwdptr(o, x), "test 17");
+checkequal(18, Overload_byval1fwdptr(o, NULL), "test 18");
 
-checkequal(19, Overload_byval2forwardptr(o, NULL), "test 19");
-checkequal(20, Overload_byval2forwardptr(o, x), "test 20");
+checkequal(19, Overload_byval2fwdptr(o, NULL), "test 19");
+checkequal(20, Overload_byval2fwdptr(o, x), "test 20");
 
-checkequal(21, Overload_byval1forwardref(o, x), "test 21");
+checkequal(21, Overload_byval1fwdref(o, x), "test 21");
 
-checkequal(22, Overload_byval2forwardref(o, x), "test 22");
+checkequal(22, Overload_byval2fwdref(o, x), "test 22");
 
 exec("swigtest.quit", -1);
 
diff --git a/Examples/test-suite/scilab/preproc_constants_runme.sci b/Examples/test-suite/scilab/preproc_constants_runme.sci
index d3d0a4b..3dc1433 100644
--- a/Examples/test-suite/scilab/preproc_constants_runme.sci
+++ b/Examples/test-suite/scilab/preproc_constants_runme.sci
@@ -24,7 +24,7 @@
 test_global();
 
 
-// Test assignement in enums
+// Test assignment in enums
 checkequal(kValue_get(), 4, "kValue");
 
 exec("swigtest.quit", -1);
diff --git a/Examples/test-suite/scilab/scilab_identifier_name_runme.sci b/Examples/test-suite/scilab/scilab_identifier_name_runme.sci
index 9a4f3cc..1665ec9 100644
--- a/Examples/test-suite/scilab/scilab_identifier_name_runme.sci
+++ b/Examples/test-suite/scilab/scilab_identifier_name_runme.sci
@@ -1,29 +1,46 @@
 exec("swigtest.start", -1);
 
+v = getversion("scilab");
 
-// Test truncating variables, constants, functions identifier names
+// Test truncating variables, constants, functions identifier names in Scilab 5
 // not truncated
 gvar_identifier_name_set(-101);
 checkequal(gvar_identifier_name_get(), -101, "gvar_identifier_name_get()");
 checkequal(CONS_IDENTIFIER_NAME_get(), -11, "CONS_IDENTIFIER_NAME_get()");
 checkequal(function_identifier_name(), -21, "function_identifier_name()");
 
-// truncated
+// truncated in Scilab 5
+if v(1) < 6 then
 too_long_gvar_identi_set(101);
 checkequal(too_long_gvar_identi_get(), 101, "too_long_variable_id_get()");
-checkequal(TOO_LONG_CONST_IDENT_get(), 11, "TOO_LONG_CONST_IDENT_get()");
-checkequal(too_long_function_identi(), 21, "too_long_function_identi()");
+checkequal(TOO_LONG_CONST_IDENT_get(), 11, "TOO_LONG_CONST_IDENTIFIER_NAME_1_get");
+checkequal(too_long_function_identi(), 21, "too_long_function_identifier_name_1()");
+else
+too_long_gvar_identifier_name_1_set(101);
+checkequal(too_long_gvar_identifier_name_1_get(), 101, "too_long_variable_id_get()");
+checkequal(TOO_LONG_CONST_IDENTIFIER_NAME_1_get(), 11, "TOO_LONG_CONST_IDENTIFIER_NAME_1_get");
+checkequal(too_long_function_identifier_name_1(), 21, "too_long_function_identifier_name_1()");
+end
 
 // Test truncating when %scilabconst mode is activated
-checkequal(SC_CONST_IDENTIFIER_NAME, int32(-12), "SC_TOO_LONG_IDENTIF");
-checkequal(SC_TOO_LONG_CONST_IDENTI, int32(14), "SC_TOO_LONG_IDENTIF");
+checkequal(SC_CONST_IDENTIFIER_NAME, int32(-12), "SC_CONST_IDENTIFIER_NAME");
+if v(1) < 6 then
+checkequal(SC_TOO_LONG_CONST_IDENTI, int32(14), "SC_TOO_LONG_CONST_IDENTIFIER_NAME_2");
+else
+checkequal(SC_TOO_LONG_CONST_IDENTIFIER_NAME_2, int32(14), "SC_TOO_LONG_CONST_IDENTIFIER_NAME_2");
+end
 
 // Test truncating in the case of struct
 st = new_st();
 st_m_identifier_name_set(st, 15);
 checkequal(st_m_identifier_name_get(st), 15, "st_m_identifier_name_get(st)");
+if v(1) < 6 then
 st_too_long_member_i_set(st, 25);
-checkequal(st_too_long_member_i_get(st), 25, "st_too_long_member_i_get(st)");
+checkequal(st_too_long_member_i_get(st), 25, "st_too_long_member_identifier_name_get(st)");
+else
+st_too_long_member_identifier_name_set(st, 25);
+checkequal(st_too_long_member_identifier_name_get(st), 25, "st_too_long_member_identifier_name_get(st)");
+end
 delete_st(st);
 
 exec("swigtest.quit", -1);
diff --git a/Examples/test-suite/scilab/swigtest.start b/Examples/test-suite/scilab/swigtest.start
index e4347bd..1613371 100644
--- a/Examples/test-suite/scilab/swigtest.start
+++ b/Examples/test-suite/scilab/swigtest.start
@@ -2,6 +2,8 @@
 warning('off');
 ilib_verbose(0);
 
+ver = getversion('scilab');
+
 // Get test name (used in swigtest.quit file)
 [units, typ, names] = file(1);
 swigtestname = strsubst(fileparts(names, "fname"), "_runme", "");
@@ -23,7 +25,12 @@
 
 // Module initialization
 try
-    moduleInit = sprintf("%s_Init()", swigtestname);
+    if ver(1) < 6 then
+        entry = stripblanks(part(swigtestname, 1:24-5));
+    else
+        entry = swigtestname;
+    end
+    moduleInit = sprintf("%s_Init()", entry);
     execstr(moduleInit);
 catch
     mfprintf(0, "*** MODULE INIT FAILED ***\n");
diff --git a/Examples/test-suite/scilab_identifier_name.i b/Examples/test-suite/scilab_identifier_name.i
index 94dde47..4e5a574 100644
--- a/Examples/test-suite/scilab_identifier_name.i
+++ b/Examples/test-suite/scilab_identifier_name.i
@@ -7,7 +7,7 @@
 // Test truncating variables, constants, functions identifier names
 
 %inline %{
-// these identifier names wont be truncated
+// these identifier names won't be truncated
 int gvar_identifier_name = -1;
 #define CONS_IDENTIFIER_NAME -11
 int function_identifier_name() { return -21; };
diff --git a/Examples/test-suite/simple_array.i b/Examples/test-suite/simple_array.i
index 6ddc436..df3af92 100644
--- a/Examples/test-suite/simple_array.i
+++ b/Examples/test-suite/simple_array.i
@@ -31,7 +31,7 @@
     y[i] = ((double) i)/ ((double) n);
 
   n = sizeof(bars)/sizeof(bars[0]);
-  for(i = 0; i < n; i++)  {
+  for(i = 0; i < n; i++) {
     bars[i].i = x[i+2];
     bars[i].d = y[i+2];
   }
diff --git a/Examples/test-suite/sizet.i b/Examples/test-suite/sizet.i
index 5379141..6b70f68 100644
--- a/Examples/test-suite/sizet.i
+++ b/Examples/test-suite/sizet.i
@@ -3,9 +3,7 @@
 #include <vector>
 %}
 
-#ifndef SWIGCHICKEN
 %include "std_common.i"
-#endif
 
 %inline
 {
diff --git a/Examples/test-suite/smart_pointer_const_overload.i b/Examples/test-suite/smart_pointer_const_overload.i
index 75a137b..526bcc9 100644
--- a/Examples/test-suite/smart_pointer_const_overload.i
+++ b/Examples/test-suite/smart_pointer_const_overload.i
@@ -3,6 +3,10 @@
 %warnfilter(SWIGWARN_LANG_OVERLOAD_IGNORED) Bar::operator->;      // Overloaded method Bar::operator ->() ignored
 %warnfilter(SWIGWARN_LANG_OVERLOAD_IGNORED) Bar2::operator->;     // Overloaded method Bar2::operator ->() ignored
 
+%{
+#include <stdlib.h>
+%}
+
 %inline %{
 int CONST_ACCESS = 1;
 int MUTABLE_ACCESS = 2;
diff --git a/Examples/test-suite/smart_pointer_inherit.i b/Examples/test-suite/smart_pointer_inherit.i
index 52df5a9..26987a5 100644
--- a/Examples/test-suite/smart_pointer_inherit.i
+++ b/Examples/test-suite/smart_pointer_inherit.i
@@ -70,7 +70,10 @@
 
 class ItkVectorContainerUILSNUS2_Pointer {
   public:
-    ItkVectorContainerUILSNUS2 * operator->() const { return 0; }
+    ItkVectorContainerUILSNUS2 * operator->() const {
+      static ItkVectorContainerUILSNUS2 instance;
+      return &instance;
+    }
 };
 
 %}
diff --git a/Examples/test-suite/smart_pointer_member.i b/Examples/test-suite/smart_pointer_member.i
index e4f1ae2..ef7560c 100644
--- a/Examples/test-suite/smart_pointer_member.i
+++ b/Examples/test-suite/smart_pointer_member.i
@@ -32,7 +32,7 @@
     Foo *f;
   public:
     CBar(Foo *f) : f(f) { }
-    const Foo *operator->()  {
+    const Foo *operator->() {
       return f;
     }
   };
diff --git a/Examples/test-suite/special_variable_macros.i b/Examples/test-suite/special_variable_macros.i
index ca2edaa..94d0e68 100644
--- a/Examples/test-suite/special_variable_macros.i
+++ b/Examples/test-suite/special_variable_macros.i
@@ -9,6 +9,8 @@
 #if defined(_MSC_VER)
   #pragma warning(disable: 4996) // 'strdup': The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name: _strdup. See online help for details.
 #endif
+#include <stdlib.h>
+#include <string.h>
 %}
 
 %ignore Name::operator=;
@@ -37,10 +39,13 @@
 private:
   Name name;
 };
+
+// Global variable for testing whether examplekw was touched
+int accessed_examplekw = 0;
 %}
 
 // check $1 and $input get expanded properly when used from $typemap()
-%typemap(in) Name *GENERIC ($*1_type temp)
+%typemap(in, examplekw="accessed_examplekw=1;") Name *GENERIC ($*1_type temp)
 %{
   /*%typemap(in) Name *GENERIC start */
   temp = Name("$specialname");
@@ -78,6 +83,7 @@
 %typemap(in) Name *jack {
 // %typemap(in) Name *jack start
 $typemap(in, Name *GENERIC)
+$typemap(in:examplekw, Name *GENERIC)
 // %typemap(in) Name *jack end
 }
 
@@ -184,7 +190,7 @@
 %template(PairIntBool) Space::Pair<int, bool>;
 
 //////////////////////////////////////////////////////////////////////////////////////
-// A real use case for $typemap
+// A real use case for $typemap()
 
 #if defined(SWIGCSHARP)
 %typemap(cscode) Space::RenameMe %{
@@ -203,20 +209,12 @@
   }
 %}
 #elif defined(SWIGD)
-#if (SWIG_D_VERSION == 1)
-%typemap(dcode) Space::RenameMe %{
-  public static NewName factory(char[] s) {
-    return new $typemap(dtype, Space::RenameMe)( new $typemap(dtype, Name)(s) );
-  }
-%}
-#else
 %typemap(dcode) Space::RenameMe %{
   public static NewName factory(string s) {
     return new $typemap(dtype, Space::RenameMe)( new $typemap(dtype, Name)(s) );
   }
 %}
 #endif
-#endif
 
 %rename(NewName) Space::RenameMe;
 %inline %{
@@ -230,3 +228,81 @@
 }
 %}
 
+//////////////////////////////////////////////////////////////////////////////////////
+// Part 1: $typemap() and the 'out' typemap $1 variable override
+// These typemaps for Pair use the std::string typemaps via $typemap() to morph the Pair return into returning just the (first) string value of the Pair.
+// The 1=result_first variable override is needed in all the different target languages for returning a string instead of Pair.
+// $typemap() does the target language specific std::string output handling
+
+%include <std_string.i>
+%typemap(out) Space::Pair<std::string, int> {
+  /* start of out Pair<std::string, int> */
+  const std::string& result_first = $1.first;
+  $typemap(out, std::string, 1=result_first);
+  /* end of out Pair<std::string, int> */
+}
+// Additional target language specific typemaps for the strongly typed languages to return a string instead of a Pair proxy
+#if defined(SWIGCSHARP)
+%typemap(ctype) Space::Pair<std::string, int> = std::string;
+%typemap(imtype) Space::Pair<std::string, int> = std::string;
+%typemap(cstype) Space::Pair<std::string, int> = std::string;
+%typemap(csout) Space::Pair<std::string, int> = std::string;
+#elif defined(SWIGD)
+%typemap(ctype) Space::Pair<std::string, int> = std::string;
+%typemap(imtype) Space::Pair<std::string, int> = std::string;
+%typemap(dtype) Space::Pair<std::string, int> = std::string;
+%typemap(dout) Space::Pair<std::string, int> = std::string;
+#elif defined(SWIGGO)
+%typemap(gotype) Space::Pair<std::string, int> = std::string;
+%typemap(goout) Space::Pair<std::string, int> = std::string;
+#elif defined(SWIGJAVA)
+%typemap(jni) Space::Pair<std::string, int> = std::string;
+%typemap(jtype) Space::Pair<std::string, int> = std::string;
+%typemap(jstype) Space::Pair<std::string, int> = std::string;
+%typemap(javaout) Space::Pair<std::string, int> = std::string;
+#endif
+%template() Space::Pair<std::string, int>;
+%inline %{
+Space::Pair<std::string, int> makeStringInt(const std::string& s, int i) {
+  return Space::Pair<std::string, int>(s, i);
+}
+%}
+
+// Part 2: $typemap() and the 'in' typemap $1 variable override
+// Target language just passes in an int and the typemaps morph this into a Pair containing the stringified int and the input int
+// $typemap() does the target language specific int as an input handling
+%fragment("my_sstream", "header") %{#include <sstream>%}
+%typemap(in, fragment="my_sstream") Space::Pair<std::string, int> {
+  // start of in Pair<std::string, int>
+  int& input_value_second = $1.second;
+  $typemap(in, int, 1=input_value_second);
+
+  // create string from int value plus one
+  std::stringstream ss;
+  ss << $1.second + 1;
+  $1.first = ss.str();
+  // end of in Pair<std::string, int>
+}
+#if defined(SWIGCSHARP)
+%typemap(ctype) Space::Pair<std::string, int> = int;
+%typemap(imtype) Space::Pair<std::string, int> = int;
+%typemap(cstype) Space::Pair<std::string, int> = int;
+%typemap(csin) Space::Pair<std::string, int> = int;
+#elif defined(SWIGD)
+%typemap(ctype) Space::Pair<std::string, int> = int;
+%typemap(imtype) Space::Pair<std::string, int> = int;
+%typemap(dtype) Space::Pair<std::string, int> = int;
+%typemap(din) Space::Pair<std::string, int> = int;
+#elif defined(SWIGGO)
+%typemap(gotype) Space::Pair<std::string, int> = int;
+#elif defined(SWIGJAVA)
+%typemap(jni) Space::Pair<std::string, int> = int;
+%typemap(jtype) Space::Pair<std::string, int> = int;
+%typemap(jstype) Space::Pair<std::string, int> = int;
+%typemap(javain) Space::Pair<std::string, int> = int;
+#endif
+%inline %{
+std::string provideStringInt(Space::Pair<std::string, int> p) {
+  return p.first;
+}
+%}
diff --git a/Examples/test-suite/string_simple.i b/Examples/test-suite/string_simple.i
index 537daa5..55cb950 100644
--- a/Examples/test-suite/string_simple.i
+++ b/Examples/test-suite/string_simple.i
@@ -3,6 +3,7 @@
 %newobject copy_str;
 
 %inline %{
+#include <stdlib.h>
 #include <string.h>
 const char* copy_str(const char* str) {
   size_t len = strlen(str);
diff --git a/Examples/test-suite/tcl/Makefile.in b/Examples/test-suite/tcl/Makefile.in
index 322e719..db8eaa8 100644
--- a/Examples/test-suite/tcl/Makefile.in
+++ b/Examples/test-suite/tcl/Makefile.in
@@ -6,6 +6,10 @@
 TCLSH        = tclsh
 SCRIPTSUFFIX = _runme.tcl
 
+HAVE_CXX11   = @HAVE_CXX11@
+HAVE_CXX14   = @HAVE_CXX14@
+HAVE_CXX17   = @HAVE_CXX17@
+HAVE_CXX20   = @HAVE_CXX20@
 srcdir       = @srcdir@
 top_srcdir   = @top_srcdir@
 top_builddir = @top_builddir@
diff --git a/Examples/test-suite/tcl/argcargvtest_runme.tcl b/Examples/test-suite/tcl/argcargvtest_runme.tcl
new file mode 100644
index 0000000..774e860
--- /dev/null
+++ b/Examples/test-suite/tcl/argcargvtest_runme.tcl
@@ -0,0 +1,74 @@
+if [ catch { load ./argcargvtest[info sharedlibextension] Argcargvtest} err_msg ] {
+	puts stderr "Could not load shared object:\n$err_msg"
+}
+
+set largs {hi hola hello}
+if {[mainc $largs] != 3} {
+     puts stderr "bad main typemap"
+     exit 1
+}
+
+set targs {hi hola}
+if {[mainv $targs 0] != "hi"} {
+     puts stderr "bad main typemap"
+     exit 1
+}
+if {[mainv $targs 1] != "hola"} {
+     puts stderr "bad main typemap"
+     exit 1
+}
+if {[mainv $targs 2] != "<<NULL>>"} {
+     puts stderr "bad main typemap"
+     exit 1
+}
+
+set targs " hi hola "
+if {[mainv $targs 0] != "hi"} {
+     puts stderr "bad main typemap"
+     exit 1
+}
+if {[mainv $targs 1] != "hola"} {
+     puts stderr "bad main typemap"
+     exit 1
+}
+
+if { ! [ catch { mainv("hello", 1) } ] } {
+    puts stderr "bad main typemap"
+    exit 1
+}
+
+initializeApp $largs
+
+# Check that an empty array works.
+set empty_args {}
+if {[mainc $empty_args] != 0} {
+    puts stderr "bad main typemap"
+    exit 1
+}
+if {[mainv $empty_args 0] != "<<NULL>>"} {
+     puts stderr "bad main typemap"
+     exit 1
+}
+
+# Check that empty strings are handled.
+set empty_string {"hello" "" "world"}
+if {[mainc $empty_string] != 3} {
+    puts stderr "bad main typemap"
+    exit 1
+}
+if {[mainv $empty_string 0] != "hello"} {
+    puts stderr "bad main typemap"
+    exit 1
+}
+if {[mainv $empty_string 1] != ""} {
+    puts stderr "bad main typemap"
+    exit 1
+}
+if {[mainv $empty_string 2] != "world"} {
+    puts stderr "bad main typemap"
+    exit 1
+}
+if {[mainv $empty_string 3] != "<<NULL>>"} {
+    puts stderr "bad main typemap"
+    exit 1
+}
diff --git a/Examples/test-suite/tcl/bools_runme.tcl b/Examples/test-suite/tcl/bools_runme.tcl
index 582b812..cf446af 100644
--- a/Examples/test-suite/tcl/bools_runme.tcl
+++ b/Examples/test-suite/tcl/bools_runme.tcl
@@ -1,5 +1,5 @@
 
-if [ catch { load ./bools[info sharedlibextension] bools} err_msg ] {
+if [ catch { load ./bools[info sharedlibextension] Bools} err_msg ] {
 	puts stderr "Could not load shared object:\n$err_msg"
 }
 
diff --git a/Examples/test-suite/tcl/catches_strings_runme.tcl b/Examples/test-suite/tcl/catches_strings_runme.tcl
new file mode 100644
index 0000000..25ef5e7
--- /dev/null
+++ b/Examples/test-suite/tcl/catches_strings_runme.tcl
@@ -0,0 +1,31 @@
+
+if [ catch { load ./catches_strings[info sharedlibextension] Catches_strings} err_msg ] {
+	puts stderr "Could not load shared object:\n$err_msg"
+}
+
+
+set exception_thrown 0
+if [ catch {
+  StringsThrower_charstring
+} e ] {
+  if {[string first "charstring message" $e] == -1} {
+    error "incorrect exception message: $e"
+  }
+  set exception_thrown 1
+}
+if {!$exception_thrown} {
+  error "Should have thrown an exception"
+}
+
+set exception_thrown 0
+if [ catch {
+  StringsThrower_stdstring
+} e ] {
+  if {[string first "stdstring message" $e] == -1} {
+    error "incorrect exception message: $e"
+  }
+  set exception_thrown 1
+}
+if {!$exception_thrown} {
+  error "Should have thrown an exception"
+}
diff --git a/Examples/test-suite/tcl/clientdata_prop_runme.tcl b/Examples/test-suite/tcl/clientdata_prop_runme.tcl
index 2ac993f..e7b89e8 100644
--- a/Examples/test-suite/tcl/clientdata_prop_runme.tcl
+++ b/Examples/test-suite/tcl/clientdata_prop_runme.tcl
@@ -1,9 +1,9 @@
 
-if [ catch { load ./clientdata_prop_b[info sharedlibextension] clientdata_prop_b} err_msg ] {
+if [ catch { load ./clientdata_prop_b[info sharedlibextension] Clientdata_prop_b} err_msg ] {
   puts stderr "Could not load shared object:\n$err_msg"
   exit 1
 }
-if [ catch { load ./clientdata_prop_a[info sharedlibextension] clientdata_prop_a} err_msg ] {
+if [ catch { load ./clientdata_prop_a[info sharedlibextension] Clientdata_prop_a} err_msg ] {
   puts stderr "Could not load shared object:\n$err_msg"
   exit 1
 }
diff --git a/Examples/test-suite/tcl/cpp11_move_typemaps_runme.tcl b/Examples/test-suite/tcl/cpp11_move_typemaps_runme.tcl
new file mode 100644
index 0000000..51624ad
--- /dev/null
+++ b/Examples/test-suite/tcl/cpp11_move_typemaps_runme.tcl
@@ -0,0 +1,35 @@
+
+if [ catch { load ./cpp11_move_typemaps[info sharedlibextension] Cpp11_move_typemaps} err_msg ] {
+	puts stderr "Could not load shared object:\n$err_msg"
+}
+
+Counter_reset_counts
+MoveOnly mo 111
+Counter_check_counts 1 0 0 0 0 0
+MoveOnly_take mo
+Counter_check_counts 1 0 0 1 0 2
+mo -delete
+Counter_check_counts 1 0 0 1 0 2
+
+Counter_reset_counts
+MovableCopyable mo 111
+Counter_check_counts 1 0 0 0 0 0
+MovableCopyable_take mo
+Counter_check_counts 1 0 0 1 0 2
+mo -delete
+Counter_check_counts 1 0 0 1 0 2
+
+MoveOnly mo 222
+MoveOnly_take mo
+set exception_thrown 0
+if [ catch {
+  MoveOnly_take mo
+} e ] {
+  if {[string first "cannot release ownership as memory is not owned" $e] == -1} {
+    error "incorrect exception message: $e"
+  }
+  set exception_thrown 1
+}
+if {!$exception_thrown} {
+  error "Should have thrown 'Cannot release ownership as memory is not owned' error"
+}
diff --git a/Examples/test-suite/tcl/cpp11_rvalue_reference_move_runme.tcl b/Examples/test-suite/tcl/cpp11_rvalue_reference_move_runme.tcl
new file mode 100644
index 0000000..7bd51f2
--- /dev/null
+++ b/Examples/test-suite/tcl/cpp11_rvalue_reference_move_runme.tcl
@@ -0,0 +1,82 @@
+
+if [ catch { load ./cpp11_rvalue_reference_move[info sharedlibextension] Cpp11_rvalue_reference_move} err_msg ] {
+	puts stderr "Could not load shared object:\n$err_msg"
+}
+
+
+# Function containing rvalue reference parameter
+Counter_reset_counts
+MovableCopyable mo 222
+Counter_check_counts 1  0  0  0  0  0
+MovableCopyable_movein mo
+Counter_check_counts 1  0  0  1  0  2
+if {![MovableCopyable_is_nullptr mo]} {
+  error "is_nullptr failed to throw"
+}
+mo -delete
+Counter_check_counts 1  0  0  1  0  2
+
+# Move constructor test
+Counter_reset_counts
+MovableCopyable mo 222
+Counter_check_counts 1  0  0  0  0  0
+MovableCopyable mo_moved mo
+Counter_check_counts 1  0  0  1  0  1
+if {![MovableCopyable_is_nullptr mo]} {
+  error "is_nullptr failed to throw"
+}
+mo -delete
+Counter_check_counts 1  0  0  1  0  1
+mo_moved -delete
+Counter_check_counts 1  0  0  1  0  2
+
+# Move assignment operator test
+Counter_reset_counts
+MovableCopyable mo111 111
+MovableCopyable mo222 222
+Counter_check_counts 2  0  0  0  0  0
+mo111 MoveAssign mo222
+Counter_check_counts 2  0  0  0  1  1
+if {![MovableCopyable_is_nullptr mo222]} {
+  error "is_nullptr failed to throw"
+}
+mo222 -delete
+Counter_check_counts 2  0  0  0  1  1
+mo111 -delete
+Counter_check_counts 2  0  0  0  1  2
+
+# null check
+Counter_reset_counts
+set exception_thrown 0
+if [ catch {
+  MovableCopyable_movein "NULL"
+} e ] {
+  if {[string first "invalid null reference" $e] == -1} {
+    error "incorrect exception message: $e"
+  }
+  set exception_thrown 1
+}
+if {!$exception_thrown} {
+  error "Should have thrown null error"
+}
+Counter_check_counts 0  0  0  0  0  0
+
+# output
+Counter_reset_counts
+set mc [MovableCopyable_moveout 1234]
+Counter_check_counts  2  0  0  0  1  1
+MovableCopyable_check_numbers_match $mc 1234
+
+set exception_thrown 0
+if [ catch {
+  MovableCopyable_movein $mc
+} e ] {
+  if {[string first "cannot release ownership as memory is not owned" $e] == -1} {
+    error "incorrect exception message: $e"
+  }
+  set exception_thrown 1
+}
+if {!$exception_thrown} {
+  error "Should have thrown 'Cannot release ownership as memory is not owned' error"
+}
+Counter_check_counts  2  0  0  0  1  1
diff --git a/Examples/test-suite/tcl/cpp11_std_unique_ptr_runme.tcl b/Examples/test-suite/tcl/cpp11_std_unique_ptr_runme.tcl
new file mode 100644
index 0000000..afa2145
--- /dev/null
+++ b/Examples/test-suite/tcl/cpp11_std_unique_ptr_runme.tcl
@@ -0,0 +1,163 @@
+
+if [ catch { load ./cpp11_std_unique_ptr[info sharedlibextension] Cpp11_std_unique_ptr} err_msg ] {
+	puts stderr "Could not load shared object:\n$err_msg"
+}
+
+
+proc checkCount {expected_count} {
+  set actual_count [Klass_getTotal_count]
+  if {$actual_count != $expected_count} {
+    error "Counts incorrect, expected: $expected_count actual: $actual_count"
+  }
+}
+
+################################# Tcl pointer recycling bug start
+#
+# ### Possibly related to premature object deletion problem mentioned in newobject1_runme.tcl. ###
+#
+# While this won't be repeatable on all machines, the following caused the underlying C++
+# pointer value for k1 to be reused for k4.
+#
+# If the C/C++ memory allocator uses the same pointer value again, then a command name that
+# contains a pointer encoding, such as, _b09b1148bd550000_p_Klass (not a variable name) will be
+# re-used in SWIG_Tcl_NewInstanceObj. The command should have disappeared from the Tcl side when
+# the object was deleted, but there is some sort of bug preventing this from happening in this
+# scenario as follows:
+#
+# Below creates a struct via the call to Tcl_CreateObjCommand in
+# SWIG_Tcl_NewInstanceObj (creates a command name with a pointer encoding such as
+# _50fb3608ce550000_p_Klass) which also makes a second call to Tcl_CreateObjCommand in
+# SWIG_Tcl_ObjectConstructor (creates a command name with the name k1).
+Klass k1 "one"
+# Line below calls Tcl_DeleteCommandFromToken but is only called for the command created in the
+# second call (k1) and not the first call to Tcl_CreateObjCommand.
+k1 -delete
+set k2 [makeKlassUniquePtr "two"]
+set k3 [makeKlassUniquePtr "three"]
+$k2 -delete
+# If the memory allocator uses the same pointer value, then SWIG_Tcl_NewInstanceObj will find
+# the undeleted command _50fb3608ce550000_p_Klass and re-use it. This command should surely
+# have been deleted !??
+set k4 [makeKlassUniquePtr "four"]
+$k3 -delete
+$k4 -delete
+checkCount 0
+################################# Tcl pointer recycling bug end
+
+# Test raw pointer handling involving virtual inheritance
+KlassInheritance kini "KlassInheritanceInput"
+checkCount 1
+set s [useKlassRawPtr kini]
+kini -delete
+checkCount 0
+
+
+# unique_ptr as input
+Klass kin "KlassInput"
+checkCount 1
+set s [takeKlassUniquePtr kin]
+checkCount 0
+if {[kin cget -thisown]} {
+  error "thisown should be false"
+}
+if {$s != "KlassInput"} {
+  error "Incorrect string: $s"
+}
+if {![is_nullptr kin]} {
+  error "is_nullptr failed"
+}
+kin -delete # Should not fail, even though already deleted
+checkCount 0
+
+Klass kin "KlassInput"
+checkCount 1
+set s [takeKlassUniquePtr kin]
+checkCount 0
+if {[kin cget -thisown]} {
+  error "thisown should be false"
+}
+if {$s != "KlassInput"} {
+  error "Incorrect string: $s"
+}
+if {![is_nullptr kin]} {
+  error "is_nullptr failed"
+}
+set exception_thrown 0
+if [ catch { set s [takeKlassUniquePtr kin] } e ] {
+  if {[string first "cannot release ownership as memory is not owned" $e] == -1} {
+    error "incorrect exception message: $e"
+  }
+  set exception_thrown 1
+}
+if {!$exception_thrown} {
+  error "double usage of takeKlassUniquePtr should have been an error"
+}
+kin -delete # Should not fail, even though already deleted
+checkCount 0
+
+Klass kin "KlassInput"
+set exception_thrown 0
+set notowned [get_not_owned_ptr kin]
+if [ catch {
+  takeKlassUniquePtr notowned
+} ] {
+  set exception_thrown 1
+}
+if {!$exception_thrown} {
+  error "Should have thrown 'Cannot release ownership as memory is not owned' error"
+}
+checkCount 1
+kin -delete
+checkCount 0
+
+KlassInheritance kini "KlassInheritanceInput"
+checkCount 1
+set s [takeKlassUniquePtr kini]
+checkCount 0
+if {[kini cget -thisown]} {
+  error "thisown should be false"
+}
+if {$s != "KlassInheritanceInput"} {
+  error "Incorrect string: $s"
+}
+if {![is_nullptr kini]} {
+  error "is_nullptr failed"
+}
+kini -delete # Should not fail, even though already deleted
+checkCount 0
+
+takeKlassUniquePtr "NULL"
+takeKlassUniquePtr [make_null]
+checkCount 0
+
+# overloaded parameters
+if {[overloadTest] != 0} {
+  error "overloadTest failed"
+}
+if {[overloadTest "NULL"] != 1} {
+  error "overloadTest failed"
+}
+if {[overloadTest [Klass k "over"]] != 1} {
+  error "overloadTest failed"
+}
+checkCount 0
+
+
+# unique_ptr as output
+set k1 [makeKlassUniquePtr "first"]
+set k2 [makeKlassUniquePtr "second"]
+checkCount 2
+
+$k1 -delete
+checkCount 1
+
+if {[$k2 getLabel] != "second"} {
+  error "wrong object label"
+}
+
+$k2 -delete
+checkCount 0
+
+if {[makeNullUniquePtr] != "NULL"} {
+  error "null failure"
+}
diff --git a/Examples/test-suite/tcl/cpp11_strongly_typed_enumerations_runme.tcl b/Examples/test-suite/tcl/cpp11_strongly_typed_enumerations_runme.tcl
index 5132101..8a36bb9 100644
--- a/Examples/test-suite/tcl/cpp11_strongly_typed_enumerations_runme.tcl
+++ b/Examples/test-suite/tcl/cpp11_strongly_typed_enumerations_runme.tcl
@@ -1,5 +1,5 @@
 
-if [ catch { load ./cpp11_strongly_typed_enumerations[info sharedlibextension] cpp11_strongly_typed_enumerations} err_msg ] {
+if [ catch { load ./cpp11_strongly_typed_enumerations[info sharedlibextension] Cpp11_strongly_typed_enumerations} err_msg ] {
 	puts stderr "Could not load shared object:\n$err_msg"
 }
 
diff --git a/Examples/test-suite/tcl/cpp17_string_view_runme.tcl b/Examples/test-suite/tcl/cpp17_string_view_runme.tcl
new file mode 100644
index 0000000..9be2a43
--- /dev/null
+++ b/Examples/test-suite/tcl/cpp17_string_view_runme.tcl
@@ -0,0 +1,46 @@
+
+if [ catch { load ./cpp17_string_view[info sharedlibextension] Cpp17_string_view} err_msg ] {
+	puts stderr "Could not load shared object:\n$err_msg"
+}
+
+test_value "Fee"
+
+if {[test_value "Fi"] != "Fi"} { error "bad test_value"}
+
+test_const_reference "Fo"
+
+if {[test_const_reference "Fum"] != "Fum"} { error "bad test_const_reference"}
+
+set stringPtr [test_pointer_out]
+
+test_pointer $stringPtr
+
+set stringPtr [test_const_pointer_out]
+
+test_const_pointer $stringPtr
+
+set stringPtr [test_reference_out]
+
+test_reference $stringPtr
+
+# Global variables
+if {$ConstGlobalString != "const global string"} { error "bad ConstGlobalString_get"}
+
+# Member variables
+Structure s
+if {[s cget -ConstMemberString] != "const member string"} { error "bad ConstMemberString"}
+
+if {$Structure_ConstStaticMemberString != "const static member string"} { error "bad ConstStaticMemberString"}
+
+test_const_reference_returning_void "foo"
+
+if {[stdstringview_empty] != ""} { error "bad stdstringview_empty test" }
+if {[c_empty] != ""} { error "bad c_empty test" }
+# FIXME: [c_null] seems to give an empty string currently, but Tcl doesn't have
+# a real NULL value and the string "NULL" we used for elsewhere for NULL
+# pointers doesn't work well here as it's indistinguishable from the string
+# "NULL" being returned.
+#if {[c_null] != "NULL"} { error "bad c_null test" }
+#if {[get_null [c_null]] != "NULL"} { error "bad get_null c_null test" }
+if {[get_null [c_empty]] != "non-null"} { error "bad get_null c_empty test" }
+if {[get_null [stdstringview_empty]] != "non-null"} { error "bad get_null stdstringview_empty test" }
diff --git a/Examples/test-suite/tcl/disown_runme.tcl b/Examples/test-suite/tcl/disown_runme.tcl
index d6647c0..79feefd 100644
--- a/Examples/test-suite/tcl/disown_runme.tcl
+++ b/Examples/test-suite/tcl/disown_runme.tcl
@@ -2,7 +2,7 @@
 # This is the union runtime testcase. It ensures that values within a 
 # union embedded within a struct can be set and read correctly.
 
-if [ catch { load ./disown[info sharedlibextension] disown} err_msg ] {
+if [ catch { load ./disown[info sharedlibextension] Disown} err_msg ] {
 	puts stderr "Could not load shared object:\n$err_msg"
 }
 
diff --git a/Examples/test-suite/tcl/enum_thorough_runme.tcl b/Examples/test-suite/tcl/enum_thorough_runme.tcl
index d4cc199..731c6e9 100644
--- a/Examples/test-suite/tcl/enum_thorough_runme.tcl
+++ b/Examples/test-suite/tcl/enum_thorough_runme.tcl
@@ -1,5 +1,5 @@
 
-if [ catch { load ./enum_thorough[info sharedlibextension] enum_thorough} err_msg ] {
+if [ catch { load ./enum_thorough[info sharedlibextension] Enum_thorough} err_msg ] {
 	puts stderr "Could not load shared object:\n$err_msg"
 }
 
diff --git a/Examples/test-suite/tcl/import_nomodule_runme.tcl b/Examples/test-suite/tcl/import_nomodule_runme.tcl
index ead6c3f..af778c6 100644
--- a/Examples/test-suite/tcl/import_nomodule_runme.tcl
+++ b/Examples/test-suite/tcl/import_nomodule_runme.tcl
@@ -1,4 +1,4 @@
 
-if [ catch { load ./import_nomodule[info sharedlibextension] import_nomodule} err_msg ] {
+if [ catch { load ./import_nomodule[info sharedlibextension] Import_nomodule} err_msg ] {
 	puts stderr "Could not load shared object:\n$err_msg"
 }
diff --git a/Examples/test-suite/tcl/imports_runme.tcl b/Examples/test-suite/tcl/imports_runme.tcl
index 6b2e77b..cd5629c 100644
--- a/Examples/test-suite/tcl/imports_runme.tcl
+++ b/Examples/test-suite/tcl/imports_runme.tcl
@@ -1,11 +1,11 @@
 
 # This is the imports runtime testcase. 
 proc import {} {
-    if [ catch { load ./imports_b[info sharedlibextension] imports_b} err_msg ] {
+    if [ catch { load ./imports_b[info sharedlibextension] Imports_b} err_msg ] {
             puts stderr "Could not load shared object:\n$err_msg"
             exit 1
     }
-    if [ catch { load ./imports_a[info sharedlibextension] imports_a} err_msg ] {
+    if [ catch { load ./imports_a[info sharedlibextension] Imports_a} err_msg ] {
             puts stderr "Could not load shared object:\n$err_msg"
             exit 1
     }
@@ -15,8 +15,8 @@
 
 set x [new_B]
 A_hello $x
-if [ catch { $x nonexistant } ] {
+if [ catch { $x nonexistent } ] {
 } else {
-  puts stderr "nonexistant method did not throw exception\n"
+  puts stderr "nonexistent method did not throw exception\n"
   exit 1
 }
diff --git a/Examples/test-suite/tcl/integers_runme.tcl b/Examples/test-suite/tcl/integers_runme.tcl
new file mode 100644
index 0000000..b06adce
--- /dev/null
+++ b/Examples/test-suite/tcl/integers_runme.tcl
@@ -0,0 +1,26 @@
+if [ catch { load ./integers[info sharedlibextension] Integers} err_msg ] {
+	puts stderr "Could not load shared object:\n$err_msg"
+}
+
+# 32-bit long max
+set val 2147483647
+if {[signed_long_identity $val] != $val} {
+    puts stderr "Runtime test 1 failed"
+    exit 1
+}
+
+set val 3902408827
+if {[unsigned_long_identity $val] != $val} {
+    puts stderr "Runtime test 2 failed"
+    exit 1
+}
+
+if {[signed_long_long_identity $val] != $val} {
+    puts stderr "Runtime test 3 failed"
+    exit 1
+}
+
+if {[unsigned_long_long_identity $val] != $val} {
+    puts stderr "Runtime test 4 failed"
+    exit 1
+}
diff --git a/Examples/test-suite/tcl/li_carrays_runme.tcl b/Examples/test-suite/tcl/li_carrays_runme.tcl
new file mode 100644
index 0000000..5d68fdb
--- /dev/null
+++ b/Examples/test-suite/tcl/li_carrays_runme.tcl
@@ -0,0 +1,71 @@
+
+if [ catch { load ./li_carrays[info sharedlibextension] Li_carrays} err_msg ] {
+	puts stderr "Could not load shared object:\n$err_msg"
+}
+
+
+# Testing for %array_functions(int,intArray)
+set ary [new_intArray 2]
+intArray_setitem $ary 0 0
+intArray_setitem $ary 1 1
+if {[intArray_getitem $ary 0] != 0} {
+    error "wrong value index 0"
+}
+if {[intArray_getitem $ary 1] != 1} {
+    error "wrong value index 1"
+}
+delete_intArray $ary
+
+# Testing for %array_class(double, doubleArray)
+doubleArray d 10
+doubleArray_setitem d 0 7
+doubleArray_setitem d 5 [expr [doubleArray_getitem d 0] + 3]
+if {[expr [doubleArray_getitem d 5] + [doubleArray_getitem d 0]] != 17} {
+    error "wrong value doubleArray"
+}
+
+
+# Tcl Array wrapper based on Tcl.html documentation "Building new kinds of Tcl interfaces (in Tcl)"
+proc Array {type size} {
+    set ptr [new_$type $size]
+    set code {
+        set method [lindex $args 0]
+        set parms [concat $ptr [lrange $args 1 end]]
+        switch $method {
+            get {return [eval "${type}_getitem $parms"]}
+            set {return [eval "${type}_setitem $parms"]}
+            delete {eval "delete_$type $ptr; rename $ptr {}"}
+        }
+    }
+    # Create a procedure
+    uplevel "proc $ptr args {set ptr $ptr; set type $type;$code}"
+    return $ptr
+}
+
+# The memory handling for Tcl is not working properly. 
+# %newobject (not used here though) is crippled and does not take ownership of the underlying
+# pointer - see SWIGTYPE * typemap overrides in tcltypemaps.swg.
+#
+# As soon as a is set below, it gets deleted by the interpreter, even though $a is used a
+# few lines later. The interpreter seems to replace the command object created in
+# SWIG_Tcl_NewInstanceObj some sort of generic one.
+# The underlying C array is not actually deleted (it leaks) when $a is deleted, so the code
+# using $a does actually seem to work.
+
+set a [Array doubleArray 100]              ;# Create a double [100]
+for {set i 0} {$i < 100} {incr i 1} {      ;# Clear the array
+        $a set $i 0.0
+}
+
+$a set 3 3.1455                            ;# Set an individual element
+set b [$a get 10]                          ;# Retrieve an element
+
+set ia [Array intArray 50]                 ;# Create an int[50]
+for {set i 0} {$i < 50} {incr i 1} {       ;# Clear it
+        $ia set $i 0
+}
+$ia set 3 7                                ;# Set an individual element
+set ib [$ia get 10]                        ;# Get an individual element
+
+$a delete                                  ;# Destroy a
+$ia delete                                 ;# Destroy ia
diff --git a/Examples/test-suite/tcl/li_constraints_runme.tcl b/Examples/test-suite/tcl/li_constraints_runme.tcl
new file mode 100644
index 0000000..ca7a182
--- /dev/null
+++ b/Examples/test-suite/tcl/li_constraints_runme.tcl
@@ -0,0 +1,51 @@
+if [ catch { load ./li_constraints[info sharedlibextension] Li_constraints} err_msg ] {
+	puts stderr "Could not load shared object:\n$err_msg"
+}
+
+proc check_double {except fn f val} {
+	set actual [ catch { $fn $val } err_msg ]
+	if { $actual == 0 } {
+		if { $except != 0 } {
+			error "function '$f' with $val should perform an exception"
+		}
+	} else {
+		if { $except == 0 } {
+			error "function '$f' with $val should not perform an exception"
+		} elseif { [ string equal $err_msg "ValueError Expected a $f value." ] != 1 } {
+			error "function '$f' with $val should perform a proper exception"
+		}
+	}
+}
+
+proc nonnegative {val } { test_nonnegative $val }
+check_double 0 nonnegative "non-negative" 10
+check_double 0 nonnegative "non-negative" 0
+check_double 1 nonnegative "non-negative" -10
+
+proc nonpositive {val } { test_nonpositive $val }
+check_double 1 nonpositive "non-positive" 10
+check_double 0 nonpositive "non-positive" 0
+check_double 0 nonpositive "non-positive" -10
+
+proc positive {val } { test_positive $val }
+check_double 0 positive "positive" 10
+check_double 1 positive "positive" 0
+check_double 1 positive "positive" -10
+
+proc negative {val } { test_negative $val }
+check_double 1 negative "negative" 10
+check_double 1 negative "negative" 0
+check_double 0 negative "negative" -10
+
+proc nonzero {val } { test_nonzero $val }
+check_double 0 nonzero "nonzero" 10
+check_double 1 nonzero "nonzero" 0
+check_double 0 nonzero "nonzero" -10
+
+set actual [ catch { test_nonnull NULL } err_msg ]
+if { ($actual != 1) ||
+     ([ string equal $err_msg "ValueError Received a NULL pointer." ] != 1) } {
+	error "Test 'test_nonnull' with null value fail"
+}
+set nonnull [ get_nonnull ]
+test_nonnull $nonnull
diff --git a/Examples/test-suite/tcl/li_std_auto_ptr_runme.tcl b/Examples/test-suite/tcl/li_std_auto_ptr_runme.tcl
new file mode 100644
index 0000000..8156cb7
--- /dev/null
+++ b/Examples/test-suite/tcl/li_std_auto_ptr_runme.tcl
@@ -0,0 +1,134 @@
+
+if [ catch { load ./li_std_auto_ptr[info sharedlibextension] Li_std_auto_ptr} err_msg ] {
+	puts stderr "Could not load shared object:\n$err_msg"
+}
+
+
+proc checkCount {expected_count} {
+  set actual_count [Klass_getTotal_count]
+  if {$actual_count != $expected_count} {
+    error "Counts incorrect, expected: $expected_count actual: $actual_count"
+  }
+}
+
+################################# Tcl pointer recycling bug start
+# Not copied from cpp11_std_unique_ptr_runme.tcl
+################################# Tcl pointer recycling bug end
+
+# Test raw pointer handling involving virtual inheritance
+KlassInheritance kini "KlassInheritanceInput"
+checkCount 1
+set s [useKlassRawPtr kini]
+kini -delete
+checkCount 0
+
+
+# auto_ptr as input
+Klass kin "KlassInput"
+checkCount 1
+set s [takeKlassAutoPtr kin]
+checkCount 0
+if {[kin cget -thisown]} {
+  error "thisown should be false"
+}
+if {$s != "KlassInput"} {
+  error "Incorrect string: $s"
+}
+if {![is_nullptr kin]} {
+  error "is_nullptr failed"
+}
+kin -delete # Should not fail, even though already deleted
+checkCount 0
+
+Klass kin "KlassInput"
+checkCount 1
+set s [takeKlassAutoPtr kin]
+checkCount 0
+if {[kin cget -thisown]} {
+  error "thisown should be false"
+}
+if {$s != "KlassInput"} {
+  error "Incorrect string: $s"
+}
+if {![is_nullptr kin]} {
+  error "is_nullptr failed"
+}
+set exception_thrown 0
+if [ catch { set s [takeKlassAutoPtr kin] } e ] {
+  if {[string first "cannot release ownership as memory is not owned" $e] == -1} {
+    error "incorrect exception message: $e"
+  }
+  set exception_thrown 1
+}
+if {!$exception_thrown} {
+  error "double usage of takeKlassAutoPtr should have been an error"
+}
+kin -delete # Should not fail, even though already deleted
+checkCount 0
+
+Klass kin "KlassInput"
+set exception_thrown 0
+set notowned [get_not_owned_ptr kin]
+if [ catch {
+  takeKlassAutoPtr notowned
+} ] {
+  set exception_thrown 1
+}
+if {!$exception_thrown} {
+  error "Should have thrown 'Cannot release ownership as memory is not owned' error"
+}
+checkCount 1
+kin -delete
+checkCount 0
+
+KlassInheritance kini "KlassInheritanceInput"
+checkCount 1
+set s [takeKlassAutoPtr kini]
+checkCount 0
+if {[kini cget -thisown]} {
+  error "thisown should be false"
+}
+if {$s != "KlassInheritanceInput"} {
+  error "Incorrect string: $s"
+}
+if {![is_nullptr kini]} {
+  error "is_nullptr failed"
+}
+kini -delete # Should not fail, even though already deleted
+checkCount 0
+
+takeKlassAutoPtr "NULL"
+takeKlassAutoPtr [make_null]
+checkCount 0
+
+# overloaded parameters
+if {[overloadTest] != 0} {
+  error "overloadTest failed"
+}
+if {[overloadTest "NULL"] != 1} {
+  error "overloadTest failed"
+}
+if {[overloadTest [Klass k "over"]] != 1} {
+  error "overloadTest failed"
+}
+checkCount 0
+
+
+# auto_ptr as output
+set k1 [makeKlassAutoPtr "first"]
+set k2 [makeKlassAutoPtr "second"]
+checkCount 2
+
+$k1 -delete
+checkCount 1
+
+if {[$k2 getLabel] != "second"} {
+  error "wrong object label"
+}
+
+$k2 -delete
+checkCount 0
+
+if {[makeNullAutoPtr] != "NULL"} {
+  error "null failure"
+}
diff --git a/Examples/test-suite/tcl/li_std_string_runme.tcl b/Examples/test-suite/tcl/li_std_string_runme.tcl
index 333c1f1..8f4cf4d 100644
--- a/Examples/test-suite/tcl/li_std_string_runme.tcl
+++ b/Examples/test-suite/tcl/li_std_string_runme.tcl
@@ -1,15 +1,38 @@
 
-if [ catch { load ./li_std_string[info sharedlibextension] li_std_string} err_msg ] {
+if [ catch { load ./li_std_string[info sharedlibextension] Li_std_string} err_msg ] {
 	puts stderr "Could not load shared object:\n$err_msg"
 }
 
+test_value "Fee"
 
-Structure s 
+if {[test_value "Fi"] != "Fi"} { error "bad test_value"}
+
+test_const_reference "Fo"
+
+if {[test_const_reference "Fum"] != "Fum"} { error "bad test_const_reference"}
+
+set stringPtr [test_pointer_out]
+
+test_pointer $stringPtr
+
+set stringPtr [test_const_pointer_out]
+
+test_const_pointer $stringPtr
+
+set stringPtr [test_reference_out]
+
+test_reference $stringPtr
+
+# Global variables
+if {$ConstGlobalString != "const global string"} { error "bad ConstGlobalString_get"}
+
+# Member variables
+Structure s
 if {"[s cget -MemberString2]" != "member string 2"} { error "bad string map"}
 s configure -MemberString2 "hello"
 if {"[s cget -MemberString2]" != "hello"} { error "bad string map"}
 
-if {"[s cget -ConstMemberString]" != "const member string"} { error "bad string map"}
+if {[s cget -ConstMemberString] != "const member string"} { error "bad ConstMemberString"}
 
 if {"$GlobalString2" != "global string 2"} { error "bad string map"}
 if {"$Structure_StaticMemberString2" != "static member string 2"} { error "bad string map"}
@@ -19,3 +42,18 @@
 
 set Structure_StaticMemberString2 "hello"
 if {"$Structure_StaticMemberString2" != "hello"} { error "bad string map"}
+
+if {$Structure_ConstStaticMemberString != "const static member string"} { error "bad ConstStaticMemberString"}
+
+test_const_reference_returning_void "foo"
+
+if {[stdstring_empty] != ""} { error "bad stdstring_empty test" }
+if {[c_empty] != ""} { error "bad c_empty test" }
+# FIXME: [c_null] seems to give an empty string currently, but Tcl doesn't have
+# a real NULL value and the string "NULL" we used for elsewhere for NULL
+# pointers doesn't work well here as it's indistinguishable from the string
+# "NULL" being returned.
+#if {[c_null] != "NULL"} { error "bad c_null test" }
+#if {[get_null [c_null]] != "NULL"} { error "bad get_null c_null test" }
+if {[get_null [c_empty]] != "non-null"} { error "bad get_null c_empty test" }
+if {[get_null [stdstring_empty]] != "non-null"} { error "bad get_null stdstring_empty test" }
diff --git a/Examples/test-suite/tcl/li_std_vector_runme.tcl b/Examples/test-suite/tcl/li_std_vector_runme.tcl
new file mode 100644
index 0000000..24aa9aa
--- /dev/null
+++ b/Examples/test-suite/tcl/li_std_vector_runme.tcl
@@ -0,0 +1,15 @@
+
+if [ catch { load ./li_std_vector[info sharedlibextension] Li_std_vector} err_msg ] {
+	puts stderr "Could not load shared object:\n$err_msg"
+}
+
+# Regression test for bug fixed in SWIG 4.1.0.
+if {[sum []] != 0} { error "bad vector sum" }
+
+IntPtrVector v 6
+if {[v empty] != 0} { error "bad std::vector::empty()" }
+if {[v size] != 6} { error "bad std::vector::size()" }
+# Test that calling get succeeds
+v get 0
+v pop
+if {[v size] != 5} { error "bad std::vector::size()" }
diff --git a/Examples/test-suite/tcl/member_pointer_runme.tcl b/Examples/test-suite/tcl/member_pointer_runme.tcl
index e4d0991..7ba5321 100644
--- a/Examples/test-suite/tcl/member_pointer_runme.tcl
+++ b/Examples/test-suite/tcl/member_pointer_runme.tcl
@@ -1,6 +1,6 @@
 # Example using pointers to member functions
 
-if [ catch { load ./member_pointer[info sharedlibextension] member_pointer} err_msg ] {
+if [ catch { load ./member_pointer[info sharedlibextension] Member_pointer} err_msg ] {
 	puts stderr "Could not load shared object:\n$err_msg"
 }
 
diff --git a/Examples/test-suite/tcl/newobject1_runme.tcl b/Examples/test-suite/tcl/newobject1_runme.tcl
index da6ff66..707cc7e 100644
--- a/Examples/test-suite/tcl/newobject1_runme.tcl
+++ b/Examples/test-suite/tcl/newobject1_runme.tcl
@@ -1,4 +1,4 @@
-if [ catch { load ./newobject1[info sharedlibextension] newobject1} err_msg ] {
+if [ catch { load ./newobject1[info sharedlibextension] Newobject1} err_msg ] {
 	puts stderr "Could not load shared object:\n$err_msg"
 }
 
diff --git a/Examples/test-suite/tcl/newobject2_runme.tcl b/Examples/test-suite/tcl/newobject2_runme.tcl
index 18d23af..330a0c4 100644
--- a/Examples/test-suite/tcl/newobject2_runme.tcl
+++ b/Examples/test-suite/tcl/newobject2_runme.tcl
@@ -1,4 +1,4 @@
-if [ catch { load ./newobject2[info sharedlibextension] newobject2} err_msg ] {
+if [ catch { load ./newobject2[info sharedlibextension] Newobject2} err_msg ] {
 	puts stderr "Could not load shared object:\n$err_msg"
 }
 
diff --git a/Examples/test-suite/tcl/null_pointer_runme.tcl b/Examples/test-suite/tcl/null_pointer_runme.tcl
index 7ed87c1..8c77a9e 100644
--- a/Examples/test-suite/tcl/null_pointer_runme.tcl
+++ b/Examples/test-suite/tcl/null_pointer_runme.tcl
@@ -1,4 +1,4 @@
-if [ catch { load ./null_pointer[info sharedlibextension] null_pointer} err_msg ] {
+if [ catch { load ./null_pointer[info sharedlibextension] Null_pointer} err_msg ] {
 	puts stderr "Could not load shared object:\n$err_msg"
 }
 
diff --git a/Examples/test-suite/tcl/overload_copy_runme.tcl b/Examples/test-suite/tcl/overload_copy_runme.tcl
index 46d7058..973ae14 100644
--- a/Examples/test-suite/tcl/overload_copy_runme.tcl
+++ b/Examples/test-suite/tcl/overload_copy_runme.tcl
@@ -1,5 +1,5 @@
 
-if [ catch { load ./overload_copy[info sharedlibextension] overload_copy} err_msg ] {
+if [ catch { load ./overload_copy[info sharedlibextension] Overload_copy} err_msg ] {
 	puts stderr "Could not load shared object:\n$err_msg"
 }
 
diff --git a/Examples/test-suite/tcl/overload_null_runme.tcl b/Examples/test-suite/tcl/overload_null_runme.tcl
index 3716612..314036e 100644
--- a/Examples/test-suite/tcl/overload_null_runme.tcl
+++ b/Examples/test-suite/tcl/overload_null_runme.tcl
@@ -1,5 +1,5 @@
 
-if [ catch { load ./overload_null[info sharedlibextension] overload_null} err_msg ] {
+if [ catch { load ./overload_null[info sharedlibextension] Overload_null} err_msg ] {
 	puts stderr "Could not load shared object:\n$err_msg"
 }
 
@@ -40,13 +40,13 @@
 check "testX" 15 [$o byval2cpr "NULL"]
 check "testX" 16 [$o byval2cpr $x]
 
-# forward class declaration
-check "testX" 17 [$o byval1forwardptr $x]
-check "testX" 18 [$o byval1forwardptr "NULL"]
+# fwd class declaration
+check "testX" 17 [$o byval1fwdptr $x]
+check "testX" 18 [$o byval1fwdptr "NULL"]
 
-check "testX" 19 [$o byval2forwardptr "NULL"]
-check "testX" 20 [$o byval2forwardptr $x]
+check "testX" 19 [$o byval2fwdptr "NULL"]
+check "testX" 20 [$o byval2fwdptr $x]
 
-check "testX" 21 [$o byval1forwardref $x]
+check "testX" 21 [$o byval1fwdref $x]
 
-check "testX" 22 [$o byval2forwardref $x]
+check "testX" 22 [$o byval2fwdref $x]
diff --git a/Examples/test-suite/tcl/overload_simple_runme.tcl b/Examples/test-suite/tcl/overload_simple_runme.tcl
index 6b65ccc..add4248 100644
--- a/Examples/test-suite/tcl/overload_simple_runme.tcl
+++ b/Examples/test-suite/tcl/overload_simple_runme.tcl
@@ -1,5 +1,5 @@
 
-if [ catch { load ./overload_simple[info sharedlibextension] overload_simple} err_msg ] {
+if [ catch { load ./overload_simple[info sharedlibextension] Overload_simple} err_msg ] {
 	puts stderr "Could not load shared object:\n$err_msg"
 }
 
diff --git a/Examples/test-suite/tcl/primitive_ref_runme.tcl b/Examples/test-suite/tcl/primitive_ref_runme.tcl
index ab4e444..53faee5 100644
--- a/Examples/test-suite/tcl/primitive_ref_runme.tcl
+++ b/Examples/test-suite/tcl/primitive_ref_runme.tcl
@@ -1,7 +1,7 @@
 # Primitive ref testcase.  Tests to make sure references to 
 # primitive types are passed by value
 
-if [ catch { load ./primitive_ref[info sharedlibextension] primitive_ref} err_msg ] {
+if [ catch { load ./primitive_ref[info sharedlibextension] Primitive_ref} err_msg ] {
 	puts stderr "Could not load shared object:\n$err_msg"
 }
 
diff --git a/Examples/test-suite/tcl/primitive_types_runme.tcl b/Examples/test-suite/tcl/primitive_types_runme.tcl
index fa4c46b..444062f 100644
--- a/Examples/test-suite/tcl/primitive_types_runme.tcl
+++ b/Examples/test-suite/tcl/primitive_types_runme.tcl
@@ -1,5 +1,5 @@
 
-if [ catch { load ./primitive_types[info sharedlibextension] primitive_types} err_msg ] {
+if [ catch { load ./primitive_types[info sharedlibextension] Primitive_types} err_msg ] {
 	puts stderr "Could not load shared object:\n$err_msg"
 }
 
diff --git a/Examples/test-suite/tcl/profiletest_runme.tcl b/Examples/test-suite/tcl/profiletest_runme.tcl
index 087eea4..22d91ec 100644
--- a/Examples/test-suite/tcl/profiletest_runme.tcl
+++ b/Examples/test-suite/tcl/profiletest_runme.tcl
@@ -1,4 +1,4 @@
-catch { load ./profiletest[info sharedlibextension] profiletest}
+catch { load ./profiletest[info sharedlibextension] Profiletest}
 
 set  a [new_A]
 set  b [new_B]
diff --git a/Examples/test-suite/tcl/reference_global_vars_runme.tcl b/Examples/test-suite/tcl/reference_global_vars_runme.tcl
index bfd31a9..b471e37 100644
--- a/Examples/test-suite/tcl/reference_global_vars_runme.tcl
+++ b/Examples/test-suite/tcl/reference_global_vars_runme.tcl
@@ -1,4 +1,4 @@
-if [ catch { load ./reference_global_vars[info sharedlibextension] reference_global_vars} err_msg ] {
+if [ catch { load ./reference_global_vars[info sharedlibextension] Reference_global_vars} err_msg ] {
 	puts stderr "Could not load shared object:\n$err_msg"
 }
 
diff --git a/Examples/test-suite/tcl/union_parameter_runme.tcl b/Examples/test-suite/tcl/union_parameter_runme.tcl
index fb3e092..d6a324e 100644
--- a/Examples/test-suite/tcl/union_parameter_runme.tcl
+++ b/Examples/test-suite/tcl/union_parameter_runme.tcl
@@ -1,4 +1,4 @@
-if [ catch { load ./union_parameter[info sharedlibextension] union_parameter} err_msg ] {
+if [ catch { load ./union_parameter[info sharedlibextension] Union_parameter} err_msg ] {
         puts stderr "Could not load shared object:\n$err_msg"
 }
 
diff --git a/Examples/test-suite/tcl/unions_runme.tcl b/Examples/test-suite/tcl/unions_runme.tcl
index 8c31095..2723d38 100644
--- a/Examples/test-suite/tcl/unions_runme.tcl
+++ b/Examples/test-suite/tcl/unions_runme.tcl
@@ -2,7 +2,7 @@
 # This is the union runtime testcase. It ensures that values within a 
 # union embedded within a struct can be set and read correctly.
 
-if [ catch { load ./unions[info sharedlibextension] unions} err_msg ] {
+if [ catch { load ./unions[info sharedlibextension] Unions} err_msg ] {
 	puts stderr "Could not load shared object:\n$err_msg"
 }
 
diff --git a/Examples/test-suite/template_arg_replace.i b/Examples/test-suite/template_arg_replace.i
index 25274c9..d887c26 100644
--- a/Examples/test-suite/template_arg_replace.i
+++ b/Examples/test-suite/template_arg_replace.i
@@ -6,7 +6,7 @@
 
 template <typename T, int r, int c> class test_Matrix { 
 public: 
- void Func(const test_Matrix<T,r,c> &m) { }; 
+ void Func(const test_Matrix<T,r,c> &m) { }
 }; 
 %} 
 
diff --git a/Examples/test-suite/template_class_reuse_name.i b/Examples/test-suite/template_class_reuse_name.i
index 818816d..03c5c8d 100644
--- a/Examples/test-suite/template_class_reuse_name.i
+++ b/Examples/test-suite/template_class_reuse_name.i
@@ -97,6 +97,7 @@
 
 
 %warnfilter(SWIGWARN_PARSE_REDEFINED) Space::Duplicate2;
+%warnfilter(SWIGWARN_TYPE_REDEFINED) Space::Duplicate2;
 %inline %{
 namespace Space {
   template <int I> struct Duplicate2 { void n(){}; };
@@ -107,6 +108,7 @@
 
 
 %warnfilter(SWIGWARN_PARSE_REDEFINED) Space::Duplicate3;
+%warnfilter(SWIGWARN_TYPE_REDEFINED) Space::Duplicate3;
 %inline %{
 namespace Space {
   template <int I> struct Duplicate3 { void n(){}; };
@@ -123,6 +125,7 @@
 %}
 
 %warnfilter(SWIGWARN_PARSE_REDEFINED) Space::Duplicate4;
+%warnfilter(SWIGWARN_TYPE_REDEFINED) Space::Duplicate4<0>;
 namespace Space {
   template <bool B> struct Duplicate4 { void ff(){}; };
   template <bool B> struct Duplicate4 { void ff(){}; };
diff --git a/Examples/test-suite/template_construct.i b/Examples/test-suite/template_construct.i
index a6e8c3c..7949523 100644
--- a/Examples/test-suite/template_construct.i
+++ b/Examples/test-suite/template_construct.i
@@ -1,15 +1,43 @@
 %module template_construct
 
-// Tests templates to make sure an extra <> in a constructor is ok.
+// Tests templates to make sure an extra <> in a constructor and destructor is ok.
 
 %inline %{
-template<class T> 
+template<class T>
 class Foo {
     T y;
 public:
+#ifdef SWIG
     Foo<T>(T x) : y(x) { }
+    ~Foo<T>() {}
+#else
+    // Modern compilers (C++20) reject this, so feed the compiler the corrected version
+    Foo(T x) : y(x) { }
+    ~Foo() {}
+#endif
 };
 
 %}
 
 %template(Foo_int) Foo<int>;
+
+%inline %{
+template<>
+class Foo<short> {
+    short y;
+public:
+#ifdef SWIG
+    Foo<short>(short x) : y(x) { }
+    Foo<short>() : y(0) { }
+    virtual ~Foo<short>() {}
+#else
+    // Modern compilers (C++20) reject this, so feed the compiler the corrected version
+    // version.
+    Foo(short x) : y(x) { }
+    Foo() : y(0) { }
+    virtual ~Foo() {}
+#endif
+};
+%}
+
+%template(Foo_short) Foo<short>;
diff --git a/Examples/test-suite/template_default.i b/Examples/test-suite/template_default.i
index d771ef0..83ffd54 100644
--- a/Examples/test-suite/template_default.i
+++ b/Examples/test-suite/template_default.i
@@ -196,7 +196,6 @@
 %}
 
 
-#ifndef SWIGCHICKEN
 %include std_vector.i
 
 %{
@@ -211,6 +210,3 @@
 
 %constant void (*Bf)(std::vector<double> *p = 0) = g; 
 %constant void (*Cf)(double = 0) = q; 
-
-
-#endif
diff --git a/Examples/test-suite/template_default2.i b/Examples/test-suite/template_default2.i
index 9ba0455..1a22410 100644
--- a/Examples/test-suite/template_default2.i
+++ b/Examples/test-suite/template_default2.i
@@ -17,6 +17,16 @@
       static const Polarization pmode = UnaryPolarization;
     };
  
+    struct traits2
+    {
+      static const Polarization pmode = UnaryPolarization;
+    };
+ 
+    struct traits3
+    {
+      static const Polarization pmode = UnaryPolarization;
+    };
+ 
     template <class C,
           Polarization P = C::pmode,
           class Base = Interface_tpl<P> >   // **** problem here *****
@@ -37,8 +47,8 @@
                    Interface_tpl<UnaryPolarization> >;
  
    // These don't
-  %template(Module_UP2) Module<traits, UnaryPolarization>;
-  %template(Module_UP3) Module<traits>;
+  %template(Module_UP2) Module<traits2, UnaryPolarization>;
+  %template(Module_UP3) Module<traits3>;
 }
  
                                                        
diff --git a/Examples/test-suite/template_default_vw.i b/Examples/test-suite/template_default_vw.i
index 429ed30..ed20712 100644
--- a/Examples/test-suite/template_default_vw.i
+++ b/Examples/test-suite/template_default_vw.i
@@ -13,7 +13,7 @@
 typedef Handle<SomeClass> hSomeClass; 
 class AnotherClass { 
 public: 
-  void someFunc( hSomeClass a = hSomeClass() ) { }; 
+  void someFunc( hSomeClass a = hSomeClass() ) { }
 }; 
 
 %}
diff --git a/Examples/test-suite/template_duplicate.i b/Examples/test-suite/template_duplicate.i
new file mode 100644
index 0000000..a9860f0
--- /dev/null
+++ b/Examples/test-suite/template_duplicate.i
@@ -0,0 +1,21 @@
+%module template_duplicate
+
+%include <std_vector.i>
+
+%warnfilter(SWIGWARN_TYPE_REDEFINED) std::vector<boolean_T>;
+%warnfilter(SWIGWARN_TYPE_REDEFINED) std::vector<uint8_T>;
+
+%inline %{
+typedef unsigned char uint8_T;
+typedef unsigned char boolean_T;
+%}
+
+%template(std_vector_boolean_type) std::vector<boolean_T>;
+%template(std_vector_boolean_type_duplicate) std::vector<boolean_T>;
+%template(std_vector_uint8_type) std::vector<uint8_T>;
+
+namespace std {
+%template(std_vector_boolean_type_again) vector<boolean_T>;
+%template(std_vector_uint8_type_again) vector<uint8_T>;
+%template(std_vector_unsigned_char) vector<unsigned char>;
+}
diff --git a/Examples/test-suite/template_expr.i b/Examples/test-suite/template_expr.i
index a1bb7ef..98e66e3 100644
--- a/Examples/test-suite/template_expr.i
+++ b/Examples/test-suite/template_expr.i
@@ -2,8 +2,11 @@
 
 // bug #925555
 %inline %{
+struct ThisType {};
+template<int _size, int _stride, class __elementTypeSequence, class __dataPtrType>
+  class vctFixedLengthConstSequenceBase {};
 
-  template<int __stride, class __elementTypeSequence,
+  template<int _size, int __stride, class __elementTypeSequence,
     class __dataPtrType, class __elementType>
     inline const ThisType & 
     ConcatenationOf(const vctFixedLengthConstSequenceBase<_size - 1,
@@ -30,9 +33,15 @@
 // bug #646275
 
 %inline %{
+struct Ty {};
+template<typename Type, short a> struct Test {};
+template<int rank, typename X, typename Type> struct CondRetType {
+  typedef Type TestRm1;
+};
+
     template<typename Type, short Rank>
-	typedef typename CondRetType< Rank!=1,
-		Test<Type,Rank-1>, Type>::TestRm1 TestRm1;
+	void Func(typename CondRetType< Rank!=1,
+		Test<Type,Rank-1>, Type>::TestRm1) {}
 %}
 
 
diff --git a/Examples/test-suite/template_function_parm.i b/Examples/test-suite/template_function_parm.i
new file mode 100644
index 0000000..3dc011b
--- /dev/null
+++ b/Examples/test-suite/template_function_parm.i
@@ -0,0 +1,28 @@
+%module template_function_parm
+
+%include <std_vector.i>
+
+%{
+#include <numeric>
+static int accumulate_integers(std::vector<int> vi) {
+  int sum = std::accumulate(vi.begin(), vi.end(), 0);
+  return sum;
+}
+%}
+
+%inline %{
+template<typename A>
+struct C {
+  int take_function(int fp(std::vector<int>), std::vector<int> v) {
+    return fp(v);
+  }
+};
+%}
+
+%constant int accumulate_integers(std::vector<int>);
+
+%template(VectorInt) std::vector<int>;
+
+// seg fault #983
+%template(MyC) C<int(std::vector<int>)>;
+
diff --git a/Examples/test-suite/template_nested.i b/Examples/test-suite/template_nested.i
index 67668fb..941ec9e 100644
--- a/Examples/test-suite/template_nested.i
+++ b/Examples/test-suite/template_nested.i
@@ -1,11 +1,11 @@
 %module template_nested
 
-#if !defined(SWIGCSHARP) && !defined(SWIGJAVA)
-%feature ("flatnested");
-#endif
-
 // Test nested templates - that is template classes and template methods within a class.
 
+#if !defined(SWIGCSHARP) && !defined(SWIGJAVA)
+#pragma SWIG nowarn=SWIGWARN_PARSE_NAMED_NESTED_CLASS
+#endif
+
 namespace ns {
 template <class T> struct ForwardTemplate;
 }
diff --git a/Examples/test-suite/template_nested_flat.i b/Examples/test-suite/template_nested_flat.i
new file mode 100644
index 0000000..3c1d8bf
--- /dev/null
+++ b/Examples/test-suite/template_nested_flat.i
@@ -0,0 +1,7 @@
+%module template_nested_flat
+
+// Test nested templates ("flatnested" version of template_nested.i)
+
+%feature ("flatnested");
+
+%include "template_nested.i"
diff --git a/Examples/test-suite/template_ns_scope.i b/Examples/test-suite/template_ns_scope.i
index 928f628..57d27a8 100644
--- a/Examples/test-suite/template_ns_scope.i
+++ b/Examples/test-suite/template_ns_scope.i
@@ -10,7 +10,7 @@
     {
     public:
       A() {}    // *** Here, the const. breaks swig ***
-                // *** swig  works without it     ***
+                // *** swig works without it     ***
     };
  
     namespace hello
diff --git a/Examples/test-suite/template_partial_specialization.i b/Examples/test-suite/template_partial_specialization.i
index 9727b52..3452535 100644
--- a/Examples/test-suite/template_partial_specialization.i
+++ b/Examples/test-suite/template_partial_specialization.i
@@ -111,40 +111,14 @@
 
 %template(ThreeParmInt) ThreeParm<int, 0, 0>;
 
-#if 0
-// TODO fix:
 %inline %{
-//namespace S {
+namespace S {
   template<typename T> struct X      { void a() {} };
   template<typename T> struct X<T *> { void b() {} };
-//  template<>           struct X<int *> { void c() {} };
-//}
+  template<>           struct X<int *> { void c() {} };
+}
 %}
 
-namespace AA {  // thinks X is in AA namespace
+namespace S {
   %template(X2) X<int *>;
 };
-#endif
-
-#if 0
-namespace Space {
-}
-template<typename T> struct Vector {
-#ifdef SWIG
-  %template() Space::VectorHelper<T>;
-#endif
-  void gook(T i) {}
-  void geeko(double d) {}
-  void geeky(int d) {}
-};
-/*
-template<typename T> struct Vector<T *> {
-};
-*/
-//}
-%}
-
-%template(VectorIntPtr) Space::Vector<int *>; // should fail as Vector is in global namespace
-// is this a regression - no fails in 1.3.40 too
-// Note problem is removed by removing empty Space namespace!!
-#endif
diff --git a/Examples/test-suite/template_partial_specialization_more.i b/Examples/test-suite/template_partial_specialization_more.i
new file mode 100644
index 0000000..6ec72a8
--- /dev/null
+++ b/Examples/test-suite/template_partial_specialization_more.i
@@ -0,0 +1,142 @@
+%module template_partial_specialization_more
+
+
+// (1) Based on https://stackoverflow.com/questions/9757642/wrapping-specialised-c-template-class-with-swig
+%inline %{
+template<typename V> struct Vect {};
+template<class T, typename TT>
+class Foo {
+public:
+    Foo() {}
+    virtual ~Foo() {}
+    T primary() const { return T(); }
+};
+
+template<class TS, typename TTS>
+class Foo<Vect<TS>, TTS> {
+public:
+    Foo() {}
+    virtual ~Foo() {}
+    TS partially_specialized(TS parmin) const { return parmin; }
+};
+template<>
+class Foo<Vect<double>, double> {
+public:
+    Foo() {}
+    virtual ~Foo() {}
+    double value_fully_specialized(double d) const { return d; }
+};
+template<class T, typename TT>
+class Foo<T*, TT> {
+public:
+    Foo() {}
+    virtual ~Foo() {}
+    int pointer_specialize(T myT) const { return 0; }
+};
+%}
+%template(VectInt) Vect<int>;
+%template(FooVectIntDouble) Foo<Vect<int>, double>; // was failing
+%template(FooShortPtrDouble) Foo<short*, double>;
+%template(FooVectVectInt) Foo<Vect<Vect<int> >, int>; // was failing
+
+
+// (2) Same types in both args
+%inline %{
+template<typename X, typename Y> struct Hey { void primary() {} };
+template<typename T> struct Hey<T, T> { void special_hey() {} };
+%}
+%template(HeyInts) Hey<int, int>; // was failing, was calling primary
+
+
+// (3) Partial specialization using one template parameter instead of two
+%inline %{
+  struct PlainStruct {};
+  template <typename T, typename U> struct XX { void primary() {} };
+  template <typename T> struct XX<T, T &> { void special1() {} };         // r.$1
+  template <typename T> struct XX<T, T const&> { void special2() {} };    // r.q(const).$1
+  template <typename T> struct XX<T, T *const&> { void special3() {} };   // r.q(const).p.$1
+%}
+%template(XX1) XX<int, int&>; // was failing, was calling primary
+%template(XX2) XX<int, int const&>;
+%template(XX3) XX<PlainStruct, PlainStruct *const&>;
+
+
+// (4) Switching parameters around
+%inline %{
+#include <iostream>
+template<typename P1 = int, typename P2 = double> struct Partialler { void primary(P1, P2) {}; };
+template<typename S1, typename S2> struct Partialler<S2, S1*> { void special(S1*, S2, bool) {}; };
+%}
+%template(PartiallerPrimary) Partialler<short, short>;
+%template(PartiallerSpecial) Partialler<int, PlainStruct*>;
+
+
+// (5) Default args used in specialization, like std::list
+%include <std_string.i>
+%inline %{
+template <typename A> struct Allocator {};
+template <typename T, class Alloc = Allocator<T> > struct Lyst { void primary(T, Allocator<T>) {} };
+template <typename TT, class XXAlloc> struct Lyst<TT*, XXAlloc> { void specialized1(TT, XXAlloc) {} };
+template <typename TTT, class YY> struct Lyst<TTT**, Allocator<YY> > { void specialized2(TTT, YY) {} };
+template <typename TTTT> struct Lyst<const TTTT&> { void specialized3(TTTT) {} };
+
+void test_list() {
+    double mydouble = 0;
+    short myshort = 0;
+    Lyst<double>().primary(mydouble, Allocator<double>());
+    Lyst<short, Allocator<short> >().primary(myshort, Allocator<short>());
+
+    PlainStruct ps;
+    int myint = 0;
+    std::string mystring = 0;
+    Lyst<PlainStruct *>().specialized1(ps, Allocator<PlainStruct *>());
+    Lyst<double **>().specialized2(mydouble, (double **)0);
+    Lyst<const int&>().specialized3(myint);
+    // Specifying the default still calls the partially specialized template
+    Lyst<std::string const &, Allocator<std::string const &> >().specialized3(mystring);
+}
+%}
+
+%template(AllocatorDouble) Allocator<double>;
+%template(AllocatorShort) Allocator<short>;
+%template(AllocatorPlainStructPtr) Allocator<PlainStruct *>;
+
+%template(LystDouble) Lyst<double>;
+%template(LystShort) Lyst<short, Allocator<short> >;
+%template(LystPlainStructPtr) Lyst<PlainStruct *>;
+%template(LystDoublePtrPtr) Lyst<double **>; // called specialized1 instead of specialized2
+%template(LystConstIntRef) Lyst<const int&>;
+%template(LystConstStringRef) Lyst<const std::string&, Allocator<const std::string&> >;
+
+%inline %{
+// Both parameters in each of the functions below are the same type
+void UseLystDouble(Lyst<double> a, Lyst<double, Allocator<double> > b) {}
+void UseLystShort(Lyst<short> a, Lyst<short, Allocator<short> > b) {}
+void UseLystPlainStructPtr(Lyst<PlainStruct *> a, Lyst<PlainStruct *, Allocator<PlainStruct *> > b) {}
+void UseLystDoublePtrPtr(Lyst<double **> a, Lyst<double **, Allocator<double **> > b) {}
+void UseLystConstIntRef(Lyst<const int&> a, Lyst<const int&, Allocator<const int&> > b) {}
+void UseLystConstStringRef(Lyst<const std::string&> a, Lyst<const std::string&, Allocator<const std::string&> > b) {}
+%}
+
+// (6) Default args used in specialization, more variations specifying / not specifying default
+%inline %{
+template<typename P, typename Q = int> struct Spec { void spec_primary(P p, Q q) {} };
+template<typename PP> struct Spec<const PP&, int> { void spec_specialized(PP pp) {} };
+%}
+
+%template(SpecDoubleInt) Spec<const double&, int>;
+%template(SpecStringInt) Spec<const std::string&>;
+
+%inline %{
+void UseSpec1(Spec<const double&, int> x, Spec<const double&, int> y) {}
+void UseSpec2(Spec<const std::string&, int> x, Spec<const std::string&, int> y) {}
+void test_spec() {
+  double mydouble = 0.0;
+  Spec<const double&, int>().spec_specialized(mydouble);
+  Spec<const double&>().spec_specialized(mydouble);
+
+  std::string mystring;
+  Spec<const std::string&, int>().spec_specialized(mystring);
+  Spec<const std::string&>().spec_specialized(mystring);
+}
+%}
diff --git a/Examples/test-suite/template_partial_specialization_typedef.i b/Examples/test-suite/template_partial_specialization_typedef.i
index 6f8a115..ad3457a 100644
--- a/Examples/test-suite/template_partial_specialization_typedef.i
+++ b/Examples/test-suite/template_partial_specialization_typedef.i
@@ -30,10 +30,10 @@
 }
 namespace One {
   template <typename T> struct OneParm                  { void a() {} };
-  template <typename T> struct OneParm<T *>             { void b() {} };
-  template <typename T> struct OneParm<T &>             { void c() {} };
-  template <typename T> struct OneParm<T const &>       { void d() {} };
-  template <typename T> struct OneParm<T * const &>     { void e() {} };
+  template <typename T> struct OneParm<T *>             { void b() {} void bb(const T &t) {} };
+  template <typename T> struct OneParm<T &>             { void c() {} void cc(const T &t) {} };
+  template <typename T> struct OneParm<T const &>       { void d() {} void dd(const T &t) {} };
+  template <typename T> struct OneParm<T * const &>     { void e() {} void ee(const T &t) {} };
 
   template <>           struct OneParm<int>             { void f() {} };
   template <>           struct OneParm<int * const &>   { void g() {} };
@@ -90,10 +90,10 @@
 struct Concrete {};
 namespace Two {
   template <typename T1, typename T2> struct TwoParm                          { void a() {} };
-  template <typename T1, typename T2> struct TwoParm<T1 *, T2 *>              { void b() {} };
-  template <typename T1, typename T2> struct TwoParm<T1 *, const T2 *>        { void c() {} };
-  template <typename T1, typename T2> struct TwoParm<const T1 *, const T2 *>  { void d() {} };
-  template <typename T1>              struct TwoParm<T1 *, int *>             { void e() {} };
+  template <typename T1, typename T2> struct TwoParm<T1 *, T2 *>              { void b() {} void bbb(const T2 &t) {} };
+  template <typename T1, typename T2> struct TwoParm<T1 *, const T2 *>        { void c() {} void ccc(const T2 &t) {} };
+  template <typename T1, typename T2> struct TwoParm<const T1 *, const T2 *>  { void d() {} void ddd(const T2 &t) {} };
+  template <typename T1>              struct TwoParm<T1 *, int *>             { void e() {} void eee(const T1 &t) {} };
   template <typename T1>              struct TwoParm<T1, int>                 { void f() {} };
   template <>                         struct TwoParm<int *, const int *>      { void g() {} };
 }
diff --git a/Examples/test-suite/template_private_assignment.i b/Examples/test-suite/template_private_assignment.i
index e135e39..5a7b6b8 100644
--- a/Examples/test-suite/template_private_assignment.i
+++ b/Examples/test-suite/template_private_assignment.i
@@ -6,19 +6,58 @@
 instantiation for the template and hence SWIG does not find the private assignment operator.
 SwigValueWrapper is probably on by default for templates that are not instantiated for the
 same reason.
-The solution is probably to add an instantiation of the template as soon as one is parsed,
-that is an implicit empty %template().
 */
 
 %inline %{
 template<typename T, typename U> struct DeletedBits {
-//  DeletedBits& operator=(const DeletedBits&) = delete;
 private:
   DeletedBits& operator=(const DeletedBits&);
 };
+%}
 
+// Solution 1: This is a case where an instantiation is required for this to work properly.
+// Instantiation must be before the template instance is used.
+%template() DeletedBits<int, double>;
+
+%inline %{
 DeletedBits<int, double> deleted_bits;
 %}
 
-// This works around the problem
-//%template() DeletedBits<int, double>;
+// Solution 2: Alternatively use %immutable
+%immutable deleted_bits2;
+
+%inline %{
+template<typename T, typename U> struct DeletedBits2 {
+private:
+  DeletedBits2& operator=(const DeletedBits2&);
+};
+
+DeletedBits2<int, double> deleted_bits2;
+%}
+
+
+// https://github.com/swig/swig/issues/1416
+%inline %{
+template<class T> class AssignTestTemplate {
+public:
+  AssignTestTemplate() {}
+  T assigntesttemplate;
+};
+
+class AssignTestType {
+private:
+  AssignTestType( const AssignTestType& );
+  AssignTestType& operator=( const AssignTestType& );
+public:
+  AssignTestType() {}
+};
+%}
+
+%template(AssignTestTmpl) AssignTestTemplate<AssignTestType>;
+
+%inline %{
+class AssignTestContainer {
+public:
+  AssignTestTemplate<AssignTestType> assigntestcontainer;
+};
+%}
diff --git a/Examples/test-suite/template_specialization_defarg.i b/Examples/test-suite/template_specialization_defarg.i
index 2f664c6..1216ab0 100644
--- a/Examples/test-suite/template_specialization_defarg.i
+++ b/Examples/test-suite/template_specialization_defarg.i
@@ -1,5 +1,7 @@
 %module template_specialization_defarg
 
+%warnfilter(SWIGWARN_TYPE_REDEFINED) C<double, double>; // note that warning is actually for the equivalent C<double.
+
 %inline %{
 
   template <class A, class B = double>
diff --git a/Examples/test-suite/template_specialization_using_declaration.i b/Examples/test-suite/template_specialization_using_declaration.i
new file mode 100644
index 0000000..f8efe56
--- /dev/null
+++ b/Examples/test-suite/template_specialization_using_declaration.i
@@ -0,0 +1,73 @@
+%module template_specialization_using_declaration
+
+%include <std_string.i>
+
+%inline %{
+class ConcreteClass {
+  int val;
+public:
+  ConcreteClass(int i = 0) : val(i) {}
+  int concrete_value() { return val; }
+};
+
+namespace Space {
+// primary template class
+template<typename T>
+struct BaseTemplate {
+  void method_primary(T t) {}
+  virtual ~BaseTemplate() {}
+protected:
+  void method_primary_hidden(T t) {}
+};
+// specialized template class
+template<typename T>
+struct BaseTemplate<T *> {
+  void method_specialization(T t) {}
+  virtual ~BaseTemplate() {}
+protected:
+  void method_specialization_hidden(T t) {}
+};
+// partially specialized template class
+template<>
+struct BaseTemplate<int> {
+  void method_partial_specialization(int i) {}
+  virtual ~BaseTemplate() {}
+protected:
+  void method_partial_specialization_hidden(int t) {}
+};
+}
+%}
+
+%template(BaseTemplateString) Space::BaseTemplate<std::string>;
+%template(BaseTemplateConcreteClass) Space::BaseTemplate<ConcreteClass *>;
+%template(BaseTemplateInt) Space::BaseTemplate<int>;
+
+%inline %{
+namespace Space {
+// primary template class
+template<typename T>
+struct DerivedTemplate : BaseTemplate<T> {
+  void method_primary_derived(T t) {}
+  virtual ~DerivedTemplate() {}
+  using BaseTemplate<T>::method_primary_hidden;
+};
+// specialized template class
+template<typename T>
+struct DerivedTemplate<T *> : BaseTemplate<T *> {
+  void method_specialization_derived(T t) {}
+  virtual ~DerivedTemplate() {}
+  using BaseTemplate<T *>::method_specialization_hidden;
+};
+// partially specialized template class
+template<>
+struct DerivedTemplate<int> : BaseTemplate<int> {
+  void method_partial_specialization_derived(int i) {}
+  virtual ~DerivedTemplate() {}
+  using BaseTemplate<int>::method_partial_specialization_hidden;
+};
+}
+%}
+
+%template(DerivedTemplateString) Space::DerivedTemplate<std::string>;
+%template(DerivedTemplateConcreteClass) Space::DerivedTemplate<ConcreteClass *>;
+%template(DerivedTemplateInt) Space::DerivedTemplate<int>;
diff --git a/Examples/test-suite/template_static.i b/Examples/test-suite/template_static.i
index bbca994..dafb9ca 100644
--- a/Examples/test-suite/template_static.i
+++ b/Examples/test-suite/template_static.i
@@ -19,6 +19,7 @@
 namespace toto {
   class Foo {
   public:
+      static int test;
       template<class T>
       static double bar(int i) {
 	return 1.0;
@@ -28,6 +29,7 @@
       int i;
   };
 } 
+int toto::Foo::test = 5;
 %}
 
 %template(bar_double) toto::Foo::bar<double>; 
diff --git a/Examples/test-suite/template_template_parameters.i b/Examples/test-suite/template_template_parameters.i
index 8919722..068d744 100644
--- a/Examples/test-suite/template_template_parameters.i
+++ b/Examples/test-suite/template_template_parameters.i
@@ -1,7 +1,9 @@
 %module template_template_parameters
 
-
 %inline %{
+
+// part 1
+
   namespace pfc {
     template<typename t_item, template <typename> class t_alloc> class array_t {};
     template<typename t_item> class alloc_fast {
@@ -16,7 +18,7 @@
     class list_tt : public list_impl_t<t_item,pfc::array_t<t_item,t_alloc> > {
   public:
     t_item item;
-//    typename t_alloc<t_item>::alloc_type allotype; // SWIG can't handle this yet
+      typename t_alloc<t_item>::alloc_type allotype; // SWIG can handle this now
     void xx() {
       typename t_alloc<t_item>::alloc_type atype; // this type is the same as t_item type
       atype = true;
@@ -29,11 +31,68 @@
   (void) myArrayInt;
   (void) myListImplInt;
 }
+
+// part 2
+
+template<class T>
+struct Container1 { 
+    T x;
+};
+template<class U>
+struct Container2 { 
+    U x;
+};
+template<class BaseT, template<class> class TemplateTemplateT>
+struct TestStruct { 
+    TemplateTemplateT<BaseT> x;
+};
+
+TestStruct<int, Container1> TestStructContainer1Method(TestStruct<int, Container1> ts1) {
+  ts1.x.x += 10;
+  return ts1;
+}
 %}
 
+
+// part 1
 %template(ListImplFastBool) list_impl_t<bool, pfc::array_t<bool, pfc::alloc_fast> >;
 %template(ListFastBool) list_tt<bool, pfc::alloc_fast>;
 
 %template(ListImplFastDouble) list_impl_t<double, pfc::array_t<double, pfc::alloc_fast> >;
 %template(ListDefaultDouble) list_tt<double>;
 
+%template(BoolAllocFast) pfc::alloc_fast<bool>;
+%template(DoubleAllocFast) pfc::alloc_fast<double>;
+
+// part 2
+%template(IntContainer1) Container1<int>;
+%template(FloatContainer2) Container2<float>;
+%template(IntTestStruct) TestStruct<int, Container1>;
+%template(FloatTestStruct) TestStruct<float, Container2>;
+
+
+// part 3 - from #624
+
+#ifdef SWIGJAVASCRIPT
+%rename("addTo") operator+=;
+#else
+%rename("") operator+=; // For Ruby and Octave that ignore operator+=
+#endif
+
+%inline %{
+template<typename T, int dim> struct Foot {
+  template <template <typename, int> class X, typename U>
+    void operator+=(X<U, dim> & ref) {}
+};
+
+void TestInstantiationsPart3() {
+  Foot<int, 99> MyFootInt99;
+  MyFootInt99.operator+=<Foot, int>(MyFootInt99);
+  MyFootInt99 += MyFootInt99;
+}
+%}
+
+%template(MyFootInt99) Foot<int, 99>;
+%extend Foot<int, 99> {
+  %template(OperatorPlusEquals) operator+=<Foot, int>;
+}
diff --git a/Examples/test-suite/template_template_template_parameters.i b/Examples/test-suite/template_template_template_parameters.i
new file mode 100644
index 0000000..a654b64
--- /dev/null
+++ b/Examples/test-suite/template_template_template_parameters.i
@@ -0,0 +1,46 @@
+%module template_template_template_parameters
+
+%inline %{
+// Github issue #624
+class CustomAttrs {
+public:
+  enum dattr1d {pos, vel, someCustomCaseVar, d1dLast};
+};
+
+template <class TT> 
+class A {
+public:
+  TT attributes;
+  virtual ~A() {}
+};
+
+template <template<class> class A, class T> 
+class B : public A<T> {
+public:
+  virtual void BMethod(T t_parm, A<T> at_parm) {}
+};
+
+template <template<template<class> class, class> class Op, template<class> class X, class Y>
+class C : public Op<X,Y> {
+public:
+  virtual void CMethod(Y y_parm, Op<X, Y> opxy_parm) {}
+};
+
+template <template<template<class K1> class K2, class K3> class L, template<class K4> class M, class N>
+class D : public L<M,N> {
+public:
+  virtual void DMethod(N n_parm, L<M, N> lmn_parm) {}
+};
+%}
+
+%{
+template class A<CustomAttrs>;
+template class B<A, CustomAttrs>;
+template class C<B, A, CustomAttrs>;
+template class D<B, A, CustomAttrs>;
+%}
+
+%template(AC) A<CustomAttrs>;
+%template(BAC) B<A, CustomAttrs>;
+%template(CBAC) C<B, A, CustomAttrs>;
+%template(DBAC) D<B, A, CustomAttrs>;
diff --git a/Examples/test-suite/template_templated_constructors.i b/Examples/test-suite/template_templated_constructors.i
index ee9df94..c7f92ef 100644
--- a/Examples/test-suite/template_templated_constructors.i
+++ b/Examples/test-suite/template_templated_constructors.i
@@ -16,6 +16,20 @@
   ~TConstructor2() {}
 };
 
+class TConstructor3 {
+public:
+  // No implicit default constructor available
+  template<typename T> TConstructor3(T val) {}
+  ~TConstructor3() {}
+};
+
+class TConstructor4 {
+public:
+  // No constructors available from wrappers when there is no %template to instantiate templated constructor
+  template<typename T> TConstructor4() {}
+  ~TConstructor4() {}
+};
+
 template<typename T> class TClass1 {
 public:
   template<typename Y> TClass1(Y t) {}
@@ -45,3 +59,37 @@
 %extend ConstructSpace::TClass2<int> {
   %template(TClass2Int) TClass2<double>;
 }
+
+%inline %{
+// Simple version of std::pair
+namespace Standard {
+  template <class T, class U > struct Pair {
+    typedef T first_type;
+    typedef U second_type;
+    Pair() {}
+    Pair(const T& first, const U& second) {}
+    Pair(const Pair& other) {}
+
+    template <class U1, class U2> Pair(const Pair< U1, U2 > &otherone) {}
+  };
+}
+%}
+
+%include <std_string.i>
+
+namespace Standard {
+  %template(StringPair) Pair<std::string, std::string>;
+  %template(ShortPair) Pair<short, short>;
+  %template(IntPair) Pair<int, int>;
+  %template(DoublePair) Pair<double, double>;
+  %extend Pair<int, int> {
+    // Templated constructor which uses 'correct' name of the containing class (IntPair)
+    %template(IntPair) Pair<short, short>;
+    // Templated constructors that behave differently in different languages as the template name
+    // does not match IntPair, the instantiated name for Pair<int, int>.
+    // Some languages wrap as a factory style function (Python), 
+    // others ignore the name and wrap as regular constructor (Java).
+    %template(Pair) Pair<double, double>;
+    %template(MakeStringPair) Pair<std::string, std::string>;
+  }
+}
diff --git a/Examples/test-suite/template_type_collapse.i b/Examples/test-suite/template_type_collapse.i
new file mode 100644
index 0000000..f6459db
--- /dev/null
+++ b/Examples/test-suite/template_type_collapse.i
@@ -0,0 +1,23 @@
+%module template_type_collapse
+
+// Not attempted yet: reference collapsing
+
+// Tests merging multiple const when instantiating template types
+%inline %{
+template <typename T> struct Conster { 
+  const T *constptr;
+  Conster() : constptr() {}
+  void cccc1(T const& t) {}
+  void cccc2(const T& t) {}
+  void cccc3(const T t) {}
+  void cccc4(T const t) {}
+};
+template <typename T> struct DerivedConster : Conster<const T> {
+  const T& dddd(const T& t) {
+    return t;
+  }
+};
+%}
+%template(ConsterInt) Conster<const int>;
+%template(DerivedConsterInt) DerivedConster<const int>;
+
diff --git a/Examples/test-suite/template_typedef_cplx2.h b/Examples/test-suite/template_typedef_cplx2.h
index 17d0652..a23c319 100644
--- a/Examples/test-suite/template_typedef_cplx2.h
+++ b/Examples/test-suite/template_typedef_cplx2.h
@@ -1,5 +1,5 @@
-#ifndef ___typedef_import_h__
-#define ___typedef_import_h__
+#ifndef TEMPLATE_TYPEDEF_CPLX2_H
+#define TEMPLATE_TYPEDEF_CPLX2_H
 
 #ifdef SWIG
 %module template_typedef_cplx2;
@@ -113,6 +113,8 @@
 #ifndef SWIG
 
 // Initialize these static class members
+// XXX Since this is a header file, the following creates the symbols in *each* SWIG _wrap.cxx file. Linking the resulting SWIG modules together may result in
+// duplicate symbol link errors.
 
 const char* const arith_traits< double, double >::arg_type = "double";
 const char* const arith_traits< double, double >::res_type = "double";
@@ -172,4 +174,4 @@
 
 #endif
 
-#endif //___template_typedef_h__
+#endif // TEMPLATE_TYPEDEF_CPLX2_H
diff --git a/Examples/test-suite/template_using_member_default_arg.i b/Examples/test-suite/template_using_member_default_arg.i
new file mode 100644
index 0000000..117abd0
--- /dev/null
+++ b/Examples/test-suite/template_using_member_default_arg.i
@@ -0,0 +1,33 @@
+%module template_using_member_default_arg
+
+%inline %{
+template<typename T1, typename T2 = short>
+struct ThingA {
+  ThingA() {}
+protected:
+  void describeA() {}
+};
+template<typename T1, typename T2 = short>
+struct ThingB {
+  ThingB() {}
+protected:
+  void describeB() {}
+};
+%}
+
+%inline %{
+template<typename T1>
+struct ThingADerived : ThingA<T1> {
+  using ThingA<T1>::describeA;
+};
+template<typename T1>
+struct ThingBDerived : ThingB<T1> {
+  using ThingB<T1>::describeB;
+};
+%}
+
+%template(ThingAInt) ThingA<int>; // was okay
+%template(ThingADerivedInt) ThingADerived<int>;
+
+%template(ThingBInt) ThingB<int, short>; // was failing - using directive in this template was not found
+%template(ThingBDerivedInt) ThingBDerived<int>;
diff --git a/Examples/test-suite/template_whitespace.i b/Examples/test-suite/template_whitespace.i
index f00b9e8..063dec6 100644
--- a/Examples/test-suite/template_whitespace.i
+++ b/Examples/test-suite/template_whitespace.i
@@ -11,9 +11,9 @@
 };
 %}
 
-//%typemap(in) vector<int> "$target = new vector<int>();";
-//%typemap(in) vector<unsigned int> "$target = new vector<unsigned int>();";
-//%typemap(in) map<int,int> "$target = new map<int, int>();";
+//%typemap(in) vector<int> "$target = new vector<int>();"
+//%typemap(in) vector<unsigned int> "$target = new vector<unsigned int>();"
+//%typemap(in) map<int,int> "$target = new map<int, int>();"
 
 %inline %{
 void foo(vector<int > v) {}
diff --git a/Examples/test-suite/testdir/inctest/subdir2/hello.i b/Examples/test-suite/testdir/inctest/subdir2/hello.i
index ed172b1..e87b437 100644
--- a/Examples/test-suite/testdir/inctest/subdir2/hello.i
+++ b/Examples/test-suite/testdir/inctest/subdir2/hello.i
@@ -3,6 +3,7 @@
 
 %{
 typedef char * TypedefString;
+#include <string.h>
 %}
 
 
diff --git a/Examples/test-suite/threads.i b/Examples/test-suite/threads.i
index 7c6b09b..28c5594 100644
--- a/Examples/test-suite/threads.i
+++ b/Examples/test-suite/threads.i
@@ -9,6 +9,7 @@
 
 %inline %{
   #include <string>
+  #include <string.h>
   struct Kerfuffle {
     std::string StdString(std::string str) {
       return str;
diff --git a/Examples/test-suite/threads_exception.i b/Examples/test-suite/threads_exception.i
index 4708633..776e842 100644
--- a/Examples/test-suite/threads_exception.i
+++ b/Examples/test-suite/threads_exception.i
@@ -13,6 +13,7 @@
 %}
 
 %{
+#include <string.h>
 struct A {};
 %}
 
diff --git a/Examples/test-suite/typedef_inherit.i b/Examples/test-suite/typedef_inherit.i
index 48821a1..54968b8 100644
--- a/Examples/test-suite/typedef_inherit.i
+++ b/Examples/test-suite/typedef_inherit.i
@@ -30,9 +30,13 @@
   {
   }
   
-   virtual char *blah() {     
-       return (char *) "Spam::blah";
-   }
+  virtual char *blah() {
+    return (char *) "Spam::blah";
+  }
+
+  const char *far() {
+    return "Spam::far";
+  }
 } Spam;
 
 struct Grok : public Spam {
diff --git a/Examples/test-suite/typedef_struct.i b/Examples/test-suite/typedef_struct.i
index 185e811..b9a670c 100644
--- a/Examples/test-suite/typedef_struct.i
+++ b/Examples/test-suite/typedef_struct.i
@@ -31,6 +31,7 @@
 
 #define MS_NOOVERRIDE -1111
 
+#include <stdlib.h>
 %}
 
 
diff --git a/Examples/test-suite/typemap_array_qualifiers.i b/Examples/test-suite/typemap_array_qualifiers.i
index c3965ce..f7cce3c 100644
--- a/Examples/test-suite/typemap_array_qualifiers.i
+++ b/Examples/test-suite/typemap_array_qualifiers.i
@@ -26,6 +26,12 @@
 }
 %enddef
 
+%{
+#if __cplusplus >= 202002L
+#define volatile
+#endif
+%}
+
 %inline %{
   typedef struct {
     int a;
diff --git a/Examples/test-suite/typemap_out_optimal.i b/Examples/test-suite/typemap_out_optimal.i
index d707ed2..46809d1 100644
--- a/Examples/test-suite/typemap_out_optimal.i
+++ b/Examples/test-suite/typemap_out_optimal.i
@@ -4,39 +4,40 @@
 // Just the following languages tested
 #if defined (SWIGCSHARP) || defined (SWIGD)
 %typemap(out, optimal="1") SWIGTYPE %{
-  $result = new $1_ltype((const $1_ltype &)$1);
+  $result = new $1_ltype($1);
 %}
 #elif defined (SWIGJAVA)
 %typemap(out, optimal="1") SWIGTYPE %{ 
-  *($&1_ltype*)&$result = new $1_ltype((const $1_ltype &)$1);
+  *($&1_ltype*)&$result = new $1_ltype($1);
 %}
 #elif defined (SWIGUTL)
 %typemap(out,noblock="1", optimal="1") SWIGTYPE {
-  %set_output(SWIG_NewPointerObj(%new_copy($1, $ltype), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags));
+  %set_output(SWIG_NewPointerObj(new $1_ltype($1), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags));
 }
 #endif
 
 %ignore XX::operator=;
 
-#ifdef SWIGD
-%rename(trace) XX::debug;
-#endif
-
 %inline %{
 #include <iostream>
 using namespace std;
 
 struct XX {
-  XX() { if (debug) cout << "XX()" << endl; }
-  XX(int i) { if (debug) cout << "XX(" << i << ")" << endl; }
-  XX(const XX &other) { if (debug) cout << "XX(const XX &)" << endl; }
-  XX& operator =(const XX &other) { if (debug) cout << "operator=(const XX &)" << endl; return *this; }
-  ~XX() { if (debug) cout << "~XX()" << endl; }
-  static XX create() { 
+  XX() { if (trace) cout << "XX()" << endl; }
+  XX(int i) { if (trace) cout << "XX(" << i << ")" << endl; }
+  XX(const XX &other) { if (trace) cout << "XX(const XX &)" << endl; }
+  XX& operator =(const XX &other) { if (trace) cout << "operator=(const XX &)" << endl; return *this; }
+  ~XX() { if (trace) cout << "~XX()" << endl; }
+
+// Note: best observed RVO for C#, Java and Python with g++-6 to g++-10 (just one constructor and one destructor call)
+  static XX create() {
     return XX(123);
   }
-  static bool debug;
+  static const XX createConst() {
+    return XX(456);
+  }
+  static bool trace;
 };
-bool XX::debug = true;
+bool XX::trace = true;
 %}
 
diff --git a/Examples/test-suite/typemap_qualifier_strip.i b/Examples/test-suite/typemap_qualifier_strip.i
index 9b9f24c..36d524d 100644
--- a/Examples/test-suite/typemap_qualifier_strip.i
+++ b/Examples/test-suite/typemap_qualifier_strip.i
@@ -4,18 +4,18 @@
 %typemap(freearg) int *const ptrConst ""
 %typemap(freearg) int const* constPtr ""
 
-%typemap(in) int *ptr {
-  int temp = 1234;
+%typemap(in) int *ptr (int temp) {
+  temp = 1234;
   $1 = &temp;
 }
 
-%typemap(in) int *const ptrConst {
-  int temp = 5678;
+%typemap(in) int *const ptrConst (int temp) {
+  temp = 5678;
   $1 = &temp;
 }
 
-%typemap(in) int const* constPtr {
-  int temp = 3456;
+%typemap(in) int const* constPtr (int temp) {
+  temp = 3456;
   $1 = &temp;
 }
 
diff --git a/Examples/test-suite/typemap_self.i b/Examples/test-suite/typemap_self.i
index 3630688..cfa619e 100644
--- a/Examples/test-suite/typemap_self.i
+++ b/Examples/test-suite/typemap_self.i
@@ -4,7 +4,7 @@
 %typemap(in) A* (A* ptr) {
   if (SWIG_ConvertPtr($input, (void**) &ptr, $1_descriptor, 0) != -1) {
     $1 = ptr;
-  } else  {
+  } else {
     $1 = new A();
   }
  }
diff --git a/Examples/test-suite/typemap_variables.i b/Examples/test-suite/typemap_variables.i
index b1ae24f..1cff64f 100644
--- a/Examples/test-suite/typemap_variables.i
+++ b/Examples/test-suite/typemap_variables.i
@@ -18,6 +18,10 @@
 %header %{
 #define OUT_NULL_VALUE SWIGV8_NULL()
 %}
+#elif defined(SWIG_JAVASCRIPT_NAPI)
+%header %{
+#define OUT_NULL_VALUE env.Null()
+%}
 #else
 %header %{
 #define OUT_NULL_VALUE 0
@@ -68,12 +72,12 @@
 %clear int Space::nspace;
 %clear int Space::Struct::smember;
 %ignore Space::Struct::member;
-%typemap(varin) int globul "TYPEMAP_VARIABLES_FAIL";
-%typemap(varout, noblock=1, fragment=SWIG_From_frag(int)) int globul "if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, SWIG_From_int($result)))) return SWIG_ERROR;";
-%typemap(varin) int Space::nspace "TYPEMAP_VARIABLES_FAIL";
-%typemap(varout, noblock=1, fragment=SWIG_From_frag(int)) int Space::nspace "if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, SWIG_From_int($result)))) return SWIG_ERROR;";
-%typemap(varin) int Space::Struct::smember "TYPEMAP_VARIABLES_FAIL";
-%typemap(varout, noblock=1, fragment=SWIG_From_frag(int)) int Space::Struct::smember "if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, SWIG_From_int($result)))) return SWIG_ERROR;";
+%typemap(varin) int globul "TYPEMAP_VARIABLES_FAIL"
+%typemap(varout, noblock=1, fragment=SWIG_From_frag(int)) int globul "if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, SWIG_From_int($result)))) return SWIG_ERROR;"
+%typemap(varin) int Space::nspace "TYPEMAP_VARIABLES_FAIL"
+%typemap(varout, noblock=1, fragment=SWIG_From_frag(int)) int Space::nspace "if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, SWIG_From_int($result)))) return SWIG_ERROR;"
+%typemap(varin) int Space::Struct::smember "TYPEMAP_VARIABLES_FAIL"
+%typemap(varout, noblock=1, fragment=SWIG_From_frag(int)) int Space::Struct::smember "if (!SWIG_IsOK(SWIG_Scilab_SetOutput(pvApiCtx, SWIG_From_int($result)))) return SWIG_ERROR;"
 #endif
 
 %inline %{
diff --git a/Examples/test-suite/typemap_various.i b/Examples/test-suite/typemap_various.i
index 3436bac..00665b6 100644
--- a/Examples/test-suite/typemap_various.i
+++ b/Examples/test-suite/typemap_various.i
@@ -54,14 +54,22 @@
 %}
 
 %newobject FFoo::Bar(bool) const ;
-%typemap(newfree) char* Bar(bool)  {
+%typemap(newfree) char* Bar(bool) {
    /* hello */ delete[] result;
 }
 
+%{
+#include <string.h>
+%}
+
 %inline {
   class FFoo {
   public:
-    char * Bar(bool b) const { return (char *)"x"; }
+    char * Bar(bool b) const {
+      char *ret = new char[2];
+      strcpy(ret, b ? "1" : "0");
+      return ret;
+    }
   };
 }
 
diff --git a/Examples/test-suite/types_directive.i b/Examples/test-suite/types_directive.i
index 26cb6ae..530c338 100644
--- a/Examples/test-suite/types_directive.i
+++ b/Examples/test-suite/types_directive.i
@@ -19,10 +19,11 @@
 };
 
 struct Time1 {
-  Time1(unsigned int year, unsigned int month, unsigned int day, unsigned int seconds) : date(year, month, day), seconds(seconds) {}
+  Time1(unsigned int year, unsigned int month, unsigned int day, unsigned int seconds) : padding(), date(year, month, day), seconds(seconds) {}
   Date &dateFromTime() {
     return date;
   }
+  unsigned int padding; // so that memory layout is not the same as Date
   Date date;
   unsigned int seconds;
 };
diff --git a/Examples/test-suite/uffi/Makefile.in b/Examples/test-suite/uffi/Makefile.in
deleted file mode 100644
index 5d6dc11..0000000
--- a/Examples/test-suite/uffi/Makefile.in
+++ /dev/null
@@ -1,51 +0,0 @@
-#######################################################################
-# Makefile for uffi test-suite
-#######################################################################
-
-LANGUAGE     = uffi
-UFFI         = @UFFIBIN@
-SCRIPTSUFFIX = _runme.lisp
-
-srcdir       = @srcdir@
-top_srcdir   = @top_srcdir@
-top_builddir = @top_builddir@
-
-include $(srcdir)/../common.mk
-
-# Overridden variables here
-# no C++ tests for now
-CPP_TEST_CASES =
-#C_TEST_CASES +=
-
-# Custom tests - tests with additional commandline options
-# none!
-
-# Rules for the different types of tests
-%.cpptest:
-	$(setup)
-	+$(swig_and_compile_cpp)
-	$(run_testcase)
-
-%.ctest:
-	$(setup)
-	+$(swig_and_compile_c)
-	$(run_testcase)
-
-%.multicpptest:
-	$(setup)
-	+$(swig_and_compile_multi_cpp)
-	$(run_testcase)
-
-# Runs the testcase. A testcase is only run if
-# a file is found which has _runme.lisp appended after the testcase name.
-run_testcase = \
-	if [ -f $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX) ]; then \
-	  env LD_LIBRARY_PATH=.:$$LD_LIBRARY_PATH $(RUNTOOL) $(UFFI) -batch -s $(SCRIPTDIR)/$(SCRIPTPREFIX)$*$(SCRIPTSUFFIX); \
-	fi
-
-# Clean: (does nothing, we dont generate extra uffi code)
-%.clean:
-	@exit 0
-
-clean:
-	$(MAKE) -f $(top_builddir)/$(EXAMPLES)/Makefile SRCDIR='$(SRCDIR)' uffi_clean
diff --git a/Examples/test-suite/using2.i b/Examples/test-suite/using2.i
index 1f3dc46..1c471c1 100644
--- a/Examples/test-suite/using2.i
+++ b/Examples/test-suite/using2.i
@@ -1,6 +1,6 @@
 %module using2
 
-%warnfilter(SWIGWARN_PARSE_USING_UNDEF);
+%warnfilter(SWIGWARN_PARSE_USING_UNDEF) ::baz;
 
 using ::baz;
 
diff --git a/Examples/test-suite/using_member.i b/Examples/test-suite/using_member.i
new file mode 100644
index 0000000..c80a83a
--- /dev/null
+++ b/Examples/test-suite/using_member.i
@@ -0,0 +1,71 @@
+%module using_member
+
+/* using declaration tests, including renaming */
+%warnfilter(SWIGWARN_LANG_USING_NAME_DIFFERENT) one::twotwo::threetwo::BB::great;
+
+%rename(greater) one::two::three::interface1::AA::great(int);
+%rename(greater) one::two::three::interface1::AA::great(float);
+%rename(greater) one::CC::great;
+%rename(greater) one::DD::great;
+%rename(greaterstill) one::DD::great(bool);
+
+%inline %{
+namespace interface1
+{
+    struct A
+    {
+        int get(int) {return 10;}
+    };
+}
+using interface1::A;
+
+struct B : public A
+{
+    using A::get;
+    int get(double) {return 20;}
+};
+
+
+namespace one {
+    namespace two {
+        namespace three {
+            namespace interface1
+            {
+                class AA
+                {
+                public:
+                    int great(int) {return 0;}
+                    int great(float) {return 1;}
+                };
+            }
+            using interface1::AA;
+        }
+    }
+    namespace twotwo {
+        namespace threetwo {
+            class BB : public two::three::AA
+            {
+            public:
+// TODO: two::three::AA::great not introduced
+                using two::three::AA::great;
+                int great(bool) {return 2;}
+                int jj() {return 3;}
+            };
+        }
+    }
+
+    class CC : public two::three::AA
+    {
+    public:
+      using two::three::AA::great;
+      int great(bool) {return 20;}
+    };
+
+    class DD : public two::three::AA
+    {
+    public:
+      using two::three::AA::great;
+      int great(bool) {return 30;}
+    };
+}
+%}
diff --git a/Examples/test-suite/using_member_multiple_inherit.i b/Examples/test-suite/using_member_multiple_inherit.i
new file mode 100644
index 0000000..c344c39
--- /dev/null
+++ b/Examples/test-suite/using_member_multiple_inherit.i
@@ -0,0 +1,118 @@
+%module(ruby_minherit="1") using_member_multiple_inherit
+
+%warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE,
+	    SWIGWARN_CSHARP_MULTIPLE_INHERITANCE,
+	    SWIGWARN_D_MULTIPLE_INHERITANCE,
+	    SWIGWARN_PHP_MULTIPLE_INHERITANCE) MultMiddleA; /* C#, D, Java, PHP multiple inheritance */
+%warnfilter(SWIGWARN_JAVA_MULTIPLE_INHERITANCE,
+	    SWIGWARN_CSHARP_MULTIPLE_INHERITANCE,
+	    SWIGWARN_D_MULTIPLE_INHERITANCE,
+	    SWIGWARN_PHP_MULTIPLE_INHERITANCE) MultMiddleB; /* C#, D, Java, PHP multiple inheritance */
+
+
+%inline %{
+// Single inheritance three deep, only using declarations
+struct Susing1 {
+protected:
+  void usingmethod(int i) {}
+};
+struct Susing2 : Susing1 {
+protected:
+  using Susing1::usingmethod;
+};
+struct Susing3 : Susing2 {
+  using Susing2::usingmethod;
+};
+
+// Single inheritance three deep, overload using and methods
+struct Using1 {
+protected:
+  void usingmethod(int i) {}
+};
+struct Using2 : Using1 {
+protected:
+  // method declaration before using declaration
+  void usingmethod(int i, int j) {}
+  using Using1::usingmethod;
+};
+struct Using3 : Using2 {
+  void usingmethod(int i, int j, int k) {}
+  using Using2::usingmethod;
+};
+
+struct Musing2 : Using1 {
+protected:
+  // using declaration before method declaration
+  using Using1::usingmethod;
+  void usingmethod(int i, int j) {}
+};
+struct Musing3 : Musing2 {
+  using Musing2::usingmethod;
+  void usingmethod(int i, int j, int k) {}
+};
+
+struct Dusing2 : Using1 {
+protected:
+  using Using1::usingmethod;
+  void usingmethod(int i, int j) {}
+};
+struct Dusing3 : Dusing2 {
+  // redundant using declarations
+  using Using1::usingmethod;
+  using Dusing2::usingmethod;
+};
+
+// Multiple inheritance, multiple using declarations
+struct Mult1 {
+protected:
+  void multmethod(int i) {}
+};
+struct Mult2 {
+protected:
+  void multmethod(const char *c) {}
+};
+struct MultMiddleA : Mult1, Mult2 {
+public: // Note!
+  void multmethod(int i, int j) {}
+  using Mult1::multmethod;
+  using Mult2::multmethod;
+};
+#if !defined(SWIGD) // TODO: Fix bug adding incorrect override
+struct MultBottomA : MultMiddleA {
+  void multmethod(int i, int j, int k) {}
+  using MultMiddleA::multmethod;
+};
+#endif
+void cplusplus_testA() {
+  MultMiddleA m;
+  m.multmethod(123);
+  m.multmethod("hi");
+  m.multmethod(123, 234);
+}
+struct MultMiddleB : Mult1, Mult2 {
+protected: // Note!
+  void multmethod(int i, int j) {}
+  using Mult1::multmethod;
+  using Mult2::multmethod;
+};
+struct MultBottomB : MultMiddleB {
+  void multmethod(int i, int j, int k) {}
+  using MultMiddleB::multmethod;
+};
+void cplusplus_testB() {
+  MultBottomB m;
+  m.multmethod(123);
+  m.multmethod("hi");
+  m.multmethod(123, 234);
+  m.multmethod(123, 345, 567);
+}
+
+/* TODO: fix when using declaration is declared before method, for example change MultMiddleA to:
+struct MultMiddleB : Mult1, Mult2 {
+protected: // Note!
+  using Mult1::multmethod;
+  using Mult2::multmethod;
+  void multmethod(int i, int j) {}
+};
+*/
+%}
diff --git a/Examples/test-suite/using_member_scopes.i b/Examples/test-suite/using_member_scopes.i
new file mode 100644
index 0000000..3245c9c
--- /dev/null
+++ b/Examples/test-suite/using_member_scopes.i
@@ -0,0 +1,85 @@
+%module using_member_scopes
+
+// Fully qualifying parameter types in a method declared after the using declaration caused
+// a method being incorrectly added by the using declaration even though the declaration already existed
+
+%inline %{
+namespace OgreBites
+{
+    struct NativeWindowType {};
+    class ApplicationContextBase {
+    public:
+        virtual ~ApplicationContextBase() {}
+        virtual void setWindowGrab(NativeWindowType* win, bool grab = true) {}
+        void setWindowGrab(bool grab = true) {}
+    };
+    class ApplicationContextSDL : public ApplicationContextBase {
+    public:
+        using ApplicationContextBase::setWindowGrab;
+        void setWindowGrab(NativeWindowType* win, bool grab = true) {} // This should not be added again as it exists in base class
+    };
+/*
+typedef not working yet
+    class ApplicationContextSDL2 : public ApplicationContextBase {
+    public:
+        using ApplicationContextBase::setWindowGrab;
+        typedef NativeWindowType* pNWT;
+        void setWindowGrab(pNWT win, bool grab) {} // This should not be added again as it exists in base class
+    };
+*/
+}
+%}
+
+
+%inline %{
+// Test using declaration in various positions before and after overloaded methods
+// Testing where the derived class overrides all the base class methods (and more)
+namespace Bites
+{
+  struct Base
+  {
+    virtual ~Base() {}
+    virtual void grab() {}
+    virtual void grab(int i) {}
+  };
+  struct Derived1 : public Base
+  {
+    using Base::grab;
+    virtual void grab() {}
+    virtual void grab(int i) {}
+  };
+  struct Derived2 : public Base
+  {
+    using Base::grab;
+    virtual void grab() {}
+    virtual void grab(int i) {}
+    virtual void grab(int i, double d) {}
+  };
+  struct Derived3 : public Base
+  {
+    virtual void grab() {}
+    using Base::grab;
+    virtual void grab(int i) {}
+  };
+  struct Derived4 : public Base
+  {
+    virtual void grab() {}
+    using Base::grab;
+    virtual void grab(int i) {}
+    virtual void grab(int i, double d) {}
+  };
+  struct Derived5 : public Base
+  {
+    virtual void grab() {}
+    virtual void grab(int i) {}
+    using Base::grab;
+  };
+  struct Derived6 : public Base
+  {
+    virtual void grab() {}
+    virtual void grab(int i) {}
+    virtual void grab(int i, double d) {}
+    using Base::grab;
+  };
+}
+%}
diff --git a/Examples/test-suite/valuewrapper_base.i b/Examples/test-suite/valuewrapper_base.i
index 63471bb..5107a3c 100644
--- a/Examples/test-suite/valuewrapper_base.i
+++ b/Examples/test-suite/valuewrapper_base.i
@@ -12,7 +12,7 @@
     template <Polarization P> 
     struct Interface_ : Base 
     { 
-      Interface_(const Base& b) { }; 
+      Interface_(const Base& b) { }
     }; 
     
     template <class Result> 
diff --git a/Examples/test-suite/valuewrapper_opaque.i b/Examples/test-suite/valuewrapper_opaque.i
index bc7ba86..962bd2f 100644
--- a/Examples/test-suite/valuewrapper_opaque.i
+++ b/Examples/test-suite/valuewrapper_opaque.i
@@ -14,7 +14,7 @@
 %{
 template<typename T> class TemplateClass {
 public:
-TemplateClass<T>(T a) {}
+TemplateClass(T a) {}
 };
 
 struct B
diff --git a/Examples/test-suite/varargs.i b/Examples/test-suite/varargs.i
index dd56cb0..c1aee22 100644
--- a/Examples/test-suite/varargs.i
+++ b/Examples/test-suite/varargs.i
@@ -1,17 +1,35 @@
-// Tests SWIG's *default* handling of varargs (function varargs, not preprocessor varargs).
+// Tests SWIG's handling of varargs (function varargs, not preprocessor varargs).
 // The default behavior is to simply ignore the varargs.
 %module varargs
 
+// Default handling of varargs
+
+%{
+#include <string.h>
+%}
+
+%inline %{
+char *test(const char *fmt, ...) {
+  return (char *) fmt;
+}
+
+struct VarargConstructor {
+  char *str;
+  VarargConstructor(const char *fmt, ...) {
+    str = new char[strlen(fmt) + 1];
+    strcpy(str, fmt);
+  }
+};
+%}
+
+// %varargs support
+
 %varargs(int mode = 0) test_def;
 %varargs(int mode = 0) Foo::Foo;
 %varargs(int mode = 0) Foo::statictest(const char*fmt, ...);
 %varargs(2, int mode = 0) test_plenty(const char*fmt, ...);
 
 %inline %{
-char *test(const char *fmt, ...) {
-  return (char *) fmt;
-}
-
 const char *test_def(const char *fmt, ...) {
   return fmt;
 }
@@ -40,5 +58,4 @@
 const char *test_plenty(const char *fmt, ...) {
   return fmt;
 }
-
 %}
diff --git a/Examples/test-suite/voidtest.i b/Examples/test-suite/voidtest.i
index f0e6493..d792f41 100644
--- a/Examples/test-suite/voidtest.i
+++ b/Examples/test-suite/voidtest.i
@@ -9,6 +9,7 @@
 public:
    Foo(void) { }
    void memberfunc(void) { }
+   void* get_this() { return this; }
    static void staticmemberfunc(void) { }
 };
 
@@ -18,4 +19,6 @@
 Foo  *vfunc3(void *f) { return (Foo *) f; }
 Foo  *vfunc4(Foo *f) { return f; }
 
+bool test_pointers_equal(void *a, void *b) { return a == b; }
+
 %}
diff --git a/Examples/xml/Makefile.in b/Examples/xml/Makefile.in
index 44894b8..292a399 100644
--- a/Examples/xml/Makefile.in
+++ b/Examples/xml/Makefile.in
@@ -30,7 +30,7 @@
 	for f in $(all-dot-i-files) ; do				\
 	  base=`basename $$f .i` ;					\
 	  xml=$$base.xml ;						\
-	  $(SWIGINVOKE) -xml $$xml ${srcdir}/$$f ;	\
+	  $(SWIGINVOKE) -xml -o $$xml ${srcdir}/$$f ;	\
 	  cat $$xml | $(cleanup) | diff -c ${srcdir}/$$base.expected-xml - ;	\
 	done
 
@@ -43,9 +43,9 @@
 # from here on, non-developers beware!
 
 %.expected-xml : %.i
-	$(SWIGINVOKE) -xml tmp-file $^
-	cat tmp-file | $(cleanup) > $@
-	rm -f tmp-file
+	$(SWIGINVOKE) -xml -o tmp-file.xml $^
+	cat tmp-file.xml | $(cleanup) > $@
+	rm -f tmp-file.xml
 
 all-expected-xml:
 	for f in $(all-dot-i-files) ; do \
diff --git a/Examples/xml/example_apply.expected-xml b/Examples/xml/example_apply.expected-xml
index 6118ef1..26cf5df 100644
--- a/Examples/xml/example_apply.expected-xml
+++ b/Examples/xml/example_apply.expected-xml
@@ -409,7 +409,7 @@
   } else if (strcmp(type,"char *") == 0) {
     char *c = SvPV(value,PL_na);
     char **ca = (char **) ptr;
-    if (ca[index]) free(ca[index]);
+    free(ca[index]);
     if (strcmp(c,"NULL") == 0) {
       ca[index] = 0;
     } else {
@@ -500,8 +500,7 @@
       }
     }
   }
-  if (ptr)
-    free((char *) ptr);
+  free((char *) ptr);
 }
 
                     </swigxml:code>
diff --git a/Examples/xml/example_apply.i b/Examples/xml/example_apply.i
index 2ed2b5b..41a7c79 100644
--- a/Examples/xml/example_apply.i
+++ b/Examples/xml/example_apply.i
@@ -6,7 +6,7 @@
 
 /* First we'll use the pointer library */
 extern void add(int *x, int *y, int *result);
-%include pointer.i
+%include cpointer.i
 
 /* Next we'll use some typemaps */
 
diff --git a/Examples/xml/example_ro.i b/Examples/xml/example_ro.i
index 23bd1a8..b494e1e 100644
--- a/Examples/xml/example_ro.i
+++ b/Examples/xml/example_ro.i
@@ -1,5 +1,5 @@
 /* File : example.i */
-%readonly 
+%immutable;
 extern int  status;
 extern char path[256];
 
diff --git a/Examples/xml/example_title_add.expected-xml b/Examples/xml/example_title_add.expected-xml
index 5aed729..fc4af4f 100644
--- a/Examples/xml/example_title_add.expected-xml
+++ b/Examples/xml/example_title_add.expected-xml
@@ -76,7 +76,7 @@
               <c:function name="size" >
                 <swigxml:type string="int"  />
               </c:function>
-              <swig:addmethods >
+              <swig:extend >
                 <swigxml:child >
                   <c:function name="get" >
                     <swigxml:parms >
@@ -106,7 +106,7 @@
                     <swigxml:type string="void"  />
                   </c:function>
                 </swigxml:child>
-              </swig:addmethods>
+              </swig:extend>
             </swigxml:child>
             <swigxml:classtype string="class"  />
             <swigxml:namespace string="VectorArray"  />
diff --git a/Examples/xml/example_title_add.i b/Examples/xml/example_title_add.i
index 3320919..624cb5c 100644
--- a/Examples/xml/example_title_add.i
+++ b/Examples/xml/example_title_add.i
@@ -1,5 +1,5 @@
 /* File : example.i */
-%title "Matrix and vector package"
+/* Matrix and vector package */
 
 /* This file has a few "typical" uses of C++ references. */
 
@@ -32,7 +32,7 @@
   int size();
   
   /* This wrapper provides an alternative to the [] operator */
-  %addmethods {
+  %extend {
     Vector &get(int index) {
       return (*self)[index];
     }
diff --git a/Examples/xml/example_xml.expected-xml b/Examples/xml/example_xml.expected-xml
index 4d08b20..e13bcf2 100644
--- a/Examples/xml/example_xml.expected-xml
+++ b/Examples/xml/example_xml.expected-xml
@@ -441,7 +441,7 @@
   } else if (strcmp(type,"char *") == 0) {
     char *c = SvPV(value,PL_na);
     char **ca = (char **) ptr;
-    if (ca[index]) free(ca[index]);
+    free(ca[index]);
     if (strcmp(c,"NULL") == 0) {
       ca[index] = 0;
     } else {
@@ -532,8 +532,7 @@
       }
     }
   }
-  if (ptr)
-    free((char *) ptr);
+  free((char *) ptr);
 }
 
                     </swigxml:code>
diff --git a/Examples/xml/example_xml.i b/Examples/xml/example_xml.i
index a598b6a..99ca53c 100644
--- a/Examples/xml/example_xml.i
+++ b/Examples/xml/example_xml.i
@@ -14,7 +14,7 @@
 
 
 
-%include pointer.i
+%include cpointer.i
 
 /* Next we'll use some typemaps */
 
diff --git a/Lib/allegrocl/allegrocl.swg b/Lib/allegrocl/allegrocl.swg
deleted file mode 100644
index 524aa7c..0000000
--- a/Lib/allegrocl/allegrocl.swg
+++ /dev/null
@@ -1,615 +0,0 @@
-/* Define a C preprocessor symbol that can be used in interface files
-   to distinguish between the SWIG language modules. */ 
-
-#define SWIG_ALLEGRO_CL
-
-#define %ffargs(...) %feature("ffargs", "1", ##__VA_ARGS__)
-%ffargs(strings_convert="t");
-
-/* typemaps for argument and result type conversions. */
-%typemap(lin,numinputs=1)	SWIGTYPE 	"(cl::let (($out $in))\n  $body)";
-
-%typemap(lout) bool, char, unsigned char, signed char,
-               short, signed short, unsigned short,
-               int, signed int, unsigned int,
-               long, signed long, unsigned long,
-               float, double, long double, char *, void *,
-               enum SWIGTYPE    "(cl::setq ACL_ffresult $body)";
-%typemap(lout) void "$body";
-#ifdef __cplusplus
-%typemap(lout) SWIGTYPE[ANY], SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&
-%{ (cl:let* ((address $body)
-	  (new-inst (cl:make-instance '$lclass :foreign-address address)))
-     (cl:when (cl:and $owner (cl:not (cl:zerop address)))
-       (excl:schedule-finalization new-inst #'$ldestructor))
-     (cl:setq ACL_ffresult new-inst)) %}
-
-%typemap(lout) SWIGTYPE         "(cl::let* ((address $body)\n         (new-inst (cl::make-instance '$lclass :foreign-address address)))\n    (cl::unless (cl::zerop address)\n      (excl:schedule-finalization new-inst #'$ldestructor))\n    (cl::setq ACL_ffresult new-inst))";
-#else
-%typemap(lout) SWIGTYPE[ANY], SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE
-%{ (cl:let* ((address $body)
-	  (new-inst (cl:make-instance '$lclass :foreign-address address)))
-     (cl:setq ACL_ffresult new-inst)) %}
-#endif
-
-%typemap(lisptype) bool, const bool "cl:boolean";
-%typemap(lisptype) char, const char "cl:character";
-%typemap(lisptype) unsigned char, const unsigned char "cl:integer";
-%typemap(lisptype) signed char, const signed char "cl:integer";
-
-%typemap(ffitype) bool, const bool ":int";
-%typemap(ffitype) char, const char,
-		  signed char, const signed char ":char";
-%typemap(ffitype) unsigned char, const unsigned char ":unsigned-char";
-%typemap(ffitype) short, const short,
-		  signed short, const signed short ":short";
-%typemap(ffitype) unsigned short, const unsigned short ":unsigned-short";
-%typemap(ffitype) int, const int, signed int, const signed int ":int";
-%typemap(ffitype) unsigned int, const unsigned int ":unsigned-int";
-%typemap(ffitype) long, const long, signed long, const signed long ":long";
-%typemap(ffitype) unsigned long, const unsigned long ":unsigned-long";
-%typemap(ffitype) float, const float ":float";
-%typemap(ffitype) double, const double ":double";
-%typemap(ffitype) char *, const char *, signed char *,
-		  const signed char *, signed char &,
-		  const signed char &			 "(* :char)";
-%typemap(ffitype) unsigned char *, const unsigned char *,
-		  unsigned char &, const unsigned char & "(* :unsigned-char)";
-%typemap(ffitype) short *, const short *, short &,
-		  const short &				"(* :short)";
-%typemap(ffitype) unsigned short *, const unsigned short *,
-		  unsigned short &, const unsigned short & "(* :unsigned-short)";
-%typemap(ffitype) int *, const int *, int &, const int & "(* :int)";
-%typemap(ffitype) unsigned int *, const unsigned int *,
-		  unsigned int &, const unsigned int &	"(* :unsigned-int)";
-%typemap(ffitype) void * "(* :void)";
-%typemap(ffitype) void ":void";
-%typemap(ffitype) enum SWIGTYPE ":int";
-%typemap(ffitype) SWIGTYPE & "(* :void)";
-%typemap(ffitype) SWIGTYPE && "(* :void)";
-
-/* const typemaps
-idea: marshall all primitive c types to their respective lisp types
-to maintain const corretness. For pointers/references, all bets
-are off if you try to modify them.
-
-idea: add a constant-p slot to the base foreign-pointer class. For
-constant pointer/references check this value when setting (around method?)
-and error if a setf operation is performed on the address of this object.
-
-*/
-
-/* 
-%exception %{
-   try {
-      $action
-   } catch (...) {
-      return $null;
-   }
-%}
-
-*/
-
-// %typemap(throws) SWIGTYPE {
-//   (void)$1;
-//   SWIG_fail;
-// }
-
-%typemap(ctype) bool, const bool		"int";
-%typemap(ctype) char, unsigned char, signed char,
-                short, signed short, unsigned short,
-                int, signed int, unsigned int,
-                long, signed long, unsigned long,
-                float, double, long double, char *, void *, void,
-                enum SWIGTYPE, SWIGTYPE *, SWIGTYPE[],
-                SWIGTYPE[ANY], SWIGTYPE &, SWIGTYPE &&, const SWIGTYPE  "$1_ltype";
-%typemap(ctype) SWIGTYPE                   "$&1_type";
-
-%typemap(in) bool                          "$1 = (bool)$input;";
-%typemap(in) char, unsigned char, signed char,
-             short, signed short, unsigned short,
-             int, signed int, unsigned int,
-             long, signed long, unsigned long,
-             float, double, long double, char *, void *, void,
-             enum SWIGTYPE, SWIGTYPE *, SWIGTYPE[],
-             SWIGTYPE[ANY], SWIGTYPE &, SWIGTYPE && "$1 = $input;";
-%typemap(in) SWIGTYPE                      "$1 = *$input;";
-
-/* We don't need to do any actual C-side typechecking, but need to
-   use the precedence values to choose which overloaded function
-   interfaces to generate when conflicts arise. */
-
-/* predefined precedence values
-
-Symbolic Name                   Precedence Value
-------------------------------  ------------------
-SWIG_TYPECHECK_POINTER           0  
-SWIG_TYPECHECK_VOIDPTR           10 
-SWIG_TYPECHECK_BOOL              15 
-SWIG_TYPECHECK_UINT8             20 
-SWIG_TYPECHECK_INT8              25 
-SWIG_TYPECHECK_UINT16            30 
-SWIG_TYPECHECK_INT16             35 
-SWIG_TYPECHECK_UINT32            40 
-SWIG_TYPECHECK_INT32             45 
-SWIG_TYPECHECK_UINT64            50 
-SWIG_TYPECHECK_INT64             55 
-SWIG_TYPECHECK_UINT128           60 
-SWIG_TYPECHECK_INT128            65 
-SWIG_TYPECHECK_INTEGER           70 
-SWIG_TYPECHECK_FLOAT             80 
-SWIG_TYPECHECK_DOUBLE            90 
-SWIG_TYPECHECK_COMPLEX           100 
-SWIG_TYPECHECK_UNICHAR           110 
-SWIG_TYPECHECK_UNISTRING         120 
-SWIG_TYPECHECK_CHAR              130 
-SWIG_TYPECHECK_STRING            140 
-SWIG_TYPECHECK_BOOL_ARRAY        1015 
-SWIG_TYPECHECK_INT8_ARRAY        1025 
-SWIG_TYPECHECK_INT16_ARRAY       1035 
-SWIG_TYPECHECK_INT32_ARRAY       1045 
-SWIG_TYPECHECK_INT64_ARRAY       1055 
-SWIG_TYPECHECK_INT128_ARRAY      1065 
-SWIG_TYPECHECK_FLOAT_ARRAY       1080 
-SWIG_TYPECHECK_DOUBLE_ARRAY      1090 
-SWIG_TYPECHECK_CHAR_ARRAY        1130 
-SWIG_TYPECHECK_STRING_ARRAY      1140
-*/
-
-%typecheck(SWIG_TYPECHECK_BOOL) bool { $1 = 1; };
-%typecheck(SWIG_TYPECHECK_CHAR) char { $1 = 1; };
-%typecheck(SWIG_TYPECHECK_FLOAT) float { $1 = 1; };
-%typecheck(SWIG_TYPECHECK_DOUBLE) double { $1 = 1; };
-%typecheck(SWIG_TYPECHECK_STRING) char * { $1 = 1; };
-%typecheck(SWIG_TYPECHECK_INTEGER)
-                    unsigned char, signed char,
-                    short, signed short, unsigned short,
-                    int, signed int, unsigned int,
-                    long, signed long, unsigned long,
-                    enum SWIGTYPE { $1 = 1; };
-%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&,
-				   SWIGTYPE[], SWIGTYPE[ANY],
-				   SWIGTYPE { $1 = 1; };
-
-/* This maps C/C++ types to Lisp classes for overload dispatch */
-
-%typemap(lispclass) bool "t";
-%typemap(lispclass) char "cl:character";
-%typemap(lispclass) unsigned char, signed char,
-                    short, signed short, unsigned short,
-                    int, signed int, unsigned int,
-                    long, signed long, unsigned long,
-                    enum SWIGTYPE       "cl:integer";
-%typemap(lispclass) float "cl:single-float";
-%typemap(lispclass) double "cl:double-float";
-%typemap(lispclass) char * "cl:string";
-
-%typemap(out) void                          "";
-%typemap(out) bool                          "$result = (int)$1;";
-%typemap(out) char, unsigned char, signed char,
-              short, signed short, unsigned short,
-              int, signed int, unsigned int,
-              long, signed long, unsigned long,
-              float, double, long double, char *, void *,
-              enum SWIGTYPE, SWIGTYPE *,
-              SWIGTYPE[ANY], SWIGTYPE &, SWIGTYPE && "$result = $1;";
-#ifdef __cplusplus
-%typemap(out) SWIGTYPE                     "$result = new $1_ltype($1);";
-#else
-%typemap(out) SWIGTYPE {
-  $result = ($&1_ltype) malloc(sizeof($1_type));
-  memmove($result, &$1, sizeof($1_type));
-}
-#endif
-
-//////////////////////////////////////////////////////////////
-// UCS-2 string conversion
-
-// should this be SWIG_TYPECHECK_CHAR?
-%typecheck(SWIG_TYPECHECK_UNICHAR) wchar_t { $1 = 1; };
-
-%typemap(in)        wchar_t "$1 = $input;";
-%typemap(lin,numinputs=1)       wchar_t "(cl::let (($out (cl:char-code $in)))\n  $body)";
-%typemap(lin,numinputs=1)       wchar_t * "(excl:with-native-string ($out $in
-:external-format #+little-endian :fat-le #-little-endian :fat)\n
-$body)"
-
-%typemap(out)       wchar_t "$result = $1;";
-%typemap(lout)      wchar_t "(cl::setq ACL_ffresult (cl::code-char $body))";
-%typemap(lout)      wchar_t * "(cl::setq ACL_ffresult (excl:native-to-string $body
-:external-format #+little-endian :fat-le #-little-endian :fat))";
-
-%typemap(ffitype)   wchar_t ":unsigned-short";
-%typemap(lisptype)  wchar_t "";
-%typemap(ctype)     wchar_t "wchar_t";
-%typemap(lispclass) wchar_t "cl:character";
-%typemap(lispclass) wchar_t * "cl:string";
-//////////////////////////////////////////////////////////////
-
-/* Array reference typemaps */
-%apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) }
-%apply SWIGTYPE && { SWIGTYPE ((&&)[ANY]) }
-
-/* const pointers */
-%apply SWIGTYPE * { SWIGTYPE *const }
-%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) }
-%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) }
-
-/* name conversion for overloaded operators. */
-#ifdef __cplusplus
-%rename(__add__)	     *::operator+;
-%rename(__pos__)	     *::operator+();
-%rename(__pos__)	     *::operator+() const;
-
-%rename(__sub__)	     *::operator-;
-%rename(__neg__)	     *::operator-() const;
-%rename(__neg__)	     *::operator-();
-
-%rename(__mul__)	     *::operator*;
-%rename(__deref__)	     *::operator*();
-%rename(__deref__)	     *::operator*() const;
-
-%rename(__div__)	     *::operator/;
-%rename(__mod__)	     *::operator%;
-%rename(__logxor__)	     *::operator^;
-%rename(__logand__)	     *::operator&;
-%rename(__logior__)	     *::operator|;
-%rename(__lognot__)	     *::operator~();
-%rename(__lognot__)	     *::operator~() const;
-
-%rename(__not__)	     *::operator!();
-%rename(__not__)	     *::operator!() const;
-
-%rename(__assign__)	     *::operator=;
-
-%rename(__add_assign__)      *::operator+=;
-%rename(__sub_assign__)	     *::operator-=;
-%rename(__mul_assign__)	     *::operator*=;
-%rename(__div_assign__)	     *::operator/=;
-%rename(__mod_assign__)	     *::operator%=;
-%rename(__logxor_assign__)   *::operator^=;
-%rename(__logand_assign__)   *::operator&=;
-%rename(__logior_assign__)   *::operator|=;
-
-%rename(__lshift__)	     *::operator<<;
-%rename(__lshift_assign__)   *::operator<<=;
-%rename(__rshift__)	     *::operator>>;
-%rename(__rshift_assign__)   *::operator>>=;
-
-%rename(__eq__)		     *::operator==;
-%rename(__ne__)		     *::operator!=;
-%rename(__lt__)		     *::operator<;
-%rename(__gt__)		     *::operator>;
-%rename(__lte__)	     *::operator<=;
-%rename(__gte__)	     *::operator>=;
-
-%rename(__and__)	     *::operator&&;
-%rename(__or__)		     *::operator||;
-
-%rename(__preincr__)	     *::operator++();
-%rename(__postincr__)	     *::operator++(int);
-%rename(__predecr__)	     *::operator--();
-%rename(__postdecr__)	     *::operator--(int);
-
-%rename(__comma__)	     *::operator,();
-%rename(__comma__)	     *::operator,() const;
-
-%rename(__member_ref__)      *::operator->;
-%rename(__member_func_ref__) *::operator->*;
-
-%rename(__funcall__)	     *::operator();
-%rename(__aref__)	     *::operator[];
-
-%rename(__bool__)	     *::operator bool();
-%rename(__bool__)	     *::operator bool() const;
-#endif
-
-%insert("lisphead") %{
-(eval-when (:compile-toplevel :load-toplevel :execute)
-
-  ;; avoid compiling ef-templates at runtime
-  (excl:find-external-format :fat)
-  (excl:find-external-format :fat-le)
-
-;;; You can define your own identifier converter if you want.
-;;; Use the -identifier-converter command line argument to
-;;; specify its name.
-
-(eval-when (:compile-toplevel :load-toplevel :execute)
-   (cl::defparameter *swig-export-list* nil))
-
-(cl::defconstant *void* :..void..)
-
-;; parsers to aid in finding SWIG definitions in files.
-(cl::defun scm-p1 (form)
-  (let* ((info (cl::second form))
-	 (id (car info))
-	 (id-args (if (eq (cl::car form) 'swig-dispatcher)
-		      (cl::cdr info)
-		      (cl::cddr info))))
-    (cl::apply *swig-identifier-converter* id 
-	   (cl::progn (cl::when (cl::eq (cl::car form) 'swig-dispatcher)
-		    (cl::remf id-args :arities))
-		  id-args))))
-
-(cl::defmacro defswig1 (name (&rest args) &body body)
-  `(cl::progn (cl::defmacro ,name ,args
-	    ,@body)
-	  (excl::define-simple-parser ,name scm-p1)) )
-
-(cl::defmacro defswig2 (name (&rest args) &body body)
-  `(cl::progn (cl::defmacro ,name ,args
-	    ,@body)
-	  (excl::define-simple-parser ,name second)))
-
-(defun read-symbol-from-string (string)
-  (cl::multiple-value-bind (result position)
-      (cl::read-from-string string nil "eof" :preserve-whitespace t)
-    (cl::if (cl::and (cl::symbolp result)
-    	             (cl::eql position (cl::length string)))
-        result
-	(cl::multiple-value-bind (sym)
-	    (cl::intern string)
-	  sym))))
-
-(cl::defun full-name (id type arity class)
-  ; We need some kind of a hack here to handle template classes
-  ; and other synonym types right. We need the original name.
-  (let*( (sym (read-symbol-from-string 
-                (if (eq *swig-identifier-converter* 'identifier-convert-lispify)
-                  (string-lispify id)
-                  id)))
-         (sym-class (find-class sym nil))
-         (id (cond ( (not sym-class)
-                     id )
-                   ( (and sym-class
-                          (not (eq (class-name sym-class)
-                                sym)))
-                     (class-name sym-class) )
-                   ( t
-                     id ))) )
-    (cl::case type
-      (:getter (cl::format nil "~@[~A_~]~A" class id))
-      (:constructor (cl::format nil "new_~A~@[~A~]" id arity))
-      (:destructor (cl::format nil "delete_~A" id))
-      (:type (cl::format nil "ff_~A" id))
-      (:slot id)
-      (:ff-operator (cl::format nil "ffi_~A" id))
-      (otherwise (cl::format nil "~@[~A_~]~A~@[~A~]"
-                         class id arity)))))
-  
-(cl::defun identifier-convert-null (id &key type class arity)
-  (cl::if (cl::eq type :setter)
-      `(cl::setf ,(identifier-convert-null
-               id :type :getter :class class :arity arity))
-      (read-symbol-from-string (full-name id type arity class))))
-
-(cl::defun string-lispify (str)
-  (cl::let ( (cname (excl::replace-regexp str "_" "-"))
-             (lastcase :other)
-             newcase char res ) 
-    (cl::dotimes (n (cl::length cname))
-      (cl::setf char (cl::schar cname n))
-      (excl::if* (cl::alpha-char-p char)
-         then
-              (cl::setf newcase (cl::if (cl::upper-case-p char) :upper :lower))
-              (cl::when (cl::and (cl::eq lastcase :lower)
-                                 (cl::eq newcase :upper))
-                ;; case change... add a dash
-                (cl::push #\- res)
-                (cl::setf newcase :other))
-              (cl::push (cl::char-downcase char) res)
-              (cl::setf lastcase newcase)
-         else
-              (cl::push char res)
-              (cl::setf lastcase :other)))
-    (cl::coerce (cl::nreverse res) 'string)))
-  
-(cl::defun identifier-convert-lispify (cname &key type class arity)
-  (cl::assert (cl::stringp cname))
-  (cl::when (cl::eq type :setter)
-    (cl::return-from identifier-convert-lispify
-      `(cl::setf ,(identifier-convert-lispify
-               cname :type :getter :class class :arity arity))))
-  (cl::setq cname (full-name cname type arity class))
-  (cl::if (cl::eq type :constant)
-      (cl::setf cname (cl::format nil "*~A*" cname)))
-  (read-symbol-from-string (string-lispify cname)))
-
-(cl::defun id-convert-and-export (name &rest kwargs)
-  (cl::multiple-value-bind (symbol package)
-      (cl::apply *swig-identifier-converter* name kwargs)
-    (cl::let ((args (cl::list (cl::if (cl::consp symbol)
-    	     	    	         (cl::cadr symbol) symbol)
-                      (cl::or package cl::*package*))))
-      (cl::apply #'cl::export args)
-      (cl::pushnew args *swig-export-list*))
-    symbol))
-
-(cl::defmacro swig-insert-id (name namespace &key (type :type) class)
-  `(cl::let ((cl::*package* (cl::find-package ,(package-name-for-namespace namespace))))
-    (id-convert-and-export ,name :type ,type :class ,class)))
-
-(defswig2 swig-defconstant (string value)
-  (cl::let ((symbol (id-convert-and-export string :type :constant)))
-    `(cl::eval-when (:compile-toplevel :load-toplevel :execute)
-       (cl::defconstant ,symbol ,value))))
-
-(cl::defun maybe-reorder-args (funcname arglist)
-  ;; in the foreign setter function the new value will be the last argument
-  ;; in Lisp it needs to be the first
-  (cl::if (cl::consp funcname)
-      (cl::append (cl::last arglist) (cl::butlast arglist))
-      arglist))
-
-(cl::defun maybe-return-value (funcname arglist)
-  ;; setf functions should return the new value
-  (cl::when (cl::consp funcname)
-    `(,(cl::if (cl::consp (cl::car arglist))
-           (cl::caar arglist)
-           (cl::car arglist)))))
-
-(cl::defun swig-anyvarargs-p (arglist)
-  (cl::member :SWIG__varargs_ arglist))
-
-(defswig1 swig-defun ((name &optional (mangled-name name)
-                            &key (type :operator) class arity)
-                      arglist kwargs
-		      &body body)
-  (cl::let* ((symbol (id-convert-and-export name :type type
-                          :arity arity :class class))
-             (mangle (excl::if* (cl::string-equal name mangled-name)
-                      then (id-convert-and-export 
-				    (cl::cond
-					  ((cl::eq type :setter) (cl::format nil "~A-set" name))
-					  ((cl::eq type :getter) (cl::format nil "~A-get" name))
-					  (t name))
-				    :type :ff-operator :arity arity :class class)
-                      else (cl::intern mangled-name)))
-         (defun-args (maybe-reorder-args
-                      symbol
-		      (cl::mapcar #'cl::car (cl::and (cl::not (cl::equal arglist '(:void)))
-					 (cl::loop as i in arglist
-					       when (cl::eq (cl::car i) :p+)
-					       collect (cl::cdr i))))))
-	 (ffargs (cl::if (cl::equal arglist '(:void))
-	 	      arglist
-		    (cl::mapcar #'cl::cdr arglist)))
-	 )
-    (cl::when (swig-anyvarargs-p ffargs)
-      (cl::setq ffargs '()))
-    `(cl::eval-when (:compile-toplevel :load-toplevel :execute)
-       (excl::compiler-let ((*record-xref-info* nil))
-         (ff:def-foreign-call (,mangle ,mangled-name) ,ffargs ,@kwargs))
-       (cl::macrolet ((swig-ff-call (&rest args)
-                      (cl::cons ',mangle args)))
-         (cl::defun ,symbol ,defun-args
-           ,@body
-           ,@(maybe-return-value symbol defun-args))))))
-
-(defswig1 swig-defmethod ((name &optional (mangled-name name)
-	  	                &key (type :operator) class arity)
-                          ffargs kwargs
-                          &body body)
-  (cl::let* ((symbol (id-convert-and-export name :type type
-                          :arity arity :class class))
-         (mangle (cl::intern mangled-name))
-         (defmethod-args (maybe-reorder-args
-                          symbol
-                          (cl::unless (cl::equal ffargs '(:void))
-                            (cl::loop for (lisparg name dispatch) in ffargs
-			    	  when (eq lisparg :p+)
-                                  collect `(,name ,dispatch)))))
-         (ffargs (cl::if (cl::equal ffargs '(:void))
-                     ffargs
-                     (cl::loop for (nil name nil . ffi) in ffargs
-                           collect `(,name ,@ffi)))))
-    `(cl::eval-when (:compile-toplevel :load-toplevel :execute)
-       (excl::compiler-let ((*record-xref-info* nil))
-         (ff:def-foreign-call (,mangle ,mangled-name) ,ffargs ,@kwargs))
-       (cl::macrolet ((swig-ff-call (&rest args)
-                      (cl::cons ',mangle args)))
-         (cl::defmethod ,symbol ,defmethod-args
-           ,@body
-           ,@(maybe-return-value symbol defmethod-args))))))
-
-(defswig1 swig-dispatcher ((name &key (type :operator) class arities))
-  (cl::let ((symbol (id-convert-and-export name
-                         :type type :class class)))
-    `(cl::eval-when (:compile-toplevel :load-toplevel :execute)
-       (cl::defun ,symbol (&rest args)
-         (cl::case (cl::length args)
-           ,@(cl::loop for arity in arities
-                   for symbol-n = (id-convert-and-export name
-                                           :type type :class class :arity arity)
-                   collect `(,arity (cl::apply #',symbol-n args)))
-	   (t (cl::error "No applicable wrapper-methods for foreign call ~a with args ~a of classes ~a" ',symbol args (cl::mapcar #'(cl::lambda (x) (cl::class-name (cl::class-of x))) args)))
-	   )))))
-
-(defswig2 swig-def-foreign-stub (name)
-  (cl::let ((lsymbol (id-convert-and-export name :type :class))
-	    (symbol (id-convert-and-export name :type :type)))
-    `(cl::eval-when (:compile-toplevel :load-toplevel :execute)
-	(ff:def-foreign-type ,symbol (:class ))
-	(cl::defclass ,lsymbol (ff:foreign-pointer) ()))))
-
-(defswig2 swig-def-foreign-class (name supers &rest rest)
-  (cl::let ((lsymbol (id-convert-and-export name :type :class))
-	    (symbol (id-convert-and-export name :type :type)))
-    `(cl::eval-when (:compile-toplevel :load-toplevel :execute)
-       (ff:def-foreign-type ,symbol ,@rest)
-       (cl::defclass ,lsymbol ,supers
-	 ((foreign-type :initform ',symbol :initarg :foreign-type
-			:accessor foreign-pointer-type))))))
-
-(defswig2 swig-def-foreign-type (name &rest rest)
-  (cl::let ((symbol (id-convert-and-export name :type :type)))
-    `(cl::eval-when (:compile-toplevel :load-toplevel :execute)
-       (ff:def-foreign-type ,symbol ,@rest))))
-
-(defswig2 swig-def-synonym-type (synonym of ff-synonym)
-  `(cl::eval-when (:compile-toplevel :load-toplevel :execute)
-     (cl::setf (cl::find-class ',synonym) (cl::find-class ',of))
-     (ff:def-foreign-type ,ff-synonym (:struct ))))
-
-(cl::defun package-name-for-namespace (namespace)
-  (excl::list-to-delimited-string
-   (cl::cons *swig-module-name*
-         (cl::mapcar #'(cl::lambda (name)
-                     (cl::string
-                      (cl::funcall *swig-identifier-converter*
-                               name
-                               :type :namespace)))
-                 namespace))
-   "."))
-
-(cl::defmacro swig-defpackage (namespace)
-  (cl::let* ((parent-namespaces (cl::maplist #'cl::reverse (cl::cdr (cl::reverse namespace))))
-             (parent-strings (cl::mapcar #'package-name-for-namespace
-                                 parent-namespaces))
-             (string (package-name-for-namespace namespace)))
-    `(cl::eval-when (:compile-toplevel :load-toplevel :execute)
-      (cl::defpackage ,string
-        (:use :swig :ff #+ignore '(:common-lisp :ff :excl)
-              ,@parent-strings ,*swig-module-name*)
-	(:import-from :cl :* :nil :t)))))
-
-(cl::defmacro swig-in-package (namespace)
-  `(cl::eval-when (:compile-toplevel :load-toplevel :execute)
-    (cl::in-package ,(package-name-for-namespace namespace))))
-
-(defswig2 swig-defvar (name mangled-name &key type (ftype :unsigned-natural))
-  (cl::let ((symbol (id-convert-and-export name :type type)))
-    `(cl::eval-when (:compile-toplevel :load-toplevel :execute)
-      (ff:def-foreign-variable (,symbol ,mangled-name) :type ,ftype))))
-
-) ;; eval-when
-
-(cl::eval-when (:compile-toplevel :execute)
-  (cl::flet ((starts-with-p (str prefix)
-              (cl::and (cl::>= (cl::length str) (cl::length prefix))
-                (cl::string= str prefix :end1 (cl::length prefix)))))
-    (cl::export (cl::loop for sym being each present-symbol of cl::*package*
-                  when (cl::or (starts-with-p (cl::symbol-name sym) (cl::symbol-name :swig-))
-                           (starts-with-p (cl::symbol-name sym) (cl::symbol-name :identifier-convert-)))
-                  collect sym))))
-
-%}
-
-typedef void *__SWIGACL_FwdReference;
-
-%{
-
-#ifdef __cplusplus
-#  define EXTERN   extern "C"
-#else
-#  define EXTERN   extern
-#endif
-
-#define EXPORT   EXTERN SWIGEXPORT
-
-typedef void *__SWIGACL_FwdReference;
-
-#include <string.h>
-#include <stdlib.h>
-%}
diff --git a/Lib/allegrocl/inout_typemaps.i b/Lib/allegrocl/inout_typemaps.i
deleted file mode 100644
index d8d61fe..0000000
--- a/Lib/allegrocl/inout_typemaps.i
+++ /dev/null
@@ -1,111 +0,0 @@
-/* inout_typemaps.i
-
-   Support for INPUT, OUTPUT, and INOUT typemaps. OUTPUT variables are returned
-   as multiple values.
-
-*/
-
-
-/* Note that this macro automatically adds a pointer to the type passed in.
-   As a result, INOUT typemaps for char are for 'char *'. The definition
-   of typemaps for 'char' takes advantage of this, believing that it's more
-   likely to see an INOUT argument for strings, than a single char. */
-%define INOUT_TYPEMAP(type_, OUTresult_, INbind_)
-// OUTPUT map.
-%typemap(lin,numinputs=0) type_ *OUTPUT, type_ &OUTPUT
-%{(cl::let (($out (ff:allocate-fobject '$*in_fftype :c)))
-     $body
-     OUTresult_
-     (ff:free-fobject $out)) %}
-
-// INPUT map.
-%typemap(in) type_ *INPUT, type_ &INPUT
-%{ $1 = &$input; %}
-
-%typemap(ctype) type_ *INPUT, type_ &INPUT "$*1_ltype";
-
-
-// INOUT map.
-// careful here. the input string is converted to a C string
-// with length equal to the input string. This should be large
-// enough to contain whatever OUTPUT value will be stored in it.
-%typemap(lin,numinputs=1) type_ *INOUT, type_ &INOUT
-%{(cl::let (($out (ff:allocate-fobject '$*in_fftype :c)))
-     INbind_
-     $body
-     OUTresult_
-     (ff:free-fobject $out)) %}
-
-%enddef
-
-// $in, $out, $lclass,
-// $in_fftype, $*in_fftype
-
-INOUT_TYPEMAP(int,
-	      (cl::push (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out) ACL_result),
-	      (cl::setf (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out) $in));
-INOUT_TYPEMAP(short,
-	      (cl::push (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out) ACL_result),
-	      (cl::setf (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out) $in));
-INOUT_TYPEMAP(long,
-	      (cl::push (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out) ACL_result),
-	      (cl::setf (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out) $in));
-INOUT_TYPEMAP(unsigned int,
-	      (cl::push (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out) ACL_result),
-	      (cl::setf (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out) $in));
-INOUT_TYPEMAP(unsigned short,
-	      (cl::push (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out) ACL_result),
-	      (cl::setf (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out) $in));
-INOUT_TYPEMAP(unsigned long,
-	      (cl::push (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out) ACL_result),
-	      (cl::setf (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out) $in));
-// char * mapping for passing strings. didn't quite work
-// INOUT_TYPEMAP(char,
-//              (cl::push (excl:native-to-string $out) ACL_result),
-//	      (cl::setf (ff:fslot-value-typed (cl::quote $in_fftype) :c $out)
-//		    (excl:string-to-native $in)))
-INOUT_TYPEMAP(float,
-	      (cl::push (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out) ACL_result),
-	      (cl::setf (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out) $in));
-INOUT_TYPEMAP(double,
-	      (cl::push (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out) ACL_result),
-	      (cl::setf (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out) $in));
-INOUT_TYPEMAP(bool,
-	      (cl::push (not (zerop (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out)))
-		    ACL_result),
-	      (cl::setf (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out) (if $in 1 0)));
-
-%typemap(lisptype) bool *INPUT, bool &INPUT "boolean";
-
-// long long support not yet complete
-// INOUT_TYPEMAP(long long);
-// INOUT_TYPEMAP(unsigned long long);
-
-// char *OUTPUT map.
-// for this to work, swig needs to know how large an array to allocate.
-// you can fake this by 
-// %typemap(ffitype) char *myarg	"(:array :char 30)";
-// %apply char *OUTPUT { char *myarg };
-%typemap(lin,numinputs=0) char *OUTPUT, char &OUTPUT
-%{(cl::let (($out (ff:allocate-fobject '$*in_fftype :c)))
-     $body
-     (cl::push (excl:native-to-string $out) ACL_result)
-     (ff:free-fobject $out)) %}
-
-// char *INPUT map.
-%typemap(in) char *INPUT, char &INPUT
-%{ $1 = &$input; %}
-%typemap(ctype) char *INPUT, char &INPUT "$*1_ltype";
-
-// char *INOUT map.
-%typemap(lin,numinputs=1) char *INOUT, char &INOUT
-%{(cl::let (($out (excl:string-to-native $in)))
-     $body
-     (cl::push (excl:native-to-string $out) ACL_result)
-     (ff:free-fobject $out)) %}
-
-// uncomment this if you want INOUT mappings for chars instead of strings.
-// INOUT_TYPEMAP(char,
-// 	      (cl::push (code-char (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out))
-//		    ACL_result),
-//	      (cl::setf (ff:fslot-value-typed (cl::quote $*in_fftype) :c $out) $in));
diff --git a/Lib/allegrocl/longlongs.i b/Lib/allegrocl/longlongs.i
deleted file mode 100644
index a15adcd..0000000
--- a/Lib/allegrocl/longlongs.i
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -----------------------------------------------------------------------------
- * longlongs.i
- *
- * Typemap addition for support of 'long long' type and 'unsigned long long 
- * Makes use of swig-def-foreign-class, so this header should be loaded
- * after allegrocl.swg and after any custom user identifier-conversion
- * functions have been defined.
- * ----------------------------------------------------------------------------- */
-
-#ifdef Acl64Bit
-%typemap(ctype) long long, unsigned long long "$1_ltype";
-%typemap(out) long long, unsigned long long "$result = $1;";
-
-%typemap(ffitype) long long ":nat";
-%typemap(ffitype) unsigned long long ":unsigned-nat";
-
-%typemap(lout) long long, unsigned long long "  #+64bit (cl::setq ACL_ffresult $body)";
-
-#else
-%typemap(out) long long, unsigned long long "$result = &$1;";
-%typemap(ffitype) long long "(:struct (l1 :long) (l2 :long))";
-
-%typemap(ffitype) unsigned long long "(:struct (l1 :unsigned-long) (l2 :unsigned-long))";
-
-%typemap(lout) long long 
-"  (cl::setq ACL_ffresult (make-instance '#.(swig-insert-id \"longlong\" () :type :class)
-                  :foreign-address $body))";
-
-%typemap(lout) unsigned long long
-"  (cl:setq ACL_ffresult (make-instance '#.(swig-insert-id \"ulonglong\" () :type :class)
-                  :foreign-address $body))";
-
-#endif
-
-%typemap(in) long long, unsigned long long "$1 = $input;";
-
-
-%insert("lisphead") %{
-
-#-64bit
-(swig-def-foreign-class "longlong"
- (ff:foreign-pointer)
- (:struct (l1 :long) (l2 :long)))
-
-#-64bit
-(swig-def-foreign-class "ulonglong"
- (ff:foreign-pointer)
- (:struct (l1 :unsigned-long) (l2 :unsigned-long)))
-%}
diff --git a/Lib/allegrocl/std_list.i b/Lib/allegrocl/std_list.i
deleted file mode 100644
index a3660c9..0000000
--- a/Lib/allegrocl/std_list.i
+++ /dev/null
@@ -1,230 +0,0 @@
-/* -----------------------------------------------------------------------------
- * std_list.i
- *
- * SWIG typemaps for std::list types
- * 
- * To use, add:
- * 
- * %include "std_list.i"
- *
- * to your interface file. You will also need to include a template directive
- * for each instance of the list container you want to use in your application.
- * e.g.
- * 
- * %template (intlist) std::list<int>;
- * %template (floatlist) std::list<float>;
- * ----------------------------------------------------------------------------- */
-
-%module std_list
-%warnfilter(468) std::list;
-
-%{
-#include <list>
-#include <stdexcept>
-%}
-
-
-namespace std{
-    template<class T> class list
-    {
-    public:
-        typedef size_t size_type;
-        typedef ptrdiff_t difference_type;
-        typedef T value_type;
-        typedef value_type* pointer;
-        typedef const value_type* const_pointer;
-        typedef value_type& reference;
-        typedef const value_type& const_reference;
-	typedef T &iterator;
-	typedef const T& const_iterator; 
-
-	list();
-	list(unsigned int size, const T& value = T());
-	list(const list& other);
-
-	void assign(unsigned int n, const T& value);
-	void swap(list<T> &x);
-
-	const_reference front();
-	const_reference back();
-	const_iterator begin();
-	const_iterator end();
-
-	void resize(unsigned int n, T c = T());
-	bool empty() const;
-
-	void push_front(const T& INPUT);
-	void push_back(const T& INPUT);
-
-	void pop_front();
-	void pop_back();
-	void clear();
-	unsigned int size() const;
-	unsigned int max_size() const;
-	void resize(unsigned int n, const T& INPUT);
-
-	void remove(const T& INPUT);
-	void unique();
-	void reverse();
-	void sort();
-
-	%extend 
-	    {
-	        %typemap(lout) T &__getitem__ "(cl::setq ACL_ffresult (ff:fslot-value-typed '$*out_fftype :c $body))";
-		%typemap(lout) T *__getitem__ "(cl::setq ACL_ffresult (make-instance '$lclass :foreign-address $body))";
-
-		const_reference __getitem__(int i) throw (std::out_of_range) 
-		    {
-			std::list<T>::iterator first = self->begin(); 
-			int size = int(self->size());
-			if (i<0) i += size;
-			if (i>=0 && i<size)
-			{
-			    for (int k=0;k<i;k++)
-			    {
-				first++;
-			    }
-			    return *first;
-			}
-			else throw std::out_of_range("list index out of range");
-		    }
-		void __setitem__(int i, const T& INPUT) throw (std::out_of_range)
-		    {
-			std::list<T>::iterator first = self->begin(); 
-			int size = int(self->size());
-			if (i<0) i += size;
-			if (i>=0 && i<size)
-			{
-			    for (int k=0;k<i;k++)
-			    {
-				first++;
-			    }
-			    *first = INPUT;
-			}
-			else throw std::out_of_range("list index out of range");
-		    }
-		void __delitem__(int i) throw (std::out_of_range)
-		    {
-			std::list<T>::iterator first = self->begin(); 
-			int size = int(self->size());
-			if (i<0) i += size;
-			if (i>=0 && i<size)
-			{
-			    for (int k=0;k<i;k++)
-			    {
-				first++;
-			    }
-			    self->erase(first);
-			}
-			else throw std::out_of_range("list index out of range");
-		    }	     
-		std::list<T> __getslice__(int i,int j) 
-		    {
-			std::list<T>::iterator first = self->begin();
-			std::list<T>::iterator end = self->end();
-
-			int size = int(self->size());
-			if (i<0) i += size;
-			if (j<0) j += size;
-			if (i<0) i = 0;
-			if (j>size) j = size;
-			if (i>=j) i=j;
-			if (i>=0 && i<size && j>=0)
-			{
-			    for (int k=0;k<i;k++)
-			    {
-				first++;
-			    }
-			    for (int m=0;m<j;m++)
-			    {
-				end++;
-			    }
-			    std::list<T> tmp(j-i);
-			    if (j>i) std::copy(first,end,tmp.begin());
-			    return tmp;
-			}
-			else throw std::out_of_range("list index out of range");
-		    }
-		void __delslice__(int i,int j) 
-		    {
-			std::list<T>::iterator first = self->begin();
-			std::list<T>::iterator end = self->end();
-
-			int size = int(self->size());
-			if (i<0) i += size;
-			if (j<0) j += size;
-			if (i<0) i = 0;
-			if (j>size) j = size;
-
-			for (int k=0;k<i;k++)
-			{
-			    first++;
-			}
-			for (int m=0;m<=j;m++)
-			{
-			    end++;
-			}		   
-			self->erase(first,end);		
-		    }
-		void __setslice__(int i,int j, const std::list<T>& v) 
-		    {
-			std::list<T>::iterator first = self->begin();
-			std::list<T>::iterator end = self->end();
-
-			int size = int(self->size());
-			if (i<0) i += size;
-			if (j<0) j += size;
-			if (i<0) i = 0;
-			if (j>size) j = size;
-
-			for (int k=0;k<i;k++)
-			{
-			    first++;
-			}
-			for (int m=0;m<=j;m++)
-			{
-			    end++;
-			}
-			if (int(v.size()) == j-i) 
-			{
-			    std::copy(v.begin(),v.end(),first);
-			}
-			else {
-			    self->erase(first,end);
-			    if (i+1 <= int(self->size())) 
-			    {
-				first = self->begin();
-				for (int k=0;k<i;k++)
-				{
-				    first++;
-				}
-				self->insert(first,v.begin(),v.end());
-			    }
-			    else self->insert(self->end(),v.begin(),v.end());
-			}
-		    }
-		unsigned int __len__() 
-		    {
-			return self->size();
-		    }	
-		bool __nonzero__()
-		    {
-			return !(self->empty());
-		    }
-		void append(const T& INPUT)
-		    {
-			self->push_back(INPUT);
-		    }
-		void pop()
-		    {
-			self->pop_back();
-		    }
-	    }
-    };
-}
-
-
-
-
-
-
diff --git a/Lib/allegrocl/std_string.i b/Lib/allegrocl/std_string.i
deleted file mode 100644
index cbcd250..0000000
--- a/Lib/allegrocl/std_string.i
+++ /dev/null
@@ -1,209 +0,0 @@
-/* -----------------------------------------------------------------------------
- * std_string.i
- *
- * SWIG typemaps for std::string
- * ----------------------------------------------------------------------------- */
-
-// ------------------------------------------------------------------------
-// std::string is typemapped by value
-// This can prevent exporting methods which return a string
-// in order for the user to modify it.
-// However, I think I'll wait until someone asks for it...
-// ------------------------------------------------------------------------
-
-// %include <exception.i>
-%warnfilter(404) std::string;
-%warnfilter(404) std::wstring;
-
-%{
-#include <string>
-%}
-
-// %include <std_vector.i>
-
-// %naturalvar std::string;
-// %naturalvar std::wstring;
-
-namespace std {
-    typedef unsigned long size_t;
-    typedef signed long ptrdiff_t;
-
-    template <class charT> class basic_string {
-    public:
-	typedef charT *pointer;
-	typedef charT &reference;
-	typedef const charT &const_reference;
-	typedef size_t size_type;
-	typedef ptrdiff_t difference_type;
-	basic_string();
-	basic_string( charT *str );
-	size_type size();
-	charT operator []( int pos ) const;
-	charT *c_str() const;
-	basic_string<charT> &operator = ( const basic_string &ws );
-	basic_string<charT> &operator = ( const charT *str );
-	basic_string<charT> &append( const basic_string<charT> &other );
-	basic_string<charT> &append( const charT *str );
-	void push_back( charT c );
-	void clear();
-	void reserve( size_type t );
-	void resize( size_type n, charT c = charT() );
-	int compare( const basic_string<charT> &other ) const;
-	int compare( const charT *str ) const;
-	basic_string<charT> &insert( size_type pos, 
-				     const basic_string<charT> &str );
-	size_type find( const basic_string<charT> &other, int pos = 0 ) const;
-	size_type find( charT c, int pos = 0 ) const;
-	%extend {
-	    bool operator == ( const basic_string<charT> &other ) const {
-		return self->compare( other ) == 0;
-	    }
-	    bool operator != ( const basic_string<charT> &other ) const {
-		return self->compare( other ) != 0;
-	    }
-	    bool operator < ( const basic_string<charT> &other ) const {
-		return self->compare( other ) == -1;
-	    }
-	    bool operator > ( const basic_string<charT> &other ) const {
-		return self->compare( other ) == 1;
-	    }
-	    bool operator <= ( const basic_string<charT> &other ) const {
-		return self->compare( other ) != 1;
-	    }
-	    bool operator >= ( const basic_string<charT> &other ) const {
-		return self->compare( other ) != -1;
-	    }
-
-	}
-    };
-
-    %template(string) basic_string<char>;
-    %template(wstring) basic_string<wchar_t>;
-
-    %apply char * { string };
-    %apply wchar_t * { wstring };
-
-    typedef basic_string<char> string;
-    typedef basic_string<wchar_t> wstring;
-
-    // automatically convert constant std::strings to cl:strings
-    %typemap(ctype) string "char *";
-    %typemap(in) string "$1.assign($input);";
-    %typemap(out) string "$result = (char *)(&$1)->c_str();";
-    %typemap(lisptype) string "cl:string";
-    %typemap(lout) string "(cl::setq ACL_ffresult $body)";
-
-    %typemap(ctype) const string *"char *";
-    %typemap(in) const string * "$1.assign($input);";
-    %typemap(out) const string * "$result = (char *)($1)->c_str();";
-    %typemap(lisptype) const string * "cl:string";
-    %typemap(lout) const string * "(cl::setq ACL_ffresult $body)";
-
-    %typemap(ctype) wstring "wchar_t *";
-    %typemap(in) wstring "$1.assign($input);";
-    %typemap(out) wstring "$result = (wchar_t *)(&$1)->c_str();";
-    %typemap(lisptype) wstring "cl:string";
-    %typemap(lout) wstring "(cl::setq ACL_ffresult (excl:native-to-string $body
-:external-format #+little-endian :fat-le #-little-endian :fat))";
-
-    %typemap(ctype) const wstring *"char *";
-    %typemap(in) const wstring * "$1.assign($input);";
-    %typemap(out) const wstring * "$result = (char *)($1)->c_str();";
-    %typemap(lisptype) const wstring * "cl:string";
-    %typemap(lout) const wstring * "(cl::setq ACL_ffresult $body)";
-
-    /* Overloading check */
-//     %typemap(in) string {
-//         if (caml_ptr_check($input))
-//             $1.assign((char *)caml_ptr_val($input,0),
-// 			 caml_string_len($input));
-//         else
-//             SWIG_exception(SWIG_TypeError, "string expected");
-//     }
-
-//     %typemap(in) const string & ($*1_ltype temp) {
-//         if (caml_ptr_check($input)) {
-//             temp.assign((char *)caml_ptr_val($input,0),
-// 			   caml_string_len($input));
-//             $1 = &temp;
-//         } else {
-//             SWIG_exception(SWIG_TypeError, "string expected");
-//         }
-//     }
-
-//     %typemap(in) string & ($*1_ltype temp) {
-//         if (caml_ptr_check($input)) {
-//             temp.assign((char *)caml_ptr_val($input,0),
-// 			   caml_string_len($input));
-//             $1 = &temp;
-//         } else {
-//             SWIG_exception(SWIG_TypeError, "string expected");
-//         }
-//     }
-
-//     %typemap(in) string * ($*1_ltype *temp) {
-//         if (caml_ptr_check($input)) {
-//             temp = new $*1_ltype((char *)caml_ptr_val($input,0),
-// 				   caml_string_len($input));
-//             $1 = temp;
-//         } else {
-//             SWIG_exception(SWIG_TypeError, "string expected");
-//         }
-//     }
-
-//     %typemap(free) string * ($*1_ltype *temp) {
-// 	delete temp;
-//     }
-
-//    %typemap(argout) string & {
-//	caml_list_append(swig_result,caml_val_string_len((*$1).c_str(),
-//							 (*$1).size()));
-//    }
-
-//    %typemap(directorout) string {
-//	$result.assign((char *)caml_ptr_val($input,0),
-//		       caml_string_len($input));
-//    }
-
-//    %typemap(out) string {
-//        $result = caml_val_string_len($1.c_str(),$1.size());
-//    }
-
-//    %typemap(out) string * {
-//	$result = caml_val_string_len((*$1).c_str(),(*$1).size());
-//    }
-}
-
-// #ifdef ENABLE_CHARPTR_ARRAY
-// char **c_charptr_array( const std::vector <string > &str_v );
-
-// %{
-//   SWIGEXT char **c_charptr_array( const std::vector <string > &str_v ) {
-//     char **out = new char *[str_v.size() + 1];
-//     out[str_v.size()] = 0;
-//     for( int i = 0; i < str_v.size(); i++ ) {
-//       out[i] = (char *)str_v[i].c_str();
-//     }
-//     return out;
-//   }
-// %}
-// #endif
-
-// #ifdef ENABLE_STRING_VECTOR
-// %template (StringVector) std::vector<string >;
-
-// %insert(ml) %{
-//   (* Some STL convenience items *)
-
-//   let string_array_to_vector sa = 
-//     let nv = _new_StringVector C_void in
-//       array_to_vector nv (fun x -> C_string x) sa ; nv
-	
-//   let c_string_array ar = 
-//     _c_charptr_array (string_array_to_vector ar)
-// %}
-
-// %insert(mli) %{
-//   val c_string_array: string array -> c_obj
-// %}
-// #endif
diff --git a/Lib/allegrocl/typemaps.i b/Lib/allegrocl/typemaps.i
deleted file mode 100644
index 293d1cd..0000000
--- a/Lib/allegrocl/typemaps.i
+++ /dev/null
@@ -1,4 +0,0 @@
-/* Unused for Allegro CL module */
-
-%include "inout_typemaps.i"
-%include "longlongs.i"
diff --git a/Lib/allkw.swg b/Lib/allkw.swg
index 2d3cf6e..5e4cb83 100644
--- a/Lib/allkw.swg
+++ b/Lib/allkw.swg
@@ -1,5 +1,5 @@
-#ifndef __Lib_allkw_swg__
-#define __Lib_allkw_swg__
+#ifndef SWIG_INCLUDED_LIB_ALLKW_SWG
+#define SWIG_INCLUDED_LIB_ALLKW_SWG
 
 
 /*  
@@ -30,4 +30,4 @@
 %include <tcl/tclkw.swg>
 
 
-#endif //__Lib_allkw_swg__
+#endif // SWIG_INCLUDED_LIB_ALLKW_SWG
diff --git a/Lib/carrays.i b/Lib/carrays.i
index 3a9c3cf..71712c8 100644
--- a/Lib/carrays.i
+++ b/Lib/carrays.i
@@ -5,22 +5,28 @@
  * pointers as arrays.
  * ----------------------------------------------------------------------------- */
 
+#ifndef __cplusplus
+// C uses free/calloc/malloc
+%include "swigfragments.swg"
+%fragment("<stdlib.h>");
+#endif
+
 /* -----------------------------------------------------------------------------
  * %array_functions(TYPE,NAME)
  *
  * Generates functions for creating and accessing elements of a C array
  * (as pointers).  Creates the following functions:
  *
- *        TYPE *new_NAME(int nelements)
+ *        TYPE *new_NAME(size_t nelements)
  *        void delete_NAME(TYPE *);
- *        TYPE NAME_getitem(TYPE *, int index);
- *        void NAME_setitem(TYPE *, int index, TYPE value);
- * 
+ *        TYPE NAME_getitem(TYPE *, size_t index);
+ *        void NAME_setitem(TYPE *, size_t index, TYPE value);
+ *
  * ----------------------------------------------------------------------------- */
 
 %define %array_functions(TYPE,NAME)
 %{
-static TYPE *new_##NAME(int nelements) { %}
+static TYPE *new_##NAME(size_t nelements) { %}
 #ifdef __cplusplus
 %{  return new TYPE[nelements](); %}
 #else
@@ -36,18 +42,18 @@
 #endif
 %{}
 
-static TYPE NAME##_getitem(TYPE *ary, int index) {
+static TYPE NAME##_getitem(TYPE *ary, size_t index) {
     return ary[index];
 }
-static void NAME##_setitem(TYPE *ary, int index, TYPE value) {
+static void NAME##_setitem(TYPE *ary, size_t index, TYPE value) {
     ary[index] = value;
 }
 %}
 
-TYPE *new_##NAME(int nelements);
+TYPE *new_##NAME(size_t nelements);
 void delete_##NAME(TYPE *ary);
-TYPE NAME##_getitem(TYPE *ary, int index);
-void NAME##_setitem(TYPE *ary, int index, TYPE value);
+TYPE NAME##_getitem(TYPE *ary, size_t index);
+void NAME##_setitem(TYPE *ary, size_t index, TYPE value);
 
 %enddef
 
@@ -59,13 +65,13 @@
  * interface:
  *
  *          struct NAME {
- *              NAME(int nelements);
+ *              NAME(size_t nelements);
  *             ~NAME();
- *              TYPE getitem(int index);
- *              void setitem(int index, TYPE value);
+ *              TYPE getitem(size_t index);
+ *              void setitem(size_t index, TYPE value);
  *              TYPE * cast();
  *              static NAME *frompointer(TYPE *t);
-  *         }
+ *          }
  *
  * ----------------------------------------------------------------------------- */
 
@@ -80,14 +86,14 @@
 %extend NAME {
 
 #ifdef __cplusplus
-NAME(int nelements) {
+NAME(size_t nelements) {
   return new TYPE[nelements]();
 }
 ~NAME() {
   delete [] self;
 }
 #else
-NAME(int nelements) {
+NAME(size_t nelements) {
   return (TYPE *) calloc(nelements,sizeof(TYPE));
 }
 ~NAME() {
@@ -95,10 +101,10 @@
 }
 #endif
 
-TYPE getitem(int index) {
+TYPE getitem(size_t index) {
   return self[index];
 }
-void setitem(int index, TYPE value) {
+void setitem(size_t index, TYPE value) {
   self[index] = value;
 }
 TYPE * cast() {
diff --git a/Lib/cdata.i b/Lib/cdata.i
index f18ed4a..8736de1 100644
--- a/Lib/cdata.i
+++ b/Lib/cdata.i
@@ -4,6 +4,8 @@
  * SWIG library file containing macros for manipulating raw C data as strings.
  * ----------------------------------------------------------------------------- */
 
+%include <swigfragments.swg>
+
 %{
 typedef struct SWIGCDATA {
     char *data;
@@ -21,7 +23,7 @@
 }
 %typemap(in) (const void *indata, int inlen) = (char *STRING, int LENGTH);
 
-#elif SWIGPHP7
+#elif SWIGPHP
 
 %typemap(out) SWIGCDATA {
   ZVAL_STRINGL($result, $1.data, $1.len);
@@ -60,7 +62,7 @@
 
 
 /* -----------------------------------------------------------------------------
- * %cdata(TYPE [, NAME]) 
+ * %cdata(TYPE [, NAME])
  *
  * Convert raw C data to a binary string.
  * ----------------------------------------------------------------------------- */
@@ -99,6 +101,8 @@
 
 %cdata(void);
 
+%fragment("<string.h>");
+
 /* Memory move function. Due to multi-argument typemaps this appears to be wrapped as
 void memmove(void *data, const char *s); */
 void memmove(void *data, const void *indata, int inlen);
diff --git a/Lib/cffi/cffi.swg b/Lib/cffi/cffi.swg
deleted file mode 100644
index f729495..0000000
--- a/Lib/cffi/cffi.swg
+++ /dev/null
@@ -1,294 +0,0 @@
-/* Define a C preprocessor symbol that can be used in interface files
-   to distinguish between the SWIG language modules. */ 
-
-#define SWIG_CFFI
-
-/* Typespecs for basic types. */
-
-%typemap(cin) void ":void";
-
-%typemap(cin) char ":char";
-%typemap(cin) char * ":string";
-%typemap(cin) unsigned char ":unsigned-char";
-%typemap(cin) signed char ":char";
-
-%typemap(cin) short ":short";
-%typemap(cin) signed short ":short";
-%typemap(cin) unsigned short ":unsigned-short";
-
-%typemap(cin) int ":int";
-%typemap(cin) signed int ":int";
-%typemap(cin) unsigned int ":unsigned-int";
-
-%typemap(cin) long ":long";
-%typemap(cin) signed long ":long";
-%typemap(cin) unsigned long ":unsigned-long";
-
-%typemap(cin) long long ":long-long";
-%typemap(cin) signed long long ":long-long";
-%typemap(cin) unsigned long long ":unsigned-long-long";
-
-%typemap(cin) float ":float";
-%typemap(cin) double ":double";
-%typemap(cin) SWIGTYPE ":pointer";
-
-%typemap(cout) void ":void";
-
-%typemap(cout) char ":char";
-%typemap(cout) char * ":string";
-%typemap(cout) unsigned char ":unsigned-char";
-%typemap(cout) signed char ":char";
-
-%typemap(cout) short ":short";
-%typemap(cout) signed short ":short";
-%typemap(cout) unsigned short ":unsigned-short";
-
-%typemap(cout) int ":int";
-%typemap(cout) signed int ":int";
-%typemap(cout) unsigned int ":unsigned-int";
-
-%typemap(cout) long ":long";
-%typemap(cout) signed long ":long";
-%typemap(cout) unsigned long ":unsigned-long";
-
-%typemap(cout) long long ":long-long";
-%typemap(cout) signed long long ":long-long";
-%typemap(cout) unsigned long long ":unsigned-long-long";
-
-%typemap(cout) float ":float";
-%typemap(cout) double ":double";
-%typemap(cout) SWIGTYPE ":pointer";
-
-
-%typemap(ctype) bool                       "int";
-%typemap(ctype) char, unsigned char, signed char,
-                short, signed short, unsigned short,
-                int, signed int, unsigned int,
-                long, signed long, unsigned long,
-                float, double, long double, char *, void *, void,
-                enum SWIGTYPE, SWIGTYPE *,
-                SWIGTYPE[ANY], SWIGTYPE &, SWIGTYPE && "$1_ltype";
-%typemap(ctype) SWIGTYPE                   "$&1_type";
-
-%typemap(in) bool                          "$1 = (bool)$input;";
-%typemap(in) char, unsigned char, signed char,
-             short, signed short, unsigned short,
-             int, signed int, unsigned int,
-             long, signed long, unsigned long,
-             float, double, long double, char *, void *, void,
-             enum SWIGTYPE, SWIGTYPE *,
-             SWIGTYPE[ANY], SWIGTYPE &, SWIGTYPE && "$1 = $input;";
-%typemap(in) SWIGTYPE                      "$1 = *$input;";
-
-%typemap(out) void                         "";
-%typemap(out) bool                          "$result = (int)$1;";
-%typemap(out) char, unsigned char, signed char,
-              short, signed short, unsigned short,
-              int, signed int, unsigned int,
-              long, signed long, unsigned long,
-              float, double, long double, char *, void *,
-              enum SWIGTYPE, SWIGTYPE *,
-              SWIGTYPE[ANY], SWIGTYPE &, SWIGTYPE && "$result = $1;";
-#ifdef __cplusplus
-%typemap(out) SWIGTYPE                     "$result = new $1_type($1);";
-#else
-%typemap(out) SWIGTYPE {
-  $result = ($&1_ltype) malloc(sizeof($1_type));
-  memmove($result, &$1, sizeof($1_type));
-}
-#endif
-
-%typecheck(SWIG_TYPECHECK_BOOL) bool { $1 = 1; };
-%typecheck(SWIG_TYPECHECK_CHAR) char { $1 = 1; };
-%typecheck(SWIG_TYPECHECK_FLOAT) float { $1 = 1; };
-%typecheck(SWIG_TYPECHECK_DOUBLE) double { $1 = 1; };
-%typecheck(SWIG_TYPECHECK_STRING) char * { $1 = 1; };
-%typecheck(SWIG_TYPECHECK_INTEGER)
-                    unsigned char, signed char,
-                    short, signed short, unsigned short,
-                    int, signed int, unsigned int,
-                    long, signed long, unsigned long,
-                    enum SWIGTYPE { $1 = 1; };
-%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&,
-                                   SWIGTYPE[ANY], SWIGTYPE { $1 = 1; };
-/* This maps C/C++ types to Lisp classes for overload dispatch */
-
-%typemap(lisptype) bool "cl:boolean";
-%typemap(lisptype) char "cl:character";
-%typemap(lisptype) unsigned char "cl:integer";
-%typemap(lisptype) signed char "cl:integer";
-
-%typemap(lispclass) bool "t";
-%typemap(lispclass) char "cl:character";
-%typemap(lispclass) unsigned char, signed char,
-                    short, signed short, unsigned short,
-                    int, signed int, unsigned int,
-                    long, signed long, unsigned long,
-                    enum SWIGTYPE       "cl:integer";
-/* CLOS methods can't be specialized on single-float or double-float */
-%typemap(lispclass) float "cl:number";
-%typemap(lispclass) double "cl:number";
-%typemap(lispclass) char * "cl:string";
-
-/* Array reference typemaps */
-%apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) }
-%apply SWIGTYPE && { SWIGTYPE ((&&)[ANY]) }
-
-/* const pointers */
-%apply SWIGTYPE * { SWIGTYPE *const }
-%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) }
-%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) }
-
-%{
-
-#ifdef __cplusplus
-#  define EXTERN   extern "C"
-#else
-#  define EXTERN   extern
-#endif
-
-#define EXPORT   EXTERN SWIGEXPORT
-
-#include <string.h>
-%}
-
-%insert("swiglisp") %{
-;;;SWIG wrapper code starts here
-
-(cl:defmacro defanonenum (cl:&body enums)
-   "Converts anonymous enums to defconstants."
-  `(cl:progn ,@(cl:loop for value in enums
-                        for index = 0 then (cl:1+ index)
-                        when (cl:listp value) do (cl:setf index (cl:second value)
-                                                          value (cl:first value))
-                        collect `(cl:defconstant ,value ,index))))
-
-(cl:eval-when (:compile-toplevel :load-toplevel)
-  (cl:unless (cl:fboundp 'swig-lispify)
-    (cl:defun swig-lispify (name flag cl:&optional (package cl:*package*))
-      (cl:labels ((helper (lst last rest cl:&aux (c (cl:car lst)))
-                    (cl:cond
-                      ((cl:null lst)
-                       rest)
-                      ((cl:upper-case-p c)
-                       (helper (cl:cdr lst) 'upper
-                               (cl:case last
-                                 ((lower digit) (cl:list* c #\- rest))
-                                 (cl:t (cl:cons c rest)))))
-                      ((cl:lower-case-p c)
-                       (helper (cl:cdr lst) 'lower (cl:cons (cl:char-upcase c) rest)))
-                      ((cl:digit-char-p c)
-                       (helper (cl:cdr lst) 'digit 
-                               (cl:case last
-                                 ((upper lower) (cl:list* c #\- rest))
-                                 (cl:t (cl:cons c rest)))))
-                      ((cl:char-equal c #\_)
-                       (helper (cl:cdr lst) '_ (cl:cons #\- rest)))
-                      (cl:t
-                       (cl:error "Invalid character: ~A" c)))))
-        (cl:let ((fix (cl:case flag
-                        ((constant enumvalue) "+")
-                        (variable "*")
-                        (cl:t ""))))
-          (cl:intern
-           (cl:concatenate
-            'cl:string
-            fix
-            (cl:nreverse (helper (cl:concatenate 'cl:list name) cl:nil cl:nil))
-            fix)
-           package))))))
-
-;;;SWIG wrapper code ends here
-%}
-
-#ifdef __cplusplus
-%typemap(out) SWIGTYPE                     "$result = new $1_type($1);";
-#else
-%typemap(out) SWIGTYPE {
-  $result = ($&1_ltype) malloc(sizeof($1_type));
-  memmove($result, &$1, sizeof($1_type));
-}
-#endif
-
-//////////////////////////////////////////////////////////////
-
-/* name conversion for overloaded operators. */
-#ifdef __cplusplus
-%rename(__add__)	     *::operator+;
-%rename(__pos__)	     *::operator+();
-%rename(__pos__)	     *::operator+() const;
-
-%rename(__sub__)	     *::operator-;
-%rename(__neg__)	     *::operator-() const;
-%rename(__neg__)	     *::operator-();
-
-%rename(__mul__)	     *::operator*;
-%rename(__deref__)	     *::operator*();
-%rename(__deref__)	     *::operator*() const;
-
-%rename(__div__)	     *::operator/;
-%rename(__mod__)	     *::operator%;
-%rename(__logxor__)	     *::operator^;
-%rename(__logand__)	     *::operator&;
-%rename(__logior__)	     *::operator|;
-%rename(__lognot__)	     *::operator~();
-%rename(__lognot__)	     *::operator~() const;
-
-%rename(__not__)	     *::operator!();
-%rename(__not__)	     *::operator!() const;
-
-%rename(__assign__)	     *::operator=;
-
-%rename(__add_assign__)      *::operator+=;
-%rename(__sub_assign__)	     *::operator-=;
-%rename(__mul_assign__)	     *::operator*=;
-%rename(__div_assign__)	     *::operator/=;
-%rename(__mod_assign__)	     *::operator%=;
-%rename(__logxor_assign__)   *::operator^=;
-%rename(__logand_assign__)   *::operator&=;
-%rename(__logior_assign__)   *::operator|=;
-
-%rename(__lshift__)	     *::operator<<;
-%rename(__lshift_assign__)   *::operator<<=;
-%rename(__rshift__)	     *::operator>>;
-%rename(__rshift_assign__)   *::operator>>=;
-
-%rename(__eq__)		     *::operator==;
-%rename(__ne__)		     *::operator!=;
-%rename(__lt__)		     *::operator<;
-%rename(__gt__)		     *::operator>;
-%rename(__lte__)	     *::operator<=;
-%rename(__gte__)	     *::operator>=;
-
-%rename(__and__)	     *::operator&&;
-%rename(__or__)		     *::operator||;
-
-%rename(__preincr__)	     *::operator++();
-%rename(__postincr__)	     *::operator++(int);
-%rename(__predecr__)	     *::operator--();
-%rename(__postdecr__)	     *::operator--(int);
-
-%rename(__comma__)	     *::operator,();
-%rename(__comma__)	     *::operator,() const;
-
-%rename(__member_ref__)      *::operator->;
-%rename(__member_func_ref__) *::operator->*;
-
-%rename(__funcall__)	     *::operator();
-%rename(__aref__)	     *::operator[];
-#endif
-
-
-%{
-
-#ifdef __cplusplus
-#  define EXTERN   extern "C"
-#else
-#  define EXTERN   extern
-#endif
-
-#define EXPORT   EXTERN SWIGEXPORT
-
-#include <string.h>
-#include <stdlib.h>
-%}
diff --git a/Lib/chicken/chicken.swg b/Lib/chicken/chicken.swg
deleted file mode 100644
index 7df6767..0000000
--- a/Lib/chicken/chicken.swg
+++ /dev/null
@@ -1,809 +0,0 @@
-/* -----------------------------------------------------------------------------
- * chicken.swg
- *
- * CHICKEN configuration module.
- * ----------------------------------------------------------------------------- */
-
-/* chicken.h has to appear first. */
-
-%insert(runtime) %{
-#include <assert.h>
-#include <chicken.h>
-%}
-
-%insert(runtime) "swigrun.swg"          // Common C API type-checking code
-%insert(runtime) "swigerrors.swg"       // SWIG errors
-%insert(runtime) "chickenrun.swg"       // CHICKEN run-time code
-
-/* -----------------------------------------------------------------------------
- *                          standard typemaps
- * ----------------------------------------------------------------------------- */
-
-/*
-  CHICKEN: C
-  ----------
-
-  fixnum: int, short, unsigned int, unsigned short, unsigned char,
-  signed char
-
-  char: char
-
-  bool: bool
-
-  flonum: float, double, long, long long, unsigned long, unsigned long
-  long
- */
-
-/* --- Primitive types --- */
-
-%define SIMPLE_TYPEMAP(type_, from_scheme, to_scheme, checker, convtype, storage_)
-
-%typemap(in) type_ 
-%{  if (!checker ($input)) {
-    swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument #$argnum is not of type 'type_'");
-  }
-  $1 = ($1_ltype) from_scheme ($input); %}
-
-/* Const primitive references.  Passed by value */
-
-%typemap(in) const type_ & ($*1_ltype temp)
-%{  if (!checker ($input)) {
-    swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument #$argnum is not of type 'type_'");
-  }
-  temp = ($*1_ltype) from_scheme ($input); 
-  $1 = &temp; %}
-
-/* --- Variable input --- */
-%typemap(varin) type_
-%{  if (!checker ($input)) {
-    swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Cannot use '$1_ltype' for variable '$name' of type 'type_'");
-  }
-  $1 = ($1_ltype) from_scheme ($input); %}
-
-#if "storage_" == "0"
-
-%typemap(out) type_ 
-%{
-  $result = to_scheme (convtype ($1));
-%}
-
-/* References to primitive types.  Return by value */
-
-%typemap(out) const type_ &
-%{
-  $result = to_scheme (convtype (*$1));
-%}
-
-/* --- Variable output --- */
-%typemap(varout) type_ 
-%{
-  $result = to_scheme (convtype ($varname));
-%}
-
-%typemap(throws) type_
-%{
-  SWIG_Chicken_ThrowException(to_scheme ( convtype ($1)));
-%}
-
-#else
-
-%typemap(out) type_ 
-%{
-  {
-  C_word *space = C_alloc(storage_);
-  $result = to_scheme (&space, convtype ($1));
-  }
-%}
-
-/* References to primitive types.  Return by value */
-
-%typemap(out) const type_ &
-%{
-  {
-  C_word *space = C_alloc(storage_);
-  $result = to_scheme (&space, convtype (*$1));
-  }
-%}
-
-/* --- Variable output --- */
-%typemap(varout) type_ 
-%{
-  {
-  C_word *space = C_alloc(storage_);
-  $result = to_scheme (&space, convtype ($varname));
-  }
-%}
-
-%typemap(throws) type_
-%{
-  {
-  C_word *space = C_alloc(storage_);
-  SWIG_Chicken_ThrowException(to_scheme (&space, convtype ($1)));
-  }
-%}
-
-#endif
-
-/* --- Constants --- */
-
-%typemap(constcode) type_
-"static const $1_type $result = $value;"
-
-%enddef
-
-SIMPLE_TYPEMAP(int, C_num_to_int, C_fix, C_swig_is_number, (int), 0);
-//SIMPLE_TYPEMAP(enum SWIGTYPE, C_unfix, C_fix, C_swig_is_fixnum, (int), 0);
-SIMPLE_TYPEMAP(short, C_num_to_int, C_fix, C_swig_is_number, (int), 0);
-SIMPLE_TYPEMAP(long, C_num_to_long, C_long_to_num, C_swig_is_long, (long), C_SIZEOF_FLONUM);
-SIMPLE_TYPEMAP(long long, C_num_to_long, C_long_to_num, C_swig_is_long, (long), C_SIZEOF_FLONUM);
-SIMPLE_TYPEMAP(unsigned int, C_num_to_unsigned_int, C_unsigned_int_to_num, C_swig_is_number, (unsigned int), C_SIZEOF_FLONUM);
-SIMPLE_TYPEMAP(unsigned short, C_num_to_unsigned_int, C_fix, C_swig_is_number, (unsigned int), 0);
-SIMPLE_TYPEMAP(unsigned long, C_num_to_unsigned_long, C_unsigned_long_to_num, C_swig_is_long, (unsigned long), C_SIZEOF_FLONUM);
-SIMPLE_TYPEMAP(unsigned long long, C_num_to_unsigned_long, C_unsigned_long_to_num, C_swig_is_long, (unsigned long), C_SIZEOF_FLONUM);
-SIMPLE_TYPEMAP(unsigned char, C_character_code, C_make_character, C_swig_is_char, (unsigned int), 0);
-SIMPLE_TYPEMAP(signed char, C_character_code, C_make_character, C_swig_is_char, (int), 0);
-SIMPLE_TYPEMAP(char, C_character_code, C_make_character, C_swig_is_char, (char), 0);
-SIMPLE_TYPEMAP(bool, C_truep, C_mk_bool, C_swig_is_bool, (bool), 0);
-SIMPLE_TYPEMAP(float, C_c_double, C_flonum, C_swig_is_number, (double), C_SIZEOF_FLONUM);
-SIMPLE_TYPEMAP(double, C_c_double, C_flonum, C_swig_is_number, (double), C_SIZEOF_FLONUM);
-
-/* enum SWIGTYPE */
-%apply int { enum SWIGTYPE };
-%apply const int& { const enum SWIGTYPE& };
-%apply const int& { const enum SWIGTYPE&& };
-
-%typemap(varin) enum SWIGTYPE
-{
-  if (!C_swig_is_fixnum($input) && sizeof(int) != sizeof($1)) {
-    swig_barf(SWIG_BARF1_BAD_ARGUMENT_TYPE, "enum variable '$name' can not be set");
-  }
-  *((int *)(void *)&$1) = C_unfix($input);
-}
-
-
-/* --- Input arguments --- */
-
-/* Strings */
-
-%typemap(in) char * 
-{ if ($input == C_SCHEME_FALSE) {
-  $1 = NULL;
- }
- else { 
-   if (!C_swig_is_string ($input)) {
-     swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument #$argnum is not of type 'char *'");
-   }
-   $1 = ($ltype) SWIG_MakeString ($input);
- }
-}
-
-%typemap(freearg) char * "if ($1 != NULL) { free ($1); }"
-
-/* Pointers, references, and arrays */
-%typemap(in,closcode="(slot-ref $input 'swig-this)") SWIGTYPE *, SWIGTYPE [], SWIGTYPE &, SWIGTYPE &&  {
-   $1 = ($1_ltype)SWIG_MustGetPtr($input, $descriptor, $argnum, $disown);
-}
-
-%typemap(in,closcode="(slot-ref $input 'swig-this)") SWIGTYPE *DISOWN {
-  $1 = ($1_ltype)SWIG_MustGetPtr($input, $descriptor, $argnum, SWIG_POINTER_DISOWN);
-}
-
-/* Void pointer.  Accepts any kind of pointer */
-%typemap(in) void * {
-  $1 = ($1_ltype)SWIG_MustGetPtr($input, NULL, $argnum, 0);
-}
-
-%typemap(varin,closcode="(slot-ref $input 'swig-this)") SWIGTYPE * {
-  $1 = ($1_ltype)SWIG_MustGetPtr($input, $descriptor, 1, SWIG_POINTER_DISOWN);
-}
-
-%typemap(varin,closcode="(slot-ref $input 'swig-this)") SWIGTYPE & {
-  $1 = *(($1_ltype)SWIG_MustGetPtr($input, $descriptor, 1, 0));
-}
-
-%typemap(varin,closcode="(slot-ref $input 'swig-this)") SWIGTYPE && {
-  $1 = *(($1_ltype)SWIG_MustGetPtr($input, $descriptor, 1, 0));
-}
-
-%typemap(varin) SWIGTYPE [] {
-  SWIG_Chicken_Barf(SWIG_BARF1_BAD_ARGUMENT_TYPE, "Type error");
-}
-
-%typemap(varin) SWIGTYPE [ANY] {
-  void *temp;
-  int ii;
-  $1_basetype *b = 0;
-  temp = SWIG_MustGetPtr($input, $1_descriptor, 1, 0);
-  b = ($1_basetype *) $1;
-  for (ii = 0; ii < $1_size; ii++) b[ii] = *(($1_basetype *) temp + ii);
-}
-
-%typemap(varin) void * {
-  $1 = SWIG_MustGetPtr($input, NULL, 1, 0);
-}
-
-%typemap(out) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] {
-  C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
-  $result = SWIG_NewPointerObj($1, $descriptor, $owner);
-}
-
-%typemap(out) SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC {
-  C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
-  swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor,(void **) &$1);
-  $result = SWIG_NewPointerObj($1, ty, $owner);
-}
-    
-%typemap(varout) SWIGTYPE *, SWIGTYPE [] {
-  C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
-  $result = SWIG_NewPointerObj($varname, $descriptor, 0);
-}
-
-%typemap(varout) SWIGTYPE & {
-  C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
-  $result = SWIG_NewPointerObj((void *) &$varname, $1_descriptor, 0);
-}
-
-%typemap(varout) SWIGTYPE && {
-  C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
-  $result = SWIG_NewPointerObj((void *) &$varname, $1_descriptor, 0);
-}
-
-/* special typemaps for class pointers */
-%typemap(in) SWIGTYPE (CLASS::*) {
-  char err_msg[256];
-
-  if (C_swig_is_pair($input)) {
-    /* try and convert pointer object */
-    void *result;
-    if (!SWIG_ConvertPtr(C_block_item($input,1), &result, $descriptor, 0)) {
-      C_word ptr = C_block_item($input,0);
-      if (C_swig_is_string(ptr)) {
-        SWIG_UnpackData(C_c_string(ptr), (void *) &$1, sizeof($type));
-      } else {
-        snprintf(err_msg, sizeof(err_msg), "Type error in argument #%i: expected %s", $argnum, ($descriptor->str ? $descriptor->str : $descriptor->name));
-        SWIG_Chicken_Barf(SWIG_BARF1_BAD_ARGUMENT_TYPE, err_msg);
-      }
-    } else {
-      snprintf(err_msg, sizeof(err_msg), "Type error in argument #%i: expected %s", $argnum, ($descriptor->str ? $descriptor->str : $descriptor->name));
-      SWIG_Chicken_Barf(SWIG_BARF1_BAD_ARGUMENT_TYPE, err_msg);
-    }
-  } else {
-    snprintf(err_msg, sizeof(err_msg), "Type error in argument #%i: expected %s", $argnum, ($descriptor->str ? $descriptor->str : $descriptor->name));
-    SWIG_Chicken_Barf(SWIG_BARF1_BAD_ARGUMENT_TYPE, err_msg);
-  }
-}
-
-%typemap(out) SWIGTYPE (CLASS::*) {
-  size_t ptr_size = sizeof($type);
-  C_word *known_space = C_alloc(C_SIZEOF_PAIR + C_SIZEOF_STRING(2*ptr_size) + C_SIZEOF_SWIG_POINTER);
-  char *temp = (char *)malloc(2*ptr_size);
-  C_word ptr = SWIG_NewPointerObj((void *) known_space, $descriptor, 0);
-
-  SWIG_PackData(temp, (void *) &$1, ptr_size);
-  $result = C_pair(&known_space, C_string(&known_space, 2*ptr_size, temp), ptr);
-  free(temp);
-}
-
-%typemap(varin) SWIGTYPE (CLASS::*) {
-  char err_msg[256];
-
-  if (C_swig_is_pair($input)) {
-    /* try and convert pointer object */
-    void *result;
-    if (!SWIG_ConvertPtr(C_block_item($input,1), &result, $descriptor, 0)) {
-      C_word ptr = C_block_item($input,0);
-      if (C_swig_is_string(ptr)) {
-        SWIG_UnpackData(C_c_string(ptr), (void *) &$1, sizeof($type));
-      } else {
-        snprintf(err_msg, sizeof(err_msg), "Type error in argument #%i: expected %s", 1, ($descriptor->str ? $descriptor->str : $descriptor->name));
-        SWIG_Chicken_Barf(SWIG_BARF1_BAD_ARGUMENT_TYPE, err_msg);
-      }
-    } else {
-      snprintf(err_msg, sizeof(err_msg), "Type error in argument #%i: expected %s", 1, ($descriptor->str ? $descriptor->str : $descriptor->name));
-      SWIG_Chicken_Barf(SWIG_BARF1_BAD_ARGUMENT_TYPE, err_msg);
-    }
-  } else {
-    snprintf(err_msg, sizeof(err_msg), "Type error in argument #%i: expected %s", 1, ($descriptor->str ? $descriptor->str : $descriptor->name));
-    SWIG_Chicken_Barf(SWIG_BARF1_BAD_ARGUMENT_TYPE, err_msg);
-  }
-}
-
-%typemap(varout) SWIGTYPE (CLASS::*) {
-  size_t ptr_size = sizeof($type);
-  C_word *known_space = C_alloc(C_SIZEOF_PAIR + C_SIZEOF_STRING(2*ptr_size) + C_SIZEOF_SWIG_POINTER);
-  char *temp = (char *)malloc(2*ptr_size);
-  C_word ptr = SWIG_NewPointerObj((void *) known_space, $descriptor, 0);
-
-  SWIG_PackData(temp, (void *) &$varname, ptr_size);
-  $result = C_pair(&known_space, C_string(&known_space, 2*ptr_size, temp), ptr);
-  free(temp);
-}
-
-  
-
-/* Pass-by-value */
-
-%typemap(in,closcode="(slot-ref $input 'swig-this)") SWIGTYPE($&1_ltype argp) {
-  argp = ($&1_ltype)SWIG_MustGetPtr($input, $&1_descriptor, $argnum, 0);
-  $1 = *argp;
-}
-
-%typemap(varin,closcode="(slot-ref $input 'swig-this)") SWIGTYPE {
-  $&1_ltype argp;
-  argp = ($&1_ltype)SWIG_MustGetPtr($input, $&1_descriptor, 1, 0);
-  $1 = *argp;
-}
-
-%typemap(out) SWIGTYPE 
-#ifdef __cplusplus
-{
-  $&1_ltype resultptr;
-  C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
-  resultptr = new $1_ltype((const $1_ltype &) $1);
-  $result =  SWIG_NewPointerObj(resultptr, $&1_descriptor, 1);
-} 
-#else
-{
-  $&1_ltype resultptr;
-  C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
-  resultptr = ($&1_ltype) malloc(sizeof($1_type));
-  memmove(resultptr, &$1, sizeof($1_type));
-  $result = SWIG_NewPointerObj(resultptr, $&1_descriptor, 1);
-}
-#endif
-
-%typemap(varout) SWIGTYPE 
-#ifdef __cplusplus
-{
-  $&1_ltype resultptr;
-  C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
-  resultptr = new $1_ltype((const $1_ltype&) $1);
-  $result =  SWIG_NewPointerObj(resultptr, $&1_descriptor, 0);
-} 
-#else
-{
-  $&1_ltype resultptr;
-  C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
-  resultptr = ($&1_ltype) malloc(sizeof($1_type));
-  memmove(resultptr, &$1, sizeof($1_type));
-  $result = SWIG_NewPointerObj(resultptr, $&1_descriptor, 0);
-}
-#endif
-
-/* --- Output values --- */
-
-/* Strings */
-
-%typemap(out) 
-  char *
-{ char *s = (char*) $1;
-  if ($1 == NULL) {
-    $result = C_SCHEME_FALSE;
-  } 
-  else {
-    int string_len = strlen ((char *) ($1));
-    C_word *string_space = C_alloc (C_SIZEOF_STRING (string_len));
-    $result = C_string (&string_space, string_len, s);
-  }
-}
-
-%typemap(varout) 
-  char *
-{ char *s = (char*) $varname;
-  if ($varname == NULL) {
-    $result = C_SCHEME_FALSE;
-  } 
-  else {
-    int string_len = strlen ($varname);
-    C_word *string_space = C_alloc (C_SIZEOF_STRING (string_len));
-    $result = C_string (&string_space, string_len, s);
-  }
-}
-
-%typemap(throws) char *
-{ 
-  if ($1 == NULL) {
-    SWIG_Chicken_ThrowException(C_SCHEME_FALSE);
-  } else {
-    int string_len = strlen($1);
-    C_word *string_space = C_alloc(C_SIZEOF_STRING(string_len));
-    SWIG_Chicken_ThrowException(C_string(&string_space, string_len, (char *) $1));
-  }
-}
-
-/* Void */
-%typemap(out) void
-%{
-$result = C_SCHEME_UNDEFINED;
-%}
-
-/* Special typemap for character array return values */
-
-%typemap(out) 
-  char [ANY], const char [ANY] 
-%{ if ($1 == NULL) {
-  $result = C_SCHEME_FALSE;
- }
- else {
-   const int string_len = strlen ($1);
-   C_word *string_space = C_alloc (C_SIZEOF_STRING (string_len));
-   $result = C_string (&string_space, string_len, $1);
- } %}
-
-/* Primitive types--return by value */
-
-/* --- Variable input --- */
-
-/* A string */
-#ifdef __cplusplus
-%typemap(varin) char * {
-  if ($input == C_SCHEME_FALSE) {
-    $1 = NULL;
-  }
-  else if (!C_swig_is_string ($input)) {
-      swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "C variable '$name ($1_ltype)'");
-  }
-  else {
-    char *temp = C_c_string ($input);
-    int  len   = C_header_size ($input);
-    if ($1) delete [] $1;
-    $1 = ($type) new char[len+1];
-    strncpy((char*)$1, temp, len);
-    ((char*)$1) [len] = 0;
-  }
-}
-%typemap(varin,warning="451:Setting const char * variable may leak memory") const char * {
-  if ($input == C_SCHEME_FALSE) {
-    $1 = NULL;
-  }
-  else if (!C_swig_is_string ($input)) {
-    swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "C variable '$name ($1_ltype)'");
-  }
-  else {
-    char *temp = C_c_string ($input);
-    int  len   = C_header_size ($input);
-    $1 = ($type) new char[len+1];
-    strncpy((char*)$1,temp,len);
-    ((char*)$1) [len] = 0;
-  }
-}
-#else
-%typemap(varin) char * {
-  if ($input == C_SCHEME_FALSE) {
-    $1 = NULL;
-  }
-  else if (!C_swig_is_string ($input)) {
-    swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "C variable '$name ($1_ltype)'");
-  }
-  else {
-    char *temp = C_c_string ($input);
-    int  len   = C_header_size ($input);
-    if ($1) free((char*) $1);
-    $1 = ($type) malloc(len+1);
-    strncpy((char*)$1,temp,len);
-    ((char*)$1) [len] = 0;
-  }
-}
-%typemap(varin,warning="451:Setting const char * variable may leak memory") const char * {
-  if ($input == C_SCHEME_FALSE) {
-    $1 = NULL;
-  }
-  else if (!C_swig_is_string ($input)) {
-    swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "C variable '$name ($1_ltype)'");
-  }
-  else {
-    char *temp = C_c_string ($input);
-    int  len   = C_header_size ($input);
-    $1 = ($type) malloc(len+1);
-    strncpy((char*)$1,temp,len);
-    ((char*)$1) [len] = 0;
-  }
-}
-#endif
-
-%typemap(varin) char [] {
-  swig_barf(SWIG_BARF1_BAD_ARGUMENT_TYPE, "C/C++ variable '$name' is read-only");
-}
-
-/* Special case for string array variables */
-%typemap(varin) char [ANY] {
-  if ($input == C_SCHEME_FALSE) {
-    memset($1,0,$1_dim0*sizeof(char));
-  }
-  else if (!C_swig_is_string ($input)) {
-    swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "C variable '$name ($1_ltype)'");
-  }
-  else {
-    char *temp = C_c_string ($input);
-    strncpy($1,temp,$1_dim0*sizeof(char));
-  }
-}
-
-/* --- Variable output --- */
-
-/* Void */
-%typemap(varout) void "$result = C_SCHEME_UNDEFINED;";
-
-/* Special typemap for character array return values */
-%typemap(varout) char [ANY], const char [ANY] 
-%{  if ($varname == NULL) {
-    $result = C_SCHEME_FALSE;
-  }
-  else {
-   const int string_len = strlen ($varname);
-   C_word *string_space = C_alloc (C_SIZEOF_STRING (string_len));
-   $result = C_string (&string_space, string_len, (char *) $varname);
-  }
-%}
-
-
-/* --- Constants --- */
-
-%typemap(constcode) char *
-"static const char *$result = $value;"
-
-%typemap(constcode) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE []
-"static const void *$result = (void*) $value;"
-
-/* ------------------------------------------------------------
- * String & length
- * ------------------------------------------------------------ */
-
-%typemap(in) (char *STRING, int LENGTH), (char *STRING, size_t LENGTH) {
-  if ($input == C_SCHEME_FALSE) {
-    swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Cannot use a null/#f string for a char*, int arguments");
-  }
-  else if (C_swig_is_string ($input)) {
-    $1 = ($1_ltype) C_c_string ($input);
-    $2 = ($2_ltype) C_header_size ($input);
-  }
-  else {
-    swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument #$argnum is not of type 'string'");
-  }
-}
-
-/* ------------------------------------------------------------
- * CHICKEN types
- * ------------------------------------------------------------ */
-
-%typemap(in)   C_word "$1 = $input;";
-%typemap(out)  C_word "$result = $1;";
-
-/* ------------------------------------------------------------
- * Typechecking rules
- * ------------------------------------------------------------ */
-
-%typecheck(SWIG_TYPECHECK_INTEGER)
-         bool, const bool & 
-{
-  $1 = C_swig_is_bool ($input);
-}
-
-%typecheck(SWIG_TYPECHECK_INTEGER)
-	 int, short, 
- 	 unsigned int, unsigned short,
-	 signed char, unsigned char,
-	 const int &, const short &, 
- 	 const unsigned int &, const unsigned short &,
-	 enum SWIGTYPE
-{
-  $1 = C_swig_is_fixnum ($input);
-}
-
-%typecheck(SWIG_TYPECHECK_INTEGER)
-	 long,
- 	 unsigned long,
-	 long long, unsigned long long,
-	 const long &,
- 	 const unsigned long &,
-	 const long long &, const unsigned long long &
-{
-  $1 = (C_swig_is_bool ($input) || 
-    C_swig_is_fixnum ($input) || 
-    C_swig_is_flonum ($input)) ? 1 : 0;
-}
-
-%typecheck(SWIG_TYPECHECK_DOUBLE)
-	float, double,
-	const float &, const double &
-{
-  $1 = C_swig_is_flonum ($input);
-}
-
-%typecheck(SWIG_TYPECHECK_CHAR) char {
-  $1 = C_swig_is_string ($input);
-}
-
-%typecheck(SWIG_TYPECHECK_STRING) char * {
-  $1 = C_swig_is_string ($input);
-}
-
-%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE [] {
-  void *ptr;
-  $1 = !SWIG_ConvertPtr($input, &ptr, $1_descriptor, 0);
-}
-
-%typecheck(SWIG_TYPECHECK_VOIDPTR) void * {
-  void *ptr;
-  $1 = !SWIG_ConvertPtr($input, &ptr, 0, 0);
-}
-
-%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE &
-{
-  void *ptr = 0;
-  if (SWIG_ConvertPtr($input, &ptr, $descriptor, SWIG_POINTER_NO_NULL)) {
-    $1 = 0;
-  } else {
-    $1 = 1;
-  }
-}
-
-%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE &&
-{
-  void *ptr = 0;
-  if (SWIG_ConvertPtr($input, &ptr, $descriptor, SWIG_POINTER_NO_NULL)) {
-    $1 = 0;
-  } else {
-    $1 = 1;
-  }
-}
-
-%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE 
-{
-  void *ptr = 0;
-  if (SWIG_ConvertPtr($input, &ptr, $&descriptor, SWIG_POINTER_NO_NULL)) {
-    $1 = 0;
-  } else {
-    $1 = 1;
-  }
-}
-
-
-/* ------------------------------------------------------------
- * Exception handling
- * ------------------------------------------------------------ */
-
-/* ------------------------------------------------------------
- * --- Exception handling ---
- * ------------------------------------------------------------ */
-
-%typemap(throws) SWIGTYPE {
-  $&ltype temp = new $ltype($1);
-  C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
-  C_word ptr = SWIG_NewPointerObj(temp, $&descriptor,1);
-  SWIG_Chicken_ThrowException(ptr);
-}
-
-%typemap(throws) SWIGTYPE * {
-  C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
-  C_word ptr = SWIG_NewPointerObj((void *) $1, $descriptor, 0);
-  SWIG_Chicken_ThrowException(ptr);
-}
-
-%typemap(throws) SWIGTYPE [ANY] {
-  C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
-  C_word ptr = SWIG_NewPointerObj((void *) $1, $descriptor, 0);
-  SWIG_Chicken_ThrowException(ptr);
-}
-
-%typemap(throws) SWIGTYPE & {
-  C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
-  C_word ptr = SWIG_NewPointerObj((void *)&($1),$descriptor,0);
-  SWIG_Chicken_ThrowException(ptr);
-}
-
-%typemap(throws) SWIGTYPE && {
-  C_word *known_space = C_alloc(C_SIZEOF_SWIG_POINTER);
-  C_word ptr = SWIG_NewPointerObj((void *)&($1),$descriptor,0);
-  SWIG_Chicken_ThrowException(ptr);
-}
-
-/* ------------------------------------------------------------
- * ANSI C typemaps
- * ------------------------------------------------------------ */
-
-%apply unsigned long { size_t };
-
-/* ------------------------------------------------------------
- * Various
- * ------------------------------------------------------------ */
-
-/* Array reference typemaps */
-%apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) }
-%apply SWIGTYPE && { SWIGTYPE ((&&)[ANY]) }
-
-/* const pointers */
-%apply SWIGTYPE * { SWIGTYPE *const }
-%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) }
-%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) }
-
-/* ------------------------------------------------------------
- * Overloaded operator support
- * ------------------------------------------------------------ */
-
-#ifdef __cplusplus
-%rename(__add__)      *::operator+;
-%rename(__pos__)      *::operator+();
-%rename(__pos__)      *::operator+() const;
-%rename(__sub__)      *::operator-;
-%rename(__neg__)      *::operator-();
-%rename(__neg__)      *::operator-() const;
-%rename(__mul__)      *::operator*;
-%rename(__div__)      *::operator/;
-%rename(__mod__)      *::operator%;
-%rename(__lshift__)   *::operator<<;
-%rename(__rshift__)   *::operator>>;
-%rename(__and__)      *::operator&;
-%rename(__or__)       *::operator|;
-%rename(__xor__)      *::operator^;
-%rename(__invert__)   *::operator~;
-%rename(__iadd__)     *::operator+=;
-%rename(__isub__)     *::operator-=;
-%rename(__imul__)     *::operator*=;
-%rename(__idiv__)     *::operator/=;
-%rename(__imod__)     *::operator%=;
-%rename(__ilshift__)  *::operator<<=;
-%rename(__irshift__)  *::operator>>=;
-%rename(__iand__)     *::operator&=;
-%rename(__ior__)      *::operator|=;
-%rename(__ixor__)     *::operator^=;
-%rename(__lt__)       *::operator<;
-%rename(__le__)       *::operator<=;
-%rename(__gt__)       *::operator>;
-%rename(__ge__)       *::operator>=;
-%rename(__eq__)       *::operator==;
-%rename(__ne__)       *::operator!=;
-
-/* Special cases */
-%rename(__call__)     *::operator();
-
-#endif
-/* Warnings for certain CHICKEN keywords */
-%include <chickenkw.swg>
-
-/* TinyCLOS <--> Low-level CHICKEN */
-
-%typemap("clos_in") SIMPLE_CLOS_OBJECT * "(slot-ref $input (quote this))"
-%typemap("clos_out") SIMPLE_CLOS_OBJECT * "(make $class (quote this) $1)"
-
-%insert(header) %{
-#ifdef __cplusplus
-extern "C" {
-#endif
-/* Chicken initialization function */
-SWIGEXPORT void SWIG_init(C_word, C_word, C_word) C_noret;
-#ifdef __cplusplus
-}
-#endif
-%}
-
-%insert(closprefix) "swigclosprefix.scm"
-
-%insert(init) "swiginit.swg"
-
-%insert(init) %{
-/* CHICKEN initialization function */
-#ifdef __cplusplus
-extern "C" {
-#endif
-SWIGEXPORT void SWIG_init(C_word argc, C_word closure, C_word continuation) {
-  int       i;
-  C_word sym;
-  C_word tmp;
-  C_word *a;
-  C_word ret;
-  C_word *return_vec;
-
-  SWIG_InitializeModule(0);
-  SWIG_PropagateClientData();
-  ret = C_SCHEME_TRUE;
-  
-#if $veclength
-  return_vec = C_alloc(C_SIZEOF_VECTOR($veclength));
-  ret = (C_word) return_vec;
-  *(return_vec++) = C_VECTOR_TYPE | $veclength;
-#endif
-
-  a = C_alloc(2*$nummethods$symsize);
-
-%}
diff --git a/Lib/chicken/chickenkw.swg b/Lib/chicken/chickenkw.swg
deleted file mode 100644
index d2c26c7..0000000
--- a/Lib/chicken/chickenkw.swg
+++ /dev/null
@@ -1,31 +0,0 @@
-#ifndef CHICKEN_CHICKENKW_SWG_
-#define CHICKEN_CHICKENKW_SWG_
-
-/* Warnings for certain CHICKEN keywords. From Section 7.1.1 of
-   Revised^5 Report on the Algorithmic Language Scheme */
-#define CHICKENKW(x) %namewarn("314: '" #x "' is a R^5RS syntatic keyword")  #x
-
-CHICKENKW(else);
-CHICKENKW(=>);
-CHICKENKW(define);
-CHICKENKW(unquote);
-CHICKENKW(unquote-splicing);
-CHICKENKW(quote);
-CHICKENKW(lambda);
-CHICKENKW(if);
-CHICKENKW(set!);
-CHICKENKW(begin);
-CHICKENKW(cond);
-CHICKENKW(and);
-CHICKENKW(or);
-CHICKENKW(case);
-CHICKENKW(let);
-CHICKENKW(let*);
-CHICKENKW(letrec);
-CHICKENKW(do);
-CHICKENKW(delay);
-CHICKENKW(quasiquote);
-
-#undef CHICKENKW 
-
-#endif //CHICKEN_CHICKENKW_SWG_
diff --git a/Lib/chicken/chickenrun.swg b/Lib/chicken/chickenrun.swg
deleted file mode 100644
index bb14b4b..0000000
--- a/Lib/chicken/chickenrun.swg
+++ /dev/null
@@ -1,375 +0,0 @@
-/* -----------------------------------------------------------------------------
- * chickenrun.swg
- * ----------------------------------------------------------------------------- */
-
-#include <chicken.h>
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#if (defined(_MSC_VER) && (_MSC_VER < 1900)) || defined(__BORLANDC__) || defined(_WATCOM)
-# ifndef snprintf
-#  define snprintf _snprintf
-# endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define SWIG_malloc(size) \
-  malloc(size)
-#define SWIG_free(mem) \
-  free(mem)
-#define SWIG_MakeString(c) \
-  SWIG_Chicken_MakeString(c)
-#define SWIG_ConvertPtr(s, result, type, flags) \
-  SWIG_Chicken_ConvertPtr(s, result, type, flags)
-#define SWIG_MustGetPtr(s, type, argnum, flags) \
-  SWIG_Chicken_MustGetPtr(s, type, argnum, flags)
-#define SWIG_NewPointerObj(ptr, type, owner) \
-  SWIG_Chicken_NewPointerObj((void*)ptr, type, owner, &known_space)
-#define swig_barf SWIG_Chicken_Barf
-#define SWIG_ThrowException(val) SWIG_Chicken_ThrowException(val)
-
-#define SWIG_contract_assert(expr, message) if (!(expr)) { \
-                                              SWIG_Chicken_Barf(SWIG_BARF1_CONTRACT_ASSERT, C_text(message)); } else
-
-/* Runtime API */
-#define SWIG_GetModule(clientdata) SWIG_Chicken_GetModule(clientdata)
-#define SWIG_SetModule(clientdata, pointer) SWIG_Chicken_SetModule(pointer)
-
-#define C_swig_is_bool(x) C_truep (C_booleanp (x))
-#define C_swig_is_char(x) C_truep (C_charp (x))
-#define C_swig_is_fixnum(x) C_truep (C_fixnump (x))
-#define C_swig_is_flonum(x) (C_truep (C_blockp (x)) && C_truep (C_flonump (x)))
-#define C_swig_is_string(x) (C_truep (C_blockp (x)) && C_truep (C_stringp (x)))
-#define C_swig_is_vector(x) (C_truep (C_blockp (x)) && C_truep (C_vectorp (x)))
-#define C_swig_is_list(x) (C_truep (C_i_listp (x)))
-#define C_swig_is_pair(x) (C_truep (C_blockp(x)) && C_truep (C_pairp(x)))
-#define C_swig_is_ptr(x) (C_truep (C_blockp (x)) && C_truep (C_pointerp (x)))
-#define C_swig_is_swigpointer(x) (C_truep (C_blockp(x)) && C_truep (C_swigpointerp(x)))
-#define C_swig_is_closurep(x) (C_truep (C_blockp(x)) && C_truep(C_closurep(x)))
-#define C_swig_is_number(x) (C_swig_is_fixnum(x) || C_swig_is_flonum(x))
-#define C_swig_is_long(x) C_swig_is_number(x)
-
-#define C_swig_sizeof_closure(num) (num+1)
-
-#define SWIG_Chicken_SetupArgout { \
-  C_word *a = C_alloc(C_swig_sizeof_closure(2)); \
-  C_word *closure = a; \
-  *(a++)=C_CLOSURE_TYPE|2; \
-  *(a++)=(C_word)SWIG_Chicken_ApplyResults; \
-  *(a++)=continuation; \
-  continuation=(C_word)closure; \
-}
-
-#define SWIG_APPEND_VALUE(obj) { \
-  C_word val = (C_word)(obj); \
-  if (val != C_SCHEME_UNDEFINED) { \
-    C_word *a = C_alloc(C_swig_sizeof_closure(3)); \
-    C_word *closure = a; \
-    *(a++)=C_CLOSURE_TYPE|3; \
-    *(a++)=(C_word)SWIG_Chicken_MultiResultBuild; \
-    *(a++)=(C_word)continuation; \
-    *(a++)=val; \
-    continuation=(C_word)closure; \
-  } }
-
-#define SWIG_Chicken_FindCreateProxy(func,obj) \
-  if (C_swig_is_swigpointer(obj)) { \
-    swig_type_info *t = (swig_type_info *) C_block_item(obj, 1); \
-    if (t && t->clientdata &&    ((swig_chicken_clientdata *)t->clientdata)->gc_proxy_create) { \
-      func = CHICKEN_gc_root_ref( ((swig_chicken_clientdata *)t->clientdata)->gc_proxy_create); \
-    } else { \
-      func = C_SCHEME_FALSE; \
-    } \
-  } else { \
-    func = C_SCHEME_FALSE; \
-  }
-
-
-enum {
-  SWIG_BARF1_BAD_ARGUMENT_TYPE /* 1 arg */,
-  SWIG_BARF1_ARGUMENT_NULL /* 1 arg */,
-  SWIG_BARF1_CONTRACT_ASSERT /* 1 arg */,
-};
-
-typedef C_word (*swig_chicken_destructor)(C_word,C_word,C_word,C_word);
-typedef struct swig_chicken_clientdata {
-  void *gc_proxy_create;
-  swig_chicken_destructor destroy;
-} swig_chicken_clientdata;
-  
-static char *
-SWIG_Chicken_MakeString(C_word str) {
-  char *ret;
-  size_t l;
-
-  l = C_header_size(str);
-  ret = (char *) SWIG_malloc( (l + 1) * sizeof(char));
-  if (!ret) return NULL;
-
-  memcpy(ret, C_c_string(str), l);
-  ret[l] = '\0';
-  return ret;
-}
-
-static C_word SWIG_Chicken_LookupSymbol(char *name, C_SYMBOL_TABLE *stable) {
-  C_word *a = C_alloc(C_SIZEOF_STRING (strlen (name)));
-  C_word n = C_string2(&a, name);
-  C_word sym = C_find_symbol(n, stable);
-  if (C_truep(sym)) {
-    return C_symbol_value(sym);
-  } else {
-    return C_SCHEME_FALSE;
-  }
-}
-
-/* Just a helper function.  Do not export it */
-static void SWIG_Chicken_Panic (C_char *) C_noret;
-static void SWIG_Chicken_Panic (C_char *msg)
-{
-  C_word *a = C_alloc (C_SIZEOF_STRING (strlen (msg)));
-  C_word scmmsg = C_string2 (&a, msg);
-  C_halt (scmmsg);
-  exit (5); /* should never get here */
-}
-
-static void
-SWIG_Chicken_Barf(int code, C_char *msg, ...) C_noret;
-static void
-SWIG_Chicken_Barf(int code, C_char *msg, ...)
-{
-  char *errorhook = C_text("\003syserror-hook");
-  C_word *a = C_alloc (C_SIZEOF_STRING (strlen (errorhook)));
-  C_word err = C_intern2 (&a, errorhook);
-  int c = -1;
-  int i, barfval;
-  va_list v;
-
-  
-  C_temporary_stack = C_temporary_stack_bottom;
-  err = C_block_item(err, 0);
-
-  if(C_immediatep (err))
-    SWIG_Chicken_Panic (C_text ("`##sys#error-hook' is not defined"));
-
-  switch (code) {
-  case SWIG_BARF1_BAD_ARGUMENT_TYPE:
-    barfval = C_BAD_ARGUMENT_TYPE_ERROR;
-    c = 1;
-    break;
-  case SWIG_BARF1_ARGUMENT_NULL:
-    barfval = C_BAD_ARGUMENT_TYPE_ERROR;
-    c = 1;
-    break;
-  case SWIG_BARF1_CONTRACT_ASSERT:
-    barfval = C_BAD_ARGUMENT_TYPE_ERROR;
-    c = 1;
-    break;
-  default:
-    SWIG_Chicken_Panic (C_text (msg));
-  };
-
-  if(c > 0 && !C_immediatep (err)) {
-    C_save (C_fix (barfval));
-
-    i = c;
-    if (i) {
-      C_word *b = C_alloc (C_SIZEOF_STRING (strlen (msg)));
-      C_word scmmsg = C_string2 (&b, msg);
-      C_save (scmmsg);
-      i--;
-    }
-
-    va_start (v, msg);
-
-    while(i--)
-      C_save (va_arg (v, C_word));
-
-    va_end (v);
-    C_do_apply (c + 1, err, 
-		C_SCHEME_UNDEFINED);  /* <- no continuation is passed:
-					 '##sys#error-hook' may not
-					 return! */
-  }
-  else if (msg) {
-    SWIG_Chicken_Panic (msg);
-  }
-  else {
-    SWIG_Chicken_Panic (C_text ("unspecified panic"));
-  }
-}
-
-static void SWIG_Chicken_ThrowException(C_word value) C_noret;
-static void SWIG_Chicken_ThrowException(C_word value)
-{
-  char *aborthook = C_text("\003sysabort");
-  C_word *a = C_alloc(C_SIZEOF_STRING(strlen(aborthook)));
-  C_word abort = C_intern2(&a, aborthook);
-
-  abort = C_block_item(abort, 0);
-  if (C_immediatep(abort))
-    SWIG_Chicken_Panic(C_text("`##sys#abort' is not defined"));
-
-  C_save(value);
-  C_do_apply(1, abort, C_SCHEME_UNDEFINED);
-}
-
-static void
-SWIG_Chicken_Finalizer(C_word argc, C_word closure, C_word continuation, C_word s)
-{
-  swig_type_info *type;
-  swig_chicken_clientdata *cdata;
-
-  if (argc == 3 && s != C_SCHEME_FALSE && C_swig_is_swigpointer(s)) {
-    type = (swig_type_info *) C_block_item(s, 1);
-    if (type) {
-      cdata = (swig_chicken_clientdata *) type->clientdata;
-      if (cdata && cdata->destroy) {
-	/* this will not return, but will continue correctly */
-        cdata->destroy(3,closure,continuation,s);
-      }
-    }
-  }
-  C_kontinue(continuation, C_SCHEME_UNDEFINED);
-}
-static C_word finalizer_obj[2] = {(C_word) (C_CLOSURE_TYPE|1), (C_word) SWIG_Chicken_Finalizer};
-
-static C_word
-SWIG_Chicken_NewPointerObj(void *ptr, swig_type_info *type, int owner, C_word **data)
-{
-  swig_chicken_clientdata *cdata = (swig_chicken_clientdata *) type->clientdata;
-
-  if (ptr == NULL)
-    return C_SCHEME_FALSE;
-  else {
-    C_word cptr = C_swigmpointer(data, ptr, type);
-    /* add finalizer to object */
-    #ifndef SWIG_CHICKEN_NO_COLLECTION
-    if (owner)
-      C_do_register_finalizer(cptr, (C_word) finalizer_obj);
-    #endif
-
-    return cptr;
-  }
-}
-
-/* Return 0 if successful. */
-static int
-SWIG_Chicken_ConvertPtr(C_word s, void **result, swig_type_info *type, int flags)
-{
-  swig_cast_info *cast;
-  swig_type_info *from;
-
-  if (s == C_SCHEME_FALSE) {
-    *result = NULL;
-    return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
-  } else if (C_swig_is_swigpointer(s)) {
-    /* try and convert type */
-    from = (swig_type_info *) C_block_item(s, 1);
-    if (!from) return 1;
-    if (type) {
-      cast = SWIG_TypeCheckStruct(from, type);
-      if (cast) {
-        int newmemory = 0;
-        *result = SWIG_TypeCast(cast, (void *) C_block_item(s, 0), &newmemory);
-        assert(!newmemory); /* newmemory handling not yet implemented */
-      } else {
-        return 1;
-      }
-    } else {
-      *result = (void *) C_block_item(s, 0);
-    }
-
-    /* check if we are disowning this object */
-    if (flags & SWIG_POINTER_DISOWN) {
-      C_do_unregister_finalizer(s);
-    }
-  } else {
-    return 1;
-  }
-
-  return 0;
-}
-
-static SWIGINLINE void *
-SWIG_Chicken_MustGetPtr (C_word s, swig_type_info *type, int argnum, int flags)
-{
-  void *result;
-  char err_msg[256];
-  if (SWIG_Chicken_ConvertPtr(s, &result, type, flags)) {
-    /* type mismatch */
-    snprintf(err_msg, sizeof(err_msg), "Type error in argument #%i: expected %s", argnum, (type->str ? type->str : type->name));
-    SWIG_Chicken_Barf(SWIG_BARF1_BAD_ARGUMENT_TYPE, err_msg);
-  }
-  return result;
-}
-
-static char *chicken_runtimevar_name = "type_pointer" SWIG_TYPE_TABLE_NAME;
-
-static swig_module_info *
-SWIG_Chicken_GetModule(void *SWIGUNUSEDPARM(clientdata)) {
-    swig_module_info *ret = 0;
-    C_word sym;
-
-    /* lookup the type pointer... it is stored in its own symbol table */
-    C_SYMBOL_TABLE *stable = C_find_symbol_table("swig_runtime_data" SWIG_RUNTIME_VERSION);
-    if (stable != NULL) {
-      sym = SWIG_Chicken_LookupSymbol(chicken_runtimevar_name, stable);
-      if (C_truep(sym) && C_swig_is_ptr(sym)) {
-        ret = (swig_module_info *) C_block_item(sym, 0);
-      }
-    }
-
-    return ret;
-}
-
-static void
-SWIG_Chicken_SetModule(swig_module_info *module) {
-    C_word *a;
-    C_SYMBOL_TABLE *stable;
-    C_word sym;
-    C_word pointer;
-    static C_word *space = 0;
-    
-    /* type pointer is stored in its own symbol table */
-    stable = C_find_symbol_table("swig_runtime_data" SWIG_RUNTIME_VERSION);
-    if (stable == NULL) {
-      stable = C_new_symbol_table("swig_runtime_data" SWIG_RUNTIME_VERSION, 16);
-    }
-
-    if (!space) {
-      space = (C_word *) C_malloc((C_SIZEOF_POINTER + C_SIZEOF_INTERNED_SYMBOL(C_strlen(chicken_runtimevar_name))) * sizeof(C_word));
-    }
-    a = space;
-    pointer = C_mpointer(&a, (void *) module);
-    sym = C_intern_in(&a, C_strlen(chicken_runtimevar_name), chicken_runtimevar_name, stable);
-    C_set_block_item(sym, 0, pointer);
-}
-
-static C_word SWIG_Chicken_MultiResultBuild(C_word num, C_word closure, C_word lst) {
-  C_word cont = C_block_item(closure,1);
-  C_word obj = C_block_item(closure,2);
-  C_word func;
-
-  SWIG_Chicken_FindCreateProxy(func,obj);
-
-  if (C_swig_is_closurep(func)) {
-    ((C_proc4)(void *)C_block_item(func, 0))(4,func,cont,obj,lst);
-  } else {
-    C_word *a = C_alloc(C_SIZEOF_PAIR);
-    C_kontinue(cont,C_pair(&a,obj,lst));
-  }
-  return C_SCHEME_UNDEFINED; /* never reached */
-}
-
-static C_word SWIG_Chicken_ApplyResults(C_word num, C_word closure, C_word result) {
-  C_apply_values(3,C_SCHEME_UNDEFINED,C_block_item(closure,1),result);
-  return C_SCHEME_UNDEFINED; /* never reached */
-}
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/Lib/chicken/extra-install.list b/Lib/chicken/extra-install.list
deleted file mode 100644
index 48721ce..0000000
--- a/Lib/chicken/extra-install.list
+++ /dev/null
@@ -1,3 +0,0 @@
-swigclosprefix.scm
-multi-generic.scm
-tinyclos-multi-generic.patch
diff --git a/Lib/chicken/multi-generic.scm b/Lib/chicken/multi-generic.scm
deleted file mode 100644
index 9d2e31d..0000000
--- a/Lib/chicken/multi-generic.scm
+++ /dev/null
@@ -1,152 +0,0 @@
-;; This file is no longer necessary with Chicken versions above 1.92
-;; 
-;; This file overrides two functions inside TinyCLOS to provide support
-;; for multi-argument generics.  There are many ways of linking this file
-;; into your code... all that needs to happen is this file must be
-;; executed after loading TinyCLOS but before any SWIG modules are loaded
-;;
-;; something like the following
-;; (require 'tinyclos)
-;; (load "multi-generic")
-;; (declare (uses swigmod))
-;;
-;; An alternative to loading this scheme code directly is to add a
-;; (declare (unit multi-generic)) to the top of this file, and then
-;; compile this into the final executable or something.  Or compile
-;; this into an extension.
-
-;; Lastly, to override TinyCLOS method creation, two functions are
-;; overridden: see the end of this file for which two are overridden.
-;; You might want to remove those two lines and then exert more control over
-;; which functions are used when.
-
-;; Comments, bugs, suggestions: send either to chicken-users@nongnu.org or to
-;; Most code copied from TinyCLOS
-
-(define <multi-generic> (make <entity-class>
-			  'name "multi-generic"
-			  'direct-supers (list <generic>)
-			  'direct-slots '()))
-
-(letrec ([applicable?
-          (lambda (c arg)
-            (memq c (class-cpl (class-of arg))))]
-
-         [more-specific?
-          (lambda (c1 c2 arg)
-            (memq c2 (memq c1 (class-cpl (class-of arg)))))]
-
-         [filter-in
-           (lambda (f l)
-             (if (null? l)
-                 '()
-                 (let ([h (##sys#slot l 0)]
-	               [r (##sys#slot l 1)] )
-	           (if (f h)
-	               (cons h (filter-in f r))
-	               (filter-in f r) ) ) ) )])
-
-(add-method compute-apply-generic
-  (make-method (list <multi-generic>)
-    (lambda (call-next-method generic)
-      (lambda args
-		(let ([cam (let ([x (compute-apply-methods generic)]
-				 [y ((compute-methods generic) args)] )
-			     (lambda (args) (x y args)) ) ] )
-		  (cam args) ) ) ) ) )
-
-
-
-(add-method compute-methods
-  (make-method (list <multi-generic>)
-    (lambda (call-next-method generic)
-      (lambda (args)
-	(let ([applicable
-	       (filter-in (lambda (method)
-                            (let check-applicable ([list1 (method-specializers method)]
-                                                   [list2 args])
-                              (cond ((null? list1) #t)
-                                    ((null? list2) #f)
-                                    (else
-                                      (and (applicable? (##sys#slot list1 0) (##sys#slot list2 0))
-                                           (check-applicable (##sys#slot list1 1) (##sys#slot list2 1)))))))
-			  (generic-methods generic) ) ] )
-	  (if (or (null? applicable) (null? (##sys#slot applicable 1))) 
-	      applicable
-	      (let ([cmms (compute-method-more-specific? generic)])
-		(sort applicable (lambda (m1 m2) (cmms m1 m2 args))) ) ) ) ) ) ) )
-
-(add-method compute-method-more-specific?
-  (make-method (list <multi-generic>)
-    (lambda (call-next-method generic)
-      (lambda (m1 m2 args)
-	(let loop ((specls1 (method-specializers m1))
-		   (specls2 (method-specializers m2))
-		   (args args))
-	  (cond-expand
-	   [unsafe
-	    (let ((c1  (##sys#slot specls1 0))
-		  (c2  (##sys#slot specls2 0))
-		  (arg (##sys#slot args 0)))
-	      (if (eq? c1 c2)
-		  (loop (##sys#slot specls1 1)
-			(##sys#slot specls2 1)
-			(##sys#slot args 1))
-		  (more-specific? c1 c2 arg))) ] 
-	   [else
-	    (cond ((and (null? specls1) (null? specls2))
-		   (##sys#error "two methods are equally specific" generic))
-		  ;((or (null? specls1) (null? specls2))
-		  ; (##sys#error "two methods have different number of specializers" generic))
-                  ((null? specls1) #f)
-                  ((null? specls2) #t)
-		  ((null? args)
-		   (##sys#error "fewer arguments than specializers" generic))
-		  (else
-		   (let ((c1  (##sys#slot specls1 0))
-			 (c2  (##sys#slot specls2 0))
-			 (arg (##sys#slot args 0)))
-		     (if (eq? c1 c2)
-			 (loop (##sys#slot specls1 1)
-			       (##sys#slot specls2 1)
-			       (##sys#slot args 1))
-			 (more-specific? c1 c2 arg)))) ) ] ) ) ) ) ) )
-
-) ;; end of letrec
-
-(define multi-add-method
-  (lambda (generic method)
-    (slot-set!
-     generic
-     'methods
-       (let filter-in-method ([methods (slot-ref generic 'methods)])
-         (if (null? methods)
-           (list method)
-           (let ([l1 (length (method-specializers method))]
-		 [l2 (length (method-specializers (##sys#slot methods 0)))])
-             (cond ((> l1 l2)
-                    (cons (##sys#slot methods 0) (filter-in-method (##sys#slot methods 1))))
-                   ((< l1 l2)
-                    (cons method methods))
-                   (else
-                     (let check-method ([ms1 (method-specializers method)]
-                                        [ms2 (method-specializers (##sys#slot methods 0))])
-                       (cond ((and (null? ms1) (null? ms2))
-                              (cons method (##sys#slot methods 1))) ;; skip the method already in the generic
-                             ((eq? (##sys#slot ms1 0) (##sys#slot ms2 0))
-                              (check-method (##sys#slot ms1 1) (##sys#slot ms2 1)))
-                             (else
-                               (cons (##sys#slot methods 0) (filter-in-method (##sys#slot methods 1))))))))))))
-
-    (##sys#setslot (##sys#slot generic (- (##sys#size generic) 2)) 1 (compute-apply-generic generic)) ))
-
-(define (multi-add-global-method val sym specializers proc)
-  (let ((generic (if (procedure? val) val (make <multi-generic> 'name (##sys#symbol->string sym)))))
-    (multi-add-method generic (make-method specializers proc))
-    generic))
-
-;; Might want to remove these, or perhaps do something like
-;; (define old-add-method ##tinyclos#add-method)
-;; and then you can switch between creating multi-generics and TinyCLOS generics.
-(set! ##tinyclos#add-method multi-add-method)
-(set! ##tinyclos#add-global-method multi-add-global-method)
diff --git a/Lib/chicken/std_string.i b/Lib/chicken/std_string.i
deleted file mode 100644
index fa77c15..0000000
--- a/Lib/chicken/std_string.i
+++ /dev/null
@@ -1,96 +0,0 @@
-/* -----------------------------------------------------------------------------
- * std_string.i
- *
- * SWIG typemaps for std::string
- * ----------------------------------------------------------------------------- */
-
-%{
-#include <string>
-%}
-
-namespace std {
-    %naturalvar string;
-  
-
-    %insert(closprefix) %{ (declare (hide <std-string>)) %}
-    %nodefault string;
-    %rename("std-string") string;
-    class string {
-      public:
-	~string() {}
-    };
-    %extend string {
-      char *str;
-    }
-    %{
-      #define std_string_str_get(s) ((char *)((s)->c_str()))
-      #define std_string_str_set(s,v) (s->assign((char *)(v)))
-    %}
-
-    %typemap(typecheck) string = char *;
-    %typemap(typecheck) const string & = char *;
-
-    %typemap(in) string (char * tempptr) {
-      if ($input == C_SCHEME_FALSE) {
-	$1.resize(0);
-      } else { 
-	if (!C_swig_is_string ($input)) {
-	  swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, 
-		     "Argument #$argnum is not a string");
-	}
-	tempptr = SWIG_MakeString($input);
-	$1.assign(tempptr);
-	if (tempptr) SWIG_free(tempptr);
-      }
-    }
-
-    %typemap(in) const string& ($*1_ltype temp, char *tempptr) {
-
-      if ($input == C_SCHEME_FALSE) {
-	temp.resize(0);
-	$1 = &temp;
-      } else { 
-	if (!C_swig_is_string ($input)) {
-	  swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, 
-		     "Argument #$argnum is not a string");
-	}
-	tempptr = SWIG_MakeString($input);
-	temp.assign(tempptr);
-	if (tempptr) SWIG_free(tempptr);
-	$1 = &temp;
-      }
-    }
-
-    %typemap(out) string { 
-      int size = $1.size();
-      C_word *space = C_alloc (C_SIZEOF_STRING (size));
-      $result = C_string (&space, size, (char *) $1.c_str());
-    }
-
-    %typemap(out) const string& { 
-      int size = $1->size();
-      C_word *space = C_alloc (C_SIZEOF_STRING (size));
-      $result = C_string (&space, size, (char *) $1->c_str());
-    }
-
-    %typemap(varin) string {
-      if ($input == C_SCHEME_FALSE) {
-	$1.resize(0);
-      } else { 
-        char *tempptr;
-	if (!C_swig_is_string ($input)) {
-	  swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, 
-		     "Argument #$argnum is not a string");
-   	}
-	tempptr = SWIG_MakeString($input);
-	$1.assign(tempptr);
-	if (tempptr) SWIG_free(tempptr);
-      }
-    }
-
-    %typemap(varout) string { 
-      int size = $1.size();
-      C_word *space = C_alloc (C_SIZEOF_STRING (size));
-      $result = C_string (&space, size, (char *) $1.c_str());
-    }
-}
diff --git a/Lib/chicken/swigclosprefix.scm b/Lib/chicken/swigclosprefix.scm
deleted file mode 100644
index e4bd72b..0000000
--- a/Lib/chicken/swigclosprefix.scm
+++ /dev/null
@@ -1,31 +0,0 @@
-(declare (hide swig-initialize))
-
-(define (swig-initialize obj initargs create)
-     (slot-set! obj 'swig-this
-        (if (memq 'swig-this initargs)
-            (cadr initargs)
-            (let ((ret (apply create initargs)))
-              (if (instance? ret)
-                (slot-ref ret 'swig-this)
-                ret)))))
-
-(define-class <swig-metaclass-$module> (<class>) (void))
-
-(define-method (compute-getter-and-setter (class <swig-metaclass-$module>) slot allocator)
-  (if (not (memq ':swig-virtual slot))
-    (call-next-method)
-    (let ((getter (let search-get ((lst slot))
-                    (if (null? lst)
-                      #f
-                      (if (eq? (car lst) ':swig-get)
-                        (cadr lst)
-                        (search-get (cdr lst))))))
-          (setter (let search-set ((lst slot))
-                    (if (null? lst)
-                      #f
-                      (if (eq? (car lst) ':swig-set)
-                        (cadr lst)
-                        (search-set (cdr lst)))))))
-      (values
-        (lambda (o) (getter (slot-ref o 'swig-this)))
-	(lambda (o new) (setter (slot-ref o 'swig-this) new) new)))))
diff --git a/Lib/chicken/tinyclos-multi-generic.patch b/Lib/chicken/tinyclos-multi-generic.patch
deleted file mode 100644
index 2e58596..0000000
--- a/Lib/chicken/tinyclos-multi-generic.patch
+++ /dev/null
@@ -1,150 +0,0 @@
-# This patch is against chicken 1.92, but it should work just fine
-# with older versions of chicken.  It adds support for mulit-argument
-# generics, that is, generics now correctly handle adding methods
-# with different lengths of specializer lists
-
-# This patch has been committed into the CHICKEN darcs repository,
-# so chicken versions above 1.92 work fine.
-
-# Comments, bugs, suggestions send to chicken-users@nongnu.org
-
-# Patch written by John Lenz <lenz@cs.wisc.edu>
-
---- tinyclos.scm.old	2005-04-05 01:13:56.000000000 -0500
-+++ tinyclos.scm	2005-04-11 16:37:23.746181489 -0500
-@@ -37,8 +37,10 @@
- 
- (include "parameters")
- 
-+(cond-expand [(not chicken-compile-shared) (declare (unit tinyclos))]
-+	     [else] )
-+
- (declare
--  (unit tinyclos)
-   (uses extras)
-   (usual-integrations)
-   (fixnum) 
-@@ -234,7 +236,10 @@
-             y = C_block_item(y, 1);
-           }
-         }
--        return(C_block_item(v, i + 1));
-+        if (x == C_SCHEME_END_OF_LIST && y == C_SCHEME_END_OF_LIST)
-+          return(C_block_item(v, i + 1));
-+        else
-+          goto mismatch;
-       }
-       else if(free_index == -1) free_index = i;
-     mismatch:
-@@ -438,7 +443,7 @@
- (define hash-arg-list
-   (foreign-lambda* unsigned-int ((scheme-object args) (scheme-object svector)) "
-     C_word tag, h, x;
--    int n, i, j;
-+    int n, i, j, len = 0;
-     for(i = 0; args != C_SCHEME_END_OF_LIST; args = C_block_item(args, 1)) {
-       x = C_block_item(args, 0);
-       if(C_immediatep(x)) {
-@@ -481,8 +486,9 @@
-         default: i += 255;
-         }
-       }
-+      ++len;
-     }
--    return(i & (C_METHOD_CACHE_SIZE - 1));") )
-+    return((i + len) & (C_METHOD_CACHE_SIZE - 1));") )
- 
- 
- ;
-@@ -868,13 +874,27 @@
-     (##tinyclos#slot-set!
-      generic
-      'methods
--     (cons method
--	   (filter-in
--	    (lambda (m) 
--	      (let ([ms1 (method-specializers m)]
--		    [ms2 (method-specializers method)] )
--		(not (every2 (lambda (x y) (eq? x y)) ms1 ms2) ) ) )
--	    (##tinyclos#slot-ref generic 'methods))))
-+     (let* ([ms1 (method-specializers method)]
-+	    [l1 (length ms1)] )
-+       (let filter-in-method ([methods (##tinyclos#slot-ref generic 'methods)])
-+	 (if (null? methods)
-+	     (list method)
-+	     (let* ([mm (##sys#slot methods 0)]
-+		    [ms2 (method-specializers mm)]
-+		    [l2 (length ms2)])
-+	       (cond ((> l1 l2)
-+		      (cons mm (filter-in-method (##sys#slot methods 1))))
-+		     ((< l1 l2)
-+		      (cons method methods))
-+		     (else
-+		      (let check-method ([ms1 ms1]
-+					 [ms2 ms2])
-+			(cond ((and (null? ms1) (null? ms2))
-+			       (cons method (##sys#slot methods 1))) ;; skip the method already in the generic
-+			      ((eq? (##sys#slot ms1 0) (##sys#slot ms2 0))
-+			       (check-method (##sys#slot ms1 1) (##sys#slot ms2 1)))
-+			      (else
-+			       (cons mm (filter-in-method (##sys#slot methods 1)))))))))))))
-     (if (memq generic generic-invocation-generics)
- 	(set! method-cache-tag (vector))
- 	(%entity-cache-set! generic #f) )
-@@ -925,11 +945,13 @@
- 				(memq (car args) generic-invocation-generics))
- 			   (let ([proc 
- 				  (method-procedure
-+				    ; select the first method of one argument
- 				   (let lp ([lis (generic-methods generic)])
--				     (let ([tail (##sys#slot lis 1)])
--				       (if (null? tail)
--					   (##sys#slot lis 0)
--					   (lp tail)) ) ) ) ] )
-+				     (if (null? lis)
-+				       (##sys#error "Unable to find original compute-apply-generic")
-+				       (if (= (length (method-specializers (##sys#slot lis 0))) 1)
-+					 (##sys#slot lis 0)
-+					 (lp (##sys#slot lis 1)))))) ] )
- 			     (lambda (args) (apply proc #f args)) )
- 			   (let ([x (compute-apply-methods generic)]
- 				 [y ((compute-methods generic) args)] )
-@@ -946,9 +968,13 @@
-       (lambda (args)
- 	(let ([applicable
- 	       (filter-in (lambda (method)
--			    (every2 applicable?
--				   (method-specializers method)
--				   args))
-+                            (let check-applicable ([list1 (method-specializers method)]
-+                                                   [list2 args])
-+                              (cond ((null? list1) #t)
-+                                    ((null? list2) #f)
-+                                    (else
-+                                      (and (applicable? (##sys#slot list1 0) (##sys#slot list2 0))
-+                                           (check-applicable (##sys#slot list1 1) (##sys#slot list2 1)))))))
- 			  (generic-methods generic) ) ] )
- 	  (if (or (null? applicable) (null? (##sys#slot applicable 1))) 
- 	      applicable
-@@ -975,8 +1001,10 @@
- 	   [else
- 	    (cond ((and (null? specls1) (null? specls2))
- 		   (##sys#error "two methods are equally specific" generic))
--		  ((or (null? specls1) (null? specls2))
--		   (##sys#error "two methods have different number of specializers" generic))
-+		  ;((or (null? specls1) (null? specls2))
-+		  ; (##sys#error "two methods have different number of specializers" generic))
-+                  ((null? specls1) #f)
-+                  ((null? specls2) #t)
- 		  ((null? args)
- 		   (##sys#error "fewer arguments than specializers" generic))
- 		  (else
-@@ -1210,7 +1238,7 @@
- (define <structure>      (make-primitive-class "structure"))
- (define <procedure> (make-primitive-class "procedure" <procedure-class>))
- (define <end-of-file> (make-primitive-class "end-of-file"))
--(define <environment> (make-primitive-class "environment" <structure>))	; (Benedikt insisted on this)
-+(define <environment> (make-primitive-class "environment" <structure>))
- (define <hash-table> (make-primitive-class "hash-table" <structure>))
- (define <promise> (make-primitive-class "promise" <structure>))
- (define <queue> (make-primitive-class "queue" <structure>))
diff --git a/Lib/chicken/typemaps.i b/Lib/chicken/typemaps.i
deleted file mode 100644
index fd587fd..0000000
--- a/Lib/chicken/typemaps.i
+++ /dev/null
@@ -1,314 +0,0 @@
-/* -----------------------------------------------------------------------------
- * typemaps.i
- *
- * Pointer handling
- *
- * These mappings provide support for input/output arguments and
- * common uses for C/C++ pointers.  INOUT mappings allow for C/C++
- * pointer variables in addition to input/output arguments.
- * ----------------------------------------------------------------------------- */
-
-// INPUT typemaps.
-// These remap a C pointer to be an "INPUT" value which is passed by value
-// instead of reference.
-
-/* 
-The following methods can be applied to turn a pointer into a simple
-"input" value.  That is, instead of passing a pointer to an object,
-you would use a real value instead.
-
-         int            *INPUT
-         short          *INPUT
-         long           *INPUT
-	 long long      *INPUT
-         unsigned int   *INPUT
-         unsigned short *INPUT
-         unsigned long  *INPUT
-         unsigned long long *INPUT
-         unsigned char  *INPUT
-         char           *INPUT
-         bool           *INPUT
-         float          *INPUT
-         double         *INPUT
-         
-To use these, suppose you had a C function like this :
-
-        double fadd(double *a, double *b) {
-               return *a+*b;
-        }
-
-You could wrap it with SWIG as follows :
-        
-        %include <typemaps.i>
-        double fadd(double *INPUT, double *INPUT);
-
-or you can use the %apply directive :
-
-        %include <typemaps.i>
-        %apply double *INPUT { double *a, double *b };
-        double fadd(double *a, double *b);
-
-*/
-
-// OUTPUT typemaps.   These typemaps are used for parameters that
-// are output only.   The output value is appended to the result as
-// a list element.
-
-/* 
-The following methods can be applied to turn a pointer into an "output"
-value.  When calling a function, no input value would be given for
-a parameter, but an output value would be returned.  In the case of
-multiple output values, they are returned in the form of a Scheme list.
-
-         int            *OUTPUT
-         short          *OUTPUT
-         long           *OUTPUT
-         long long      *OUTPUT
-         unsigned int   *OUTPUT
-         unsigned short *OUTPUT
-         unsigned long  *OUTPUT
-         unsigned long long *OUTPUT
-         unsigned char  *OUTPUT
-         char           *OUTPUT
-         bool           *OUTPUT
-         float          *OUTPUT
-         double         *OUTPUT
-         
-For example, suppose you were trying to wrap the modf() function in the
-C math library which splits x into integral and fractional parts (and
-returns the integer part in one of its parameters).K:
-
-        double modf(double x, double *ip);
-
-You could wrap it with SWIG as follows :
-
-        %include <typemaps.i>
-        double modf(double x, double *OUTPUT);
-
-or you can use the %apply directive :
-
-        %include <typemaps.i>
-        %apply double *OUTPUT { double *ip };
-        double modf(double x, double *ip);
-
-*/
-
-//----------------------------------------------------------------------
-//
-// T_OUTPUT typemap (and helper function) to return multiple argouts as
-// a tuple instead of a list.
-//
-//----------------------------------------------------------------------
-
-// Simple types
-
-%define INOUT_TYPEMAP(type_, from_scheme, to_scheme, checker, convtype, storage_)
-
-%typemap(in) type_ *INPUT($*1_ltype temp), type_ &INPUT($*1_ltype temp)
-%{  if (!checker ($input)) {
-    swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, "Argument #$argnum is not of type 'type_'");
-  }
-  temp = ($*1_ltype) from_scheme ($input);
-  $1 = &temp; %}
-
-%typemap(typecheck) type_ *INPUT = type_;
-%typemap(typecheck) type_ &INPUT = type_;
-
-%typemap(in, numinputs=0) type_ *OUTPUT($*1_ltype temp), type_ &OUTPUT($*1_ltype temp)
-"  $1 = &temp;"
-
-#if "storage_" == "0"
-
-%typemap(argout) type_ *OUTPUT, type_ &OUTPUT 
-%{ 
-  if ($1 == NULL) {
-    swig_barf (SWIG_BARF1_ARGUMENT_NULL, "Argument #$argnum must be non-null");
-  }
-  SWIG_APPEND_VALUE(to_scheme (convtype (*$1)));
-%}
-
-#else
-
-%typemap(argout) type_ *OUTPUT, type_ &OUTPUT 
-%{
-  {
-    C_word *known_space = C_alloc(storage_);
-    if ($1 == NULL) {
-      swig_barf (SWIG_BARF1_ARGUMENT_NULL, "Variable '$1' must be non-null");
-    }
-    SWIG_APPEND_VALUE(to_scheme (&known_space, convtype (*$1)));
-  }
-%}
-
-#endif
-
-%enddef
-
-INOUT_TYPEMAP(int, C_num_to_int, C_fix, C_swig_is_number, (int), 0);
-INOUT_TYPEMAP(enum SWIGTYPE, C_num_to_int, C_fix, C_swig_is_number, (int), 0);
-INOUT_TYPEMAP(short, C_num_to_int, C_fix, C_swig_is_number, (int), 0);
-INOUT_TYPEMAP(long, C_num_to_long, C_long_to_num, C_swig_is_long, (long), C_SIZEOF_FLONUM);
-INOUT_TYPEMAP(long long, C_num_to_long, C_long_to_num, C_swig_is_long, (long), C_SIZEOF_FLONUM);
-INOUT_TYPEMAP(unsigned int, C_num_to_unsigned_int, C_unsigned_int_to_num, C_swig_is_number, (int), C_SIZEOF_FLONUM);
-INOUT_TYPEMAP(unsigned short, C_num_to_unsigned_int, C_fix, C_swig_is_number, (unsigned int), 0);
-INOUT_TYPEMAP(unsigned long, C_num_to_unsigned_long, C_unsigned_long_to_num, C_swig_is_long, (unsigned long), C_SIZEOF_FLONUM);
-INOUT_TYPEMAP(unsigned long long, C_num_to_unsigned_long, C_unsigned_long_to_num, C_swig_is_long, (unsigned long), C_SIZEOF_FLONUM);
-INOUT_TYPEMAP(unsigned char, C_character_code, C_make_character, C_swig_is_char, (unsigned int), 0);
-INOUT_TYPEMAP(signed char, C_character_code, C_make_character, C_swig_is_char, (int), 0);
-INOUT_TYPEMAP(char, C_character_code, C_make_character, C_swig_is_char, (char), 0);
-INOUT_TYPEMAP(bool, C_truep, C_mk_bool, C_swig_is_bool, (bool), 0);
-INOUT_TYPEMAP(float, C_c_double, C_flonum, C_swig_is_number, (double), C_SIZEOF_FLONUM);
-INOUT_TYPEMAP(double, C_c_double, C_flonum, C_swig_is_number, (double), C_SIZEOF_FLONUM);
-
-// INOUT
-// Mappings for an argument that is both an input and output
-// parameter
-
-/*
-The following methods can be applied to make a function parameter both
-an input and output value.  This combines the behavior of both the
-"INPUT" and "OUTPUT" methods described earlier.  Output values are
-returned in the form of a CHICKEN tuple.  
-
-         int            *INOUT
-         short          *INOUT
-         long           *INOUT
-         long long      *INOUT
-         unsigned int   *INOUT
-         unsigned short *INOUT
-         unsigned long  *INOUT
-         unsigned long long *INOUT
-         unsigned char  *INOUT
-         char           *INOUT
-         bool           *INOUT
-         float          *INOUT
-         double         *INOUT
-         
-For example, suppose you were trying to wrap the following function :
-
-        void neg(double *x) {
-             *x = -(*x);
-        }
-
-You could wrap it with SWIG as follows :
-
-        %include <typemaps.i>
-        void neg(double *INOUT);
-
-or you can use the %apply directive :
-
-        %include <typemaps.i>
-        %apply double *INOUT { double *x };
-        void neg(double *x);
-
-As well, you can wrap variables with :
-
-        %include <typemaps.i>
-        %apply double *INOUT { double *y };
-        extern double *y;
-
-Unlike C, this mapping does not directly modify the input value (since
-this makes no sense in CHICKEN).  Rather, the modified input value shows
-up as the return value of the function.  Thus, to apply this function
-to a CHICKEN variable you might do this :
-
-       x = neg(x)
-
-Note : previous versions of SWIG used the symbol 'BOTH' to mark
-input/output arguments.   This is still supported, but will be slowly
-phased out in future releases.
-
-*/
-
-%typemap(in) int *INOUT = int *INPUT;
-%typemap(in) enum SWIGTYPE *INOUT = enum SWIGTYPE *INPUT;
-%typemap(in) short *INOUT = short *INPUT;
-%typemap(in) long *INOUT = long *INPUT;
-%typemap(in) long long *INOUT = long long *INPUT;
-%typemap(in) unsigned *INOUT = unsigned *INPUT;
-%typemap(in) unsigned short *INOUT = unsigned short *INPUT;
-%typemap(in) unsigned long *INOUT = unsigned long *INPUT;
-%typemap(in) unsigned long long *INOUT = unsigned long long *INPUT;
-%typemap(in) unsigned char *INOUT = unsigned char *INPUT;
-%typemap(in) char *INOUT = char *INPUT;
-%typemap(in) bool *INOUT = bool *INPUT;
-%typemap(in) float *INOUT = float *INPUT;
-%typemap(in) double *INOUT = double *INPUT;
-
-%typemap(in) int &INOUT = int &INPUT;
-%typemap(in) enum SWIGTYPE &INOUT = enum SWIGTYPE &INPUT;
-%typemap(in) short &INOUT = short &INPUT;
-%typemap(in) long &INOUT = long &INPUT;
-%typemap(in) long long &INOUT = long long &INPUT;
-%typemap(in) unsigned &INOUT = unsigned &INPUT;
-%typemap(in) unsigned short &INOUT = unsigned short &INPUT;
-%typemap(in) unsigned long &INOUT = unsigned long &INPUT;
-%typemap(in) unsigned long long &INOUT = unsigned long long &INPUT;
-%typemap(in) unsigned char &INOUT = unsigned char &INPUT;
-%typemap(in) char &INOUT = char &INPUT;
-%typemap(in) bool &INOUT = bool &INPUT;
-%typemap(in) float &INOUT = float &INPUT;
-%typemap(in) double &INOUT = double &INPUT;
-
-%typemap(argout) int *INOUT = int *OUTPUT;
-%typemap(argout) enum SWIGTYPE *INOUT = enum SWIGTYPE *OUTPUT;
-%typemap(argout) short *INOUT = short *OUTPUT;
-%typemap(argout) long *INOUT = long *OUTPUT;
-%typemap(argout) long long *INOUT = long long *OUTPUT;
-%typemap(argout) unsigned *INOUT = unsigned *OUTPUT;
-%typemap(argout) unsigned short *INOUT = unsigned short *OUTPUT;
-%typemap(argout) unsigned long *INOUT = unsigned long *OUTPUT;
-%typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT;
-%typemap(argout) unsigned char *INOUT = unsigned char *OUTPUT;
-%typemap(argout) bool *INOUT = bool *OUTPUT;
-%typemap(argout) float *INOUT = float *OUTPUT;
-%typemap(argout) double *INOUT = double *OUTPUT;
-
-%typemap(argout) int &INOUT = int &OUTPUT;
-%typemap(argout) enum SWIGTYPE &INOUT = enum SWIGTYPE &OUTPUT;
-%typemap(argout) short &INOUT = short &OUTPUT;
-%typemap(argout) long &INOUT = long &OUTPUT;
-%typemap(argout) long long &INOUT = long long &OUTPUT;
-%typemap(argout) unsigned &INOUT = unsigned &OUTPUT;
-%typemap(argout) unsigned short &INOUT = unsigned short &OUTPUT;
-%typemap(argout) unsigned long &INOUT = unsigned long &OUTPUT;
-%typemap(argout) unsigned long long &INOUT = unsigned long long &OUTPUT;
-%typemap(argout) unsigned char &INOUT = unsigned char &OUTPUT;
-%typemap(argout) char &INOUT = char &OUTPUT;
-%typemap(argout) bool &INOUT = bool &OUTPUT;
-%typemap(argout) float &INOUT = float &OUTPUT;
-%typemap(argout) double &INOUT = double &OUTPUT;
-
-/* Overloading information */
-
-%typemap(typecheck) double *INOUT = double;
-%typemap(typecheck) bool *INOUT = bool;
-%typemap(typecheck) char *INOUT = char;
-%typemap(typecheck) signed char *INOUT = signed char;
-%typemap(typecheck) unsigned char *INOUT = unsigned char;
-%typemap(typecheck) unsigned long *INOUT = unsigned long;
-%typemap(typecheck) unsigned long long *INOUT = unsigned long long;
-%typemap(typecheck) unsigned short *INOUT = unsigned short;
-%typemap(typecheck) unsigned int *INOUT = unsigned int;
-%typemap(typecheck) long *INOUT = long;
-%typemap(typecheck) long long *INOUT = long long;
-%typemap(typecheck) short *INOUT = short;
-%typemap(typecheck) int *INOUT = int;
-%typemap(typecheck) enum SWIGTYPE *INOUT = enum SWIGTYPE;
-%typemap(typecheck) float *INOUT = float;
-
-%typemap(typecheck) double &INOUT = double;
-%typemap(typecheck) bool &INOUT = bool;
-%typemap(typecheck) char &INOUT = char;
-%typemap(typecheck) signed char &INOUT = signed char;
-%typemap(typecheck) unsigned char &INOUT = unsigned char;
-%typemap(typecheck) unsigned long &INOUT = unsigned long;
-%typemap(typecheck) unsigned long long &INOUT = unsigned long long;
-%typemap(typecheck) unsigned short &INOUT = unsigned short;
-%typemap(typecheck) unsigned int &INOUT = unsigned int;
-%typemap(typecheck) long &INOUT = long;
-%typemap(typecheck) long long &INOUT = long long;
-%typemap(typecheck) short &INOUT = short;
-%typemap(typecheck) int &INOUT = int;
-%typemap(typecheck) enum SWIGTYPE &INOUT = enum SWIGTYPE;
-%typemap(typecheck) float &INOUT = float;
diff --git a/Lib/clisp/clisp.swg b/Lib/clisp/clisp.swg
deleted file mode 100644
index e1d330c..0000000
--- a/Lib/clisp/clisp.swg
+++ /dev/null
@@ -1,32 +0,0 @@
-/* -----------------------------------------------------------------------------
- * clisp.swg
- * ----------------------------------------------------------------------------- */
-
-/* Define a C preprocessor symbol that can be used in interface files
-   to distinguish between the SWIG language modules. */ 
-
-#define SWIG_CLISP
-
-/* Typespecs for basic types. */
-
-%typemap(in) void "NIL";
-
-%typemap(in) char "character";
-%typemap(in) char * "ffi:c-string";
-%typemap(in) unsigned char "ffi:uchar";
-%typemap(in) signed char "ffi:char";
-
-%typemap(in) short "ffi:short";
-%typemap(in) signed short "ffi:short";
-%typemap(in) unsigned short "ffi:ushort";
-
-%typemap(in) int "ffi:int";
-%typemap(in) signed int "ffi:int";
-%typemap(in) unsigned int "ffi:uint";
-
-%typemap(in) long "ffi:long";
-%typemap(in) signed long "ffi:long";
-%typemap(in) unsigned long "ffi:ulong";
-
-%typemap(in) float "SINGLE-FLOAT";
-%typemap(in) double "DOUBLE-FLOAT";
diff --git a/Lib/constraints.i b/Lib/constraints.i
index 8bc7f91..77e9778 100644
--- a/Lib/constraints.i
+++ b/Lib/constraints.i
@@ -8,67 +8,60 @@
  * errors in a language-independent manner.
  * ----------------------------------------------------------------------------- */
 
-#ifdef AUTODOC
-%text %{
-%include <constraints.i>
-
-This library provides support for applying constraints to function
-arguments.  Using a constraint, you can restrict arguments to be
-positive numbers, non-NULL pointers, and so on.   The following
-constraints are available :
-
-      Number  POSITIVE        - Positive number (not zero)
-      Number  NEGATIVE        - Negative number (not zero)
-      Number  NONZERO         - Nonzero number
-      Number  NONNEGATIVE     - Positive number (including zero)
-      Number  NONPOSITIVE     - Negative number (including zero)
-      Pointer NONNULL         - Non-NULL pointer
-      Pointer ALIGN8          - 8-byte aligned pointer
-      Pointer ALIGN4          - 4-byte aligned pointer
-      Pointer ALIGN2          - 2-byte aligned pointer
-
-To use the constraints, you need to "apply" them to specific
-function arguments in your code.  This is done using the %apply
-directive.   For example :
-
-  %apply Number NONNEGATIVE { double nonneg };
-  double sqrt(double nonneg);         // Name of argument must match
-  
-  %apply Pointer NONNULL { void *ptr };
-  void *malloc(int POSITIVE);       // May return a NULL pointer
-  void free(void *ptr);             // May not accept a NULL pointer
-
-Any function argument of the type you specify with the %apply directive
-will be checked with the appropriate constraint.   Multiple types may
-be specified as follows :
-
-  %apply Pointer NONNULL { void *, Vector *, List *, double *};
-
-In this case, all of the types listed would be checked for non-NULL 
-pointers.
-
-The common datatypes of int, short, long, unsigned int, unsigned long,
-unsigned short, unsigned char, signed char, float, and double can be
-checked without using the %apply directive by simply using the 
-constraint name as the parameter name. For example :
-
-  double sqrt(double NONNEGATIVE);
-  double log(double POSITIVE);
-
-If you have used typedef to change type-names, you can also do this :
-
-  %apply double { Real };       // Make everything defined for doubles
-                                // work for Reals.
-  Real sqrt(Real NONNEGATIVE);
-  Real log(Real POSITIVE);
-
-%}
-#endif
+// This library provides support for applying constraints to function
+// arguments.  Using a constraint, you can restrict arguments to be
+// positive numbers, non-NULL pointers, and so on.   The following
+// constraints are available :
+//
+//       Number  POSITIVE        - Positive number (not zero)
+//       Number  NEGATIVE        - Negative number (not zero)
+//       Number  NONZERO         - Nonzero number
+//       Number  NONNEGATIVE     - Positive number (including zero)
+//       Number  NONPOSITIVE     - Negative number (including zero)
+//       Pointer NONNULL         - Non-NULL pointer
+//       Pointer ALIGN8          - 8-byte aligned pointer
+//       Pointer ALIGN4          - 4-byte aligned pointer
+//       Pointer ALIGN2          - 2-byte aligned pointer
+//
+// To use the constraints, you need to "apply" them to specific
+// function arguments in your code.  This is done using the %apply
+// directive.   For example :
+//
+//   %apply Number NONNEGATIVE { double nonneg };
+//   double sqrt(double nonneg);         // Name of argument must match
+//
+//   %apply Pointer NONNULL { FILE *stream };
+//   FILE *fdopen(int NONNEGATIVE);      // May return a NULL pointer
+//   int fclose(void *stream);           // Does not accept a NULL pointer
+//
+// Any function argument of the type you specify with the %apply directive
+// will be checked with the appropriate constraint.   Multiple types may
+// be specified as follows :
+//
+//   %apply Pointer NONNULL { void *, Vector *, List *, double *};
+//
+// In this case, all of the types listed would be checked for non-NULL
+// pointers.
+//
+// The common datatypes of int, short, long, unsigned int, unsigned long,
+// unsigned short, unsigned char, signed char, float, and double can be
+// checked without using the %apply directive by simply using the
+// constraint name as the parameter name. For example :
+//
+//   double sqrt(double NONNEGATIVE);
+//   double log(double POSITIVE);
+//
+// If you have used typedef to change type-names, you can also do this :
+//
+//   %apply double { Real };       // Make everything defined for doubles
+//                                 // work for Reals.
+//   Real sqrt(Real NONNEGATIVE);
+//   Real log(Real POSITIVE);
 
 %include <exception.i>
 
-#ifdef SWIGCSHARP
-// Required attribute for C# exception handling
+#if defined(SWIGCSHARP) || defined(SWIGD)
+// Required attribute for C# and D exception handling
 #define SWIGCSHARPCANTHROW , canthrow=1
 #else
 #define SWIGCSHARPCANTHROW
diff --git a/Lib/cpointer.i b/Lib/cpointer.i
index 881c511..df40c04 100644
--- a/Lib/cpointer.i
+++ b/Lib/cpointer.i
@@ -5,6 +5,12 @@
  * pointer objects.
  * ----------------------------------------------------------------------------- */
 
+#ifndef __cplusplus
+// C uses free/calloc/malloc
+%include "swigfragments.swg"
+%fragment("<stdlib.h>");
+#endif
+
 /* -----------------------------------------------------------------------------
  * %pointer_class(type,name)
  *
@@ -55,14 +61,14 @@
   return new TYPE();
 }
 ~NAME() {
-  if ($self) delete $self;
+  delete $self;
 }
 #else
 NAME() {
   return (TYPE *) calloc(1,sizeof(TYPE));
 }
 ~NAME() {
-  if ($self) free($self);
+  free($self);
 }
 #endif
 }
@@ -114,7 +120,7 @@
 
 %define %pointer_functions(TYPE,NAME)
 %{
-static TYPE *new_##NAME() { %}
+static TYPE *new_##NAME(void) { %}
 #ifdef __cplusplus
 %{  return new TYPE(); %}
 #else
@@ -134,9 +140,9 @@
 
 static void delete_##NAME(TYPE *obj) { %}
 #ifdef __cplusplus
-%{  if (obj) delete obj; %}
+%{  delete obj; %}
 #else
-%{  if (obj) free(obj); %}
+%{  free(obj); %}
 #endif
 %{}
 
@@ -149,7 +155,7 @@
 }
 %}
 
-TYPE *new_##NAME();
+TYPE *new_##NAME(void);
 TYPE *copy_##NAME(TYPE value);
 void  delete_##NAME(TYPE *obj);
 void  NAME##_assign(TYPE *obj, TYPE value);
diff --git a/Lib/csharp/argcargv.i b/Lib/csharp/argcargv.i
new file mode 100644
index 0000000..2dae1f6
--- /dev/null
+++ b/Lib/csharp/argcargv.i
@@ -0,0 +1,76 @@
+/* -------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------- */
+
+%typemap(cstype) (int ARGC, char **ARGV) "string[]"
+%typemap(imtype) (int ARGC, char **ARGV) "global::System.IntPtr"
+%typemap(ctype) (int ARGC, char **ARGV) "void*"
+%typemap(csin) (int ARGC, char **ARGV) "$modulePINVOKE.SWIG_csharp_string_array_to_c($csinput.Length, $csinput)"
+%pragma(csharp) imclasscode=%{
+  [global::System.Runtime.InteropServices.DllImport("$module", EntryPoint="SWIG_csharp_string_array_to_c")]
+  public static extern global::System.IntPtr SWIG_csharp_string_array_to_c(int len, [global::System.Runtime.InteropServices.In,global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPArray, ArraySubType=global::System.Runtime.InteropServices.UnmanagedType.LPStr, SizeParamIndex=0)] string[] array);
+%}
+%fragment("SWIG_csharp_string_array", "header") %{
+#ifdef __cplusplus
+extern "C" {
+#endif
+typedef struct { int len; char* array[1]; } SWIG_csharp_string_array;
+
+static void* SWIG_csharp_string_array_free(SWIG_csharp_string_array *arr) {
+  if (arr != SWIG_NULLPTR) {
+    int i;
+    for(i = 0; i < arr->len; i++) {
+      free(arr->array[i]);
+    }
+    free(arr);
+  }
+  return SWIG_NULLPTR;
+}
+
+SWIGEXPORT void* SWIGSTDCALL SWIG_csharp_string_array_to_c(int len, void *array) {
+  int i;
+  size_t alen, slen;
+  char *p, **ptr;
+  SWIG_csharp_string_array *ret;
+  /* We don't need to add one to len for the terminating NULL here because
+   * SWIG_csharp_string_array includes one element already.
+   */
+  alen = sizeof(SWIG_csharp_string_array) + sizeof(char *) * len;
+  ret = (SWIG_csharp_string_array *)malloc(alen);
+  if (ret == SWIG_NULLPTR) {
+    SWIG_CSharpSetPendingException(SWIG_CSharpOutOfMemoryException, "fail to duplicate array.");
+    return SWIG_NULLPTR;
+  }
+  memset(ret, 0, alen);
+  ret->len = len;
+  ptr = (char **)array;
+  for(i = 0; i < len; i++) {
+    slen = strlen(ptr[i]) + 1;
+    p = (char*)malloc(slen);
+    if (p == SWIG_NULLPTR) {
+      SWIG_CSharpSetPendingException(SWIG_CSharpOutOfMemoryException, "fail to alloc a string.");
+      return SWIG_csharp_string_array_free(ret);
+    }
+    memcpy(p, ptr[i], slen);
+    ret->array[i] = p;
+  }
+  ret->array[i] = SWIG_NULLPTR;
+  return ret;
+}
+
+#ifdef __cplusplus
+}
+#endif
+%}
+
+%typemap(in, canthrow=1, fragment="SWIG_csharp_string_array") (int ARGC, char **ARGV) %{
+  SWIG_csharp_string_array *arr = (SWIG_csharp_string_array*)$input;
+  if (arr != SWIG_NULLPTR) {
+    $1 = ($1_ltype)arr->len;
+    $2 = ($2_ltype)arr->array;
+  }
+%}
+
+%typemap(freearg, fragment="SWIG_csharp_string_array") (int ARGC, char **ARGV) %{
+  SWIG_csharp_string_array_free((SWIG_csharp_string_array*)$input);
+%}
diff --git a/Lib/csharp/arrays_csharp.i b/Lib/csharp/arrays_csharp.i
index 861da83..00ded71 100644
--- a/Lib/csharp/arrays_csharp.i
+++ b/Lib/csharp/arrays_csharp.i
@@ -49,8 +49,17 @@
  *   %csmethodmodifiers myArrayCopy "public unsafe";
  *   void myArrayCopy( int *sourceArray, int* targetArray, int nitems );
  *
+ * long type
+ * ---------
+ * Unlike other primitive types, the sizeof(long) varies considerably from one
+ * platform to another. The sizeof(long) in the unmanaged layer must match the
+ * number of bytes used in the managed layer. A check is implemented via the
+ * "long_check_wordsize" fragment which results in a compile time error upon an
+ * inconsistent match. Use the SWIGWORDSIZE64 macro to target 64-bit long.
+ * For easiest portability, avoid using long!
  * ----------------------------------------------------------------------------- */
 
+
 %define CSHARP_ARRAYS( CTYPE, CSTYPE )
 
 // input only arrays
@@ -94,16 +103,23 @@
 CSHARP_ARRAYS(unsigned short, ushort)
 CSHARP_ARRAYS(int, int)
 CSHARP_ARRAYS(unsigned int, uint)
-// FIXME - on Unix 64 bit, long is 8 bytes but is 4 bytes on Windows 64 bit.
-//         How can this be handled sensibly?
-//         See e.g. http://www.xml.com/ldd/chapter/book/ch10.html
-CSHARP_ARRAYS(long, int)
-CSHARP_ARRAYS(unsigned long, uint)
 CSHARP_ARRAYS(long long, long)
 CSHARP_ARRAYS(unsigned long long, ulong)
 CSHARP_ARRAYS(float, float)
 CSHARP_ARRAYS(double, double)
 
+// 32-bit/64-bit architecture specific typemaps - special handling to ensure sizeof(long) on C side matches size used on C# side
+#if !defined(SWIGWORDSIZE64)
+CSHARP_ARRAYS(long, int)
+CSHARP_ARRAYS(unsigned long, uint)
+#else
+CSHARP_ARRAYS(long, long)
+CSHARP_ARRAYS(unsigned long, ulong)
+#endif
+%typemap(in, fragment="long_check_wordsize") long INPUT[], unsigned long INPUT[] "$1 = $input;"
+%typemap(in, fragment="long_check_wordsize") long OUTPUT[], unsigned long OUTPUT[] "$1 = $input;"
+%typemap(in, fragment="long_check_wordsize") long INOUT[], unsigned long INOUT[] "$1 = $input;"
+
 // By default C# will marshal bools as 4 bytes
 // UnmanagedType.I1 will change this to 1 byte
 // FIXME - When running on mono ArraySubType appears to be ignored and bools will be marshalled as 4-byte
@@ -169,11 +185,18 @@
 CSHARP_ARRAYS_FIXED(unsigned short, ushort)
 CSHARP_ARRAYS_FIXED(int, int)
 CSHARP_ARRAYS_FIXED(unsigned int, uint)
-CSHARP_ARRAYS_FIXED(long, int)
-CSHARP_ARRAYS_FIXED(unsigned long, uint)
 CSHARP_ARRAYS_FIXED(long long, long)
 CSHARP_ARRAYS_FIXED(unsigned long long, ulong)
 CSHARP_ARRAYS_FIXED(float, float)
 CSHARP_ARRAYS_FIXED(double, double)
 CSHARP_ARRAYS_FIXED(bool, bool)
 
+// 32-bit/64-bit architecture specific typemaps - special handling to ensure sizeof(long) on C side matches size used on C# side
+#ifdef !SWIGWORDSIZE64
+CSHARP_ARRAYS_FIXED(long, int)
+CSHARP_ARRAYS_FIXED(unsigned long, uint)
+#else
+CSHARP_ARRAYS_FIXED(long, long)
+CSHARP_ARRAYS_FIXED(unsigned long, ulong)
+#endif
+%typemap(in, fragment="long_check_wordsize") long FIXED[], unsigned long FIXED[] "$1 = $input;"
diff --git a/Lib/csharp/boost_intrusive_ptr.i b/Lib/csharp/boost_intrusive_ptr.i
index fa3f53a..355a910 100644
--- a/Lib/csharp/boost_intrusive_ptr.i
+++ b/Lib/csharp/boost_intrusive_ptr.i
@@ -32,7 +32,7 @@
 %}
 %typemap(out, fragment="SWIG_intrusive_deleter") CONST TYPE %{
   //plain value(out)
-  $1_ltype* resultp = new $1_ltype(($1_ltype &)$1);
+  $1_ltype* resultp = new $1_ltype($1);
   intrusive_ptr_add_ref(resultp);
   *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(resultp, SWIG_intrusive_deleter< CONST TYPE >());
 %}
@@ -372,7 +372,7 @@
   }
   $1 = *argp; %}
 %typemap(out) CONST TYPE
-%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
+%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1)); %}
 
 // plain pointer
 %typemap(in) CONST TYPE * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
diff --git a/Lib/csharp/boost_shared_ptr.i b/Lib/csharp/boost_shared_ptr.i
index 508c0ec..d47fab5 100644
--- a/Lib/csharp/boost_shared_ptr.i
+++ b/Lib/csharp/boost_shared_ptr.i
@@ -29,10 +29,10 @@
   }
   $1 = *argp; %}
 %typemap(out) CONST TYPE
-%{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
+%{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1)); %}
 
 %typemap(directorin) CONST TYPE
-%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype((const $1_ltype &)$1)); %}
+%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype(SWIG_STD_MOVE($1))); %}
 
 %typemap(directorout) CONST TYPE
 %{ if (!$input) {
@@ -122,7 +122,7 @@
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * ($*1_ltype tempnull)
 %{ $1 = $input ? ($1_ltype)$input : &tempnull; %}
 %typemap(out, fragment="SWIG_null_deleter") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *
-%{ $result = ($1 && *$1) ? new $*1_ltype(*($1_ltype)$1) : 0;
+%{ $result = ($1 && *$1) ? new $*1_ltype(*$1) : 0;
    if ($owner) delete $1; %}
 
 %typemap(directorin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *
diff --git a/Lib/csharp/csharp.swg b/Lib/csharp/csharp.swg
index 8322063..fffde50 100644
--- a/Lib/csharp/csharp.swg
+++ b/Lib/csharp/csharp.swg
@@ -82,8 +82,8 @@
 %typemap(ctype) unsigned short,     const unsigned short &     "unsigned short"
 %typemap(ctype) int,                const int &                "int"
 %typemap(ctype) unsigned int,       const unsigned int &       "unsigned int"
-%typemap(ctype) long,               const long &               "long"
-%typemap(ctype) unsigned long,      const unsigned long &      "unsigned long"
+%typemap(ctype) long,               const long &               "int"
+%typemap(ctype) unsigned long,      const unsigned long &      "unsigned int"
 %typemap(ctype) long long,          const long long &          "long long"
 %typemap(ctype) unsigned long long, const unsigned long long & "unsigned long long"
 %typemap(ctype) float,              const float &              "float"
@@ -201,9 +201,9 @@
 %typemap(directorin) short              "$input = $1;"
 %typemap(directorin) unsigned short     "$input = $1;"
 %typemap(directorin) int                "$input = $1;"
-%typemap(directorin) unsigned int       "$input = $1;"
+%typemap(directorin) unsigned int       "$input = (unsigned int)$1;"
 %typemap(directorin) long               "$input = $1;"
-%typemap(directorin) unsigned long      "$input = (unsigned long)$1;"
+%typemap(directorin) unsigned long      "$input = $1;"
 %typemap(directorin) long long          "$input = $1;"
 %typemap(directorin) unsigned long long "$input = $1;"
 %typemap(directorin) float              "$input = $1;"
@@ -246,9 +246,9 @@
 %typemap(out) short              %{ $result = $1; %}
 %typemap(out) unsigned short     %{ $result = $1; %}
 %typemap(out) int                %{ $result = $1; %}
-%typemap(out) unsigned int       %{ $result = $1; %}
+%typemap(out) unsigned int       %{ $result = (unsigned int)$1; %}
 %typemap(out) long               %{ $result = $1; %}
-%typemap(out) unsigned long      %{ $result = (unsigned long)$1; %}
+%typemap(out) unsigned long      %{ $result = $1; %}
 %typemap(out) long long          %{ $result = $1; %}
 %typemap(out) unsigned long long %{ $result = $1; %}
 %typemap(out) float              %{ $result = $1; %}
@@ -327,7 +327,7 @@
 %typemap(directorin) const short &          "$input = $1;"
 %typemap(directorin) const unsigned short & "$input = $1;"
 %typemap(directorin) const int &            "$input = $1;"
-%typemap(directorin) const unsigned int &   "$input = $1;"
+%typemap(directorin) const unsigned int &   "$input = (unsigned int)$1;"
 %typemap(directorin) const long &           "$input = $1;"
 %typemap(directorin) const unsigned long &  "$input = $1;"
 %typemap(directorin) const long long &      "$input = $1;"
@@ -373,9 +373,9 @@
 %typemap(out) const short &              %{ $result = *$1; %}
 %typemap(out) const unsigned short &     %{ $result = *$1; %}
 %typemap(out) const int &                %{ $result = *$1; %}
-%typemap(out) const unsigned int &       %{ $result = *$1; %}
+%typemap(out) const unsigned int &       %{ $result = (unsigned int)*$1; %}
 %typemap(out) const long &               %{ $result = *$1; %}
-%typemap(out) const unsigned long &      %{ $result = (unsigned long)*$1; %}
+%typemap(out) const unsigned long &      %{ $result = *$1; %}
 %typemap(out) const long long &          %{ $result = *$1; %}
 %typemap(out) const unsigned long long & %{ $result = *$1; %}
 %typemap(out) const float &              %{ $result = *$1; %}
@@ -399,7 +399,7 @@
 
 %typemap(out) SWIGTYPE 
 #ifdef __cplusplus
-%{ $result = new $1_ltype((const $1_ltype &)$1); %}
+%{ $result = new $1_ltype($1); %}
 #else
 {
   $&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype));
@@ -409,7 +409,7 @@
 #endif
 
 %typemap(directorin) SWIGTYPE 
-%{ $input = (void *)new $1_ltype((const $1_ltype &)$1); %}
+%{ $input = (void *)new $1_ltype(SWIG_STD_MOVE($1)); %}
 %typemap(csdirectorin) SWIGTYPE "new $&csclassname($iminput, true)"
 %typemap(csdirectorout) SWIGTYPE "$&csclassname.getCPtr($cscall).Handle"
 
@@ -420,14 +420,15 @@
 %}
 %typemap(in, canthrow=1) SWIGTYPE & %{ $1 = ($1_ltype)$input;
   if (!$1) {
-    SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "$1_type type is null", 0);
+    SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "$1_type is null", 0);
     return $null;
   } %}
-%typemap(in, canthrow=1) SWIGTYPE && %{ $1 = ($1_ltype)$input;
+%typemap(in, canthrow=1, fragment="<memory>") SWIGTYPE && (std::unique_ptr<$*1_ltype> rvrdeleter) %{ $1 = ($1_ltype)$input;
   if (!$1) {
-    SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "$1_type type is null", 0);
+    SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "$1_type is null", 0);
     return $null;
-  } %}
+  }
+  rvrdeleter.reset($1); %}
 %typemap(out) SWIGTYPE * %{ $result = (void *)$1; %} 
 %typemap(out, fragment="SWIG_PackData") SWIGTYPE (CLASS::*) %{
   char buf[128];
@@ -578,7 +579,7 @@
                  unsigned long, 
                  unsigned short
 %{ char error_msg[256];
-   sprintf(error_msg, "C++ $1_type exception thrown, value: %d", $1);
+   SWIG_snprintf(error_msg, sizeof(error_msg), "C++ $1_type exception thrown, value: %d", $1);
    SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, error_msg);
    return $null; %}
 
@@ -613,7 +614,8 @@
     "$csinput"
 %typemap(csin) char *, char *&, char[ANY], char[] "$csinput"
 %typemap(csin) SWIGTYPE "$&csclassname.getCPtr($csinput)"
-%typemap(csin) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] "$csclassname.getCPtr($csinput)"
+%typemap(csin) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "$csclassname.getCPtr($csinput)"
+%typemap(csin) SWIGTYPE && "$csclassname.swigRelease($csinput)"
 %typemap(csin) SWIGTYPE (CLASS::*) "$csclassname.getCMemberPtr($csinput)"
 
 /* The csout typemap is used for converting function return types from the return type
@@ -875,6 +877,15 @@
     global::System.IntPtr ret = $imcall;$excode
     return ret;
   }
+%typemap(csvarin, excode=SWIGEXCODE2) void *VOID_INT_PTR %{
+    set {
+      $imcall;$excode
+    } %}
+%typemap(csvarout, excode=SWIGEXCODE2) void *VOID_INT_PTR %{
+    get {
+      global::System.IntPtr ret = $imcall;$excode
+      return ret;
+    } %}
 %typemap(csdirectorin) void *VOID_INT_PTR "$iminput"
 %typemap(csdirectorout) void *VOID_INT_PTR "$cscall"
 
@@ -885,6 +896,7 @@
 %typemap(csinterfaces)                SWIGTYPE "global::System.IDisposable"
 %typemap(csinterfaces)                          SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
 %typemap(csinterfaces_derived)        SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
+%typemap(csinterfacemodifiers)        SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "public interface"
 
 
 // csbody typemaps... these are in macros so that the visibility of the methods can be easily changed by users.
@@ -903,6 +915,19 @@
   CPTR_VISIBILITY static global::System.Runtime.InteropServices.HandleRef getCPtr($csclassname obj) {
     return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
   }
+
+  CPTR_VISIBILITY static global::System.Runtime.InteropServices.HandleRef swigRelease($csclassname obj) {
+    if (obj != null) {
+      if (!obj.swigCMemOwn)
+        throw new global::System.ApplicationException("Cannot release ownership as memory is not owned");
+      global::System.Runtime.InteropServices.HandleRef ptr = obj.swigCPtr;
+      obj.swigCMemOwn = false;
+      obj.Dispose();
+      return ptr;
+    } else {
+      return new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
+    }
+  }
 %}
 
 // Derived proxy classes
@@ -916,6 +941,19 @@
   CPTR_VISIBILITY static global::System.Runtime.InteropServices.HandleRef getCPtr($csclassname obj) {
     return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
   }
+
+  CPTR_VISIBILITY static global::System.Runtime.InteropServices.HandleRef swigRelease($csclassname obj) {
+    if (obj != null) {
+      if (!obj.swigCMemOwn)
+        throw new global::System.ApplicationException("Cannot release ownership as memory is not owned");
+      global::System.Runtime.InteropServices.HandleRef ptr = obj.swigCPtr;
+      obj.swigCMemOwn = false;
+      obj.Dispose();
+      return ptr;
+    } else {
+      return new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
+    }
+  }
 %}
 %enddef
 
@@ -935,6 +973,10 @@
   CPTR_VISIBILITY static global::System.Runtime.InteropServices.HandleRef getCPtr($csclassname obj) {
     return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
   }
+
+  CPTR_VISIBILITY static global::System.Runtime.InteropServices.HandleRef swigRelease($csclassname obj) {
+    return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
+  }
 %}
 
 %typemap(csbody) TYPE (CLASS::*) %{
@@ -1020,10 +1062,17 @@
 %pragma(csharp) imclassclassmodifiers="class"
 %pragma(csharp) moduleclassmodifiers="public class"
 
-/* Some ANSI C typemaps */
+/* 64-bit architecture specific typemaps */
+#if defined(SWIGWORDSIZE64)
+%apply long long { long };
+%apply unsigned long long { unsigned long };
+%apply const long long & { const long & };
+%apply const unsigned long long & { const unsigned long & };
+#endif
 
-%apply unsigned long { size_t };
-%apply const unsigned long & { const size_t & };
+/* size_t maps to C# 32-bit uint type */
+%apply unsigned int { size_t };
+%apply const unsigned int & { const size_t & };
 
 /* Array reference typemaps */
 %apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) }
diff --git a/Lib/csharp/csharphead.swg b/Lib/csharp/csharphead.swg
index 7db4c0e..56a019b 100644
--- a/Lib/csharp/csharphead.swg
+++ b/Lib/csharp/csharphead.swg
@@ -335,5 +335,5 @@
 %insert(runtime) %{
 /* Contract support */
 
-#define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentOutOfRangeException, msg, ""); return nullreturn; } else
+#define SWIG_contract_assert(nullreturn, expr, msg) do { if (!(expr)) {SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentOutOfRangeException, msg, ""); return nullreturn; } } while (0)
 %}
diff --git a/Lib/csharp/csharpkw.swg b/Lib/csharp/csharpkw.swg
index 824f618..1904fce 100644
--- a/Lib/csharp/csharpkw.swg
+++ b/Lib/csharp/csharpkw.swg
@@ -2,9 +2,9 @@
 #define CSHARP_CSHARPKW_SWG_
 
 /* Warnings for C# keywords */
-#define CSHARPKW(x) %keywordwarn("'" `x` "' is a C# keyword, renaming to '" `x` "_'",rename="%s_")  `x`
+#define CSHARPKW(x) %keywordwarn("'" `x` "' is a C# keyword",rename="%s_")  `x`
 
-#define CSHARPCLASSKW(x) %keywordwarn("'" `x` "' is a special method name used in the C# wrapper classes, class renamed to '" `x` "_'",%$isclass,rename="%s_") `x`
+#define CSHARPCLASSKW(x) %keywordwarn("'" `x` "' is a special method name used in the C# wrapper classes",%$isclass,rename="%s_") `x`
 
 /*
    from
diff --git a/Lib/csharp/std_array.i b/Lib/csharp/std_array.i
index a4f0f96..87b1b89 100644
--- a/Lib/csharp/std_array.i
+++ b/Lib/csharp/std_array.i
@@ -6,37 +6,37 @@
  * The C# wrapper is made to look and feel like a C# System.Collections.Generic.IReadOnlyList<> collection.
  * ----------------------------------------------------------------------------- */
 
-%{
-#include <algorithm>
-#include <array>
-#include <stdexcept>
-%}
-
 %include <std_common.i>
 
 
-%define SWIG_STD_ARRAY_INTERNAL(T, N)
-%typemap(csinterfaces) std::array< T, N > "global::System.IDisposable, global::System.Collections.IEnumerable\n    , global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)>\n";
+%define SWIG_STD_ARRAY_INTERNAL(CTYPE, N)
+%typemap(csinterfaces) std::array< CTYPE, N > "global::System.IDisposable, global::System.Collections.IEnumerable\n    , global::System.Collections.Generic.IEnumerable<$typemap(cstype, CTYPE)>\n"
 %proxycode %{
   public $csclassname(global::System.Collections.ICollection c) : this() {
     if (c == null)
       throw new global::System.ArgumentNullException("c");
-    int end = global::System.Math.Min(this.Count, c.Count);
+    int count = this.Count;
     int i = 0;
-    foreach ($typemap(cstype, T) elem in c) {
-      if (i >= end)
+    foreach ($typemap(cstype, CTYPE) element in c) {
+      if (i >= count)
         break;
-      this[i++] = elem;
+      this[i++] = element;
     }
   }
 
-  public int Count {
+  public bool IsFixedSize {
     get {
-      return (int)size();
+      return true;
     }
   }
 
-  public $typemap(cstype, T) this[int index]  {
+  public bool IsReadOnly {
+    get {
+      return false;
+    }
+  }
+
+  public $typemap(cstype, CTYPE) this[int index]  {
     get {
       return getitem(index);
     }
@@ -51,17 +51,29 @@
     }
   }
 
-  public void CopyTo($typemap(cstype, T)[] array)
+  public int Count {
+    get {
+      return (int)size();
+    }
+  }
+
+  public bool IsSynchronized {
+    get {
+      return false;
+    }
+  }
+
+  public void CopyTo($typemap(cstype, CTYPE)[] array)
   {
     CopyTo(0, array, 0, this.Count);
   }
 
-  public void CopyTo($typemap(cstype, T)[] array, int arrayIndex)
+  public void CopyTo($typemap(cstype, CTYPE)[] array, int arrayIndex)
   {
     CopyTo(0, array, arrayIndex, this.Count);
   }
 
-  public void CopyTo(int index, $typemap(cstype, T)[] array, int arrayIndex, int count)
+  public void CopyTo(int index, $typemap(cstype, CTYPE)[] array, int arrayIndex, int count)
   {
     if (array == null)
       throw new global::System.ArgumentNullException("array");
@@ -79,7 +91,13 @@
       array.SetValue(getitemcopy(index+i), arrayIndex+i);
   }
 
-  global::System.Collections.Generic.IEnumerator<$typemap(cstype, T)> global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)>.GetEnumerator() {
+  public $typemap(cstype, CTYPE)[] ToArray() {
+    $typemap(cstype, CTYPE)[] array = new $typemap(cstype, CTYPE)[this.Count];
+    this.CopyTo(array);
+    return array;
+  }
+
+  global::System.Collections.Generic.IEnumerator<$typemap(cstype, CTYPE)> global::System.Collections.Generic.IEnumerable<$typemap(cstype, CTYPE)>.GetEnumerator() {
     return new $csclassnameEnumerator(this);
   }
 
@@ -97,7 +115,7 @@
   /// collection but not when one of the elements of the collection is modified as it is a bit
   /// tricky to detect unmanaged code that modifies the collection under our feet.
   public sealed class $csclassnameEnumerator : global::System.Collections.IEnumerator
-    , global::System.Collections.Generic.IEnumerator<$typemap(cstype, T)>
+    , global::System.Collections.Generic.IEnumerator<$typemap(cstype, CTYPE)>
   {
     private $csclassname collectionRef;
     private int currentIndex;
@@ -112,7 +130,7 @@
     }
 
     // Type-safe iterator Current
-    public $typemap(cstype, T) Current {
+    public $typemap(cstype, CTYPE) Current {
       get {
         if (currentIndex == -1)
           throw new global::System.InvalidOperationException("Enumeration not started.");
@@ -120,7 +138,7 @@
           throw new global::System.InvalidOperationException("Enumeration finished.");
         if (currentObject == null)
           throw new global::System.InvalidOperationException("Collection modified.");
-        return ($typemap(cstype, T))currentObject;
+        return ($typemap(cstype, CTYPE))currentObject;
       }
     }
 
@@ -161,7 +179,7 @@
   public:
     typedef size_t size_type;
     typedef ptrdiff_t difference_type;
-    typedef T value_type;
+    typedef CTYPE value_type;
     typedef value_type* pointer;
     typedef const value_type* const_pointer;
     typedef value_type& reference;
@@ -180,7 +198,7 @@
     void swap(array& other);
 
     %extend {
-      T getitemcopy(int index) throw (std::out_of_range) {
+      CTYPE getitemcopy(int index) throw (std::out_of_range) {
         if (index>=0 && index<(int)$self->size())
           return (*$self)[index];
         else
@@ -213,6 +231,11 @@
     }
 %enddef
 
+%{
+#include <array>
+#include <algorithm>
+#include <stdexcept>
+%}
 
 %csmethodmodifiers std::array::empty "private"
 %csmethodmodifiers std::array::getitemcopy "private"
diff --git a/Lib/csharp/std_auto_ptr.i b/Lib/csharp/std_auto_ptr.i
index d7e5f16..da15df3 100644
--- a/Lib/csharp/std_auto_ptr.i
+++ b/Lib/csharp/std_auto_ptr.i
@@ -1,25 +1,38 @@
-/*
-    The typemaps here allow to handle functions returning std::auto_ptr<>,
-    which is the most common use of this type. If you have functions taking it
-    as parameter, these typemaps can't be used for them and you need to do
-    something else (e.g. use shared_ptr<> which SWIG supports fully).
- */
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
 
 %define %auto_ptr(TYPE)
-%typemap (ctype) std::auto_ptr<TYPE > "void *"
-%typemap (imtype, out="System.IntPtr") std::auto_ptr<TYPE > "HandleRef"
-%typemap (cstype) std::auto_ptr<TYPE > "$typemap(cstype, TYPE)"
-%typemap (out) std::auto_ptr<TYPE > %{
-   $result = (void *)$1.release();
+%typemap (ctype) std::auto_ptr< TYPE > "void *"
+%typemap (imtype, out="System.IntPtr") std::auto_ptr< TYPE > "global::System.Runtime.InteropServices.HandleRef"
+%typemap (cstype) std::auto_ptr< TYPE > "$typemap(cstype, TYPE)"
+
+%typemap(in) std::auto_ptr< TYPE >
+%{ $1.reset((TYPE *)$input); %}
+
+%typemap(csin) std::auto_ptr< TYPE > "$typemap(cstype, TYPE).swigRelease($csinput)"
+
+%typemap (out) std::auto_ptr< TYPE > %{
+  $result = (void *)$1.release();
 %}
-%typemap(csout, excode=SWIGEXCODE) std::auto_ptr<TYPE > {
-     System.IntPtr cPtr = $imcall;
-     $typemap(cstype, TYPE) ret = (cPtr == System.IntPtr.Zero) ? null : new $typemap(cstype, TYPE)(cPtr, true);$excode
-     return ret;
-   }
-%template() std::auto_ptr<TYPE >;
+
+%typemap(csout, excode=SWIGEXCODE) std::auto_ptr< TYPE > {
+    System.IntPtr cPtr = $imcall;
+    $typemap(cstype, TYPE) ret = (cPtr == System.IntPtr.Zero) ? null : new $typemap(cstype, TYPE)(cPtr, true);$excode
+    return ret;
+  }
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *") std::auto_ptr< TYPE > ""
+
+%template() std::auto_ptr< TYPE >;
 %enddef
 
 namespace std {
-   template <class T> class auto_ptr {};
-} 
+  template <class T> class auto_ptr {};
+}
diff --git a/Lib/csharp/std_list.i b/Lib/csharp/std_list.i
index 674aba0..cf6f202 100644
--- a/Lib/csharp/std_list.i
+++ b/Lib/csharp/std_list.i
@@ -19,7 +19,7 @@
 
 // MACRO for use within the std::list class body
 %define SWIG_STD_LIST_MINIMUM_INTERNAL(CSINTERFACE, CTYPE...)
-%typemap(csinterfaces) std::list< CTYPE > "global::System.IDisposable, global::System.Collections.IEnumerable, global::System.Collections.Generic.CSINTERFACE<$typemap(cstype, CTYPE)>\n";
+%typemap(csinterfaces) std::list< CTYPE > "global::System.IDisposable, global::System.Collections.IEnumerable, global::System.Collections.Generic.CSINTERFACE<$typemap(cstype, CTYPE)>\n"
 
 %apply void *VOID_INT_PTR { std::list< CTYPE >::iterator * };
 
diff --git a/Lib/csharp/std_map.i b/Lib/csharp/std_map.i
index e538a03..4f44742 100644
--- a/Lib/csharp/std_map.i
+++ b/Lib/csharp/std_map.i
@@ -26,7 +26,7 @@
 /* K is the C++ key type, T is the C++ value type */
 %define SWIG_STD_MAP_INTERNAL(K, T, C)
 
-%typemap(csinterfaces) std::map< K, T, C > "global::System.IDisposable \n    , global::System.Collections.Generic.IDictionary<$typemap(cstype, K), $typemap(cstype, T)>\n";
+%typemap(csinterfaces) std::map< K, T, C > "global::System.IDisposable \n    , global::System.Collections.Generic.IDictionary<$typemap(cstype, K), $typemap(cstype, T)>\n"
 %proxycode %{
 
   public $typemap(cstype, T) this[$typemap(cstype, K) key] {
@@ -48,6 +48,12 @@
     return false;
   }
 
+  public bool IsEmpty {
+    get {
+      return empty();
+    }
+  }
+
   public int Count {
     get {
       return (int)size();
@@ -236,7 +242,11 @@
       }
 
       void setitem(const key_type& key, const mapped_type& x) {
+%#ifdef __cpp_lib_map_try_emplace
+        (*$self).insert_or_assign(key, x);
+%#else
         (*$self)[key] = x;
+%#endif
       }
 
       bool ContainsKey(const key_type& key) {
@@ -269,12 +279,14 @@
       }
 
       const key_type& get_next_key(std::map< K, T, C >::iterator *swigiterator) {
+        (void)$self;
         std::map< K, T, C >::iterator iter = *swigiterator;
         (*swigiterator)++;
         return (*iter).first;
       }
 
       void destroy_iterator(std::map< K, T, C >::iterator *swigiterator) {
+        (void)$self;
         delete swigiterator;
       }
     }
@@ -282,6 +294,7 @@
 
 %enddef
 
+%csmethodmodifiers std::map::empty "private"
 %csmethodmodifiers std::map::size "private"
 %csmethodmodifiers std::map::getitem "private"
 %csmethodmodifiers std::map::setitem "private"
@@ -295,18 +308,3 @@
     SWIG_STD_MAP_INTERNAL(K, T, C)
   };
 }
-
-
-// Legacy macros (deprecated)
-%define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_key ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_value ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO)
-#warning "specialize_std_map_on_both ignored - macro is deprecated and no longer necessary"
-%enddef
-
diff --git a/Lib/csharp/std_set.i b/Lib/csharp/std_set.i
index 82f010a..480a24c 100644
--- a/Lib/csharp/std_set.i
+++ b/Lib/csharp/std_set.i
@@ -16,6 +16,7 @@
 #include <stdexcept>
 %}
 
+%csmethodmodifiers std::set::empty "private"
 %csmethodmodifiers std::set::size "private"
 %csmethodmodifiers std::set::getitem "private"
 %csmethodmodifiers std::set::create_iterator_begin "private"
@@ -28,7 +29,7 @@
 template <class T>
 class set {
 
-%typemap(csinterfaces) std::set<T> "global::System.IDisposable, global::System.Collections.Generic.ISet<$typemap(cstype, T)>\n";
+%typemap(csinterfaces) std::set<T> "global::System.IDisposable, global::System.Collections.Generic.ISet<$typemap(cstype, T)>\n"
 %proxycode %{
   void global::System.Collections.Generic.ICollection<$typemap(cstype, T)>.Add($typemap(cstype, T) item) {
       ((global::System.Collections.Generic.ISet<$typemap(cstype, T)>)this).Add(item);
@@ -44,6 +45,12 @@
     }
   }
 
+  public bool IsEmpty {
+    get {
+      return empty();
+    }
+  }
+
   public int Count {
     get {
       return (int)size();
@@ -297,12 +304,14 @@
       }
 
       const key_type& get_next(std::set<T>::iterator *swigiterator) {
+        (void)$self;
         std::set<T>::iterator iter = *swigiterator;
         (*swigiterator)++;
         return *iter;
       }
 
       void destroy_iterator(std::set<T>::iterator *swigiterator) {
+        (void)$self;
         delete swigiterator;
       }
     }
diff --git a/Lib/csharp/std_string.i b/Lib/csharp/std_string.i
index 5f8fa44..c8920c0 100644
--- a/Lib/csharp/std_string.i
+++ b/Lib/csharp/std_string.i
@@ -20,7 +20,7 @@
 class string;
 
 // string
-%typemap(ctype) string "char *"
+%typemap(ctype) string "const char *"
 %typemap(imtype) string "string"
 %typemap(cstype) string "string"
 
@@ -42,7 +42,7 @@
    }
    $result.assign($input); %}
 
-%typemap(directorin) string %{ $input = SWIG_csharp_string_callback($1.c_str()); %}
+%typemap(directorin) string %{ $input = $1.c_str(); %}
 
 %typemap(csin) string "$csinput"
 %typemap(csout, excode=SWIGEXCODE) string {
@@ -57,7 +57,7 @@
    return $null; %}
 
 // const string &
-%typemap(ctype) const string & "char *"
+%typemap(ctype) const string & "const char *"
 %typemap(imtype) const string & "string"
 %typemap(cstype) const string & "string"
 
@@ -89,7 +89,7 @@
    $1_str = $input;
    $result = &$1_str; %}
 
-%typemap(directorin) const string & %{ $input = SWIG_csharp_string_callback($1.c_str()); %}
+%typemap(directorin) const string & %{ $input = $1.c_str(); %}
 
 %typemap(csvarin, excode=SWIGEXCODE2) const string & %{
     set {
diff --git a/Lib/csharp/std_string_view.i b/Lib/csharp/std_string_view.i
new file mode 100644
index 0000000..3b6cd40
--- /dev/null
+++ b/Lib/csharp/std_string_view.i
@@ -0,0 +1,116 @@
+/* -----------------------------------------------------------------------------
+ * std_string_view.i
+ *
+ * Typemaps for std::string_view and const std::string_view&
+ * These are mapped to a C# String and are passed around by value.
+ *
+ * To use non-const std::string_view references use the following %apply.  Note
+ * that they are passed by value.
+ * %apply const std::string_view & {std::string_view &};
+ * ----------------------------------------------------------------------------- */
+
+%{
+#include <string_view>
+#include <string>
+%}
+
+namespace std {
+
+%naturalvar string_view;
+
+class string_view;
+
+// string_view
+%typemap(ctype) string_view "const char *"
+%typemap(imtype) string_view "string"
+%typemap(cstype) string_view "string"
+
+%typemap(csdirectorin) string_view "$iminput"
+%typemap(csdirectorout) string_view "$cscall"
+
+%typemap(in, canthrow=1) string_view
+%{ if (!$input) {
+    SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null string", 0);
+    return $null;
+   }
+   $1 = std::string_view($input); %}
+%typemap(out) string_view %{ $result = SWIG_csharp_string_callback(std::string($1).c_str()); %}
+
+%typemap(directorout, canthrow=1, warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) string_view
+%{ if (!$input) {
+    SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null string", 0);
+    return $null;
+   }
+   /* possible thread/reentrant code problem */
+   static std::string $1_str;
+   $1_str = $input;
+   $result = std::string_view($1_str); %}
+
+%typemap(directorin) string_view %{ $input = std::string($1).c_str(); %}
+
+%typemap(csin) string_view "$csinput"
+%typemap(csout, excode=SWIGEXCODE) string_view {
+    string ret = $imcall;$excode
+    return ret;
+  }
+
+%typemap(typecheck) string_view = char *;
+
+%typemap(throws, canthrow=1) string_view
+%{ SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, std::string($1).c_str());
+   return $null; %}
+
+// const string_view &
+%typemap(ctype) const string_view & "const char *"
+%typemap(imtype) const string_view & "string"
+%typemap(cstype) const string_view & "string"
+
+%typemap(csdirectorin) const string_view & "$iminput"
+%typemap(csdirectorout) const string_view & "$cscall"
+
+%typemap(in, canthrow=1) const string_view &
+%{ if (!$input) {
+    SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null string", 0);
+    return $null;
+   }
+   $*1_ltype $1_str($input);
+   $1 = &$1_str; %}
+%typemap(out) const string_view & %{ $result = SWIG_csharp_string_callback(std::string(*$1).c_str()); %}
+
+%typemap(csin) const string_view & "$csinput"
+%typemap(csout, excode=SWIGEXCODE) const string_view & {
+    string ret = $imcall;$excode
+    return ret;
+  }
+
+%typemap(directorout, canthrow=1, warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const string_view &
+%{ if (!$input) {
+    SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null string", 0);
+    return $null;
+   }
+   /* possible thread/reentrant code problem */
+   static std::string $1_str;
+   $1_str = $input;
+   static $*1_ltype $1_strview;
+   $1_strview = $1_str;
+   $result = &$1_strview; %}
+
+%typemap(directorin) const string_view & %{ $input = std::string($1).c_str(); %}
+
+%typemap(csvarin, excode=SWIGEXCODE2) const string_view & %{
+    set {
+      $imcall;$excode
+    } %}
+%typemap(csvarout, excode=SWIGEXCODE2) const string_view & %{
+    get {
+      string ret = $imcall;$excode
+      return ret;
+    } %}
+
+%typemap(typecheck) const string_view & = char *;
+
+%typemap(throws, canthrow=1) const string_view &
+%{ SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, std::string($1).c_str());
+   return $null; %}
+
+}
diff --git a/Lib/csharp/std_unique_ptr.i b/Lib/csharp/std_unique_ptr.i
new file mode 100644
index 0000000..0a4caaf
--- /dev/null
+++ b/Lib/csharp/std_unique_ptr.i
@@ -0,0 +1,38 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap (ctype) std::unique_ptr< TYPE > "void *"
+%typemap (imtype, out="System.IntPtr") std::unique_ptr< TYPE > "global::System.Runtime.InteropServices.HandleRef"
+%typemap (cstype) std::unique_ptr< TYPE > "$typemap(cstype, TYPE)"
+
+%typemap(in) std::unique_ptr< TYPE >
+%{ $1.reset((TYPE *)$input); %}
+
+%typemap(csin) std::unique_ptr< TYPE > "$typemap(cstype, TYPE).swigRelease($csinput)"
+
+%typemap (out) std::unique_ptr< TYPE > %{
+  $result = (void *)$1.release();
+%}
+
+%typemap(csout, excode=SWIGEXCODE) std::unique_ptr< TYPE > {
+    System.IntPtr cPtr = $imcall;
+    $typemap(cstype, TYPE) ret = (cPtr == System.IntPtr.Zero) ? null : new $typemap(cstype, TYPE)(cPtr, true);$excode
+    return ret;
+  }
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *") std::unique_ptr< TYPE > ""
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class unique_ptr {};
+}
diff --git a/Lib/csharp/std_unordered_map.i b/Lib/csharp/std_unordered_map.i
new file mode 100644
index 0000000..f8145e3
--- /dev/null
+++ b/Lib/csharp/std_unordered_map.i
@@ -0,0 +1,306 @@
+/* -----------------------------------------------------------------------------
+ * std_unordered_map.i
+ *
+ * SWIG typemaps for std::unordered_map< K, T, H >
+ *
+ * The C# wrapper is made to look and feel like a C# System.Collections.Generic.IDictionary<>.
+ *
+ * Using this wrapper is fairly simple. For example, to create an unordered_map from integers to doubles use:
+ *
+ *   %include <std_unordered_map.i>
+ *   %template(MapIntDouble) std::unordered_map<int, double>
+ *
+ * Notes:
+ * 1) IEnumerable<> is implemented in the proxy class which is useful for using LINQ with
+ *    C++ std::unordered_map wrappers.
+ *
+ * Warning: heavy macro usage in this file. Use swig -E to get a sane view on the real file contents!
+ * ----------------------------------------------------------------------------- */
+
+%{
+#include <unordered_map>
+#include <algorithm>
+#include <stdexcept>
+%}
+
+/* K is the C++ key type, T is the C++ value type */
+%define SWIG_STD_UNORDERED_MAP_INTERNAL(K, T, H)
+
+%typemap(csinterfaces) std::unordered_map< K, T, H > "global::System.IDisposable \n    , global::System.Collections.Generic.IDictionary<$typemap(cstype, K), $typemap(cstype, T)>\n"
+%proxycode %{
+
+  public $typemap(cstype, T) this[$typemap(cstype, K) key] {
+    get {
+      return getitem(key);
+    }
+
+    set {
+      setitem(key, value);
+    }
+  }
+
+  public bool TryGetValue($typemap(cstype, K) key, out $typemap(cstype, T) value) {
+    if (this.ContainsKey(key)) {
+      value = this[key];
+      return true;
+    }
+    value = default($typemap(cstype, T));
+    return false;
+  }
+
+  public bool IsEmpty {
+    get {
+      return empty();
+    }
+  }
+
+  public int Count {
+    get {
+      return (int)size();
+    }
+  }
+
+  public bool IsReadOnly {
+    get {
+      return false;
+    }
+  }
+
+  public global::System.Collections.Generic.ICollection<$typemap(cstype, K)> Keys {
+    get {
+      global::System.Collections.Generic.ICollection<$typemap(cstype, K)> keys = new global::System.Collections.Generic.List<$typemap(cstype, K)>();
+      int size = this.Count;
+      if (size > 0) {
+        global::System.IntPtr iter = create_iterator_begin();
+        for (int i = 0; i < size; i++) {
+          keys.Add(get_next_key(iter));
+        }
+        destroy_iterator(iter);
+      }
+      return keys;
+    }
+  }
+
+  public global::System.Collections.Generic.ICollection<$typemap(cstype, T)> Values {
+    get {
+      global::System.Collections.Generic.ICollection<$typemap(cstype, T)> vals = new global::System.Collections.Generic.List<$typemap(cstype, T)>();
+      foreach (global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> pair in this) {
+        vals.Add(pair.Value);
+      }
+      return vals;
+    }
+  }
+
+  public void Add(global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> item) {
+    Add(item.Key, item.Value);
+  }
+
+  public bool Remove(global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> item) {
+    if (Contains(item)) {
+      return Remove(item.Key);
+    } else {
+      return false;
+    }
+  }
+
+  public bool Contains(global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> item) {
+    if (this[item.Key] == item.Value) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  public void CopyTo(global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>[] array) {
+    CopyTo(array, 0);
+  }
+
+  public void CopyTo(global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>[] array, int arrayIndex) {
+    if (array == null)
+      throw new global::System.ArgumentNullException("array");
+    if (arrayIndex < 0)
+      throw new global::System.ArgumentOutOfRangeException("arrayIndex", "Value is less than zero");
+    if (array.Rank > 1)
+      throw new global::System.ArgumentException("Multi dimensional array.", "array");
+    if (arrayIndex+this.Count > array.Length)
+      throw new global::System.ArgumentException("Number of elements to copy is too large.");
+
+    global::System.Collections.Generic.IList<$typemap(cstype, K)> keyList = new global::System.Collections.Generic.List<$typemap(cstype, K)>(this.Keys);
+    for (int i = 0; i < keyList.Count; i++) {
+      $typemap(cstype, K) currentKey = keyList[i];
+      array.SetValue(new global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>(currentKey, this[currentKey]), arrayIndex+i);
+    }
+  }
+
+  global::System.Collections.Generic.IEnumerator<global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>> global::System.Collections.Generic.IEnumerable<global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>>.GetEnumerator() {
+    return new $csclassnameEnumerator(this);
+  }
+
+  global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() {
+    return new $csclassnameEnumerator(this);
+  }
+
+  public $csclassnameEnumerator GetEnumerator() {
+    return new $csclassnameEnumerator(this);
+  }
+
+  // Type-safe enumerator
+  /// Note that the IEnumerator documentation requires an InvalidOperationException to be thrown
+  /// whenever the collection is modified. This has been done for changes in the size of the
+  /// collection but not when one of the elements of the collection is modified as it is a bit
+  /// tricky to detect unmanaged code that modifies the collection under our feet.
+  public sealed class $csclassnameEnumerator : global::System.Collections.IEnumerator,
+      global::System.Collections.Generic.IEnumerator<global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>>
+  {
+    private $csclassname collectionRef;
+    private global::System.Collections.Generic.IList<$typemap(cstype, K)> keyCollection;
+    private int currentIndex;
+    private object currentObject;
+    private int currentSize;
+
+    public $csclassnameEnumerator($csclassname collection) {
+      collectionRef = collection;
+      keyCollection = new global::System.Collections.Generic.List<$typemap(cstype, K)>(collection.Keys);
+      currentIndex = -1;
+      currentObject = null;
+      currentSize = collectionRef.Count;
+    }
+
+    // Type-safe iterator Current
+    public global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)> Current {
+      get {
+        if (currentIndex == -1)
+          throw new global::System.InvalidOperationException("Enumeration not started.");
+        if (currentIndex > currentSize - 1)
+          throw new global::System.InvalidOperationException("Enumeration finished.");
+        if (currentObject == null)
+          throw new global::System.InvalidOperationException("Collection modified.");
+        return (global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>)currentObject;
+      }
+    }
+
+    // Type-unsafe IEnumerator.Current
+    object global::System.Collections.IEnumerator.Current {
+      get {
+        return Current;
+      }
+    }
+
+    public bool MoveNext() {
+      int size = collectionRef.Count;
+      bool moveOkay = (currentIndex+1 < size) && (size == currentSize);
+      if (moveOkay) {
+        currentIndex++;
+        $typemap(cstype, K) currentKey = keyCollection[currentIndex];
+        currentObject = new global::System.Collections.Generic.KeyValuePair<$typemap(cstype, K), $typemap(cstype, T)>(currentKey, collectionRef[currentKey]);
+      } else {
+        currentObject = null;
+      }
+      return moveOkay;
+    }
+
+    public void Reset() {
+      currentIndex = -1;
+      currentObject = null;
+      if (collectionRef.Count != currentSize) {
+        throw new global::System.InvalidOperationException("Collection modified.");
+      }
+    }
+
+    public void Dispose() {
+      currentIndex = -1;
+      currentObject = null;
+    }
+  }
+
+%}
+
+  public:
+    typedef size_t size_type;
+    typedef ptrdiff_t difference_type;
+    typedef K key_type;
+    typedef T mapped_type;
+    typedef std::pair< const K, T > value_type;
+    typedef value_type* pointer;
+    typedef const value_type* const_pointer;
+    typedef value_type& reference;
+    typedef const value_type& const_reference;
+
+    unordered_map();
+    unordered_map(const unordered_map& other);
+    size_type size() const;
+    bool empty() const;
+    %rename(Clear) clear;
+    void clear();
+    %extend {
+      const mapped_type& getitem(const key_type& key) throw (std::out_of_range) {
+        std::unordered_map< K, T, H >::iterator iter = $self->find(key);
+        if (iter != $self->end())
+          return iter->second;
+        else
+          throw std::out_of_range("key not found");
+      }
+
+      void setitem(const key_type& key, const mapped_type& x) {
+        (*$self)[key] = x;
+      }
+
+      bool ContainsKey(const key_type& key) {
+        std::unordered_map< K, T, H >::iterator iter = $self->find(key);
+        return iter != $self->end();
+      }
+
+      void Add(const key_type& key, const mapped_type& value) throw (std::out_of_range) {
+        std::unordered_map< K, T, H >::iterator iter = $self->find(key);
+        if (iter != $self->end())
+          throw std::out_of_range("key already exists");
+        $self->insert(std::pair< K, T >(key, value));
+      }
+
+      bool Remove(const key_type& key) {
+        std::unordered_map< K, T, H >::iterator iter = $self->find(key);
+        if (iter != $self->end()) {
+          $self->erase(iter);
+          return true;
+        }
+        return false;
+      }
+
+      // create_iterator_begin(), get_next_key() and destroy_iterator work together to provide a collection of keys to C#
+      %apply void *VOID_INT_PTR { std::unordered_map< K, T, H >::iterator *create_iterator_begin }
+      %apply void *VOID_INT_PTR { std::unordered_map< K, T, H >::iterator *swigiterator }
+
+      std::unordered_map< K, T, H >::iterator *create_iterator_begin() {
+        return new std::unordered_map< K, T, H >::iterator($self->begin());
+      }
+
+      const key_type& get_next_key(std::unordered_map< K, T, H >::iterator *swigiterator) {
+        (void)self;
+        std::unordered_map< K, T, H >::iterator iter = *swigiterator;
+        (*swigiterator)++;
+        return (*iter).first;
+      }
+
+      void destroy_iterator(std::unordered_map< K, T, H >::iterator *swigiterator) {
+        (void)self;
+        delete swigiterator;
+      }
+    }
+
+
+%enddef
+
+%csmethodmodifiers std::unordered_map::empty "private"
+%csmethodmodifiers std::unordered_map::size "private"
+%csmethodmodifiers std::unordered_map::getitem "private"
+%csmethodmodifiers std::unordered_map::setitem "private"
+%csmethodmodifiers std::unordered_map::create_iterator_begin "private"
+%csmethodmodifiers std::unordered_map::get_next_key "private"
+%csmethodmodifiers std::unordered_map::destroy_iterator "private"
+
+// Default implementation
+namespace std {
+  template<class K, class T, class H = std::hash<K> > class unordered_map {
+    SWIG_STD_UNORDERED_MAP_INTERNAL(K, T, H)
+  };
+}
diff --git a/Lib/csharp/std_unordered_set.i b/Lib/csharp/std_unordered_set.i
new file mode 100644
index 0000000..d6f6a18
--- /dev/null
+++ b/Lib/csharp/std_unordered_set.i
@@ -0,0 +1,320 @@
+/* -----------------------------------------------------------------------------
+ * std_unordered_set.i
+ *
+ * SWIG typemaps for std::unordered_set<T>.
+ *
+ * Note that ISet<> used here requires .NET 4 or later.
+ *
+ * The C# wrapper implements ISet<> interface and is similar in
+ * characteristics to the C# System.Collections.Generic.HashSet<> class, but
+ * doesn't provide quite all of its methods.
+ * ----------------------------------------------------------------------------- */
+
+%{
+#include <unordered_set>
+#include <algorithm>
+#include <stdexcept>
+%}
+
+%csmethodmodifiers std::unordered_set::empty "private"
+%csmethodmodifiers std::unordered_set::size "private"
+%csmethodmodifiers std::unordered_set::getitem "private"
+%csmethodmodifiers std::unordered_set::create_iterator_begin "private"
+%csmethodmodifiers std::unordered_set::get_next "private"
+%csmethodmodifiers std::unordered_set::destroy_iterator "private"
+
+namespace std {
+
+// TODO: Add support for comparator and allocator template parameters.
+template <class T>
+class unordered_set {
+
+%typemap(csinterfaces) std::unordered_set<T> "global::System.IDisposable, global::System.Collections.Generic.ISet<$typemap(cstype, T)>\n"
+%proxycode %{
+  void global::System.Collections.Generic.ICollection<$typemap(cstype, T)>.Add($typemap(cstype, T) item) {
+      ((global::System.Collections.Generic.ISet<$typemap(cstype, T)>)this).Add(item);
+  }
+
+  public bool TryGetValue($typemap(cstype, T) equalValue, out $typemap(cstype, T) actualValue) {
+    try {
+      actualValue = getitem(equalValue);
+      return true;
+    } catch {
+      actualValue = default($typemap(cstype, T));
+      return false;
+    }
+  }
+
+  public bool IsEmpty {
+    get {
+      return empty();
+    }
+  }
+
+  public int Count {
+    get {
+      return (int)size();
+    }
+  }
+
+  public bool IsReadOnly {
+    get {
+      return false;
+    }
+  }
+
+  public void CopyTo($typemap(cstype, T)[] array) {
+    CopyTo(array, 0);
+  }
+
+  public void CopyTo($typemap(cstype, T)[] array, int arrayIndex) {
+    if (array == null)
+      throw new global::System.ArgumentNullException("array");
+    if (arrayIndex < 0)
+      throw new global::System.ArgumentOutOfRangeException("arrayIndex", "Value is less than zero");
+    if (array.Rank > 1)
+      throw new global::System.ArgumentException("Multi dimensional array.", "array");
+    if (arrayIndex+this.Count > array.Length)
+      throw new global::System.ArgumentException("Number of elements to copy is too large.");
+
+    foreach ($typemap(cstype, T) item in this) {
+      array.SetValue(item, arrayIndex++);
+    }
+  }
+
+  public void ExceptWith(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+    foreach ($typemap(cstype, T) item in other) {
+      Remove(item);
+    }
+  }
+
+  public void IntersectWith(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+    $csclassname old = new $csclassname(this);
+
+    Clear();
+    foreach ($typemap(cstype, T) item in other) {
+      if (old.Contains(item))
+        Add(item);
+    }
+  }
+
+  private static int count_enum(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+    int count = 0;
+    foreach ($typemap(cstype, T) item in other) {
+      count++;
+    }
+
+    return count;
+  }
+
+  public bool IsProperSubsetOf(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+    return IsSubsetOf(other) && Count < count_enum(other);
+  }
+
+  public bool IsProperSupersetOf(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+    return IsSupersetOf(other) && Count > count_enum(other);
+  }
+
+  public bool IsSubsetOf(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+    int countContained = 0;
+
+    foreach ($typemap(cstype, T) item in other) {
+      if (Contains(item))
+        countContained++;
+    }
+
+    return countContained == Count;
+  }
+
+  public bool IsSupersetOf(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+    foreach ($typemap(cstype, T) item in other) {
+      if (!Contains(item))
+        return false;
+    }
+
+    return true;
+  }
+
+  public bool Overlaps(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+    foreach ($typemap(cstype, T) item in other) {
+      if (Contains(item))
+        return true;
+    }
+
+    return false;
+  }
+
+  public bool SetEquals(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+    return IsSupersetOf(other) && Count == count_enum(other);
+  }
+
+  public void SymmetricExceptWith(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+    foreach ($typemap(cstype, T) item in other) {
+      if (!Remove(item))
+        Add(item);
+    }
+  }
+
+  public void UnionWith(global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)> other) {
+    foreach ($typemap(cstype, T) item in other) {
+      Add(item);
+    }
+  }
+
+  private global::System.Collections.Generic.ICollection<$typemap(cstype, T)> Items {
+    get {
+      global::System.Collections.Generic.ICollection<$typemap(cstype, T)> items = new global::System.Collections.Generic.List<$typemap(cstype, T)>();
+      int size = this.Count;
+      if (size > 0) {
+        global::System.IntPtr iter = create_iterator_begin();
+        for (int i = 0; i < size; i++) {
+          items.Add(get_next(iter));
+        }
+        destroy_iterator(iter);
+      }
+      return items;
+    }
+  }
+
+  global::System.Collections.Generic.IEnumerator<$typemap(cstype, T)> global::System.Collections.Generic.IEnumerable<$typemap(cstype, T)>.GetEnumerator() {
+    return new $csclassnameEnumerator(this);
+  }
+
+  global::System.Collections.IEnumerator global::System.Collections.IEnumerable.GetEnumerator() {
+    return new $csclassnameEnumerator(this);
+  }
+
+  public $csclassnameEnumerator GetEnumerator() {
+    return new $csclassnameEnumerator(this);
+  }
+
+  // Type-safe enumerator
+  /// Note that the IEnumerator documentation requires an InvalidOperationException to be thrown
+  /// whenever the collection is modified. This has been done for changes in the size of the
+  /// collection but not when one of the elements of the collection is modified as it is a bit
+  /// tricky to detect unmanaged code that modifies the collection under our feet.
+  public sealed class $csclassnameEnumerator : global::System.Collections.IEnumerator,
+      global::System.Collections.Generic.IEnumerator<$typemap(cstype, T)>
+  {
+    private $csclassname collectionRef;
+    private global::System.Collections.Generic.IList<$typemap(cstype, T)> ItemsCollection;
+    private int currentIndex;
+    private object currentObject;
+    private int currentSize;
+
+    public $csclassnameEnumerator($csclassname collection) {
+      collectionRef = collection;
+      ItemsCollection = new global::System.Collections.Generic.List<$typemap(cstype, T)>(collection.Items);
+      currentIndex = -1;
+      currentObject = null;
+      currentSize = collectionRef.Count;
+    }
+
+    // Type-safe iterator Current
+    public $typemap(cstype, T) Current {
+      get {
+        if (currentIndex == -1)
+          throw new global::System.InvalidOperationException("Enumeration not started.");
+        if (currentIndex > currentSize - 1)
+          throw new global::System.InvalidOperationException("Enumeration finished.");
+        if (currentObject == null)
+          throw new global::System.InvalidOperationException("Collection modified.");
+        return ($typemap(cstype, T))currentObject;
+      }
+    }
+
+    // Type-unsafe IEnumerator.Current
+    object global::System.Collections.IEnumerator.Current {
+      get {
+        return Current;
+      }
+    }
+
+    public bool MoveNext() {
+      int size = collectionRef.Count;
+      bool moveOkay = (currentIndex+1 < size) && (size == currentSize);
+      if (moveOkay) {
+        currentIndex++;
+        currentObject = ItemsCollection[currentIndex];
+      } else {
+        currentObject = null;
+      }
+      return moveOkay;
+    }
+
+    public void Reset() {
+      currentIndex = -1;
+      currentObject = null;
+      if (collectionRef.Count != currentSize) {
+        throw new global::System.InvalidOperationException("Collection modified.");
+      }
+    }
+
+    public void Dispose() {
+      currentIndex = -1;
+      currentObject = null;
+    }
+  }
+
+%}
+
+  public:
+    typedef size_t size_type;
+    typedef ptrdiff_t difference_type;
+    typedef T key_type;
+    typedef T value_type;
+    typedef value_type* pointer;
+    typedef const value_type* const_pointer;
+    typedef value_type& reference;
+    typedef const value_type& const_reference;
+
+    unordered_set();
+    unordered_set(const unordered_set& other);
+    size_type size() const;
+    bool empty() const;
+    %rename(Clear) clear;
+    void clear();
+    %extend {
+      bool Add(const value_type& item) {
+        return $self->insert(item).second;
+      }
+
+      bool Contains(const value_type& item) {
+        return $self->count(item) != 0;
+      }
+
+      bool Remove(const value_type& item) {
+        return $self->erase(item) != 0;
+      }
+
+      const value_type& getitem(const value_type& item) throw (std::out_of_range) {
+        std::unordered_set<T>::iterator iter = $self->find(item);
+        if (iter == $self->end())
+          throw std::out_of_range("item not found");
+
+        return *iter;
+      }
+
+      // create_iterator_begin(), get_next() and destroy_iterator work together to provide a collection of items to C#
+      %apply void *VOID_INT_PTR { std::unordered_set<T>::iterator *create_iterator_begin }
+      %apply void *VOID_INT_PTR { std::unordered_set<T>::iterator *swigiterator }
+
+      std::unordered_set<T>::iterator *create_iterator_begin() {
+        return new std::unordered_set<T>::iterator($self->begin());
+      }
+
+      const key_type& get_next(std::unordered_set<T>::iterator *swigiterator) {
+        (void)$self;
+        std::unordered_set<T>::iterator iter = *swigiterator;
+        (*swigiterator)++;
+        return *iter;
+      }
+
+      void destroy_iterator(std::unordered_set<T>::iterator *swigiterator) {
+        (void)$self;
+        delete swigiterator;
+      }
+    }
+};
+
+}
diff --git a/Lib/csharp/std_vector.i b/Lib/csharp/std_vector.i
index e281129..982306e 100644
--- a/Lib/csharp/std_vector.i
+++ b/Lib/csharp/std_vector.i
@@ -19,7 +19,7 @@
 
 // MACRO for use within the std::vector class body
 %define SWIG_STD_VECTOR_MINIMUM_INTERNAL(CSINTERFACE, CONST_REFERENCE, CTYPE...)
-%typemap(csinterfaces) std::vector< CTYPE > "global::System.IDisposable, global::System.Collections.IEnumerable, global::System.Collections.Generic.CSINTERFACE<$typemap(cstype, CTYPE)>\n";
+%typemap(csinterfaces) std::vector< CTYPE > "global::System.IDisposable, global::System.Collections.IEnumerable, global::System.Collections.Generic.CSINTERFACE<$typemap(cstype, CTYPE)>\n"
 %proxycode %{
   public $csclassname(global::System.Collections.IEnumerable c) : this() {
     if (c == null)
@@ -63,12 +63,18 @@
       return (int)capacity();
     }
     set {
-      if (value < size())
+      if (value < 0 || ($typemap(cstype, size_t))value < size())
         throw new global::System.ArgumentOutOfRangeException("Capacity");
       reserve(($typemap(cstype, size_t))value);
     }
   }
 
+  public bool IsEmpty {
+    get {
+      return empty();
+    }
+  }
+
   public int Count {
     get {
       return (int)size();
@@ -203,19 +209,20 @@
     typedef value_type& reference;
     typedef CONST_REFERENCE const_reference;
 
+    vector();
+    vector(const vector &other);
+
     %rename(Clear) clear;
     void clear();
     %rename(Add) push_back;
     void push_back(CTYPE const& x);
     size_type size() const;
+    bool empty() const;
     size_type capacity() const;
     void reserve(size_type n);
     %newobject GetRange(int index, int count);
     %newobject Repeat(CTYPE const& value, int count);
 
-    vector();
-    vector(const vector &other);
-
     %extend {
       vector(int capacity) throw (std::out_of_range) {
         std::vector< CTYPE >* pv = 0;
@@ -357,22 +364,13 @@
 }
 %enddef
 
-// Legacy macros
-%define SWIG_STD_VECTOR_SPECIALIZE(CSTYPE, CTYPE...)
-#warning SWIG_STD_VECTOR_SPECIALIZE macro deprecated, please see csharp/std_vector.i and switch to SWIG_STD_VECTOR_ENHANCED
-SWIG_STD_VECTOR_ENHANCED(CTYPE)
-%enddef
-
-%define SWIG_STD_VECTOR_SPECIALIZE_MINIMUM(CSTYPE, CTYPE...)
-#warning SWIG_STD_VECTOR_SPECIALIZE_MINIMUM macro deprecated, it is no longer required
-%enddef
-
 %{
 #include <vector>
 #include <algorithm>
 #include <stdexcept>
 %}
 
+%csmethodmodifiers std::vector::empty "private"
 %csmethodmodifiers std::vector::getitemcopy "private"
 %csmethodmodifiers std::vector::getitem "private"
 %csmethodmodifiers std::vector::setitem "private"
@@ -415,4 +413,3 @@
 SWIG_STD_VECTOR_ENHANCED(double)
 SWIG_STD_VECTOR_ENHANCED(std::string) // also requires a %include <std_string.i>
 SWIG_STD_VECTOR_ENHANCED(std::wstring) // also requires a %include <std_wstring.i>
-
diff --git a/Lib/csharp/std_wstring.i b/Lib/csharp/std_wstring.i
index 162b90e..c7fef41 100644
--- a/Lib/csharp/std_wstring.i
+++ b/Lib/csharp/std_wstring.i
@@ -2,7 +2,9 @@
  * std_wstring.i
  *
  * Typemaps for std::wstring and const std::wstring&
- * These are mapped to a C# String and are passed around by value.
+ * std::wstring is mapped to a C# Unicode string (UTF16) and is passed around by value.
+ * std::wstring support includes wchar_t as a 2 byte type (Windows) and a 4 byte type
+ * (most Unix systems).
  *
  * To use non-const std::wstring references use the following %apply.  Note 
  * that they are passed by value.
@@ -15,6 +17,28 @@
 #include <string>
 %}
 
+%fragment("Swig_csharp_UTF16ToWString", "header") %{
+/* For converting from .NET UTF16 (2 byte unicode) strings. wchar_t is 2 bytes on Windows, 4 bytes on Linux. */
+static std::wstring Swig_csharp_UTF16ToWString(const unsigned short *str) {
+  if (sizeof(wchar_t) == 2) {
+    return std::wstring((wchar_t *)str);
+  } else {
+    const unsigned short *pBegin(str);
+    const unsigned short *ptr(pBegin);
+
+    while (*ptr != 0)
+      ++ptr;
+
+    std::wstring result;
+    result.reserve(ptr - pBegin);
+    while(pBegin != ptr)
+      result.push_back(*pBegin++);
+
+    return result;
+  }
+}
+%}
+
 namespace std {
 
 %naturalvar wstring;
@@ -22,31 +46,33 @@
 class wstring;
 
 // wstring
-%typemap(ctype, out="void *") wstring "wchar_t *"
+%typemap(ctype, out="void *") wstring "unsigned short *"
 %typemap(imtype,
          inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
-         outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
+         outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+         directorinattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+         directoroutattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
          ) wstring "string"
 %typemap(cstype) wstring "string"
 %typemap(csdirectorin) wstring "$iminput"
 %typemap(csdirectorout) wstring "$cscall"
 
-%typemap(in, canthrow=1) wstring 
+%typemap(in, canthrow=1, fragment="Swig_csharp_UTF16ToWString") wstring
 %{ if (!$input) {
     SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null wstring", 0);
     return $null;
    }
-   $1.assign($input); %}
-%typemap(out) wstring %{ $result = SWIG_csharp_wstring_callback($1.c_str()); %}
+   $1 = Swig_csharp_UTF16ToWString($input); %}
+%typemap(out) wstring %{ $result = SWIG_csharp_wstring_with_length_callback($1.data(), (int)$1.size()); %}
 
-%typemap(directorout, canthrow=1) wstring 
+%typemap(directorout, canthrow=1) wstring
 %{ if (!$input) {
     SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null wstring", 0);
     return $null;
    }
-   $result.assign($input); %}
+   $result = Swig_csharp_UTF16ToWString($input); %}
 
-%typemap(directorin) wstring %{ $input = SWIG_csharp_wstring_callback($1.c_str()); %}
+%typemap(directorin) wstring %{ $input = SWIG_csharp_wstring_with_length_callback($1.data(), (int)$1.size()); %}
 
 %typemap(csin) wstring "$csinput"
 %typemap(csout, excode=SWIGEXCODE) wstring {
@@ -57,29 +83,30 @@
 %typemap(typecheck) wstring = wchar_t *;
 
 %typemap(throws, canthrow=1) wstring
-%{ std::string message($1.begin(), $1.end());
-   SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, message.c_str());
+%{ SWIG_csharp_ApplicationException_callback($1.data(), (int)$1.size());
    return $null; %}
 
 // const wstring &
-%typemap(ctype, out="void *") const wstring & "wchar_t *"
+%typemap(ctype, out="void *") const wstring & "unsigned short *"
 %typemap(imtype,
          inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
-         outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
+         outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+         directorinattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+         directoroutattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
          ) const wstring & "string"
 %typemap(cstype) const wstring & "string"
 
 %typemap(csdirectorin) const wstring & "$iminput"
 %typemap(csdirectorout) const wstring & "$cscall"
 
-%typemap(in, canthrow=1) const wstring &
+%typemap(in, canthrow=1, fragment="Swig_csharp_UTF16ToWString") const wstring &
 %{ if (!$input) {
     SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "null wstring", 0);
     return $null;
    }
-   std::wstring $1_str($input);
+   std::wstring $1_str(Swig_csharp_UTF16ToWString($input));
    $1 = &$1_str; %}
-%typemap(out) const wstring & %{ $result = SWIG_csharp_wstring_callback($1->c_str()); %}
+%typemap(out) const wstring & %{ $result = SWIG_csharp_wstring_with_length_callback($1->data(), (int)$1->size()); %}
 
 %typemap(csin) const wstring & "$csinput"
 %typemap(csout, excode=SWIGEXCODE) const wstring & {
@@ -94,10 +121,10 @@
    }
    /* possible thread/reentrant code problem */
    static std::wstring $1_str;
-   $1_str = $input;
+   $1_str = Swig_csharp_UTF16ToWString($input);
    $result = &$1_str; %}
 
-%typemap(directorin) const wstring & %{ $input = SWIG_csharp_wstring_callback($1.c_str()); %}
+%typemap(directorin) const wstring & %{ $input = SWIG_csharp_wstring_with_length_callback($1.data(), (int)$1.size()); %}
 
 %typemap(csvarin, excode=SWIGEXCODE2) const wstring & %{
     set {
@@ -112,8 +139,7 @@
 %typemap(typecheck) const wstring & = wchar_t *;
 
 %typemap(throws, canthrow=1) const wstring &
-%{ std::string message($1.begin(), $1.end());
-   SWIG_CSharpSetPendingException(SWIG_CSharpApplicationException, message.c_str());
+%{ SWIG_csharp_ApplicationException_callback($1.data(), (int)$1.size());
    return $null; %}
 
 }
diff --git a/Lib/csharp/swigmove.i b/Lib/csharp/swigmove.i
new file mode 100644
index 0000000..2f21bd6
--- /dev/null
+++ b/Lib/csharp/swigmove.i
@@ -0,0 +1,16 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in, canthrow=1, fragment="<memory>") SWIGTYPE MOVE ($&1_type argp)
+%{ argp = ($&1_ltype)$input;
+   if (!argp) {
+     SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null $1_type", 0);
+     return $null;
+   }
+   SwigValueWrapper< $1_ltype >::reset($1, argp); %}
+
+%typemap(csin) SWIGTYPE MOVE "$&csclassname.swigRelease($csinput)"
diff --git a/Lib/csharp/typemaps.i b/Lib/csharp/typemaps.i
index b6f9bdd..80a5cb5 100644
--- a/Lib/csharp/typemaps.i
+++ b/Lib/csharp/typemaps.i
@@ -74,15 +74,11 @@
 INPUT_TYPEMAP(unsigned short,     unsigned short,       ushort)
 INPUT_TYPEMAP(int,                int,                  int)
 INPUT_TYPEMAP(unsigned int,       unsigned int,         uint)
-INPUT_TYPEMAP(long,               long,                 int)
-INPUT_TYPEMAP(unsigned long,      unsigned long,        uint)
 INPUT_TYPEMAP(long long,          long long,            long)
 INPUT_TYPEMAP(unsigned long long, unsigned long long,   ulong)
 INPUT_TYPEMAP(float,              float,                float)
 INPUT_TYPEMAP(double,             double,               double)
 
-#undef INPUT_TYPEMAP
-
 /*
 OUTPUT typemaps
 ---------------
@@ -153,15 +149,11 @@
 OUTPUT_TYPEMAP(unsigned short,     unsigned short,       ushort,   UINT16_PTR)
 OUTPUT_TYPEMAP(int,                int,                  int,      INT32_PTR)
 OUTPUT_TYPEMAP(unsigned int,       unsigned int,         uint,     UINT32_PTR)
-OUTPUT_TYPEMAP(long,               long,                 int,      INT32_PTR)
-OUTPUT_TYPEMAP(unsigned long,      unsigned long,        uint,     UINT32_PTR)
 OUTPUT_TYPEMAP(long long,          long long,            long,     INT64_PTR)
 OUTPUT_TYPEMAP(unsigned long long, unsigned long long,   ulong,    UINT64_PTR)
 OUTPUT_TYPEMAP(float,              float,                float,    FLOAT_PTR)
 OUTPUT_TYPEMAP(double,             double,               double,   DOUBLE_PTR)
 
-#undef OUTPUT_TYPEMAP
-
 %typemap(in) bool *OUTPUT, bool &OUTPUT
 %{ *$input = 0; 
    $1 = ($1_ltype)$input; %}
@@ -242,12 +234,47 @@
 INOUT_TYPEMAP(unsigned short,     unsigned short,       ushort,   UINT16_PTR)
 INOUT_TYPEMAP(int,                int,                  int,      INT32_PTR)
 INOUT_TYPEMAP(unsigned int,       unsigned int,         uint,     UINT32_PTR)
-INOUT_TYPEMAP(long,               long,                 int,      INT32_PTR)
-INOUT_TYPEMAP(unsigned long,      unsigned long,        uint,     UINT32_PTR)
 INOUT_TYPEMAP(long long,          long long,            long,     INT64_PTR)
 INOUT_TYPEMAP(unsigned long long, unsigned long long,   ulong,    UINT64_PTR)
 INOUT_TYPEMAP(float,              float,                float,    FLOAT_PTR)
 INOUT_TYPEMAP(double,             double,               double,   DOUBLE_PTR)
 
-#undef INOUT_TYPEMAP
 
+// 32-bit/64-bit architecture specific typemaps - marshal as 32-bit by default
+#if !defined(SWIGWORDSIZE64)
+INPUT_TYPEMAP(long,               int,                 int)
+INPUT_TYPEMAP(unsigned long,      unsigned int,        uint)
+
+OUTPUT_TYPEMAP(long,              int,                 int,       INT32_PTR)
+OUTPUT_TYPEMAP(unsigned long,     unsigned int,        uint,      UINT32_PTR)
+
+INOUT_TYPEMAP(long,               int,                 int,       INT32_PTR)
+INOUT_TYPEMAP(unsigned long,      unsigned int,        uint,      UINT32_PTR)
+#else
+INPUT_TYPEMAP(long,               long long,           int)
+INPUT_TYPEMAP(unsigned long,      unsigned long long,  uint)
+
+OUTPUT_TYPEMAP(long,              long long,           int,       INT64_PTR)
+OUTPUT_TYPEMAP(unsigned long,     unsigned long long,  uint,      UINT64_PTR)
+
+INOUT_TYPEMAP(long,               long long,           int,       INT64_PTR)
+INOUT_TYPEMAP(unsigned long,      unsigned long long,  uint,      UINT64_PTR)
+#endif
+%typemap(in) long INPUT[] ($*1_ltype tempinput), unsigned long INPUT[] ($*1_ltype tempinput)
+%{tempinput = ($*1_ltype)*$input;
+  $1 = &tempinput;%}
+
+%typemap(in) long OUTPUT[] ($*1_ltype tempoutput), unsigned long OUTPUT[] ($*1_ltype tempoutput)
+%{$1 = &tempoutput;%}
+
+%typemap(in) long INOUT[] ($*1_ltype tempinout), unsigned long INOUT[] ($*1_ltype tempinout)
+%{tempinout = ($*1_ltype)*$input;
+  $1 = &tempinout;%}
+
+%typemap(argout) long OUTPUT[], unsigned long OUTPUT[] "*$input = *$1;"
+%typemap(argout) long INOUT[], unsigned long INOUT[] "*$input = *$1;"
+
+
+#undef INPUT_TYPEMAP
+#undef OUTPUT_TYPEMAP
+#undef INOUT_TYPEMAP
diff --git a/Lib/csharp/wchar.i b/Lib/csharp/wchar.i
index 7981941..f1e0d5a 100644
--- a/Lib/csharp/wchar.i
+++ b/Lib/csharp/wchar.i
@@ -2,37 +2,58 @@
  * wchar.i
  *
  * Typemaps for the wchar_t type
- * These are mapped to a C# String and are passed around by value.
+ * wchar_t * is mapped to a C# Unicode string (UTF16) and is passed around by value.
+ * wchar_t * support includes wchar_t as a 2 byte type (Windows) and a 4 byte type
+ * (most Unix systems).
  *
  * Support code for wide strings can be turned off by defining SWIG_CSHARP_NO_WSTRING_HELPER
- *
  * ----------------------------------------------------------------------------- */
 
 #if !defined(SWIG_CSHARP_NO_WSTRING_HELPER)
 #if !defined(SWIG_CSHARP_WSTRING_HELPER_)
 #define SWIG_CSHARP_WSTRING_HELPER_
+
+%fragment("<wchar.h>"); // TODO: %fragment("<wchar.h", "runtime");
+
 %insert(runtime) %{
 /* Callback for returning strings to C# without leaking memory */
-typedef void * (SWIGSTDCALL* SWIG_CSharpWStringHelperCallback)(const wchar_t *);
-static SWIG_CSharpWStringHelperCallback SWIG_csharp_wstring_callback = NULL;
+typedef void * (SWIGSTDCALL* SWIG_CSharpWStringHelperCallback)(const wchar_t *, int length);
+static SWIG_CSharpWStringHelperCallback SWIG_csharp_wstring_with_length_callback = NULL;
 %}
 
+%insert(header) %{
+static void * SWIG_csharp_wstring_callback(const wchar_t *s) {
+  return SWIG_csharp_wstring_with_length_callback(s, (int)wcslen(s));
+}
+%}
+
+
 %pragma(csharp) imclasscode=%{
   protected class SWIGWStringHelper {
 
     [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]
-    public delegate string SWIGWStringDelegate(global::System.IntPtr message);
-    static SWIGWStringDelegate wstringDelegate = new SWIGWStringDelegate(CreateWString);
+    public delegate string SWIGWStringDelegate(global::System.IntPtr message, int length);
+    static SWIGWStringDelegate wstringUTF16Delegate = new SWIGWStringDelegate(CreateWStringFromUTF16);
+    static SWIGWStringDelegate wstringUTF32Delegate = new SWIGWStringDelegate(CreateWStringFromUTF32);
 
     [global::System.Runtime.InteropServices.DllImport("$dllimport", EntryPoint="SWIGRegisterWStringCallback_$module")]
-    public static extern void SWIGRegisterWStringCallback_$module(SWIGWStringDelegate wstringDelegate);
+    public static extern void SWIGRegisterWStringCallback_$module(SWIGWStringDelegate wstringUTF16Delegate, SWIGWStringDelegate wstringUTF32Delegate);
 
-    static string CreateWString([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString) {
-      return global::System.Runtime.InteropServices.Marshal.PtrToStringUni(cString);
+    public static string CreateWStringFromUTF16([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+      return global::System.Runtime.InteropServices.Marshal.PtrToStringUni(cString, length);
+    }
+
+    public static string CreateWStringFromUTF32([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+      if (length == 0)
+        return string.Empty;
+
+      byte[] buffer = new byte[length * 4];
+      global::System.Runtime.InteropServices.Marshal.Copy(cString, buffer, 0, buffer.Length);
+      return global::System.Text.Encoding.UTF32.GetString(buffer);
     }
 
     static SWIGWStringHelper() {
-      SWIGRegisterWStringCallback_$module(wstringDelegate);
+      SWIGRegisterWStringCallback_$module(wstringUTF16Delegate, wstringUTF32Delegate);
     }
   }
 
@@ -43,13 +64,76 @@
 #ifdef __cplusplus
 extern "C"
 #endif
-SWIGEXPORT void SWIGSTDCALL SWIGRegisterWStringCallback_$module(SWIG_CSharpWStringHelperCallback callback) {
-  SWIG_csharp_wstring_callback = callback;
+SWIGEXPORT void SWIGSTDCALL SWIGRegisterWStringCallback_$module(SWIG_CSharpWStringHelperCallback callback_utf16, SWIG_CSharpWStringHelperCallback callback_utf32) {
+  SWIG_csharp_wstring_with_length_callback = sizeof(wchar_t) == 2 ? callback_utf16 : callback_utf32;
 }
 %}
 #endif // SWIG_CSHARP_WSTRING_HELPER_
 #endif // SWIG_CSHARP_NO_WSTRING_HELPER
 
+#if !defined(SWIG_CSHARP_NO_WSTRING_EXCEPTION_HELPER)
+#if !defined(SWIG_CSHARP_WSTRING_EXCEPTION_HELPER_)
+#define SWIG_CSHARP_WSTRING_EXCEPTION_HELPER_
+
+%insert(runtime) %{
+/* Callback for returning strings to C# without leaking memory */
+typedef void (SWIGSTDCALL* SWIG_CSharpWStringExceptionHelperCallback)(const wchar_t *, int length);
+static SWIG_CSharpWStringExceptionHelperCallback SWIG_csharp_ApplicationException_callback = NULL;
+%}
+
+%pragma(csharp) imclasscode=%{
+  protected class SWIGWStringExceptionHelper {
+
+    [return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]
+    public delegate void SWIGWStringExceptionDelegate(global::System.IntPtr message, int length);
+    static SWIGWStringExceptionDelegate applicationExceptionUTF16Delegate = new SWIGWStringExceptionDelegate(SetPendingApplicationExceptionUTF16);
+    static SWIGWStringExceptionDelegate applicationExceptionUTF32Delegate = new SWIGWStringExceptionDelegate(SetPendingApplicationExceptionUTF32);
+
+    [global::System.Runtime.InteropServices.DllImport("$dllimport", EntryPoint="SWIGRegisterWStringExceptionCallback_$module")]
+    public static extern void SWIGRegisterWStringExceptionCallback_$module(SWIGWStringExceptionDelegate applicationExceptionUTF16Delegate, SWIGWStringExceptionDelegate applicationExceptionUTF32Delegate);
+
+    static string CreateWStringFromUTF16([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+      return global::System.Runtime.InteropServices.Marshal.PtrToStringUni(cString, length);
+    }
+
+    public static string CreateWStringFromUTF32([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+      if (length == 0)
+        return string.Empty;
+
+      byte[] buffer = new byte[length * 4];
+      return global::System.Text.Encoding.UTF32.GetString(buffer);
+    }
+
+    static void SetPendingApplicationExceptionUTF16([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+      string message = SWIGWStringHelper.CreateWStringFromUTF16(cString, length);
+      SWIGPendingException.Set(new global::System.ApplicationException(message, SWIGPendingException.Retrieve()));
+    }
+
+    static void SetPendingApplicationExceptionUTF32([global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]global::System.IntPtr cString, int length) {
+      string message = SWIGWStringHelper.CreateWStringFromUTF32(cString, length);
+      SWIGPendingException.Set(new global::System.ApplicationException(message, SWIGPendingException.Retrieve()));
+    }
+
+    static SWIGWStringExceptionHelper() {
+      SWIGRegisterWStringExceptionCallback_$module(applicationExceptionUTF16Delegate, applicationExceptionUTF32Delegate);
+    }
+  }
+
+  static protected SWIGWStringExceptionHelper swigWStringExceptionHelper = new SWIGWStringExceptionHelper();
+%}
+
+%insert(runtime) %{
+#ifdef __cplusplus
+extern "C"
+#endif
+SWIGEXPORT void SWIGSTDCALL SWIGRegisterWStringExceptionCallback_$module(SWIG_CSharpWStringExceptionHelperCallback callback_utf16, SWIG_CSharpWStringExceptionHelperCallback callback_utf32) {
+  SWIG_csharp_ApplicationException_callback = sizeof(wchar_t) == 2 ? callback_utf16 : callback_utf32;
+}
+%}
+
+#endif // SWIG_CSHARP_WSTRING_EXCEPTION_HELPER_
+#endif // SWIG_CSHARP_NO_WSTRING_EXCEPTION_HELPER
+
 
 // wchar_t
 %typemap(ctype) wchar_t "wchar_t"
@@ -77,13 +161,64 @@
 %typemap(typecheck) wchar_t = char;
 
 // wchar_t *
-%typemap(ctype) wchar_t * "wchar_t *"
-%typemap(imtype, inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]", out="global::System.IntPtr" ) wchar_t * "string"
+
+%fragment("Swig_csharp_UTF16ToWCharPtr", "header") %{
+/* For converting from .NET UTF16 (2 byte unicode) strings. wchar_t is 2 bytes on Windows, 4 bytes on Linux. */
+static wchar_t * Swig_csharp_UTF16ToWCharPtr(const unsigned short *str) {
+  if (sizeof(wchar_t) == 2) {
+    return (wchar_t *)str;
+  } else {
+    wchar_t *result = 0;
+
+    if (str) {
+      const unsigned short *pBegin(str);
+      const unsigned short *pEnd(pBegin);
+      wchar_t *ptr = 0;
+
+      while (*pEnd != 0)
+        ++pEnd;
+
+#ifdef __cplusplus
+      result = ptr = new wchar_t[pEnd - pBegin + 1];
+#else
+      result = ptr = (wchar_t *)malloc(sizeof(wchar_t) * (pEnd - pBegin + 1));
+#endif
+      while(pBegin != pEnd)
+        *ptr++ = *pBegin++;
+      *ptr++ = 0;
+    }
+
+    return result;
+  }
+}
+%}
+
+%fragment("Swig_csharp_UTF16ToWCharPtrFree", "header") %{
+static void Swig_csharp_UTF16ToWCharPtrFree(wchar_t *str) {
+  if (sizeof(wchar_t) != 2) {
+#ifdef __cplusplus
+    delete [] str;
+#else
+    free(str);
+#endif
+  }
+}
+%}
+
+%typemap(ctype, out="void *") wchar_t * "unsigned short *"
+%typemap(imtype,
+         inattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+         outattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+         directorinattributes="[global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]",
+         directoroutattributes="[return: global::System.Runtime.InteropServices.MarshalAs(global::System.Runtime.InteropServices.UnmanagedType.LPWStr)]"
+         ) wchar_t * "string"
 %typemap(cstype) wchar_t * "string"
+%typemap(csdirectorin) wchar_t * "$iminput"
+%typemap(csdirectorout) wchar_t * "$cscall"
 
 %typemap(csin) wchar_t * "$csinput"
 %typemap(csout, excode=SWIGEXCODE) wchar_t * {
-    string ret = global::System.Runtime.InteropServices.Marshal.PtrToStringUni($imcall);$excode
+    string ret = $imcall;$excode
     return ret;
   }
 %typemap(csvarin, excode=SWIGEXCODE2) wchar_t * %{
@@ -96,8 +231,105 @@
       return ret;
     } %}
 
-%typemap(in) wchar_t * %{ $1 = ($1_ltype)$input; %}
-%typemap(out) wchar_t * %{ $result = (wchar_t *)$1; %}
+%typemap(in, fragment="Swig_csharp_UTF16ToWCharPtr") wchar_t *
+%{ $1 = Swig_csharp_UTF16ToWCharPtr($input); %}
+
+%typemap(out) wchar_t * %{ $result = $1 ? SWIG_csharp_wstring_callback($1) : 0; %}
+
+%typemap(freearg, fragment="Swig_csharp_UTF16ToWCharPtrFree") wchar_t *
+%{ Swig_csharp_UTF16ToWCharPtrFree($1); %}
+
+%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) wchar_t *
+%{ $result = Swig_csharp_UTF16ToWCharPtr($input); %}
+
+%typemap(directorin) wchar_t * %{ $input = SWIG_csharp_wstring_with_length_callback($1, (int)wcslen($1)); %}
 
 %typemap(typecheck) wchar_t * = char *;
 
+%typemap(throws, canthrow=1, fragment="<wchar.h>") wchar_t *
+%{ SWIG_csharp_ApplicationException_callback($1, (int)wcslen($1));
+   return $null; %}
+
+
+/* Default typemap for handling wchar_t * members (based on char * in swig.swg) */
+
+#ifdef __cplusplus
+%typemap(memberin,fragment="<wchar.h>") wchar_t * {
+  delete [] $1;
+  if ($input && sizeof(wchar_t) == 2) {
+    $1 = ($1_type) (new wchar_t[wcslen((const wchar_t *)$input)+1]);
+    wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+  } else {
+    $1 = $input;
+    $input = 0;
+  }
+}
+%typemap(memberin,warning=SWIGWARN_TYPEMAP_WCHARLEAK_MSG,fragment="<wchar.h>") const wchar_t * {
+  if ($input && sizeof(wchar_t) == 2) {
+    $1 = ($1_type) (new wchar_t[wcslen((const wchar_t *)$input)+1]);
+    wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+  } else {
+    $1 = $input;
+    $input = 0;
+  }
+}
+%typemap(globalin,fragment="<wchar.h>") wchar_t * {
+  delete [] $1;
+  if ($input && sizeof(wchar_t) == 2) {
+    $1 = ($1_type) (new wchar_t[wcslen((const wchar_t *)$input)+1]);
+    wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+  } else {
+    $1 = $input;
+    $input = 0;
+  }
+}
+%typemap(globalin,warning=SWIGWARN_TYPEMAP_WCHARLEAK_MSG,fragment="<wchar.h>") const wchar_t * {
+  if ($input && sizeof(wchar_t) == 2) {
+    $1 = ($1_type) (new wchar_t[wcslen((const wchar_t *)$input)+1]);
+    wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+  } else {
+    $1 = $input;
+    $input = 0;
+  }
+}
+#else
+%typemap(memberin,fragment="<wchar.h>") wchar_t * {
+  free($1);
+  if ($input && sizeof(wchar_t) == 2) {
+    $1 = ($1_type) malloc(wcslen((const wchar_t *)$input)+1);
+    wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+  } else {
+    $1 = $input;
+    $input = 0;
+  }
+}
+%typemap(memberin,warning=SWIGWARN_TYPEMAP_WCHARLEAK_MSG,fragment="<wchar.h>") const wchar_t * {
+  if ($input && sizeof(wchar_t) == 2) {
+    $1 = ($1_type) malloc(wcslen((const wchar_t *)$input)+1);
+    wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+  } else {
+    $1 = $input;
+    $input = 0;
+  }
+}
+%typemap(globalin,fragment="<wchar.h>") wchar_t * {
+  free($1);
+  if ($input && sizeof(wchar_t) == 2) {
+    $1 = ($1_type) malloc(wcslen((const wchar_t *)$input)+1);
+    wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+  } else {
+    $1 = $input;
+    $input = 0;
+  }
+}
+%typemap(globalin,warning=SWIGWARN_TYPEMAP_WCHARLEAK_MSG,fragment="<wchar.h>") const wchar_t * {
+  if ($input && sizeof(wchar_t) == 2) {
+    $1 = ($1_type) malloc(wcslen((const wchar_t *)$input)+1);
+    wcscpy((wchar_t *)$1, (const wchar_t *)$input);
+  } else {
+    $1 = $input;
+    $input = 0;
+  }
+}
+
+#endif
diff --git a/Lib/d/argcargv.i b/Lib/d/argcargv.i
new file mode 100644
index 0000000..92544f9
--- /dev/null
+++ b/Lib/d/argcargv.i
@@ -0,0 +1,26 @@
+/* -------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------- */
+
+%typemap(ctype) (int ARGC, char **ARGV) "SWIG_c_dstring_array"
+%typemap(imtype) (int ARGC, char **ARGV) "string[]"
+%typemap(dtype) (int ARGC, char **ARGV) "string[]"
+
+%typemap(in, canthrow=1) (int ARGC, char **ARGV) {
+  $1_ltype i, len;
+  len = $input.len;
+  $2 = ($2_ltype) malloc((len+1)*sizeof($*2_ltype));
+  if ($2 == SWIG_NULLPTR) {
+    SWIG_DSetPendingException(SWIG_DException, "memory allocation failed");
+    return $null;
+  }
+  $1 = len;
+  for (i = 0; i < len; i++) {
+    $2[i] = $input.array[i].str;
+  }
+  $2[i] = SWIG_NULLPTR;
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+  free((void *)$2);
+}
diff --git a/Lib/d/boost_shared_ptr.i b/Lib/d/boost_shared_ptr.i
index 4a220a5..6d85c5a 100644
--- a/Lib/d/boost_shared_ptr.i
+++ b/Lib/d/boost_shared_ptr.i
@@ -23,10 +23,10 @@
   }
   $1 = *argp; %}
 %typemap(out) CONST TYPE
-%{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
+%{ $result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1)); %}
 
 %typemap(directorin) CONST TYPE
-%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype((const $1_ltype &)$1)); %}
+%{ $input = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype(SWIG_STD_MOVE($1))); %}
 
 %typemap(directorout) CONST TYPE
 %{ if (!$input) {
@@ -116,7 +116,7 @@
 %typemap(in) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > * ($*1_ltype tempnull)
 %{ $1 = $input ? ($1_ltype)$input : &tempnull; %}
 %typemap(out, fragment="SWIG_null_deleter") SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *
-%{ $result = ($1 && *$1) ? new $*1_ltype(*($1_ltype)$1) : 0;
+%{ $result = ($1 && *$1) ? new $*1_ltype(*$1) : 0;
    if ($owner) delete $1; %}
 
 %typemap(directorin) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *
diff --git a/Lib/d/carrays.i b/Lib/d/carrays.i
index f2803ea..0bd99a7 100644
--- a/Lib/d/carrays.i
+++ b/Lib/d/carrays.i
@@ -10,16 +10,16 @@
  * Generates functions for creating and accessing elements of a C array
  * (as pointers).  Creates the following functions:
  *
- *        TYPE *new_NAME(int nelements)
+ *        TYPE *new_NAME(size_t nelements)
  *        void delete_NAME(TYPE *);
- *        TYPE NAME_getitem(TYPE *, int index);
- *        void NAME_setitem(TYPE *, int index, TYPE value);
+ *        TYPE NAME_getitem(TYPE *, size_t index);
+ *        void NAME_setitem(TYPE *, size_t index, TYPE value);
  *
  * ----------------------------------------------------------------------------- */
 
 %define %array_functions(TYPE,NAME)
 %{
-static TYPE *new_##NAME(int nelements) { %}
+static TYPE *new_##NAME(size_t nelements) { %}
 #ifdef __cplusplus
 %{  return new TYPE[nelements](); %}
 #else
@@ -35,18 +35,18 @@
 #endif
 %{}
 
-static TYPE NAME##_getitem(TYPE *ary, int index) {
+static TYPE NAME##_getitem(TYPE *ary, size_t index) {
     return ary[index];
 }
-static void NAME##_setitem(TYPE *ary, int index, TYPE value) {
+static void NAME##_setitem(TYPE *ary, size_t index, TYPE value) {
     ary[index] = value;
 }
 %}
 
-TYPE *new_##NAME(int nelements);
+TYPE *new_##NAME(size_t nelements);
 void delete_##NAME(TYPE *ary);
-TYPE NAME##_getitem(TYPE *ary, int index);
-void NAME##_setitem(TYPE *ary, int index, TYPE value);
+TYPE NAME##_getitem(TYPE *ary, size_t index);
+void NAME##_setitem(TYPE *ary, size_t index, TYPE value);
 
 %enddef
 
@@ -58,13 +58,13 @@
  * interface:
  *
  *          struct NAME {
- *              NAME(int nelements);
+ *              NAME(size_t nelements);
  *             ~NAME();
- *              TYPE getitem(int index);
- *              void setitem(int index, TYPE value);
+ *              TYPE getitem(size_t index);
+ *              void setitem(size_t index, TYPE value);
  *              TYPE * ptr();
  *              static NAME *frompointer(TYPE *t);
-  *         }
+ *          }
  *
  * ----------------------------------------------------------------------------- */
 
@@ -76,34 +76,36 @@
 typedef struct {} NAME;
 
 %extend NAME {
+
 #ifdef __cplusplus
-  NAME(int nelements) {
-    return new TYPE[nelements]();
-  }
-  ~NAME() {
-    delete [] self;
-  }
+NAME(size_t nelements) {
+  return new TYPE[nelements]();
+}
+~NAME() {
+  delete [] self;
+}
 #else
-  NAME(int nelements) {
-    return (TYPE *) calloc(nelements,sizeof(TYPE));
-  }
-  ~NAME() {
-    free(self);
-  }
+NAME(size_t nelements) {
+  return (TYPE *) calloc(nelements,sizeof(TYPE));
+}
+~NAME() {
+  free(self);
+}
 #endif
 
-  TYPE getitem(int index) {
-    return self[index];
-  }
-  void setitem(int index, TYPE value) {
-    self[index] = value;
-  }
-  TYPE * ptr() {
-    return self;
-  }
-  static NAME *frompointer(TYPE *t) {
-    return (NAME *) t;
-  }
+TYPE getitem(size_t index) {
+  return self[index];
+}
+void setitem(size_t index, TYPE value) {
+  self[index] = value;
+}
+TYPE * ptr() {
+  return self;
+}
+static NAME *frompointer(TYPE *t) {
+  return (NAME *) t;
+}
+
 };
 
 %types(NAME = TYPE);
diff --git a/Lib/d/cpointer.i b/Lib/d/cpointer.i
index 75e610f..da3084b 100644
--- a/Lib/d/cpointer.i
+++ b/Lib/d/cpointer.i
@@ -54,14 +54,14 @@
   return new TYPE();
 }
 ~NAME() {
-  if (self) delete self;
+  delete self;
 }
 #else
 NAME() {
   return (TYPE *) calloc(1,sizeof(TYPE));
 }
 ~NAME() {
-  if (self) free(self);
+  free(self);
 }
 #endif
 }
@@ -133,9 +133,9 @@
 
 static void delete_##NAME(TYPE *self) { %}
 #ifdef __cplusplus
-%{  if (self) delete self; %}
+%{  delete self; %}
 #else
-%{  if (self) free(self); %}
+%{  free(self); %}
 #endif
 %{}
 
diff --git a/Lib/d/dclassgen.swg b/Lib/d/dclassgen.swg
index 84fa03a..e4ff8d5 100644
--- a/Lib/d/dclassgen.swg
+++ b/Lib/d/dclassgen.swg
@@ -76,6 +76,19 @@
   return (obj is null) ? null : obj.swigCPtr;
 }
 
+public static void* swigRelease(typeof(this) obj) {
+  if (obj !is null) {
+    if (!obj.swigCMemOwn)
+      throw new Exception("Cannot release ownership as memory is not owned");
+    void* ptr = obj.swigCPtr;
+    obj.swigCMemOwn = false;
+    obj.dispose();
+    return ptr;
+  } else {
+    return null;
+  }
+}
+
 mixin $imdmodule.SwigOperatorDefinitions;
 %}
 
@@ -92,6 +105,19 @@
   return (obj is null) ? null : obj.swigCPtr;
 }
 
+public static void* swigRelease(typeof(this) obj) {
+  if (obj !is null) {
+    if (!obj.swigCMemOwn)
+      throw new Exception("Cannot release ownership as memory is not owned");
+    void* ptr = obj.swigCPtr;
+    obj.swigCMemOwn = false;
+    obj.dispose();
+    return ptr;
+  } else {
+    return null;
+  }
+}
+
 mixin $imdmodule.SwigOperatorDefinitions;
 %}
 
@@ -100,7 +126,7 @@
  * Type wrapper classes.
  */
 
-%typemap(dbody) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] %{
+%typemap(dbody) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] %{
 private void* swigCPtr;
 
 public this(void* cObject, bool futureUse) {
@@ -115,6 +141,10 @@
   return (obj is null) ? null : obj.swigCPtr;
 }
 
+public static void* swigRelease(typeof(this) obj) {
+  return (obj is null) ? null : obj.swigCPtr;
+}
+
 mixin $imdmodule.SwigOperatorDefinitions;
 %}
 
diff --git a/Lib/d/dexception.swg b/Lib/d/dexception.swg
index 1aadbaa..74e0422 100644
--- a/Lib/d/dexception.swg
+++ b/Lib/d/dexception.swg
@@ -15,7 +15,7 @@
                  unsigned long,
                  unsigned short
 %{ char error_msg[256];
-   sprintf(error_msg, "C++ $1_type exception thrown, value: %d", $1);
+   SWIG_snprintf(error_msg, sizeof(error_msg), "C++ $1_type exception thrown, value: %d", $1);
    SWIG_DSetPendingException(SWIG_DException, error_msg);
    return $null; %}
 
diff --git a/Lib/d/dhead.swg b/Lib/d/dhead.swg
index 50e9c2e..40393c9 100644
--- a/Lib/d/dhead.swg
+++ b/Lib/d/dhead.swg
@@ -1,9 +1,6 @@
 /* -----------------------------------------------------------------------------
  * dhead.swg
  *
- * Support code for exceptions if the SWIG_D_NO_EXCEPTION_HELPER is not defined
- * Support code for strings if the SWIG_D_NO_STRING_HELPER is not defined
- *
  * Support code for function pointers. ----------------------------------------------------------------------------- */
 
 %insert(runtime) %{
@@ -12,7 +9,7 @@
 #include <stdio.h>
 
 /* Contract support. */
-#define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_DSetPendingException(SWIG_DException, msg); return nullreturn; } else
+#define SWIG_contract_assert(nullreturn, expr, msg) do { if (!(expr)) {SWIG_DSetPendingException(SWIG_DException, msg); return nullreturn; } } while (0)
 %}
 
 
@@ -20,7 +17,6 @@
  * Exception support code.
  */
 
-#if !defined(SWIG_D_NO_EXCEPTION_HELPER)
 %insert(runtime) %{
 // Support for throwing D exceptions from C/C++.
 typedef enum {
@@ -71,87 +67,6 @@
 }
 %}
 
-#if (SWIG_D_VERSION == 1)
-%pragma(d) imdmoduleimports=%{
-// Exception throwing support currently requires Tango, but there is no reason
-// why it could not support Phobos.
-static import tango.core.Exception;
-static import tango.core.Thread;
-static import tango.stdc.stringz;
-%}
-
-%pragma(d) imdmodulecode=%{
-private class SwigExceptionHelper {
-  static this() {
-    swigRegisterExceptionCallbacks$module(
-      &setException,
-      &setIllegalArgumentException,
-      &setIllegalElementException,
-      &setIOException,
-      &setNoSuchElementException);
-  }
-
-  static void setException(char* message) {
-    auto exception = new object.Exception(tango.stdc.stringz.fromStringz(message).dup);
-    SwigPendingException.set(exception);
-  }
-
-  static void setIllegalArgumentException(char* message) {
-    auto exception = new tango.core.Exception.IllegalArgumentException(tango.stdc.stringz.fromStringz(message).dup);
-    SwigPendingException.set(exception);
-  }
-
-  static void setIllegalElementException(char* message) {
-    auto exception = new tango.core.Exception.IllegalElementException(tango.stdc.stringz.fromStringz(message).dup);
-    SwigPendingException.set(exception);
-  }
-
-  static void setIOException(char* message) {
-    auto exception = new tango.core.Exception.IOException(tango.stdc.stringz.fromStringz(message).dup);
-    SwigPendingException.set(exception);
-  }
-
-  static void setNoSuchElementException(char* message) {
-    auto exception = new tango.core.Exception.NoSuchElementException(tango.stdc.stringz.fromStringz(message).dup);
-    SwigPendingException.set(exception);
-  }
-}
-
-package class SwigPendingException {
-public:
-  static this() {
-    m_sPendingException = new ThreadLocalData(null);
-  }
-
-  static bool isPending() {
-    return m_sPendingException.val !is null;
-  }
-
-  static void set(object.Exception e) {
-    auto pending = m_sPendingException.val;
-    if (pending !is null) {
-      e.next = pending;
-      throw new object.Exception("FATAL: An earlier pending exception from C/C++ " ~
-        "code was missed and thus not thrown (" ~ pending.classinfo.name ~ ": " ~
-        pending.msg ~ ")!", e);
-    }
-    m_sPendingException.val = e;
-  }
-
-  static object.Exception retrieve() {
-    auto e = m_sPendingException.val;
-    m_sPendingException.val = null;
-    return e;
-  }
-
-private:
-  // The reference to the pending exception (if any) is stored thread-local.
-  alias tango.core.Thread.ThreadLocal!(object.Exception) ThreadLocalData;
-  static ThreadLocalData m_sPendingException;
-}
-alias void function(char* message) SwigExceptionCallback;
-%}
-#else
 %pragma(d) imdmoduleimports=%{
 static import std.conv;
 %}
@@ -175,7 +90,7 @@
   }
 }
 
-package struct SwigPendingException {
+public class SwigPendingException {
 public:
   static this() {
     m_sPendingException = null;
@@ -208,16 +123,13 @@
 }
 alias void function(const char* message) SwigExceptionCallback;
 %}
-#endif
 // Callback registering function in wrapperloader.swg.
-#endif // SWIG_D_NO_EXCEPTION_HELPER
 
 
 /*
  * String support code.
  */
 
-#if !defined(SWIG_D_NO_STRING_HELPER)
 %insert(runtime) %{
 // Callback for returning strings to D without leaking memory.
 typedef char * (* SWIG_DStringHelperCallback)(const char *);
@@ -231,23 +143,6 @@
 }
 %}
 
-#if (SWIG_D_VERSION == 1)
-%pragma(d) imdmoduleimports = "static import tango.stdc.stringz;";
-
-%pragma(d) imdmodulecode = %{
-private class SwigStringHelper {
-  static this() {
-    swigRegisterStringCallback$module(&createString);
-  }
-
-  static char* createString(char* cString) {
-    // We are effectively dup'ing the string here.
-    return tango.stdc.stringz.toStringz(tango.stdc.stringz.fromStringz(cString));
-  }
-}
-alias char* function(char* cString) SwigStringCallback;
-%}
-#else
 %pragma(d) imdmoduleimports = %{
 static import std.conv;
 static import std.string;
@@ -261,31 +156,18 @@
 
   static const(char)* createString(const(char*) cString) {
     // We are effectively dup'ing the string here.
-    // TODO: Is this also correct for D2/Phobos?
+    // TODO: Is this correct for D2/Phobos?
     return std.string.toStringz(std.conv.to!string(cString));
   }
 }
 alias const(char)* function(const(char*) cString) SwigStringCallback;
 %}
-#endif
 // Callback registering function in wrapperloader.swg.
-#endif // SWIG_D_NO_STRING_HELPER
 
 
 /*
  * Function pointer support code.
  */
-#if (SWIG_D_VERSION == 1)
-%pragma(d) imdmodulecode = %{
-template SwigExternC(T) {
-  static if (is(typeof(*(T.init)) R == return)) {
-    static if (is(typeof(*(T.init)) P == function)) {
-      alias extern(C) R function(P) SwigExternC;
-    }
-  }
-}
-%}
-#else
 %pragma(d) imdmodulecode = %{
 template SwigExternC(T) if (is(typeof(*(T.init)) P == function)) {
   static if (is(typeof(*(T.init)) R == return)) {
@@ -295,4 +177,3 @@
   }
 }
 %}
-#endif
diff --git a/Lib/d/dkw.swg b/Lib/d/dkw.swg
index 581093f..b96d1fa 100644
--- a/Lib/d/dkw.swg
+++ b/Lib/d/dkw.swg
@@ -2,7 +2,7 @@
 #define D_DKW_SWG_
 
 /* Warnings for D keywords */
-#define DKEYWORD(x) %keywordwarn("'" `x` "' is a D keyword, renaming to '_" `x` "'",rename="_%s")  `x`
+#define DKEYWORD(x) %keywordwarn("'" `x` "' is a D keyword",rename="_%s")  `x`
 
 // Source: http://www.digitalmars.com/d/{1.0,2.0}/lex.html and
 DKEYWORD(Error);
@@ -120,7 +120,7 @@
 DKEYWORD(wstring);
 
 // Not really a keyword, but dispose() methods are generated in proxy classes
-// and it's a special method name for D1/Tango.
+// and it was a special method name for D1/Tango.
 DKEYWORD(dispose);
 
 #undef DKEYWORD
diff --git a/Lib/d/doperators.swg b/Lib/d/doperators.swg
index 0cb6353..f651c39 100644
--- a/Lib/d/doperators.swg
+++ b/Lib/d/doperators.swg
@@ -4,129 +4,6 @@
  * Mapping of C++ operator overloading methods to D.
  * ----------------------------------------------------------------------------- */
 
-#if (SWIG_D_VERSION == 1)
-
-%pragma(d) imdmodulecode=%{
-template SwigOperatorDefinitions() {
-  public override int opEquals(Object o) {
-    if (auto rhs = cast(typeof(this))o) {
-      if (swigCPtr == rhs.swigCPtr) return 1;
-      static if (is(typeof(swigOpEquals(rhs)))) {
-        return swigOpEquals(rhs) ? 1 : 0;
-      } else {
-        return 0; 
-      }
-    }
-    return super.opEquals(o);
-  }
-%}
-// opEquals is emitted in pure C mode as well to define two proxy classes
-// pointing to the same struct as equal.
-
-#ifdef __cplusplus
-%rename(opPos) *::operator+();
-%rename(opPos) *::operator+() const;
-%rename(opNeg) *::operator-();
-%rename(opNeg) *::operator-() const;
-%rename(opCom) *::operator~();
-%rename(opCom) *::operator~() const;
-
-%rename(opAdd) *::operator+;
-%rename(opAddAssign) *::operator+=;
-%rename(opSub) *::operator-;
-%rename(opSubAssign) *::operator-=;
-%rename(opMul) *::operator*;
-%rename(opMulAssign) *::operator*=;
-%rename(opDiv) *::operator/;
-%rename(opDivAssign) *::operator/=;
-%rename(opMod) *::operator%;
-%rename(opModAssign) *::operator%=;
-%rename(opAnd) *::operator&;
-%rename(opAndAssign) *::operator&=;
-%rename(opOr) *::operator|;
-%rename(opOrAssign) *::operator|=;
-%rename(opXor) *::operator^;
-%rename(opXorAssign) *::operator^=;
-%rename(opShl) *::operator<<;
-%rename(opShlAssign) *::operator<<=;
-%rename(opShr) *::operator>>;
-%rename(opShrAssign) *::operator>>=;
-
-%rename(opIndex) *::operator[](unsigned) const;
-// opIndexAssign is not currently generated, it needs more extensive support
-// mechanisms.
-
-%rename(opCall) *::operator();
-  
-// !a is not overrideable in D1.
-%ignoreoperator(LNOT) operator!;
-
-// opCmp is used in D.
-%rename(swigOpEquals) *::operator==;
-%rename(swigOpLt) *::operator<;
-%rename(swigOpLtEquals) *::operator<=;
-%rename(swigOpGt) *::operator>;
-%rename(swigOpGtEquals) *::operator>=;
-
-// a != b is rewritten as !a.opEquals(b) in D.
-%ignoreoperator(NOTEQUAL) operator!=;
-
-// The logic operators are not overrideable in D.
-%ignoreoperator(LAND) operator&&;
-%ignoreoperator(LOR) operator||;
-
-// ++/--a is rewritten as a +/-= 1 in D1,so ignore the prefix operators.
-%ignoreoperator(PLUSPLUS) *::operator++();
-%ignoreoperator(MINUSMINUS) *::operator--();
-%rename(swigOpInc) *::operator++(int);
-%rename(swigOpDec) *::operator--(int);
-
-// The C++ assignment operator does not translate well to D where the proxy
-// classes have reference semantics.
-%ignoreoperator(EQ) operator=;
-
-%pragma(d) imdmodulecode=%{
-  public override int opCmp(Object o) {
-    static if (is(typeof(swigOpLt(typeof(this).init) &&
-        swigOpEquals(typeof(this).init)))) {
-      if (auto rhs = cast(typeof(this))o) {
-        if (swigOpLt(rhs)) {
-          return -1;
-        } else if (swigOpEquals(rhs)) {
-          return 0;
-        } else {
-          return 1;
-        }
-      }
-    }
-    return super.opCmp(o);
-  }
-
-  public typeof(this) opPostInc(T = int)(T unused = 0) {
-    static assert(
-      is(typeof(swigOpInc(int.init))),
-      "opPostInc called on " ~ typeof(this).stringof ~ ", but no postfix " ~
-        "increment operator exists in the corresponding C++ class."
-    );
-    return swigOpInc(int.init);
-  }
-
-  public typeof(this) opPostDec(T = int)(T unused = 0) {
-    static assert(
-      is(typeof(swigOpDec(int.init))),
-      "opPostInc called on " ~ typeof(this).stringof ~ ", but no postfix " ~
-        "decrement operator exists in the corresponding C++ class."
-    );
-    return swigOpDec(int.init);
-  }
-%}
-#endif
-
-%pragma(d) imdmodulecode=%{
-}
-%}
-
-#else
 %pragma(d) imdmodulecode=%{
 mixin template SwigOperatorDefinitions() {
   public override bool opEquals(Object o) {
@@ -198,7 +75,7 @@
 // a != b is rewritten as !a.opEquals(b) in D.
 %ignoreoperator(NOTEQUAL) operator!=;
 
-// The logic operators are not overrideable in D.
+// The logic operators are not overridable in D.
 %ignoreoperator(LAND) operator&&;
 %ignoreoperator(LOR) operator||;
 
@@ -255,5 +132,3 @@
 %pragma(d) imdmodulecode=%{
 }
 %}
-
-#endif
diff --git a/Lib/d/dprimitives.swg b/Lib/d/dprimitives.swg
index eaee816..843350f 100644
--- a/Lib/d/dprimitives.swg
+++ b/Lib/d/dprimitives.swg
@@ -5,17 +5,10 @@
  * ----------------------------------------------------------------------------- */
 
 // C long/ulong width depends on the target arch, use stdlib aliases for them.
-#if (SWIG_D_VERSION == 1)
-%pragma(d) imdmoduleimports = "static import tango.stdc.config;"
-%pragma(d) globalproxyimports = "static import tango.stdc.config;"
-#define SWIG_LONG_DTYPE tango.stdc.config.c_long
-#define SWIG_ULONG_DTYPE tango.stdc.config.c_ulong
-#else
 %pragma(d) imdmoduleimports = "static import core.stdc.config;"
 %pragma(d) globalproxyimports = "static import core.stdc.config;"
 #define SWIG_LONG_DTYPE core.stdc.config.c_long
 #define SWIG_ULONG_DTYPE core.stdc.config.c_ulong
-#endif
 
 /*
  * The SWIG_D_PRIMITIVE macro is used to define the typemaps for the primitive
@@ -150,6 +143,12 @@
     const unsigned long &
     ""
 
+// Default assumes size_t is 32-bit for overloading
+%typecheck(SWIG_TYPECHECK_UINT32)
+    size_t,
+    const size_t &
+    ""
+
 %typecheck(SWIG_TYPECHECK_INT64)
     long long,
     const long long &
diff --git a/Lib/d/dstrings.swg b/Lib/d/dstrings.swg
index 02895c1..0b875b5 100644
--- a/Lib/d/dstrings.swg
+++ b/Lib/d/dstrings.swg
@@ -64,17 +64,10 @@
 
 // We need to have the \0-terminated string conversion functions available in
 // the D proxy modules.
-#if (SWIG_D_VERSION == 1)
-// Could be easily extended to support Phobos as well.
-SWIGD_STRING_TYPEMAPS(char*, char[], tango.stdc.stringz.fromStringz, tango.stdc.stringz.toStringz)
-
-%pragma(d) globalproxyimports = "static import tango.stdc.stringz;";
-#else
 SWIGD_STRING_TYPEMAPS(const(char)*, string, std.conv.to!string, std.string.toStringz)
 
 %pragma(d) globalproxyimports = %{
 static import std.conv;
 static import std.string;
 %}
-#endif
 #undef SWIGD_STRING_TYPEMAPS
diff --git a/Lib/d/dswigtype.swg b/Lib/d/dswigtype.swg
index f0d604b..81a7d83 100644
--- a/Lib/d/dswigtype.swg
+++ b/Lib/d/dswigtype.swg
@@ -20,6 +20,10 @@
 %typemap(imtype) SWIGTYPE & "void*"
 %typemap(dtype, nativepointer="$dtype") SWIGTYPE & "$dclassname"
 
+%typemap(ctype) SWIGTYPE && "void *"
+%typemap(imtype) SWIGTYPE && "void*"
+%typemap(dtype, nativepointer="$dtype") SWIGTYPE && "$dclassname"
+
 %typemap(ctype) SWIGTYPE *const& "void *"
 %typemap(imtype) SWIGTYPE *const& "void*"
 %typemap(dtype) SWIGTYPE *const& "$*dclassname"
@@ -28,6 +32,7 @@
     SWIGTYPE,
     SWIGTYPE *,
     SWIGTYPE &,
+    SWIGTYPE &&,
     SWIGTYPE [],
     SWIGTYPE *const&
   ""
@@ -47,7 +52,7 @@
 
 %typemap(out) SWIGTYPE
 #ifdef __cplusplus
-%{ $result = new $1_ltype((const $1_ltype &)$1); %}
+%{ $result = new $1_ltype($1); %}
 #else
 {
   $&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype));
@@ -57,7 +62,7 @@
 #endif
 
 %typemap(directorin) SWIGTYPE
-  "$input = (void *)new $1_ltype((const $1_ltype &)$1);"
+  "$input = (void *)new $1_ltype(SWIG_STD_MOVE($1));"
 %typemap(directorout) SWIGTYPE
 %{ if (!$input) {
      SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "Unexpected null return for type $1_type");
@@ -117,7 +122,7 @@
 
 %typemap(in, canthrow=1) SWIGTYPE & %{ $1 = ($1_ltype)$input;
   if (!$1) {
-    SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "$1_type type is null");
+    SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "$1_type is null");
     return $null;
   } %}
 %typemap(out) SWIGTYPE & "$result = (void *)$1;"
@@ -149,6 +154,44 @@
 
 
 /*
+ * Rvalue reference conversion typemaps.
+ */
+
+%typemap(in, canthrow=1, fragment="<memory>") SWIGTYPE && (std::unique_ptr<$*1_ltype> rvrdeleter) %{ $1 = ($1_ltype)$input;
+  if (!$1) {
+    SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "$1_type is null");
+    return $null;
+  }
+  rvrdeleter.reset($1); %}
+%typemap(out) SWIGTYPE && "$result = (void *)$1;"
+
+%typemap(directorin) SWIGTYPE &&
+  "$input = ($1_ltype) &$1;"
+%typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) SWIGTYPE &&
+%{ if (!$input) {
+     SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "Unexpected null return for type $1_type");
+     return $null;
+   }
+   $result = ($1_ltype)$input; %}
+
+%typemap(ddirectorin,
+  nativepointer="cast($dtype)$winput"
+) SWIGTYPE && "new $dclassname($winput, false)"
+%typemap(ddirectorout,
+  nativepointer="cast(void*)$dcall"
+) SWIGTYPE && "$dclassname.swigGetCPtr($dcall)"
+
+%typemap(din,
+  nativepointer="cast(void*)$dinput"
+) SWIGTYPE && "$dclassname.swigRelease($dinput)"
+%typemap(dout, excode=SWIGEXCODE,
+  nativepointer="{\n  auto ret = cast($dtype)$imcall;$excode\n  return ret;\n}") SWIGTYPE && {
+  $dclassname ret = new $dclassname($imcall, $owner);$excode
+  return ret;
+}
+
+
+/*
  * Array conversion typemaps.
  */
 
@@ -164,6 +207,7 @@
 
 // Treat references to arrays like references to a single element.
 %apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) }
+%apply SWIGTYPE && { SWIGTYPE ((&&)[ANY]) }
 
 
 /*
@@ -195,3 +239,46 @@
   nativepointer="cast(void*)$dcall"
 ) SWIGTYPE *const& "$*dclassname.swigGetCPtr($dcall)"
 
+/*
+ * D String & D array represent in C
+ */
+
+%insert(runtime) %{
+#include <stddef.h>
+typedef struct { size_t len; char *str;} SWIG_c_dstring;
+typedef struct { size_t len; SWIG_c_dstring *array; } SWIG_c_dstring_array;
+%}
+
+/*
+ * String & length
+ */
+%typemap(imtype)  (const char *STRING, size_t LENGTH) "string"
+%typemap(dtype)   (const char *STRING, size_t LENGTH) "string"
+%typemap(ctype,default="={0,0}") (const char *STRING, size_t LENGTH) "SWIG_c_dstring"
+%typemap(din, nativepointer="std.conv.to!string($dinput)") (const char *STRING, size_t LENGTH) "$dinput"
+%typemap(freearg) (const char *STRING, size_t LENGTH) ""
+%typemap(in, canthrow=1) (const char *STRING, size_t LENGTH) %{
+  $1 = ($1_ltype)$input.str;
+  $2 = ($2_ltype)$input.len;
+%}
+%typemap(argout)  (const char *STRING, size_t LENGTH) {
+  $input.str = (char *)$1;
+  $input.len = (size_t)$2;
+}
+%typemap(directorin) (const char *STRING, size_t LENGTH) {
+  $input.str = (char *)$1;
+  $input.len = (size_t)$2;
+}
+%typemap(ddirectorin) (const char *STRING, size_t LENGTH) "std.conv.to!string($winput)"
+%apply (const char *STRING, size_t LENGTH) { (char *STRING, size_t LENGTH) }
+/* Enable write-back for non-const version */
+%typemap(argout)  (char *STRING, size_t LENGTH) {
+  $input.str = (char *)$1;
+  $input.len = (size_t)$2;
+}
+%typemap(directorargout) (char *STRING, size_t LENGTH)
+{
+  $1 = ($1_ltype)$input.str;
+  $2 = ($2_ltype)$input.len;
+}
+%apply (char *STRING, size_t LENGTH) { (char *STRING, int LENGTH) }
diff --git a/Lib/d/std_auto_ptr.i b/Lib/d/std_auto_ptr.i
new file mode 100644
index 0000000..500b611
--- /dev/null
+++ b/Lib/d/std_auto_ptr.i
@@ -0,0 +1,42 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap (ctype) std::auto_ptr< TYPE > "void *"
+%typemap (imtype) std::auto_ptr< TYPE > "void*"
+%typemap (dtype) std::auto_ptr< TYPE > "$typemap(dtype, TYPE)"
+
+%typemap(in) std::auto_ptr< TYPE >
+%{ $1.reset((TYPE *)$input); %}
+
+%typemap(din,
+  nativepointer="cast(void*)$dinput"
+) std::auto_ptr< TYPE > "$typemap(dtype, TYPE).swigRelease($dinput)"
+
+%typemap (out) std::auto_ptr< TYPE > %{
+  $result = (void *)$1.release();
+%}
+
+%typemap(dout, excode=SWIGEXCODE,
+  nativepointer="{\n  auto ret = cast($dtype)$imcall;$excode\n  return ret;\n}"
+) std::auto_ptr< TYPE > {
+  void* cPtr = $imcall;
+  $typemap(dtype, TYPE) ret = (cPtr is null) ? null : new $typemap(dtype, TYPE)(cPtr, true);$excode
+  return ret;
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *") std::auto_ptr< TYPE > ""
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class auto_ptr {};
+}
diff --git a/Lib/d/std_map.i b/Lib/d/std_map.i
index c5e03d0..a374f55 100644
--- a/Lib/d/std_map.i
+++ b/Lib/d/std_map.i
@@ -44,7 +44,11 @@
             throw std::out_of_range("key not found");
         }
         void set(const K& key, const T& x) {
+%#ifdef __cpp_lib_map_try_emplace
+          (*self).insert_or_assign(key, x);
+%#else
           (*self)[key] = x;
+%#endif
         }
         void del(const K& key) throw (std::out_of_range) {
           std::map< K, T, C >::iterator i = self->find(key);
diff --git a/Lib/d/std_string.i b/Lib/d/std_string.i
index 8d75d23..fbee057 100644
--- a/Lib/d/std_string.i
+++ b/Lib/d/std_string.i
@@ -79,19 +79,12 @@
 
 // We need to have the \0-terminated string conversion functions available in
 // the D proxy modules.
-#if (SWIG_D_VERSION == 1)
-// Could be easily extended to support Phobos as well.
-SWIGD_STD_STRING_TYPEMAPS(char*, char[], tango.stdc.stringz.fromStringz, tango.stdc.stringz.toStringz)
-
-%pragma(d) globalproxyimports = "static import tango.stdc.stringz;";
-#else
 SWIGD_STD_STRING_TYPEMAPS(const(char)*, string, std.conv.to!string, std.string.toStringz)
 
 %pragma(d) globalproxyimports = %{
 static import std.conv;
 static import std.string;
 %}
-#endif
 
 #undef SWIGD_STD_STRING_TYPEMAPS
 
diff --git a/Lib/d/std_unique_ptr.i b/Lib/d/std_unique_ptr.i
new file mode 100644
index 0000000..9317a7e
--- /dev/null
+++ b/Lib/d/std_unique_ptr.i
@@ -0,0 +1,42 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap (ctype) std::unique_ptr< TYPE > "void *"
+%typemap (imtype) std::unique_ptr< TYPE > "void*"
+%typemap (dtype) std::unique_ptr< TYPE > "$typemap(dtype, TYPE)"
+
+%typemap(in) std::unique_ptr< TYPE >
+%{ $1.reset((TYPE *)$input); %}
+
+%typemap(din,
+  nativepointer="cast(void*)$dinput"
+) std::unique_ptr< TYPE > "$typemap(dtype, TYPE).swigRelease($dinput)"
+
+%typemap (out) std::unique_ptr< TYPE > %{
+  $result = (void *)$1.release();
+%}
+
+%typemap(dout, excode=SWIGEXCODE,
+  nativepointer="{\n  auto ret = cast($dtype)$imcall;$excode\n  return ret;\n}"
+) std::unique_ptr< TYPE > {
+  void* cPtr = $imcall;
+  $typemap(dtype, TYPE) ret = (cPtr is null) ? null : new $typemap(dtype, TYPE)(cPtr, true);$excode
+  return ret;
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *") std::unique_ptr< TYPE > ""
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class unique_ptr {};
+}
diff --git a/Lib/d/std_vector.i b/Lib/d/std_vector.i
index fb8f7d2..8c67402 100644
--- a/Lib/d/std_vector.i
+++ b/Lib/d/std_vector.i
@@ -22,169 +22,6 @@
 
 // MACRO for use within the std::vector class body
 %define SWIG_STD_VECTOR_MINIMUM_INTERNAL(CONST_REFERENCE, CTYPE...)
-#if (SWIG_D_VERSION == 1)
-%typemap(dimports) std::vector< CTYPE > "static import tango.core.Exception;"
-%proxycode %{
-public this($typemap(dtype, CTYPE)[] values) {
-  this();
-  append(values);
-}
-
-alias push_back add;
-alias push_back push;
-alias push_back opCatAssign;
-alias size length;
-alias opSlice slice;
-
-public $typemap(dtype, CTYPE) opIndexAssign($typemap(dtype, CTYPE) value, size_t index) {
-  if (index >= size()) {
-    throw new tango.core.Exception.NoSuchElementException("Tried to assign to element out of vector bounds.");
-  }
-  setElement(index, value);
-  return value;
-}
-
-public $typemap(dtype, CTYPE) opIndex(size_t index) {
-  if (index >= size()) {
-    throw new tango.core.Exception.NoSuchElementException("Tried to read from element out of vector bounds.");
-  }
-  return getElement(index);
-}
-
-public void append($typemap(dtype, CTYPE)[] value...) {
-  foreach (v; value) {
-    add(v);
-  }
-}
-
-public $typemap(dtype, CTYPE)[] opSlice() {
-  $typemap(dtype, CTYPE)[] array = new $typemap(dtype, CTYPE)[size()];
-  foreach (i, ref value; array) {
-    value = getElement(i);
-  }
-  return array;
-}
-
-public int opApply(int delegate(ref $typemap(dtype, CTYPE) value) dg) {
-  int result;
-
-  size_t currentSize = size();
-  for (size_t i = 0; i < currentSize; ++i) {
-    auto value = getElement(i);
-    result = dg(value);
-    setElement(i, value);
-  }
-  return result;
-}
-
-public int opApply(int delegate(ref size_t index, ref $typemap(dtype, CTYPE) value) dg) {
-  int result;
-
-  size_t currentSize = size();
-  for (size_t i = 0; i < currentSize; ++i) {
-    auto value = getElement(i);
-
-    // Workaround for http://d.puremagic.com/issues/show_bug.cgi?id=2443.
-    auto index = i;
-
-    result = dg(index, value);
-    setElement(i, value);
-  }
-  return result;
-}
-
-public void capacity(size_t value) {
-  if (value < size()) {
-    throw new tango.core.Exception.IllegalArgumentException("Tried to make the capacity of a vector smaller than its size.");
-  }
-
-  reserve(value);
-}
-%}
-
-  public:
-    typedef size_t size_type;
-    typedef ptrdiff_t difference_type;
-    typedef CTYPE value_type;
-    typedef value_type* pointer;
-    typedef const value_type* const_pointer;
-    typedef value_type& reference;
-    typedef CONST_REFERENCE const_reference;
-
-    void clear();
-    void push_back(CTYPE const& x);
-    size_type size() const;
-    size_type capacity() const;
-    void reserve(size_type n) throw (std::length_error);
-
-    vector();
-    vector(const vector &other);
-
-    %extend {
-      vector(size_type capacity) throw (std::length_error) {
-        std::vector< CTYPE >* pv = 0;
-        pv = new std::vector< CTYPE >();
-
-        // Might throw std::length_error.
-        pv->reserve(capacity);
-
-        return pv;
-      }
-
-      size_type unused() const {
-        return $self->capacity() - $self->size();
-      }
-
-      const_reference remove() throw (std::out_of_range) {
-        if ($self->empty()) {
-          throw std::out_of_range("Tried to remove last element from empty vector.");
-        }
-
-        std::vector< CTYPE >::const_reference value = $self->back();
-        $self->pop_back();
-        return value;
-      }
-
-      const_reference remove(size_type index) throw (std::out_of_range) {
-        if (index >= $self->size()) {
-          throw std::out_of_range("Tried to remove element with invalid index.");
-        }
-
-        std::vector< CTYPE >::iterator it = $self->begin() + index;
-        std::vector< CTYPE >::const_reference value = *it;
-        $self->erase(it);
-        return value;
-      }
-    }
-
-    // Wrappers for setting/getting items with the possibly thrown exception
-    // specified (important for SWIG wrapper generation).
-    %extend {
-      const_reference getElement(size_type index) throw (std::out_of_range) {
-        if ((index < 0) || ($self->size() <= index)) {
-          throw std::out_of_range("Tried to get value of element with invalid index.");
-        }
-        return (*$self)[index];
-      }
-    }
-
-    // Use CTYPE const& instead of const_reference to work around SWIG code
-    // generation issue when using const pointers as vector elements (like
-    // std::vector< const int* >).
-    %extend {
-      void setElement(size_type index, CTYPE const& val) throw (std::out_of_range) {
-        if ((index < 0) || ($self->size() <= index)) {
-          throw std::out_of_range("Tried to set value of element with invalid index.");
-        }
-        (*$self)[index] = val;
-      }
-    }
-
-%dmethodmodifiers std::vector::getElement "private"
-%dmethodmodifiers std::vector::setElement "private"
-%dmethodmodifiers std::vector::reserve "private"
-
-#else
 
 %typemap(dimports) std::vector< CTYPE > %{
 static import std.algorithm;
@@ -541,7 +378,6 @@
 
 %dmethodmodifiers std::vector::getElement "private"
 %dmethodmodifiers std::vector::setElement "private"
-#endif
 %enddef
 
 // Extra methods added to the collection class if operator== is defined for the class being wrapped
diff --git a/Lib/d/swigmove.i b/Lib/d/swigmove.i
new file mode 100644
index 0000000..e2eb834
--- /dev/null
+++ b/Lib/d/swigmove.i
@@ -0,0 +1,16 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in, canthrow=1) SWIGTYPE MOVE ($&1_type argp)
+%{ argp = ($&1_ltype)$input;
+   if (!argp) {
+     SWIG_DSetPendingException(SWIG_DIllegalArgumentException, "Attempt to dereference null $1_type");
+     return $null;
+   }
+   SwigValueWrapper< $1_ltype >::reset($1, argp); %}
+
+%typemap(din) SWIGTYPE MOVE "$dclassname.swigRelease($dinput)"
diff --git a/Lib/d/wrapperloader.swg b/Lib/d/wrapperloader.swg
index b3c1d0d..f0f1d1b 100644
--- a/Lib/d/wrapperloader.swg
+++ b/Lib/d/wrapperloader.swg
@@ -40,9 +40,10 @@
   } else {
     version(D_Version2) {
       static import std.conv;
+    } else {
+      static import std.c.string;
     }
     static import std.string;
-    static import std.c.string;
   }
 
   version(D_Version2) {
@@ -112,7 +113,7 @@
     version(Tango) {
       import tango.sys.Common;
     } else version(linux) {
-      import std.c.linux.linux;
+      import core.sys.posix.dlfcn;
     } else {
       extern(C) {
         const RTLD_NOW = 2;
@@ -281,27 +282,19 @@
       "))library.loadSymbol(`" ~ symbol ~ "`);";
   }
 
-  //#if !defined(SWIG_D_NO_EXCEPTION_HELPER)
   mixin(bindCode("swigRegisterExceptionCallbacks$module", "SWIGRegisterExceptionCallbacks_$module"));
-  //#endif // SWIG_D_NO_EXCEPTION_HELPER
-  //#if !defined(SWIG_D_NO_STRING_HELPER)
   mixin(bindCode("swigRegisterStringCallback$module", "SWIGRegisterStringCallback_$module"));
-  //#endif // SWIG_D_NO_STRING_HELPER
   $wrapperloaderbindcode
 }
 
-//#if !defined(SWIG_D_NO_EXCEPTION_HELPER)
 extern(C) void function(
   SwigExceptionCallback exceptionCallback,
   SwigExceptionCallback illegalArgumentCallback,
   SwigExceptionCallback illegalElementCallback,
   SwigExceptionCallback ioCallback,
   SwigExceptionCallback noSuchElementCallback) swigRegisterExceptionCallbacks$module;
-//#endif // SWIG_D_NO_EXCEPTION_HELPER
 
-//#if !defined(SWIG_D_NO_STRING_HELPER)
 extern(C) void function(SwigStringCallback callback) swigRegisterStringCallback$module;
-//#endif // SWIG_D_NO_STRING_HELPER
 %}
 
 %pragma(d) wrapperloaderbindcommand = %{
diff --git a/Lib/exception.i b/Lib/exception.i
index ee9ce9b..1c00fb3 100644
--- a/Lib/exception.i
+++ b/Lib/exception.i
@@ -12,10 +12,15 @@
 %insert("runtime") "swigerrors.swg"
 
 
-#ifdef SWIGPHP7
+#ifdef SWIGPHP
 %{
-#include "zend_exceptions.h"
-#define SWIG_exception(code, msg) do { zend_throw_exception(NULL, (char*)msg, code); goto thrown; } while (0)
+#define SWIG_exception(code, msg) do { zend_throw_exception( \
+    code == SWIG_TypeError ? zend_ce_type_error : \
+    code == SWIG_ValueError ? zend_ce_value_error : \
+    code == SWIG_DivisionByZero ? zend_ce_division_by_zero_error : \
+    code == SWIG_SyntaxError ? zend_ce_parse_error : \
+    code == SWIG_OverflowError ? zend_ce_arithmetic_error : \
+    NULL, msg, code); SWIG_fail; } while (0)
 %}
 #endif
 
@@ -24,9 +29,8 @@
   SWIGINTERN void SWIG_exception_ (int code, const char *msg,
                                const char *subr) {
 #define ERROR(scmerr)					\
-	scm_error(scm_from_locale_string((char *) (scmerr)),	\
-		  (char *) subr, (char *) msg,		\
-		  SCM_EOL, SCM_BOOL_F)
+	scm_error(scm_from_locale_string(scmerr),	\
+		  subr, msg, SCM_EOL, SCM_BOOL_F)
 #define MAP(swigerr, scmerr)			\
 	case swigerr:				\
 	  ERROR(scmerr);			\
diff --git a/Lib/go/argcargv.i b/Lib/go/argcargv.i
new file mode 100644
index 0000000..f2dee2b
--- /dev/null
+++ b/Lib/go/argcargv.i
@@ -0,0 +1,62 @@
+/* -------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------- */
+
+%typemap(gotype) (int ARGC, char **ARGV) "[]string"
+
+%insert(go_wrapper) %{
+//export cgo_swig_get_string_slice_idx
+func cgo_swig_get_string_slice_idx(s []string, i C.swig_intgo) string {
+    return s[i]
+}
+%}
+
+%{
+extern
+#ifdef __cplusplus
+  "C"
+#endif
+_gostring_ cgo_swig_get_string_slice_idx(_goslice_ s, intgo i);
+%}
+
+%typemap(in) (int ARGC, char **ARGV) {
+  $1_ltype len = ($1_ltype)$input.len;
+  size_t aralloc = (size_t)((len + 1) * sizeof(char *));
+  if (len < 0) {
+    _swig_gopanic("negative array length");
+  }
+  $2 = ($2_ltype) Swig_malloc((int)aralloc);
+  if ($2 == NULL) {
+    _swig_gopanic("fail allocating memory for array");
+  }
+  memset($2, 0, aralloc);
+  $1 = len;
+  {
+    $1_ltype i;
+    for (i = 0; i < len; i++) {
+      char *p;
+      _gostring_ st = cgo_swig_get_string_slice_idx($input, (intgo)i);
+      if (st.n < 0) {
+        _swig_gopanic("string length negative");
+      }
+      p = (char *) Swig_malloc((int)(st.n + 1));
+      if (p == NULL) {
+        _swig_gopanic("fail allocating memory for a string");
+      }
+      memcpy(p, st.p, st.n);
+      p[st.n] = 0;
+      $2[i] = p;
+    }
+    $2[i] = NULL;
+  }
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+  if ($2 != NULL) {
+    $1_ltype i;
+    for (i = 0; i < $1; i++) {
+      Swig_free((void *)$2[i]);
+    }
+    Swig_free((void *)$2);
+  }
+}
diff --git a/Lib/go/go.swg b/Lib/go/go.swg
index c225ed9..348ae5f 100644
--- a/Lib/go/go.swg
+++ b/Lib/go/go.swg
@@ -388,8 +388,9 @@
 %typemap(gotype) SWIGTYPE &&
 %{$gotypename%}
 
-%typemap(in) SWIGTYPE &&
-%{ $1 = *($&1_ltype)&$input; %}
+%typemap(in, fragment="<memory>") SWIGTYPE && (std::unique_ptr<$*1_ltype> rvrdeleter)
+%{ $1 = *($&1_ltype)&$input;
+rvrdeleter.reset($1); %}
 
 %typemap(out) SWIGTYPE &&
 %{ *($&1_ltype)&$result = $1; %}
@@ -453,9 +454,12 @@
 %}
 
 %typemap(freearg)
-	char *, char *&, char[ANY], char[]
+	char *, char[ANY], char[]
 %{ free($1); %}
 
+%typemap(freearg) char *&
+%{ free(temp$argnum); %}
+
 %typemap(out,fragment="AllocateString")
 	char *, char *&, char[ANY], char[]
 %{ $result = Swig_AllocateString((char*)$1, $1 ? strlen((char*)$1) : 0); %}
@@ -520,6 +524,44 @@
   $2 = ($2_ltype)$input.n;
 %}
 
+/* The int & type needs to convert to intgo.  */
+
+%typemap(gotype) int & "*int"
+
+%typemap(in) int & (int e)
+%{
+  e = (int)*$input;
+  $1 = &e;
+%}
+
+%typemap(out) int &
+%{ $result = new intgo(*$1); %}
+
+%typemap(argout) int &
+%{ *$input = (intgo)e$argnum; %}
+
+%typemap(goout) int & ""
+
+%typemap(directorin) int & (intgo e)
+%{
+  e = (intgo)$1;
+  $input = &e;
+%}
+
+%typemap(godirectorin) int & ""
+
+%typemap(directorout) int &
+%{
+  $*1_ltype f = ($*1_ltype)*$input;
+  $result = ($1_ltype)&f;
+%}
+
+%typemap(directorargout) int &
+%{ $1 = (int)*$input; %}
+
+%typemap(argout) const int & ""
+%typemap(directorargout) const int & ""
+
 /* Enums.  We can't do the right thing for enums in typemap(gotype) so
    we deliberately don't define them.  The right thing would be to
    capitalize the name.  This is instead done in go.cxx.  */
@@ -552,10 +594,7 @@
 %typemap(godirectorin) enum SWIGTYPE & ""
 
 %typemap(directorout) enum SWIGTYPE &
-%{
-  $*1_ltype f = ($*1_ltype)*$input;
-  $result = ($1_ltype)&f;
-%}
+%{ $result = $input; %}
 
 /* Arbitrary type.  This is a type passed by value in the C/C++ code.
    We convert it to a pointer for the Go code.  Note that all basic
@@ -587,7 +626,7 @@
 %typemap(goout) SWIGTYPE ""
 
 %typemap(directorin) SWIGTYPE
-%{ $input = new $1_ltype((const $1_ltype &)$1); %}
+%{ $input = new $1_ltype(SWIG_STD_MOVE($1)); %}
 
 %typemap(godirectorin) SWIGTYPE ""
 
diff --git a/Lib/go/gokw.swg b/Lib/go/gokw.swg
index dd9f35a..3542830 100644
--- a/Lib/go/gokw.swg
+++ b/Lib/go/gokw.swg
@@ -1,6 +1,6 @@
 /* Rename keywords.  */
 
-#define GOKW(x) %keywordwarn("'" `x` "' is a Go keyword, renaming to 'X"`x`"'",rename="X%s")  `x`
+#define GOKW(x) %keywordwarn("'" `x` "' is a Go keyword",rename="X%s")  `x`
 #define GOBN(x) %builtinwarn("'" `x` "' conflicts with a built-in name in Go")  "::"`x`
 
 GOKW(break);
diff --git a/Lib/go/goruntime.swg b/Lib/go/goruntime.swg
index 269a4ee..7bf083b 100644
--- a/Lib/go/goruntime.swg
+++ b/Lib/go/goruntime.swg
@@ -23,46 +23,39 @@
 
 %}
 
-#if SWIGGO_CGO
 %insert(cgo_comment_typedefs) %{
+#include <stddef.h>
 #include <stdint.h>
 %}
-#endif
 
 #if SWIGGO_INTGO_SIZE == 32
 %insert(runtime) %{
 typedef int intgo;
 typedef unsigned int uintgo;
 %}
-#if SWIGGO_CGO
 %insert(cgo_comment_typedefs) %{
 typedef int intgo;
 typedef unsigned int uintgo;
 %}
-#endif
 #elif SWIGGO_INTGO_SIZE == 64
 %insert(runtime) %{
 typedef long long intgo;
 typedef unsigned long long uintgo;
 %}
-#if SWIGGO_CGO
 %insert(cgo_comment_typedefs) %{
 typedef long long intgo;
 typedef unsigned long long uintgo;
 %}
-#endif
 #else
 %insert(runtime) %{
 typedef ptrdiff_t intgo;
 typedef size_t uintgo;
 %}
-#if SWIGGO_CGO
 %insert(cgo_comment_typedefs) %{
 typedef ptrdiff_t intgo;
 typedef size_t uintgo;
 %}
 #endif
-#endif
 
 #ifndef SWIGGO_GCCGO
 // Set the host compiler struct attribute that will be
@@ -89,8 +82,6 @@
 
 %}
 
-#ifdef SWIGGO_CGO
-
 %insert(cgo_comment_typedefs) %{
 
 typedef struct { char *p; intgo n; } _gostring_;
@@ -98,91 +89,7 @@
 
 %}
 
-#endif
-
-#ifndef SWIGGO_GCCGO
-/* Boilerplate for C/C++ code when using 6g/8g.  This code is compiled
-   with gcc.  */
-%insert(runtime) %{
-
-#define swiggo_size_assert_eq(x, y, name) typedef char name[(x-y)*(x-y)*-2+1];
-#define swiggo_size_assert(t, n) swiggo_size_assert_eq(sizeof(t), n, swiggo_sizeof_##t##_is_not_##n)
-
-swiggo_size_assert(char, 1)
-swiggo_size_assert(short, 2)
-swiggo_size_assert(int, 4)
-typedef long long swiggo_long_long;
-swiggo_size_assert(swiggo_long_long, 8)
-swiggo_size_assert(float, 4)
-swiggo_size_assert(double, 8)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-extern void crosscall2(void (*fn)(void *, int), void *, int);
-extern char* _cgo_topofstack(void) __attribute__ ((weak));
-extern void _cgo_allocate(void *, int);
-extern void _cgo_panic(void *, int);
-#ifdef __cplusplus
-}
-#endif
-
-static char *_swig_topofstack() {
-  if (_cgo_topofstack) {
-    return _cgo_topofstack();
-  } else {
-    return 0;
-  }
-}
-
-static void _swig_gopanic(const char *p) {
-  struct {
-    const char *p;
-  } SWIGSTRUCTPACKED a;
-  a.p = p;
-  crosscall2(_cgo_panic, &a, (int) sizeof a);
-}
-
-%}
-
-#if !SWIGGO_CGO
-
-/* This is here for backward compatibility, but it will not work
-   with Go 1.5 or later.  Do not use it in new code.  */
-%insert(runtime) %{
-
-static void *_swig_goallocate(size_t len) {
-  struct {
-    size_t len;
-    void *ret;
-  } SWIGSTRUCTPACKED a;
-  a.len = len;
-  crosscall2(_cgo_allocate, &a, (int) sizeof a);
-  return a.ret;
-}
-
-%}
-
-#endif
-
-#if !SWIGGO_CGO
-
-/* Boilerplate for C code when using 6g/8g.  This code is compiled
-   with 6c/8c.  */
-%insert(gc_header) %{
-#include "runtime.h"
-#include "cgocall.h"
-
-#pragma dataflag 16
-static void *cgocall = runtime·cgocall;
-#pragma dataflag 16
-void *·_cgo_runtime_cgocall = &cgocall;
-
-%}
-
-#endif
-
-#else
+#ifdef SWIGGO_GCCGO
 
 /* Boilerplate for C/C++ code when using gccgo.  */
 %insert(runtime) %{
@@ -201,115 +108,12 @@
 #define _swig_gopanic _cgo_panic
 %}
 
-#if !SWIGGO_CGO
-
-%insert(runtime) %{
-
-/* Implementations of SwigCgocall and friends for different versions
-   of gccgo.  The Go code will call these functions using C names with
-   a prefix of the module name.  The implementations here call the
-   routine in libgo.  The routines to call vary depending on the gccgo
-   version.  We assume that the version of gcc used to compile this
-   file is the same as the version of gccgo.  */
-
-#ifdef __cplusplus
-extern "C" {
 #endif
 
-#define SWIG_GCC_VERSION \
-  (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
-
-#if SWIG_GCC_VERSION < 40700
-#define SwigDoCgocall()
-#define SwigDoCgocallDone()
-#define SwigDoCgocallBack()
-#define SwigDoCgocallBackDone()
-#elif SWIG_GCC_VERSION == 40700
-void SwigDoCgocall(void) __asm__("libgo_syscall.syscall.Entersyscall");
-void SwigDoCgocallDone(void) __asm__("libgo_syscall.syscall.Exitsyscall");
-void SwigDoCgocallBack(void) __asm__("libgo_syscall.syscall.Exitsyscall");
-void SwigDoCgocallBackDone(void) __asm__("libgo_syscall.syscall.Entersyscall");
-#else
-void SwigDoCgocall(void) __asm__("syscall.Cgocall");
-void SwigDoCgocallDone(void) __asm__("syscall.CgocallDone");
-void SwigDoCgocallBack(void) __asm__("syscall.CgocallBack");
-void SwigDoCgocallBackDone(void) __asm__("syscall.CgocallBackDone");
-#endif
-
-#define SWIGSTRINGIFY2(s) #s
-#define SWIGSTRINGIFY(s) SWIGSTRINGIFY2(s)
-
-void SwigCgocall()
-  __asm__(SWIGSTRINGIFY(SWIGGO_PREFIX) ".SwigCgocall");
-void SwigCgocall() {
-  SwigDoCgocall();
-}
-
-void SwigCgocallDone()
-  __asm__(SWIGSTRINGIFY(SWIGGO_PREFIX) ".SwigCgocallDone");
-void SwigCgocallDone() {
-  SwigDoCgocallDone();
-}
-
-void SwigCgocallBack()
-  __asm__(SWIGSTRINGIFY(SWIGGO_PREFIX) ".SwigCgocallBack");
-void SwigCgocallBack() {
-  SwigDoCgocallBack();
-}
-
-void SwigCgocallBackDone()
-  __asm__(SWIGSTRINGIFY(SWIGGO_PREFIX) ".SwigCgocallBackDone");
-void SwigCgocallBackDone() {
-  SwigDoCgocallBackDone();
-}
-
-#undef SWIGSTRINGIFY
-#undef SWIGSTRINGIFY2
-
-#ifdef __cplusplus
-}
-#endif
-
-%}
-
-#endif
-
-#endif
-
-#if !SWIGGO_CGO
-
-%insert(runtime) %{
-
-/* This is here for backward compatibility, but it will not work
-   with Go 1.5 or later.  Do not use it in new code.  */
-static _gostring_ _swig_makegostring(const char *p, size_t l) {
-  _gostring_ ret;
-  ret.p = (char*)_swig_goallocate(l + 1);
-  memcpy(ret.p, p, l);
-  ret.n = l;
-  return ret;
-}
-
-%}
-
-#endif
-
-%insert(runtime) %{
-
-#define SWIG_contract_assert(expr, msg) \
-  if (!(expr)) { _swig_gopanic(msg); } else
-%}
-
 #ifndef SWIGGO_GCCGO
 
 %go_import("unsafe", _ "runtime/cgo")
 
-#if !SWIGGO_CGO
-%insert(go_header) %{
-var _cgo_runtime_cgocall func(unsafe.Pointer, uintptr)
-%}
-#endif
-
 #else
 
 %go_import("syscall", "unsafe")
@@ -346,6 +150,17 @@
 type _swig_memberptr *byte
 %}
 
+/* Convert a Go interface value into a C++ pointer.  */
+
+%insert(go_header) %{
+func getSwigcptr(v interface { Swigcptr() uintptr }) uintptr {
+	if v == nil {
+		return 0
+	}
+	return v.Swigcptr()
+}
+%}
+
 /* For directors we need C++ to track a Go pointer.  Since we can't
    pass a Go pointer into C++, we use a map to track the pointers on
    the Go side.  */
diff --git a/Lib/go/std_array.i b/Lib/go/std_array.i
new file mode 100644
index 0000000..36c790e
--- /dev/null
+++ b/Lib/go/std_array.i
@@ -0,0 +1,43 @@
+/* -----------------------------------------------------------------------------
+ * std_array.i
+ * ----------------------------------------------------------------------------- */
+
+%include <std_common.i>
+
+namespace std {
+
+  template<class T, size_t N> class array {
+  public:
+    typedef size_t size_type;
+    typedef ptrdiff_t difference_type;
+    typedef T value_type;
+    typedef value_type* pointer;
+    typedef const value_type* const_pointer;
+    typedef value_type& reference;
+    typedef const value_type& const_reference;
+
+    array();
+    array(const array& other);
+
+    size_type size() const;
+    %rename(isEmpty) empty;
+    bool empty() const;
+    void fill(const T& u);
+    %extend {
+      const_reference get(int i) throw (std::out_of_range) {
+        int size = int(self->size());
+        if (i>=0 && i<size)
+          return (*self)[i];
+        else
+          throw std::out_of_range("array index out of range");
+      }
+      void set(int i, const value_type& val) throw (std::out_of_range) {
+        int size = int(self->size());
+        if (i>=0 && i<size)
+          (*self)[i] = val;
+        else
+          throw std::out_of_range("array index out of range");
+      }
+    }
+  };
+}
diff --git a/Lib/go/std_map.i b/Lib/go/std_map.i
index 773b6d0..19281ad 100644
--- a/Lib/go/std_map.i
+++ b/Lib/go/std_map.i
@@ -48,7 +48,11 @@
                     throw std::out_of_range("key not found");
             }
             void set(const K& key, const T& x) {
+%#ifdef __cpp_lib_map_try_emplace
+                (*self).insert_or_assign(key, x);
+%#else
                 (*self)[key] = x;
+%#endif
             }
             void del(const K& key) throw (std::out_of_range) {
                 std::map< K, T, C >::iterator i = self->find(key);
diff --git a/Lib/go/std_string.i b/Lib/go/std_string.i
index 099ae84..35b4a5e 100644
--- a/Lib/go/std_string.i
+++ b/Lib/go/std_string.i
@@ -52,6 +52,9 @@
 %typemap(godirectorin,fragment="CopyString") string
 %{ $result = swigCopyString($input) %}
 
+%typemap(throws) string
+%{ _swig_gopanic($1.c_str()); %}
+
 %typemap(in) const string &
 %{
   $*1_ltype $1_str($input.p, $input.n);
@@ -88,4 +91,72 @@
 %typemap(godirectorin,fragment="CopyString") const string &
 %{ $result = swigCopyString($input) %}
 
+%typemap(throws) const string &
+%{ _swig_gopanic($1.c_str()); %}
+
+
+%typemap(gotype) string * "*string"
+
+%typemap(in) string * (string temp)
+%{
+  if ($input) {
+    temp.assign($input->p, $input->n);
+    $1 = &temp;
+  } else
+    $1 = 0;
+%}
+
+%typemap(godirectorout) string *
+%{
+  if $input != nil {
+    p := Swig_malloc(len(*$input))
+    s := (*[1<<30]byte)(unsafe.Pointer(p))[:len(*$input)]
+    copy(s, *$input)
+    $result = (*string)(unsafe.Pointer(&s))
+  } else {
+    $result = nil
+  }
+%}
+
+%typemap(directorout) string * (string temp)
+%{
+  temp.assign($input->p, $input->n);
+  $result = &temp;
+  free($input.p);
+%}
+
+%typemap(out,fragment="AllocateString") string * (_gostring_ temp)
+%{
+  temp = Swig_AllocateString($1->data(), $1->length());
+  $result = &temp;
+%}
+
+%typemap(goout,fragment="CopyString") string *
+%{ *$result = swigCopyString(*$1) %}
+
+%typemap(directorin,fragment="AllocateString") string * (_gostring_ temp)
+%{
+  if ($1) {
+    temp = Swig_AllocateString($1->data(), $1->length());
+    $input = &temp;
+  } else
+    $input = 0;
+%}
+
+%typemap(godirectorin,fragment="CopyString") string *
+%{ *$result = swigCopyString(*$input); %}
+
+%typemap(argout,fragment="AllocateString") string *
+%{
+  if ($1)
+    *$input = Swig_AllocateString($1->data(), $1->length());
+%}
+
+%typemap(goargout,fragment="CopyString") string *
+%{
+  if $input != nil {
+    *$1 = swigCopyString(*$input)
+  }
+%}
+
 }
diff --git a/Lib/go/swigmove.i b/Lib/go/swigmove.i
new file mode 100644
index 0000000..e1984b6
--- /dev/null
+++ b/Lib/go/swigmove.i
@@ -0,0 +1,15 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in) SWIGTYPE MOVE ($&1_type argp)
+%{
+  argp = ($&1_ltype)$input;
+  if (argp == NULL) {
+    _swig_gopanic("Attempt to dereference null $1_type");
+  }
+  SwigValueWrapper< $1_ltype >::reset($1, argp);
+%}
diff --git a/Lib/guile/argcargv.i b/Lib/guile/argcargv.i
new file mode 100644
index 0000000..003be96
--- /dev/null
+++ b/Lib/guile/argcargv.i
@@ -0,0 +1,44 @@
+/* -------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------- */
+
+%typemap(in) (int ARGC, char **ARGV) {
+  $1_ltype i, len;
+  SWIG_contract_assert($input != (SCM)0 &&
+                       !scm_is_null($input) &&
+                       scm_is_array($input),
+                       "you must pass array of strings");
+  len = scm_c_array_length($input);
+  $1 = len;
+  $2 = ($2_ltype) malloc((len+1)*sizeof($*2_ltype));
+  if ($2 == NULL) {
+    scm_misc_error(FUNC_NAME, "fail allocating memory for array", SCM_EOL);
+  }
+  for (i = 0; i < len; i++) {
+    SCM args = scm_list_1(scm_from_long(i));
+    SCM str = scm_array_ref($input, args);
+    SWIG_contract_assert(scm_is_string(str), "elements in array must be strings");
+    $2[i] = ($*2_ltype)SWIG_scm2str(str);
+  }
+  $2[i] = NULL;
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+  if ($input != (SCM)0 && !scm_is_null($input) && scm_is_array($input)) {
+    size_t len = scm_c_array_length($input);
+    size_t i;
+    for(i = 0; i < len; i++) {
+      SCM args = scm_list_1(scm_from_long(i));
+      SCM str = scm_array_ref($input, args);
+      if (!scm_is_string(str)) {
+        break;
+      }
+    }
+    /* All elements are strings! */
+    $1 = (i == len);
+  }
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+  free((void *)$2);
+}
diff --git a/Lib/guile/guile_scm_run.swg b/Lib/guile/guile_scm_run.swg
index 86e5c3b..89eda39 100644
--- a/Lib/guile/guile_scm_run.swg
+++ b/Lib/guile/guile_scm_run.swg
@@ -2,6 +2,12 @@
  * guile_scm_run.swg
  * ----------------------------------------------------------------------------- */
 
+#if __GNUC__ >= 10
+#if defined(__cplusplus)
+#pragma GCC diagnostic ignored "-Wvolatile" /* For 'volatile SCM *' in at least Guile 3.0 and earlier */
+#endif
+#endif
+
 #include <libguile.h>
 #include <stdio.h>
 #include <string.h>
@@ -65,10 +71,11 @@
 #define SWIG_IsPointer(object) \
   SWIG_Guile_IsPointer(object)
 #define SWIG_contract_assert(expr, msg)				\
-  if (!(expr))							\
-    scm_error(scm_from_locale_symbol("swig-contract-assertion-failed"),	\
-	      (char *) FUNC_NAME, (char *) msg,			\
-	      SCM_EOL, SCM_BOOL_F); else
+  do { \
+    if (!(expr))							\
+      scm_error(scm_from_locale_symbol("swig-contract-assertion-failed"),	\
+                FUNC_NAME, msg, SCM_EOL, SCM_BOOL_F); \
+  } while (0)
 
 /* for C++ member pointers, ie, member methods */
 #define SWIG_ConvertMember(obj, ptr, sz, ty) \
@@ -110,6 +117,8 @@
   ( !scm_is_null(x) && SCM_INSTANCEP(x) && scm_is_true(scm_slot_exists_p(x, swig_symbol)) \
       ? scm_slot_ref(x, swig_symbol) : (x) )
 
+SWIGINTERN void SWIG_Guile_MarkPointerNoncollectable(SCM s);
+
 SWIGINTERN SCM
 SWIG_Guile_NewPointerObj(void *ptr, swig_type_info *type, int owner)
 {
@@ -123,7 +132,7 @@
     else
       SCM_NEWSMOB2(smob, swig_tag, ptr, (void *) type);
 
-    if (!cdata || SCM_NULLP(cdata->goops_class) || swig_make_func == SCM_EOL ) {
+    if (!cdata || scm_is_null(cdata->goops_class) || swig_make_func == SCM_EOL ) {
       return smob;
     } else {
       /* the scm_make() C function only handles the creation of gf,
@@ -143,7 +152,7 @@
 SWIG_Guile_PointerAddress(SCM object)
 {
   SCM smob = SWIG_Guile_GetSmob(object);
-  if (SCM_NULLP(smob)) return 0;
+  if (scm_is_null(smob)) return 0;
   else if (SCM_SMOB_PREDICATE(swig_tag, smob)
 	   || SCM_SMOB_PREDICATE(swig_collectable_tag, smob)
 	   || SCM_SMOB_PREDICATE(swig_destroyed_tag, smob)) {
@@ -156,7 +165,7 @@
 SWIG_Guile_PointerType(SCM object)
 {
   SCM smob = SWIG_Guile_GetSmob(object);
-  if (SCM_NULLP(smob)) return NULL;
+  if (scm_is_null(smob)) return NULL;
   else if (SCM_SMOB_PREDICATE(swig_tag, smob)
 	   || SCM_SMOB_PREDICATE(swig_collectable_tag, smob)
 	   || SCM_SMOB_PREDICATE(swig_destroyed_tag, smob)) {
@@ -183,8 +192,9 @@
   swig_cast_info *cast;
   swig_type_info *from;
   SCM smob = SWIG_Guile_GetSmob(s);
+  int ret = SWIG_ERROR;
 
-  if (SCM_NULLP(smob)) {
+  if (scm_is_null(smob)) {
     *result = NULL;
     return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
 #if SCM_MAJOR_VERSION >= 2
@@ -195,22 +205,36 @@
   } else if (SWIG_Guile_IsValidSmob(smob)) {
     from = (swig_type_info *) SCM_CELL_WORD_2(smob);
     if (!from) return SWIG_ERROR;
+
+    if ((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) {
+      if ((SCM_CELL_TYPE(smob) == swig_collectable_tag && SCM_CELL_WORD_1(smob) == 0) || SCM_CELL_TYPE(smob) == swig_tag) {
+        return SWIG_ERROR_RELEASE_NOT_OWNED;
+      }
+    }
+
     if (type) {
       cast = SWIG_TypeCheckStruct(from, type);
       if (cast) {
         int newmemory = 0;
         *result = SWIG_TypeCast(cast, (void *) SCM_CELL_WORD_1(smob), &newmemory);
         assert(!newmemory); /* newmemory handling not yet implemented */
-        return SWIG_OK;
+        ret = SWIG_OK;
       } else {
         return SWIG_ERROR;
       }
     } else {
       *result = (void *) SCM_CELL_WORD_1(smob);
-      return SWIG_OK;
+      ret = SWIG_OK;
+    }
+
+    if (flags & SWIG_POINTER_DISOWN) {
+      SWIG_Guile_MarkPointerNoncollectable(smob);
+    }
+    if (flags & SWIG_POINTER_CLEAR) {
+      SCM_SET_CELL_WORD_1(smob, 0);
     }
   }
-  return SWIG_ERROR;
+  return ret;
 }
 
 SWIGINTERNINLINE void *
@@ -221,7 +245,7 @@
   int res = SWIG_Guile_ConvertPtr(s, &result, type, flags);
   if (!SWIG_IsOK(res)) {
     /* type mismatch */
-    scm_wrong_type_arg((char *) func_name, argnum, s);
+    scm_wrong_type_arg(func_name, argnum, s);
   }
   return result;
 }
@@ -250,7 +274,7 @@
 SWIG_Guile_MarkPointerNoncollectable(SCM s)
 {
   SCM smob = SWIG_Guile_GetSmob(s);
-  if (!SCM_NULLP(smob)) {
+  if (!scm_is_null(smob)) {
     if (SWIG_Guile_IsValidSmob(smob)) {
       SCM_SET_CELL_TYPE(smob, swig_tag);
     }
@@ -263,7 +287,7 @@
 SWIG_Guile_MarkPointerDestroyed(SCM s)
 {
   SCM smob = SWIG_Guile_GetSmob(s);
-  if (!SCM_NULLP(smob)) {
+  if (!scm_is_null(smob)) {
     if (SWIG_Guile_IsValidSmob(smob)) {
       SCM_SET_CELL_TYPE(smob, swig_destroyed_tag);
     }
@@ -315,13 +339,13 @@
   
   type = (swig_type_info *) SCM_CELL_WORD_2(swig_smob);
   if (type) {
-    scm_puts((char *) "#<", port);
-    scm_puts((char *) attribute, port);
-    scm_puts((char *) "swig-pointer ", port);
-    scm_puts((char *) SWIG_TypePrettyName(type), port);
-    scm_puts((char *) " ", port);
+    scm_puts("#<", port);
+    scm_puts(attribute, port);
+    scm_puts("swig-pointer ", port);
+    scm_puts(SWIG_TypePrettyName(type), port);
+    scm_puts(" ", port);
     scm_intprint((long) SCM_CELL_WORD_1(swig_smob), 16, port);
-    scm_puts((char *) ">", port);
+    scm_puts(">", port);
     /* non-zero means success */
     return 1;
   } else {
@@ -354,10 +378,10 @@
   swig_type_info *type;
   type = (swig_type_info *) SCM_CELL_WORD_2(swig_smob);
   if (type) {
-    scm_puts((char *) "#<", port);
-    scm_puts((char *) "swig-member-function-pointer ", port);
-    scm_puts((char *) SWIG_TypePrettyName(type), port);
-    scm_puts((char *) " >", port);
+    scm_puts("#<", port);
+    scm_puts("swig-member-function-pointer ", port);
+    scm_puts(SWIG_TypePrettyName(type), port);
+    scm_puts(" >", port);
     /* non-zero means success */
     return 1;
   } else {
@@ -401,7 +425,7 @@
   SCM variable = scm_module_variable(swig_module,
                              scm_from_locale_symbol(scheme_variable_name));
   if (scm_is_false(variable)) {
-    *tag_variable = scm_make_smob_type((char*)scheme_variable_name, 0);
+    *tag_variable = scm_make_smob_type(scheme_variable_name, 0);
     scm_c_module_define(swig_module, scheme_variable_name, 
                         scm_from_ulong(*tag_variable));
     return 1;
@@ -446,7 +470,7 @@
   }
   swig_make_func = scm_permanent_object(
   scm_variable_ref(scm_c_module_lookup(scm_c_resolve_module("oop goops"), "make")));
-  swig_keyword = scm_permanent_object(scm_from_locale_keyword((char*) "init-smob"));
+  swig_keyword = scm_permanent_object(scm_from_locale_keyword("init-smob"));
   swig_symbol = scm_permanent_object(scm_from_locale_symbol("swig-smob"));
 #ifdef SWIG_INIT_RUNTIME_MODULE
   SWIG_INIT_RUNTIME_MODULE
@@ -484,21 +508,21 @@
   int i;
   int num_args_passed = 0;
   for (i = 0; i<reqargs; i++) {
-    if (!SCM_CONSP(rest))
-      scm_wrong_num_args(scm_from_utf8_string(procname ? (char *) procname : "unknown procedure"));
+    if (!scm_is_pair(rest))
+      scm_wrong_num_args(scm_from_utf8_string(procname ? procname : "unknown procedure"));
     *dest++ = SCM_CAR(rest);
     rest = SCM_CDR(rest);
     num_args_passed++;
   }
-  for (i = 0; i<optargs && SCM_CONSP(rest); i++) {
+  for (i = 0; i<optargs && scm_is_pair(rest); i++) {
     *dest++ = SCM_CAR(rest);
     rest = SCM_CDR(rest);
     num_args_passed++;
   }
   for (; i<optargs; i++)
     *dest++ = SCM_UNDEFINED;
-  if (!SCM_NULLP(rest))
-      scm_wrong_num_args(scm_from_utf8_string(procname ? (char *) procname : "unknown procedure"));
+  if (!scm_is_null(rest))
+      scm_wrong_num_args(scm_from_utf8_string(procname ? procname : "unknown procedure"));
   return num_args_passed;
 }
 
diff --git a/Lib/guile/list-vector.i b/Lib/guile/list-vector.i
index 057a1da..b6530d1 100644
--- a/Lib/guile/list-vector.i
+++ b/Lib/guile/list-vector.i
@@ -107,7 +107,7 @@
                      (size_t VECTORLENINPUT, C_TYPE *VECTORINPUT),
                      (int LISTLENINPUT, C_TYPE *LISTINPUT),
                      (size_t LISTLENINPUT, C_TYPE *LISTINPUT)
-       {if ($2!=NULL) SWIG_free($2);}
+       {SWIG_free($2);}
 
 %enddef
 
@@ -173,7 +173,7 @@
 	  (int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT),
 	  (size_t *LISTLENOUTPUT, C_TYPE **LISTOUTPUT)
      {
-        if ((*$2)!=NULL) free(*$2);
+       free(*$2);
      }
 
 %enddef
@@ -231,7 +231,7 @@
 	 if ((*$2)!=NULL) {
 	     int i;
 	     for (i = 0; i < *$1; i++) {
-		 if ((*$2)[i] != NULL) free((*$2)[i]);
+		 free((*$2)[i]);
 	     }
 	     free(*$2);
 	 }
@@ -249,7 +249,7 @@
     if (($2)!=NULL) {
 	int i;
 	for (i = 0; i< $1; i++)
-	    if (($2)[i] != NULL) free(($2)[i]);
+	    free(($2)[i]);
 	free($2);
     }
 }
@@ -283,8 +283,7 @@
   /* input */
      
      /* Passing data is a little complicated here; just remember:
-	IGNORE typemaps come first, then IN, then CHECK.  But if
-	IGNORE is given, IN won't be used for this type.
+	IN typemaps come first, then CHECK.
 
 	We need to "ignore" one of the parameters because there shall
 	be only one argument on the Scheme side.  Here we only
@@ -360,7 +359,7 @@
 		       const C_TYPE *PARALLEL_VECTORINPUT,
 		       C_TYPE *PARALLEL_LISTINPUT, 
 		       const C_TYPE *PARALLEL_LISTINPUT
-       {if ($1!=NULL) SWIG_free($1);}
+       {SWIG_free($1);}
 
 %enddef
 
@@ -422,7 +421,7 @@
      %typemap(freearg) C_TYPE **PARALLEL_VECTOROUTPUT, 
 		       C_TYPE **PARALLEL_LISTOUTPUT
      {
-        if ((*$1)!=NULL) free(*$1);
+       free(*$1);
      }
 
 %enddef
@@ -471,7 +470,7 @@
     if (($1)!=NULL) {
 	int i;
 	for (i = 0; i<*_global_list_length; i++)
-	    if (($1)[i] != NULL) SWIG_free(($1)[i]);
+	    SWIG_free(($1)[i]);
 	SWIG_free($1);
     }
 }
@@ -482,7 +481,7 @@
     if ((*$1)!=NULL) {
 	int i;
 	for (i = 0; i<_global_arraylentemp; i++)
-	    if ((*$1)[i] != NULL) free((*$1)[i]);
+	    free((*$1)[i]);
 	free(*$1);
     }
 }
diff --git a/Lib/guile/pointer-in-out.i b/Lib/guile/pointer-in-out.i
index d8a631c..8010030 100644
--- a/Lib/guile/pointer-in-out.i
+++ b/Lib/guile/pointer-in-out.i
@@ -37,7 +37,6 @@
 
        Likewise, but make the pointer object not garbage collectable.
    
-   func(int **BOTH)
    func(int **INOUT)
 
        This annotation combines INPUT and OUTPUT.
@@ -82,8 +81,6 @@
 %typemap(argout, doc="<" #SCM_TYPE ">") PTRTYPE *OUTPUT_NONCOLLECTABLE
      "SWIG_APPEND_VALUE(SWIG_NewPointerObj(*$1, $*descriptor, 0));"; 
 
-%typemap(in) PTRTYPE *BOTH = PTRTYPE *INPUT;
-%typemap(argout) PTRTYPE *BOTH = PTRTYPE *OUTPUT;
 %typemap(in) PTRTYPE *INOUT = PTRTYPE *INPUT;
 %typemap(argout) PTRTYPE *INOUT = PTRTYPE *OUTPUT;
 
diff --git a/Lib/guile/std_auto_ptr.i b/Lib/guile/std_auto_ptr.i
new file mode 100644
index 0000000..59d5c0e
--- /dev/null
+++ b/Lib/guile/std_auto_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      scm_misc_error(FUNC_NAME, "Cannot release ownership as memory is not owned for argument $argnum of type 'TYPE *'", SCM_EOL);
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+  %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class auto_ptr {};
+}
diff --git a/Lib/guile/std_common.i b/Lib/guile/std_common.i
index 5899c55..9797449 100644
--- a/Lib/guile/std_common.i
+++ b/Lib/guile/std_common.i
@@ -19,7 +19,7 @@
     char* temp;
     temp = SWIG_scm2str(x);
     std::string s(temp);
-    if (temp) SWIG_free(temp);
+    SWIG_free(temp);
     return s;
 }
 %}
diff --git a/Lib/guile/std_map.i b/Lib/guile/std_map.i
index f84e78b..6fb9bca 100644
--- a/Lib/guile/std_map.i
+++ b/Lib/guile/std_map.i
@@ -5,6 +5,7 @@
  * ----------------------------------------------------------------------------- */
 
 %include <std_common.i>
+%include <exception.i>
 
 // ------------------------------------------------------------------------
 // std::map
@@ -64,7 +65,11 @@
                         val = SCM_CAR(val);
                         x = (T*) SWIG_MustGetPtr(val,$descriptor(T *),$argnum, 0);
                     }
+%#ifdef __cpp_lib_map_try_emplace
+                    (($1_type &)$1).insert_or_assign(*k, *x);
+%#else
                     (($1_type &)$1)[*k] = *x;
+%#endif
                     alist = SCM_CDR(alist);
                 }
             } else {
@@ -98,7 +103,11 @@
                         val = SCM_CAR(val);
                         x = (T*) SWIG_MustGetPtr(val,$descriptor(T *),$argnum, 0);
                     }
+%#ifdef __cpp_lib_map_try_emplace
+                    temp.insert_or_assign(*k, *x);
+%#else
                     temp[*k] = *x;
+%#endif
                     alist = SCM_CDR(alist);
                 }
             } else {
@@ -239,7 +248,11 @@
                     throw std::out_of_range("key not found");
             }
             void __setitem__(const K& key, const T& x) {
+%#ifdef __cpp_lib_map_try_emplace
+                (*self).insert_or_assign(key, x);
+%#else
                 (*self)[key] = x;
+%#endif
             }
             void __delitem__(const K& key) throw (std::out_of_range) {
                 std::map< K, T, C >::iterator i = self->find(key);
@@ -264,1107 +277,4 @@
         }
     };
 
-
-    // specializations for built-ins
-
-    %define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO)
-
-    template<class T> class map< K, T, C > {
-        %typemap(in) map< K, T, C > {
-            if (scm_is_null($input)) {
-                $1 = std::map< K, T, C >();
-            } else if (scm_is_pair($input)) {
-                $1 = std::map< K, T, C >();
-                SCM alist = $input;
-                while (!scm_is_null(alist)) {
-                    T* x;
-                    SCM entry, key, val;
-                    entry = SCM_CAR(alist);
-                    if (!scm_is_pair(entry))
-                        SWIG_exception(SWIG_TypeError,"alist expected");
-                    key = SCM_CAR(entry);
-                    val = SCM_CDR(entry);
-                    if (!CHECK(key))
-                        SWIG_exception(SWIG_TypeError,
-                                       "map<" #K "," #T "," #C "> expected");
-                    if (SWIG_ConvertPtr(val,(void**) &x,
-                                    $descriptor(T *), 0) != 0) {
-                        if (!scm_is_pair(val))
-                            SWIG_exception(SWIG_TypeError,"alist expected");
-                        val = SCM_CAR(val);
-                        x = (T*) SWIG_MustGetPtr(val,$descriptor(T *),$argnum, 0);
-                    }
-                    (($1_type &)$1)[CONVERT_FROM(key)] = *x;
-                    alist = SCM_CDR(alist);
-                }
-            } else {
-                $1 = *(($&1_type)
-                       SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0));
-            }
-        }
-        %typemap(in) const map< K, T, C >& (std::map< K, T, C > temp),
-                     const map< K, T, C >* (std::map< K, T, C > temp) {
-            if (scm_is_null($input)) {
-                temp = std::map< K, T, C >();
-                $1 = &temp;
-            } else if (scm_is_pair($input)) {
-                temp = std::map< K, T, C >();
-                $1 = &temp;
-                SCM alist = $input;
-                while (!scm_is_null(alist)) {
-                    T* x;
-                    SCM entry, key, val;
-                    entry = SCM_CAR(alist);
-                    if (!scm_is_pair(entry))
-                        SWIG_exception(SWIG_TypeError,"alist expected");
-                    key = SCM_CAR(entry);
-                    val = SCM_CDR(entry);
-                    if (!CHECK(key))
-                        SWIG_exception(SWIG_TypeError,
-                                       "map<" #K "," #T "," #C "> expected");
-                    if (SWIG_ConvertPtr(val,(void**) &x,
-                                    $descriptor(T *), 0) != 0) {
-                        if (!scm_is_pair(val))
-                            SWIG_exception(SWIG_TypeError,"alist expected");
-                        val = SCM_CAR(val);
-                        x = (T*) SWIG_MustGetPtr(val,$descriptor(T *),$argnum, 0);
-                    }
-                    temp[CONVERT_FROM(key)] = *x;
-                    alist = SCM_CDR(alist);
-                }
-            } else {
-                $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0);
-            }
-        }
-        %typemap(out) map< K, T, C > {
-            SCM alist = SCM_EOL;
-            for (std::map< K, T, C >::reverse_iterator i=$1.rbegin(); i!=$1.rend(); ++i) {
-                T* val = new T(i->second);
-                SCM k = CONVERT_TO(i->first);
-                SCM x = SWIG_NewPointerObj(val,$descriptor(T *), 1);
-                SCM entry = scm_cons(k,x);
-                alist = scm_cons(entry,alist);
-            }
-            $result = alist;
-        }
-        %typecheck(SWIG_TYPECHECK_MAP) map< K, T, C > {
-            // native sequence?
-            if (scm_is_null($input)) {
-                /* an empty sequence can be of any type */
-                $1 = 1;
-            } else if (scm_is_pair($input)) {
-                // check the first element only
-                T* x;
-                SCM head = SCM_CAR($input);
-                if (scm_is_pair(head)) {
-                    SCM key = SCM_CAR(head);
-                    SCM val = SCM_CDR(head);
-                    if (!CHECK(key)) {
-                        $1 = 0;
-                    } else {
-                        if (SWIG_ConvertPtr(val,(void**) &x,
-                                        $descriptor(T *), 0) == 0) {
-                            $1 = 1;
-                        } else if (scm_is_pair(val)) {
-                            val = SCM_CAR(val);
-                            if (SWIG_ConvertPtr(val,(void**) &x,
-                                            $descriptor(T *), 0) == 0)
-                                $1 = 1;
-                            else
-                                $1 = 0;
-                        } else {
-                            $1 = 0;
-                        }
-                    }
-                } else {
-                    $1 = 0;
-                }
-            } else {
-                // wrapped map?
-                std::map< K, T, C >* m;
-                if (SWIG_ConvertPtr($input,(void **) &m,
-                                $&1_descriptor, 0) == 0)
-                    $1 = 1;
-                else
-                    $1 = 0;
-            }
-        }
-        %typecheck(SWIG_TYPECHECK_MAP) const map< K, T, C >&,
-                                       const map< K, T, C >* {
-            // native sequence?
-            if (scm_is_null($input)) {
-                /* an empty sequence can be of any type */
-                $1 = 1;
-            } else if (scm_is_pair($input)) {
-                // check the first element only
-                T* x;
-                SCM head = SCM_CAR($input);
-                if (scm_is_pair(head)) {
-                    SCM key = SCM_CAR(head);
-                    SCM val = SCM_CDR(head);
-                    if (!CHECK(key)) {
-                        $1 = 0;
-                    } else {
-                        if (SWIG_ConvertPtr(val,(void**) &x,
-                                        $descriptor(T *), 0) == 0) {
-                            $1 = 1;
-                        } else if (scm_is_pair(val)) {
-                            val = SCM_CAR(val);
-                            if (SWIG_ConvertPtr(val,(void**) &x,
-                                            $descriptor(T *), 0) == 0)
-                                $1 = 1;
-                            else
-                                $1 = 0;
-                        } else {
-                            $1 = 0;
-                        }
-                    }
-                } else {
-                    $1 = 0;
-                }
-            } else {
-                // wrapped map?
-                std::map< K, T, C >* m;
-                if (SWIG_ConvertPtr($input,(void **) &m,
-                                $1_descriptor, 0) == 0)
-                    $1 = 1;
-                else
-                    $1 = 0;
-            }
-        }
-        %rename("length") size;
-        %rename("null?") empty;
-        %rename("clear!") clear;
-        %rename("ref") __getitem__;
-        %rename("set!") __setitem__;
-        %rename("delete!") __delitem__;
-        %rename("has-key?") has_key;
-      public:
-        typedef size_t size_type;
-        typedef ptrdiff_t difference_type;
-        typedef K key_type;
-        typedef T mapped_type;
-        typedef std::pair< const K, T > value_type;
-        typedef value_type* pointer;
-        typedef const value_type* const_pointer;
-        typedef value_type& reference;
-        typedef const value_type& const_reference;
-
-        map();
-        map(const map& other);
-        
-        unsigned int size() const;
-        bool empty() const;
-        void clear();
-        %extend {
-            T& __getitem__(K key) throw (std::out_of_range) {
-                std::map< K, T, C >::iterator i = self->find(key);
-                if (i != self->end())
-                    return i->second;
-                else
-                    throw std::out_of_range("key not found");
-            }
-            void __setitem__(K key, const T& x) {
-                (*self)[key] = x;
-            }
-            void __delitem__(K key) throw (std::out_of_range) {
-                std::map< K, T, C >::iterator i = self->find(key);
-                if (i != self->end())
-                    self->erase(i);
-                else
-                    throw std::out_of_range("key not found");
-            }
-            bool has_key(K key) {
-                std::map< K, T, C >::iterator i = self->find(key);
-                return i != self->end();
-            }
-            SCM keys() {
-                SCM result = SCM_EOL;
-                for (std::map< K, T, C >::reverse_iterator i=self->rbegin(); i!=self->rend(); ++i) {
-                    SCM k = CONVERT_TO(i->first);
-                    result = scm_cons(k,result);
-                }
-                return result;
-            }
-        }
-    };
-    %enddef
-
-    %define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO)
-    template<class K> class map< K, T, C > {
-        %typemap(in) map< K, T, C > {
-            if (scm_is_null($input)) {
-                $1 = std::map< K, T, C >();
-            } else if (scm_is_pair($input)) {
-                $1 = std::map< K, T, C >();
-                SCM alist = $input;
-                while (!scm_is_null(alist)) {
-                    K* k;
-                    SCM entry, key, val;
-                    entry = SCM_CAR(alist);
-                    if (!scm_is_pair(entry))
-                        SWIG_exception(SWIG_TypeError,"alist expected");
-                    key = SCM_CAR(entry);
-                    val = SCM_CDR(entry);
-                    k = (K*) SWIG_MustGetPtr(key,$descriptor(K *),$argnum, 0);
-                    if (!CHECK(val)) {
-                        if (!scm_is_pair(val))
-                            SWIG_exception(SWIG_TypeError,"alist expected");
-                        val = SCM_CAR(val);
-                        if (!CHECK(val))
-                            SWIG_exception(SWIG_TypeError,
-                                           "map<" #K "," #T "," #C "> expected");
-                    }
-                    (($1_type &)$1)[*k] = CONVERT_FROM(val);
-                    alist = SCM_CDR(alist);
-                }
-            } else {
-                $1 = *(($&1_type)
-                       SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0));
-            }
-        }
-        %typemap(in) const map< K, T, C >& (std::map< K, T, C > temp),
-                     const map< K, T, C >* (std::map< K, T, C > temp) {
-            if (scm_is_null($input)) {
-                temp = std::map< K, T, C >();
-                $1 = &temp;
-            } else if (scm_is_pair($input)) {
-                temp = std::map< K, T, C >();
-                $1 = &temp;
-                SCM alist = $input;
-                while (!scm_is_null(alist)) {
-                    K* k;
-                    SCM entry, key, val;
-                    entry = SCM_CAR(alist);
-                    if (!scm_is_pair(entry))
-                        SWIG_exception(SWIG_TypeError,"alist expected");
-                    key = SCM_CAR(entry);
-                    val = SCM_CDR(entry);
-                    k = (K*) SWIG_MustGetPtr(key,$descriptor(K *),$argnum, 0);
-                    if (!CHECK(val)) {
-                        if (!scm_is_pair(val))
-                            SWIG_exception(SWIG_TypeError,"alist expected");
-                        val = SCM_CAR(val);
-                        if (!CHECK(val))
-                            SWIG_exception(SWIG_TypeError,
-                                           "map<" #K "," #T "," #C "> expected");
-                    }
-                    temp[*k] = CONVERT_FROM(val);
-                    alist = SCM_CDR(alist);
-                }
-            } else {
-                $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0);
-            }
-        }
-        %typemap(out) map< K, T, C > {
-            SCM alist = SCM_EOL;
-            for (std::map< K, T, C >::reverse_iterator i=$1.rbegin(); i!=$1.rend(); ++i) {
-                K* key = new K(i->first);
-                SCM k = SWIG_NewPointerObj(key,$descriptor(K *), 1);
-                SCM x = CONVERT_TO(i->second);
-                SCM entry = scm_cons(k,x);
-                alist = scm_cons(entry,alist);
-            }
-            $result = alist;
-        }
-        %typecheck(SWIG_TYPECHECK_MAP) map< K, T, C > {
-            // native sequence?
-            if (scm_is_null($input)) {
-                /* an empty sequence can be of any type */
-                $1 = 1;
-            } else if (scm_is_pair($input)) {
-                // check the first element only
-                K* k;
-                SCM head = SCM_CAR($input);
-                if (scm_is_pair(head)) {
-                    SCM val = SCM_CDR(head);
-                    if (SWIG_ConvertPtr(val,(void **) &k,
-                                    $descriptor(K *), 0) != 0) {
-                        $1 = 0;
-                    } else {
-                        if (CHECK(val)) {
-                            $1 = 1;
-                        } else if (scm_is_pair(val)) {
-                            val = SCM_CAR(val);
-                            if (CHECK(val))
-                                $1 = 1;
-                            else
-                                $1 = 0;
-                        } else {
-                            $1 = 0;
-                        }
-                    }
-                } else {
-                    $1 = 0;
-                }
-            } else {
-                // wrapped map?
-                std::map< K, T, C >* m;
-                if (SWIG_ConvertPtr($input,(void **) &m,
-                                $&1_descriptor, 0) == 0)
-                    $1 = 1;
-                else
-                    $1 = 0;
-            }
-        }
-        %typecheck(SWIG_TYPECHECK_MAP) const map< K, T, C >&,
-                                       const map< K, T, C >* {
-            // native sequence?
-            if (scm_is_null($input)) {
-                /* an empty sequence can be of any type */
-                $1 = 1;
-            } else if (scm_is_pair($input)) {
-                // check the first element only
-                K* k;
-                SCM head = SCM_CAR($input);
-                if (scm_is_pair(head)) {
-                    SCM val = SCM_CDR(head);
-                    if (SWIG_ConvertPtr(val,(void **) &k,
-                                    $descriptor(K *), 0) != 0) {
-                        $1 = 0;
-                    } else {
-                        if (CHECK(val)) {
-                            $1 = 1;
-                        } else if (scm_is_pair(val)) {
-                            val = SCM_CAR(val);
-                            if (CHECK(val))
-                                $1 = 1;
-                            else
-                                $1 = 0;
-                        } else {
-                            $1 = 0;
-                        }
-                    }
-                } else {
-                    $1 = 0;
-                }
-            } else {
-                // wrapped map?
-                std::map< K, T, C >* m;
-                if (SWIG_ConvertPtr($input,(void **) &m,
-                                $1_descriptor, 0) == 0)
-                    $1 = 1;
-                else
-                    $1 = 0;
-            }
-        }
-        %rename("length") size;
-        %rename("null?") empty;
-        %rename("clear!") clear;
-        %rename("ref") __getitem__;
-        %rename("set!") __setitem__;
-        %rename("delete!") __delitem__;
-        %rename("has-key?") has_key;
-      public:
-        typedef size_t size_type;
-        typedef ptrdiff_t difference_type;
-        typedef K key_type;
-        typedef T mapped_type;
-        typedef std::pair< const K, T > value_type;
-        typedef value_type* pointer;
-        typedef const value_type* const_pointer;
-        typedef value_type& reference;
-        typedef const value_type& const_reference;
-
-        map();
-        map(const map& other);
-        
-        unsigned int size() const;
-        bool empty() const;
-        void clear();
-        %extend {
-            T __getitem__(const K& key) throw (std::out_of_range) {
-                std::map< K, T, C >::iterator i = self->find(key);
-                if (i != self->end())
-                    return i->second;
-                else
-                    throw std::out_of_range("key not found");
-            }
-            void __setitem__(const K& key, T x) {
-                (*self)[key] = x;
-            }
-            void __delitem__(const K& key) throw (std::out_of_range) {
-                std::map< K, T, C >::iterator i = self->find(key);
-                if (i != self->end())
-                    self->erase(i);
-                else
-                    throw std::out_of_range("key not found");
-            }
-            bool has_key(const K& key) {
-                std::map< K, T, C >::iterator i = self->find(key);
-                return i != self->end();
-            }
-            SCM keys() {
-                SCM result = SCM_EOL;
-                for (std::map< K, T, C >::reverse_iterator i=self->rbegin(); i!=self->rend(); ++i) {
-                    K* key = new K(i->first);
-                    SCM k = SWIG_NewPointerObj(key,$descriptor(K *), 1);
-                    result = scm_cons(k,result);
-                }
-                return result;
-            }
-        }
-    };
-    %enddef
-
-    %define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO,
-                                       T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO)
-    template<> class map< K, T, C > {
-        %typemap(in) map< K, T, C > {
-            if (scm_is_null($input)) {
-                $1 = std::map< K, T, C >();
-            } else if (scm_is_pair($input)) {
-                $1 = std::map< K, T, C >();
-                SCM alist = $input;
-                while (!scm_is_null(alist)) {
-                    SCM entry, key, val;
-                    entry = SCM_CAR(alist);
-                    if (!scm_is_pair(entry))
-                        SWIG_exception(SWIG_TypeError,"alist expected");
-                    key = SCM_CAR(entry);
-                    val = SCM_CDR(entry);
-                    if (!CHECK_K(key))
-                        SWIG_exception(SWIG_TypeError,
-                                           "map<" #K "," #T "," #C "> expected");
-                    if (!CHECK_T(val)) {
-                        if (!scm_is_pair(val))
-                            SWIG_exception(SWIG_TypeError,"alist expected");
-                        val = SCM_CAR(val);
-                        if (!CHECK_T(val))
-                            SWIG_exception(SWIG_TypeError,
-                                           "map<" #K "," #T "," #C "> expected");
-                    }
-                    (($1_type &)$1)[CONVERT_K_FROM(key)] = 
-                                               CONVERT_T_FROM(val);
-                    alist = SCM_CDR(alist);
-                }
-            } else {
-                $1 = *(($&1_type)
-                       SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0));
-            }
-        }
-        %typemap(in) const map< K, T, C >& (std::map< K, T, C > temp),
-                     const map< K, T, C >* (std::map< K, T, C > temp) {
-            if (scm_is_null($input)) {
-                temp = std::map< K, T, C >();
-                $1 = &temp;
-            } else if (scm_is_pair($input)) {
-                temp = std::map< K, T, C >();
-                $1 = &temp;
-                SCM alist = $input;
-                while (!scm_is_null(alist)) {
-                    SCM entry, key, val;
-                    entry = SCM_CAR(alist);
-                    if (!scm_is_pair(entry))
-                        SWIG_exception(SWIG_TypeError,"alist expected");
-                    key = SCM_CAR(entry);
-                    val = SCM_CDR(entry);
-                    if (!CHECK_K(key))
-                        SWIG_exception(SWIG_TypeError,
-                                           "map<" #K "," #T "," #C "> expected");
-                    if (!CHECK_T(val)) {
-                        if (!scm_is_pair(val))
-                            SWIG_exception(SWIG_TypeError,"alist expected");
-                        val = SCM_CAR(val);
-                        if (!CHECK_T(val))
-                            SWIG_exception(SWIG_TypeError,
-                                           "map<" #K "," #T "," #C "> expected");
-                    }
-                    temp[CONVERT_K_FROM(key)] = CONVERT_T_FROM(val);
-                    alist = SCM_CDR(alist);
-                }
-            } else {
-                $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0);
-            }
-        }
-        %typemap(out) map< K, T, C > {
-            SCM alist = SCM_EOL;
-            for (std::map< K, T, C >::reverse_iterator i=$1.rbegin(); i!=$1.rend(); ++i) {
-                SCM k = CONVERT_K_TO(i->first);
-                SCM x = CONVERT_T_TO(i->second);
-                SCM entry = scm_cons(k,x);
-                alist = scm_cons(entry,alist);
-            }
-            $result = alist;
-        }
-        %typecheck(SWIG_TYPECHECK_MAP) map< K, T, C > {
-            // native sequence?
-            if (scm_is_null($input)) {
-                /* an empty sequence can be of any type */
-                $1 = 1;
-            } else if (scm_is_pair($input)) {
-                // check the first element only
-                SCM head = SCM_CAR($input);
-                if (scm_is_pair(head)) {
-                    SCM key = SCM_CAR(head);
-                    SCM val = SCM_CDR(head);
-                    if (!CHECK_K(key)) {
-                        $1 = 0;
-                    } else {
-                        if (CHECK_T(val)) {
-                            $1 = 1;
-                        } else if (scm_is_pair(val)) {
-                            val = SCM_CAR(val);
-                            if (CHECK_T(val))
-                                $1 = 1;
-                            else
-                                $1 = 0;
-                        } else {
-                            $1 = 0;
-                        }
-                    }
-                } else {
-                    $1 = 0;
-                }
-            } else {
-                // wrapped map?
-                std::map< K, T, C >* m;
-                if (SWIG_ConvertPtr($input,(void **) &m,
-                                $&1_descriptor, 0) == 0)
-                    $1 = 1;
-                else
-                    $1 = 0;
-            }
-        }
-        %typecheck(SWIG_TYPECHECK_MAP) const map< K, T, C >&,
-                                       const map< K, T, C >* {
-            // native sequence?
-            if (scm_is_null($input)) {
-                /* an empty sequence can be of any type */
-                $1 = 1;
-            } else if (scm_is_pair($input)) {
-                // check the first element only
-                SCM head = SCM_CAR($input);
-                if (scm_is_pair(head)) {
-                    SCM key = SCM_CAR(head);
-                    SCM val = SCM_CDR(head);
-                    if (!CHECK_K(key)) {
-                        $1 = 0;
-                    } else {
-                        if (CHECK_T(val)) {
-                            $1 = 1;
-                        } else if (scm_is_pair(val)) {
-                            val = SCM_CAR(val);
-                            if (CHECK_T(val))
-                                $1 = 1;
-                            else
-                                $1 = 0;
-                        } else {
-                            $1 = 0;
-                        }
-                    }
-                } else {
-                    $1 = 0;
-                }
-            } else {
-                // wrapped map?
-                std::map< K, T, C >* m;
-                if (SWIG_ConvertPtr($input,(void **) &m,
-                                $1_descriptor, 0) == 0)
-                    $1 = 1;
-                else
-                    $1 = 0;
-            }
-        }
-        %rename("length") size;
-        %rename("null?") empty;
-        %rename("clear!") clear;
-        %rename("ref") __getitem__;
-        %rename("set!") __setitem__;
-        %rename("delete!") __delitem__;
-        %rename("has-key?") has_key;
-      public:
-        typedef size_t size_type;
-        typedef ptrdiff_t difference_type;
-        typedef K key_type;
-        typedef T mapped_type;
-        typedef std::pair< const K, T > value_type;
-        typedef value_type* pointer;
-        typedef const value_type* const_pointer;
-        typedef value_type& reference;
-        typedef const value_type& const_reference;
-
-        map();
-        map(const map& other);
-        
-        unsigned int size() const;
-        bool empty() const;
-        void clear();
-        %extend {
-            T __getitem__(K key) throw (std::out_of_range) {
-                std::map< K, T, C >::iterator i = self->find(key);
-                if (i != self->end())
-                    return i->second;
-                else
-                    throw std::out_of_range("key not found");
-            }
-            void __setitem__(K key, T x) {
-                (*self)[key] = x;
-            }
-            void __delitem__(K key) throw (std::out_of_range) {
-                std::map< K, T, C >::iterator i = self->find(key);
-                if (i != self->end())
-                    self->erase(i);
-                else
-                    throw std::out_of_range("key not found");
-            }
-            bool has_key(K key) {
-                std::map< K, T, C >::iterator i = self->find(key);
-                return i != self->end();
-            }
-            SCM keys() {
-                SCM result = SCM_EOL;
-                for (std::map< K, T, C >::reverse_iterator i=self->rbegin(); i!=self->rend(); ++i) {
-                    SCM k = CONVERT_K_TO(i->first);
-                    result = scm_cons(k,result);
-                }
-                return result;
-            }
-        }
-    };
-    %enddef
-
-
-    specialize_std_map_on_key(bool,scm_is_bool,
-                              scm_is_true,SWIG_bool2scm);
-    specialize_std_map_on_key(int,scm_is_number,
-                              scm_to_long,scm_from_long);
-    specialize_std_map_on_key(short,scm_is_number,
-                              scm_to_long,scm_from_long);
-    specialize_std_map_on_key(long,scm_is_number,
-                              scm_to_long,scm_from_long);
-    specialize_std_map_on_key(unsigned int,scm_is_number,
-                              scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_key(unsigned short,scm_is_number,
-                              scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_key(unsigned long,scm_is_number,
-                              scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_key(double,scm_is_number,
-                              scm_to_double,scm_from_double);
-    specialize_std_map_on_key(float,scm_is_number,
-                              scm_to_double,scm_from_double);
-    specialize_std_map_on_key(std::string,scm_is_string,
-                              SWIG_scm2string,SWIG_string2scm);
-
-    specialize_std_map_on_value(bool,scm_is_bool,
-                                scm_is_true,SWIG_bool2scm);
-    specialize_std_map_on_value(int,scm_is_number,
-                                scm_to_long,scm_from_long);
-    specialize_std_map_on_value(short,scm_is_number,
-                                scm_to_long,scm_from_long);
-    specialize_std_map_on_value(long,scm_is_number,
-                                scm_to_long,scm_from_long);
-    specialize_std_map_on_value(unsigned int,scm_is_number,
-                                scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_value(unsigned short,scm_is_number,
-                                scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_value(unsigned long,scm_is_number,
-                                scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_value(double,scm_is_number,
-                                scm_to_double,scm_from_double);
-    specialize_std_map_on_value(float,scm_is_number,
-                                scm_to_double,scm_from_double);
-    specialize_std_map_on_value(std::string,scm_is_string,
-                                SWIG_scm2string,SWIG_string2scm);
-
-    specialize_std_map_on_both(bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm,
-                               bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm);
-    specialize_std_map_on_both(bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm,
-                               int,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm,
-                               short,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm,
-                               long,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm,
-                               unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm,
-                               unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm,
-                               unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm,
-                               double,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm,
-                               float,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm,
-                               std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm);
-    specialize_std_map_on_both(int,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm);
-    specialize_std_map_on_both(int,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               int,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(int,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               short,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(int,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               long,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(int,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(int,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(int,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(int,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               double,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(int,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               float,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(int,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm);
-    specialize_std_map_on_both(short,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm);
-    specialize_std_map_on_both(short,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               int,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(short,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               short,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(short,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               long,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(short,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(short,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(short,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(short,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               double,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(short,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               float,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(short,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm);
-    specialize_std_map_on_both(long,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm);
-    specialize_std_map_on_both(long,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               int,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(long,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               short,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(long,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               long,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(long,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(long,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(long,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(long,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               double,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(long,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               float,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(long,scm_is_number,
-                               scm_to_long,scm_from_long,
-                               std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm);
-    specialize_std_map_on_both(unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm);
-    specialize_std_map_on_both(unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               int,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               short,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               long,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               double,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               float,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm);
-    specialize_std_map_on_both(unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm);
-    specialize_std_map_on_both(unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               int,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               short,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               long,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               double,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               float,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm);
-    specialize_std_map_on_both(unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm);
-    specialize_std_map_on_both(unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               int,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               short,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               long,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               double,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               float,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong,
-                               std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm);
-    specialize_std_map_on_both(double,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm);
-    specialize_std_map_on_both(double,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               int,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(double,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               short,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(double,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               long,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(double,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(double,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(double,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(double,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               double,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(double,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               float,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(double,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm);
-    specialize_std_map_on_both(float,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm);
-    specialize_std_map_on_both(float,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               int,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(float,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               short,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(float,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               long,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(float,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(float,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(float,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(float,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               double,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(float,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               float,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(float,scm_is_number,
-                               scm_to_double,scm_from_double,
-                               std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm);
-    specialize_std_map_on_both(std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm,
-                               bool,scm_is_bool,
-                               scm_is_true,SWIG_bool2scm);
-    specialize_std_map_on_both(std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm,
-                               int,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm,
-                               short,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm,
-                               long,scm_is_number,
-                               scm_to_long,scm_from_long);
-    specialize_std_map_on_both(std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm,
-                               unsigned int,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm,
-                               unsigned short,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm,
-                               unsigned long,scm_is_number,
-                               scm_to_ulong,scm_from_ulong);
-    specialize_std_map_on_both(std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm,
-                               double,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm,
-                               float,scm_is_number,
-                               scm_to_double,scm_from_double);
-    specialize_std_map_on_both(std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm,
-                               std::string,scm_is_string,
-                               SWIG_scm2string,SWIG_string2scm);
 }
diff --git a/Lib/guile/std_string.i b/Lib/guile/std_string.i
index 6513173..178c484 100644
--- a/Lib/guile/std_string.i
+++ b/Lib/guile/std_string.i
@@ -30,7 +30,7 @@
         if (scm_is_string($input)) {
             tempptr = SWIG_scm2str($input);
             $1.assign(tempptr);
-            if (tempptr) SWIG_free(tempptr);
+            SWIG_free(tempptr);
         } else {
             SWIG_exception(SWIG_TypeError, "string expected");
         }
@@ -40,7 +40,7 @@
         if (scm_is_string($input)) {
             tempptr = SWIG_scm2str($input);
             temp.assign(tempptr);
-            if (tempptr) SWIG_free(tempptr);
+            SWIG_free(tempptr);
             $1 = &temp;
         } else {
             SWIG_exception(SWIG_TypeError, "string expected");
@@ -51,7 +51,7 @@
         if (scm_is_string($input)) {
             tempptr = SWIG_scm2str($input);
             $1 = new $*1_ltype(tempptr);
-            if (tempptr) SWIG_free(tempptr);
+            SWIG_free(tempptr);
         } else {
             SWIG_exception(SWIG_TypeError, "string expected");
         }
@@ -73,7 +73,7 @@
         if (scm_is_string($input)) {
 	    char *tempptr = SWIG_scm2str($input);
             $1.assign(tempptr);
-            if (tempptr) SWIG_free(tempptr);
+            SWIG_free(tempptr);
         } else {
             SWIG_exception(SWIG_TypeError, "string expected");
         }
@@ -83,4 +83,13 @@
         $result = SWIG_str02scm($1.c_str());
     }
 
+    %typemap(throws) string {
+      scm_throw(scm_from_locale_symbol("swig-exception"),
+                scm_list_n(SWIG_str02scm($1.c_str()), SCM_UNDEFINED));
+    }
+
+    %typemap(throws) const string & {
+      scm_throw(scm_from_locale_symbol("swig-exception"),
+                scm_list_n(SWIG_str02scm($1.c_str()), SCM_UNDEFINED));
+    }
 }
diff --git a/Lib/guile/std_unique_ptr.i b/Lib/guile/std_unique_ptr.i
new file mode 100644
index 0000000..6f907e9
--- /dev/null
+++ b/Lib/guile/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      scm_misc_error(FUNC_NAME, "Cannot release ownership as memory is not owned for argument $argnum of type 'TYPE *'", SCM_EOL);
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+  %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class unique_ptr {};
+}
diff --git a/Lib/guile/swigmove.i b/Lib/guile/swigmove.i
new file mode 100644
index 0000000..87ab91e
--- /dev/null
+++ b/Lib/guile/swigmove.i
@@ -0,0 +1,19 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in, noblock=1) SWIGTYPE MOVE (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $&1_descriptor, SWIG_POINTER_RELEASE);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "$1_type", $symname, $argnum);
+    } else {
+      %argument_fail(res, "$1_type", $symname, $argnum);
+    }
+  }
+  if (!argp) { %argument_nullref("$1_type", $symname, $argnum); }
+  SwigValueWrapper< $1_ltype >::reset($1, ($&1_type)argp);
+}
diff --git a/Lib/guile/swigrun.i b/Lib/guile/swigrun.i
index 4b9ea2c..e4573eb 100644
--- a/Lib/guile/swigrun.i
+++ b/Lib/guile/swigrun.i
@@ -4,8 +4,6 @@
 
 #ifdef SWIGGUILE_SCM
 
-/* Hook the runtime module initialization
-   into the shared initialization function SWIG_Guile_Init. */
 %runtime %{
 /* Hook the runtime module initialization
    into the shared initialization function SWIG_Guile_Init. */
diff --git a/Lib/guile/typemaps.i b/Lib/guile/typemaps.i
index cfccced..d9b78fb 100644
--- a/Lib/guile/typemaps.i
+++ b/Lib/guile/typemaps.i
@@ -4,17 +4,43 @@
  * Guile-specific typemaps
  * ----------------------------------------------------------------------------- */
 
+/* These are defined with a view to eventually merging with those defined for other target languages in swigtypemaps.swg and exception.swg */
+#define %set_output(obj)                  $result = obj
+#define %set_varoutput(obj)               $result = obj
+#define %argument_fail(_code, _type, _name, _argn)	scm_wrong_type_arg(FUNC_NAME, _argn, $input)
+#define %as_voidptr(ptr)		(void*)(ptr)
+#define %argument_nullref(_type, _name, _argn) scm_misc_error(FUNC_NAME, "invalid null reference for argument " #_argn " of type '" _type "'", SCM_EOL)
+#define %releasenotowned_fail(_code, _type, _name, _argn) scm_misc_error(FUNC_NAME, "cannot release ownership as memory is not owned for argument " #_argn " of type '" _type "'", SCM_EOL)
+
 /* Pointers */
 
-%typemap(in) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] {
+%typemap(in) SWIGTYPE *, SWIGTYPE [] {
   $1 = ($1_ltype)SWIG_MustGetPtr($input, $descriptor, $argnum, 0);
 }
-%typemap(freearg) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] "";
+%typemap(in) SWIGTYPE & ($1_ltype argp) {
+  argp = ($1_ltype)SWIG_MustGetPtr($input, $descriptor, $argnum, 0);
+  if (!argp) { %argument_nullref("$1_type", $symname, $argnum); }
+  $1 = argp;
+}
+%typemap(in, noblock=1, fragment="<memory>") SWIGTYPE && (void *argp = 0, int res = 0, std::unique_ptr<$*1_ltype> rvrdeleter) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor, SWIG_POINTER_RELEASE);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "$1_type", $symname, $argnum);
+    } else {
+      %argument_fail(res, "$1_type", $symname, $argnum);
+    }
+  }
+  if (!argp) { %argument_nullref("$1_type", $symname, $argnum); }
+  $1 = ($1_ltype)argp;
+  rvrdeleter.reset($1);
+}
+%typemap(freearg) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] ""
 
 %typemap(in) void * {
   $1 = ($1_ltype)SWIG_MustGetPtr($input, NULL, $argnum, 0);
 }
-%typemap(freearg) void * "";
+%typemap(freearg) void * ""
 
 %typemap(varin) SWIGTYPE * {
   $1 = ($1_ltype)SWIG_MustGetPtr($input, $descriptor, 1, 0);
@@ -29,7 +55,7 @@
 }
 
 %typemap(varin) SWIGTYPE [] {
-  scm_wrong_type_arg((char *) FUNC_NAME, 1, $input);
+  scm_wrong_type_arg(FUNC_NAME, 1, $input);
 }
 
 %typemap(varin) SWIGTYPE [ANY] {
@@ -68,31 +94,31 @@
 
 %typemap(throws) SWIGTYPE {
   $&ltype temp = new $ltype($1);
-  scm_throw(scm_from_locale_symbol((char *) "swig-exception"),
+  scm_throw(scm_from_locale_symbol("swig-exception"),
 	    scm_list_n(SWIG_NewPointerObj(temp, $&descriptor, 1),
 		    SCM_UNDEFINED));
 }
 
 %typemap(throws) SWIGTYPE & {
-  scm_throw(scm_from_locale_symbol((char *) "swig-exception"),
+  scm_throw(scm_from_locale_symbol("swig-exception"),
 	    scm_list_n(SWIG_NewPointerObj(&$1, $descriptor, 1),
 		    SCM_UNDEFINED));
 }
 
 %typemap(throws) SWIGTYPE && {
-  scm_throw(gh_symbol2scm((char *) "swig-exception"),
-	    gh_list(SWIG_NewPointerObj(&$1, $descriptor, 1),
+  scm_throw(scm_from_locale_symbol("swig-exception"),
+	    scm_list_n(SWIG_NewPointerObj(&$1, $descriptor, 1),
 		    SCM_UNDEFINED));
 }
 
 %typemap(throws) SWIGTYPE * {
-  scm_throw(scm_from_locale_symbol((char *) "swig-exception"),
+  scm_throw(scm_from_locale_symbol("swig-exception"),
 	    scm_list_n(SWIG_NewPointerObj($1, $descriptor, 1),
 		    SCM_UNDEFINED));
 }
 
 %typemap(throws) SWIGTYPE [] {
-  scm_throw(scm_from_locale_symbol((char *) "swig-exception"),
+  scm_throw(scm_from_locale_symbol("swig-exception"),
 	    scm_list_n(SWIG_NewPointerObj($1, $descriptor, 1),
 		    SCM_UNDEFINED));
 }
@@ -115,8 +141,9 @@
 
 /* Pass-by-value */
 
-%typemap(in) SWIGTYPE($&1_ltype argp) {
+%typemap(in) SWIGTYPE ($&1_ltype argp) {
   argp = ($&1_ltype)SWIG_MustGetPtr($input, $&1_descriptor, $argnum, 0);
+  if (!argp) { %argument_nullref("$1_type", $symname, $argnum); }
   $1 = *argp;
 }
 
@@ -130,7 +157,7 @@
 #ifdef __cplusplus
 {
   $&1_ltype resultptr;
-  resultptr = new $1_ltype((const $1_ltype &) $1);
+  resultptr = new $1_ltype($1);
   $result =  SWIG_NewPointerObj (resultptr, $&1_descriptor, 1);
 } 
 #else
@@ -145,8 +172,7 @@
 %typemap(varout) SWIGTYPE 
 #ifdef __cplusplus
 {
-  $&1_ltype resultptr;
-  resultptr = new $1_ltype((const $1_ltype&) $1);
+  $&1_ltype resultptr = ($&1_ltype)&$1;
   $result =  SWIG_NewPointerObj (resultptr, $&1_descriptor, 0);
 } 
 #else
@@ -166,8 +192,8 @@
 %typemap(varin)  enum SWIGTYPE  {
   if (sizeof(int) != sizeof($1)) {
     scm_error(scm_from_locale_symbol("swig-error"),
-	      (char *) FUNC_NAME,
-	      (char *) "enum variable '$name' cannot be set",
+	      FUNC_NAME,
+	      "enum variable '$name' cannot be set",
 	      SCM_EOL, SCM_BOOL_F); 
   }
   * (int *) &($1) = scm_to_int($input);
@@ -175,7 +201,7 @@
 %typemap(out)    enum SWIGTYPE  { $result = scm_from_long((int)$1); }
 %typemap(varout) enum SWIGTYPE  { $result = scm_from_long((int)$1); }
 %typemap(throws) enum SWIGTYPE {
-  scm_throw(scm_from_locale_symbol((char *) "swig-exception"),
+  scm_throw(scm_from_locale_symbol("swig-exception"),
      scm_list_n(scm_from_long((int)$1), SCM_UNDEFINED));
 }
 
@@ -209,8 +235,6 @@
  %typemap (argout,doc="$name (of type <" #SCM_NAME ">)") C_NAME *OUTPUT
      { C_NAME swig_c_value = *$1;
        SWIG_APPEND_VALUE(C_TO_SCM_EXPR); }
- %typemap (in)          C_NAME *BOTH = C_NAME *INPUT;
- %typemap (argout)      C_NAME *BOTH = C_NAME *OUTPUT;
  %typemap (in)          C_NAME *INOUT = C_NAME *INPUT;
  %typemap (argout)      C_NAME *INOUT = C_NAME *OUTPUT;
  /* Const primitive references.  Passed by value */
@@ -224,7 +248,7 @@
  /* Throw typemap */
  %typemap(throws) C_NAME {
    C_NAME swig_c_value = $1;
-   scm_throw(scm_from_locale_symbol((char *) "swig-exception"),
+   scm_throw(scm_from_locale_symbol("swig-exception"),
 	     scm_list_n(C_TO_SCM_EXPR, SCM_UNDEFINED));
  }
 %enddef
@@ -252,8 +276,6 @@
    {$1 = &temp;}
  %typemap (argout,doc="$name (of type <" #SCM_NAME ">)") C_NAME *OUTPUT, C_NAME &OUTPUT
    {SWIG_APPEND_VALUE(C_TO_SCM(*$1));}
- %typemap (in)          C_NAME *BOTH = C_NAME *INPUT;
- %typemap (argout)      C_NAME *BOTH = C_NAME *OUTPUT;
  %typemap (in)          C_NAME *INOUT = C_NAME *INPUT;
  %typemap (argout)      C_NAME *INOUT = C_NAME *OUTPUT;
  %typemap (in)          C_NAME &INOUT = C_NAME &INPUT;
@@ -268,7 +290,7 @@
  }
  /* Throw typemap */
  %typemap(throws) C_NAME {
-   scm_throw(scm_from_locale_symbol((char *) "swig-exception"),
+   scm_throw(scm_from_locale_symbol("swig-exception"),
 	     scm_list_n(C_TO_SCM($1), SCM_UNDEFINED));
  }
 %enddef
@@ -314,27 +336,25 @@
    {$1 = &temp;}
  %typemap (argout,doc="$NAME (a string)") char **OUTPUT
    {SWIG_APPEND_VALUE(SWIG_str02scm(*$1));}
- %typemap (in)          char **BOTH = char **INPUT;
- %typemap (argout)      char **BOTH = char **OUTPUT;
  %typemap (in)          char **INOUT = char **INPUT;
  %typemap (argout)      char **INOUT = char **OUTPUT;
 
 /* SWIG_scm2str makes a malloc'ed copy of the string, so get rid of it after
    the function call. */
 
-%typemap (freearg) char * "if (must_free$argnum && $1) SWIG_free($1);";
-%typemap (freearg) char **INPUT, char **BOTH "if (must_free$argnum && (*$1)) SWIG_free(*$1);"
+%typemap (freearg) char * "if (must_free$argnum) SWIG_free($1);"
+%typemap (freearg) char **INPUT, char **INOUT "if (must_free$argnum) SWIG_free(*$1);"
 %typemap (freearg) char **OUTPUT "SWIG_free(*$1);"
   
 /* But this shall not apply if we try to pass a single char by
    reference. */
 
-%typemap (freearg) char *OUTPUT, char *BOTH "";
+%typemap (freearg) char *OUTPUT, char *INOUT ""
 
 /* If we set a string variable, delete the old result first, unless const. */
 
 %typemap (varin) char * {
-    if ($1) free($1);
+    free($1);
     $1 = ($1_ltype) SWIG_scm2str($input);
 }
 
@@ -343,19 +363,19 @@
 }
 
 %typemap(throws) char * {
-  scm_throw(scm_from_locale_symbol((char *) "swig-exception"),
+  scm_throw(scm_from_locale_symbol("swig-exception"),
 	    scm_list_n(SWIG_str02scm($1), SCM_UNDEFINED));
 }
 
 /* Void */
 
-%typemap (out,doc="") void "gswig_result = SCM_UNSPECIFIED;";
+%typemap (out,doc="") void "gswig_result = SCM_UNSPECIFIED;"
 
 /* SCM is passed through */
 
 typedef unsigned long SCM;
-%typemap (in) SCM "$1=$input;";
-%typemap (out) SCM "$result=$1;";
+%typemap (in) SCM "$1=$input;"
+%typemap (out) SCM "$result=$1;"
 %typecheck(SWIG_TYPECHECK_POINTER) SCM "$1=1;";
 
 /* ------------------------------------------------------------
@@ -373,31 +393,26 @@
  * taken from typemaps/swigtype.swg
  * ------------------------------------------------------------ */
 
-#define %set_output(obj)                  $result = obj
-#define %set_varoutput(obj)               $result = obj
-#define %argument_fail(code, type, name, argn)	scm_wrong_type_arg((char *) FUNC_NAME, argn, $input);
-#define %as_voidptr(ptr)		(void*)(ptr)
-
-%typemap(in) SWIGTYPE (CLASS::*) {  
-  int res = SWIG_ConvertMember($input, %as_voidptr(&$1), sizeof($type),$descriptor);
+%typemap(in) SWIGTYPE (CLASS::*) {
+  int res = SWIG_ConvertMember($input, %as_voidptr(&$1), sizeof($1), $descriptor);
   if (!SWIG_IsOK(res)) {
-    %argument_fail(res,"$type",$symname, $argnum); 
+    %argument_fail(res,"$type",$symname, $argnum);
   }
 }
 
 %typemap(out,noblock=1) SWIGTYPE (CLASS::*) {
-  %set_output(SWIG_NewMemberObj(%as_voidptr(&$1), sizeof($type), $descriptor));
+  %set_output(SWIG_NewMemberObj(%as_voidptr(&$1), sizeof($1), $descriptor));
 }
 
 %typemap(varin) SWIGTYPE (CLASS::*) {
-  int res = SWIG_ConvertMember($input,%as_voidptr(&$1), sizeof($type), $descriptor);
+  int res = SWIG_ConvertMember($input,%as_voidptr(&$1), sizeof($1), $descriptor);
   if (!SWIG_IsOK(res)) {
-    scm_wrong_type_arg((char *) FUNC_NAME, 1, $input);
+    scm_wrong_type_arg(FUNC_NAME, 1, $input);
   }
 }
 
 %typemap(varout,noblock=1) SWIGTYPE (CLASS::*) {
-  %set_varoutput(SWIG_NewMemberObj(%as_voidptr(&$1), sizeof($type), $descriptor));
+  %set_varoutput(SWIG_NewMemberObj(%as_voidptr(&$1), sizeof($1), $descriptor));
 }
 
 /* ------------------------------------------------------------
@@ -426,7 +441,7 @@
 %typecheck(SWIG_TYPECHECK_BOOL)
 	bool, bool&, const bool&
 {
-  $1 = SCM_BOOLP($input) ? 1 : 0;
+  $1 = scm_is_bool($input) ? 1 : 0;
 }
 
 %typecheck(SWIG_TYPECHECK_DOUBLE)
diff --git a/Lib/intrusive_ptr.i b/Lib/intrusive_ptr.i
index 621a701..a4e8df0 100644
--- a/Lib/intrusive_ptr.i
+++ b/Lib/intrusive_ptr.i
@@ -56,25 +56,3 @@
 SWIG_INTRUSIVE_PTR_TYPEMAPS_NO_WRAP(, TYPE)
 SWIG_INTRUSIVE_PTR_TYPEMAPS_NO_WRAP(const, TYPE)
 %enddef
-
-// Legacy macros
-%define SWIG_INTRUSIVE_PTR(PROXYCLASS, TYPE...)
-#warning "SWIG_INTRUSIVE_PTR(PROXYCLASS, TYPE) is deprecated. Please use %intrusive_ptr(TYPE) instead."
-%intrusive_ptr(TYPE)
-%enddef
-
-%define SWIG_INTRUSIVE_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE...)
-#warning "SWIG_INTRUSIVE_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE) is deprecated. Please use %intrusive_ptr(TYPE) instead."
-%intrusive_ptr(TYPE)
-%enddef
-
-%define SWIG_INTRUSIVE_PTR_NO_WRAP(PROXYCLASS, TYPE...)
-#warning "SWIG_INTRUSIVE_PTR_NO_WRAP(PROXYCLASS, TYPE) is deprecated. Please use %intrusive_ptr_no_wrap(TYPE) instead."
-%intrusive_ptr_no_wrap(TYPE)
-%enddef
-
-%define SWIG_INTRUSIVE_PTR_DERIVED_NO_WRAP(PROXYCLASS, BASECLASSTYPE, TYPE...)
-#warning "SWIG_INTRUSIVE_PTR_DERIVED_NO_WRAP(PROXYCLASS, BASECLASSTYPE, TYPE) is deprecated. Please use %intrusive_ptr_no_wrap(TYPE) instead."
-%intrusive_ptr_no_wrap(TYPE)
-%enddef
-
diff --git a/Lib/inttypes.i b/Lib/inttypes.i
index 85bd5ad..f5a09f0 100644
--- a/Lib/inttypes.i
+++ b/Lib/inttypes.i
@@ -49,37 +49,12 @@
   extern uintmax_t wcstoumax (const wchar_t *nptr, wchar_t ** endptr, int base);
 #endif
 
-#ifdef SWIGWORDSIZE64
-  
   /* Like `strtol' but convert to `intmax_t'.  */
   extern  intmax_t strtoimax (const char *nptr, char **endptr, int base);
   
   /* Like `strtoul' but convert to `uintmax_t'.  */
   extern  uintmax_t strtoumax (const char *nptr, char **endptr,int base);
   
-#ifdef SWIG_WCHAR
-  /* Like `wcstol' but convert to `intmax_t'.  */
-  extern  intmax_t wcstoimax (const wchar_t *nptr, wchar_t **endptr, int base);
-  
-  /* Like `wcstoul' but convert to `uintmax_t'.  */
-  extern  uintmax_t wcstoumax (const wchar_t *nptr, wchar_t **endptr, int base);
-#endif
-  
-#else /* SWIGWORDSIZE32 */
-  
-  /* Like `strtol' but convert to `intmax_t'.  */
-  extern  intmax_t strtoimax (const char *nptr, char **endptr, int base);
-  
-  /* Like `strtoul' but convert to `uintmax_t'.  */
-  extern  uintmax_t strtoumax (const char *nptr, char **endptr, int base);
-  
-#ifdef SWIG_WCHAR
-  /* Like `wcstol' but convert to `intmax_t'.  */
-  extern  uintmax_t wcstoumax (const wchar_t *nptr, wchar_t **endptr, int base);
-#endif
-
-#endif /* SWIGWORDSIZE64 */
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/Lib/java/argcargv.i b/Lib/java/argcargv.i
new file mode 100644
index 0000000..cf0f85b
--- /dev/null
+++ b/Lib/java/argcargv.i
@@ -0,0 +1,36 @@
+/* -------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------- */
+
+%typemap(jni) (int ARGC, char **ARGV) "jobjectArray"
+%typemap(jtype) (int ARGC, char **ARGV) "String[]"
+%typemap(jstype) (int ARGC, char **ARGV) "String[]"
+
+%typemap(in) (int ARGC, char **ARGV) {
+  $1_ltype i, len;
+  if ($input == (jobjectArray)0) {
+    SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null array");
+    return $null;
+  }
+  len = ($1_ltype)JCALL1(GetArrayLength, jenv, $input);
+  if (len < 0) {
+    SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, "array length negative");
+    return $null;
+  }
+  $2 = ($2_ltype) malloc((len+1)*sizeof($*2_ltype));
+  if ($2 == NULL) {
+    SWIG_JavaThrowException(jenv, SWIG_JavaOutOfMemoryError, "memory allocation failed");
+    return $null;
+  }
+  $1 = len;
+  for (i = 0; i < len; i++) {
+    jstring j_string = (jstring)JCALL2(GetObjectArrayElement, jenv, $input, (jsize)i);
+    const char *c_string = JCALL2(GetStringUTFChars, jenv, j_string, 0);
+    $2[i] = ($*2_ltype)c_string;
+  }
+  $2[i] = NULL;
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+  free((void *)$2);
+}
diff --git a/Lib/java/arrays_java.i b/Lib/java/arrays_java.i
index dd38438..a8f5180 100644
--- a/Lib/java/arrays_java.i
+++ b/Lib/java/arrays_java.i
@@ -104,7 +104,7 @@
 JAVA_ARRAYS_DECL(unsigned int, jlong, Long, Uint)     /* unsigned int[] */
 JAVA_ARRAYS_DECL(long, jint, Int, Long)               /* long[] */
 JAVA_ARRAYS_DECL(unsigned long, jlong, Long, Ulong)   /* unsigned long[] */
-JAVA_ARRAYS_DECL(jlong, jlong, Long, Longlong)        /* long long[] */
+JAVA_ARRAYS_DECL(long long, jlong, Long, Longlong)    /* long long[] */
 JAVA_ARRAYS_DECL(float, jfloat, Float, Float)         /* float[] */
 JAVA_ARRAYS_DECL(double, jdouble, Double, Double)     /* double[] */
 
@@ -128,7 +128,7 @@
 JAVA_ARRAYS_IMPL(unsigned int, jlong, Long, Uint)     /* unsigned int[] */
 JAVA_ARRAYS_IMPL(long, jint, Int, Long)               /* long[] */
 JAVA_ARRAYS_IMPL(unsigned long, jlong, Long, Ulong)   /* unsigned long[] */
-JAVA_ARRAYS_IMPL(jlong, jlong, Long, Longlong)        /* long long[] */
+JAVA_ARRAYS_IMPL(long long, jlong, Long, Longlong)    /* long long[] */
 JAVA_ARRAYS_IMPL(float, jfloat, Float, Float)         /* float[] */
 JAVA_ARRAYS_IMPL(double, jdouble, Double, Double)     /* double[] */
 
@@ -147,19 +147,19 @@
 %typemap(jstype) CTYPE[ANY], CTYPE[]            %{JTYPE[]%}
 
 %typemap(in) CTYPE[] (JNITYPE *jarr)
-%{  if (!SWIG_JavaArrayIn##JFUNCNAME(jenv, &jarr, (CTYPE **)&$1, $input)) return $null; %}
+%{  if (!SWIG_JavaArrayIn##JFUNCNAME(jenv, &jarr, ($&1_ltype)&$1, $input)) return $null; %}
 %typemap(in) CTYPE[ANY] (JNITYPE *jarr)
 %{  if ($input && JCALL1(GetArrayLength, jenv, $input) != $1_size) {
     SWIG_JavaThrowException(jenv, SWIG_JavaIndexOutOfBoundsException, "incorrect array size");
     return $null;
   }
-  if (!SWIG_JavaArrayIn##JFUNCNAME(jenv, &jarr, (CTYPE **)&$1, $input)) return $null; %}
+  if (!SWIG_JavaArrayIn##JFUNCNAME(jenv, &jarr, ($&1_ltype)&$1, $input)) return $null; %}
 %typemap(argout) CTYPE[ANY], CTYPE[] 
-%{ SWIG_JavaArrayArgout##JFUNCNAME(jenv, jarr$argnum, (CTYPE *)$1, $input); %}
+%{ SWIG_JavaArrayArgout##JFUNCNAME(jenv, jarr$argnum, ($1_ltype)$1, $input); %}
 %typemap(out) CTYPE[ANY]
-%{$result = SWIG_JavaArrayOut##JFUNCNAME(jenv, (CTYPE *)$1, $1_dim0); %}
+%{$result = SWIG_JavaArrayOut##JFUNCNAME(jenv, ($1_ltype)$1, $1_dim0); %}
 %typemap(out) CTYPE[] 
-%{$result = SWIG_JavaArrayOut##JFUNCNAME(jenv, (CTYPE *)$1, FillMeInAsSizeCannotBeDeterminedAutomatically); %}
+%{$result = SWIG_JavaArrayOut##JFUNCNAME(jenv, ($1_ltype)$1, FillMeInAsSizeCannotBeDeterminedAutomatically); %}
 %typemap(freearg) CTYPE[ANY], CTYPE[] 
 #ifdef __cplusplus
 %{ delete [] $1; %}
@@ -227,6 +227,12 @@
     double[ANY], double[]
     ""
 
+#if defined(SWIGWORDSIZE64)
+%apply long long[ANY] { long[ANY] };
+%apply unsigned long long[ANY] { unsigned long[ANY] };
+%apply long long[] { long[] };
+%apply unsigned long long[] { unsigned long[] };
+#endif
 
 /* Arrays of proxy classes. The typemaps in this macro make it possible to treat an array of 
  * class/struct/unions as an array of Java classes. 
diff --git a/Lib/java/boost_intrusive_ptr.i b/Lib/java/boost_intrusive_ptr.i
index 3bc80b4..072a31e 100644
--- a/Lib/java/boost_intrusive_ptr.i
+++ b/Lib/java/boost_intrusive_ptr.i
@@ -33,7 +33,7 @@
 %}
 %typemap(out, fragment="SWIG_intrusive_deleter") CONST TYPE %{
   //plain value(out)
-  $1_ltype* resultp = new $1_ltype(($1_ltype &)$1);
+  $1_ltype* resultp = new $1_ltype($1);
   intrusive_ptr_add_ref(resultp);
   *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(resultp, SWIG_intrusive_deleter< CONST TYPE >());
 %}
@@ -342,7 +342,7 @@
   }
   $1 = *argp; %}
 %typemap(out) CONST TYPE
-%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
+%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1)); %}
 
 // plain pointer
 %typemap(in) CONST TYPE * (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
diff --git a/Lib/java/boost_shared_ptr.i b/Lib/java/boost_shared_ptr.i
index 325a683..ce00162 100644
--- a/Lib/java/boost_shared_ptr.i
+++ b/Lib/java/boost_shared_ptr.i
@@ -29,11 +29,11 @@
   }
   $1 = *argp; %}
 %typemap(out) CONST TYPE
-%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1)); %}
+%{ *(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$result = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1)); %}
 
 %typemap(directorin,descriptor="L$packagepath/$&javaclassname;") CONST TYPE
 %{ $input = 0;
-  *((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input) = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype((const $1_ltype &)$1)); %}
+  *((SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > **)&$input) = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > (new $1_ltype(SWIG_STD_MOVE($1))); %}
 
 %typemap(directorout) CONST TYPE
 %{ if (!$input) {
diff --git a/Lib/java/director.swg b/Lib/java/director.swg
index d3bd162..630a98f 100644
--- a/Lib/java/director.swg
+++ b/Lib/java/director.swg
@@ -51,16 +51,20 @@
 
 #endif
 
+#if defined(SWIG_JAVA_DETACH_ON_THREAD_END)
+#include <pthread.h>
+#endif
+
 namespace Swig {
 
   /* Java object wrapper */
   class JObjectWrapper {
   public:
-    JObjectWrapper() : jthis_(NULL), weak_global_(true) {
+    JObjectWrapper() : jthis_(SWIG_NULLPTR), weak_global_(true) {
     }
 
     ~JObjectWrapper() {
-      jthis_ = NULL;
+      jthis_ = SWIG_NULLPTR;
       weak_global_ = true;
     }
 
@@ -99,13 +103,13 @@
 #endif
       if (jthis_) {
         if (weak_global_) {
-          if (jenv->IsSameObject(jthis_, NULL) == JNI_FALSE)
+          if (jenv->IsSameObject(jthis_, SWIG_NULLPTR) == JNI_FALSE)
             jenv->DeleteWeakGlobalRef((jweak)jthis_);
         } else
           jenv->DeleteGlobalRef(jthis_);
       }
 
-      jthis_ = NULL;
+      jthis_ = SWIG_NULLPTR;
       weak_global_ = true;
     }
 
@@ -133,6 +137,19 @@
       }
     }
 
+#if defined(SWIG_JAVA_DETACH_ON_THREAD_END)
+    static void detach(void *jvm) {
+      static_cast<JavaVM *>(jvm)->DetachCurrentThread();
+    }
+
+    static void make_detach_key() {
+      pthread_key_create(&detach_key_, detach);
+    }
+
+    /* thread-local key to register a destructor */
+    static pthread_key_t detach_key_;
+#endif
+
   private:
     /* pointer to Java object */
     jobject jthis_;
@@ -140,6 +157,10 @@
     bool weak_global_;
   };
 
+#if defined(SWIG_JAVA_DETACH_ON_THREAD_END)
+  pthread_key_t JObjectWrapper::detach_key_;
+#endif
+
   /* Local JNI reference deleter */
   class LocalRefGuard {
     JNIEnv *jenv_;
@@ -172,7 +193,7 @@
       JNIEnv *jenv_;
       int env_status;
     public:
-      JNIEnvWrapper(const Director *director) : director_(director), jenv_(0), env_status(0) {
+      JNIEnvWrapper(const Director *director) : director_(director), jenv_(SWIG_NULLPTR), env_status(0) {
 #if defined(__ANDROID__)
         JNIEnv **jenv = &jenv_;
 #else
@@ -181,8 +202,8 @@
         env_status = director_->swig_jvm_->GetEnv((void **)&jenv_, JNI_VERSION_1_2);
         JavaVMAttachArgs args;
         args.version = JNI_VERSION_1_2;
-        args.group = NULL;
-        args.name = NULL;
+        args.group = SWIG_NULLPTR;
+        args.name = SWIG_NULLPTR;
 #if defined(SWIG_JAVA_USE_THREAD_NAME)
         char thread_name[64];  // MAX_TASK_COMM_LEN=16 is hard-coded in the Linux kernel and MacOS has MAXTHREADNAMESIZE=64.
         if (Swig::GetThreadName(thread_name, sizeof(thread_name)) == 0) {
@@ -201,9 +222,19 @@
 #else
         director_->swig_jvm_->AttachCurrentThread(jenv, &args);
 #endif
+
+#if defined(SWIG_JAVA_DETACH_ON_THREAD_END)
+        // At least on Android 6, detaching after every call causes a memory leak.
+        // Instead, register a thread desructor and detach only when the thread ends.
+        // See https://developer.android.com/training/articles/perf-jni#threads
+        static pthread_once_t once = PTHREAD_ONCE_INIT;
+
+        pthread_once(&once, JObjectWrapper::make_detach_key);
+        pthread_setspecific(JObjectWrapper::detach_key_, director->swig_jvm_);
+#endif
       }
       ~JNIEnvWrapper() {
-#if !defined(SWIG_JAVA_NO_DETACH_CURRENT_THREAD)
+#if !defined(SWIG_JAVA_DETACH_ON_THREAD_END) && !defined(SWIG_JAVA_NO_DETACH_CURRENT_THREAD)
         // Some JVMs, eg jdk-1.4.2 and lower on Solaris have a bug and crash with the DetachCurrentThread call.
         // However, without this call, the JVM hangs on exit when the thread was not created by the JVM and creates a memory leak.
         if (env_status == JNI_EDETACHED)
@@ -215,6 +246,15 @@
       }
     };
 
+    struct SwigDirectorMethod {
+      const char *name;
+      const char *desc;
+      jmethodID methid;
+      SwigDirectorMethod(JNIEnv *jenv, jclass baseclass, const char *name, const char *desc) : name(name), desc(desc) {
+        methid = jenv->GetMethodID(baseclass, name, desc);
+      }
+    };
+
     /* Java object wrapper */
     JObjectWrapper swig_self_;
 
@@ -227,7 +267,7 @@
 #if defined(DEBUG_DIRECTOR_OWNED)
       std::cout << "Swig::Director::disconnect_director_self(" << jobj << ")" << std::endl;
 #endif
-      if (jobj && jenv->IsSameObject(jobj, NULL) == JNI_FALSE) {
+      if (jobj && jenv->IsSameObject(jobj, SWIG_NULLPTR) == JNI_FALSE) {
         jmethodID disconn_meth = jenv->GetMethodID(jenv->GetObjectClass(jobj), disconn_method, "()V");
         if (disconn_meth) {
 #if defined(DEBUG_DIRECTOR_OWNED)
@@ -238,8 +278,13 @@
       }
     }
 
+    jclass swig_new_global_ref(JNIEnv *jenv, const char *classname) {
+      jclass clz = jenv->FindClass(classname);
+      return clz ? (jclass)jenv->NewGlobalRef(clz) : SWIG_NULLPTR;
+    }
+
   public:
-    Director(JNIEnv *jenv) : swig_jvm_((JavaVM *) NULL), swig_self_() {
+    Director(JNIEnv *jenv) : swig_jvm_((JavaVM *) SWIG_NULLPTR), swig_self_() {
       /* Acquire the Java VM pointer */
       jenv->GetJavaVM(&swig_jvm_);
     }
@@ -284,9 +329,9 @@
   // Simple holder for a Java string during exception handling, providing access to a c-style string
   class JavaString {
   public:
-    JavaString(JNIEnv *jenv, jstring jstr) : jenv_(jenv), jstr_(jstr), cstr_(0) {
+    JavaString(JNIEnv *jenv, jstring jstr) : jenv_(jenv), jstr_(jstr), cstr_(SWIG_NULLPTR) {
       if (jenv_ && jstr_)
-	cstr_ = (const char *) jenv_->GetStringUTFChars(jstr_, NULL);
+	cstr_ = (const char *) jenv_->GetStringUTFChars(jstr_, SWIG_NULLPTR);
     }
 
     ~JavaString() {
@@ -327,7 +372,7 @@
 
     // Get exception message by calling Java method Throwable.getMessage()
     static jstring exceptionMessageFromThrowable(JNIEnv *jenv, jthrowable throwable) {
-      jstring jmsg = NULL;
+      jstring jmsg = SWIG_NULLPTR;
       if (jenv && throwable) {
 	jenv->ExceptionClear(); // Cannot invoke methods with any pending exceptions
 	jclass throwclz = jenv->GetObjectClass(throwable);
@@ -337,7 +382,7 @@
 	  if (getMessageMethodID)
 	    jmsg = (jstring)jenv->CallObjectMethod(throwable, getMessageMethodID);
 	}
-	if (jmsg == NULL && jenv->ExceptionCheck())
+	if (jmsg == SWIG_NULLPTR && jenv->ExceptionCheck())
 	  jenv->ExceptionClear();
       }
       return jmsg;
@@ -351,7 +396,7 @@
   public:
 
     // Construct exception from a Java throwable
-    DirectorException(JNIEnv *jenv, jthrowable throwable) : jenv_(jenv), throwable_(throwable), classname_(0), msg_(0) {
+    DirectorException(JNIEnv *jenv, jthrowable throwable) : jenv_(jenv), throwable_(throwable), classname_(SWIG_NULLPTR), msg_(SWIG_NULLPTR) {
 
       // Call Java method Object.getClass().getName() to obtain the throwable's class name (delimited by '/')
       if (jenv && throwable) {
@@ -366,7 +411,7 @@
               // Copy strings, since there is no guarantee that jenv will be active when handled
               if (jstr_classname) {
                 JavaString jsclassname(jenv, jstr_classname);
-                const char *classname = jsclassname.c_str(0);
+                const char *classname = jsclassname.c_str(SWIG_NULLPTR);
                 if (classname)
                   classname_ = copypath(classname);
               }
@@ -376,11 +421,11 @@
       }
 
       JavaExceptionMessage exceptionmsg(jenv, throwable);
-      msg_ = copystr(exceptionmsg.message(0));
+      msg_ = copystr(exceptionmsg.message(SWIG_NULLPTR));
     }
 
     // More general constructor for handling as a java.lang.RuntimeException
-    DirectorException(const char *msg) : jenv_(0), throwable_(0), classname_(0), msg_(msg ? copystr(msg) : 0) {
+    DirectorException(const char *msg) : jenv_(SWIG_NULLPTR), throwable_(SWIG_NULLPTR), classname_(SWIG_NULLPTR), msg_(msg ? copystr(msg) : SWIG_NULLPTR) {
     }
 
     ~DirectorException() throw() {
@@ -401,7 +446,7 @@
           jthrowable throwable = jenv->ExceptionOccurred();
           if (throwable && jenv->IsSameObject(throwable, throwable_) == JNI_FALSE) {
             jenv->ExceptionClear();
-            throwable = 0;
+            throwable = SWIG_NULLPTR;
           }
           if (!throwable)
             jenv->Throw(throwable_);
@@ -409,8 +454,8 @@
           // Try and reconstruct original exception, but original stacktrace is not reconstructed
           jenv->ExceptionClear();
 
-          jmethodID ctorMethodID = 0;
-          jclass throwableclass = 0;
+          jmethodID ctorMethodID = SWIG_NULLPTR;
+          jclass throwableclass = SWIG_NULLPTR;
           if (classname_) {
             throwableclass = jenv->FindClass(classname_);
             if (throwableclass)
@@ -447,7 +492,7 @@
     }
 
     static char *copystr(const char *srcmsg) {
-      char *target = 0;
+      char *target = SWIG_NULLPTR;
       if (srcmsg) {
 	size_t msglen = strlen(srcmsg) + 1;
 	target = new char[msglen];
diff --git a/Lib/java/java.swg b/Lib/java/java.swg
index e930933..4d427cb 100644
--- a/Lib/java/java.swg
+++ b/Lib/java/java.swg
@@ -665,7 +665,7 @@
 
 %typemap(out) SWIGTYPE 
 #ifdef __cplusplus
-%{ *($&1_ltype*)&$result = new $1_ltype((const $1_ltype &)$1); %}
+%{ *($&1_ltype*)&$result = new $1_ltype($1); %}
 #else
 {
   $&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype));
@@ -676,7 +676,7 @@
 
 %typemap(directorin,descriptor="L$packagepath/$&javaclassname;") SWIGTYPE 
 %{ $input = 0;
-   *(($&1_ltype*)&$input) = new $1_ltype((const $1_ltype &)$1); %}
+   *(($&1_ltype*)&$input) = new $1_ltype(SWIG_STD_MOVE($1)); %}
 %typemap(javadirectorin) SWIGTYPE "new $&javaclassname($jniinput, true)"
 %typemap(javadirectorout) SWIGTYPE "$&javaclassname.getCPtr($javacall)"
 
@@ -692,14 +692,15 @@
 }
 %typemap(in) SWIGTYPE & %{ $1 = *($&1_ltype)&$input;
   if (!$1) {
-    SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type reference is null");
+    SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type is null");
     return $null;
   } %}
-%typemap(in) SWIGTYPE && %{ $1 = *($&1_ltype)&$input;
+%typemap(in, fragment="<memory>") SWIGTYPE && (std::unique_ptr<$*1_ltype> rvrdeleter) %{ $1 = *($&1_ltype)&$input;
   if (!$1) {
-    SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type reference is null");
+    SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type is null");
     return $null;
-  } %}
+  }
+  rvrdeleter.reset($1); %}
 %typemap(out) SWIGTYPE *
 %{ *($&1_ltype)&$result = $1; %} 
 %typemap(out, fragment="SWIG_PackData", noblock=1) SWIGTYPE (CLASS::*) {
@@ -1038,7 +1039,7 @@
                  unsigned long, 
                  unsigned short
 %{ char error_msg[256];
-   sprintf(error_msg, "C++ $1_type exception thrown, value: %d", $1);
+   SWIG_snprintf(error_msg, sizeof(error_msg), "C++ $1_type exception thrown, value: %d", $1);
    SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, error_msg);
    return $null; %}
 
@@ -1101,7 +1102,8 @@
                  jobjectArray
     "$javainput"
 %typemap(javain) SWIGTYPE "$&javaclassname.getCPtr($javainput)"
-%typemap(javain) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] "$javaclassname.getCPtr($javainput)"
+%typemap(javain) SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] "$javaclassname.getCPtr($javainput)"
+%typemap(javain) SWIGTYPE && "$javaclassname.swigRelease($javainput)"
 %typemap(javain) SWIGTYPE (CLASS::*) "$javaclassname.getCMemberPtr($javainput)"
 
 /* The javaout typemap is used for converting function return types from the return type
@@ -1196,6 +1198,7 @@
 %typemap(javacode)             SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
 %typemap(javaimports)          SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
 %typemap(javainterfaces)       SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
+%typemap(javainterfacemodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "public interface"
 
 /* javabody typemaps */
 
@@ -1215,6 +1218,18 @@
   CPTR_VISIBILITY static long getCPtr($javaclassname obj) {
     return (obj == null) ? 0 : obj.swigCPtr;
   }
+
+  CPTR_VISIBILITY static long swigRelease($javaclassname obj) {
+    long ptr = 0;
+    if (obj != null) {
+      if (!obj.swigCMemOwn)
+        throw new RuntimeException("Cannot release ownership as memory is not owned");
+      ptr = obj.swigCPtr;
+      obj.swigCMemOwn = false;
+      obj.delete();
+    }
+    return ptr;
+  }
 %}
 
 // Derived proxy classes
@@ -1229,6 +1244,18 @@
   CPTR_VISIBILITY static long getCPtr($javaclassname obj) {
     return (obj == null) ? 0 : obj.swigCPtr;
   }
+
+  CPTR_VISIBILITY static long swigRelease($javaclassname obj) {
+    long ptr = 0;
+    if (obj != null) {
+      if (!obj.swigCMemOwn)
+        throw new RuntimeException("Cannot release ownership as memory is not owned");
+      ptr = obj.swigCPtr;
+      obj.swigCMemOwn = false;
+      obj.delete();
+    }
+    return ptr;
+  }
 %}
 %enddef
 
@@ -1248,6 +1275,10 @@
   CPTR_VISIBILITY static long getCPtr($javaclassname obj) {
     return (obj == null) ? 0 : obj.swigCPtr;
   }
+
+  CPTR_VISIBILITY static long swigRelease($javaclassname obj) {
+    return (obj == null) ? 0 : obj.swigCPtr;
+  }
 %}
 
 %typemap(javabody) TYPE (CLASS::*) %{
@@ -1273,7 +1304,7 @@
 SWIG_JAVABODY_TYPEWRAPPER(protected, protected, protected, SWIGTYPE)
 
 %typemap(javafinalize) SWIGTYPE %{
-  @SuppressWarnings("deprecation")
+  @SuppressWarnings({"deprecation", "removal"})
   protected void finalize() {
     delete();
   }
@@ -1368,10 +1399,17 @@
 %pragma(java) jniclassclassmodifiers="public class"
 %pragma(java) moduleclassmodifiers="public class"
 
-/* Some ANSI C typemaps */
+/* 64-bit architecture specific typemaps */
+#if defined(SWIGWORDSIZE64)
+%apply long long { long };
+%apply unsigned long long { unsigned long };
+%apply const long long & { const long & };
+%apply const unsigned long long & { const unsigned long & };
+#endif
 
-%apply unsigned long { size_t };
-%apply const unsigned long & { const size_t & };
+/* size_t maps to Java 64-bit (signed) long type */
+%apply unsigned int { size_t };
+%apply const unsigned int & { const size_t & };
 
 /* Array reference typemaps */
 %apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) }
diff --git a/Lib/java/javahead.swg b/Lib/java/javahead.swg
index 2e10254..758a037 100644
--- a/Lib/java/javahead.swg
+++ b/Lib/java/javahead.swg
@@ -30,18 +30,6 @@
 #endif
 
 %insert(runtime) %{
-/* Fix for jlong on some versions of gcc on Windows */
-#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
-  typedef long long __int64;
-#endif
-
-/* Fix for jlong on 64-bit x86 Solaris */
-#if defined(__x86_64)
-# ifdef _LP64
-#   undef _LP64
-# endif
-#endif
-
 #include <jni.h>
 #include <stdlib.h>
 #include <string.h>
@@ -99,5 +87,5 @@
 %insert(runtime) %{
 /* Contract support */
 
-#define SWIG_contract_assert(nullreturn, expr, msg) if (!(expr)) {SWIG_JavaThrowException(jenv, SWIG_JavaIllegalArgumentException, msg); return nullreturn; } else
+#define SWIG_contract_assert(nullreturn, expr, msg) do { if (!(expr)) {SWIG_JavaThrowException(jenv, SWIG_JavaIllegalArgumentException, msg); return nullreturn; } } while (0)
 %}
diff --git a/Lib/java/javakw.swg b/Lib/java/javakw.swg
index 99cd547..8a5b76e 100644
--- a/Lib/java/javakw.swg
+++ b/Lib/java/javakw.swg
@@ -2,7 +2,7 @@
 #define JAVA_JAVAKW_SWG_
 
 /* Warnings for Java keywords */
-#define JAVAKW(x) %keywordwarn("'" `x` "' is a java keyword, renaming to '_"`x`"'",rename="_%s")  `x`
+#define JAVAKW(x) %keywordwarn("'" `x` "' is a java keyword",rename="_%s")  `x`
 
 /*
    from
diff --git a/Lib/java/std_array.i b/Lib/java/std_array.i
index d3436cc..b5012de 100644
--- a/Lib/java/std_array.i
+++ b/Lib/java/std_array.i
@@ -4,6 +4,19 @@
 
 %include <std_common.i>
 
+%fragment("SWIG_ArraySize", "header", fragment="SWIG_JavaIntFromSize_t") {
+  SWIGINTERN jint SWIG_ArraySize(size_t size) {
+    jint sz = SWIG_JavaIntFromSize_t(size);
+    if (sz == -1) {
+      throw std::out_of_range("array size is too large to fit into a Java int");
+    }
+
+    return sz;
+  }
+}
+
+%javamethodmodifiers std::array::sizeImpl "private";
+
 namespace std {
 
   template<class T, size_t N> class array {
@@ -19,11 +32,16 @@
     array();
     array(const array& other);
 
-    size_type size() const;
     %rename(isEmpty) empty;
     bool empty() const;
     void fill(const T& u);
     %extend {
+      %fragment("SWIG_ArraySize");
+
+      jint size() const throw (std::out_of_range) {
+        return SWIG_ArraySize(self->size());
+      }
+
       const_reference get(int i) throw (std::out_of_range) {
         int size = int(self->size());
         if (i>=0 && i<size)
diff --git a/Lib/java/std_auto_ptr.i b/Lib/java/std_auto_ptr.i
index 9b3cd73..aee9b48 100644
--- a/Lib/java/std_auto_ptr.i
+++ b/Lib/java/std_auto_ptr.i
@@ -1,27 +1,41 @@
-/*
-    The typemaps here allow to handle functions returning std::auto_ptr<>,
-    which is the most common use of this type. If you have functions taking it
-    as parameter, these typemaps can't be used for them and you need to do
-    something else (e.g. use shared_ptr<> which SWIG supports fully).
- */
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
 
 %define %auto_ptr(TYPE)
-%typemap (jni) std::auto_ptr<TYPE > "jlong"
-%typemap (jtype) std::auto_ptr<TYPE > "long"
-%typemap (jstype) std::auto_ptr<TYPE > "$typemap(jstype, TYPE)"
 
-%typemap (out) std::auto_ptr<TYPE > %{
-   jlong lpp = 0;
-   *(TYPE**) &lpp = $1.release();
-   $result = lpp;
+%typemap (jni) std::auto_ptr< TYPE > "jlong"
+%typemap (jtype) std::auto_ptr< TYPE > "long"
+%typemap (jstype) std::auto_ptr< TYPE > "$typemap(jstype, TYPE)"
+
+%typemap(in) std::auto_ptr< TYPE > (TYPE *auto_temp)
+%{ auto_temp = *(TYPE **)&$input;
+  $1.reset(auto_temp); %}
+
+%typemap(javain) std::auto_ptr< TYPE > "$typemap(jstype, TYPE).swigRelease($javainput)"
+
+%typemap (out) std::auto_ptr< TYPE > %{
+  jlong lpp = 0;
+  *(TYPE **) &lpp = $1.release();
+  $result = lpp;
 %}
-%typemap(javaout) std::auto_ptr<TYPE > {
-     long cPtr = $jnicall;
-     return (cPtr == 0) ? null : new $typemap(jstype, TYPE)(cPtr, true);
-   }
-%template() std::auto_ptr<TYPE >;
+
+%typemap(javaout) std::auto_ptr< TYPE > {
+    long cPtr = $jnicall;
+    return (cPtr == 0) ? null : new $typemap(jstype, TYPE)(cPtr, true);
+  }
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *") std::auto_ptr< TYPE > ""
+
+%template() std::auto_ptr< TYPE >;
 %enddef
 
 namespace std {
-   template <class T> class auto_ptr {};
-} 
+  template <class T> class auto_ptr {};
+}
diff --git a/Lib/java/std_list.i b/Lib/java/std_list.i
index 1077bd0..896df30 100644
--- a/Lib/java/std_list.i
+++ b/Lib/java/std_list.i
@@ -168,7 +168,7 @@
 	  return **$self;
 	}
 
-	iterator advance_unchecked(size_type index) const {
+	iterator advance_unchecked(int index) const {
 	  std::list<T>::iterator ret = *$self;
 	  std::advance(ret, index);
 	  return ret;
diff --git a/Lib/java/std_map.i b/Lib/java/std_map.i
index 6d5ca1a..d9623b2 100644
--- a/Lib/java/std_map.i
+++ b/Lib/java/std_map.i
@@ -79,7 +79,7 @@
   }
 
   public $typemap(jboxtype, T) put($typemap(jboxtype, K) key, $typemap(jboxtype, T) value) {
-    Iterator itr = find(($typemap(jboxtype, K)) key);
+    Iterator itr = find(key);
     if (itr.isNot(end())) {
       $typemap(jboxtype, T) oldValue = itr.getValue();
       itr.setValue(value);
@@ -199,7 +199,11 @@
       }
 
       void putUnchecked(const K& key, const T& value) {
+%#ifdef __cpp_lib_map_try_emplace
+        (*self).insert_or_assign(key, value);
+%#else
         (*self)[key] = value;
+%#endif
       }
 
       void removeUnchecked(const std::map< K, T, C >::iterator itr) {
@@ -208,17 +212,4 @@
     }
 };
 
-// Legacy macros (deprecated)
-%define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_key ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_value ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO)
-#warning "specialize_std_map_on_both ignored - macro is deprecated and no longer necessary"
-%enddef
-
 }
diff --git a/Lib/java/std_set.i b/Lib/java/std_set.i
index 73e0c2c..053866b 100644
--- a/Lib/java/std_set.i
+++ b/Lib/java/std_set.i
@@ -96,6 +96,10 @@
       public boolean hasNext() {
         return curr.isNot(end);
       }
+
+      public void remove() {
+        throw new java.lang.UnsupportedOperationException();
+      }
     }.init();
   }
 
diff --git a/Lib/java/std_string_view.i b/Lib/java/std_string_view.i
new file mode 100644
index 0000000..c89f799
--- /dev/null
+++ b/Lib/java/std_string_view.i
@@ -0,0 +1,138 @@
+/* -----------------------------------------------------------------------------
+ * std_string_view.i
+ *
+ * Typemaps for std::string_view and const std::string_view&
+ * These are mapped to a Java String and are passed around by value.
+ *
+ * To use non-const std::string_view references use the following %apply.  Note
+ * that they are passed by value.
+ * %apply const std::string_view & {std::string_view &};
+ * ----------------------------------------------------------------------------- */
+
+%{
+#include <string_view>
+#include <string>
+%}
+
+namespace std {
+
+%naturalvar string_view;
+
+class string_view;
+
+// string_view
+%typemap(jni) string_view "jstring"
+%typemap(jtype) string_view "String"
+%typemap(jstype) string_view "String"
+%typemap(javadirectorin) string_view "$jniinput"
+%typemap(javadirectorout) string_view "$javacall"
+
+%typemap(in) string_view
+%{ if(!$input) {
+     SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string");
+     return $null;
+   }
+   const char *$1_pstr = (const char *)jenv->GetStringUTFChars($input, 0);
+   if (!$1_pstr) return $null;
+   $1 = std::string_view($1_pstr); %}
+
+/* std::string_view requires the string data to remain valid while the
+ * string_view is in use. */
+%typemap(freearg) string_view
+%{ jenv->ReleaseStringUTFChars($input, $1_pstr); %}
+
+%typemap(directorout,warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) string_view
+%{ if(!$input) {
+     if (!jenv->ExceptionCheck()) {
+       SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string");
+     }
+     return $null;
+   }
+   const char *$1_pstr = (const char *)jenv->GetStringUTFChars($input, 0);
+   if (!$1_pstr) return $null;
+   /* possible thread/reentrant code problem */
+   static std::string $1_str;
+   $1_str = $1_pstr;
+   $result = std::string_view($1_str);
+   jenv->ReleaseStringUTFChars($input, $1_pstr); %}
+
+/* std::string_view::data() isn't zero-byte terminated, but NewStringUTF()
+ * requires a zero byte so it seems we have to make a copy (ick).  The
+ * cleanest way to do that seems to be via a temporary std::string.
+ */
+%typemap(directorin,descriptor="Ljava/lang/String;") string_view
+%{ $input = jenv->NewStringUTF(std::string($1).c_str());
+   Swig::LocalRefGuard $1_refguard(jenv, $input); %}
+
+%typemap(out) string_view
+%{ $result = jenv->NewStringUTF(std::string($1).c_str()); %}
+
+%typemap(javain) string_view "$javainput"
+
+%typemap(javaout) string_view {
+    return $jnicall;
+  }
+
+%typemap(typecheck) string_view = char *;
+
+%typemap(throws) string_view
+%{ SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string($1).c_str());
+   return $null; %}
+
+// const string_view &
+%typemap(jni) const string_view & "jstring"
+%typemap(jtype) const string_view & "String"
+%typemap(jstype) const string_view & "String"
+%typemap(javadirectorin) const string_view & "$jniinput"
+%typemap(javadirectorout) const string_view & "$javacall"
+
+%typemap(in) const string_view &
+%{ if(!$input) {
+     SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string");
+     return $null;
+   }
+   const char *$1_pstr = (const char *)jenv->GetStringUTFChars($input, 0);
+   if (!$1_pstr) return $null;
+   $*1_ltype $1_str($1_pstr);
+   $1 = &$1_str; %}
+
+/* std::string_view requires the string data to remain valid while the
+ * string_view is in use. */
+%typemap(freearg) const string_view &
+%{ jenv->ReleaseStringUTFChars($input, $1_pstr); %}
+
+%typemap(directorout,warning=SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG) const string_view &
+%{ if(!$input) {
+     SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "null string");
+     return $null;
+   }
+   const char *$1_pstr = (const char *)jenv->GetStringUTFChars($input, 0);
+   if (!$1_pstr) return $null;
+   /* possible thread/reentrant code problem */
+   static std::string $1_str;
+   $1_str = $1_pstr;
+   static $*1_ltype $1_strview;
+   $1_strview = $1_str;
+   $result = &$1_strview;
+   jenv->ReleaseStringUTFChars($input, $1_pstr); %}
+
+%typemap(directorin,descriptor="Ljava/lang/String;") const string_view &
+%{ $input = jenv->NewStringUTF(std::string($1).c_str());
+   Swig::LocalRefGuard $1_refguard(jenv, $input); %}
+
+%typemap(out) const string_view &
+%{ $result = jenv->NewStringUTF(std::string(*$1).c_str()); %}
+
+%typemap(javain) const string_view & "$javainput"
+
+%typemap(javaout) const string_view & {
+    return $jnicall;
+  }
+
+%typemap(typecheck) const string_view & = char *;
+
+%typemap(throws) const string_view &
+%{ SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, std::string($1).c_str());
+   return $null; %}
+
+}
diff --git a/Lib/java/std_unique_ptr.i b/Lib/java/std_unique_ptr.i
new file mode 100644
index 0000000..838ca49
--- /dev/null
+++ b/Lib/java/std_unique_ptr.i
@@ -0,0 +1,41 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+
+%typemap (jni) std::unique_ptr< TYPE > "jlong"
+%typemap (jtype) std::unique_ptr< TYPE > "long"
+%typemap (jstype) std::unique_ptr< TYPE > "$typemap(jstype, TYPE)"
+
+%typemap(in) std::unique_ptr< TYPE > (TYPE *unique_temp)
+%{ unique_temp = *(TYPE **)&$input;
+  $1.reset(unique_temp); %}
+
+%typemap(javain) std::unique_ptr< TYPE > "$typemap(jstype, TYPE).swigRelease($javainput)"
+
+%typemap (out) std::unique_ptr< TYPE > %{
+  jlong lpp = 0;
+  *(TYPE **) &lpp = $1.release();
+  $result = lpp;
+%}
+
+%typemap(javaout) std::unique_ptr< TYPE > {
+    long cPtr = $jnicall;
+    return (cPtr == 0) ? null : new $typemap(jstype, TYPE)(cPtr, true);
+  }
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *") std::unique_ptr< TYPE > ""
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class unique_ptr {};
+}
diff --git a/Lib/java/std_unordered_map.i b/Lib/java/std_unordered_map.i
index 283a9b4..2d93395 100644
--- a/Lib/java/std_unordered_map.i
+++ b/Lib/java/std_unordered_map.i
@@ -199,7 +199,11 @@
       }
 
       void putUnchecked(const K& key, const T& value) {
+%#ifdef __cpp_lib_map_try_emplace
+        (*self).insert_or_assign(key, value);
+%#else
         (*self)[key] = value;
+%#endif
       }
 
       void removeUnchecked(const std::unordered_map< K, T >::iterator itr) {
diff --git a/Lib/java/std_unordered_set.i b/Lib/java/std_unordered_set.i
index 59726e9..ddcedf0 100644
--- a/Lib/java/std_unordered_set.i
+++ b/Lib/java/std_unordered_set.i
@@ -92,6 +92,10 @@
       public boolean hasNext() {
         return curr.isNot(end);
       }
+
+      public void remove() {
+        throw new java.lang.UnsupportedOperationException();
+      }
     }.init();
   }
 
diff --git a/Lib/java/std_vector.i b/Lib/java/std_vector.i
index 60ee23e..dee48fa 100644
--- a/Lib/java/std_vector.i
+++ b/Lib/java/std_vector.i
@@ -75,6 +75,14 @@
   public int size() {
     return doSize();
   }
+
+  public int capacity() {
+    return doCapacity();
+  }
+
+  public void reserve(int n) {
+    doReserve(n);
+  }
 %}
 
   public:
@@ -89,8 +97,6 @@
     vector();
     vector(const vector &other);
 
-    size_type capacity() const;
-    void reserve(size_type n) throw (std::length_error);
     %rename(isEmpty) empty;
     bool empty() const;
     void clear();
@@ -103,6 +109,16 @@
         return new std::vector< CTYPE >(static_cast<std::vector< CTYPE >::size_type>(count), value);
       }
 
+      jint doCapacity() throw (std::out_of_range) {
+        return SWIG_VectorSize(self->capacity());
+      }
+
+      void doReserve(jint n) throw (std::length_error, std::out_of_range) {
+        if (n < 0)
+          throw std::out_of_range("vector reserve size must be positive");
+        self->reserve(n);
+      }
+
       jint doSize() const throw (std::out_of_range) {
         return SWIG_VectorSize(self->size());
       }
@@ -161,6 +177,8 @@
     }
 %enddef
 
+%javamethodmodifiers std::vector::doCapacity    "private";
+%javamethodmodifiers std::vector::doReserve     "private";
 %javamethodmodifiers std::vector::doSize        "private";
 %javamethodmodifiers std::vector::doAdd         "private";
 %javamethodmodifiers std::vector::doGet         "private";
diff --git a/Lib/java/std_wstring.i b/Lib/java/std_wstring.i
index dd0b2f5..efa9e63 100644
--- a/Lib/java/std_wstring.i
+++ b/Lib/java/std_wstring.i
@@ -60,7 +60,7 @@
  %}
 
 %typemap(directorin,descriptor="Ljava/lang/String;") wstring %{
-  jsize $1_len = $1.length();
+  jsize $1_len = (jsize)$1.length();
   jchar *$1_conv_buf = new jchar[$1_len];
   for (jsize i = 0; i < $1_len; ++i) {
     $1_conv_buf[i] = (jchar)$1[i];
@@ -71,7 +71,7 @@
 %}
 
 %typemap(out) wstring
-%{jsize $1_len = $1.length();
+%{jsize $1_len = (jsize)$1.length();
   jchar *conv_buf = new jchar[$1_len];
   for (jsize i = 0; i < $1_len; ++i) {
     conv_buf[i] = (jchar)$1[i];
@@ -88,9 +88,12 @@
 //%typemap(typecheck) wstring = wchar_t *;
 
 %typemap(throws) wstring
-%{ std::string message($1.begin(), $1.end());
-   SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, message.c_str());
-   return $null; %}
+%{std::string message($1.size(), '\0');
+  for (size_t i = 0; i < $1.size(); ++i) {
+    message[i] = (char)$1[i];
+  }
+  SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, message.c_str());
+  return $null; %}
 
 // const wstring &
 %typemap(jni) const wstring & "jstring"
@@ -138,7 +141,7 @@
   jenv->ReleaseStringChars($input, $1_pstr); %}
 
 %typemap(directorin,descriptor="Ljava/lang/String;") const wstring & %{
-  jsize $1_len = $1.length();
+  jsize $1_len = (jsize)$1.length();
   jchar *$1_conv_buf = new jchar[$1_len];
   for (jsize i = 0; i < $1_len; ++i) {
     $1_conv_buf[i] = (jchar)($1)[i];
@@ -149,7 +152,7 @@
 %}
 
 %typemap(out) const wstring & 
-%{jsize $1_len = $1->length();
+%{jsize $1_len = (jsize)$1->length();
   jchar *conv_buf = new jchar[$1_len];
   for (jsize i = 0; i < $1_len; ++i) {
     conv_buf[i] = (jchar)(*$1)[i];
@@ -166,9 +169,12 @@
 //%typemap(typecheck) const wstring & = wchar_t *;
 
 %typemap(throws) const wstring &
-%{ std::string message($1.begin(), $1.end());
-   SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, message.c_str());
-   return $null; %}
+%{std::string message($1.size(), '\0');
+  for (size_t i = 0; i < $1.size(); ++i) {
+    message[i] = (char)$1[i];
+  }
+  SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, message.c_str());
+  return $null; %}
 
 }
 
diff --git a/Lib/java/swiginterface.i b/Lib/java/swiginterface.i
index 3344641..c3ca97d 100644
--- a/Lib/java/swiginterface.i
+++ b/Lib/java/swiginterface.i
@@ -28,7 +28,7 @@
   }
 %typemap(javaout) CTYPE *const& {
     long cPtr = $jnicall;
-    return (cPtr == 0) ? null : ($javainterfacename)new $javaclassname(cPtr, $owner);
+    return (cPtr == 0) ? null : ($*javainterfacename)new $*javaclassname(cPtr, $owner);
   }
 
 %typemap(javadirectorin) CTYPE "($&javainterfacename)new $&javaclassname($jniinput, true)"
@@ -40,7 +40,7 @@
 %typemap(javadirectorout) CTYPE *const& "$javacall.$*interfacename_GetInterfaceCPtr()"
 %typemap(directorin,descriptor="L$packagepath/$&javainterfacename;") CTYPE
 %{ $input = 0;
-   *(($&1_ltype*)&$input) = new $1_ltype((const $1_ltype &)$1); %}
+   *(($&1_ltype*)&$input) = new $1_ltype(SWIG_STD_MOVE($1)); %}
 %typemap(directorin,descriptor="L$packagepath/$javainterfacename;") CTYPE *, CTYPE []
 %{ *(($&1_ltype)&$input) = ($1_ltype) $1; %}
 %typemap(directorin,descriptor="L$packagepath/$javainterfacename;") CTYPE &
diff --git a/Lib/java/swigmove.i b/Lib/java/swigmove.i
new file mode 100644
index 0000000..671b988
--- /dev/null
+++ b/Lib/java/swigmove.i
@@ -0,0 +1,16 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in) SWIGTYPE MOVE ($&1_type argp)
+%{ argp = *($&1_ltype*)&$input; 
+   if (!argp) {
+     SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null $1_type");
+     return $null;
+   }
+  SwigValueWrapper< $1_ltype >::reset($1, argp); %}
+
+%typemap(javain) SWIGTYPE MOVE "$&javaclassname.swigRelease($javainput)"
diff --git a/Lib/java/typemaps.i b/Lib/java/typemaps.i
index e130c19..658a6b1 100644
--- a/Lib/java/typemaps.i
+++ b/Lib/java/typemaps.i
@@ -527,3 +527,23 @@
 
 %typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT;
 %typemap(argout) unsigned long long &INOUT = unsigned long long &OUTPUT;
+
+#if defined(SWIGWORDSIZE64)
+%apply long long *INPUT { long *INPUT };
+%apply unsigned long long *INPUT { unsigned long *INPUT };
+
+%apply long long &INPUT { long &INPUT };
+%apply unsigned long long &INPUT { unsigned long &INPUT };
+
+%apply long long *INOUT { long *INOUT };
+%apply unsigned long long *INOUT { unsigned long *INOUT };
+
+%apply long long &INOUT { long &INOUT };
+%apply unsigned long long &INOUT { unsigned long &INOUT };
+
+%apply long long *OUTPUT { long *OUTPUT };
+%apply unsigned long long *OUTPUT { unsigned long *OUTPUT };
+
+%apply long long &OUTPUT { long &OUTPUT };
+%apply unsigned long long &OUTPUT { unsigned long &OUTPUT };
+#endif
diff --git a/Lib/javascript/jsc/argcargv.i b/Lib/javascript/jsc/argcargv.i
new file mode 100644
index 0000000..dacecb0
--- /dev/null
+++ b/Lib/javascript/jsc/argcargv.i
@@ -0,0 +1,67 @@
+/* ------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------ */
+
+%{
+SWIGINTERN int SWIG_AsVal_string SWIG_JSC_AS_DECL_ARGS(JSValueRef obj, JSStringRef* str)
+{
+  if (!JSValueIsString SWIG_JSC_FROM_CALL_ARGS(obj)) {
+    return SWIG_TypeError;
+  }
+  if(str != SWIG_NULLPTR) {
+    *str = JSValueToStringCopy SWIG_JSC_AS_CALL_ARGS(obj, SWIG_NULLPTR);
+  }
+  return SWIG_OK;
+}
+%}
+
+%typemap(in) (int ARGC, char **ARGV) {
+  int i, len;
+  size_t arraysize;
+  JSObjectRef array;
+  if (!JSValueIsArray SWIG_JSC_FROM_CALL_ARGS($input)) {
+    SWIG_exception_fail(SWIG_ERROR, "not array");
+  }
+  array = JSValueToObject SWIG_JSC_AS_CALL_ARGS($input, SWIG_NULLPTR);
+  len = SWIGJSC_ArrayLength SWIG_JSC_FROM_CALL_ARGS(array);
+  arraysize = (len+1)*sizeof($*2_ltype);
+  $1 = len;
+  $2 = ($2_ltype) malloc(arraysize);
+  if ($2 == SWIG_NULLPTR) {
+    SWIG_exception_fail(SWIG_ERROR, "memory allocation of array failed");
+  }
+  memset($2, 0, arraysize);
+  for (i = 0; i < len; i++) {
+    int res, slen;
+    $*2_ltype pstr;
+    JSStringRef str;
+    JSValueRef jsvalue = JSObjectGetPropertyAtIndex(context, array, i, SWIG_NULLPTR);
+    res = SWIG_AsVal_string SWIG_JSC_AS_CALL_ARGS(jsvalue, &str);
+    if (!SWIG_IsOK(res)) {
+      SWIG_exception_fail(SWIG_ERROR, "failed to convert to string");
+    }
+    slen = JSStringGetMaximumUTF8CStringSize(str);
+    pstr = ($*2_ltype) malloc(slen);
+    if (pstr == SWIG_NULLPTR) {
+      SWIG_exception_fail(SWIG_ERROR, "memory allocation of a string failed");
+    }
+    if (slen) {
+      res = JSStringGetUTF8CString(str, pstr, slen);
+      if (res > slen) {
+        SWIG_exception_fail(SWIG_ERROR, "wrong string length");
+      }
+    }
+    $2[i] = pstr;
+  }
+  $2[i] = SWIG_NULLPTR;
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+  if ($2 != SWIG_NULLPTR) {
+    $1_ltype i;
+    for (i = 0; i < $1; i++) {
+      free((void *)$2[i]);
+    }
+    free((void *)$2);
+  }
+}
diff --git a/Lib/javascript/jsc/arrays_javascript.i b/Lib/javascript/jsc/arrays_javascript.i
index b9199d8..713b7ef 100644
--- a/Lib/javascript/jsc/arrays_javascript.i
+++ b/Lib/javascript/jsc/arrays_javascript.i
@@ -21,34 +21,39 @@
  *   fs = example.FiddleSticks;
  * ----------------------------------------------------------------------------- */
 
-%fragment("SWIG_JSCGetIntProperty",    "header", fragment=SWIG_AsVal_frag(int)) {}
+
+%fragment("SWIG_JSCGetIntProperty", "header", fragment=SWIG_AsVal_frag(int)) {}
 %fragment("SWIG_JSCGetNumberProperty", "header", fragment=SWIG_AsVal_frag(double)) {}
+%fragment("SWIG_JSCOutInt", "header", fragment=SWIG_From_frag(int)) {}
+%fragment("SWIG_JSCOutNumber", "header", fragment=SWIG_From_frag(double)) {}
 
-%typemap(in, fragment="SWIG_JSCGetIntProperty") int[], int[ANY]
-    (int length = 0, JSObjectRef array, JSValueRef jsvalue, int i = 0, int res = 0, $*1_ltype temp) {
+%define JAVASCRIPT_ARRAYS_IN_DECL(NAME, CTYPE, ANY, ANYLENGTH)
+
+%typemap(in, fragment=NAME) CTYPE[ANY] {
   if (JSValueIsObject(context, $input))
   {
+    int i;
     // Convert into Array
-    array = JSValueToObject(context, $input, NULL);
+    JSObjectRef array = JSValueToObject(context, $input, NULL);
 
-    length = $1_dim0;
+    int length = ANYLENGTH;
 
     $1  = ($*1_ltype *)malloc(sizeof($*1_ltype) * length);
 
     // Get each element from array
     for (i = 0; i < length; i++)
     {
-      jsvalue = JSObjectGetPropertyAtIndex(context, array, i, NULL);
+      JSValueRef jsvalue = JSObjectGetPropertyAtIndex(context, array, i, NULL);
+      $*1_ltype temp;
 
       // Get primitive value from JSObject
-      res = SWIG_AsVal(int)(jsvalue, &temp);
+      int res = SWIG_AsVal(CTYPE)(jsvalue, &temp);
       if (!SWIG_IsOK(res))
       {
         SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double");
       }
       arg$argnum[i] = temp;
     }
-
   }
   else
   {
@@ -56,68 +61,34 @@
   }
 }
 
-%typemap(freearg) int[], int[ANY] {
+%typemap(freearg) CTYPE[ANY] {
     free($1);
 }
 
-%typemap(out, fragment=SWIG_From_frag(int)) int[], int[ANY] (int length = 0, int i = 0)
-{
-  length = $1_dim0;
+%enddef
+
+%define JAVASCRIPT_ARRAYS_OUT_DECL(NAME, CTYPE)
+
+%typemap(out, fragment=NAME) CTYPE[ANY] {
+  int length = $1_dim0;
   JSValueRef values[length];
+  int i;
 
   for (i = 0; i < length; i++)
   {
-    values[i] = SWIG_From(int)($1[i]);
+    values[i] = SWIG_From(CTYPE)($1[i]);
   }
 
   $result = JSObjectMakeArray(context, length, values, NULL);
 }
 
-%typemap(in, fragment="SWIG_JSCGetNumberProperty") double[], double[ANY]
-    (int length = 0, JSObjectRef array, JSValueRef jsvalue, int i = 0, int res = 0, $*1_ltype temp) {
-  if (JSValueIsObject(context, $input))
-  {
-    // Convert into Array
-    array = JSValueToObject(context, $input, NULL);
+%enddef
 
-    length = $1_dim0;
+JAVASCRIPT_ARRAYS_IN_DECL("SWIG_JSCGetIntProperty", int, , SWIGJSC_ArrayLength(context, array))
+JAVASCRIPT_ARRAYS_IN_DECL("SWIG_JSCGetIntProperty", int, ANY, $1_dim0)
+JAVASCRIPT_ARRAYS_IN_DECL("SWIG_JSCGetNumberProperty", double, , SWIGJSC_ArrayLength(context, array))
+JAVASCRIPT_ARRAYS_IN_DECL("SWIG_JSCGetNumberProperty", double, ANY, $1_dim0)
 
-    $1  = ($*1_ltype *)malloc(sizeof($*1_ltype) * length);
+JAVASCRIPT_ARRAYS_OUT_DECL("SWIG_JSCOutInt", int)
+JAVASCRIPT_ARRAYS_OUT_DECL("SWIG_JSCOutNumber", double)
 
-    // Get each element from array
-    for (i = 0; i < length; i++)
-    {
-      jsvalue = JSObjectGetPropertyAtIndex(context, array, i, NULL);
-
-      // Get primitive value from JSObject
-      res = SWIG_AsVal(double)(jsvalue, &temp);
-      if (!SWIG_IsOK(res))
-      {
-        SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double");
-      }
-      arg$argnum[i] = temp;
-    }
-
-  }
-  else
-  {
-    SWIG_exception_fail(SWIG_ERROR, "$input is not JSObjectRef");
-  }
-}
-
-%typemap(freearg) double[], double[ANY] {
-    free($1);
-}
-
-%typemap(out, fragment=SWIG_From_frag(double)) double[], double[ANY] (int length = 0, int i = 0)
-{
-  length = $1_dim0;
-  JSValueRef values[length];
-
-  for (i = 0; i < length; i++)
-  {
-    values[i] = SWIG_From(double)($1[i]);
-  }
-
-  $result = JSObjectMakeArray(context, length, values, NULL);
-}
diff --git a/Lib/javascript/jsc/ccomplex.i b/Lib/javascript/jsc/ccomplex.i
index 50f0f95..e58dbf7 100644
--- a/Lib/javascript/jsc/ccomplex.i
+++ b/Lib/javascript/jsc/ccomplex.i
@@ -12,15 +12,16 @@
 #include <complex.h>
 %}
 
+#define complex _Complex
 
 /* C complex constructor */
 #define CCplxConst(r, i) ((r) + I*(i))
 
-%swig_cplxflt_convn(float complex, CCplxConst, creal, cimag);
-%swig_cplxdbl_convn(double complex, CCplxConst, creal, cimag);
-%swig_cplxdbl_convn(complex, CCplxConst, creal, cimag);
+%swig_cplxflt_convn(float _Complex, CCplxConst, creal, cimag);
+%swig_cplxdbl_convn(double _Complex, CCplxConst, creal, cimag);
+%swig_cplxdbl_convn(_Complex, CCplxConst, creal, cimag);
 
 /* declaring the typemaps */
-%typemaps_primitive(SWIG_TYPECHECK_CPLXFLT, float complex);
-%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, double complex);
-%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, complex);
+%typemaps_primitive(SWIG_TYPECHECK_CPLXFLT, float _Complex);
+%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, double _Complex);
+%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, _Complex);
diff --git a/Lib/javascript/jsc/cmalloc.i b/Lib/javascript/jsc/cmalloc.i
new file mode 100644
index 0000000..248f06b
--- /dev/null
+++ b/Lib/javascript/jsc/cmalloc.i
@@ -0,0 +1 @@
+%include <typemaps/cmalloc.swg>
diff --git a/Lib/javascript/jsc/factory.i b/Lib/javascript/jsc/factory.i
new file mode 100644
index 0000000..46a0a87
--- /dev/null
+++ b/Lib/javascript/jsc/factory.i
@@ -0,0 +1 @@
+%include <typemaps/factory.swg>
diff --git a/Lib/javascript/jsc/javascriptcode.swg b/Lib/javascript/jsc/javascriptcode.swg
index 4050a6e..e560200 100644
--- a/Lib/javascript/jsc/javascriptcode.swg
+++ b/Lib/javascript/jsc/javascriptcode.swg
@@ -4,6 +4,7 @@
  *   - $jslocals:         locals part of wrapper
  *   - $jscode:           code part of wrapper
  *   - $jsargcount:       number of arguments
+ *   - $jsargrequired:    required number of arguments
  *   - $jsmangledtype:    mangled type of class
  * ----------------------------------------------------------------------------- */
 %fragment ("js_ctor", "templates")
@@ -11,7 +12,7 @@
 static JSObjectRef $jswrapper(JSContextRef context, JSObjectRef thisObject, size_t argc, const JSValueRef argv[], JSValueRef* exception)
 {
     $jslocals
-    if(argc != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper.");
+    if (argc < $jsargrequired || argc > $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper.");
 
     $jscode
     return SWIG_JSC_NewPointerObj(context, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN);
@@ -67,6 +68,7 @@
  *   - $jslocals:         locals part of wrapper
  *   - $jscode:           code part of wrapper
  *   - $jsargcount:       number of arguments
+ *   - $jsargrequired:    required number of arguments
  *   - $jsmangledtype:    mangled type of class
  * ----------------------------------------------------------------------------- */
 %fragment ("js_overloaded_ctor", "templates")
@@ -86,13 +88,14 @@
 /* -----------------------------------------------------------------------------
  * js_ctor_dispatch_case:  template for a dispatch case for calling an overloaded ctor.
  *   - $jsargcount:       number of arguments of called ctor
+ *   - $jsargrequired:    required number of arguments
  *   - $jswrapper:        wrapper of called ctor
  *
  *  Note: a try-catch-like mechanism is used to switch cases
  * ----------------------------------------------------------------------------- */
 %fragment ("js_ctor_dispatch_case", "templates")
 %{
-  if(argc == $jsargcount) {
+  if(argc >= $jsargrequired && argc <= $jsargcount) {
     thisObject = $jswrapper(context, NULL, argc, argv, exception);
     if(thisObject != NULL) { *exception=0; return thisObject; } /* reset exception and return */
   }
@@ -187,9 +190,11 @@
 
 /* -----------------------------------------------------------------------------
  * js_function:  template for function wrappers
- *   - $jswrapper:  wrapper function name
- *   - $jslocals:   locals part of wrapper
- *   - $jscode:     code part of wrapper
+ *   - $jswrapper:     wrapper function name
+ *   - $jslocals:      locals part of wrapper
+ *   - $jsargcount:    number of arguments
+ *   - $jsargrequired: required number of arguments
+ *   - $jscode:        code part of wrapper
  * ----------------------------------------------------------------------------- */
 %fragment ("js_function", "templates")
 %{
@@ -198,7 +203,7 @@
   $jslocals
   JSValueRef jsresult;
 
-  if(argc != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper.");
+  if (argc < $jsargrequired || argc > $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper.");
 
   $jscode
   return jsresult;
@@ -236,9 +241,11 @@
 
 /* -----------------------------------------------------------------------------
  * js_overloaded_function:  template for a overloaded function
- *   - $jswrapper:  wrapper function name
- *   - $jslocals:   locals part of wrapper
- *   - $jscode:     code part of wrapper
+ *   - $jswrapper:     wrapper function name
+ *   - $jslocals:      locals part of wrapper
+ *   - $jsargcount:    required number of arguments
+ *   - $jsargrequired: required number of arguments
+ *   - $jscode:        code part of wrapper
  * ----------------------------------------------------------------------------- */
 %fragment ("js_overloaded_function", "templates")
 %{
@@ -247,7 +254,7 @@
   $jslocals
   JSValueRef jsresult;
 
-  if(argc != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper.");
+  if (argc < $jsargrequired || argc > $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper.");
 
   $jscode
   *p_result = jsresult;
@@ -261,19 +268,27 @@
 
 /* -----------------------------------------------------------------------------
  * js_function_dispatch_case:  template for a case used in the function dispatcher
- *   - $jswrapper:  wrapper function name
- *   - $jsargcount: number of arguments of overloaded function
- *   - $jscode:     code part of wrapper
+ *   - $jswrapper:     wrapper function name
+ *   - $jsargcount:    number of arguments of overloaded function
+ *   - $jsargrequired: required number of arguments
+ *   - $jscode:        code part of wrapper
  * ----------------------------------------------------------------------------- */
 %fragment ("js_function_dispatch_case", "templates")
 %{
-  if(argc == $jsargcount) {
+  if(argc >= $jsargrequired && argc <= $jsargcount) {
      res = $jswrapper(context, function, thisObject, argc, argv, exception, &jsresult);
      if(res == SWIG_OK) { *exception = 0; return jsresult; }
   }
 %}
 
 /* -----------------------------------------------------------------------------
+ * js_check_arg:  template for checking if an argument exists
+ *   - $jsarg: number of argument
+ * ----------------------------------------------------------------------------- */
+%fragment ("js_check_arg", "templates")
+%{if(argc > $jsarg)%}
+
+/* -----------------------------------------------------------------------------
  * jsc_variable_declaration:  template for a variable table entry
  *   - $jsname:       name of the variable
  *   - $jsgetter:     wrapper of getter function
diff --git a/Lib/javascript/jsc/javascriptcomplex.swg b/Lib/javascript/jsc/javascriptcomplex.swg
index 7be120b..dcc205d 100644
--- a/Lib/javascript/jsc/javascriptcomplex.swg
+++ b/Lib/javascript/jsc/javascriptcomplex.swg
@@ -127,7 +127,7 @@
     float re;
     int res = SWIG_AddCast(SWIG_AsVal(float)(o, &re));
     if (SWIG_IsOK(res)) {
-      if (val) *val = Constructor(re, 0.0);
+      if (val) *val = Constructor(re, 0.0f);
       return res;
     }
   }
diff --git a/Lib/javascript/jsc/javascripthelpers.swg b/Lib/javascript/jsc/javascripthelpers.swg
index 4576543..bdd5142 100644
--- a/Lib/javascript/jsc/javascripthelpers.swg
+++ b/Lib/javascript/jsc/javascripthelpers.swg
@@ -46,7 +46,7 @@
     int res;
     
     JSStringGetUTF8CString(propertyName, buffer, 256);
-    res = sprintf(msg, "Tried to write read-only variable: %s.", buffer);
+    res = SWIG_snprintf(msg, sizeof(msg), "Tried to write read-only variable: %s.", buffer);
     
     if(res<0) {
       SWIG_exception(SWIG_ERROR, "Tried to write read-only variable.");
diff --git a/Lib/javascript/jsc/javascriptinit.swg b/Lib/javascript/jsc/javascriptinit.swg
index a32ba33..b0138b3 100644
--- a/Lib/javascript/jsc/javascriptinit.swg
+++ b/Lib/javascript/jsc/javascriptinit.swg
@@ -1,14 +1,59 @@
 %insert(init) %{
 SWIGRUNTIME void
-SWIG_JSC_SetModule(swig_module_info *swig_module) {}
+SWIG_JSC_SetModule(JSGlobalContextRef context, swig_module_info *swig_module) {
+    JSObjectRef globalObject;
+    JSStringRef moduleName;
+    JSClassDefinition classDef;
+    JSClassRef classRef;
+    JSObjectRef object;
 
+    if(context == 0){
+        return;
+    }
+
+    globalObject = JSContextGetGlobalObject(context);
+    moduleName = JSStringCreateWithUTF8CString("swig_module_info_data");
+
+    classDef  = kJSClassDefinitionEmpty;
+    classRef = JSClassCreate(&classDef);
+
+    object = JSObjectMake(context, classRef, NULL);
+    JSObjectSetPrivate(object, (void*)swig_module);
+
+    JSObjectSetProperty(context, globalObject, moduleName, object, kJSPropertyAttributeNone, NULL);
+
+    JSClassRelease(classRef);
+    JSStringRelease(moduleName);
+}
 SWIGRUNTIME swig_module_info *
-SWIG_JSC_GetModule(void) {
-  return 0;
+SWIG_JSC_GetModule(JSGlobalContextRef context) {
+    JSObjectRef globalObject;
+    JSStringRef moduleName;
+    JSValueRef value;
+    JSObjectRef object;
+
+    if(context == 0){
+        return 0;
+    }
+
+    globalObject = JSContextGetGlobalObject(context);
+    moduleName = JSStringCreateWithUTF8CString("swig_module_info_data");
+
+    if(JSObjectHasProperty(context, globalObject, moduleName) == false) {
+        JSStringRelease(moduleName);
+        return 0;
+    }
+
+    value = JSObjectGetProperty(context, globalObject, moduleName, NULL);
+    object = JSValueToObject(context, value, NULL);
+    JSStringRelease(moduleName);
+
+    return (swig_module_info*)JSObjectGetPrivate(object);
 }
 
-#define SWIG_GetModule(clientdata)                SWIG_JSC_GetModule()
-#define SWIG_SetModule(clientdata, pointer)       SWIG_JSC_SetModule(pointer)
+#define SWIG_GetModule(clientdata)                SWIG_JSC_GetModule(clientdata)
+#define SWIG_SetModule(clientdata, pointer)       SWIG_JSC_SetModule(clientdata, pointer)
+#define SWIG_INIT_CLIENT_DATA_TYPE                JSGlobalContextRef
 %}
 
 %insert(init) "swiginit.swg"
@@ -26,7 +71,7 @@
 #endif
 
 bool SWIGJSC_INIT (JSGlobalContextRef context, JSObjectRef *exports) {
-    SWIG_InitializeModule(0);
+    SWIG_InitializeModule(context);
 %}
 
 /* -----------------------------------------------------------------------------
diff --git a/Lib/javascript/jsc/javascriptkw.swg b/Lib/javascript/jsc/javascriptkw.swg
deleted file mode 100644
index c3c1183..0000000
--- a/Lib/javascript/jsc/javascriptkw.swg
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef JAVASCRIPT_JAVASCRIPTKW_SWG_
-#define JAVASCRIPT_JAVASCRIPTKW_SWG_
-
-/* Warnings for Java keywords */
-#define JAVASCRIPTKW(x) %keywordwarn("'" `x` "' is a javascript keyword, renaming to '_"`x`"'",rename="_%s")  `x`
-
-/* Taken from https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Reserved_Words */
-
-JAVASCRIPTKW(break);
-JAVASCRIPTKW(case);
-JAVASCRIPTKW(catch);
-JAVASCRIPTKW(continue);
-JAVASCRIPTKW(default);
-JAVASCRIPTKW(delete);
-JAVASCRIPTKW(do);
-JAVASCRIPTKW(else);
-JAVASCRIPTKW(finally);
-JAVASCRIPTKW(for);
-JAVASCRIPTKW(function);
-JAVASCRIPTKW(if);
-JAVASCRIPTKW(in);
-JAVASCRIPTKW(instanceof);
-JAVASCRIPTKW(new);
-JAVASCRIPTKW(return);
-JAVASCRIPTKW(switch);
-JAVASCRIPTKW(this);
-JAVASCRIPTKW(throw);
-JAVASCRIPTKW(try);
-JAVASCRIPTKW(typeof);
-JAVASCRIPTKW(var);
-JAVASCRIPTKW(void);
-JAVASCRIPTKW(while);
-JAVASCRIPTKW(with);
-
-/* others bad names if any*/
-// for example %namewarn("321:clone() is a javascript bad method name") *::clone();
-
-#undef JAVASCRIPTKW
-
-#endif //JAVASCRIPT_JAVASCRIPTKW_SWG_
diff --git a/Lib/javascript/jsc/javascriptrun.swg b/Lib/javascript/jsc/javascriptrun.swg
index 4a8fc5b..ee68c57 100644
--- a/Lib/javascript/jsc/javascriptrun.swg
+++ b/Lib/javascript/jsc/javascriptrun.swg
@@ -7,23 +7,27 @@
 #define SWIG_exception(code, msg) do { SWIG_JSC_exception(context, exception, code, msg); SWIG_fail; } while (0)
 #define SWIG_fail                 goto fail
 
-SWIGRUNTIME void SWIG_Javascript_Raise(JSContextRef context, JSValueRef *exception, const char* type) {
-  JSStringRef message = JSStringCreateWithUTF8CString(type);
+SWIGRUNTIME void SWIG_Javascript_Raise_ValueRef(JSContextRef context, JSValueRef *exception, JSValueRef valRef) {
   JSValueRef error_arguments[1]; 
   JSObjectRef exception_object;
-  JSValueRef exception_value;
-  exception_value = JSValueMakeString(context, message);
   /* Converting the result to an object will let JavascriptCore add 
      "sourceURL" (file) and "line" (number) and "message" to the exception,
      instead of just returning a raw string. This is extremely important for debugging your errors.
      Using JSObjectMakeError is better than JSValueToObject because the latter only populates
      "sourceURL" and "line", but not "message" or any others I don't know about.
    */
-  error_arguments[0] = exception_value;
+  error_arguments[0] = valRef;
   exception_object = JSObjectMakeError(context, 1, error_arguments, NULL);
 
   /* Return the exception_object */
   *exception = exception_object;
+}
+
+SWIGRUNTIME void SWIG_Javascript_Raise(JSContextRef context, JSValueRef *exception, const char* msg) {
+  JSStringRef message = JSStringCreateWithUTF8CString(msg);
+  JSValueRef exception_value = JSValueMakeString(context, message);
+
+  SWIG_Javascript_Raise_ValueRef(context, exception, exception_value);
 
   JSStringRelease(message);
 }
@@ -117,28 +121,33 @@
   SwigPrivData *cdata;
 
   cdata = (SwigPrivData *) JSObjectGetPrivate(objRef);
-  if(cdata == NULL) {
+  if (cdata == NULL) {
     return SWIG_ERROR;
   }
-  if(cdata->info != info) {
-    bool type_valid = false;
-    swig_cast_info *t = info->cast;
-    while(t != NULL) {
-      if(t->type == cdata->info) {
-        type_valid = true;
-        break;
-      }
-      t = t->next;
-    }
-    if(!type_valid) {
-      return SWIG_TypeError;
+  assert(ptr);
+  *ptr = NULL;
+  if (!info || cdata->info == info) {
+    *ptr = cdata->swigCObject;
+  } else {
+    swig_cast_info *tc = SWIG_TypeCheckStruct(cdata->info, info);
+    if (tc) {
+      int newmemory = 0;
+      *ptr = SWIG_TypeCast(tc, cdata->swigCObject, &newmemory);
+      assert(!newmemory); /* newmemory handling not yet implemented */
+    } else {
+      return SWIG_ERROR;
     }
   }
 
-  *ptr = cdata->swigCObject;
-
-  if(flags & SWIG_POINTER_DISOWN) {
-    cdata->swigCMemOwn = false;
+  if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !cdata->swigCMemOwn) {
+    return SWIG_ERROR_RELEASE_NOT_OWNED;
+  } else {
+    if (flags & SWIG_POINTER_DISOWN) {
+      cdata->swigCMemOwn = false;
+    }
+    if (flags & SWIG_POINTER_CLEAR) {
+      cdata->swigCObject = 0;
+    }
   }
 
   return SWIG_OK;
@@ -264,11 +273,12 @@
 SWIGRUNTIME
 JSValueRef SWIG_JSC_NewPackedObj(JSContextRef context, void *data, size_t size, swig_type_info *type) {
 
-  JSClassRef classRef = _SwigObject_classRef;
+  JSClassRef classRef = _SwigPackedData_classRef;
   JSObjectRef result = JSObjectMake(context, classRef, NULL);
 
   SwigPackedData* cdata = (SwigPackedData*) malloc(sizeof(SwigPackedData));
-  cdata->data = data;
+  cdata->data = malloc(size);
+  memcpy(cdata->data, data, size);
   cdata->size = size;
   cdata->type = type;
 
@@ -318,12 +328,38 @@
 }
 
 SWIGRUNTIME
+bool SWIGJSC_ValueIsArray(JSContextRef context, JSValueRef value) {
+  if (JSValueIsObject(context, value)) {
+    static JSStringRef ArrayString = NULL;
+    static JSStringRef isArrayString = NULL;
+    JSObjectRef array = NULL;
+    JSObjectRef isArray = NULL;
+    JSValueRef retval = NULL;
+
+    if (!ArrayString)
+      ArrayString = JSStringCreateWithUTF8CString("Array");
+    if (!isArrayString)
+      isArrayString = JSStringCreateWithUTF8CString("isArray");
+
+    array = (JSObjectRef)JSObjectGetProperty(context, JSContextGetGlobalObject(context), ArrayString, NULL);
+    isArray = (JSObjectRef)JSObjectGetProperty(context, array, isArrayString, NULL);
+    retval = JSObjectCallAsFunction(context, isArray, NULL, 1, &value, NULL);
+
+    if (JSValueIsBoolean(context, retval))
+      return JSValueToBoolean(context, retval);
+  }
+  return false;
+}
+
+SWIGRUNTIME
 JSValueRef SWIGJSC_AppendOutput(JSContextRef context, JSValueRef value, JSValueRef obj) {
   JSObjectRef arr;
   unsigned int length;
 
   if (JSValueIsUndefined(context, value)) {
     arr = JSObjectMakeArray(context, 0, 0, 0);
+  } else if (!SWIGJSC_ValueIsArray(context, value)) {
+    arr = JSObjectMakeArray(context, 1, &value, 0);
   } else {
     arr = JSValueToObject(context, value, 0);
   }
diff --git a/Lib/javascript/jsc/javascriptruntime.swg b/Lib/javascript/jsc/javascriptruntime.swg
index 8f83908..a626390 100644
--- a/Lib/javascript/jsc/javascriptruntime.swg
+++ b/Lib/javascript/jsc/javascriptruntime.swg
@@ -11,6 +11,7 @@
 #include <string.h>
 #include <errno.h>
 #include <limits.h>
+#include <assert.h>
 %}
 
 %insert(runtime) "swigrun.swg";         /* SWIG API */
diff --git a/Lib/javascript/jsc/javascriptstrings.swg b/Lib/javascript/jsc/javascriptstrings.swg
index 55c8e4b..5c8081a 100644
--- a/Lib/javascript/jsc/javascriptstrings.swg
+++ b/Lib/javascript/jsc/javascriptstrings.swg
@@ -75,6 +75,7 @@
 }
 
 %define %_typemap2_string(StringCode, CharCode,
+			 WarningLeakMsg,
 			 Char, CharName,
 			 SWIG_AsCharPtrAndSize,
 			 SWIG_FromCharPtrAndSize,
@@ -166,6 +167,7 @@
 
 %_typemap_string(StringCode,
                  Char,
+                 WarningLeakMsg,
                  SWIG_AsCharPtrAndSize,
                  SWIG_FromCharPtrAndSize,
                  SWIG_CharPtrLen,
diff --git a/Lib/javascript/jsc/javascripttypemaps.swg b/Lib/javascript/jsc/javascripttypemaps.swg
index e8fbbec..fd8e7aa 100644
--- a/Lib/javascript/jsc/javascripttypemaps.swg
+++ b/Lib/javascript/jsc/javascripttypemaps.swg
@@ -41,7 +41,7 @@
 #define SWIG_SetConstant(name, obj)
 
 /* raise */
-#define SWIG_Raise(obj, type, desc)  SWIG_Javascript_Raise(context, exception, type)
+#define SWIG_Raise(obj, type, desc)  SWIG_Javascript_Raise_ValueRef(context, exception, obj)
 
 %insert("runtime") %{
 #define SWIG_JSC_FROM_DECL_ARGS(arg1)              (JSContextRef context, arg1)
diff --git a/Lib/javascript/jsc/std_auto_ptr.i b/Lib/javascript/jsc/std_auto_ptr.i
new file mode 100644
index 0000000..3d7ae8b
--- /dev/null
+++ b/Lib/javascript/jsc/std_auto_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+  %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class auto_ptr {};
+}
diff --git a/Lib/javascript/jsc/std_map.i b/Lib/javascript/jsc/std_map.i
index 9fa1088..a679f44 100644
--- a/Lib/javascript/jsc/std_map.i
+++ b/Lib/javascript/jsc/std_map.i
@@ -49,7 +49,11 @@
                     throw std::out_of_range("key not found");
             }
             void set(const K& key, const T& x) {
+%#ifdef __cpp_lib_map_try_emplace
+                (*self).insert_or_assign(key, x);
+%#else
                 (*self)[key] = x;
+%#endif
             }
             void del(const K& key) throw (std::out_of_range) {
                 std::map< K, T, C >::iterator i = self->find(key);
@@ -65,17 +69,4 @@
         }
     };
 
-// Legacy macros (deprecated)
-%define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_key ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_value ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO)
-#warning "specialize_std_map_on_both ignored - macro is deprecated and no longer necessary"
-%enddef
-
 }
diff --git a/Lib/javascript/jsc/std_unique_ptr.i b/Lib/javascript/jsc/std_unique_ptr.i
new file mode 100644
index 0000000..f988714
--- /dev/null
+++ b/Lib/javascript/jsc/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+  %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class unique_ptr {};
+}
diff --git a/Lib/javascript/jsc/swigmove.i b/Lib/javascript/jsc/swigmove.i
new file mode 100644
index 0000000..62ecca7
--- /dev/null
+++ b/Lib/javascript/jsc/swigmove.i
@@ -0,0 +1 @@
+%include <typemaps/swigmove.swg>
diff --git a/Lib/javascript/jsc/typemaps.i b/Lib/javascript/jsc/typemaps.i
index d3d8afb..08b5838 100644
--- a/Lib/javascript/jsc/typemaps.i
+++ b/Lib/javascript/jsc/typemaps.i
@@ -18,7 +18,7 @@
          int            *INPUT
          short          *INPUT
          long           *INPUT
-   long long      *INPUT
+         long long      *INPUT
          unsigned int   *INPUT
          unsigned short *INPUT
          unsigned long  *INPUT
@@ -72,7 +72,7 @@
 
 For example, suppose you were trying to wrap the modf() function in the
 C math library which splits x into integral and fractional parts (and
-returns the integer part in one of its parameters).K:
+returns the integer part in one of its parameters) :
 
         double modf(double x, double *ip);
 
@@ -139,10 +139,6 @@
 
        x = neg(x)
 
-Note : previous versions of SWIG used the symbol 'BOTH' to mark
-input/output arguments.   This is still supported, but will be slowly
-phased out in future releases.
-
 */
 
 %include <typemaps/typemaps.swg>
diff --git a/Lib/javascript/napi/argcargv.i b/Lib/javascript/napi/argcargv.i
new file mode 100644
index 0000000..4a14604
--- /dev/null
+++ b/Lib/javascript/napi/argcargv.i
@@ -0,0 +1,66 @@
+/* ------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------ */
+
+%{
+SWIGINTERN int SWIG_AsVal_string (Napi::Value valRef, Napi::String *str)
+{
+  if (!valRef.IsString()) {
+    return SWIG_TypeError;
+  }
+  if(str != SWIG_NULLPTR) {
+      *str = valRef.ToString();
+  }
+  return SWIG_OK;
+}
+%}
+
+%typemap(in) (int ARGC, char **ARGV) {
+  $1_ltype i, len;
+  size_t arraysize;
+  Napi::Array array;
+  if (!$input.IsArray()) {
+    SWIG_exception_fail(SWIG_ERROR, "not array");
+  }
+  array = $input.As<Napi::Array>();
+  len = array.Length();
+  arraysize = (len+1)*sizeof($*2_ltype);
+  $1 = len;
+  $2 = ($2_ltype) malloc(arraysize);
+  if ($2 == SWIG_NULLPTR) {
+    SWIG_exception_fail(SWIG_ERROR, "memory allocation of array failed");
+  }
+  memset($2, 0, arraysize);
+  for (i = 0; i < len; i++) {
+    int res, slen;
+    $*2_ltype pstr;
+    Napi::String napi_str;
+    Napi::Value jsvalue = array.Get(i);
+    res = SWIG_AsVal_string(jsvalue, &napi_str);
+    if (!SWIG_IsOK(res)) {
+      SWIG_exception_fail(SWIG_ERROR, "failed to convert to string");
+    }
+    std::string str = napi_str.Utf8Value();
+    slen = str.size();
+    pstr = ($*2_ltype) malloc(slen + 1);
+    if (pstr == SWIG_NULLPTR) {
+      SWIG_exception_fail(SWIG_ERROR, "memory allocation of a string failed");
+    }
+    if (slen) {
+      memcpy(pstr, str.c_str(), slen);
+    }
+    pstr[slen] = 0;
+    $2[i] = pstr;
+  }
+  $2[i] = SWIG_NULLPTR;
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+  if ($2 != SWIG_NULLPTR) {
+    $1_ltype i;
+    for (i = 0; i < $1; i++) {
+      free((void *)$2[i]);
+    }
+    free((void *)$2);
+  }
+}
diff --git a/Lib/javascript/napi/arrays_javascript.i b/Lib/javascript/napi/arrays_javascript.i
new file mode 100644
index 0000000..c020978
--- /dev/null
+++ b/Lib/javascript/napi/arrays_javascript.i
@@ -0,0 +1,88 @@
+/* -----------------------------------------------------------------------------
+ * arrays_javascript.i
+ *
+ * These typemaps give more natural support for arrays. The typemaps are not efficient
+ * as there is a lot of copying of the array values whenever the array is passed to C/C++
+ * from JavaScript and vice versa. The JavaScript array is expected to be the same size as the C array.
+ * An exception is thrown if they are not.
+ *
+ * Example usage:
+ * Wrapping:
+ *
+ *   %include <arrays_javascript.i>
+ *   %inline %{
+ *       extern int FiddleSticks[3];
+ *   %}
+ *
+ * Use from JavaScript like this:
+ *
+ *   var fs = [10, 11, 12];
+ *   example.FiddleSticks = fs;
+ *   fs = example.FiddleSticks;
+ * ----------------------------------------------------------------------------- */
+
+
+%fragment("SWIG_NAPI_GetIntProperty", "header", fragment=SWIG_AsVal_frag(int)) {}
+%fragment("SWIG_NAPI_GetNumberProperty", "header", fragment=SWIG_AsVal_frag(double)) {}
+%fragment("SWIG_NAPI_OutInt", "header", fragment=SWIG_From_frag(int)) {}
+%fragment("SWIG_NAPI_OutNumber", "header", fragment=SWIG_From_frag(double)) {}
+
+%define JAVASCRIPT_ARRAYS_IN_DECL(NAME, CTYPE, ANY, ANYLENGTH)
+
+%typemap(in, fragment=NAME) CTYPE[ANY] {
+  if ($input.IsArray()) {
+    Napi::Env env = $input.Env();
+    // Convert into Array
+    Napi::Array array = $input.As<Napi::Array>();
+
+    int length = ANYLENGTH;
+
+    $1 = ($*1_ltype *)malloc(sizeof($*1_ltype) * length);
+
+    // Get each element from array
+    for (int i = 0; i < length; i++) {
+      Napi::Value jsvalue = array.Get(i);
+      $*1_ltype temp;
+
+      // Get primitive value from JSObject
+      int res = SWIG_AsVal(CTYPE)(jsvalue, &temp);
+      if (!SWIG_IsOK(res)) {
+        SWIG_Error(SWIG_ERROR, "Failed to convert $input to double");
+      }
+      arg$argnum[i] = temp;
+    }
+  } else {
+    Napi::Env env = $input.Env();
+    SWIG_Error(SWIG_ERROR, "$input is not an array");
+  }
+}
+
+%typemap(freearg) CTYPE[ANY] {
+  free($1);
+}
+
+%enddef
+
+%define JAVASCRIPT_ARRAYS_OUT_DECL(NAME, CTYPE)
+
+%typemap(out, fragment=NAME) CTYPE[ANY] {
+  int length = $1_dim0;
+  Napi::Array array = Napi::Array::New(env, length);
+
+  for (int i = 0; i < length; i++) {
+    array.Set(i, SWIG_From(CTYPE)($1[i]));
+  }
+
+  $result = array;
+}
+
+%enddef
+
+JAVASCRIPT_ARRAYS_IN_DECL("SWIG_NAPI_GetIntProperty", int, , array.Length())
+JAVASCRIPT_ARRAYS_IN_DECL("SWIG_NAPI_GetIntProperty", int, ANY, $1_dim0)
+JAVASCRIPT_ARRAYS_IN_DECL("SWIG_NAPI_GetNumberProperty", double, , array.Length())
+JAVASCRIPT_ARRAYS_IN_DECL("SWIG_NAPI_GetNumberProperty", double, ANY, $1_dim0)
+
+JAVASCRIPT_ARRAYS_OUT_DECL("SWIG_NAPI_OutInt", int)
+JAVASCRIPT_ARRAYS_OUT_DECL("SWIG_NAPI_OutNumber", double)
+
diff --git a/Lib/javascript/napi/ccomplex.i b/Lib/javascript/napi/ccomplex.i
new file mode 100644
index 0000000..e58dbf7
--- /dev/null
+++ b/Lib/javascript/napi/ccomplex.i
@@ -0,0 +1,27 @@
+/* -----------------------------------------------------------------------------
+ * ccomplex.i
+ *
+ * C complex typemaps
+ * ISO C99:  7.3 Complex arithmetic <complex.h>
+ * ----------------------------------------------------------------------------- */
+
+
+%include <javascriptcomplex.swg>
+
+%{
+#include <complex.h>
+%}
+
+#define complex _Complex
+
+/* C complex constructor */
+#define CCplxConst(r, i) ((r) + I*(i))
+
+%swig_cplxflt_convn(float _Complex, CCplxConst, creal, cimag);
+%swig_cplxdbl_convn(double _Complex, CCplxConst, creal, cimag);
+%swig_cplxdbl_convn(_Complex, CCplxConst, creal, cimag);
+
+/* declaring the typemaps */
+%typemaps_primitive(SWIG_TYPECHECK_CPLXFLT, float _Complex);
+%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, double _Complex);
+%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, _Complex);
diff --git a/Lib/javascript/napi/cdata.i b/Lib/javascript/napi/cdata.i
new file mode 100644
index 0000000..3679659
--- /dev/null
+++ b/Lib/javascript/napi/cdata.i
@@ -0,0 +1 @@
+%include <typemaps/cdata.swg>
diff --git a/Lib/javascript/napi/cmalloc.i b/Lib/javascript/napi/cmalloc.i
new file mode 100644
index 0000000..248f06b
--- /dev/null
+++ b/Lib/javascript/napi/cmalloc.i
@@ -0,0 +1 @@
+%include <typemaps/cmalloc.swg>
diff --git a/Lib/javascript/napi/complex.i b/Lib/javascript/napi/complex.i
new file mode 100644
index 0000000..4c3b3c5
--- /dev/null
+++ b/Lib/javascript/napi/complex.i
@@ -0,0 +1,6 @@
+#ifdef __cplusplus
+%include <std_complex.i>
+#else
+%include <ccomplex.i>
+#endif
+
diff --git a/Lib/javascript/napi/exception.i b/Lib/javascript/napi/exception.i
new file mode 100644
index 0000000..0246cfd
--- /dev/null
+++ b/Lib/javascript/napi/exception.i
@@ -0,0 +1 @@
+%include <typemaps/exception.swg>
diff --git a/Lib/javascript/napi/factory.i b/Lib/javascript/napi/factory.i
new file mode 100644
index 0000000..46a0a87
--- /dev/null
+++ b/Lib/javascript/napi/factory.i
@@ -0,0 +1 @@
+%include <typemaps/factory.swg>
diff --git a/Lib/javascript/napi/javascript.swg b/Lib/javascript/napi/javascript.swg
new file mode 100644
index 0000000..c37a384
--- /dev/null
+++ b/Lib/javascript/napi/javascript.swg
@@ -0,0 +1,17 @@
+/* -----------------------------------------------------------------------------
+ * javascript.swg
+ *
+ * Javascript typemaps
+ * ----------------------------------------------------------------------------- */
+
+%include <typemaps/swigmacros.swg>
+
+%include <javascripttypemaps.swg>
+
+%include <javascriptruntime.swg>
+
+%include <javascriptkw.swg>
+
+%include <javascriptcode.swg>
+
+%include <javascriptinit.swg>
diff --git a/Lib/javascript/napi/javascriptcode.swg b/Lib/javascript/napi/javascriptcode.swg
new file mode 100644
index 0000000..26e8ade
--- /dev/null
+++ b/Lib/javascript/napi/javascriptcode.swg
@@ -0,0 +1,880 @@
+/* -----------------------------------------------------------------------------
+ * js_ctor:  template for wrapping a ctor.
+ *   - $jswrapper:        wrapper of called ctor
+ *   - $jsparent:         mangled name of parent (or SWIG_NAPI_ObjectWrap if none)
+ *   - $jslocals:         locals part of wrapper
+ *   - $jscode:           code part of wrapper
+ *   - $jsargcount:       number of arguments
+ *   - $jsargrequired:    minimum number of arguments
+ *   - $jsmangledname:    mangled name of class
+ *   - $jsmangledtype:    mangled type of class
+ * ----------------------------------------------------------------------------- */
+
+%fragment("js_ctor", "templates") %{
+template <typename SWIG_OBJ_WRAP>
+// js_ctor
+// This is the main constructor
+$jsmangledname_templ<SWIG_OBJ_WRAP>::$jsmangledname_templ(const Napi::CallbackInfo &info)
+        : $jsparent_templ<SWIG_OBJ_WRAP>(true, info) {
+  Napi::Env env = info.Env();
+
+  this->info = SWIGTYPE_$jsmangledtype;
+  if (info.Length() == 1 && info[0].IsExternal()) {
+    // This constructor has been called internally from C++/SWIG
+    // to wrap an already existing C++ object in JS
+    this->self = info[0].As<Napi::External<void>>().Data();
+    this->owned = false;
+    return;
+  }
+  this->owned = true;
+
+  $jslocals
+  if(static_cast<int>(info.Length()) < $jsargrequired || static_cast<int>(info.Length()) > $jsargcount) {
+    SWIG_Error(SWIG_ERROR, "Illegal number of arguments for $jswrapper.");
+  }
+  $jscode
+  this->self = result;
+  return;
+  goto fail;
+fail:
+  return;
+}
+
+// This is the bypass constructor to be used from child classes
+template <typename SWIG_OBJ_WRAP>
+$jsmangledname_templ<SWIG_OBJ_WRAP>::$jsmangledname_templ(bool, const Napi::CallbackInfo &info)
+        : $jsparent_templ<SWIG_OBJ_WRAP>(true, info) {}
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * js_veto_ctor:  a vetoing ctor for abstract classes
+ *   - $jsmangledname:    mangled name of class
+ *   - $jsparent:         mangled name of parent (or SWIG_NAPI_ObjectWrap if none)
+ * ----------------------------------------------------------------------------- */
+%fragment ("js_veto_ctor", "templates")
+%{
+// js_veto_ctor
+template <typename SWIG_OBJ_WRAP>
+$jsmangledname_templ<SWIG_OBJ_WRAP>::$jsmangledname_templ(const Napi::CallbackInfo &info)
+        : $jsparent_templ<SWIG_OBJ_WRAP>(true, info) {
+  Napi::Env env = info.Env();
+  if (info.Length() == 1 && info[0].IsExternal()) {
+    // This constructor has been called internally from C++/SWIG
+    // to wrap an already existing C++ object in JS as its
+    // base abstract class
+    this->self = info[0].As<Napi::External<void>>().Data();
+    this->owned = false;
+    return;
+  }
+  SWIG_Error(SWIG_ERROR, "Class $jsname can not be instantiated");
+  return;
+  goto fail;
+fail:
+  return;
+}
+
+// This is the extendable constructor to be used from child classes
+template <typename SWIG_OBJ_WRAP>
+$jsmangledname_templ<SWIG_OBJ_WRAP>::$jsmangledname_templ(bool, const Napi::CallbackInfo &info)
+        : $jsparent_templ<SWIG_OBJ_WRAP>(true, info) {
+}
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * js_ctor_dispatcher:  dispatcher for overloaded constructors
+ *   - $jsmangledname:    mangled name of class
+ *   - $jsparent:         mangled name of parent (or SWIG_NAPI_ObjectWrap if none)
+ *   - $jsdispatchcases:  part containing code for dispatching
+ *   - $jsmangledtype:    mangled type of class
+ * ----------------------------------------------------------------------------- */
+%fragment ("js_ctor_dispatcher", "templates")
+%{
+// js_ctor_dispatcher
+template <typename SWIG_OBJ_WRAP>
+$jsmangledname_templ<SWIG_OBJ_WRAP>::$jsmangledname_templ(const Napi::CallbackInfo &info)
+        : $jsparent_templ<SWIG_OBJ_WRAP>(true, info) {
+  Napi::Env env = info.Env();
+  Napi::Object self;
+  NAPI_CHECK_RESULT(info.This().ToObject(), self);
+  this->info = SWIGTYPE_$jsmangledtype;
+  if (info.Length() == 1 && info[0].IsExternal()) {
+    // This constructor has been called internally from C++/SWIG
+    // to wrap an already existing C++ object in JS
+    this->self = info[0].As<Napi::External<void>>().Data();
+    this->owned = false;
+    return;
+  }
+
+  // switch all cases by means of series of if-returns.
+  $jsdispatchcases
+
+  // default:
+  SWIG_Error(SWIG_ERROR, "Illegal arguments for construction of $jsmangledname");
+
+  goto fail;
+fail:
+  return;
+}
+
+// This is the extendable constructor to be used from child classes
+template <typename SWIG_OBJ_WRAP>
+$jsmangledname_templ<SWIG_OBJ_WRAP>::$jsmangledname_templ(bool, const Napi::CallbackInfo &info)
+        : $jsparent_templ<SWIG_OBJ_WRAP>(true, info) {
+}
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * js_overloaded_ctor:  template for wrapping a ctor.
+ *   - $jswrapper:        wrapper of called ctor
+ *   - $jslocals:         locals part of wrapper
+ *   - $jscode:           code part of wrapper
+ *   - $jsargcount:       number of arguments
+ *   - $jsargrequired:    minimum number of arguments
+ *   - $jsmangledtype:    mangled type of class
+ * ----------------------------------------------------------------------------- */
+%fragment("js_overloaded_ctor", "templates") %{
+// js_overloaded_ctor
+template <typename SWIG_OBJ_WRAP>
+Napi::Value $jsmangledname_templ<SWIG_OBJ_WRAP>::$jswrapper(const Napi::CallbackInfo &info) {
+  Napi::Env env = info.Env();
+  Napi::Object self;
+  $jslocals
+  NAPI_CHECK_RESULT(info.This().ToObject(), self);
+  this->owned = true;
+  if(static_cast<int>(info.Length()) < $jsargrequired || static_cast<int>(info.Length()) > $jsargcount) {
+    SWIG_Error(SWIG_ERROR, "Illegal number of arguments for $jswrapper.");
+  }
+  $jscode
+  this->self = result;
+
+  goto fail;
+fail:
+  return Napi::Value();
+}
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * js_ctor_dispatch_case:  template for a dispatch case for calling an overloaded ctor.
+ *   - $jsargcount:       number of arguments of called ctor
+ *   - $jsargrequired:    minimum number of arguments
+ *   - $jswrapper:        wrapper of called ctor
+ *
+ *  Note: a try-catch-like mechanism is used to switch cases
+ * ----------------------------------------------------------------------------- */
+%fragment ("js_ctor_dispatch_case", "templates")
+%{
+  // js_ctor_dispatch_case
+  if(static_cast<int>(info.Length()) >= $jsargrequired && static_cast<int>(info.Length()) <= $jsargcount) {
+#ifdef NAPI_CPP_EXCEPTIONS
+    bool tryNext = false;
+    try {
+      $jswrapper(info);
+    } catch (const Napi::TypeError &) {
+      tryNext = true;
+    } catch (const Napi::Error &e) {
+      throw e;
+    }
+    if (!tryNext)
+      return;
+#else
+    $jswrapper(info);
+    if (env.IsExceptionPending()) {
+      Napi::Error e = env.GetAndClearPendingException();
+      Napi::Value typeErrorValue;
+      bool isTypeError;
+      Napi::Function typeErrorCons;
+      // Yes, this is ugly
+      // TODO: Fix this in Node.js when the core team grows up
+      NAPI_CHECK_RESULT(env.Global().Get("TypeError"), typeErrorValue);
+      typeErrorCons = typeErrorValue.As<Napi::Function>();
+      NAPI_CHECK_RESULT(e.Value().InstanceOf(typeErrorCons), isTypeError);
+      if (!isTypeError) {
+        // This is not the error you are looking for
+        e.ThrowAsJavaScriptException();
+        SWIG_fail;
+      }
+    } else {
+      return;
+    }
+#endif
+  }
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * js_check_arg:  template for checking if an argument exists
+ *   - $jsarg: number of argument
+ * ----------------------------------------------------------------------------- */
+%fragment ("js_check_arg", "templates")
+%{if(info.Length() > $jsarg)%}
+
+
+/* -----------------------------------------------------------------------------
+ * js_dtor:  template for a destructor wrapper
+ *   - $jsmangledname:  mangled class name
+ *   - $jstype:         class type
+ * ----------------------------------------------------------------------------- */
+%fragment ("js_dtor", "templates")
+%{
+// js_dtor
+template <typename SWIG_OBJ_WRAP>
+$jsmangledname_templ<SWIG_OBJ_WRAP>::~$jsmangledname_templ() {
+}
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * js_dtoroverride:  template for a destructor wrapper
+ *   - ${classname_mangled}:  mangled class name
+ *   - $jstype:         class type
+ *   - ${destructor_action}: The custom destructor action to invoke.
+ * ----------------------------------------------------------------------------- */
+%fragment ("js_dtoroverride", "templates")
+%{
+// js_dtoroverride
+template <typename SWIG_OBJ_WRAP>
+${classname_mangled}_templ<SWIG_OBJ_WRAP>::~${classname_mangled}_templ() {
+  auto arg1 = reinterpret_cast<$jstype>(this->self);
+  if (this->owned && arg1) {
+    ${destructor_action}
+    this->self = nullptr;
+  }
+}
+%}
+
+/* -----------------------------------------------------------------------------
+ * js_global_getter:  template for global getter function wrappers
+ *   - $jswrapper:      wrapper function name
+ *   - $jslocals:       locals part of wrapper
+ *   - $jscode:         code part of wrapper
+ * ----------------------------------------------------------------------------- */
+%fragment("js_global_getter", "templates")
+%{
+// js_global_getter
+Napi::Value $jswrapper(const Napi::CallbackInfo &info) {
+  Napi::Env env = info.Env();
+  Napi::Value jsresult;
+  $jslocals
+  $jscode
+  return jsresult;
+
+  goto fail;
+fail:
+  return Napi::Value();
+}
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * js_global_setter:  template for global setter function wrappers
+ *   - $jswrapper:      wrapper function name
+ *   - $jslocals:       locals part of wrapper
+ *   - $jscode:         code part of wrapper
+ * ----------------------------------------------------------------------------- */
+%fragment("js_global_setter", "templates")
+%{
+// js_global_setter
+void $jswrapper(const Napi::CallbackInfo &info) {
+  Napi::Env env = info.Env();
+  Napi::Value value = info.Length() > 0 ? info[0] : Napi::Value();
+  Napi::Value jsresult;
+  $jslocals
+  $jscode
+  return;
+
+  goto fail;
+fail:
+  return;
+}
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * jsnapi_register_global_variable:  template for a statement that registers a global variable
+ *   - $jsname:         variable name
+ *   - $jsparent:       parent namespace
+ *   - $jsgetter:       wrapper of the getter function
+ *   - $jssetter:       wrapper of the setter function
+ *
+ * Note: this template is also used for global variables.
+ * ----------------------------------------------------------------------------- */
+%fragment("jsnapi_register_global_variable", "templates")
+%{
+  // jsnapi_register_global_variable
+  do {
+    Napi::PropertyDescriptor pd = Napi::PropertyDescriptor::Accessor<$jsgetter, $jssetter>("$jsname");
+    NAPI_CHECK_MAYBE($jsparent.DefineProperties({pd}));
+  } while (0);
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * js_global_function:  template for function wrappers
+ *   - $jswrapper:     wrapper function name
+ *   - $jslocals:      locals part of wrapper
+ *   - $jsargcount:    number of arguments
+ *   - $jsargrequired: minimum number of arguments
+ *   - $jscode:        code part of wrapper
+ * ----------------------------------------------------------------------------- */
+%fragment("js_global_function", "templates")
+%{
+// js_global_function
+Napi::Value $jswrapper(const Napi::CallbackInfo &info) {
+  Napi::Env env = info.Env();
+  Napi::Value jsresult;
+  $jslocals
+  if(static_cast<int>(info.Length()) < $jsargrequired || static_cast<int>(info.Length()) > $jsargcount) {
+    SWIG_Error(SWIG_ERROR, "Illegal number of arguments for $jswrapper.");
+  }
+
+  $jscode
+  return jsresult;
+
+  goto fail;
+fail:
+  return Napi::Value();
+}
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * js_global_function_dispatcher:  template for a global function dispatcher for
+ * global overloaded functions
+ *   - $jswrapper:  wrapper function name
+ *   - $jsname:     name of the wrapped function
+ *   - $jslocals:   locals part of wrapper
+ *   - $jscode:     code part of wrapper
+ * ----------------------------------------------------------------------------- */
+%fragment("js_global_function_dispatcher", "templates")
+%{
+// js_global_function_dispatcher
+Napi::Value $jswrapper(const Napi::CallbackInfo &info) {
+  Napi::Env env = info.Env();
+  Napi::Value jsresult;
+  $jscode
+
+  SWIG_Error(SWIG_ERROR, "Illegal arguments for function $jsname.");
+
+  goto fail;
+fail:
+  return Napi::Value();
+}
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * jsnapi_register_global_function:  template for a statement that registers a global function
+ *   - $jsname:         function name
+ *   - $jsparent:       parent namespace
+ *   - $jswrapper:      name of the JS wrapper
+ *
+ * Note: this template is also used for global variables.
+ * ----------------------------------------------------------------------------- */
+%fragment("jsnapi_register_global_function", "templates")
+%{
+  // jsnapi_register_global_function
+  do {
+    Napi::PropertyDescriptor pd = Napi::PropertyDescriptor::Function("$jsname", $jswrapper);
+    NAPI_CHECK_MAYBE($jsparent.DefineProperties({pd}));
+  } while (0);
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * js_getter:  template for getter function wrappers
+ *   - $jsmangledname:  mangled class name
+ *   - $jswrapper:      wrapper function name
+ *   - $jslocals:       locals part of wrapper
+ *   - $jscode:         code part of wrapper
+ * ----------------------------------------------------------------------------- */
+%fragment("js_getter", "templates")
+%{
+// js_getter
+template <typename SWIG_OBJ_WRAP>
+Napi::Value $jsmangledname_templ<SWIG_OBJ_WRAP>::$jswrapper(const Napi::CallbackInfo &info) {
+  Napi::Env env = info.Env();
+  Napi::Value jsresult;
+  $jslocals
+  $jscode
+  return jsresult;
+
+  goto fail;
+fail:
+  return Napi::Value();
+}
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * js_setter:  template for setter function wrappers
+ *   - $jsmangledname:  mangled class name
+ *   - $jswrapper:      wrapper function name
+ *   - $jslocals:       locals part of wrapper
+ *   - $jscode:         code part of wrapper
+ * ----------------------------------------------------------------------------- */
+%fragment("js_setter", "templates")
+%{
+// js_setter
+template <typename SWIG_OBJ_WRAP>
+void $jsmangledname_templ<SWIG_OBJ_WRAP>::$jswrapper(const Napi::CallbackInfo &info, const Napi::Value &value) {
+  Napi::Env env = info.Env();
+  Napi::Value jsresult;
+  $jslocals
+  $jscode
+  return;
+
+  goto fail;
+fail:
+  return;
+}
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * js_function:  template for function wrappers
+ *   - $jsmangledname:  mangled class name
+ *   - $jswrapper:      wrapper function name
+ *   - $jsargcount:     minimum number of arguments
+ *   - $jsargrequired:  minimum number of arguments
+ *   - $jslocals:       locals part of wrapper
+ *   - $jscode:         code part of wrapper
+ * ----------------------------------------------------------------------------- */
+%fragment("js_function", "templates")
+%{
+// js_function
+template <typename SWIG_OBJ_WRAP>
+Napi::Value $jsmangledname_templ<SWIG_OBJ_WRAP>::$jswrapper(const Napi::CallbackInfo &info) {
+  Napi::Env env = info.Env();
+  Napi::Value jsresult;
+  $jslocals
+  if(static_cast<int>(info.Length()) < $jsargrequired || static_cast<int>(info.Length()) > $jsargcount) {
+    SWIG_Error(SWIG_ERROR, "Illegal number of arguments for $jswrapper.");
+  }
+
+  $jscode
+  return jsresult;
+
+  goto fail;
+fail:
+  return Napi::Value();
+}
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * js_function_dispatcher:  template for a function dispatcher for overloaded functions
+ *   - $jsmangledname:  mangled class name
+ *   - $jswrapper:      wrapper function name
+ *   - $jsname:         name of the wrapped function
+ *   - $jslocals:       locals part of wrapper
+ *   - $jscode:         code part of wrapper
+ * ----------------------------------------------------------------------------- */
+%fragment("js_function_dispatcher", "templates")
+%{
+// js_function_dispatcher
+template <typename SWIG_OBJ_WRAP>
+Napi::Value $jsmangledname_templ<SWIG_OBJ_WRAP>::$jswrapper(const Napi::CallbackInfo &info) {
+  Napi::Env env = info.Env();
+  Napi::Value jsresult;
+  $jscode
+
+  SWIG_Error(SWIG_ERROR, "Illegal arguments for function $jsname.");
+
+  goto fail;
+fail:
+  return Napi::Value();
+}
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * js_overloaded_function:  template for a overloaded function
+ *   - $jswrapper:  wrapper function name
+ *   - $jslocals:   locals part of wrapper
+ *   - $jscode:     code part of wrapper
+ * ----------------------------------------------------------------------------- */
+%fragment ("js_overloaded_function", "templates")
+%{
+// js_overloaded_function
+template <typename SWIG_OBJ_WRAP>
+Napi::Value $jsmangledname_templ<SWIG_OBJ_WRAP>::$jswrapper(const Napi::CallbackInfo &info) {
+  Napi::Env env = info.Env();
+  Napi::Value jsresult;
+  $jslocals
+  $jscode
+  return jsresult;
+
+  goto fail;
+fail:
+  return Napi::Value();
+}
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * js_global_overloaded_function:  template for a global overloaded function
+ *   - $jswrapper:      wrapper function name
+ *   - $jslocals:       locals part of wrapper
+ *   - $jscode:         code part of wrapper
+ * ----------------------------------------------------------------------------- */
+%fragment ("js_global_overloaded_function", "templates")
+%{
+// js_global_overloaded_function
+Napi::Value $jswrapper(const Napi::CallbackInfo &info) {
+  Napi::Env env = info.Env();
+  Napi::Value jsresult;
+  $jslocals
+  $jscode
+  return jsresult;
+
+  goto fail;
+fail:
+  return Napi::Value();
+}
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * js_function_dispatch_case:  template for a case used in the function dispatcher
+ *   - $jswrapper:     wrapper function name
+ *   - $jsargcount:    number of arguments of overloaded function
+ *   - $jsargrequired: minimum number of arguments
+ *   - $jscode:        code part of wrapper
+ * ----------------------------------------------------------------------------- */
+%fragment ("js_function_dispatch_case", "templates")
+%{
+  // js_function_dispatch_case
+  if(static_cast<int>(info.Length()) >= $jsargrequired && static_cast<int>(info.Length()) <= $jsargcount) {
+#ifdef NAPI_CPP_EXCEPTIONS
+    bool tryNext = false;
+    try {
+      jsresult = $jswrapper(info);
+    } catch (const Napi::TypeError &) {
+      tryNext = true;
+    } catch (const Napi::Error &e) {
+      throw e;
+    }
+    if (!tryNext)
+      return jsresult;
+#else
+    $jswrapper(info);
+    if (env.IsExceptionPending()) {
+      Napi::Error e = env.GetAndClearPendingException();
+      Napi::Value typeErrorValue;
+      bool isTypeError;
+      Napi::Function typeErrorCons;
+      // Yes, this is ugly
+      // TODO: Fix this in Node.js when the core team grows up
+      NAPI_CHECK_RESULT(env.Global().Get("TypeError"), typeErrorValue);
+      typeErrorCons = typeErrorValue.As<Napi::Function>();
+      NAPI_CHECK_RESULT(e.Value().InstanceOf(typeErrorCons), isTypeError);
+      if (!isTypeError) {
+        // This is not the error you are looking for
+        e.ThrowAsJavaScriptException();
+        SWIG_fail;
+      }
+    } else {
+      return jsresult;
+    }
+#endif
+  }
+%}
+
+/* -----------------------------------------------------------------------------
+ * jsnapi_class_prologue_template:  template for a class prologue
+ *   - $jsmangledname:  mangled class name
+ *   - $jsparent:       mangled name of parent (or SWIG_NAPI_ObjectWrap if none)
+ * ----------------------------------------------------------------------------- */
+%fragment("jsnapi_class_prologue_template", "templates")
+%{
+  // jsnapi_class_prologue_template
+  template <typename SWIG_OBJ_WRAP>
+  class $jsmangledname_templ : public $jsparent_templ<SWIG_OBJ_WRAP> {
+    public:
+      $jsmangledname_templ(const Napi::CallbackInfo &);
+      $jsmangledname_templ(bool, const Napi::CallbackInfo &);
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * jsnapi_class_dtor_declaration:  template for a class destructor declaration
+ *   - $jsmangledname:  mangled class name
+ * ----------------------------------------------------------------------------- */
+%fragment("jsnapi_class_dtor_declaration", "templates")
+%{
+    virtual ~$jsmangledname_templ();
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * jsnapi_class_method_declaration:  template for a class method declaration
+ *   - $jsmangledname:  mangled class name
+ *   - $jswrapper:      method name
+ *   - $jsstatic:       static modifier
+ * ----------------------------------------------------------------------------- */
+%fragment("jsnapi_class_method_declaration", "templates")
+%{
+    // jsnapi_class_method_declaration
+    $jsstatic Napi::Value $jswrapper(const Napi::CallbackInfo &);
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * jsnapi_class_setter_declaration:  template for a class method declaration
+ *   - $jsmangledname:  mangled class name
+ *   - $jswrapper:      method name
+ *   - $jsstatic:       static modifier
+ * ----------------------------------------------------------------------------- */
+%fragment("jsnapi_class_setter_declaration", "templates")
+%{
+    // jsnapi_class_setter_declaration
+    $jsstatic void $jswrapper(const Napi::CallbackInfo &, const Napi::Value &);
+%}
+
+
+
+/* -----------------------------------------------------------------------------
+ * jsnapi_class_epilogue_template:  template for a class epilogue
+ *   - $jsmangledname:  mangled class name
+ * ----------------------------------------------------------------------------- */
+%fragment("jsnapi_class_epilogue_template", "templates")
+%{
+  // jsnapi_class_epilogue_template
+  static void JS_veto_set_static_variable(const Napi::CallbackInfo &, const Napi::Value &);
+  void JS_veto_set_variable(const Napi::CallbackInfo &, const Napi::Value &);
+};
+
+template <typename SWIG_OBJ_WRAP>
+void $jsmangledname_templ<SWIG_OBJ_WRAP>::JS_veto_set_static_variable(const Napi::CallbackInfo &info, const Napi::Value &value) {
+  SWIG_NAPI_Raise(info.Env(), "Tried to write read-only variable.");
+}
+
+template <typename SWIG_OBJ_WRAP>
+void $jsmangledname_templ<SWIG_OBJ_WRAP>::JS_veto_set_variable(const Napi::CallbackInfo &info, const Napi::Value &value) {
+  SWIG_NAPI_Raise(info.Env(), "Tried to write read-only variable.");
+}
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * jsnapi_class_instance:  template for a class declaration instance
+ *   - $jsmangledname:  mangled class name
+ * ----------------------------------------------------------------------------- */
+%fragment("jsnapi_declare_class_instance", "templates")
+%{
+  // jsnapi_class_instance
+  class $jsmangledname_inst : public $jsmangledname_templ<$jsmangledname_inst> {
+    public:
+      using $jsmangledname_templ::$jsmangledname_templ;
+      virtual ~$jsmangledname_inst() {};
+      static void GetMembers(
+        Napi::Env,
+        std::map<std::string, $jsmangledname_templ::PropertyDescriptor> &,
+        std::map<std::string, $jsmangledname_templ::PropertyDescriptor> &
+      );
+      static Napi::Function GetClass(Napi::Env);
+  };
+%}
+
+
+/*
+ * Inheritance is still not officially supported in NAPI
+ * Refer to this for my workaround: 
+ * https://mmomtchev.medium.com/c-class-inheritance-with-node-api-and-node-addon-api-c180334d9902
+ */
+
+/* -----------------------------------------------------------------------------
+ * jsnapi_inherited_class_prologue_template:  template for a class prologue
+ *   - $jsmangledname:  mangled class name
+ *   - $jsparent:       mangled name of parent class
+ * ----------------------------------------------------------------------------- */
+%fragment("jsnapi_inherited_class_prologue_template", "templates")
+%{
+  // jsnapi_inherited_class_prologue_template
+  SWIG_NAPI_ClientData $jsmangledname_clientData;
+  template <typename SWIG_OBJ_WRAP>
+  class $jsmangledname_templ : public $jsparent_templ<SWIG_OBJ_WRAP> {
+    public:
+      $jsmangledname_templ(const Napi::CallbackInfo& info);
+%}
+
+
+/* -----------------------------------------------------------------------------
+ * jsnapi_getclass:  template for creating a class object
+ *   - $jsname:         class name
+ *   - $jsmangledname:  mangled class name
+ *   - $jsfunctions:    member functions
+ * ----------------------------------------------------------------------------- */
+%fragment("jsnapi_getclass", "templates")
+%{
+  /* Class: $jsname ($jsmangledname) */
+  // jsnapi_getclass
+Napi::Function $jsmangledname_inst::GetClass(Napi::Env env) {
+  std::map<std::string, $jsmangledname_templ::PropertyDescriptor> members, staticMembers;
+  GetMembers(env, members, staticMembers);
+
+  std::vector<$jsmangledname_inst::PropertyDescriptor> symbolTable;
+  for (auto it = members.begin(); it != members.end(); it++)
+    symbolTable.push_back(it->second);
+  for (auto it = staticMembers.begin(); it != staticMembers.end(); it++)
+    symbolTable.push_back(it->second);
+
+  return Napi::ObjectWrap<$jsmangledname_inst>::DefineClass(env, "$jsname", symbolTable);
+}
+
+void $jsmangledname_inst::GetMembers(
+        Napi::Env env,
+        std::map<std::string, $jsmangledname_templ::PropertyDescriptor> &members,
+        std::map<std::string, $jsmangledname_templ::PropertyDescriptor> &staticMembers
+) {
+    std::map<std::string, $jsparent_templ<$jsparent_inst>::PropertyDescriptor> baseMembers, baseStaticMembers;
+    $jsparent_inst::GetMembers(env, baseMembers, baseStaticMembers);
+    members.insert(baseMembers.begin(), baseMembers.end());
+    staticMembers.insert(staticMembers.begin(), staticMembers.end());
+
+    /* register wrapper functions */
+    $jsnapiwrappers
+    /* add static class functions and variables */
+    $jsnapistaticwrappers
+}
+%}
+
+/* -----------------------------------------------------------------------------
+ * jsnapi_registerclass:  template for regsitering a class object
+ *   - $jsname:         class name
+ *   - $jsmangledname:  mangled class name
+ *   - $jsparent:       parent namespace
+ *   - $jsmangledtype:  mangled class type
+ *   - $jsclassidx:     class index in the class table
+ * ----------------------------------------------------------------------------- */
+%fragment("jsnapi_registerclass", "templates")
+%{
+
+  /* Class: $jsname ($jsmangledname) */
+  // jsnapi_registerclass
+  Napi::Function $jsmangledname_ctor = $jsmangledname_inst::GetClass(env);
+  $jsparent.Set("$jsname", $jsmangledname_ctor);
+  if (SWIGTYPE_$jsmangledtype->clientdata == nullptr) {
+    SWIGTYPE_$jsmangledtype->clientdata = new size_t($jsclassidx);
+  }
+  Napi::FunctionReference *$jsmangledname_ctor_ref = new Napi::FunctionReference();
+  *$jsmangledname_ctor_ref = Napi::Persistent($jsmangledname_ctor);
+  env.GetInstanceData<EnvInstanceData>()->ctor[$jsclassidx] = $jsmangledname_ctor_ref;
+%}
+
+/* -----------------------------------------------------------------------------
+ * jsnapi_setup_inheritance:  setup inheritance between two classes
+ *   - $jsname:         class name
+ *   - $jsmangledname:  mangled class name
+ *   - $jsparent:       mangled name of parent class
+ * ----------------------------------------------------------------------------- */
+%fragment("jsnapi_setup_inheritance", "templates")
+%{
+  // Inheritance for $jsmangledname ($jsname) <- $jsparent
+  // jsnapi_setup_inheritance
+  do {
+    Napi::Value protoBase, protoSub;
+    NAPI_CHECK_RESULT($jsmangledname_ctor.Get("prototype"), protoSub);
+    NAPI_CHECK_RESULT($jsparent_ctor.Get("prototype"), protoBase);
+    NAPI_CHECK_MAYBE(setProto.Call({$jsmangledname_ctor, $jsparent_ctor}));
+    NAPI_CHECK_MAYBE(setProto.Call({protoSub, protoBase}));
+  } while (0);
+%}
+
+/* -----------------------------------------------------------------------------
+ * jsnapi_create_namespace:  template for a statement that creates a namespace object.
+ *   - $jsmangledname:  mangled namespace name
+ * ----------------------------------------------------------------------------- */
+%fragment("jsnapi_create_namespace", "templates")
+%{
+  // jsnapi_create_namespace
+  Napi::Object $jsmangledname = Napi::Object::New(env);
+%}
+
+/* -----------------------------------------------------------------------------
+ * jsnapi_register_namespace:  template for a statement that registers a namespace in a parent namespace.
+ *   - $jsname:         name of namespace
+ *   - $jsmangledname:  mangled name of namespace
+ *   - $jsparent:       mangled name of parent namespace
+ * ----------------------------------------------------------------------------- */
+%fragment("jsnapi_register_namespace", "templates")
+%{
+  // jsnapi_register_namespace
+  NAPI_CHECK_MAYBE($jsparent.Set("$jsname", $jsmangledname));
+%}
+
+/* -----------------------------------------------------------------------------
+ * jsnapi_member_function_descriptor:  template for a statement that registers a member function.
+ *   - $jsmangledname:  mangled class name
+ *   - $jsname:         name of the function
+ *   - $jswrapper:      wrapper of the member function
+ * ----------------------------------------------------------------------------- */
+%fragment("jsnapi_register_member_function", "templates")
+%{
+  // jsnapi_member_function_descriptor
+  members.erase("$jsname");
+  members.insert({"$jsname",
+        $jsmangledname_templ::InstanceMethod("$jsname",
+                &$jsmangledname_templ::$jswrapper,
+                static_cast<napi_property_attributes>(napi_writable | napi_configurable))
+        });
+%}
+
+/* -----------------------------------------------------------------------------
+ * jsnapi_register_member_variable:  template for a statement that registers a member variable.
+ *   - $jsname:         name of the function
+ *   - $jsmangledname:  mangled class name
+ *   - $jsgetter:       wrapper of the getter function
+ *   - $jssetter:       wrapper of the setter function
+ * ----------------------------------------------------------------------------- */
+%fragment("jsnapi_register_member_variable", "templates")
+%{
+  // jsnapi_register_member_variable
+  members.erase("$jsname");
+  members.insert({"$jsname",
+        $jsmangledname_templ::InstanceAccessor("$jsname",
+                &$jsmangledname_templ::$jsgetter,
+                &$jsmangledname_templ::$jssetter,
+                static_cast<napi_property_attributes>(napi_writable | napi_enumerable | napi_configurable))
+        });
+%}
+
+/* -----------------------------------------------------------------------------
+ * jsnapi_register_static_function:  template for a statement that registers a static class function.
+ *   - $jsname:         function name
+ *   - $jsmangledname:  mangled class name
+ *   - $jswrapper:      wrapper of the function
+ * ----------------------------------------------------------------------------- */
+%fragment("jsnapi_register_static_function", "templates")
+%{
+  // jsnapi_register_static_function
+  staticMembers.erase("$jsname");
+  staticMembers.insert({"$jsname",
+        StaticMethod("$jsname",
+                &$jsmangledname_templ::$jswrapper,
+                static_cast<napi_property_attributes>(napi_writable | napi_configurable))
+        });
+%}
+
+/* -----------------------------------------------------------------------------
+ * jsnapi_register_static_variable:  template for a statement that registers a static variable.
+ *   - $jsname:         variable name
+ *   - $jsmangledname:  mangled class name
+ *   - $jsgetter:       wrapper of the getter function
+ *   - $jssetter:       wrapper of the setter function
+ * ----------------------------------------------------------------------------- */
+%fragment("jsnapi_register_static_variable", "templates")
+%{
+  // jsnapi_register_static_variable
+  staticMembers.erase("$jsname");
+  staticMembers.insert({"$jsname",
+        StaticAccessor("$jsname",
+                &$jsmangledname_templ::$jsgetter,
+                &$jsmangledname_templ::$jssetter,
+                static_cast<napi_property_attributes>(napi_writable | napi_enumerable | napi_configurable))
+        });
+%}
diff --git a/Lib/javascript/napi/javascriptcomplex.swg b/Lib/javascript/napi/javascriptcomplex.swg
new file mode 100644
index 0000000..3b08644
--- /dev/null
+++ b/Lib/javascript/napi/javascriptcomplex.swg
@@ -0,0 +1,116 @@
+/*
+  Defines the As/From converters for double/float complex, you need to
+  provide complex Type, the Name you want to use in the converters,
+  the complex Constructor method, and the Real and Imag complex
+  accessor methods.
+
+  See the std_complex.i and ccomplex.i for concrete examples.
+*/
+
+/* the common from converter */
+%define %swig_fromcplx_conv(Type, Real, Imag)
+%fragment(SWIG_From_frag(Type),"header",
+          fragment=SWIG_From_frag(double))
+{
+SWIGINTERNINLINE Napi::Value
+SWIG_From_dec(Type)(%ifcplusplus(const Type&, Type) c)
+{
+  Napi::Array vals = Napi::Array::New(0);
+
+  vals.Set(0, SWIG_From(double)(Real(c)));
+  vals.Set(1, SWIG_From(double)(Imag(c)));
+  return vals;
+}
+}
+%enddef
+
+/* the double case */
+%define %swig_cplxdbl_conv(Type, Constructor, Real, Imag)
+%fragment(SWIG_AsVal_frag(Type),"header",
+	  fragment=SWIG_AsVal_frag(double))
+{
+SWIGINTERN int
+SWIG_AsVal_dec(Type) (Napi::Value o, Type* val)
+{
+  if (o.IsArray()) {
+    Napi::Array array = Napi::Array::Cast(o);
+    
+    if (array->Length() != 2) SWIG_Error(SWIG_TypeError, "Illegal argument for complex: must be array[2].");
+    double re, im;
+    Napi::Value r;
+
+    r = array.Get(0);
+    if (!r.IsNumber()) {
+      return SWIG_TypeError;
+    }
+    re = r.ToNumber().DoubleValue();
+    
+    r = array.Get(1);
+    if (!r.IsNumber()) {
+      return SWIG_TypeError;
+    }
+    im = r.ToNumber().DoubleValue();
+    
+    if (val) *val = Constructor(re, im);
+    return SWIG_OK;
+  } else if (o.IsNumber()) {
+    double d = o.ToNumber().DoubleValue();
+    if (val) *val = Constructor(d, 0.0);
+    return SWIG_OK;
+  }
+  return SWIG_TypeError;
+}
+}
+%swig_fromcplx_conv(Type, Real, Imag);
+%enddef
+
+/* the float case */
+%define %swig_cplxflt_conv(Type, Constructor, Real, Imag)
+%fragment(SWIG_AsVal_frag(Type),"header",
+          fragment=SWIG_AsVal_frag(float)) {
+SWIGINTERN int
+SWIG_AsVal_dec(Type) (Napi::Value o, Type* val)
+{
+  if (o.IsArray()) {
+    Napi::Array array = o.As<Napi::Array>();
+    
+    if (array.Length() != 2) SWIG_Error(SWIG_TypeError, "Illegal argument for complex: must be array[2].");
+    double re, im;
+    Napi::Value r;
+    
+    r = array.Get(0);
+    if (!r.IsNumber()) {
+      return SWIG_TypeError;
+    }
+    re = r.ToNumber().DoubleValue();
+    
+    r = array.Get(1);
+    if (!r.IsNumber()) {
+      return SWIG_TypeError;
+    }
+    im = r.ToNumber().DoubleValue();
+    
+    if ((-FLT_MAX <= re && re <= FLT_MAX) && (-FLT_MAX <= im && im <= FLT_MAX)) {
+      if (val) *val = Constructor(%numeric_cast(re, float),
+                                  %numeric_cast(im, float));
+      return SWIG_OK;
+    } else {
+      return SWIG_OverflowError;
+    }    
+  } else if (o.IsNumber()) {
+    float f = static_cast<float>(o.ToNumber().DoubleValue());
+    if (val) *val = Constructor(f, 0.0);
+    return SWIG_OK;
+  }
+  return SWIG_TypeError;
+}
+}
+%swig_fromcplx_conv(Type, Real, Imag);
+%enddef
+
+#define %swig_cplxflt_convn(Type, Constructor, Real, Imag) \
+%swig_cplxflt_conv(Type, Constructor, Real, Imag)
+
+
+#define %swig_cplxdbl_convn(Type, Constructor, Real, Imag) \
+%swig_cplxdbl_conv(Type, Constructor, Real, Imag)
diff --git a/Lib/javascript/napi/javascriptfragments.swg b/Lib/javascript/napi/javascriptfragments.swg
new file mode 100644
index 0000000..4778bf0
--- /dev/null
+++ b/Lib/javascript/napi/javascriptfragments.swg
@@ -0,0 +1,23 @@
+/*
+
+  Create a file with this name, 'javascriptfragments.swg', in your working
+  directory and add all the %fragments you want to take precedence
+  over the default ones defined by swig.
+
+  For example, if you add:
+  
+  %fragment(SWIG_AsVal_frag(int),"header") {
+   SWIGINTERNINLINE int
+   SWIG_AsVal(int)(PyObject *obj, int *val)
+   { 
+     <your code here>;
+   }
+  }
+  
+  this will replace the code used to retrieve an integer value for all
+  the typemaps that need it, including:
+  
+    int, std::vector<int>, std::list<std::pair<int,int> >, etc.
+
+    
+*/
diff --git a/Lib/javascript/napi/javascriptinit.swg b/Lib/javascript/napi/javascriptinit.swg
new file mode 100644
index 0000000..e8b3d38
--- /dev/null
+++ b/Lib/javascript/napi/javascriptinit.swg
@@ -0,0 +1,111 @@
+%insert(header) %{
+#include <assert.h>
+%}
+
+%insert(init) %{
+
+EnvInstanceData::EnvInstanceData(Napi::Env env, swig_module_info *swig_module) :
+env(env), SWIG_NAPI_ObjectWrapCtor(nullptr), ctor(nullptr), swig_module(swig_module) {
+  ctor = new Napi::FunctionReference*[swig_module->size + 1];
+  for (size_t i = 0; i <= swig_module->size; i++) {
+    ctor[i] = nullptr;
+  }
+}
+
+EnvInstanceData::~EnvInstanceData() {
+  for (size_t i = 0; i <= swig_module->size; i++) {
+    if (ctor[i] != nullptr)
+      delete ctor[i];
+    ctor[i] = nullptr;
+  }
+  delete [] ctor;
+  delete SWIG_NAPI_ObjectWrapCtor;
+}
+
+SWIGRUNTIME void
+SWIG_NAPI_SetModule(Napi::Env env, swig_module_info *swig_module) {
+  auto data = new EnvInstanceData(env, swig_module);
+  env.SetInstanceData(data);
+}
+
+SWIGRUNTIME swig_module_info *
+SWIG_NAPI_GetModule(Napi::Env env) {
+  auto data = env.GetInstanceData<EnvInstanceData>();
+  if (data == nullptr) return nullptr;
+  return data->swig_module;
+}
+
+#define SWIG_GetModule(clientdata)                SWIG_NAPI_GetModule(clientdata)
+#define SWIG_SetModule(clientdata, pointer)       SWIG_NAPI_SetModule(clientdata, pointer)
+#define SWIG_INIT_CLIENT_DATA_TYPE                Napi::Env
+
+%}
+
+%insert(init) "swiginit.swg"
+
+// Open the initializer function definition here
+
+%fragment ("js_initializer_define", "templates") %{
+#define SWIG_NAPI_INIT $jsname_initialize
+%}
+
+%insert(init) %{
+Napi::Object Init(Napi::Env env, Napi::Object exports) {
+  SWIG_InitializeModule(env);
+%}
+
+/* -----------------------------------------------------------------------------
+ * js_init_inheritance:  template for enabling the inheritance
+ * ----------------------------------------------------------------------------- */
+%fragment("js_init_inheritance", "templates")
+%{
+  Napi::Value jsObjectValue, jsSetProtoValue;
+  Napi::Object jsObject;
+  Napi::Function setProto;
+  NAPI_CHECK_RESULT(env.Global().Get("Object"), jsObjectValue);
+  NAPI_CHECK_RESULT(jsObjectValue.ToObject(), jsObject);
+  NAPI_CHECK_RESULT(jsObject.Get("setPrototypeOf"), jsSetProtoValue);
+  setProto = jsSetProtoValue.As<Napi::Function>();
+%}
+
+/* -----------------------------------------------------------------------------
+ * js_initializer:  template for the module initializer function
+ *   - $jsname:                     module name
+ *   - $jsnapipreinheritance:       the previous template
+ *   - $jsnapinspaces:              part with code creating namespace objects
+ *   - $jsnapiwrappers:             part with code that registers wrapper functions
+ *   - $jsnapiinitinheritance:      part with inherit statements
+ *   - $jsnapistaticwrappers:       part with code adding static functions to class objects
+ *   - $jsnapiregisterclasses:      part with code that registers class objects in namespaces
+ *   - $jsnapiregisternspaces:      part with code that registers namespaces in parent namespaces
+ * ----------------------------------------------------------------------------- */
+%fragment("js_initializer", "templates")
+%{
+  Napi::Function SWIG_NAPI_ObjectWrap_ctor = SWIG_NAPI_ObjectWrap_inst::GetClass(env);
+  Napi::FunctionReference *SWIG_NAPI_ObjectWrap_ctor_ref = new Napi::FunctionReference();
+  *SWIG_NAPI_ObjectWrap_ctor_ref = Napi::Persistent(SWIG_NAPI_ObjectWrap_ctor);
+  env.GetInstanceData<EnvInstanceData>()->SWIG_NAPI_ObjectWrapCtor = SWIG_NAPI_ObjectWrap_ctor_ref;
+
+  /* create objects for namespaces */
+  $jsnapinspaces
+
+  /* register classes */
+  $jsnapiregisterclasses
+
+  /* enable inheritance */
+  $jsnapipreinheritance
+
+  /* setup inheritances */
+  $jsnapiinitinheritance
+
+  /* create and register namespace objects */
+  $jsnapiregisternspaces
+
+  return exports;
+  goto fail;
+fail:
+  return Napi::Object();
+}
+
+NODE_API_MODULE($jsname, Init)
+%}
diff --git a/Lib/javascript/napi/javascriptprimtypes.swg b/Lib/javascript/napi/javascriptprimtypes.swg
new file mode 100644
index 0000000..e6224f9
--- /dev/null
+++ b/Lib/javascript/napi/javascriptprimtypes.swg
@@ -0,0 +1,387 @@
+/* ------------------------------------------------------------
+ * Primitive Types
+ * ------------------------------------------------------------ */
+
+/* boolean */
+
+%fragment(SWIG_From_frag(bool),"header", "header") {
+SWIGINTERN
+Napi::Value SWIG_From_bool(Napi::Env env, bool val)
+{
+  return Napi::Boolean::New(env, val);
+}
+}
+
+
+%fragment(SWIG_AsVal_frag(bool),"header",
+          fragment=SWIG_AsVal_frag(long)) {
+SWIGINTERN
+int SWIG_AsVal_dec(bool)(Napi::Value obj, bool *val)
+{
+  if(!obj.IsBoolean()) {
+    return SWIG_TypeError;
+  }
+
+  Napi::Boolean b;
+  NAPI_CHECK_RESULT(obj.ToBoolean(), b);
+  if (val) *val = b.Value();
+  return SWIG_OK;
+  goto fail;
+fail:
+  return SWIG_ERROR;
+}
+}
+
+/* char */
+
+%fragment(SWIG_From_frag(unsigned char), "header") {
+SWIGINTERNINLINE Napi::Value
+SWIG_From_unsigned_SS_char(Napi::Env env, unsigned char c)
+{
+  return Napi::Number::New(env, static_cast<double>(c));
+}
+}
+
+
+%fragment(SWIG_From_frag(signed char), "header") {
+SWIGINTERNINLINE Napi::Value
+SWIG_From_signed_SS_char(Napi::Env env, signed char c)
+{
+  return Napi::Number::New(env, static_cast<double>(c));
+}
+}
+
+/* int */
+
+%fragment(SWIG_From_frag(int), "header") {
+SWIGINTERN
+Napi::Value SWIG_From_int(Napi::Env env, int val)
+{
+  return Napi::Number::New(env, val);
+}
+}
+
+%fragment(SWIG_AsVal_frag(int),"header") {
+SWIGINTERN
+int SWIG_AsVal_dec(int)(Napi::Value valRef, int* val)
+{
+  if (!valRef.IsNumber()) {
+    return SWIG_TypeError;
+  }
+  if (val) {
+    Napi::Number num;
+    NAPI_CHECK_RESULT(valRef.ToNumber(), num);
+    *val = static_cast<int>(num.Int32Value());
+  }
+
+  return SWIG_OK;
+  goto fail;
+fail:
+  return SWIG_ERROR;
+}
+}
+
+
+/* unsigned int */
+
+%fragment(SWIG_From_frag(unsigned int), "header") {
+SWIGINTERN
+Napi::Value SWIG_From_unsigned_SS_int(Napi::Env env, unsigned int val)
+{
+  return Napi::Number::New(env, val);
+}
+}
+
+%fragment(SWIG_AsVal_frag(unsigned int),"header") {
+SWIGINTERN
+int SWIG_AsVal_dec(unsigned int)(Napi::Value valRef, unsigned int* val)
+{
+  if (!valRef.IsNumber()) {
+    return SWIG_TypeError;
+  }
+  if (val) {
+    Napi::Number num;
+    NAPI_CHECK_RESULT(valRef.ToNumber(), num);
+    if (num.Int64Value() < 0) {
+      return SWIG_TypeError;
+    }
+    *val = static_cast<unsigned int>(num.Uint32Value());
+  }
+
+  return SWIG_OK;
+  goto fail;
+fail:
+  return SWIG_ERROR;
+}
+}
+
+
+/* short */
+
+%fragment("SWIG_Env_FromShort", "header") {
+SWIGINTERN
+Napi::Value SWIG_From_short(Napi::Env env, short val)
+{
+  return Napi::Number::New(env, val);
+}
+}
+
+%fragment(SWIG_AsVal_frag(short),"header") {
+SWIGINTERN
+int SWIG_AsVal_dec(short)(Napi::Value valRef, short* val)
+{
+  if (!valRef.IsNumber()) {
+    return SWIG_TypeError;
+  }
+  if (val) {
+    Napi::Number num;
+    NAPI_CHECK_RESULT(valRef.ToNumber(), num);
+    *val = static_cast<short>(num.Int32Value());
+  }
+
+  return SWIG_OK;
+  goto fail;
+fail:
+  return SWIG_ERROR;
+}
+}
+
+
+/* unsigned short */
+
+%fragment(SWIG_From_frag(unsigned short), "header") {
+SWIGINTERN
+Napi::Value SWIG_From_unsigned_SS_short(Napi::Env env, unsigned short val)
+{
+  return Napi::Number::New(env, val);
+}
+}
+
+%fragment(SWIG_AsVal_frag(unsigned short),"header") {
+SWIGINTERN
+int SWIG_AsVal_dec(unsigned short)(Napi::Value valRef, unsigned short* val)
+{
+  if (!valRef.IsNumber()) {
+    return SWIG_TypeError;
+  }
+  if (val) {
+    Napi::Number num;
+    NAPI_CHECK_RESULT(valRef.ToNumber(), num);
+    if (num.Int64Value() < 0) {
+      return SWIG_TypeError;
+    }
+    *val = static_cast<unsigned short>(num.Uint32Value());
+  }
+
+  return SWIG_OK;
+  goto fail;
+fail:
+  return SWIG_ERROR;
+}
+}
+
+
+/* long */
+
+%fragment(SWIG_From_frag(long), "header") {
+SWIGINTERN
+Napi::Value SWIG_From_long(Napi::Env env, long val)
+{
+  return Napi::Number::New(env, val);
+}
+}
+
+%fragment(SWIG_AsVal_frag(long),"header",
+          fragment="SWIG_CanCastAsInteger") {
+SWIGINTERN
+int SWIG_AsVal_dec(long)(Napi::Value obj, long* val)
+{
+  if (!obj.IsNumber()) {
+    return SWIG_TypeError;
+  }
+  if (val) {
+    Napi::Number num;
+    NAPI_CHECK_RESULT(obj.ToNumber(), num);
+    *val = static_cast<long>(num.Int64Value());
+  }
+
+  return SWIG_OK;
+  goto fail;
+fail:
+  return SWIG_ERROR;
+}
+}
+
+/* unsigned long */
+
+%fragment(SWIG_From_frag(unsigned long), "header") {
+SWIGINTERN
+Napi::Value SWIG_From_unsigned_SS_long(Napi::Env env, unsigned long val)
+{
+  return Napi::Number::New(env, val);
+}
+}
+
+%fragment(SWIG_AsVal_frag(unsigned long),"header",
+          fragment="SWIG_CanCastAsInteger") {
+SWIGINTERN
+int SWIG_AsVal_dec(unsigned long)(Napi::Value obj, unsigned long *val)
+{
+  if(!obj.IsNumber()) {
+    return SWIG_TypeError;
+  }
+  if (val) {
+    Napi::Number num;
+    NAPI_CHECK_RESULT(obj.ToNumber(), num);
+    if (num.Int64Value() < 0) {
+      return SWIG_TypeError;
+    }
+    *val = static_cast<unsigned long>(num.Int64Value());
+  }
+  return SWIG_OK;
+  goto fail;
+fail:
+  return SWIG_ERROR;
+}
+}
+
+/* long long */
+
+%fragment(SWIG_From_frag(long long), "header", fragment="SWIG_LongLongAvailable") {
+%#ifdef SWIG_LONG_LONG_AVAILABLE
+SWIGINTERN
+Napi::Value SWIG_From_long_SS_long(Napi::Env env, long long val)
+{
+  return Napi::Number::New(env, val);
+}
+%#endif
+}
+
+%fragment(SWIG_AsVal_frag(long long),"header",
+    fragment=SWIG_AsVal_frag(long),
+    fragment="SWIG_CanCastAsInteger",
+    fragment="SWIG_LongLongAvailable") {
+%#ifdef SWIG_LONG_LONG_AVAILABLE
+SWIGINTERN
+int SWIG_AsVal_dec(long long)(Napi::Value obj, long long* val)
+{
+  if(!obj.IsNumber()) {
+    return SWIG_TypeError;
+  }
+
+  if (val) {
+    Napi::Number num;
+    NAPI_CHECK_RESULT(obj.ToNumber(), num);
+    *val = static_cast<long long>(num.Int64Value());
+  }
+  return SWIG_OK;
+  goto fail;
+fail:
+  return SWIG_ERROR;
+}
+%#endif
+}
+
+/* unsigned long long */
+
+%fragment(SWIG_From_frag(unsigned long long), "header", fragment="SWIG_LongLongAvailable") {
+%#ifdef SWIG_LONG_LONG_AVAILABLE
+SWIGINTERN
+Napi::Value SWIG_From_unsigned_SS_long_SS_long(Napi::Env env, unsigned long long val)
+{
+  return Napi::Number::New(env, val);
+}
+%#endif
+}
+
+
+%fragment(SWIG_AsVal_frag(unsigned long long),"header",
+    fragment=SWIG_AsVal_frag(unsigned long),
+    fragment="SWIG_CanCastAsInteger",
+    fragment="SWIG_LongLongAvailable") {
+%#ifdef SWIG_LONG_LONG_AVAILABLE
+SWIGINTERN
+int SWIG_AsVal_dec(unsigned long long)(Napi::Value obj, unsigned long long *val)
+{
+  if(!obj.IsNumber()) {
+    return SWIG_TypeError;
+  }
+  if (obj.ToNumber().Int64Value() < 0) {
+    return SWIG_TypeError;
+  }
+  if (val) {
+    Napi::Number num;
+    NAPI_CHECK_RESULT(obj.ToNumber(), num);
+    *val = static_cast<unsigned long long>(num.Int64Value());
+  }
+  return SWIG_OK;
+  goto fail;
+fail:
+  return SWIG_ERROR;
+}
+%#endif
+}
+
+
+/* float */
+
+%fragment(SWIG_From_frag(float), "header") {
+SWIGINTERN
+Napi::Value SWIG_From_float(Napi::Env env, float val)
+{
+  return Napi::Number::New(env, val);
+}
+}
+
+%fragment(SWIG_AsVal_frag(float),"header") {
+SWIGINTERN
+int SWIG_AsVal_dec(float)(Napi::Value obj, float *val)
+{
+  if(!obj.IsNumber()) {
+    return SWIG_TypeError;
+  }
+
+  if(val) {
+    Napi::Number num;
+    NAPI_CHECK_RESULT(obj.ToNumber(), num);
+    *val = static_cast<float>(num.DoubleValue());
+  }
+
+  return SWIG_OK;
+  goto fail;
+fail:
+  return SWIG_ERROR;
+}
+}
+
+
+/* double */
+
+%fragment(SWIG_From_frag(double), "header") {
+SWIGINTERN
+Napi::Value SWIG_From_double(Napi::Env env, double val)
+{
+  return Napi::Number::New(env, val);
+}
+}
+
+%fragment(SWIG_AsVal_frag(double),"header") {
+SWIGINTERN
+int SWIG_AsVal_dec(double)(Napi::Value obj, double *val)
+{
+  if(!obj.IsNumber()) {
+    return SWIG_TypeError;
+  }
+
+  if(val) {
+    Napi::Number num;
+    NAPI_CHECK_RESULT(obj.ToNumber(), num);
+    *val = static_cast<double>(num.DoubleValue());
+  }
+
+  return SWIG_OK;
+  goto fail;
+fail:
+  return SWIG_ERROR;
+}
+}
diff --git a/Lib/javascript/napi/javascriptrun.swg b/Lib/javascript/napi/javascriptrun.swg
new file mode 100644
index 0000000..ce698fe
--- /dev/null
+++ b/Lib/javascript/napi/javascriptrun.swg
@@ -0,0 +1,446 @@
+/* ---------------------------------------------------------------------------
+ * Error handling
+ *
+ * ---------------------------------------------------------------------------*/
+
+/*
+ * We support several forms:
+ *
+ * SWIG_Raise("Error message")
+ * which creates an Error object with the error message
+ *
+ * SWIG_Raise(SWIG_TypeError, "Type error")
+ * which creates the specified error type with the message
+ *
+ * SWIG_Raise(obj)
+ * which throws the object itself
+ *
+ * SWIG_Raise(obj, "Exception const &", SWIGType_p_Exception)
+ * which also throws the object itself and discards the unneeded extra type info
+ *
+ * These must be functions instead of macros to use the C++ overloading to
+ * resolve the arguments
+ */
+#define SWIG_exception(code, msg)               SWIG_Error(code, msg)
+#define SWIG_fail                               goto fail
+
+#ifdef NAPI_CPP_EXCEPTIONS
+
+#define SWIG_Error(code, msg)                   SWIG_NAPI_Raise(env, code, msg)
+#define NAPI_CHECK_MAYBE(maybe)                 (maybe)
+#define NAPI_CHECK_RESULT(maybe, result)        (result = maybe)
+
+SWIGINTERN void SWIG_NAPI_Raise(Napi::Env env, const char *msg) {
+  throw Napi::Error::New(env, msg);
+}
+
+SWIGINTERN void SWIG_NAPI_Raise(Napi::Env env, int type, const char *msg) {
+  switch(type) {
+    default:
+    case SWIG_IOError:
+    case SWIG_MemoryError:
+    case SWIG_SystemError:
+    case SWIG_RuntimeError:
+    case SWIG_DivisionByZero:
+    case SWIG_SyntaxError:
+      throw Napi::Error::New(env, msg);
+    case SWIG_OverflowError:
+    case SWIG_IndexError:
+      throw Napi::RangeError::New(env, msg);
+    case SWIG_ValueError:
+    case SWIG_TypeError:
+      throw Napi::TypeError::New(env, msg);
+  }
+}
+
+SWIGINTERN void SWIG_NAPI_Raise(Napi::Env env, Napi::Value obj,
+        const char *msg = nullptr, swig_type_info *info = nullptr) {
+  throw Napi::Error(env, obj);
+}
+
+#else
+
+#define SWIG_Error(code, msg)     do { SWIG_NAPI_Raise(env, code, msg); SWIG_fail; } while (0)
+#define NAPI_CHECK_MAYBE(maybe)   do { if (maybe.IsNothing()) SWIG_fail; } while (0)
+#define NAPI_CHECK_RESULT(maybe, result)          \
+        do {                                      \
+                auto r = maybe;                   \
+                if (r.IsNothing()) SWIG_fail;     \
+                result = r.Unwrap();              \
+        } while (0)
+
+SWIGINTERN void SWIG_NAPI_Raise(Napi::Env env, const char *msg) {
+  Napi::Error::New(env, msg).ThrowAsJavaScriptException();
+}
+
+SWIGINTERN void SWIG_NAPI_Raise(Napi::Env env, int type, const char *msg) {
+  switch(type) {
+    default:
+    case SWIG_IOError:
+    case SWIG_MemoryError:
+    case SWIG_SystemError:
+    case SWIG_RuntimeError:
+    case SWIG_DivisionByZero:
+    case SWIG_SyntaxError:
+      Napi::Error::New(env, msg).ThrowAsJavaScriptException();
+      return;
+    case SWIG_OverflowError:
+    case SWIG_IndexError:
+      Napi::RangeError::New(env, msg).ThrowAsJavaScriptException();
+      return;
+    case SWIG_ValueError:
+    case SWIG_TypeError:
+      Napi::TypeError::New(env, msg).ThrowAsJavaScriptException();
+      return;
+  }
+}
+
+SWIGINTERN void SWIG_NAPI_Raise(Napi::Env env, Napi::Value obj,
+        const char *msg = nullptr, swig_type_info *info = nullptr) {
+  Napi::Error(env, obj).ThrowAsJavaScriptException();
+}
+
+#endif
+
+void JS_veto_set_variable(const Napi::CallbackInfo &info) {
+  SWIG_NAPI_Raise(info.Env(), "Tried to write read-only variable.");
+}
+
+struct EnvInstanceData {
+  Napi::Env env;
+  // Base class per-environment constructor, used to check
+  // if a JS object is a SWIG wrapper
+  Napi::FunctionReference *SWIG_NAPI_ObjectWrapCtor;
+  // Per-environment wrapper constructors, indexed by the number in
+  // swig_type->clientdata
+  Napi::FunctionReference **ctor;
+  swig_module_info *swig_module;
+  EnvInstanceData(Napi::Env, swig_module_info *);
+  ~EnvInstanceData();
+};
+
+typedef size_t SWIG_NAPI_ClientData;
+
+// Base class for all wrapped objects,
+// used mostly when unwrapping unknown objects
+template <typename SWIG_OBJ_WRAP>
+class SWIG_NAPI_ObjectWrap_templ : public Napi::ObjectWrap<SWIG_OBJ_WRAP> {
+  public:
+    void *self;
+    bool owned;
+    size_t size;
+    swig_type_info *info;
+    SWIG_NAPI_ObjectWrap_templ(const Napi::CallbackInfo &info);
+    SWIG_NAPI_ObjectWrap_templ(bool, const Napi::CallbackInfo &info) :
+        Napi::ObjectWrap<SWIG_OBJ_WRAP>(info),
+        self(nullptr),
+        owned(true),
+        size(0),
+        info(nullptr)
+        {}
+    virtual ~SWIG_NAPI_ObjectWrap_templ() {};
+
+    Napi::Value ToString(const Napi::CallbackInfo &info);
+};
+
+template <typename SWIG_OBJ_WRAP>
+SWIG_NAPI_ObjectWrap_templ<SWIG_OBJ_WRAP>::SWIG_NAPI_ObjectWrap_templ(const Napi::CallbackInfo &info) :
+        Napi::ObjectWrap<SWIG_OBJ_WRAP>(info), size(0), info(nullptr) { 
+  Napi::Env env = info.Env();
+  if (info.Length() == 1 && info[0].IsExternal()) {
+    // This constructor has been called internally from C++/SWIG
+    // to wrap an already existing C++ object of unknown type in JS
+    this->self = info[0].As<Napi::External<void>>().Data();
+    this->owned = false;
+  } else {
+    SWIG_Error(SWIG_ERROR, "This constructor is not accessible from JS");
+  }
+  return;
+  goto fail;
+fail:
+  return;
+}
+
+template <typename SWIG_OBJ_WRAP>
+Napi::Value SWIG_NAPI_ObjectWrap_templ<SWIG_OBJ_WRAP>::ToString(const Napi::CallbackInfo &info) {
+  Napi::Env env = info.Env();
+  static char repr[128];
+  const char *name = SWIG_TypePrettyName(this->info);
+  snprintf(repr, sizeof(repr), "{SwigObject %s (%s) at %p %s}",
+    this->info ? this->info->name : "unknown",
+    name ? name : "unknown",
+    this->self,
+    this->owned ? "[owned]" : "[copy]");
+  return Napi::String::New(env, repr);
+}
+
+class SWIG_NAPI_ObjectWrap_inst : public SWIG_NAPI_ObjectWrap_templ<SWIG_NAPI_ObjectWrap_inst> {
+public:
+  using SWIG_NAPI_ObjectWrap_templ::SWIG_NAPI_ObjectWrap_templ;
+  static Napi::Function GetClass(Napi::Env);
+  static void GetMembers(
+    Napi::Env,
+    std::map<std::string, SWIG_NAPI_ObjectWrap_templ::PropertyDescriptor> &,
+    std::map<std::string, SWIG_NAPI_ObjectWrap_templ::PropertyDescriptor> &
+  );
+};
+
+void SWIG_NAPI_ObjectWrap_inst::GetMembers(
+        Napi::Env env,
+        std::map<std::string, SWIG_NAPI_ObjectWrap_templ::PropertyDescriptor> &members,
+        std::map<std::string, SWIG_NAPI_ObjectWrap_templ::PropertyDescriptor> &
+) {
+  members.erase("toString");
+  members.insert({"toString", SWIG_NAPI_ObjectWrap_templ::InstanceMethod("toString", &SWIG_NAPI_ObjectWrap_templ::ToString)});
+}
+
+Napi::Function SWIG_NAPI_ObjectWrap_inst::GetClass(Napi::Env env) {
+  return Napi::ObjectWrap<SWIG_NAPI_ObjectWrap_inst>::DefineClass(env, "SwigObject", {});
+}
+
+SWIGRUNTIME int SWIG_NAPI_ConvertInstancePtr(Napi::Object objRef, void **ptr, swig_type_info *info, int flags) {
+  SWIG_NAPI_ObjectWrap_inst *ow;
+  Napi::Env env = objRef.Env();
+  if(!objRef.IsObject()) return SWIG_ERROR;
+
+  // Check if this is a SWIG wrapper
+  Napi::FunctionReference *ctor = env.GetInstanceData<EnvInstanceData>()->SWIG_NAPI_ObjectWrapCtor;
+  bool instanceOf;
+  NAPI_CHECK_RESULT(objRef.InstanceOf(ctor->Value()), instanceOf);
+  if (!instanceOf) {
+    return SWIG_TypeError;
+  }
+
+  ow = Napi::ObjectWrap<SWIG_NAPI_ObjectWrap_inst>::Unwrap(objRef);
+
+  // Now check if the SWIG type is compatible unless the types match exactly or the type is unknown
+  if(info && ow->info != info && ow->info != nullptr) {
+    swig_cast_info *tc = SWIG_TypeCheckStruct(ow->info, info);
+    if (!tc && ow->info->name) {
+      tc = SWIG_TypeCheck(ow->info->name, info);
+    }
+    bool type_valid = tc != 0;
+    if(!type_valid) {
+      return SWIG_TypeError;
+    }
+    int newmemory = 0;
+    *ptr = SWIG_TypeCast(tc, ow->self, &newmemory);
+    assert(!newmemory); /* newmemory handling not yet implemented */
+  } else {
+    *ptr = ow->self;
+  }
+
+  if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !ow->owned) {
+    return SWIG_ERROR_RELEASE_NOT_OWNED;
+  } else {
+    if (flags & SWIG_POINTER_DISOWN) {
+      ow->owned = false;
+    }
+    if (flags & SWIG_POINTER_CLEAR) {
+      ow->self = nullptr;
+    }
+  }
+  return SWIG_OK;
+  goto fail;
+fail:
+  return SWIG_ERROR;
+}
+
+
+SWIGRUNTIME int SWIG_NAPI_GetInstancePtr(Napi::Value valRef, void **ptr) {
+  SWIG_NAPI_ObjectWrap_inst *ow;
+  if(!valRef.IsObject()) {
+    return SWIG_TypeError;
+  }
+  Napi::Object objRef;
+  NAPI_CHECK_RESULT(valRef.ToObject(), objRef);
+  ow = Napi::ObjectWrap<SWIG_NAPI_ObjectWrap_inst>::Unwrap(objRef);
+
+  if(ow->self == nullptr) {
+    return SWIG_ERROR;
+  }
+
+  *ptr = ow->self;
+  return SWIG_OK;
+  goto fail;
+fail:
+  return SWIG_ERROR;
+}
+
+
+SWIGRUNTIME int SWIG_NAPI_ConvertPtr(Napi::Value valRef, void **ptr, swig_type_info *info, int flags) {
+  // special case: JavaScript null => C NULL pointer
+  if (valRef.IsNull()) {
+    *ptr=0;
+    return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
+  }
+
+  if (!valRef.IsObject()) {
+    return SWIG_TypeError;
+  }
+
+  Napi::Object objRef;
+  NAPI_CHECK_RESULT(valRef.ToObject(), objRef);
+  return SWIG_NAPI_ConvertInstancePtr(objRef, ptr, info, flags);
+  goto fail;
+fail:
+  return SWIG_ERROR;
+}
+
+SWIGRUNTIME Napi::Value SWIG_NAPI_NewPointerObj(Napi::Env env, void *ptr, swig_type_info *info, int flags) {
+  Napi::External<void> native;
+  Napi::FunctionReference *ctor;
+
+  if (ptr == nullptr) {
+    return env.Null();
+  }
+  native = Napi::External<void>::New(env, ptr);
+
+  size_t *idx = info != nullptr ?
+        reinterpret_cast<SWIG_NAPI_ClientData *>(info->clientdata) :
+        nullptr;
+  if (idx == nullptr) {
+    // This type does not have a dedicated wrapper
+    ctor = env.GetInstanceData<EnvInstanceData>()->SWIG_NAPI_ObjectWrapCtor;
+  } else {
+    ctor = env.GetInstanceData<EnvInstanceData>()->ctor[*idx];
+  }
+
+  Napi::Value wrapped;
+  NAPI_CHECK_RESULT(ctor->New({native}), wrapped);
+
+  // Preserve the type even if using the generic wrapper
+  if (idx == nullptr && info != nullptr) {
+    Napi::Object obj;
+    NAPI_CHECK_RESULT(wrapped.ToObject(), obj);
+    Napi::ObjectWrap<SWIG_NAPI_ObjectWrap_inst>::Unwrap(obj)->info = info;
+  }
+
+  if ((flags & SWIG_POINTER_OWN) == SWIG_POINTER_OWN) {
+    Napi::Object obj;
+    NAPI_CHECK_RESULT(wrapped.ToObject(), obj);
+    Napi::ObjectWrap<SWIG_NAPI_ObjectWrap_inst>::Unwrap(obj)->owned = true;
+  }
+
+  return wrapped;
+  goto fail;
+fail:
+  return Napi::Value();
+}
+
+#define SWIG_ConvertPtr(obj, ptr, info, flags)          SWIG_NAPI_ConvertPtr(obj, ptr, info, flags)
+#define SWIG_NewPointerObj(ptr, info, flags)            SWIG_NAPI_NewPointerObj(env, ptr, info, flags)
+
+#define SWIG_ConvertInstance(obj, pptr, type, flags)    SWIG_NAPI_ConvertInstancePtr(obj, pptr, type, flags)
+#define SWIG_NewInstanceObj(thisvalue, type, flags)     SWIG_NAPI_NewPointerObj(env, thisvalue, type, flags)
+
+#define SWIG_ConvertFunctionPtr(obj, pptr, type)        SWIG_NAPI_ConvertPtr(obj, pptr, type, 0)
+#define SWIG_NewFunctionPtrObj(ptr, type)               SWIG_NAPI_NewPointerObj(env, ptr, type, 0)
+
+#define SWIG_GetInstancePtr(obj, ptr)                   SWIG_NAPI_GetInstancePtr(obj, ptr)
+
+SWIGRUNTIME Napi::Value _SWIG_NAPI_wrap_equals(const Napi::CallbackInfo &info) {
+  Napi::Env env = info.Env();
+  Napi::Value jsresult;
+  void *arg1 = (void *) 0 ;
+  void *arg2 = (void *) 0 ;
+  bool result;
+  int res1;
+  int res2;
+
+  if(info.Length() != 1) SWIG_Error(SWIG_ERROR, "Illegal number of arguments for equals.");
+
+  res1 = SWIG_GetInstancePtr(info.This(), &arg1);
+  if (!SWIG_IsOK(res1)) {
+    SWIG_Error(SWIG_ERROR, "Could not get pointer from 'this' object for equals.");
+  }
+  res2 = SWIG_GetInstancePtr(info[0], &arg2);
+  if (!SWIG_IsOK(res2)) {
+    SWIG_Error(SWIG_ArgError(res2), " in method '" "equals" "', argument " "1"" of type '" "void *""'");
+  }
+
+  result = (bool)(arg1 == arg2);
+  jsresult = Napi::Boolean::New(env, result);
+
+  return jsresult;
+  goto fail;
+fail:
+  return Napi::Value();
+}
+
+SWIGRUNTIME Napi::Value _wrap_getCPtr(const Napi::CallbackInfo &info) {
+  Napi::Env env = info.Env();
+  Napi::Value jsresult;
+  void *arg1 = (void *) 0 ;
+  long result;
+  int res1;
+
+  res1 = SWIG_GetInstancePtr(info.This(), &arg1);
+  if (!SWIG_IsOK(res1)) {
+    SWIG_Error(SWIG_ArgError(res1), " in method '" "getCPtr" "', argument " "1"" of type '" "void *""'");
+  }
+
+  result = (long)arg1;
+  jsresult = Napi::Number::New(env, result);
+
+  return jsresult;
+  goto fail;
+fail:
+  return Napi::Value();
+}
+
+
+/* ---------------------------------------------------------------------------
+ * PackedData object
+ * (objects visible to JS that do not have a dedicated wrapper but must preserve type)
+ * ---------------------------------------------------------------------------*/
+
+SWIGRUNTIME
+Napi::Value SWIG_NAPI_NewPackedObj(Napi::Env env, void *data, size_t size, swig_type_info *type) {
+  void *data_copy = new uint8_t[size];
+  memcpy(data_copy, data, size);
+  Napi::Value val = SWIG_NAPI_NewPointerObj(env, data_copy, type, SWIG_POINTER_OWN);
+  Napi::Object obj;
+  if (val.IsEmpty()) goto fail;
+
+  NAPI_CHECK_RESULT(val.ToObject(), obj);
+  Napi::ObjectWrap<SWIG_NAPI_ObjectWrap_inst>::Unwrap(obj)->size = size;
+
+fail:
+  return val;
+}
+
+SWIGRUNTIME
+int SWIG_NAPI_ConvertPacked(Napi::Value valRef, void *ptr, size_t size, swig_type_info *type) {
+  void *tmp;
+  if (!SWIG_IsOK(SWIG_NAPI_ConvertPtr(valRef, &tmp, type, 0))) {
+    return SWIG_ERROR;
+  }
+  memcpy(ptr, tmp, size);
+  return SWIG_OK;
+}
+
+#define SWIG_ConvertMember(obj, ptr, sz, ty)            SWIG_NAPI_ConvertPacked(obj, ptr, sz, ty)
+#define SWIG_NewMemberObj(ptr, sz, type)                SWIG_NAPI_NewPackedObj(env, ptr, sz, type)
+
+
+/* ---------------------------------------------------------------------------
+ * Support for IN/OUTPUT typemaps (see Lib/typemaps/inoutlist.swg)
+ *
+ * ---------------------------------------------------------------------------*/
+
+SWIGRUNTIME
+
+Napi::Value SWIG_NAPI_AppendOutput(Napi::Env env, Napi::Value result, Napi::Value obj) {
+  if (result.IsUndefined()) {
+    result = Napi::Array::New(env);
+  } else if (!result.IsArray()) {
+    Napi::Array tmparr = Napi::Array::New(env);
+    tmparr.Set(static_cast<uint32_t>(0), result);
+    result = tmparr;
+  }
+
+  Napi::Array arr = result.As<Napi::Array>();
+  arr.Set(arr.Length(), obj);
+  return arr;
+}
diff --git a/Lib/javascript/napi/javascriptruntime.swg b/Lib/javascript/napi/javascriptruntime.swg
new file mode 100644
index 0000000..42f11ed
--- /dev/null
+++ b/Lib/javascript/napi/javascriptruntime.swg
@@ -0,0 +1,40 @@
+/* -----------------------------------------------------------------------------
+ * javascriptruntime.swg
+ *
+ * ----------------------------------------------------------------------------- */
+
+// NAPI
+// ----------
+
+%insert(runtime) %{
+#if defined(_CPPUNWIND) || defined(__EXCEPTIONS)
+#define NAPI_CPP_EXCEPTIONS
+#else
+#define NAPI_DISABLE_CPP_EXCEPTIONS
+#define NODE_ADDON_API_ENABLE_MAYBE
+#endif
+
+// This gives us
+// Branch Node.js v10.x - from v10.20.0
+// Branch Node.js v12.x - from v12.17.0
+// Everything from Node.js v14.0.0 on
+// Our limiting feature is napi_set_instance_data
+#ifndef NAPI_VERSION
+#define NAPI_VERSION 6
+#elif NAPI_VERSION < 6
+#error NAPI_VERSION 6 is the minimum supported target (Node.js >=14, >=12.17, >=10.20)
+#endif
+#include <napi.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <map>
+%}
+
+%insert(runtime) "swigrun.swg";         /* SWIG API */
+%insert(runtime) "swigerrors.swg";      /* SWIG errors */
+
+%insert(runtime) "javascriptrun.swg"
+
diff --git a/Lib/javascript/napi/javascriptstrings.swg b/Lib/javascript/napi/javascriptstrings.swg
new file mode 100644
index 0000000..7293c7b
--- /dev/null
+++ b/Lib/javascript/napi/javascriptstrings.swg
@@ -0,0 +1,77 @@
+
+/* ------------------------------------------------------------
+ *  utility methods for char strings 
+ * ------------------------------------------------------------ */
+%fragment("SWIG_AsCharPtrAndSize", "header", fragment="SWIG_pchar_descriptor") {
+SWIGINTERN int
+SWIG_AsCharPtrAndSize(Napi::Value valRef, char** cptr, size_t* psize, int *alloc)
+{
+  if(valRef.IsString()) {
+    Napi::String js_str;
+    NAPI_CHECK_RESULT(valRef.ToString(), js_str);
+
+    std::string str = js_str.Utf8Value();
+    size_t len = str.size() + 1;
+    char* cstr = (char*) %new_array(len, char);
+    memcpy(cstr, str.data(), len);
+    
+    if(alloc) *alloc = SWIG_NEWOBJ;
+    if(psize) *psize = len;
+    if(cptr) *cptr = cstr;
+    
+    return SWIG_OK;
+  } else {
+    if(valRef.IsObject()) {
+      swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
+      Napi::Object obj;
+      NAPI_CHECK_RESULT(valRef.ToObject(), obj);
+      // try if the object is a wrapped char[]
+      if (pchar_descriptor) {
+        void* vptr = 0;
+        if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) {
+          if (cptr) *cptr = (char *) vptr;
+          if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0;
+          if (alloc) *alloc = SWIG_OLDOBJ;
+          return SWIG_OK;
+        }
+      }
+    }
+  }
+  goto fail;
+fail:
+  return SWIG_TypeError;
+}
+}
+
+
+%fragment(SWIG_From_frag(char), "header") {
+SWIGINTERNINLINE Napi::Value
+SWIG_From_char(Napi::Env env, char c)
+{
+  Napi::String js_str = Napi::String::New(env, &c, 1);
+  return js_str;
+}
+}
+
+
+%fragment("SWIG_FromCharPtr", "header", fragment = "SWIG_FromCharPtrAndSize") {
+// Override the default one with an empty one
+}
+
+%fragment("SWIG_FromCharPtrAndSize", "header") {
+SWIGINTERNINLINE Napi::Value
+SWIG_Env_FromCharPtrAndSize(Napi::Env env, const char* carray, size_t size)
+{
+  if (carray) {
+    Napi::String js_str = Napi::String::New(env, carray, size);
+    return js_str;
+  } else {
+    return env.Undefined();
+  }
+}
+}
+
+%insert(runtime) %{
+#define SWIG_FromCharPtrAndSize(cptr, size) SWIG_Env_FromCharPtrAndSize(env, cptr, size)
+#define SWIG_FromCharPtr(cptr)              SWIG_Env_FromCharPtrAndSize(env, cptr, strlen(cptr))
+%}
diff --git a/Lib/javascript/napi/javascripttypemaps.swg b/Lib/javascript/napi/javascripttypemaps.swg
new file mode 100644
index 0000000..d7d21be
--- /dev/null
+++ b/Lib/javascript/napi/javascripttypemaps.swg
@@ -0,0 +1,56 @@
+/* ------------------------------------------------------------
+ *  Typemap specializations for Javascript
+ * ------------------------------------------------------------ */
+
+/* ------------------------------------------------------------
+ *  Fragment section
+ * ------------------------------------------------------------ */
+
+/* These macros are necessary to provide an extra parameter
+   to SWIG_AsVal_dec functions (Napi::Env environment).
+   They must be defined before including `typemaps/fragments.swg`
+*/
+#define SWIG_FROM_DECL_ARGS SWIG_NAPI_FROM_DECL_ARGS
+#define SWIG_FROM_CALL_ARGS SWIG_NAPI_FROM_CALL_ARGS
+
+/* Include fundamental fragemt definitions */
+%include <typemaps/fragments.swg>
+
+/* Look for user fragments file. */
+%include <javascriptfragments.swg>
+
+/* Javascript fragments for fundamental types */
+%include <javascriptprimtypes.swg>
+
+/* Javascript fragments for char* strings */
+%include <javascriptstrings.swg>
+
+
+/* ------------------------------------------------------------
+ *  Unified typemap section
+ * ------------------------------------------------------------ */
+
+/* Javascript types */
+
+#define SWIG_Object                     Napi::Value
+#define VOID_Object                     env.Undefined()
+
+/* Overload of the output/constant/exception/dirout handling */
+
+/* append output */
+#define SWIG_AppendOutput(result, obj)  SWIG_NAPI_AppendOutput(env, result, obj)
+
+/* set constant */
+#define SWIG_SetConstant(name, obj)
+
+/* raise */
+#define SWIG_Raise(...)                 SWIG_NAPI_Raise(env, __VA_ARGS__)
+
+%insert("runtime") %{
+#define SWIG_NAPI_FROM_DECL_ARGS(arg1)              (Napi::Env env, arg1)
+#define SWIG_NAPI_FROM_CALL_ARGS(arg1)              (env, arg1)
+%}
+
+
+/* Include the unified typemap library */
+%include <typemaps/swigtypemaps.swg>
diff --git a/Lib/javascript/napi/nodejs_buffer.i b/Lib/javascript/napi/nodejs_buffer.i
new file mode 100644
index 0000000..d95ba2d
--- /dev/null
+++ b/Lib/javascript/napi/nodejs_buffer.i
@@ -0,0 +1,47 @@
+/*
+ * To include generic versions of the in typemaps, add:
+ *
+ * %typemap(in)        (void *, size_t) = (const void* buffer_data, const size_t buffer_len);
+ * %typemap(typecheck) (void *, size_t) = (const void* buffer_data, const size_t buffer_len);
+ *
+ * or to discriminate by argument names:
+ * %typemap(in)        (void *data, size_t length) = (const void* buffer_data, const size_t buffer_len);
+ * %typemap(typecheck) (void *data, size_t length) = (const void* buffer_data, const size_t buffer_len);
+ */
+
+%typemap(in) (const void* buffer_data, const size_t buffer_len) {
+  if ($input.IsBuffer()) {
+    Napi::Buffer<char> buf = $input.As<Napi::Buffer<char>>();
+    $1 = reinterpret_cast<void *>(buf.Data());
+    $2 = buf.ByteLength();
+  } else {
+    SWIG_exception_fail(SWIG_TypeError, "in method '$symname', argument is not a Buffer");
+  }
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_VOIDPTR) (const void* buffer_data, const size_t buffer_len) {
+  $1 = $input.IsBuffer();
+}
+
+
+/*
+ * In order to use the argout typemap, the function must have the following signature:
+ *
+ * void buffer(void **buffer_data, size_t *buffer_len)
+ *
+ * In this case, this function will be wrapped by a JS function that takes
+ * no arguments (because of numinputs=0) and returns a Buffer
+ */
+
+%typemap(in, numinputs=0) (void **buffer_data, size_t *buffer_len) (void *temp_data, size_t temp_len) {
+  $1 = &temp_data;
+  $2 = &temp_len;
+}
+%typemap(argout) (void **buffer_data, size_t *buffer_len) {
+  if (*$1 != nullptr) {
+    Napi::Buffer<char> buf = Napi::Buffer<char>::Copy(env, reinterpret_cast<char *>(*$1), *$2);
+    NAPI_CHECK_RESULT(buf.As<Napi::Value>(), $result);
+  } else {
+    $result = env.Null();
+  }
+}
diff --git a/Lib/javascript/napi/std_auto_ptr.i b/Lib/javascript/napi/std_auto_ptr.i
new file mode 100644
index 0000000..3d7ae8b
--- /dev/null
+++ b/Lib/javascript/napi/std_auto_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+  %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class auto_ptr {};
+}
diff --git a/Lib/javascript/napi/std_common.i b/Lib/javascript/napi/std_common.i
new file mode 100644
index 0000000..cee11e8
--- /dev/null
+++ b/Lib/javascript/napi/std_common.i
@@ -0,0 +1,5 @@
+%include <std_except.i>
+
+%apply size_t { std::size_t };
+%apply const size_t& { const std::size_t& };
+
diff --git a/Lib/javascript/napi/std_complex.i b/Lib/javascript/napi/std_complex.i
new file mode 100644
index 0000000..a252e0a
--- /dev/null
+++ b/Lib/javascript/napi/std_complex.i
@@ -0,0 +1,26 @@
+/*
+ *  STD C++ complex typemaps
+ */
+
+%include <javascriptcomplex.swg>
+
+%{
+#include <complex> 
+%}
+
+namespace std {
+  %naturalvar complex;
+  template<typename T> class complex;
+  %template() complex<double>;
+  %template() complex<float>;
+}
+
+/* defining the complex as/from converters */
+
+%swig_cplxdbl_convn(std::complex<double>, std::complex<double>, std::real, std::imag)
+%swig_cplxflt_convn(std::complex<float>,  std::complex<float>,  std::real, std::imag)
+
+/* defining the typemaps */
+
+%typemaps_primitive(%checkcode(CPLXDBL), std::complex<double>);
+%typemaps_primitive(%checkcode(CPLXFLT), std::complex<float>);
diff --git a/Lib/javascript/napi/std_deque.i b/Lib/javascript/napi/std_deque.i
new file mode 100644
index 0000000..cb98f6c
--- /dev/null
+++ b/Lib/javascript/napi/std_deque.i
@@ -0,0 +1 @@
+%include <std/_std_deque.i>
diff --git a/Lib/javascript/napi/std_except.i b/Lib/javascript/napi/std_except.i
new file mode 100644
index 0000000..af98428
--- /dev/null
+++ b/Lib/javascript/napi/std_except.i
@@ -0,0 +1 @@
+%include <typemaps/std_except.swg>
diff --git a/Lib/javascript/napi/std_map.i b/Lib/javascript/napi/std_map.i
new file mode 100644
index 0000000..a33e886
--- /dev/null
+++ b/Lib/javascript/napi/std_map.i
@@ -0,0 +1,71 @@
+/* -----------------------------------------------------------------------------
+ * std_map.i
+ *
+ * SWIG typemaps for std::map
+ * ----------------------------------------------------------------------------- */
+
+%include <std_common.i>
+
+// ------------------------------------------------------------------------
+// std::map
+// ------------------------------------------------------------------------
+
+%{
+#include <map>
+#include <algorithm>
+#include <stdexcept>
+%}
+
+// exported class
+
+namespace std {
+
+    template<class K, class T, class C = std::less<K> > class map {
+        // add typemaps here
+      public:
+        typedef size_t size_type;
+        typedef ptrdiff_t difference_type;
+        typedef K key_type;
+        typedef T mapped_type;
+        typedef std::pair< const K, T > value_type;
+        typedef value_type* pointer;
+        typedef const value_type* const_pointer;
+        typedef value_type& reference;
+        typedef const value_type& const_reference;
+
+        map();
+        map(const map& other);
+        
+        unsigned int size() const;
+        bool empty() const;
+        void clear();
+        %extend {
+            const T& get(const K& key) throw (std::out_of_range) {
+                std::map< K, T, C >::iterator i = self->find(key);
+                if (i != self->end())
+                    return i->second;
+                else
+                    throw std::out_of_range("key not found");
+            }
+            void set(const K& key, const T& x) {
+%#ifdef __cpp_lib_map_try_emplace
+                (*self).insert_or_assign(key, x);
+%#else
+                (*self)[key] = x;
+%#endif
+            }
+            void del(const K& key) throw (std::out_of_range) {
+                std::map< K, T, C >::iterator i = self->find(key);
+                if (i != self->end())
+                    self->erase(i);
+                else
+                    throw std::out_of_range("key not found");
+            }
+            bool has_key(const K& key) {
+                std::map< K, T, C >::iterator i = self->find(key);
+                return i != self->end();
+            }
+        }
+    };
+
+}
diff --git a/Lib/javascript/napi/std_pair.i b/Lib/javascript/napi/std_pair.i
new file mode 100644
index 0000000..b72c50b
--- /dev/null
+++ b/Lib/javascript/napi/std_pair.i
@@ -0,0 +1,35 @@
+/* -----------------------------------------------------------------------------
+ * std_pair.i
+ *
+ * SWIG typemaps for std::pair
+ * ----------------------------------------------------------------------------- */
+
+%include <std_common.i>
+
+// ------------------------------------------------------------------------
+// std::pair
+// ------------------------------------------------------------------------
+
+%{
+#include <utility>
+%}
+
+namespace std {
+
+  template<class T, class U> struct pair {
+    typedef T first_type;
+    typedef U second_type;
+
+    pair();
+    pair(T first, U second);
+    pair(const pair& other);
+
+    template <class U1, class U2> pair(const pair<U1, U2> &other);
+
+    T first;
+    U second;
+  };
+
+  // add specializations here
+
+}
diff --git a/Lib/javascript/napi/std_string.i b/Lib/javascript/napi/std_string.i
new file mode 100644
index 0000000..dc1378a
--- /dev/null
+++ b/Lib/javascript/napi/std_string.i
@@ -0,0 +1 @@
+%include <typemaps/std_string.swg>
diff --git a/Lib/javascript/napi/std_unique_ptr.i b/Lib/javascript/napi/std_unique_ptr.i
new file mode 100644
index 0000000..f988714
--- /dev/null
+++ b/Lib/javascript/napi/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+  %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class unique_ptr {};
+}
diff --git a/Lib/javascript/napi/std_vector.i b/Lib/javascript/napi/std_vector.i
new file mode 100644
index 0000000..586ac5c
--- /dev/null
+++ b/Lib/javascript/napi/std_vector.i
@@ -0,0 +1,99 @@
+/* -----------------------------------------------------------------------------
+ * std_vector.i
+ * ----------------------------------------------------------------------------- */
+
+%include <std_common.i>
+
+%{
+#include <vector>
+#include <stdexcept>
+%}
+
+namespace std {
+    
+    template<class T> class vector {
+      public:
+        typedef size_t size_type;
+        typedef ptrdiff_t difference_type;
+        typedef T value_type;
+        typedef value_type* pointer;
+        typedef const value_type* const_pointer;
+        typedef value_type& reference;
+        typedef const value_type& const_reference;
+
+        vector();
+        vector(size_type n);
+        vector(const vector& other);
+
+        size_type size() const;
+        size_type capacity() const;
+        void reserve(size_type n);
+        %rename(isEmpty) empty;
+        bool empty() const;
+        void clear();
+        %rename(add) push_back;
+        void push_back(const value_type& x);
+        %extend {
+            const_reference get(int i) throw (std::out_of_range) {
+                int size = int(self->size());
+                if (i>=0 && i<size)
+                    return (*self)[i];
+                else
+                    throw std::out_of_range("vector index out of range");
+            }
+            void set(int i, const value_type& val) throw (std::out_of_range) {
+                int size = int(self->size());
+                if (i>=0 && i<size)
+                    (*self)[i] = val;
+                else
+                    throw std::out_of_range("vector index out of range");
+            }
+        }
+    };
+
+    // bool specialization
+    template<> class vector<bool> {
+      public:
+        typedef size_t size_type;
+        typedef ptrdiff_t difference_type;
+        typedef bool value_type;
+        typedef value_type* pointer;
+        typedef const value_type* const_pointer;
+        typedef value_type& reference;
+        typedef bool const_reference;
+
+        vector();
+        vector(size_type n);
+        vector(const vector& other);
+
+        size_type size() const;
+        size_type capacity() const;
+        void reserve(size_type n);
+        %rename(isEmpty) empty;
+        bool empty() const;
+        void clear();
+        %rename(add) push_back;
+        void push_back(const value_type& x);
+        %extend {
+            bool get(int i) throw (std::out_of_range) {
+                int size = int(self->size());
+                if (i>=0 && i<size)
+                    return (*self)[i];
+                else
+                    throw std::out_of_range("vector index out of range");
+            }
+            void set(int i, const value_type& val) throw (std::out_of_range) {
+                int size = int(self->size());
+                if (i>=0 && i<size)
+                    (*self)[i] = val;
+                else
+                    throw std::out_of_range("vector index out of range");
+            }
+        }
+    };
+}
+
+%define specialize_std_vector(T)
+#warning "specialize_std_vector - specialization for type T no longer needed"
+%enddef
+
diff --git a/Lib/javascript/napi/stl.i b/Lib/javascript/napi/stl.i
new file mode 100644
index 0000000..04f8601
--- /dev/null
+++ b/Lib/javascript/napi/stl.i
@@ -0,0 +1,10 @@
+/* -----------------------------------------------------------------------------
+ * stl.i
+ * ----------------------------------------------------------------------------- */
+
+%include <std_common.i>
+%include <std_string.i>
+%include <std_vector.i>
+%include <std_map.i>
+%include <std_pair.i>
+
diff --git a/Lib/javascript/napi/swigmove.i b/Lib/javascript/napi/swigmove.i
new file mode 100644
index 0000000..62ecca7
--- /dev/null
+++ b/Lib/javascript/napi/swigmove.i
@@ -0,0 +1 @@
+%include <typemaps/swigmove.swg>
diff --git a/Lib/javascript/napi/typemaps.i b/Lib/javascript/napi/typemaps.i
new file mode 100644
index 0000000..08b5838
--- /dev/null
+++ b/Lib/javascript/napi/typemaps.i
@@ -0,0 +1,144 @@
+/* -----------------------------------------------------------------------------
+ * typemaps.i
+ *
+ * Pointer handling
+ * These mappings provide support for input/output arguments and common
+ * uses for C/C++ pointers.
+ * ----------------------------------------------------------------------------- */
+
+// INPUT typemaps.
+// These remap a C pointer to be an "INPUT" value which is passed by value
+// instead of reference.
+
+/*
+The following methods can be applied to turn a pointer into a simple
+"input" value.  That is, instead of passing a pointer to an object,
+you would use a real value instead.
+
+         int            *INPUT
+         short          *INPUT
+         long           *INPUT
+         long long      *INPUT
+         unsigned int   *INPUT
+         unsigned short *INPUT
+         unsigned long  *INPUT
+         unsigned long long *INPUT
+         unsigned char  *INPUT
+         bool           *INPUT
+         float          *INPUT
+         double         *INPUT
+
+To use these, suppose you had a C function like this :
+
+        double fadd(double *a, double *b) {
+               return *a+*b;
+        }
+
+You could wrap it with SWIG as follows :
+
+        %include <typemaps.i>
+        double fadd(double *INPUT, double *INPUT);
+
+or you can use the %apply directive :
+
+        %include <typemaps.i>
+        %apply double *INPUT { double *a, double *b };
+        double fadd(double *a, double *b);
+
+*/
+
+// OUTPUT typemaps.   These typemaps are used for parameters that
+// are output only.   The output value is appended to the result as
+// a list element.
+
+/*
+The following methods can be applied to turn a pointer into an "output"
+value.  When calling a function, no input value would be given for
+a parameter, but an output value would be returned.  In the case of
+multiple output values, they are returned in the form of a Python tuple.
+
+         int            *OUTPUT
+         short          *OUTPUT
+         long           *OUTPUT
+         long long      *OUTPUT
+         unsigned int   *OUTPUT
+         unsigned short *OUTPUT
+         unsigned long  *OUTPUT
+         unsigned long long *OUTPUT
+         unsigned char  *OUTPUT
+         bool           *OUTPUT
+         float          *OUTPUT
+         double         *OUTPUT
+
+For example, suppose you were trying to wrap the modf() function in the
+C math library which splits x into integral and fractional parts (and
+returns the integer part in one of its parameters) :
+
+        double modf(double x, double *ip);
+
+You could wrap it with SWIG as follows :
+
+        %include <typemaps.i>
+        double modf(double x, double *OUTPUT);
+
+or you can use the %apply directive :
+
+        %include <typemaps.i>
+        %apply double *OUTPUT { double *ip };
+        double modf(double x, double *ip);
+
+The Python output of the function would be a tuple containing both
+output values.
+
+*/
+
+// INOUT
+// Mappings for an argument that is both an input and output
+// parameter
+
+/*
+The following methods can be applied to make a function parameter both
+an input and output value.  This combines the behavior of both the
+"INPUT" and "OUTPUT" methods described earlier.  Output values are
+returned in the form of a Python tuple.
+
+         int            *INOUT
+         short          *INOUT
+         long           *INOUT
+         long long      *INOUT
+         unsigned int   *INOUT
+         unsigned short *INOUT
+         unsigned long  *INOUT
+         unsigned long long *INOUT
+         unsigned char  *INOUT
+         bool           *INOUT
+         float          *INOUT
+         double         *INOUT
+
+For example, suppose you were trying to wrap the following function :
+
+        void neg(double *x) {
+             *x = -(*x);
+        }
+
+You could wrap it with SWIG as follows :
+
+        %include <typemaps.i>
+        void neg(double *INOUT);
+
+or you can use the %apply directive :
+
+        %include <typemaps.i>
+        %apply double *INOUT { double *x };
+        void neg(double *x);
+
+Unlike C, this mapping does not directly modify the input value (since
+this makes no sense in Python).  Rather, the modified input value shows
+up as the return value of the function.  Thus, to apply this function
+to a Python variable you might do this :
+
+       x = neg(x)
+
+*/
+
+%include <typemaps/typemaps.swg>
diff --git a/Lib/javascript/v8/argcargv.i b/Lib/javascript/v8/argcargv.i
new file mode 100644
index 0000000..b1396a4
--- /dev/null
+++ b/Lib/javascript/v8/argcargv.i
@@ -0,0 +1,75 @@
+/* ------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------ */
+
+%{
+#ifndef SWIGV8_VALUE_TO_ARRAY
+# define SWIGV8_VALUE_TO_ARRAY(val) SWIGV8_ARRAY::Cast(val)
+#endif
+#ifndef SWIGV8_STRING
+# define SWIGV8_STRING v8::Local<v8::String>
+#endif
+
+SWIGINTERN int SWIG_AsVal_string (SWIGV8_VALUE valRef, SWIGV8_STRING *str)
+{
+  if (!valRef->IsString()) {
+    return SWIG_TypeError;
+  }
+  if(str != SWIG_NULLPTR) {
+      *str = SWIGV8_TO_STRING(valRef);
+  }
+  return SWIG_OK;
+}
+%}
+
+%typemap(in) (int ARGC, char **ARGV) {
+  $1_ltype i, len;
+  size_t arraysize;
+  SWIGV8_ARRAY array;
+  if (!$input->IsArray()) {
+    SWIG_exception_fail(SWIG_ERROR, "not array");
+  }
+  array = SWIGV8_VALUE_TO_ARRAY($input);
+  len = array->Length();
+  arraysize = (len+1)*sizeof($*2_ltype);
+  $1 = len;
+  $2 = ($2_ltype) malloc(arraysize);
+  if ($2 == SWIG_NULLPTR) {
+    SWIG_exception_fail(SWIG_ERROR, "memory allocation of array failed");
+  }
+  memset($2, 0, arraysize);
+  for (i = 0; i < len; i++) {
+    int res, slen;
+    $*2_ltype pstr;
+    SWIGV8_STRING str;
+    SWIGV8_VALUE jsvalue = SWIGV8_ARRAY_GET(array, i);
+    res = SWIG_AsVal_string(jsvalue, &str);
+    if (!SWIG_IsOK(res)) {
+      SWIG_exception_fail(SWIG_ERROR, "failed to convert to string");
+    }
+    slen = SWIGV8_UTF8_LENGTH(str);
+    pstr = ($*2_ltype) malloc(slen + 1);
+    if (pstr == SWIG_NULLPTR) {
+      SWIG_exception_fail(SWIG_ERROR, "memory allocation of a string failed");
+    }
+    if (slen) {
+      res = SWIGV8_WRITE_UTF8(str, pstr, slen);
+      if (res != slen) {
+        SWIG_exception_fail(SWIG_ERROR, "wrong string length");
+      }
+    }
+    pstr[slen] = 0;
+    $2[i] = pstr;
+  }
+  $2[i] = SWIG_NULLPTR;
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+  if ($2 != SWIG_NULLPTR) {
+    $1_ltype i;
+    for (i = 0; i < $1; i++) {
+      free((void *)$2[i]);
+    }
+    free((void *)$2);
+  }
+}
diff --git a/Lib/javascript/v8/arrays_javascript.i b/Lib/javascript/v8/arrays_javascript.i
index 22b50be..6dc7e4b 100644
--- a/Lib/javascript/v8/arrays_javascript.i
+++ b/Lib/javascript/v8/arrays_javascript.i
@@ -21,105 +21,66 @@
  *   fs = example.FiddleSticks;
  * ----------------------------------------------------------------------------- */
 
-%fragment("SWIG_JSCGetIntProperty",    "header", fragment=SWIG_AsVal_frag(int)) {}
+
+%fragment("SWIG_JSCGetIntProperty", "header", fragment=SWIG_AsVal_frag(int)) {}
 %fragment("SWIG_JSCGetNumberProperty", "header", fragment=SWIG_AsVal_frag(double)) {}
+%fragment("SWIG_JSCOutInt", "header", fragment=SWIG_From_frag(int)) {}
+%fragment("SWIG_JSCOutNumber", "header", fragment=SWIG_From_frag(double)) {}
 
-%typemap(in, fragment="SWIG_JSCGetIntProperty") int[], int[ANY]
-    (int length = 0, v8::Local<v8::Array> array, v8::Local<v8::Value> jsvalue, int i = 0, int res = 0, $*1_ltype temp) {
-  if ($input->IsArray())
-  {
+%define JAVASCRIPT_ARRAYS_IN_DECL(NAME, CTYPE, ANY, ANYLENGTH)
+
+%typemap(in, fragment=NAME) CTYPE[ANY] {
+  if ($input->IsArray()) {
     // Convert into Array
-    array = v8::Local<v8::Array>::Cast($input);
+    v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast($input);
 
-    length = $1_dim0;
+    int length = ANYLENGTH;
 
-    $1  = ($*1_ltype *)malloc(sizeof($*1_ltype) * length);
+    $1 = ($*1_ltype *)malloc(sizeof($*1_ltype) * length);
 
     // Get each element from array
-    for (i = 0; i < length; i++)
-    {
-      jsvalue = array->Get(i);
+    for (int i = 0; i < length; i++) {
+      v8::Local<v8::Value> jsvalue = SWIGV8_ARRAY_GET(array, i);
+      $*1_ltype temp;
 
       // Get primitive value from JSObject
-      res = SWIG_AsVal(int)(jsvalue, &temp);
-      if (!SWIG_IsOK(res))
-      {
+      int res = SWIG_AsVal(CTYPE)(jsvalue, &temp);
+      if (!SWIG_IsOK(res)) {
         SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double");
       }
       arg$argnum[i] = temp;
     }
-
-  }
-  else
-  {
-    SWIG_exception_fail(SWIG_ERROR, "$input is not JSObjectRef");
+  } else {
+    SWIG_exception_fail(SWIG_ERROR, "$input is not an array");
   }
 }
 
-%typemap(freearg) int[], int[ANY] {
-    free($1);
+%typemap(freearg) CTYPE[ANY] {
+  free($1);
 }
 
-%typemap(out, fragment=SWIG_From_frag(int)) int[], int[ANY] (int length = 0, int i = 0)
-{
-  length = $1_dim0;
-  v8::Local<v8::Array> array = v8::Array::New(length);
+%enddef
 
-  for (i = 0; i < length; i++)
-  {
-    array->Set(i, SWIG_From(int)($1[i]));
+%define JAVASCRIPT_ARRAYS_OUT_DECL(NAME, CTYPE)
+
+%typemap(out, fragment=NAME) CTYPE[ANY] {
+  int length = $1_dim0;
+  v8::Local<v8::Array> array = SWIGV8_ARRAY_NEW(length);
+
+  for (int i = 0; i < length; i++) {
+    SWIGV8_ARRAY_SET(array, i, SWIG_From(CTYPE)($1[i]));
   }
 
-
   $result = array;
 }
 
-%typemap(in, fragment="SWIG_JSCGetNumberProperty") double[], double[ANY]
-    (int length = 0, v8::Local<v8::Array> array, v8::Local<v8::Value> jsvalue, int i = 0, int res = 0, $*1_ltype temp) {
-  if ($input->IsArray())
-  {
-    // Convert into Array
-    array = v8::Local<v8::Array>::Cast($input);
+%enddef
 
-    length = $1_dim0;
+JAVASCRIPT_ARRAYS_IN_DECL("SWIG_JSCGetIntProperty", int, , array->Length())
+JAVASCRIPT_ARRAYS_IN_DECL("SWIG_JSCGetIntProperty", int, ANY, $1_dim0)
+JAVASCRIPT_ARRAYS_IN_DECL("SWIG_JSCGetNumberProperty", double, , array->Length())
+JAVASCRIPT_ARRAYS_IN_DECL("SWIG_JSCGetNumberProperty", double, ANY, $1_dim0)
 
-    $1  = ($*1_ltype *)malloc(sizeof($*1_ltype) * length);
+JAVASCRIPT_ARRAYS_OUT_DECL("SWIG_JSCOutInt", int)
+JAVASCRIPT_ARRAYS_OUT_DECL("SWIG_JSCOutNumber", double)
 
-    // Get each element from array
-    for (i = 0; i < length; i++)
-    {
-      jsvalue = array->Get(i);
-
-      // Get primitive value from JSObject
-      res = SWIG_AsVal(double)(jsvalue, &temp);
-      if (!SWIG_IsOK(res))
-      {
-        SWIG_exception_fail(SWIG_ERROR, "Failed to convert $input to double");
-      }
-      arg$argnum[i] = temp;
-    }
-
-  }
-  else
-  {
-    SWIG_exception_fail(SWIG_ERROR, "$input is not JSObjectRef");
-  }
-}
-
-%typemap(freearg) double[], double[ANY] {
-    free($1);
-}
-
-%typemap(out, fragment=SWIG_From_frag(double)) double[], double[ANY] (int length = 0, int i = 0)
-{
-  length = $1_dim0;
-  v8::Local<v8::Array> array = v8::Array::New(length);
-
-  for (i = 0; i < length; i++)
-  {
-    array->Set(i, SWIG_From(double)($1[i]));
-  }
-
-
-  $result = array;
-}
diff --git a/Lib/javascript/v8/ccomplex.i b/Lib/javascript/v8/ccomplex.i
index 8eda920..e58dbf7 100644
--- a/Lib/javascript/v8/ccomplex.i
+++ b/Lib/javascript/v8/ccomplex.i
@@ -6,21 +6,22 @@
  * ----------------------------------------------------------------------------- */
 
 
-%include <javscriptcomplex.swg>
+%include <javascriptcomplex.swg>
 
 %{
 #include <complex.h>
 %}
 
+#define complex _Complex
 
 /* C complex constructor */
 #define CCplxConst(r, i) ((r) + I*(i))
 
-%swig_cplxflt_convn(float complex, CCplxConst, creal, cimag);
-%swig_cplxdbl_convn(double complex, CCplxConst, creal, cimag);
-%swig_cplxdbl_convn(complex, CCplxConst, creal, cimag);
+%swig_cplxflt_convn(float _Complex, CCplxConst, creal, cimag);
+%swig_cplxdbl_convn(double _Complex, CCplxConst, creal, cimag);
+%swig_cplxdbl_convn(_Complex, CCplxConst, creal, cimag);
 
 /* declaring the typemaps */
-%typemaps_primitive(SWIG_TYPECHECK_CPLXFLT, float complex);
-%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, double complex);
-%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, complex);
+%typemaps_primitive(SWIG_TYPECHECK_CPLXFLT, float _Complex);
+%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, double _Complex);
+%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, _Complex);
diff --git a/Lib/javascript/v8/cmalloc.i b/Lib/javascript/v8/cmalloc.i
new file mode 100644
index 0000000..248f06b
--- /dev/null
+++ b/Lib/javascript/v8/cmalloc.i
@@ -0,0 +1 @@
+%include <typemaps/cmalloc.swg>
diff --git a/Lib/javascript/v8/factory.i b/Lib/javascript/v8/factory.i
new file mode 100644
index 0000000..46a0a87
--- /dev/null
+++ b/Lib/javascript/v8/factory.i
@@ -0,0 +1 @@
+%include <typemaps/factory.swg>
diff --git a/Lib/javascript/v8/javascriptcode.swg b/Lib/javascript/v8/javascriptcode.swg
index c4aaf3d..7705865 100644
--- a/Lib/javascript/v8/javascriptcode.swg
+++ b/Lib/javascript/v8/javascriptcode.swg
@@ -4,16 +4,18 @@
  *   - $jslocals:         locals part of wrapper
  *   - $jscode:           code part of wrapper
  *   - $jsargcount:       number of arguments
+ *   - $jsargrequired:    required number of arguments
  *   - $jsmangledtype:    mangled type of class
  * ----------------------------------------------------------------------------- */
 
 %fragment("js_ctor", "templates") %{
 static SwigV8ReturnValue $jswrapper(const SwigV8Arguments &args) {
   SWIGV8_HANDLESCOPE();
-  
-  v8::Handle<v8::Object> self = args.Holder();
+
+  SWIGV8_OBJECT self = args.Holder();
   $jslocals
-  if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper.");
+  if(self->InternalFieldCount() < 1) SWIG_exception_fail(SWIG_ERROR, "Illegal call of constructor $jswrapper.");
+  if(args.Length() < $jsargrequired || args.Length() > $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper.");
   $jscode
 
   SWIGV8_SetPrivateData(self, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN);
@@ -53,7 +55,7 @@
   SWIGV8_HANDLESCOPE();
   
   OverloadErrorHandler errorHandler;
-  v8::Handle<v8::Value> self;
+  SWIGV8_VALUE self;
 
   // switch all cases by means of series of if-returns.
   $jsdispatchcases
@@ -72,15 +74,17 @@
  *   - $jslocals:         locals part of wrapper
  *   - $jscode:           code part of wrapper
  *   - $jsargcount:       number of arguments
+ *   - $jsargrequired:    required number of arguments
  *   - $jsmangledtype:    mangled type of class
  * ----------------------------------------------------------------------------- */
 %fragment("js_overloaded_ctor", "templates") %{
 static SwigV8ReturnValue $jswrapper(const SwigV8Arguments &args, V8ErrorHandler &SWIGV8_ErrorHandler) {
   SWIGV8_HANDLESCOPE();
-  
-  v8::Handle<v8::Object> self = args.Holder();
+
+  SWIGV8_OBJECT self = args.Holder();
   $jslocals
-  if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper.");
+  if(self->InternalFieldCount() < 1) SWIG_exception_fail(SWIG_ERROR, "Illegal call of constructor $jswrapper.");
+  if(args.Length() < $jsargrequired || args.Length() > $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper.");
   $jscode
 
   SWIGV8_SetPrivateData(self, result, SWIGTYPE_$jsmangledtype, SWIG_POINTER_OWN);
@@ -95,25 +99,19 @@
 /* -----------------------------------------------------------------------------
  * js_ctor_dispatch_case:  template for a dispatch case for calling an overloaded ctor.
  *   - $jsargcount:       number of arguments of called ctor
+ *   - $jsargrequired:    required number of arguments
  *   - $jswrapper:        wrapper of called ctor
  *
  *  Note: a try-catch-like mechanism is used to switch cases
  * ----------------------------------------------------------------------------- */
 %fragment ("js_ctor_dispatch_case", "templates")
 %{
-  if(args.Length() == $jsargcount) {
+  if(args.Length() >= $jsargrequired && args.Length() <= $jsargcount) {
     errorHandler.err.Clear();
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
-    self = $jswrapper(args, errorHandler);
-    if(errorHandler.err.IsEmpty()) {
-      SWIGV8_ESCAPE(self);
-    }
-#else
     $jswrapper(args, errorHandler);
     if(errorHandler.err.IsEmpty()) {
       return;
     }
-#endif
   }
 %}
 
@@ -125,22 +123,8 @@
 %fragment ("js_dtor", "templates")
 %{
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-static void $jswrapper(v8::Persistent< v8::Value > object, void *parameter) {
-  SWIGV8_Proxy *proxy = static_cast<SWIGV8_Proxy *>(parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-static void $jswrapper(v8::Isolate *isolate, v8::Persistent<v8::Value> object, void *parameter) {
-  SWIGV8_Proxy *proxy = static_cast<SWIGV8_Proxy *>(parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
-static void $jswrapper(v8::Isolate *isolate, v8::Persistent<v8::Object> *object, SWIGV8_Proxy *proxy) {
-#elif (V8_MAJOR_VERSION-0) < 5
-static void $jswrapper(const v8::WeakCallbackData<v8::Object, SWIGV8_Proxy> &data) {
-  v8::Local<v8::Object> object = data.GetValue();
+static void $jswrapper(const v8::WeakCallbackInfo<SWIGV8_Proxy> &data) {
   SWIGV8_Proxy *proxy = data.GetParameter();
-#else
-  static void $jswrapper(const v8::WeakCallbackInfo<SWIGV8_Proxy> &data) {
-  SWIGV8_Proxy *proxy = data.GetParameter();
-#endif
 
   if(proxy->swigCMemOwn && proxy->swigCObject) {
 #ifdef SWIGRUNTIME_DEBUG
@@ -149,20 +133,6 @@
     $jsfree proxy->swigCObject;
   }
   delete proxy;
-
-#if (V8_MAJOR_VERSION-0) < 5
-  object.Clear();
-#endif
-  
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-  object.Dispose();
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-  object.Dispose(isolate);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032100)
-  object->Dispose(isolate);
-#elif (V8_MAJOR_VERSION-0) < 5
-  object->Dispose();
-#endif
 }
 %}
 
@@ -174,40 +144,14 @@
  * ----------------------------------------------------------------------------- */
 %fragment ("js_dtoroverride", "templates")
 %{
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-static void $jswrapper(v8::Persistent<v8::Value> object, void *parameter) {
-  SWIGV8_Proxy *proxy = static_cast<SWIGV8_Proxy *>(parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-static void $jswrapper(v8::Isolate *isolate, v8::Persistent<v8::Value> object, void *parameter) {
-  SWIGV8_Proxy *proxy = static_cast<SWIGV8_Proxy *>(parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
-static void $jswrapper(v8::Isolate *isolate, v8::Persistent< v8::Object> *object, SWIGV8_Proxy *proxy) {
-#elif (V8_MAJOR_VERSION-0) < 5
-static void $jswrapper(const v8::WeakCallbackData<v8::Object, SWIGV8_Proxy> &data) {
-  v8::Local<v8::Object> object = data.GetValue();
-  SWIGV8_Proxy *proxy = data.GetParameter();
-#else
 static void $jswrapper(const v8::WeakCallbackInfo<SWIGV8_Proxy> &data) {
   SWIGV8_Proxy *proxy = data.GetParameter();
-#endif
 
   if(proxy->swigCMemOwn && proxy->swigCObject) {
     $jstype arg1 = ($jstype)proxy->swigCObject;
     ${destructor_action}
   }
   delete proxy;
-
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-  object.Dispose();
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-  object.Dispose(isolate);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032100)
-  object->Dispose(isolate);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
-  object->Dispose();
-#elif (V8_MAJOR_VERSION-0) < 5
-  object.Clear();
-#endif
 }
 %}
 
@@ -219,14 +163,10 @@
  * ----------------------------------------------------------------------------- */
 %fragment("js_getter", "templates")
 %{
-#if (V8_MAJOR_VERSION-0) < 5
-static SwigV8ReturnValue $jswrapper(v8::Local<v8::String> property, const SwigV8PropertyCallbackInfo &info) {
-#else
 static SwigV8ReturnValue $jswrapper(v8::Local<v8::Name> property, const SwigV8PropertyCallbackInfo &info) {
-#endif
   SWIGV8_HANDLESCOPE();
   
-  v8::Handle<v8::Value> jsresult;
+  SWIGV8_VALUE jsresult;
   $jslocals
   $jscode
   SWIGV8_RETURN_INFO(jsresult, info);
@@ -245,11 +185,7 @@
  * ----------------------------------------------------------------------------- */
 %fragment("js_setter", "templates")
 %{
-#if (V8_MAJOR_VERSION-0) < 5
-static void $jswrapper(v8::Local<v8::String> property, v8::Local<v8::Value> value, const SwigV8PropertyCallbackInfoVoid &info) {
-#else
 static void $jswrapper(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const SwigV8PropertyCallbackInfoVoid &info) {
-#endif
   SWIGV8_HANDLESCOPE();
   
   $jslocals
@@ -262,18 +198,20 @@
 
 /* -----------------------------------------------------------------------------
  * js_function:  template for function wrappers
- *   - $jswrapper:  wrapper function name
- *   - $jslocals:   locals part of wrapper
- *   - $jscode:     code part of wrapper
+ *   - $jswrapper:        wrapper function name
+ *   - $jslocals:         locals part of wrapper
+ *   - $jscode:           code part of wrapper
+ *   - $jsargcount:       number of arguments
+ *   - $jsargrequired:    required number of arguments
  * ----------------------------------------------------------------------------- */
 %fragment("js_function", "templates")
 %{
 static SwigV8ReturnValue $jswrapper(const SwigV8Arguments &args) {
   SWIGV8_HANDLESCOPE();
   
-  v8::Handle<v8::Value> jsresult;
+  SWIGV8_VALUE jsresult;
   $jslocals
-  if(args.Length() != $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper.");
+  if (args.Length() < $jsargrequired || args.Length() > $jsargcount) SWIG_exception_fail(SWIG_ERROR, "Illegal number of arguments for $jswrapper.");
 
   $jscode
   SWIGV8_RETURN(jsresult);
@@ -296,7 +234,7 @@
 static SwigV8ReturnValue $jswrapper(const SwigV8Arguments &args) {
   SWIGV8_HANDLESCOPE();
   
-  v8::Handle<v8::Value> jsresult;
+  SWIGV8_VALUE jsresult;
   OverloadErrorHandler errorHandler;
   $jscode
 
@@ -320,7 +258,7 @@
 {
   SWIGV8_HANDLESCOPE();
   
-  v8::Handle<v8::Value> jsresult;
+  SWIGV8_VALUE jsresult;
   $jslocals
   $jscode
   SWIGV8_RETURN(jsresult);
@@ -333,30 +271,31 @@
 
 /* -----------------------------------------------------------------------------
  * js_function_dispatch_case:  template for a case used in the function dispatcher
- *   - $jswrapper:  wrapper function name
- *   - $jsargcount: number of arguments of overloaded function
- *   - $jscode:     code part of wrapper
+ *   - $jswrapper:     wrapper function name
+ *   - $jsargcount:    number of arguments of overloaded function
+ *   - $jsargrequired: required number of arguments
+ *   - $jscode:        code part of wrapper
  * ----------------------------------------------------------------------------- */
 %fragment ("js_function_dispatch_case", "templates")
 %{
 
-  if(args.Length() == $jsargcount) {
+  if(args.Length() >= $jsargrequired && args.Length() <= $jsargcount) {
     errorHandler.err.Clear();
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
-    jsresult = $jswrapper(args, errorHandler);
-    if(errorHandler.err.IsEmpty()) {
-      SWIGV8_ESCAPE(jsresult);
-    }
-#else
     $jswrapper(args, errorHandler);
     if(errorHandler.err.IsEmpty()) {
       return;
     }
-#endif
   }
 %}
 
 /* -----------------------------------------------------------------------------
+ * js_check_arg:  template for checking if an argument exists
+ *   - $jsarg: number of argument
+ * ----------------------------------------------------------------------------- */
+%fragment ("js_check_arg", "templates")
+%{if(args.Length() > $jsarg)%}
+
+/* -----------------------------------------------------------------------------
  * jsv8_declare_class_template:  template for a class template declaration.
  *   - $jsmangledname:  mangled class name
  * ----------------------------------------------------------------------------- */
@@ -374,7 +313,7 @@
 %fragment("jsv8_define_class_template", "templates")
 %{
   /* Name: $jsmangledname, Type: $jsmangledtype, Dtor: $jsdtor */
-  v8::Handle<v8::FunctionTemplate> $jsmangledname_class = SWIGV8_CreateClassTemplate("$jsmangledname");
+  SWIGV8_FUNCTION_TEMPLATE $jsmangledname_class = SWIGV8_CreateClassTemplate("$jsmangledname");
   SWIGV8_SET_CLASS_TEMPL($jsmangledname_clientData.class_templ, $jsmangledname_class);
   $jsmangledname_clientData.dtor = $jsdtor;
   if (SWIGTYPE_$jsmangledtype->clientdata == 0) {
@@ -392,15 +331,11 @@
 %{
   if (SWIGTYPE_p$jsbaseclass->clientdata && !(static_cast<SWIGV8_ClientData *>(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ.IsEmpty()))
   {
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
-    $jsmangledname_class->Inherit(static_cast<SWIGV8_ClientData *>(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ);
-#else
     $jsmangledname_class->Inherit(
       v8::Local<v8::FunctionTemplate>::New(
         v8::Isolate::GetCurrent(),
         static_cast<SWIGV8_ClientData *>(SWIGTYPE_p$jsbaseclass->clientdata)->class_templ)
      );
-#endif
 
 #ifdef SWIGRUNTIME_DEBUG
     printf("Inheritance successful $jsmangledname $jsbaseclass\n");
@@ -420,11 +355,15 @@
 %fragment("jsv8_create_class_instance", "templates")
 %{
   /* Class: $jsname ($jsmangledname) */
-  v8::Handle<v8::FunctionTemplate> $jsmangledname_class_0 = SWIGV8_CreateClassTemplate("$jsname");
+  SWIGV8_FUNCTION_TEMPLATE $jsmangledname_class_0 = SWIGV8_CreateClassTemplate("$jsname");
   $jsmangledname_class_0->SetCallHandler($jsctor);
   $jsmangledname_class_0->Inherit($jsmangledname_class);
+#if (SWIG_V8_VERSION < 0x0704)
   $jsmangledname_class_0->SetHiddenPrototype(true);
-  v8::Handle<v8::Object> $jsmangledname_obj = $jsmangledname_class_0->GetFunction();
+  v8::Local<v8::Object> $jsmangledname_obj = $jsmangledname_class_0->GetFunction();
+#else
+  v8::Local<v8::Object> $jsmangledname_obj = $jsmangledname_class_0->GetFunction(context).ToLocalChecked();
+#endif
 %}
 
 /* -----------------------------------------------------------------------------
@@ -435,7 +374,7 @@
  * ----------------------------------------------------------------------------- */
 %fragment("jsv8_register_class", "templates")
 %{
-  $jsparent_obj->Set(SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj);
+  SWIGV8_MAYBE_CHECK($jsparent_obj->Set(context, SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj));
 %}
 
 /* -----------------------------------------------------------------------------
@@ -444,7 +383,7 @@
  * ----------------------------------------------------------------------------- */
 %fragment("jsv8_create_namespace", "templates")
 %{
-  v8::Handle<v8::Object> $jsmangledname_obj = SWIGV8_OBJECT_NEW();
+  SWIGV8_OBJECT $jsmangledname_obj = SWIGV8_OBJECT_NEW();
 %}
 
 /* -----------------------------------------------------------------------------
@@ -455,7 +394,7 @@
  * ----------------------------------------------------------------------------- */
 %fragment("jsv8_register_namespace", "templates")
 %{
-  $jsparent_obj->Set(SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj);
+  SWIGV8_MAYBE_CHECK($jsparent_obj->Set(context, SWIGV8_SYMBOL_NEW("$jsname"), $jsmangledname_obj));
 %}
 
 /* -----------------------------------------------------------------------------
@@ -491,7 +430,7 @@
  * ----------------------------------------------------------------------------- */
 %fragment("jsv8_register_static_function", "templates")
 %{
-  SWIGV8_AddStaticFunction($jsparent_obj, "$jsname", $jswrapper);
+  SWIGV8_AddStaticFunction($jsparent_obj, "$jsname", $jswrapper, context);
 %}
 
 /* -----------------------------------------------------------------------------
@@ -505,5 +444,5 @@
  * ----------------------------------------------------------------------------- */
 %fragment("jsv8_register_static_variable", "templates")
 %{
-  SWIGV8_AddStaticVariable($jsparent_obj, "$jsname", $jsgetter, $jssetter);
+  SWIGV8_AddStaticVariable($jsparent_obj, "$jsname", $jsgetter, $jssetter, context);
 %}
diff --git a/Lib/javascript/v8/javascriptcomplex.swg b/Lib/javascript/v8/javascriptcomplex.swg
index d3b4aaf..7b3c554 100644
--- a/Lib/javascript/v8/javascriptcomplex.swg
+++ b/Lib/javascript/v8/javascriptcomplex.swg
@@ -12,15 +12,15 @@
 %fragment(SWIG_From_frag(Type),"header",
           fragment=SWIG_From_frag(double))
 {
-SWIGINTERNINLINE v8::Handle<v8::Value>
+SWIGINTERNINLINE SWIGV8_VALUE
 SWIG_From_dec(Type)(%ifcplusplus(const Type&, Type) c)
 {
   SWIGV8_HANDLESCOPE_ESC();
 
-  v8::Local<v8::Array> vals = SWIGV8_ARRAY_NEW();
+  v8::Local<v8::Array> vals = SWIGV8_ARRAY_NEW(0);
 
-  vals->Set(0, SWIG_From(double)(Real(c)));
-  vals->Set(1, SWIG_From(double)(Imag(c)));
+  SWIGV8_ARRAY_SET(vals, 0, SWIG_From(double)(Real(c)));
+  SWIGV8_ARRAY_SET(vals, 1, SWIG_From(double)(Imag(c)));
   SWIGV8_ESCAPE(vals);
 }
 }
@@ -32,30 +32,30 @@
 	  fragment=SWIG_AsVal_frag(double))
 {
 SWIGINTERN int
-SWIG_AsVal_dec(Type) (v8::Handle<v8::Value> o, Type* val)
+SWIG_AsVal_dec(Type) (SWIGV8_VALUE o, Type* val)
 {
   SWIGV8_HANDLESCOPE();
   
   if (o->IsArray()) {
-    v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(o);
+    SWIGV8_ARRAY array = SWIGV8_ARRAY::Cast(o);
     
-    if(array->Length() != 2) SWIG_Error(SWIG_TypeError, "Illegal argument for complex: must be array[2].");
+    if (array->Length() != 2) SWIG_Error(SWIG_TypeError, "Illegal argument for complex: must be array[2].");
     double re, im;
     int res;
 
-    res = SWIG_AsVal(double)(array->Get(0), &re);
-    if(!SWIG_IsOK(res)) {
+    res = SWIG_AsVal(double)(SWIGV8_ARRAY_GET(array, 0), &re);
+    if (!SWIG_IsOK(res)) {
       return SWIG_TypeError;
     }
     
-    res = SWIG_AsVal(double)(array->Get(1), &im);
-    if(!SWIG_IsOK(res)) {
+    res = SWIG_AsVal(double)(SWIGV8_ARRAY_GET(array, 1), &im);
+    if (!SWIG_IsOK(res)) {
       return SWIG_TypeError;
     }
     
     if (val) *val = Constructor(re, im);
     return SWIG_OK;
-  } else if(o->IsNumber()){
+  } else if (o->IsNumber()) {
     double d;
     int res = SWIG_AddCast(SWIG_AsVal(double)(o, &d));
     if (SWIG_IsOK(res)) {
@@ -74,24 +74,24 @@
 %fragment(SWIG_AsVal_frag(Type),"header",
           fragment=SWIG_AsVal_frag(float)) {
 SWIGINTERN int
-SWIG_AsVal_dec(Type) (v8::Handle<v8::Value> o, Type* val)
+SWIG_AsVal_dec(Type) (SWIGV8_VALUE o, Type* val)
 {
   SWIGV8_HANDLESCOPE();
 
   if (o->IsArray()) {
-    v8::Handle<v8::Array> array = v8::Handle<v8::Array>::Cast(o);
+    SWIGV8_ARRAY array = SWIGV8_ARRAY::Cast(o);
     
-    if(array->Length() != 2) SWIG_Error(SWIG_TypeError, "Illegal argument for complex: must be array[2].");
+    if (array->Length() != 2) SWIG_Error(SWIG_TypeError, "Illegal argument for complex: must be array[2].");
     double re, im;
     int res;
 
-    res = SWIG_AsVal(double)(array->Get(0), &re);
-    if(!SWIG_IsOK(res)) {
+    res = SWIG_AsVal(double)(SWIGV8_ARRAY_GET(array, 0), &re);
+    if (!SWIG_IsOK(res)) {
       return SWIG_TypeError;
     }
     
-    res = SWIG_AsVal(double)(array->Get(1), &im);
-    if(!SWIG_IsOK(res)) {
+    res = SWIG_AsVal(double)(SWIGV8_ARRAY_GET(array, 1), &im);
+    if (!SWIG_IsOK(res)) {
       return SWIG_TypeError;
     }
     
@@ -102,7 +102,7 @@
     } else {
       return SWIG_OverflowError;
     }    
-  } else if(o->IsNumber()){
+  } else if (o->IsNumber()) {
     float re;
     int res = SWIG_AddCast(SWIG_AsVal(float)(o, &re));
     if (SWIG_IsOK(res)) {
diff --git a/Lib/javascript/v8/javascripthelpers.swg b/Lib/javascript/v8/javascripthelpers.swg
index 80fbd7a..7f70406 100644
--- a/Lib/javascript/v8/javascripthelpers.swg
+++ b/Lib/javascript/v8/javascripthelpers.swg
@@ -1,39 +1,26 @@
 %insert(runtime) %{
 
-// Note: since 3.19 there are new CallBack types, since 03.21.9 the old ones have been removed
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
-typedef v8::InvocationCallback  SwigV8FunctionCallback;
-typedef v8::AccessorGetter      SwigV8AccessorGetterCallback;
-typedef v8::AccessorSetter      SwigV8AccessorSetterCallback;
-typedef v8::AccessorInfo        SwigV8PropertyCallbackInfoVoid;
-#elif (V8_MAJOR_VERSION-0) < 5
-typedef v8::FunctionCallback            SwigV8FunctionCallback;
-typedef v8::AccessorGetterCallback      SwigV8AccessorGetterCallback;
-typedef v8::AccessorSetterCallback      SwigV8AccessorSetterCallback;
-typedef v8::PropertyCallbackInfo<void>  SwigV8PropertyCallbackInfoVoid;
-#else
 typedef v8::FunctionCallback            SwigV8FunctionCallback;
 typedef v8::AccessorNameGetterCallback  SwigV8AccessorGetterCallback;
 typedef v8::AccessorNameSetterCallback  SwigV8AccessorSetterCallback;
 typedef v8::PropertyCallbackInfo<void>  SwigV8PropertyCallbackInfoVoid;
-#endif
 
 /**
  * Creates a class template for a class with specified initialization function.
  */
-SWIGRUNTIME v8::Handle<v8::FunctionTemplate> SWIGV8_CreateClassTemplate(const char* symbol) {
+SWIGRUNTIME SWIGV8_FUNCTION_TEMPLATE SWIGV8_CreateClassTemplate(const char* symbol) {
     SWIGV8_HANDLESCOPE_ESC();
     
     v8::Local<v8::FunctionTemplate> class_templ = SWIGV8_FUNCTEMPLATE_NEW_VOID();
     class_templ->SetClassName(SWIGV8_SYMBOL_NEW(symbol));
 
-    v8::Handle<v8::ObjectTemplate> inst_templ = class_templ->InstanceTemplate();
+    SWIGV8_OBJECT_TEMPLATE inst_templ = class_templ->InstanceTemplate();
     inst_templ->SetInternalFieldCount(1);
 
-    v8::Handle<v8::ObjectTemplate> equals_templ = class_templ->PrototypeTemplate();
+    SWIGV8_OBJECT_TEMPLATE equals_templ = class_templ->PrototypeTemplate();
     equals_templ->Set(SWIGV8_SYMBOL_NEW("equals"), SWIGV8_FUNCTEMPLATE_NEW(_SWIGV8_wrap_equals));
 
-    v8::Handle<v8::ObjectTemplate> cptr_templ = class_templ->PrototypeTemplate();
+    SWIGV8_OBJECT_TEMPLATE cptr_templ = class_templ->PrototypeTemplate();
     cptr_templ->Set(SWIGV8_SYMBOL_NEW("getCPtr"), SWIGV8_FUNCTEMPLATE_NEW(_wrap_getCPtr));
 
     SWIGV8_ESCAPE(class_templ);
@@ -42,64 +29,52 @@
 /**
  * Registers a class method with given name for a given class template.
  */
-SWIGRUNTIME void SWIGV8_AddMemberFunction(v8::Handle<v8::FunctionTemplate> class_templ, const char* symbol,
+SWIGRUNTIME void SWIGV8_AddMemberFunction(SWIGV8_FUNCTION_TEMPLATE class_templ, const char* symbol,
   SwigV8FunctionCallback _func) {
-    v8::Handle<v8::ObjectTemplate> proto_templ = class_templ->PrototypeTemplate();
+    SWIGV8_OBJECT_TEMPLATE proto_templ = class_templ->PrototypeTemplate();
     proto_templ->Set(SWIGV8_SYMBOL_NEW(symbol), SWIGV8_FUNCTEMPLATE_NEW(_func));
 }
 
 /**
  * Registers a class property with given name for a given class template.
  */
-SWIGRUNTIME void SWIGV8_AddMemberVariable(v8::Handle<v8::FunctionTemplate> class_templ, const char* symbol,
+SWIGRUNTIME void SWIGV8_AddMemberVariable(SWIGV8_FUNCTION_TEMPLATE class_templ, const char* symbol,
   SwigV8AccessorGetterCallback getter, SwigV8AccessorSetterCallback setter) {
-  v8::Handle<v8::ObjectTemplate> proto_templ = class_templ->InstanceTemplate();
+  SWIGV8_OBJECT_TEMPLATE proto_templ = class_templ->InstanceTemplate();
   proto_templ->SetAccessor(SWIGV8_SYMBOL_NEW(symbol), getter, setter);
 }
 
 /**
  * Registers a class method with given name for a given object.
  */
-SWIGRUNTIME void SWIGV8_AddStaticFunction(v8::Handle<v8::Object> obj, const char* symbol,
-  const SwigV8FunctionCallback& _func) {
-  obj->Set(SWIGV8_SYMBOL_NEW(symbol), SWIGV8_FUNCTEMPLATE_NEW(_func)->GetFunction());
+SWIGRUNTIME void SWIGV8_AddStaticFunction(SWIGV8_OBJECT obj, const char* symbol,
+  const SwigV8FunctionCallback& _func, v8::Local<v8::Context> context) {
+  SWIGV8_MAYBE_CHECK(obj->Set(context, SWIGV8_SYMBOL_NEW(symbol), SWIGV8_FUNCTEMPLATE_NEW(_func)->GetFunction(context).ToLocalChecked()));
 }
 
 /**
  * Registers a class method with given name for a given object.
  */
-SWIGRUNTIME void SWIGV8_AddStaticVariable(v8::Handle<v8::Object> obj, const char* symbol,
-  SwigV8AccessorGetterCallback getter, SwigV8AccessorSetterCallback setter) {
-#if (V8_MAJOR_VERSION-0) < 5
-  obj->SetAccessor(SWIGV8_SYMBOL_NEW(symbol), getter, setter);
-#else
-  obj->SetAccessor(SWIGV8_CURRENT_CONTEXT(), SWIGV8_SYMBOL_NEW(symbol), getter, setter);
-#endif
+SWIGRUNTIME void SWIGV8_AddStaticVariable(SWIGV8_OBJECT obj, const char* symbol,
+  SwigV8AccessorGetterCallback getter, SwigV8AccessorSetterCallback setter,
+  v8::Local<v8::Context> context) {
+  SWIGV8_MAYBE_CHECK(obj->SetAccessor(context, SWIGV8_SYMBOL_NEW(symbol), getter, setter));
 }
 
-#if (V8_MAJOR_VERSION-0) < 5
-SWIGRUNTIME void JS_veto_set_variable(v8::Local<v8::String> property, v8::Local<v8::Value> value, const SwigV8PropertyCallbackInfoVoid& info)
-#else
 SWIGRUNTIME void JS_veto_set_variable(v8::Local<v8::Name> property, v8::Local<v8::Value> value, const SwigV8PropertyCallbackInfoVoid& info)
-#endif
 {
     char buffer[256];
     char msg[512];
     int res;
 
-#if (V8_MAJOR_VERSION-0) < 5
-    property->WriteUtf8(buffer, 256);
-    res = sprintf(msg, "Tried to write read-only variable: %s.", buffer);
-#else
     v8::Local<v8::String> sproperty;
     if (property->ToString(SWIGV8_CURRENT_CONTEXT()).ToLocal(&sproperty)) {
       SWIGV8_WRITE_UTF8(sproperty, buffer, 256);
-      res = sprintf(msg, "Tried to write read-only variable: %s.", buffer);
+      res = SWIG_snprintf(msg, sizeof(msg), "Tried to write read-only variable: %s.", buffer);
     }
     else {
       res = -1;
     }
-#endif
 
     if(res<0) {
       SWIG_exception(SWIG_ERROR, "Tried to write read-only variable.");
diff --git a/Lib/javascript/v8/javascriptinit.swg b/Lib/javascript/v8/javascriptinit.swg
index 8faf2dd..3bf8c41 100644
--- a/Lib/javascript/v8/javascriptinit.swg
+++ b/Lib/javascript/v8/javascriptinit.swg
@@ -5,29 +5,21 @@
 %insert(init) %{
 
 SWIGRUNTIME void
-SWIG_V8_SetModule(void *, swig_module_info *swig_module) {
-  v8::Local<v8::Object> global_obj = SWIGV8_CURRENT_CONTEXT()->Global();
+SWIG_V8_SetModule(v8::Local<v8::Context> context, swig_module_info *swig_module) {
+  v8::Local<v8::Object> global_obj = context->Global();
   v8::Local<v8::External> mod = SWIGV8_EXTERNAL_NEW(swig_module);
   assert(!mod.IsEmpty());
-#if (V8_MAJOR_VERSION-0) < 5
-  global_obj->SetHiddenValue(SWIGV8_STRING_NEW("swig_module_info_data"), mod);
-#else
   v8::Local<v8::Private> privateKey = v8::Private::ForApi(v8::Isolate::GetCurrent(), SWIGV8_STRING_NEW("swig_module_info_data"));
-  global_obj->SetPrivate(SWIGV8_CURRENT_CONTEXT(), privateKey, mod);
-#endif
+  global_obj->SetPrivate(context, privateKey, mod);
 }
 
 SWIGRUNTIME swig_module_info *
-SWIG_V8_GetModule(void *) {
-  v8::Local<v8::Object> global_obj = SWIGV8_CURRENT_CONTEXT()->Global();
-#if (V8_MAJOR_VERSION-0) < 5
-  v8::Local<v8::Value> moduleinfo = global_obj->GetHiddenValue(SWIGV8_STRING_NEW("swig_module_info_data"));
-#else
+SWIG_V8_GetModule(v8::Local<v8::Context> context) {
+  v8::Local<v8::Object> global_obj = context->Global();
   v8::Local<v8::Private> privateKey = v8::Private::ForApi(v8::Isolate::GetCurrent(), SWIGV8_STRING_NEW("swig_module_info_data"));
   v8::Local<v8::Value> moduleinfo;
-  if (!global_obj->GetPrivate(SWIGV8_CURRENT_CONTEXT(), privateKey).ToLocal(&moduleinfo))
+  if (!global_obj->GetPrivate(context, privateKey).ToLocal(&moduleinfo))
     return 0;
-#endif
 
   if (moduleinfo.IsEmpty() || moduleinfo->IsNull() || moduleinfo->IsUndefined())
   {
@@ -52,6 +44,7 @@
 
 #define SWIG_GetModule(clientdata)                SWIG_V8_GetModule(clientdata)
 #define SWIG_SetModule(clientdata, pointer)       SWIG_V8_SetModule(clientdata, pointer)
+#define SWIG_INIT_CLIENT_DATA_TYPE                v8::Local<v8::Context>
 
 %}
 
@@ -64,20 +57,20 @@
 %}
 
 %insert(init) %{
+#if !defined(NODE_MODULE_VERSION) || (NODE_MODULE_VERSION < 12)
 // Note: 'extern "C"'' disables name mangling which makes it easier to load the symbol manually
-// TODO: is it ok to do that?
-extern "C"
-#if (NODE_MODULE_VERSION < 0x000C)
-void SWIGV8_INIT (v8::Handle<v8::Object> exports)
+extern "C" void SWIGV8_INIT (SWIGV8_OBJECT exports_obj)
+#elif (NODE_MODULE_VERSION < 64)
+void SWIGV8_INIT (SWIGV8_OBJECT exports_obj, SWIGV8_VALUE /*module*/, void*)
 #else
-void SWIGV8_INIT (v8::Handle<v8::Object> exports, v8::Handle<v8::Object> /*module*/)
+void SWIGV8_INIT (SWIGV8_OBJECT exports_obj, SWIGV8_VALUE /*module*/, v8::Local<v8::Context> context, void*)
 #endif
 {
-  SWIG_InitializeModule(static_cast<void *>(&exports));
+#if !defined(NODE_MODULE_VERSION) || NODE_MODULE_VERSION < 64
+  v8::Local<v8::Context> context = SWIGV8_CURRENT_CONTEXT();
+#endif
 
-  SWIGV8_HANDLESCOPE();
-  
-  v8::Handle<v8::Object> exports_obj = exports;
+  SWIG_InitializeModule(context);
 %}
 
 
@@ -124,6 +117,10 @@
 }
 
 #if defined(BUILDING_NODE_EXTENSION)
+#if (NODE_MODULE_VERSION < 64)
 NODE_MODULE($jsname, $jsname_initialize)
+#else
+NODE_MODULE_CONTEXT_AWARE($jsname, $jsname_initialize)
+#endif
 #endif
 %}
diff --git a/Lib/javascript/v8/javascriptkw.swg b/Lib/javascript/v8/javascriptkw.swg
deleted file mode 100644
index c3c1183..0000000
--- a/Lib/javascript/v8/javascriptkw.swg
+++ /dev/null
@@ -1,40 +0,0 @@
-#ifndef JAVASCRIPT_JAVASCRIPTKW_SWG_
-#define JAVASCRIPT_JAVASCRIPTKW_SWG_
-
-/* Warnings for Java keywords */
-#define JAVASCRIPTKW(x) %keywordwarn("'" `x` "' is a javascript keyword, renaming to '_"`x`"'",rename="_%s")  `x`
-
-/* Taken from https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Reserved_Words */
-
-JAVASCRIPTKW(break);
-JAVASCRIPTKW(case);
-JAVASCRIPTKW(catch);
-JAVASCRIPTKW(continue);
-JAVASCRIPTKW(default);
-JAVASCRIPTKW(delete);
-JAVASCRIPTKW(do);
-JAVASCRIPTKW(else);
-JAVASCRIPTKW(finally);
-JAVASCRIPTKW(for);
-JAVASCRIPTKW(function);
-JAVASCRIPTKW(if);
-JAVASCRIPTKW(in);
-JAVASCRIPTKW(instanceof);
-JAVASCRIPTKW(new);
-JAVASCRIPTKW(return);
-JAVASCRIPTKW(switch);
-JAVASCRIPTKW(this);
-JAVASCRIPTKW(throw);
-JAVASCRIPTKW(try);
-JAVASCRIPTKW(typeof);
-JAVASCRIPTKW(var);
-JAVASCRIPTKW(void);
-JAVASCRIPTKW(while);
-JAVASCRIPTKW(with);
-
-/* others bad names if any*/
-// for example %namewarn("321:clone() is a javascript bad method name") *::clone();
-
-#undef JAVASCRIPTKW
-
-#endif //JAVASCRIPT_JAVASCRIPTKW_SWG_
diff --git a/Lib/javascript/v8/javascriptprimtypes.swg b/Lib/javascript/v8/javascriptprimtypes.swg
index f76be98..8ed571d 100644
--- a/Lib/javascript/v8/javascriptprimtypes.swg
+++ b/Lib/javascript/v8/javascriptprimtypes.swg
@@ -6,7 +6,7 @@
 
 %fragment(SWIG_From_frag(bool),"header") {
 SWIGINTERNINLINE
-v8::Handle<v8::Value>
+SWIGV8_VALUE
 SWIG_From_dec(bool)(bool value)
 {
   return SWIGV8_BOOLEAN_NEW(value);
@@ -16,7 +16,7 @@
 %fragment(SWIG_AsVal_frag(bool),"header",
           fragment=SWIG_AsVal_frag(long)) {
 SWIGINTERN
-int SWIG_AsVal_dec(bool)(v8::Handle<v8::Value> obj, bool *val)
+int SWIG_AsVal_dec(bool)(SWIGV8_VALUE obj, bool *val)
 {
   if(!obj->IsBoolean()) {
     return SWIG_ERROR;
@@ -31,7 +31,7 @@
 
 %fragment(SWIG_From_frag(int),"header") {
 SWIGINTERNINLINE
-v8::Handle<v8::Value> SWIG_From_dec(int)(int value)
+SWIGV8_VALUE SWIG_From_dec(int)(int value)
 {
   return SWIGV8_INT32_NEW(value);
 }
@@ -39,7 +39,7 @@
 
 %fragment(SWIG_AsVal_frag(int),"header") {
 SWIGINTERN
-int SWIG_AsVal_dec(int)(v8::Handle<v8::Value> valRef, int* val)
+int SWIG_AsVal_dec(int)(SWIGV8_VALUE valRef, int* val)
 {
   if (!valRef->IsNumber()) {
     return SWIG_TypeError;
@@ -54,7 +54,7 @@
 
 %fragment(SWIG_From_frag(long),"header") {
 SWIGINTERNINLINE
-v8::Handle<v8::Value> SWIG_From_dec(long)(long value)
+SWIGV8_VALUE SWIG_From_dec(long)(long value)
 {
   return SWIGV8_NUMBER_NEW(value);
 }
@@ -63,7 +63,7 @@
 %fragment(SWIG_AsVal_frag(long),"header",
           fragment="SWIG_CanCastAsInteger") {
 SWIGINTERN
-int SWIG_AsVal_dec(long)(v8::Handle<v8::Value> obj, long* val)
+int SWIG_AsVal_dec(long)(SWIGV8_VALUE obj, long* val)
 {
   if (!obj->IsNumber()) {
     return SWIG_TypeError;
@@ -79,17 +79,16 @@
 %fragment(SWIG_From_frag(unsigned long),"header",
           fragment=SWIG_From_frag(long)) {
 SWIGINTERNINLINE
-v8::Handle<v8::Value> SWIG_From_dec(unsigned long)(unsigned long value)
+SWIGV8_VALUE SWIG_From_dec(unsigned long)(unsigned long value)
 {
-  return (value > LONG_MAX) ?
-    SWIGV8_INTEGER_NEW_UNS(value) : SWIGV8_INTEGER_NEW(%numeric_cast(value,long));
+  return value <= UINT32_MAX ? (SWIGV8_VALUE)SWIGV8_INTEGER_NEW_UNS(value) : (SWIGV8_VALUE)SWIGV8_NUMBER_NEW(static_cast<double>(value));
 }
 }
 
 %fragment(SWIG_AsVal_frag(unsigned long),"header",
           fragment="SWIG_CanCastAsInteger") {
 SWIGINTERN
-int SWIG_AsVal_dec(unsigned long)(v8::Handle<v8::Value> obj, unsigned long *val)
+int SWIG_AsVal_dec(unsigned long)(SWIGV8_VALUE obj, unsigned long *val)
 {
   if(!obj->IsNumber()) {
     return SWIG_TypeError;
@@ -115,7 +114,7 @@
     fragment="SWIG_LongLongAvailable") {
 %#ifdef SWIG_LONG_LONG_AVAILABLE
 SWIGINTERNINLINE
-v8::Handle<v8::Value> SWIG_From_dec(long long)(long long value)
+SWIGV8_VALUE SWIG_From_dec(long long)(long long value)
 {
   return SWIGV8_NUMBER_NEW(value);
 }
@@ -128,7 +127,7 @@
     fragment="SWIG_LongLongAvailable") {
 %#ifdef SWIG_LONG_LONG_AVAILABLE
 SWIGINTERN
-int SWIG_AsVal_dec(long long)(v8::Handle<v8::Value> obj, long long* val)
+int SWIG_AsVal_dec(long long)(SWIGV8_VALUE obj, long long* val)
 {
   if (!obj->IsNumber()) {
     return SWIG_TypeError;
@@ -148,10 +147,9 @@
     fragment="SWIG_LongLongAvailable") {
 %#ifdef SWIG_LONG_LONG_AVAILABLE
 SWIGINTERNINLINE
-v8::Handle<v8::Value> SWIG_From_dec(unsigned long long)(unsigned long long value)
+SWIGV8_VALUE SWIG_From_dec(unsigned long long)(unsigned long long value)
 {
-  return (value > LONG_MAX) ?
-    SWIGV8_INTEGER_NEW_UNS(value) : SWIGV8_INTEGER_NEW(%numeric_cast(value,long));
+  return value <= UINT32_MAX ? (SWIGV8_VALUE)SWIGV8_INTEGER_NEW_UNS(value) : (SWIGV8_VALUE)SWIGV8_NUMBER_NEW(static_cast<double>(value));
 }
 %#endif
 }
@@ -162,7 +160,7 @@
     fragment="SWIG_LongLongAvailable") {
 %#ifdef SWIG_LONG_LONG_AVAILABLE
 SWIGINTERN
-int SWIG_AsVal_dec(unsigned long long)(v8::Handle<v8::Value> obj, unsigned long long *val)
+int SWIG_AsVal_dec(unsigned long long)(SWIGV8_VALUE obj, unsigned long long *val)
 {
   if(!obj->IsNumber()) {
     return SWIG_TypeError;
@@ -185,7 +183,7 @@
 
 %fragment(SWIG_From_frag(double),"header") {
 SWIGINTERN
-v8::Handle<v8::Value> SWIG_From_dec(double) (double val)
+SWIGV8_VALUE SWIG_From_dec(double) (double val)
 {
   return SWIGV8_NUMBER_NEW(val);
 }
@@ -193,7 +191,7 @@
 
 %fragment(SWIG_AsVal_frag(double),"header") {
 SWIGINTERN
-int SWIG_AsVal_dec(double)(v8::Handle<v8::Value> obj, double *val)
+int SWIG_AsVal_dec(double)(SWIGV8_VALUE obj, double *val)
 {
   if(!obj->IsNumber()) {
     return SWIG_TypeError;
@@ -203,4 +201,3 @@
   return SWIG_OK;
 }
 }
-
diff --git a/Lib/javascript/v8/javascriptrun.swg b/Lib/javascript/v8/javascriptrun.swg
index 2452f40..4980863 100644
--- a/Lib/javascript/v8/javascriptrun.swg
+++ b/Lib/javascript/v8/javascriptrun.swg
@@ -1,75 +1,44 @@
 /* ---------------------------------------------------------------------------
  * These typedefs and defines are used to deal with v8 API changes
  *
+ * Useful table of versions: https://nodejs.org/en/download/releases/
  * ---------------------------------------------------------------------------*/
 
-// First v8 version that uses "SetWeak" and not "MakeWeak"
-
-#define SWIGV8_SETWEAK_VERSION 0x032224
-
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031803)
-#define SWIGV8_STRING_NEW2(cstr, len) v8::String::New(cstr, len)
-#else
+#if (SWIG_V8_VERSION < 0x0704)
 #define SWIGV8_STRING_NEW2(cstr, len) v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), cstr, v8::String::kNormalString, len)
+#else
+#define SWIGV8_STRING_NEW2(cstr, len) (v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), cstr, v8::NewStringType::kNormal, len)).ToLocalChecked()
 #endif
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
-typedef v8::Handle<v8::Value> SwigV8ReturnValue;
-typedef v8::Arguments SwigV8Arguments;
-typedef v8::AccessorInfo SwigV8PropertyCallbackInfo;
-#define SWIGV8_RETURN(val) return scope.Close(val)
-#define SWIGV8_RETURN_INFO(val, info) return scope.Close(val)
-#else
 typedef void SwigV8ReturnValue;
 typedef v8::FunctionCallbackInfo<v8::Value> SwigV8Arguments;
 typedef v8::PropertyCallbackInfo<v8::Value> SwigV8PropertyCallbackInfo;
 #define SWIGV8_RETURN(val) args.GetReturnValue().Set(val); return
 #define SWIGV8_RETURN_INFO(val, info) info.GetReturnValue().Set(val); return
-#endif
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032117)
-#define SWIGV8_HANDLESCOPE() v8::HandleScope scope
-#define SWIGV8_HANDLESCOPE_ESC() v8::HandleScope scope
-#define SWIGV8_ESCAPE(val) return scope.Close(val)
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032224)
-#define SWIGV8_HANDLESCOPE() v8::HandleScope scope(v8::Isolate::GetCurrent());
-#define SWIGV8_HANDLESCOPE_ESC() v8::HandleScope scope(v8::Isolate::GetCurrent());
-#define SWIGV8_ESCAPE(val) return scope.Close(val)
-#else
 #define SWIGV8_HANDLESCOPE() v8::HandleScope scope(v8::Isolate::GetCurrent());
 #define SWIGV8_HANDLESCOPE_ESC() v8::EscapableHandleScope scope(v8::Isolate::GetCurrent());
 #define SWIGV8_ESCAPE(val) return scope.Escape(val)
-#endif
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032224)
-#define SWIGV8_ADJUST_MEMORY(size) v8::V8::AdjustAmountOfExternalAllocatedMemory(size)
-#define SWIGV8_CURRENT_CONTEXT() v8::Context::GetCurrent()
-#define SWIGV8_THROW_EXCEPTION(err) v8::ThrowException(err)
-#define SWIGV8_STRING_NEW(str) v8::String::New(str)
-#define SWIGV8_SYMBOL_NEW(sym) v8::String::NewSymbol(sym)
-#else
 #define SWIGV8_ADJUST_MEMORY(size) v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(size)
 #define SWIGV8_CURRENT_CONTEXT() v8::Isolate::GetCurrent()->GetCurrentContext()
 #define SWIGV8_THROW_EXCEPTION(err) v8::Isolate::GetCurrent()->ThrowException(err)
-#define SWIGV8_STRING_NEW(str) v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), str)
-#define SWIGV8_SYMBOL_NEW(sym) v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), sym)
+
+#if (SWIG_V8_VERSION < 0x0704)
+#define SWIGV8_STRING_NEW(str) v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), str, v8::String::kNormalString)
+#define SWIGV8_SYMBOL_NEW(sym) v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), sym, v8::String::kNormalString)
+#else
+#define SWIGV8_STRING_NEW(str) (v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), str, v8::NewStringType::kNormal)).ToLocalChecked()
+#define SWIGV8_SYMBOL_NEW(sym) (v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), sym, v8::NewStringType::kNormal)).ToLocalChecked()
 #endif
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032318)
-#define SWIGV8_ARRAY_NEW() v8::Array::New()
-#define SWIGV8_BOOLEAN_NEW(bool) v8::Boolean::New(bool)
-#define SWIGV8_EXTERNAL_NEW(val) v8::External::New(val)
-#define SWIGV8_FUNCTEMPLATE_NEW(func) v8::FunctionTemplate::New(func)
-#define SWIGV8_FUNCTEMPLATE_NEW_VOID() v8::FunctionTemplate::New()
-#define SWIGV8_INT32_NEW(num) v8::Int32::New(num)
-#define SWIGV8_INTEGER_NEW(num) v8::Integer::New(num)
-#define SWIGV8_INTEGER_NEW_UNS(num) v8::Integer::NewFromUnsigned(num)
-#define SWIGV8_NUMBER_NEW(num) v8::Number::New(num)
-#define SWIGV8_OBJECT_NEW() v8::Object::New()
-#define SWIGV8_UNDEFINED() v8::Undefined()
-#define SWIGV8_NULL() v8::Null()
+#if (SWIG_V8_VERSION < 0x0704)
+#define SWIGV8_MAYBE_CHECK(maybe) maybe.FromJust()
 #else
-#define SWIGV8_ARRAY_NEW() v8::Array::New(v8::Isolate::GetCurrent())
+#define SWIGV8_MAYBE_CHECK(maybe) maybe.Check()
+#endif
+
+#define SWIGV8_ARRAY_NEW(size) v8::Array::New(v8::Isolate::GetCurrent(), size)
 #define SWIGV8_BOOLEAN_NEW(bool) v8::Boolean::New(v8::Isolate::GetCurrent(), bool)
 #define SWIGV8_EXTERNAL_NEW(val) v8::External::New(v8::Isolate::GetCurrent(), val)
 #define SWIGV8_FUNCTEMPLATE_NEW(func) v8::FunctionTemplate::New(v8::Isolate::GetCurrent(), func)
@@ -80,26 +49,19 @@
 #define SWIGV8_NUMBER_NEW(num) v8::Number::New(v8::Isolate::GetCurrent(), num)
 #define SWIGV8_OBJECT_NEW() v8::Object::New(v8::Isolate::GetCurrent())
 #define SWIGV8_UNDEFINED() v8::Undefined(v8::Isolate::GetCurrent())
+#define SWIGV8_ARRAY v8::Local<v8::Array>
+#define SWIGV8_FUNCTION_TEMPLATE v8::Local<v8::FunctionTemplate>
+#define SWIGV8_OBJECT v8::Local<v8::Object>
+#define SWIGV8_OBJECT_TEMPLATE v8::Local<v8::ObjectTemplate>
+#define SWIGV8_OBJECT_TEMPLATE_NEW() v8::ObjectTemplate::New(v8::Isolate::GetCurrent())
+#define SWIGV8_VALUE v8::Local<v8::Value>
 #define SWIGV8_NULL() v8::Null(v8::Isolate::GetCurrent())
-#endif
+#define SWIGV8_ARRAY_GET(array, index) (array)->Get(SWIGV8_CURRENT_CONTEXT(), index).ToLocalChecked()
+#define SWIGV8_ARRAY_SET(array, index, value) SWIGV8_MAYBE_CHECK((array)->Set(SWIGV8_CURRENT_CONTEXT(), index, value))
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-#define SWIGV8_SET_CLASS_TEMPL(class_templ, class) class_templ = v8::Persistent<v8::FunctionTemplate>::New(class);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-#define SWIGV8_SET_CLASS_TEMPL(class_templ, class) class_templ = v8::Persistent<v8::FunctionTemplate>::New(v8::Isolate::GetCurrent(), class);
-#else
 #define SWIGV8_SET_CLASS_TEMPL(class_templ, class) class_templ.Reset(v8::Isolate::GetCurrent(), class);
-#endif
 
-#ifdef NODE_VERSION
-#if NODE_VERSION_AT_LEAST(10, 12, 0)
-#define SWIG_NODE_AT_LEAST_1012
-#endif
-#endif
-
-//Necessary to check Node.js version because V8 API changes are backported in Node.js
-#if (defined(NODE_VERSION) && !defined(SWIG_NODE_AT_LEAST_1012)) || \
-    (!defined(NODE_VERSION) && (V8_MAJOR_VERSION-0) < 7)
+#if SWIG_V8_VERSION < 0x0608
 #define SWIGV8_TO_OBJECT(handle) (handle)->ToObject()
 #define SWIGV8_TO_STRING(handle) (handle)->ToString()
 #define SWIGV8_NUMBER_VALUE(handle) (handle)->NumberValue()
@@ -107,14 +69,20 @@
 #define SWIGV8_BOOLEAN_VALUE(handle) (handle)->BooleanValue()
 #define SWIGV8_WRITE_UTF8(handle, buffer, len) (handle)->WriteUtf8(buffer, len)
 #define SWIGV8_UTF8_LENGTH(handle) (handle)->Utf8Length()
+#define SWIGV8_OBJECT_TEMPLATE_INSTACE(tmpl) tmpl->NewInstance();
 #else
 #define SWIGV8_TO_OBJECT(handle) (handle)->ToObject(SWIGV8_CURRENT_CONTEXT()).ToLocalChecked()
 #define SWIGV8_TO_STRING(handle) (handle)->ToString(SWIGV8_CURRENT_CONTEXT()).ToLocalChecked()
 #define SWIGV8_NUMBER_VALUE(handle) (handle)->NumberValue(SWIGV8_CURRENT_CONTEXT()).ToChecked()
 #define SWIGV8_INTEGER_VALUE(handle) (handle)->IntegerValue(SWIGV8_CURRENT_CONTEXT()).ToChecked()
-#define SWIGV8_BOOLEAN_VALUE(handle) (handle)->BooleanValue(SWIGV8_CURRENT_CONTEXT()).ToChecked()
 #define SWIGV8_WRITE_UTF8(handle, buffer, len) (handle)->WriteUtf8(v8::Isolate::GetCurrent(), buffer, len)
 #define SWIGV8_UTF8_LENGTH(handle) (handle)->Utf8Length(v8::Isolate::GetCurrent())
+#define SWIGV8_OBJECT_TEMPLATE_INSTACE(tmpl) tmpl->NewInstance(SWIGV8_CURRENT_CONTEXT()).ToLocalChecked();
+#if (SWIG_V8_VERSION < 0x0704)
+#define SWIGV8_BOOLEAN_VALUE(handle) (handle)->BooleanValue(SWIGV8_CURRENT_CONTEXT()).ToChecked()
+#else
+#define SWIGV8_BOOLEAN_VALUE(handle) (handle)->BooleanValue(v8::Isolate::GetCurrent())
+#endif
 #endif
 
 /* ---------------------------------------------------------------------------
@@ -131,6 +99,11 @@
   SWIGV8_THROW_EXCEPTION(v8::Exception::Error(SWIGV8_STRING_NEW(msg)));
 }
 
+SWIGINTERN void SWIG_V8_Raise(SWIGV8_VALUE obj, const char *msg) {
+  SWIGV8_THROW_EXCEPTION(v8::Exception::Error(SWIGV8_TO_STRING(obj)));
+}
+
+
 /*
   Note: There are two contexts for handling errors.
   A static V8ErrorHandler is used in not overloaded methods.
@@ -163,7 +136,7 @@
         SWIGV8_THROW_EXCEPTION(err);
     }
   }
-  v8::Handle<v8::Value> err;
+  SWIGV8_VALUE err;
 };
 
 /* ---------------------------------------------------------------------------
@@ -182,23 +155,8 @@
   };
 
   ~SWIGV8_Proxy() {
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-    handle.ClearWeak();
-    handle.Dispose();
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032100)
-    handle.ClearWeak(v8::Isolate::GetCurrent());
-    handle.Dispose(v8::Isolate::GetCurrent());
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
-    handle.ClearWeak();
-    handle.Dispose();
-#else    
     handle.ClearWeak();
     handle.Reset();
-#endif
-
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
-    handle.Clear();
-#endif
 
     SWIGV8_ADJUST_MEMORY(-SWIGV8_AVG_OBJ_SIZE);
   }
@@ -213,37 +171,22 @@
 public:
   v8::Persistent<v8::FunctionTemplate> class_templ;
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-  void (*dtor) (v8::Persistent< v8::Value> object, void *parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-  void (*dtor) (v8::Isolate *isolate, v8::Persistent< v8::Value> object, void *parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
-  void (*dtor) (v8::Isolate *isolate, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy);
-#elif (V8_MAJOR_VERSION-0) < 5
-  void (*dtor) (const v8::WeakCallbackData<v8::Object, SWIGV8_Proxy> &data);
-#else
   void (*dtor) (const v8::WeakCallbackInfo<SWIGV8_Proxy> &data);
-#endif
 };
 
 SWIGRUNTIME v8::Persistent<v8::FunctionTemplate> SWIGV8_SWIGTYPE_Proxy_class_templ;
 
-SWIGRUNTIME int SWIG_V8_ConvertInstancePtr(v8::Handle<v8::Object> objRef, void **ptr, swig_type_info *info, int flags) {
+SWIGRUNTIME int SWIG_V8_ConvertInstancePtr(SWIGV8_OBJECT objRef, void **ptr, swig_type_info *info, int flags) {
   SWIGV8_HANDLESCOPE();
 
   if(objRef->InternalFieldCount() < 1) return SWIG_ERROR;
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031511)
-  v8::Handle<v8::Value> cdataRef = objRef->GetInternalField(0);
-  SWIGV8_Proxy *cdata = static_cast<SWIGV8_Proxy *>(v8::External::Unwrap(cdataRef));
-#else
   SWIGV8_Proxy *cdata = static_cast<SWIGV8_Proxy *>(objRef->GetAlignedPointerFromInternalField(0));
-#endif
 
   if(cdata == NULL) {
     return SWIG_ERROR;
   }
-  if(cdata->info != info) {
+  if(info && cdata->info != info) {
     swig_cast_info *tc = SWIG_TypeCheckStruct(cdata->info, info);
     if (!tc && cdata->info->name) {
       tc = SWIG_TypeCheck(cdata->info->name, info);
@@ -252,48 +195,41 @@
     if(!type_valid) {
       return SWIG_TypeError;
     }
+    int newmemory = 0;
+    *ptr = SWIG_TypeCast(tc, cdata->swigCObject, &newmemory);
+    assert(!newmemory); /* newmemory handling not yet implemented */
+  } else {
+    *ptr = cdata->swigCObject;
   }
-  *ptr = cdata->swigCObject;
-  if(flags & SWIG_POINTER_DISOWN) {
-    cdata->swigCMemOwn = false;
+
+  if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !cdata->swigCMemOwn) {
+    return SWIG_ERROR_RELEASE_NOT_OWNED;
+  } else {
+    if (flags & SWIG_POINTER_DISOWN) {
+      cdata->swigCMemOwn = false;
+    }
+    if (flags & SWIG_POINTER_CLEAR) {
+      cdata->swigCObject = 0;
+    }
   }
   return SWIG_OK;
 }
 
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-SWIGRUNTIME void SWIGV8_Proxy_DefaultDtor(v8::Persistent< v8::Value > object, void *parameter) {
-  SWIGV8_Proxy *proxy = static_cast<SWIGV8_Proxy *>(parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-SWIGRUNTIME void SWIGV8_Proxy_DefaultDtor(v8::Isolate *, v8::Persistent< v8::Value > object, void *parameter) {
-  SWIGV8_Proxy *proxy = static_cast<SWIGV8_Proxy *>(parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
-SWIGRUNTIME void SWIGV8_Proxy_DefaultDtor(v8::Isolate *, v8::Persistent< v8::Object > *object, SWIGV8_Proxy *proxy) {
-#elif (V8_MAJOR_VERSION-0) < 5
-SWIGRUNTIME void SWIGV8_Proxy_DefaultDtor(const v8::WeakCallbackData<v8::Object, SWIGV8_Proxy> &data) {
-  SWIGV8_Proxy *proxy = data.GetParameter();
-#else
 SWIGRUNTIME void SWIGV8_Proxy_DefaultDtor(const v8::WeakCallbackInfo<SWIGV8_Proxy> &data) {
   SWIGV8_Proxy *proxy = data.GetParameter();
-#endif
-
   delete proxy;
 }
 
-SWIGRUNTIME int SWIG_V8_GetInstancePtr(v8::Handle<v8::Value> valRef, void **ptr) {
+SWIGRUNTIME int SWIG_V8_GetInstancePtr(SWIGV8_VALUE valRef, void **ptr) {
   if(!valRef->IsObject()) {
     return SWIG_TypeError;
   }
-  v8::Handle<v8::Object> objRef = SWIGV8_TO_OBJECT(valRef);
+  SWIGV8_OBJECT objRef = SWIGV8_OBJECT::Cast(valRef);
 
   if(objRef->InternalFieldCount() < 1) return SWIG_ERROR;
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031511)
-  v8::Handle<v8::Value> cdataRef = objRef->GetInternalField(0);
-  SWIGV8_Proxy *cdata = static_cast<SWIGV8_Proxy *>(v8::External::Unwrap(cdataRef));
-#else
   SWIGV8_Proxy *cdata = static_cast<SWIGV8_Proxy *>(objRef->GetAlignedPointerFromInternalField(0));
-#endif
 
   if(cdata == NULL) {
     return SWIG_ERROR;
@@ -304,70 +240,30 @@
   return SWIG_OK;
 }
 
-SWIGRUNTIME void SWIGV8_SetPrivateData(v8::Handle<v8::Object> obj, void *ptr, swig_type_info *info, int flags) {
+SWIGRUNTIME void SWIGV8_SetPrivateData(SWIGV8_OBJECT obj, void *ptr, swig_type_info *info, int flags) {
   SWIGV8_Proxy *cdata = new SWIGV8_Proxy();
   cdata->swigCObject = ptr;
   cdata->swigCMemOwn = (flags & SWIG_POINTER_OWN) ? 1 : 0;
   cdata->info = info;
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031511)
-  obj->SetPointerInInternalField(0, cdata);
-#else
   obj->SetAlignedPointerInInternalField(0, cdata);
-#endif
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-  cdata->handle = v8::Persistent<v8::Object>::New(obj);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-  cdata->handle = v8::Persistent<v8::Object>::New(v8::Isolate::GetCurrent(), obj);
-#else
   cdata->handle.Reset(v8::Isolate::GetCurrent(), obj);
-#endif
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-  // clientdata must be set for owned data as we need to register the dtor
-  if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) {
-    cdata->handle.MakeWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor);
-  } else {
-    cdata->handle.MakeWeak(cdata, SWIGV8_Proxy_DefaultDtor);
-  }
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031918)
-  if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) {
-    cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor);
-  } else {
-    cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, SWIGV8_Proxy_DefaultDtor);
-  }
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
-  if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) {
-    cdata->handle.MakeWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor);
-  } else {
-    cdata->handle.MakeWeak(cdata, SWIGV8_Proxy_DefaultDtor);
-  }
-#elif (V8_MAJOR_VERSION-0) < 5
-  if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) {
-    cdata->handle.SetWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor);
-  } else {
-    cdata->handle.SetWeak(cdata, SWIGV8_Proxy_DefaultDtor);
-  }
-#else
   if(cdata->swigCMemOwn && (SWIGV8_ClientData*)info->clientdata) {
     cdata->handle.SetWeak(cdata, ((SWIGV8_ClientData*)info->clientdata)->dtor, v8::WeakCallbackType::kParameter);
   } else {
     cdata->handle.SetWeak(cdata, SWIGV8_Proxy_DefaultDtor, v8::WeakCallbackType::kParameter);
   }
-#endif
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
+#if (SWIG_V8_VERSION < 0x0704)
   cdata->handle.MarkIndependent();
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032100)
-  cdata->handle.MarkIndependent(v8::Isolate::GetCurrent());
-#else
-  cdata->handle.MarkIndependent();
+// Looks like future versions do not require that anymore:
+// https://monorail-prod.appspot.com/p/chromium/issues/detail?id=923361#c11
 #endif
-
 }
 
-SWIGRUNTIME int SWIG_V8_ConvertPtr(v8::Handle<v8::Value> valRef, void **ptr, swig_type_info *info, int flags) {
+SWIGRUNTIME int SWIG_V8_ConvertPtr(SWIGV8_VALUE valRef, void **ptr, swig_type_info *info, int flags) {
   SWIGV8_HANDLESCOPE();
   
   /* special case: JavaScript null => C NULL pointer */
@@ -378,31 +274,20 @@
   if(!valRef->IsObject()) {
     return SWIG_TypeError;
   }
-  v8::Handle<v8::Object> objRef = SWIGV8_TO_OBJECT(valRef);
+  SWIGV8_OBJECT objRef = SWIGV8_OBJECT::Cast(valRef);
   return SWIG_V8_ConvertInstancePtr(objRef, ptr, info, flags);
 }
 
-SWIGRUNTIME v8::Handle<v8::Value> SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, int flags) {
+SWIGRUNTIME SWIGV8_VALUE SWIG_V8_NewPointerObj(void *ptr, swig_type_info *info, int flags) {
   SWIGV8_HANDLESCOPE_ESC();
   
-  v8::Handle<v8::FunctionTemplate> class_templ;
+  SWIGV8_FUNCTION_TEMPLATE class_templ;
 
   if (ptr == NULL) {
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
-    SWIGV8_ESCAPE(SWIGV8_NULL());
-#else    
     v8::Local<v8::Primitive> result = SWIGV8_NULL();
     SWIGV8_ESCAPE(result);
-#endif
   }
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
-  if(info->clientdata != 0) {
-    class_templ = ((SWIGV8_ClientData*) info->clientdata)->class_templ;
-  } else {
-    class_templ = SWIGV8_SWIGTYPE_Proxy_class_templ;
-  }
-#else
   v8::Isolate *isolate = v8::Isolate::GetCurrent();
 
   if(info->clientdata != 0) {
@@ -410,10 +295,9 @@
   } else {
     class_templ = v8::Local<v8::FunctionTemplate>::New(isolate, SWIGV8_SWIGTYPE_Proxy_class_templ);
   }
-#endif
 
-//  v8::Handle<v8::Object> result = class_templ->InstanceTemplate()->NewInstance();
-  v8::Local<v8::Object> result = class_templ->InstanceTemplate()->NewInstance();
+  v8::Local<v8::Object> result = class_templ->InstanceTemplate()->NewInstance(SWIGV8_CURRENT_CONTEXT()).ToLocalChecked();
+
   SWIGV8_SetPrivateData(result, ptr, info, flags);
 
   SWIGV8_ESCAPE(result);
@@ -433,7 +317,7 @@
 SWIGRUNTIME SwigV8ReturnValue _SWIGV8_wrap_equals(const SwigV8Arguments &args) {
   SWIGV8_HANDLESCOPE();
   
-  v8::Handle<v8::Value> jsresult;
+  SWIGV8_VALUE jsresult;
   void *arg1 = (void *) 0 ;
   void *arg2 = (void *) 0 ;
   bool result;
@@ -463,7 +347,7 @@
 SWIGRUNTIME SwigV8ReturnValue _wrap_getCPtr(const SwigV8Arguments &args) {
   SWIGV8_HANDLESCOPE();
   
-  v8::Handle<v8::Value> jsresult;
+  SWIGV8_VALUE jsresult;
   void *arg1 = (void *) 0 ;
   long result;
   int res1;
@@ -489,9 +373,14 @@
 
 class SwigV8PackedData {
 public:
-  SwigV8PackedData(void *data, size_t size, swig_type_info *type): data(data), size(size), type(type) {};
+  SwigV8PackedData(void *data, size_t size, swig_type_info *type): data(nullptr), size(size), type(type) {
+    this->data = malloc(size);
+    if (this->data != nullptr)
+      memcpy(this->data, data, size);
+  };
 
   ~SwigV8PackedData() {
+    free(this->data);
   };
 
   void *data;
@@ -502,37 +391,28 @@
 };
 
 SWIGRUNTIMEINLINE
-int SwigV8Packed_Check(v8::Handle<v8::Value> valRef) {
+int SwigV8Packed_Check(SWIGV8_VALUE valRef) {
   SWIGV8_HANDLESCOPE();
   
-  v8::Handle<v8::Object> objRef = SWIGV8_TO_OBJECT(valRef);
+  SWIGV8_OBJECT objRef = SWIGV8_TO_OBJECT(valRef);
   if(objRef->InternalFieldCount() < 1) return false;
-#if (V8_MAJOR_VERSION-0) < 5
-  v8::Handle<v8::Value> flag = objRef->GetHiddenValue(SWIGV8_STRING_NEW("__swig__packed_data__"));
-#else
   v8::Local<v8::Private> privateKey = v8::Private::ForApi(v8::Isolate::GetCurrent(), SWIGV8_STRING_NEW("__swig__packed_data__"));
   v8::Local<v8::Value> flag;
   if (!objRef->GetPrivate(SWIGV8_CURRENT_CONTEXT(), privateKey).ToLocal(&flag))
     return false;
-#endif
   return (flag->IsBoolean() && SWIGV8_BOOLEAN_VALUE(flag));
 }
 
 SWIGRUNTIME
-swig_type_info *SwigV8Packed_UnpackData(v8::Handle<v8::Value> valRef, void *ptr, size_t size) {
+swig_type_info *SwigV8Packed_UnpackData(SWIGV8_VALUE valRef, void *ptr, size_t size) {
   if (SwigV8Packed_Check(valRef)) {
     SWIGV8_HANDLESCOPE();
     
     SwigV8PackedData *sobj;
 
-    v8::Handle<v8::Object> objRef = SWIGV8_TO_OBJECT(valRef);
+    SWIGV8_OBJECT objRef = SWIGV8_TO_OBJECT(valRef);
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031511)
-    v8::Handle<v8::Value> cdataRef = objRef->GetInternalField(0);
-    sobj = static_cast<SwigV8PackedData*>(v8::External::Unwrap(cdataRef));
-#else
     sobj = static_cast<SwigV8PackedData*>(objRef->GetAlignedPointerFromInternalField(0));
-#endif
     if (sobj == NULL || sobj->size != size) return 0;
     memcpy(ptr, sobj->data, size);
     return sobj->type;
@@ -542,7 +422,7 @@
 }
 
 SWIGRUNTIME
-int SWIGV8_ConvertPacked(v8::Handle<v8::Value> valRef, void *ptr, size_t sz, swig_type_info *ty) {
+int SWIGV8_ConvertPacked(SWIGV8_VALUE valRef, void *ptr, size_t sz, swig_type_info *ty) {
   swig_type_info *to = SwigV8Packed_UnpackData(valRef, ptr, sz);
   if (!to) return SWIG_ERROR;
   if (ty) {
@@ -555,92 +435,38 @@
   return SWIG_OK;
 }
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-SWIGRUNTIME void _wrap_SwigV8PackedData_delete(v8::Persistent< v8::Value > object, void *parameter) {
-  SwigV8PackedData *cdata = static_cast<SwigV8PackedData *>(parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-SWIGRUNTIME void _wrap_SwigV8PackedData_delete(v8::Isolate *isolate, v8::Persistent<v8::Value> object, void *parameter) {
-  SwigV8PackedData *cdata = static_cast<SwigV8PackedData *>(parameter);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
-SWIGRUNTIME void _wrap_SwigV8PackedData_delete(v8::Isolate *isolate, v8::Persistent<v8::Object> *object, SwigV8PackedData *cdata) {
-#elif (V8_MAJOR_VERSION-0) < 5
-SWIGRUNTIME void _wrap_SwigV8PackedData_delete(const v8::WeakCallbackData<v8::Object, SwigV8PackedData> &data) {
-  v8::Local<v8::Object> object = data.GetValue();
-  SwigV8PackedData *cdata = data.GetParameter();
-#else
 SWIGRUNTIME void _wrap_SwigV8PackedData_delete(const v8::WeakCallbackInfo<SwigV8PackedData> &data) {
   SwigV8PackedData *cdata = data.GetParameter();
-#endif
-
+  cdata->handle.Reset();
   delete cdata;
-
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-  object.Clear();
-  object.Dispose();
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-  object.Clear();
-  object.Dispose(isolate);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032100)
-  object->Dispose(isolate);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
-  object->Dispose();
-#elif (V8_MAJOR_VERSION-0) < 5
-  object.Clear();
-#endif
 }
 
 SWIGRUNTIME
-v8::Handle<v8::Value> SWIGV8_NewPackedObj(void *data, size_t size, swig_type_info *type) {
+SWIGV8_VALUE SWIGV8_NewPackedObj(void *data, size_t size, swig_type_info *type) {
   SWIGV8_HANDLESCOPE_ESC();
 
   SwigV8PackedData *cdata = new SwigV8PackedData(data, size, type);
-//  v8::Handle<v8::Object> obj = SWIGV8_OBJECT_NEW();
-  v8::Local<v8::Object> obj = SWIGV8_OBJECT_NEW();
+  SWIGV8_OBJECT_TEMPLATE tmpl = SWIGV8_OBJECT_TEMPLATE_NEW();
+  tmpl->SetInternalFieldCount(1);
+  v8::Local<v8::Object> obj = SWIGV8_OBJECT_TEMPLATE_INSTACE(tmpl);
 
-#if (V8_MAJOR_VERSION-0) < 5
-  obj->SetHiddenValue(SWIGV8_STRING_NEW("__swig__packed_data__"), SWIGV8_BOOLEAN_NEW(true));
-#else
   v8::Local<v8::Private> privateKey = v8::Private::ForApi(v8::Isolate::GetCurrent(), SWIGV8_STRING_NEW("__swig__packed_data__"));
   obj->SetPrivate(SWIGV8_CURRENT_CONTEXT(), privateKey, SWIGV8_BOOLEAN_NEW(true));
-#endif
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031511)
-  obj->SetPointerInInternalField(0, cdata);
-#else
   obj->SetAlignedPointerInInternalField(0, cdata);
-#endif
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-  cdata->handle = v8::Persistent<v8::Object>::New(obj);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-  cdata->handle = v8::Persistent<v8::Object>::New(v8::Isolate::GetCurrent(), obj);
-#else
   cdata->handle.Reset(v8::Isolate::GetCurrent(), obj);
-#endif
 
-
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-  cdata->handle.MakeWeak(cdata, _wrap_SwigV8PackedData_delete);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031918)
-  cdata->handle.MakeWeak(v8::Isolate::GetCurrent(), cdata, _wrap_SwigV8PackedData_delete);
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < SWIGV8_SETWEAK_VERSION)
-  cdata->handle.MakeWeak(cdata, _wrap_SwigV8PackedData_delete);
-#elif (V8_MAJOR_VERSION-0) < 5
-  cdata->handle.SetWeak(cdata, _wrap_SwigV8PackedData_delete);
-//  v8::V8::SetWeak(&cdata->handle, cdata, _wrap_SwigV8PackedData_delete);
-#else
   cdata->handle.SetWeak(cdata, _wrap_SwigV8PackedData_delete, v8::WeakCallbackType::kParameter);
-#endif
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
+#if (SWIG_V8_VERSION < 0x0704)
   cdata->handle.MarkIndependent();
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032100)
-  cdata->handle.MarkIndependent(v8::Isolate::GetCurrent());
-#else
-  cdata->handle.MarkIndependent();
+// Looks like future versions do not require that anymore:
+// https://monorail-prod.appspot.com/p/chromium/issues/detail?id=923361#c11
 #endif
 
   SWIGV8_ESCAPE(obj);
+
 }
 
 #define SWIG_ConvertMember(obj, ptr, sz, ty)            SWIGV8_ConvertPacked(obj, ptr, sz, ty)
@@ -654,22 +480,18 @@
 
 SWIGRUNTIME
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
-v8::Handle<v8::Value> SWIGV8_AppendOutput(v8::Handle<v8::Value> result, v8::Handle<v8::Value> obj) {
-#else
-v8::Handle<v8::Value> SWIGV8_AppendOutput(v8::Local<v8::Value> result, v8::Handle<v8::Value> obj) {
-#endif
+SWIGV8_VALUE SWIGV8_AppendOutput(SWIGV8_VALUE result, SWIGV8_VALUE obj) {
   SWIGV8_HANDLESCOPE_ESC();
   
   if (result->IsUndefined()) {
-    result = SWIGV8_ARRAY_NEW();
+    result = SWIGV8_ARRAY_NEW(0);
+  } else if (!result->IsArray()) {
+    SWIGV8_ARRAY tmparr = SWIGV8_ARRAY_NEW(0);
+    SWIGV8_ARRAY_SET(tmparr, 0, result);
+    result = tmparr;
   }
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
-  v8::Handle<v8::Array> arr = v8::Handle<v8::Array>::Cast(result);
-#else  
-  v8::Local<v8::Array> arr = v8::Local<v8::Array>::Cast(result);
-#endif
-  arr->Set(arr->Length(), obj);
 
+  SWIGV8_ARRAY arr = SWIGV8_ARRAY::Cast(result);
+  SWIGV8_ARRAY_SET(arr, arr->Length(), obj);
   SWIGV8_ESCAPE(arr);
 }
diff --git a/Lib/javascript/v8/javascriptruntime.swg b/Lib/javascript/v8/javascriptruntime.swg
index c78e04e..4e93fc4 100644
--- a/Lib/javascript/v8/javascriptruntime.swg
+++ b/Lib/javascript/v8/javascriptruntime.swg
@@ -7,36 +7,8 @@
 // ----------------
 //
 // v8 added version macros V8_MAJOR_VERSION, V8_MINOR_VERSION, V8_BUILD_NUMBER
-// and V8_PATCH_LEVEL in version 4.3.0.  SWIG generated code uses these if
-// they are defined - to support earlier versions you can specify the V8 version
-// in use via the command line when you run SWIG:
-//
-//   swig -c++ -javascript -v8 -DV8_VERSION=0x032530 example.i
-//
-// Or code in the interface file using SWIG_V8_VERSION:
-//
-//   %begin %{#define SWIG_V8_VERSION 0x031110%}
-//
-// This is specified as a hex constant, but the constant is read as pairs of
-// decimal digits, so for V8 3.25.30 use constant 0x032530.  This scheme can't
-// represent components > 99, but this constant is only useful for V8 < 4.3.0,
-// and no V8 versions from that era had a component > 99.
-
-%define %swig_v8_define_version(version)
-%insert("runtime") %{
-#ifndef SWIG_V8_VERSION
-#define SWIG_V8_VERSION version
-#endif
-%}
-%enddef
-
-#ifdef V8_VERSION
-%swig_v8_define_version(V8_VERSION)
-#else
-// HACK: defining a default version
-%swig_v8_define_version(0x031110)
-#endif
-
+// and V8_PATCH_LEVEL in version 4.3.0.  SWIG doesn't support anything that
+// old so SWIG generated code can rely on these.
 
 // Node support
 // ------------
@@ -56,9 +28,16 @@
 %insert(runtime) %{
 #include <v8.h>
 
+#undef SWIG_V8_VERSION
+#define SWIG_V8_VERSION ((V8_MAJOR_VERSION / 10) * 4096 + \
+                         (V8_MAJOR_VERSION % 10) * 256 + \
+                         (V8_MINOR_VERSION / 10) * 16 + \
+                         (V8_MINOR_VERSION % 10))
+
 #include <errno.h>
 #include <limits.h>
 #include <stdlib.h>
+#include <assert.h>
 %}
 
 %insert(runtime) "swigrun.swg";         /* SWIG API */
diff --git a/Lib/javascript/v8/javascriptstrings.swg b/Lib/javascript/v8/javascriptstrings.swg
index e767a6d..8dc2d94 100644
--- a/Lib/javascript/v8/javascriptstrings.swg
+++ b/Lib/javascript/v8/javascriptstrings.swg
@@ -4,13 +4,13 @@
  * ------------------------------------------------------------ */
 %fragment("SWIG_AsCharPtrAndSize", "header", fragment="SWIG_pchar_descriptor") {
 SWIGINTERN int
-SWIG_AsCharPtrAndSize(v8::Handle<v8::Value> valRef, char** cptr, size_t* psize, int *alloc)
+SWIG_AsCharPtrAndSize(SWIGV8_VALUE valRef, char** cptr, size_t* psize, int *alloc)
 {
   if(valRef->IsString()) {
-    v8::Handle<v8::String> js_str = SWIGV8_TO_STRING(valRef);
+    v8::Local<v8::String> js_str = v8::Local<v8::String>::Cast(valRef);
 
     size_t len = SWIGV8_UTF8_LENGTH(js_str) + 1;
-    char* cstr = new char[len];
+    char* cstr = (char*) %new_array(len, char);
     SWIGV8_WRITE_UTF8(js_str, cstr, len);
     
     if(alloc) *alloc = SWIG_NEWOBJ;
@@ -20,7 +20,7 @@
     return SWIG_OK;
   } else {
     if(valRef->IsObject()) {
-      v8::Handle<v8::Object> obj = SWIGV8_TO_OBJECT(valRef);
+      SWIGV8_OBJECT obj = SWIGV8_OBJECT::Cast(valRef);
       // try if the object is a wrapped char[]
       swig_type_info* pchar_descriptor = SWIG_pchar_descriptor();
       if (pchar_descriptor) {
@@ -41,7 +41,7 @@
 }
 
 %fragment("SWIG_FromCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") {
-SWIGINTERNINLINE v8::Handle<v8::Value>
+SWIGINTERNINLINE SWIGV8_VALUE
 SWIG_FromCharPtrAndSize(const char* carray, size_t size)
 {
   if (carray) {
@@ -49,7 +49,7 @@
       // TODO: handle extra long strings
       return SWIGV8_UNDEFINED();
     } else {
-      v8::Handle<v8::String> js_str = SWIGV8_STRING_NEW2(carray, size);
+      v8::Local<v8::String> js_str = SWIGV8_STRING_NEW2(carray, size);
       return js_str;
     }
   } else {
diff --git a/Lib/javascript/v8/javascripttypemaps.swg b/Lib/javascript/v8/javascripttypemaps.swg
index 4601698..c4d341b 100644
--- a/Lib/javascript/v8/javascripttypemaps.swg
+++ b/Lib/javascript/v8/javascripttypemaps.swg
@@ -25,7 +25,7 @@
 
 /* Javascript types */
 
-#define SWIG_Object                     v8::Handle<v8::Value>
+#define SWIG_Object                     SWIGV8_VALUE
 #define VOID_Object                     SWIGV8_UNDEFINED()
 
 /* Overload of the output/constant/exception/dirout handling */
@@ -37,7 +37,7 @@
 #define SWIG_SetConstant(name, obj)
 
 /* raise */
-#define SWIG_Raise(obj, type, desc)  SWIG_V8_Raise(type)
+#define SWIG_Raise(obj, type, desc)  SWIG_V8_Raise(obj, type)
 
 /* Include the unified typemap library */
 %include <typemaps/swigtypemaps.swg>
diff --git a/Lib/javascript/v8/std_auto_ptr.i b/Lib/javascript/v8/std_auto_ptr.i
new file mode 100644
index 0000000..3d7ae8b
--- /dev/null
+++ b/Lib/javascript/v8/std_auto_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+  %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class auto_ptr {};
+}
diff --git a/Lib/javascript/v8/std_map.i b/Lib/javascript/v8/std_map.i
index 3b8b093..a33e886 100644
--- a/Lib/javascript/v8/std_map.i
+++ b/Lib/javascript/v8/std_map.i
@@ -48,7 +48,11 @@
                     throw std::out_of_range("key not found");
             }
             void set(const K& key, const T& x) {
+%#ifdef __cpp_lib_map_try_emplace
+                (*self).insert_or_assign(key, x);
+%#else
                 (*self)[key] = x;
+%#endif
             }
             void del(const K& key) throw (std::out_of_range) {
                 std::map< K, T, C >::iterator i = self->find(key);
@@ -64,17 +68,4 @@
         }
     };
 
-// Legacy macros (deprecated)
-%define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_key ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_value ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO)
-#warning "specialize_std_map_on_both ignored - macro is deprecated and no longer necessary"
-%enddef
-
 }
diff --git a/Lib/javascript/v8/std_unique_ptr.i b/Lib/javascript/v8/std_unique_ptr.i
new file mode 100644
index 0000000..f988714
--- /dev/null
+++ b/Lib/javascript/v8/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+  %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class unique_ptr {};
+}
diff --git a/Lib/javascript/v8/swigmove.i b/Lib/javascript/v8/swigmove.i
new file mode 100644
index 0000000..62ecca7
--- /dev/null
+++ b/Lib/javascript/v8/swigmove.i
@@ -0,0 +1 @@
+%include <typemaps/swigmove.swg>
diff --git a/Lib/javascript/v8/typemaps.i b/Lib/javascript/v8/typemaps.i
index d3d8afb..08b5838 100644
--- a/Lib/javascript/v8/typemaps.i
+++ b/Lib/javascript/v8/typemaps.i
@@ -18,7 +18,7 @@
          int            *INPUT
          short          *INPUT
          long           *INPUT
-   long long      *INPUT
+         long long      *INPUT
          unsigned int   *INPUT
          unsigned short *INPUT
          unsigned long  *INPUT
@@ -72,7 +72,7 @@
 
 For example, suppose you were trying to wrap the modf() function in the
 C math library which splits x into integral and fractional parts (and
-returns the integer part in one of its parameters).K:
+returns the integer part in one of its parameters) :
 
         double modf(double x, double *ip);
 
@@ -139,10 +139,6 @@
 
        x = neg(x)
 
-Note : previous versions of SWIG used the symbol 'BOTH' to mark
-input/output arguments.   This is still supported, but will be slowly
-phased out in future releases.
-
 */
 
 %include <typemaps/typemaps.swg>
diff --git a/Lib/javascriptkw.swg b/Lib/javascriptkw.swg
new file mode 100644
index 0000000..81e1340
--- /dev/null
+++ b/Lib/javascriptkw.swg
@@ -0,0 +1,63 @@
+#ifndef JAVASCRIPT_JAVASCRIPTKW_SWG_
+#define JAVASCRIPT_JAVASCRIPTKW_SWG_
+
+/* Warnings for Java keywords */
+#define JAVASCRIPTKW(x) %keywordwarn("'" `x` "' is a javascript keyword, renaming to '_"`x`"'",rename="_%s")  `x`
+
+/* Taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#keywords */
+/* This the union of all currently reserved keywords in ECMAScript 4 to 6 in both sloppy and strict mode */
+
+JAVASCRIPTKW(arguments);
+JAVASCRIPTKW(await);
+JAVASCRIPTKW(break);
+JAVASCRIPTKW(case);
+JAVASCRIPTKW(catch);
+JAVASCRIPTKW(class);
+JAVASCRIPTKW(const);
+JAVASCRIPTKW(continue);
+JAVASCRIPTKW(debugger);
+JAVASCRIPTKW(default);
+JAVASCRIPTKW(delete);
+JAVASCRIPTKW(do);
+JAVASCRIPTKW(else);
+JAVASCRIPTKW(enum);
+JAVASCRIPTKW(eval);
+JAVASCRIPTKW(export);
+JAVASCRIPTKW(extends);
+JAVASCRIPTKW(false);
+JAVASCRIPTKW(finally);
+JAVASCRIPTKW(for);
+JAVASCRIPTKW(function);
+JAVASCRIPTKW(if);
+JAVASCRIPTKW(implements);
+JAVASCRIPTKW(import);
+JAVASCRIPTKW(in);
+JAVASCRIPTKW(instanceof);
+JAVASCRIPTKW(interface);
+JAVASCRIPTKW(let);
+JAVASCRIPTKW(new);
+JAVASCRIPTKW(null);
+JAVASCRIPTKW(package);
+JAVASCRIPTKW(private);
+JAVASCRIPTKW(protected);
+JAVASCRIPTKW(public);
+JAVASCRIPTKW(return);
+JAVASCRIPTKW(static);
+JAVASCRIPTKW(super);
+JAVASCRIPTKW(switch);
+JAVASCRIPTKW(this);
+JAVASCRIPTKW(throw);
+JAVASCRIPTKW(try);
+JAVASCRIPTKW(typeof);
+JAVASCRIPTKW(var);
+JAVASCRIPTKW(void);
+JAVASCRIPTKW(while);
+JAVASCRIPTKW(with);
+JAVASCRIPTKW(yield);
+
+/* others bad names if any*/
+// for example %namewarn("321:clone() is a javascript bad method name") *::clone();
+
+#undef JAVASCRIPTKW
+
+#endif //JAVASCRIPT_JAVASCRIPTKW_SWG_
diff --git a/Lib/lua/argcargv.i b/Lib/lua/argcargv.i
new file mode 100644
index 0000000..605a24f
--- /dev/null
+++ b/Lib/lua/argcargv.i
@@ -0,0 +1,57 @@
+/* -------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+
+   Use it as follows:
+
+     %apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
+     extern int mainApp(size_t argc, const char **argv);
+
+   then from lua:
+
+     args = { "arg0", "arg1" }
+     mainApp(args)
+
+ * ------------------------------------------------------------- */
+
+%{
+SWIGINTERN int SWIG_argv_size(lua_State* L, int index) {
+  int n=0;
+  while(1){
+    lua_rawgeti(L,index,n+1);
+    if (lua_isnil(L,-1))
+      break;
+    ++n;
+    lua_pop(L,1);
+  }
+  lua_pop(L,1);
+  return n;
+}
+%}
+
+%typemap(in) (int ARGC, char **ARGV) {
+  if (lua_istable(L,$input)) {
+    int i, size = SWIG_argv_size(L,$input);
+    $1 = ($1_ltype) size;
+    $2 = (char **) malloc((size+1)*sizeof(char *));
+    for (i = 0; i < size; i++) {
+      lua_rawgeti(L,$input,i+1);
+      if (lua_isnil(L,-1))
+   break;
+      $2[i] = (char *)lua_tostring(L, -1);
+      lua_pop(L,1);
+    }
+    $2[i]=NULL;
+  } else {
+    $1 = 0; $2 = 0;
+    lua_pushstring(L,"Expecting argv array");
+    lua_error(L);
+  }
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+  $1 = lua_istable(L,$input);
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+  free((char *) $2);
+}
diff --git a/Lib/lua/lua.swg b/Lib/lua/lua.swg
index 6db3add..4244435 100644
--- a/Lib/lua/lua.swg
+++ b/Lib/lua/lua.swg
@@ -18,8 +18,9 @@
  *                          constants typemaps
  * ----------------------------------------------------------------------------- */
 // this basically adds to a table of constants
+/* Extra `(`...`)` here are to handle $value being e.g. `SizeOf< int,int >::size`. */
 %typemap(consttab) int, unsigned int, short, unsigned short, long, unsigned long, unsigned char, signed char, bool, enum SWIGTYPE
-       {SWIG_LUA_CONSTTAB_INT("$symname", $value)}
+       {SWIG_LUA_CONSTTAB_INT("$symname", ($value))}
 
 %typemap(consttab) float, double
        {SWIG_LUA_CONSTTAB_FLOAT("$symname", $value)}
@@ -151,7 +152,7 @@
 (mainly because I cannot get the stack trace out of it)
 Therefore I have not bothered to try doing much in this
 
-Therefore currently its just enough to get a few test cases running ok
+Therefore currently it's just enough to get a few test cases running ok
 
 note: if you wish to throw anything related to std::exception
 use %include <std_except.i> instead
@@ -191,7 +192,7 @@
 Throwing object is a serious problem:
 Assuming some code throws a 'FooBar'
 There are a few options:
-- return a pointer to it: but its unclear how long this will last for.
+- return a pointer to it: but it's unclear how long this will last for.
 - return a copy of it: but not all objects are copyable
 	(see exception_partial_info in the test suite for a case where you cannot do this)
 - convert to a string & throw that
@@ -213,7 +214,7 @@
 //	%apply SWIGTYPE EXCEPTION_BY_VAL {FooBar};
 //	%apply SWIGTYPE& EXCEPTION_BY_VAL {FooBar&}; // note: need & twice
 %typemap(throws) SWIGTYPE EXCEPTION_BY_VAL
-%{SWIG_NewPointerObj(L,(void *)new $1_ltype(($1_ltype &) $1),$&1_descriptor,1);
+%{SWIG_NewPointerObj(L,(void *)new $1_ltype($1),$&1_descriptor,1);
 SWIG_fail;%}
 
 // similar for object reference
@@ -224,7 +225,7 @@
 
 
 // note: no support for object pointers
-// its not clear how long the pointer is valid for, therefore not supporting it
+// it's not clear how long the pointer is valid for, therefore not supporting it
 
 /* -----------------------------------------------------------------------------
  *                          extras
diff --git a/Lib/lua/lua_fnptr.i b/Lib/lua/lua_fnptr.i
index 481cfaf..b4c663c 100644
--- a/Lib/lua/lua_fnptr.i
+++ b/Lib/lua/lua_fnptr.i
@@ -17,7 +17,7 @@
 
 The SWIGLUA_FN holds a pointer to the lua_State, and the stack index where the function is held.
 The macro SWIGLUA_FN_GET() will put a copy of the lua function at the top of the stack.
-After that its fairly simple to write the rest of the code (assuming know how to use lua),
+After that it's fairly simple to write the rest of the code (assuming know how to use lua),
 just push the parameters, call the function and return the result.
 
   int my_func(int a, int b, SWIGLUA_FN fn)
@@ -119,6 +119,6 @@
 %{  swiglua_ref_set(&$1,L,$input); %}
 
 %typemap(out) SWIGLUA_REF
-%{  if ($1.L!=0)  {swiglua_ref_get(&$1);} else {lua_pushnil(L);}
+%{  if ($1.L!=0) {swiglua_ref_get(&$1);} else {lua_pushnil(L);}
   SWIG_arg++; %}
 
diff --git a/Lib/lua/luakw.swg b/Lib/lua/luakw.swg
index fc2f92b..394e400 100644
--- a/Lib/lua/luakw.swg
+++ b/Lib/lua/luakw.swg
@@ -2,7 +2,7 @@
   Warnings for Lua keywords, built-in names and bad names.
 */
 
-#define LUAKW(x) %keywordwarn("'" `x` "' is a Lua keyword, renaming to 'c_" `x` "'", rename="c_%s")  `x`
+#define LUAKW(x) %keywordwarn("'" `x` "' is a Lua keyword", rename="c_%s")  `x`
 #define LUABN(x) %namewarn(%warningmsg(SWIGWARN_PARSE_BUILTIN_NAME, "'" `x` "' conflicts with a basic function in Lua"), %$not %$ismember)  `x`
 
 /*
diff --git a/Lib/lua/luarun.swg b/Lib/lua/luarun.swg
index bd764d6..af6cd66 100644
--- a/Lib/lua/luarun.swg
+++ b/Lib/lua/luarun.swg
@@ -149,6 +149,20 @@
 # define lua_rawlen lua_objlen
 #endif
 
+/* lua_tolstring() was added in Lua 5.1.  It should be a little more
+   efficient than making two separate calls and it avoids problems with order
+   of evaluation so SWIG calls lua_tolstring() when it wants the length and
+   we provide a compatibility implementation for Lua 5.0.  */
+#if !defined(LUA_VERSION_NUM) || LUA_VERSION_NUM < 501
+static const char *(lua_tolstring)(lua_State *L, int idx, size_t *len) {
+  /* Call lua_tostring() first as it may convert the value from number to
+     string. */
+  const char *result = lua_tostring(L, idx);
+  if (len) *len = lua_strlen(L, idx);
+  return result;
+}
+#endif
+
 
 /* lua_pushglobaltable is the recommended "future-proof" way to get
    the global table for Lua 5.2 and later.  Here we define
@@ -307,7 +321,7 @@
 
 /* Contract support */
 #define SWIG_contract_assert(expr, msg)  \
-  if (!(expr)) { SWIG_Lua_pusherrstring(L, (char *) msg); goto fail; } else
+  do { if (!(expr)) { SWIG_Lua_pusherrstring(L, (char *) msg); goto fail; } } while (0)
 
 
 /* helper #defines */
@@ -819,6 +833,7 @@
   int bases_search_result;
   int substack_start = lua_gettop(L)-2;
   assert(first_arg == substack_start+1);
+  (void)first_arg;
   lua_checkstack(L,5);
   assert(lua_isuserdata(L,-2));  /* just in case */
   lua_getmetatable(L,-2);    /* get the meta table */
@@ -826,7 +841,7 @@
   /* NEW: looks for the __getitem() fn
   this is a user provided get fn */
   SWIG_Lua_get_table(L,"__getitem"); /* find the __getitem fn */
-  if (lua_iscfunction(L,-1))  /* if its there */
+  if (lua_iscfunction(L,-1))  /* if it's there */
   {  /* found it so call the fn & return its value */
     lua_pushvalue(L,substack_start+1);  /* the userdata */
     lua_pushvalue(L,substack_start+2);  /* the parameter */
@@ -857,6 +872,7 @@
   int bases_search_result;
   int substack_start = lua_gettop(L)-2;
   assert(first_arg == substack_start+1);
+  (void)first_arg;
   lua_checkstack(L,5);
   assert(lua_isuserdata(L,-2));  /* just in case */
   lua_getmetatable(L,-2);    /* get the meta table */
@@ -883,7 +899,7 @@
   lua_pushvalue(L,substack_start+2);  /* key */
   lua_rawget(L,-2);  /* look for the fn */
   lua_remove(L,-2); /* stack tidy, remove .fn table */
-  if (lua_isfunction(L,-1)) /* note: if its a C function or lua function */
+  if (lua_isfunction(L,-1)) /* note: if it's a C function or lua function */
   {  /* found it so return the fn & let lua call it */
     lua_remove(L,-2); /* stack tidy, remove metatable */
     if(ret)
@@ -966,7 +982,7 @@
   /* NEW: looks for the __setitem() fn
   this is a user provided set fn */
   SWIG_Lua_get_table(L,"__setitem"); /* find the fn */
-  if (lua_iscfunction(L,-1))  /* if its there */
+  if (lua_iscfunction(L,-1))  /* if it's there */
   {  /* found it so call the fn & return its value */
     lua_pushvalue(L,substack_start+1);  /* the userdata */
     lua_pushvalue(L,substack_start+2);  /* the parameter */
@@ -1343,15 +1359,15 @@
 SWIGRUNTIME int SWIG_Lua_resolve_metamethod(lua_State *L); /*forward declaration*/
 
 /* The real function that resolves a metamethod.
- * Function searches given class and all it's bases(recursively) for first instance of something that is
- * not equal to SWIG_Lua_resolve_metatmethod. (Almost always this 'something' is actual metamethod implementation
+ * Function searches given class and all its bases (recursively) for first instance of something that is
+ * not equal to SWIG_Lua_resolve_metamethod. (Almost always this 'something' is actual metamethod implementation
  * and it is a SWIG-generated C function.). It returns value on the top of the L and there is no garbage below the
  * answer.
  * Returns 1 if found, 0 otherwise.
  * clss is class which metatable we will search for method
  * metamethod_name_idx is index in L where metamethod name (as string) lies
- * skip_check allows to skip searching metamethod in givel clss and immideatelly go to searching in bases. skip_check
- * is not caried to subsequent recursive calls - false is always passed. It is set to true only at first call from
+ * skip_check allows skipping searching metamethod in the given class and immediately going to searching in bases. skip_check
+ * is not carried to subsequent recursive calls - false is always passed. It is set to true only at first call from
  * SWIG_Lua_resolve_metamethod
  * */
 SWIGINTERN int SWIG_Lua_do_resolve_metamethod(lua_State *L, const swig_lua_class *clss, int metamethod_name_idx,
@@ -1497,7 +1513,7 @@
     }
   }
 
-  lua_pop(L,1); /* remove inheritable metatmethods table */
+  lua_pop(L,1); /* remove inheritable metamethods table */
 
   /* Special handling for __tostring method */
   lua_pushstring(L, "__tostring");
@@ -1757,6 +1773,7 @@
  (if possible) */
 SWIGRUNTIME int  SWIG_Lua_ConvertPtr(lua_State *L,int index,void **ptr,swig_type_info *type,int flags)
 {
+  int ret = SWIG_ERROR;
   swig_lua_userdata *usr;
   swig_cast_info *cast;
   /* special case: lua nil => NULL pointer */
@@ -1765,33 +1782,49 @@
     *ptr=0;
     return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
   }
+  if (lua_islightuserdata(L,index))
+  {
+    *ptr=lua_touserdata(L,index);
+    return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
+  }
   usr=(swig_lua_userdata*)lua_touserdata(L,index);  /* get data */
   if (usr)
   {
+    if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !usr->own)
+    {
+      return SWIG_ERROR_RELEASE_NOT_OWNED;
+    }
     if (flags & SWIG_POINTER_DISOWN) /* must disown the object */
     {
-        usr->own=0;
+      usr->own = 0;
     }
     if (!type)            /* special cast void*, no casting fn */
     {
       *ptr=usr->ptr;
-      return SWIG_OK; /* ok */
+      ret = SWIG_OK;
     }
-    cast=SWIG_TypeCheckStruct(usr->type,type); /* performs normal type checking */
-    if (cast)
+    else
     {
-      int newmemory = 0;
-      *ptr=SWIG_TypeCast(cast,usr->ptr,&newmemory);
-      assert(!newmemory); /* newmemory handling not yet implemented */
-      return SWIG_OK;  /* ok */
+      cast=SWIG_TypeCheck(usr->type->name,type); /* performs normal type checking */
+      if (cast)
+      {
+        int newmemory = 0;
+        *ptr=SWIG_TypeCast(cast,usr->ptr,&newmemory);
+        assert(!newmemory); /* newmemory handling not yet implemented */
+        ret = SWIG_OK;
+      }
+    }
+    if ((ret == SWIG_OK) && (flags & SWIG_POINTER_CLEAR))
+    {
+      usr->ptr = 0;
     }
   }
-  return SWIG_ERROR;  /* error */
+  return ret;
 }
 
 SWIGRUNTIME void* SWIG_Lua_MustGetPtr(lua_State *L,int index,swig_type_info *type,int flags,
        int argnum,const char *func_name){
-  void *result;
+  void *result = 0;
   if (!SWIG_IsOK(SWIG_ConvertPtr(L,index,&result,type,flags))){
     luaL_error (L,"Error in %s, expected a %s at argument number %d\n",
 		func_name,(type && type->str)?type->str:"void*",argnum);
diff --git a/Lib/lua/luatypemaps.swg b/Lib/lua/luatypemaps.swg
index 8959f20..7d23917 100644
--- a/Lib/lua/luatypemaps.swg
+++ b/Lib/lua/luatypemaps.swg
@@ -24,7 +24,7 @@
 // additional check for unsigned numbers, to not permit negative input
 %typemap(in,checkfn="lua_isnumber") unsigned int,
              unsigned short, unsigned long, unsigned char
-%{SWIG_contract_assert((lua_tonumber(L,$input)>=0),"number must not be negative")
+%{SWIG_contract_assert((lua_tonumber(L,$input)>=0),"number must not be negative");
 $1 = ($type)lua_tonumber(L, $input);%}
 
 %typemap(out) int,short,long,
@@ -39,12 +39,12 @@
 // SWIG assumes that this code will need a pointer to int to be passed in
 // (this might be ok for objects by const ref, but not for numeric primitives)
 // therefore we add a set of typemaps to fix this (for both in & out)
-%typemap(in,checkfn="lua_isnumber") const int&($basetype temp)
-%{ temp=($basetype)lua_tonumber(L,$input); $1=&temp;%}
+%typemap(in,checkfn="lua_isnumber") const int&($*1_ltype temp)
+%{ temp=($*1_ltype)lua_tonumber(L,$input); $1=&temp;%}
 
-%typemap(in,checkfn="lua_isnumber") const unsigned int&($basetype temp)
-%{SWIG_contract_assert((lua_tonumber(L,$input)>=0),"number must not be negative")
-temp=($basetype)lua_tonumber(L,$input); $1=&temp;%}
+%typemap(in,checkfn="lua_isnumber") const unsigned int&($*1_ltype temp)
+%{SWIG_contract_assert((lua_tonumber(L,$input)>=0),"number must not be negative");
+temp=($*1_ltype)lua_tonumber(L,$input); $1=&temp;%}
 
 %typemap(out) const int&, const unsigned int&
 %{  lua_pushnumber(L, (lua_Number) *$1); SWIG_arg++;%}
@@ -151,11 +151,17 @@
   }
 %}
 
-%typemap(in,checkfn="lua_isuserdata") SWIGTYPE&&
-%{
-  if (!SWIG_IsOK(SWIG_ConvertPtr(L,$input,(void**)&$1,$descriptor,$disown))){
-    SWIG_fail_ptr("$symname",$argnum,$descriptor);
+%typemap(in,checkfn="lua_isuserdata",fragment="<memory>") SWIGTYPE&& (void *argp = 0, int res = 0, std::unique_ptr<$*1_ltype> rvrdeleter) %{
+  res = SWIG_ConvertPtr(L, $input, &argp, $descriptor, SWIG_POINTER_RELEASE);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      lua_pushfstring(L, "Cannot release ownership as memory is not owned for argument $argnum of type '$1_type' in $symname"); SWIG_fail;
+    } else {
+      SWIG_fail_ptr("$symname", $argnum, $descriptor);
+    }
   }
+  $1 = ($1_ltype)argp;
+  rvrdeleter.reset($1);
 %}
 
 // out is simple
@@ -217,7 +223,7 @@
 #ifdef __cplusplus
 %typemap(out) SWIGTYPE
 {
-  $&1_ltype resultptr = new $1_ltype((const $1_ltype &) $1);
+  $&1_ltype resultptr = new $1_ltype($1);
   SWIG_NewPointerObj(L,(void *) resultptr,$&1_descriptor,1); SWIG_arg++;
 }
 #else
@@ -237,22 +243,22 @@
 // therefore a special wrapping functions SWIG_ConvertMember() & SWIG_NewMemberObj() were written
 %typemap(in,checkfn="lua_isuserdata") SWIGTYPE (CLASS::*)
 %{
-  if (!SWIG_IsOK(SWIG_ConvertMember(L,$input,(void*)(&$1),sizeof($type),$descriptor)))
+  if (!SWIG_IsOK(SWIG_ConvertMember(L,$input,(void*)(&$1),sizeof($1),$descriptor)))
     SWIG_fail_ptr("$symname",$argnum,$descriptor);
 %}
 
 %typemap(out) SWIGTYPE (CLASS::*)
-%{ 
-  SWIG_NewMemberObj(L,(void*)(&$1),sizeof($type),$descriptor); SWIG_arg++; 
+%{
+  SWIG_NewMemberObj(L,(void*)(&$1),sizeof($1),$descriptor); SWIG_arg++;
 %}
 
 
 // void (must be empty without the SWIG_arg++)
-%typemap(out) void "";
+%typemap(out) void ""
 
 /* void* is a special case
 A function void fn(void*) should take any kind of pointer as a parameter (just like C/C++ does)
-but if its an output, then it should be wrapped like any other SWIG object (using default typemap)
+but if it's an output, then it should be wrapped like any other SWIG object (using default typemap)
 */
 %typemap(in,checkfn="SWIG_isptrtype") void*
 %{$1=($1_ltype)SWIG_MustGetPtr(L,$input,0,0,$argnum,"$symname");%}
@@ -285,7 +291,7 @@
 
 // unfortunately lua only considers one type of number
 // so all numbers (int,float,double) match
-// you could add an advanced fn to get type & check if its integral
+// you could add an advanced fn to get type & check if it's integral
 %typecheck(SWIG_TYPECHECK_INTEGER)
 	 int, short, long,
  	 unsigned int, unsigned short, unsigned long,
@@ -396,7 +402,7 @@
  *                          Specials
  * ----------------------------------------------------------------------------- */
 // swig::LANGUAGE_OBJ was added to allow containers of native objects
-// however its rather difficult to do this in lua, as you cannot hold pointers
+// however it's rather difficult to do this in lua, as you cannot hold pointers
 // to native objects (they are held in the interpreter)
 // therefore for now: just ignoring this feature
 #ifdef __cplusplus
diff --git a/Lib/lua/std_auto_ptr.i b/Lib/lua/std_auto_ptr.i
new file mode 100644
index 0000000..b3b71d0
--- /dev/null
+++ b/Lib/lua/std_auto_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, checkfn="SWIG_isptrtype", noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr(L, $input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      lua_pushfstring(L, "Cannot release ownership as memory is not owned for argument $argnum of type 'TYPE *' in $symname"); SWIG_fail;
+    } else {
+      SWIG_fail_ptr("$symname", $argnum, $descriptor(TYPE *));
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+  SWIG_NewPointerObj(L, $1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN); SWIG_arg++;
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr(L, $input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class auto_ptr {};
+}
diff --git a/Lib/lua/std_map.i b/Lib/lua/std_map.i
index 773b6d0..19281ad 100644
--- a/Lib/lua/std_map.i
+++ b/Lib/lua/std_map.i
@@ -48,7 +48,11 @@
                     throw std::out_of_range("key not found");
             }
             void set(const K& key, const T& x) {
+%#ifdef __cpp_lib_map_try_emplace
+                (*self).insert_or_assign(key, x);
+%#else
                 (*self)[key] = x;
+%#endif
             }
             void del(const K& key) throw (std::out_of_range) {
                 std::map< K, T, C >::iterator i = self->find(key);
diff --git a/Lib/lua/std_string.i b/Lib/lua/std_string.i
index b95a8a4..795db71 100644
--- a/Lib/lua/std_string.i
+++ b/Lib/lua/std_string.i
@@ -43,19 +43,28 @@
 Similarly for getting the string
   $1 = (char*)lua_tostring(L, $input);
 becomes
-  $1.assign(lua_tostring(L,$input),lua_rawlen(L,$input));
-  
-Not using: lua_tolstring() as this is only found in Lua 5.1 & not 5.0.2
+  size_t len;
+  const char *ptr = lua_tolstring(L, $input, &len);
+  $1.assign(ptr, len);
 */
 
 %typemap(in,checkfn="lua_isstring") string
-%{$1.assign(lua_tostring(L,$input),lua_rawlen(L,$input));%}
+{
+  size_t len;
+  const char *ptr = lua_tolstring(L, $input, &len);
+  $1.assign(ptr, len);
+}
 
 %typemap(out) string
 %{ lua_pushlstring(L,$1.data(),$1.size()); SWIG_arg++;%}
 
 %typemap(in,checkfn="lua_isstring") const string& ($*1_ltype temp)
-%{temp.assign(lua_tostring(L,$input),lua_rawlen(L,$input)); $1=&temp;%}
+{
+  size_t len;
+  const char *ptr = lua_tolstring(L, $input, &len);
+  temp.assign(ptr, len);
+  $1=&temp;
+}
 
 %typemap(out) const string&
 %{ lua_pushlstring(L,$1->data(),$1->size()); SWIG_arg++;%}
diff --git a/Lib/lua/std_string_view.i b/Lib/lua/std_string_view.i
new file mode 100644
index 0000000..5c8b636
--- /dev/null
+++ b/Lib/lua/std_string_view.i
@@ -0,0 +1,50 @@
+/* -----------------------------------------------------------------------------
+ * std_string_view.i
+ *
+ * std::string_view typemaps for LUA
+ * ----------------------------------------------------------------------------- */
+
+%{
+#include <string_view>
+%}
+
+namespace std {
+
+%naturalvar string_view;
+
+%typemap(in,checkfn="lua_isstring") string_view
+{
+  size_t len;
+  const char *ptr = lua_tolstring(L, $input, &len);
+  $1 = std::string_view(ptr, len);
+}
+
+%typemap(out) string_view
+%{ lua_pushlstring(L,$1.data(),$1.size()); SWIG_arg++;%}
+
+%typemap(in,checkfn="lua_isstring") const string_view& ($*1_ltype temp)
+{
+  size_t len;
+  const char *ptr = lua_tolstring(L, $input, &len);
+  temp = std::string_view(ptr, len);
+  $1=&temp;
+}
+
+%typemap(out) const string_view&
+%{ lua_pushlstring(L,$1->data(),$1->size()); SWIG_arg++;%}
+
+// for throwing of any kind of string_view, string_view ref's and string_view pointers
+// we convert all to lua strings
+%typemap(throws) string_view, string_view&, const string_view&
+%{ lua_pushlstring(L,$1.data(),$1.size()); SWIG_fail;%}
+
+%typemap(throws) string_view*, const string_view*
+%{ lua_pushlstring(L,$1->data(),$1->size()); SWIG_fail;%}
+
+%typecheck(SWIG_TYPECHECK_STRINGVIEW) string_view, const string_view& {
+  $1 = lua_isstring(L,$input);
+}
+
+class string_view;
+
+}
diff --git a/Lib/lua/std_unique_ptr.i b/Lib/lua/std_unique_ptr.i
new file mode 100644
index 0000000..ad08f3b
--- /dev/null
+++ b/Lib/lua/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, checkfn="SWIG_isptrtype", noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr(L, $input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      lua_pushfstring(L, "Cannot release ownership as memory is not owned for argument $argnum of type 'TYPE *' in $symname"); SWIG_fail;
+    } else {
+      SWIG_fail_ptr("$symname", $argnum, $descriptor(TYPE *));
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+  SWIG_NewPointerObj(L, $1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN); SWIG_arg++;
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr(L, $input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class unique_ptr {};
+}
diff --git a/Lib/lua/swigmove.i b/Lib/lua/swigmove.i
new file mode 100644
index 0000000..d130e79
--- /dev/null
+++ b/Lib/lua/swigmove.i
@@ -0,0 +1,18 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in, checkfn="lua_isuserdata", noblock=1) SWIGTYPE MOVE (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr(L, $input, &argp, $&1_descriptor, SWIG_POINTER_RELEASE);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      lua_pushfstring(L, "Cannot release ownership as memory is not owned for argument $argnum of type '$1_type' in $symname"); SWIG_fail;
+    } else {
+      SWIG_fail_ptr("$symname", $argnum, $&1_descriptor);
+    }
+  }
+  SwigValueWrapper< $1_ltype >::reset($1, ($&1_type)argp);
+}
diff --git a/Lib/lua/typemaps.i b/Lib/lua/typemaps.i
index 8392e5b..68f6f6c 100644
--- a/Lib/lua/typemaps.i
+++ b/Lib/lua/typemaps.i
@@ -28,7 +28,7 @@
 
 However the code below is a mixture of #defines & such, so nowhere as easy to read
 
-To make you code work correctly its not just a matter of %including this file
+To make you code work correctly it's not just a matter of %including this file
 You also have to give SWIG the hints on which to use where
 
 eg
@@ -77,7 +77,7 @@
 // also for long longs's
 SWIG_NUMBER_TYPEMAP(long long); SWIG_NUMBER_TYPEMAP(unsigned long long); SWIG_NUMBER_TYPEMAP(signed long long);
 
-// note we dont do char, as a char* is probably a string not a ptr to a single char
+// note we don't do char, as a char* is probably a string not a ptr to a single char
 
 // similar for booleans
 %typemap(in,checkfn="lua_isboolean") bool *INPUT(bool temp), bool &INPUT(bool temp)
@@ -188,16 +188,6 @@
 
 */
 
-/* Reported that you don't need to check for NULL for delete & free
-There probably is some compiler that its not true for, so the code is left here just in case.
-#ifdef __cplusplus	
-#define SWIG_ALLOC_ARRAY(TYPE,LEN) 	new TYPE[LEN]
-#define SWIG_FREE_ARRAY(PTR)		if(PTR){delete[] PTR;}
-#else
-#define SWIG_ALLOC_ARRAY(TYPE,LEN) 	(TYPE *)malloc(LEN*sizeof(TYPE))
-#define SWIG_FREE_ARRAY(PTR)		if(PTR){free(PTR);}
-#endif
-*/
 %{
 #ifdef __cplusplus	/* generic alloc/dealloc fns*/
 #define SWIG_ALLOC_ARRAY(TYPE,LEN) 	new TYPE[LEN]
diff --git a/Lib/math.i b/Lib/math.i
index a37c92d..ac8d9a6 100644
--- a/Lib/math.i
+++ b/Lib/math.i
@@ -9,6 +9,8 @@
 #include <math.h>
 %}
 
+#ifndef SWIGPHP /* PHP already provides all these functions except fabs() */
+
 extern double	cos(double x);
 /* Cosine of x */
 
@@ -54,9 +56,6 @@
 extern double	sqrt(double x);
 /* Square root. x >= 0 */
 
-extern double	fabs(double x);
-/* Absolute value of x */
-
 extern double	ceil(double x);
 /* Smallest integer not less than x, as a double */
 
@@ -66,6 +65,13 @@
 extern double	fmod(double x, double y);
 /* Floating-point remainder of x/y, with the same sign as x. */
 
+#endif
+
+extern double	fabs(double x);
+/* Absolute value of x */
+
+#ifndef SWIGPHP /* PHP already provides these constants and it's an error to redefine them */
+
 #define M_E		2.7182818284590452354
 #define M_LOG2E		1.4426950408889634074
 #define M_LOG10E	0.43429448190325182765
@@ -80,3 +86,4 @@
 #define M_SQRT2		1.41421356237309504880
 #define M_SQRT1_2	0.70710678118654752440
 
+#endif
diff --git a/Lib/modula3/modula3.swg b/Lib/modula3/modula3.swg
deleted file mode 100644
index 13d06e9..0000000
--- a/Lib/modula3/modula3.swg
+++ /dev/null
@@ -1,787 +0,0 @@
-/* -----------------------------------------------------------------------------
- * modula3.swg
- *
- * Modula3 typemaps
- * ----------------------------------------------------------------------------- */
-
-%include <modula3head.swg>
-
-/* The ctype, m3rawtype and m3wraptype typemaps work together and so there should be one of each. 
- * The ctype typemap contains the C type used in the signature of C wrappers for C++ functions. 
- * The m3rawtype typemap contains the M3 type used in the raw interface.
- * The m3rawintype typemap contains the M3 type used as function argument.
- * The m3rawrettype typemap contains the M3 type used as return value.
- * The m3wraptype typemap contains the M3 type used in the M3 type wrapper classes and module class. */
-
-/* Primitive types */
-%typemap(ctype) bool,               const bool &               "bool"
-%typemap(ctype) char,               const char &               "char"
-%typemap(ctype) signed char,        const signed char &        "signed char"
-%typemap(ctype) unsigned char,      const unsigned char &      "unsigned short"
-%typemap(ctype) short,              const short &              "short"
-%typemap(ctype) unsigned short,     const unsigned short &     "unsigned short"
-%typemap(ctype) int,                const int &                "int"
-%typemap(ctype) unsigned int,       const unsigned int &       "unsigned int"
-%typemap(ctype) long,               const long &               "long"
-%typemap(ctype) unsigned long,      const unsigned long &      "unsigned long"
-%typemap(ctype) long long,          const long long &          "long long"
-%typemap(ctype) unsigned long long, const unsigned long long & "unsigned long long"
-%typemap(ctype) float,              const float &              "float"
-%typemap(ctype) double,             const double &             "double"
-%typemap(ctype) char *                                         "char *"
-%typemap(ctype) void                                           "void"
-
-%typemap(m3rawtype) bool,               const bool &               "BOOLEAN"
-%typemap(m3rawtype) char,               const char &               "C.char"
-%typemap(m3rawtype) signed char,        const signed char &        "C.signed_char"
-%typemap(m3rawtype) unsigned char,      const unsigned char &      "C.unsigned_char"
-%typemap(m3rawtype) short,              const short &              "C.short"
-%typemap(m3rawtype) unsigned short,     const unsigned short &     "C.unsigned_short"
-%typemap(m3rawtype) int,                const int &                "C.int"
-%typemap(m3rawtype) unsigned int,       const unsigned int &       "C.unsigned_int"
-%typemap(m3rawtype) long,               const long &               "C.long"
-%typemap(m3rawtype) unsigned long,      const unsigned long &      "C.unsigned_long"
-%typemap(m3rawtype) long long,          const long long &          "C.long_long"
-%typemap(m3rawtype) unsigned long long, const unsigned long long & "C.unsigned_long_long"
-%typemap(m3rawtype) float,              const float &              "C.float"
-%typemap(m3rawtype) double,             const double &             "C.double"
-%typemap(m3rawtype) long double,        const long double &        "C.long_double"
-%typemap(m3rawtype) char *                                         "C.char_star"
-%typemap(m3rawtype) void                                           ""
-%typemap(m3rawtype) FILE                                           "Cstdio.FILE";
-%typemap(m3rawtype) FILE *                                         "Cstdio.FILE_star";
-
-
-%typemap(m3rawintype) bool *,               bool &,               bool               "BOOLEAN"
-%typemap(m3rawintype) char *,               char &,               char               "C.char"
-%typemap(m3rawintype) signed char *,        signed char &,        signed char        "C.signed_char"
-%typemap(m3rawintype) unsigned char *,      unsigned char &,      unsigned char      "C.unsigned_char"
-%typemap(m3rawintype) short *,              short &,              short              "C.short"
-%typemap(m3rawintype) unsigned short *,     unsigned short &,     unsigned short     "C.unsigned_short"
-%typemap(m3rawintype) int *,                int &,                int                "C.int"
-%typemap(m3rawintype) unsigned int *,       unsigned int &,       unsigned int       "C.unsigned_int"
-%typemap(m3rawintype) long *,               long &,               long               "C.long"
-%typemap(m3rawintype) unsigned long *,      unsigned long &,      unsigned long      "C.unsigned_long"
-%typemap(m3rawintype) long long *,          long long &,          long long          "C.long_long"
-%typemap(m3rawintype) unsigned long long *, unsigned long long &, unsigned long long "C.unsigned_long_long"
-%typemap(m3rawintype) float *,              float &,              float              "C.float"
-%typemap(m3rawintype) double *,             double &,             double             "C.double"
-%typemap(m3rawintype) long double *,        long double &,        long double        "C.long_double"
-%typemap(m3rawintype) char *                                                         "C.char_star"
-%typemap(m3rawintype) void                                                           ""
-%typemap(m3rawintype) void *                                                         "ADDRESS"
-%typemap(m3rawintype) FILE                                                           "Cstdio.FILE";
-%typemap(m3rawintype) FILE *                                                         "Cstdio.FILE_star";
-
-%typemap(m3rawinmode) char *, void *, FILE *  ""
-
-
-%typemap(m3rawrettype) bool,               const bool &               "BOOLEAN"
-%typemap(m3rawrettype) char,               const char &               "C.char"
-%typemap(m3rawrettype) signed char,        const signed char &        "C.signed_char"
-%typemap(m3rawrettype) unsigned char,      const unsigned char &      "C.unsigned_char"
-%typemap(m3rawrettype) short,              const short &              "C.short"
-%typemap(m3rawrettype) unsigned short,     const unsigned short &     "C.unsigned_short"
-%typemap(m3rawrettype) int,                const int &                "C.int"
-%typemap(m3rawrettype) unsigned int,       const unsigned int &       "C.unsigned_int"
-%typemap(m3rawrettype) long,               const long &               "C.long"
-%typemap(m3rawrettype) unsigned long,      const unsigned long &      "C.unsigned_long"
-%typemap(m3rawrettype) long long,          const long long &          "C.long_long"
-%typemap(m3rawrettype) unsigned long long, const unsigned long long & "C.unsigned_long_long"
-%typemap(m3rawrettype) float,              const float &              "C.float"
-%typemap(m3rawrettype) double,             const double &             "C.double"
-%typemap(m3rawrettype) long double,        const long double &        "C.long_double"
-%typemap(m3rawrettype) char *                                         "C.char_star"
-%typemap(m3rawrettype) void                                           ""
-%typemap(m3rawrettype) void *                                         "ADDRESS"
-%typemap(m3rawrettype) FILE                                           "Cstdio.FILE";
-%typemap(m3rawrettype) FILE *                                         "Cstdio.FILE_star";
-
-
-%typemap("m3rawtype:import")
-  char,               const char &,
-  signed char,        const signed char &,
-  unsigned char,      const unsigned char &,
-  short,              const short &,
-  unsigned short,     const unsigned short &,
-  int,                const int &,
-  unsigned int,       const unsigned int &,
-  long,               const long &,
-  unsigned long,      const unsigned long &,
-  long long,          const long long &,
-  unsigned long long, const unsigned long long &,
-  float,              const float &,
-  double,             const double &,
-  long double,        const long double &,
-  char *
-    "Ctypes AS C"
-
-%typemap("m3rawintype:import")
-  char,               const char &,
-  signed char,        const signed char &,
-  unsigned char,      const unsigned char &,
-  short,              const short &,
-  unsigned short,     const unsigned short &,
-  int,                const int &,
-  unsigned int,       const unsigned int &,
-  long,               const long &,
-  unsigned long,      const unsigned long &,
-  long long,          const long long &,
-  unsigned long long, const unsigned long long &,
-  float,              const float &,
-  double,             const double &,
-  long double,        const long double &,
-  char *
-    "Ctypes AS C"
-
-%typemap("m3rawrettype:import")
-  char,               const char &,
-  signed char,        const signed char &,
-  unsigned char,      const unsigned char &,
-  short,              const short &,
-  unsigned short,     const unsigned short &,
-  int,                const int &,
-  unsigned int,       const unsigned int &,
-  long,               const long &,
-  unsigned long,      const unsigned long &,
-  long long,          const long long &,
-  unsigned long long, const unsigned long long &,
-  float,              const float &,
-  double,             const double &,
-  long double,        const long double &,
-  char *
-    "Ctypes AS C"
-
-%typemap("m3rawtype:import")
-  FILE,   FILE *
-    "Cstdio";
-
-%typemap("m3rawintype:import")
-  FILE,   FILE *
-    "Cstdio";
-
-%typemap("m3rawrettype:import")
-  FILE,   FILE *
-    "Cstdio";
-
-%typemap(m3wraptype) bool,               const bool &               "BOOLEAN"
-%typemap(m3wraptype) char,               const char &               "CHAR"
-%typemap(m3wraptype) signed char,        const signed char &        "CHAR"
-%typemap(m3wraptype) unsigned char,      const unsigned char &      "CHAR"
-%typemap(m3wraptype) short,              const short &              "Integer16.T"
-%typemap(m3wraptype) unsigned short,     const unsigned short &     "Cardinal16.T"
-%typemap(m3wraptype) int,                const int &                "INTEGER"
-%typemap(m3wraptype) unsigned int,       const unsigned int &       "CARDINAL"
-%typemap(m3wraptype) long,               const long &               "Integer32.T"
-%typemap(m3wraptype) unsigned long,      const unsigned long &      "Cardinal32.T"
-%typemap(m3wraptype) long long,          const long long &          "Integer64.T"
-%typemap(m3wraptype) unsigned long long, const unsigned long long & "Cardinal64.T"
-%typemap(m3wraptype) float,              const float &              "REAL"
-%typemap(m3wraptype) double,             const double &             "LONGREAL"
-%typemap(m3wraptype) long double,        const long double &        "EXTENDED"
-%typemap(m3wraptype) char *                                         "TEXT"
-%typemap(m3wraptype) void                                           ""
-%typemap(m3wraptype) FILE                                           "Cstdio.FILE";
-%typemap(m3wraptype) FILE *                                         "Cstdio.FILE_star";
-
-%typemap(m3wrapintype) bool,               const bool *,               const bool &               "BOOLEAN"
-%typemap(m3wrapintype) char,               const char *,               const char &               "CHAR"
-%typemap(m3wrapintype) signed char,        const signed char *,        const signed char &        "CHAR"
-%typemap(m3wrapintype) unsigned char,      const unsigned char *,      const unsigned char &      "CHAR"
-%typemap(m3wrapintype) short,              const short *,              const short &              "INTEGER"
-%typemap(m3wrapintype) unsigned short,     const unsigned short *,     const unsigned short &     "CARDINAL"
-%typemap(m3wrapintype) int,                const int *,                const int &                "INTEGER"
-%typemap(m3wrapintype) unsigned int,       const unsigned int *,       const unsigned int &       "CARDINAL"
-%typemap(m3wrapintype) long,               const long *,               const long &               "INTEGER"
-%typemap(m3wrapintype) unsigned long,      const unsigned long *,      const unsigned long &      "CARDINAL"
-%typemap(m3wrapintype) long long,          const long long *,          const long long &          "INTEGER"
-%typemap(m3wrapintype) unsigned long long, const unsigned long long *, const unsigned long long & "CARDINAL"
-%typemap(m3wrapintype) float,              const float *,              const float &              "REAL"
-%typemap(m3wrapintype) double,             const double *,             const double &             "LONGREAL"
-%typemap(m3wrapintype) long double,        const long double *,        const long double &        "EXTENDED"
-%typemap(m3wrapintype) const char *, const char []   "TEXT"
-%typemap(m3wrapintype,numinputs=0) void              ""
-%typemap(m3wrapintype) FILE            "Cstdio.FILE";
-%typemap(m3wrapintype) FILE *          "Cstdio.FILE_star";
-
-
-%typemap(m3wrapouttype) bool,               bool *,               bool &                  "BOOLEAN"
-%typemap(m3wrapouttype) char,               char *,               char &                  "CHAR"
-%typemap(m3wrapouttype) signed char,        signed char *,        signed char &           "CHAR"
-%typemap(m3wrapouttype) unsigned char,      unsigned char *,      unsigned char &         "CHAR"
-%typemap(m3wrapouttype) short,              short *,              short &                 "INTEGER"
-%typemap(m3wrapouttype) unsigned short,     unsigned short *,     unsigned short &        "CARDINAL"
-%typemap(m3wrapouttype) int,                int *,                int &                   "INTEGER"
-%typemap(m3wrapouttype) unsigned int,       unsigned int *,       unsigned int &          "CARDINAL"
-%typemap(m3wrapouttype) long,               long *,               long &                  "INTEGER"
-%typemap(m3wrapouttype) unsigned long,      unsigned long *,      unsigned long &         "CARDINAL"
-%typemap(m3wrapouttype) long long,          long long *,          long long &             "INTEGER"
-%typemap(m3wrapouttype) unsigned long long, unsigned long long *, unsigned long long &    "CARDINAL"
-%typemap(m3wrapouttype) float,              float *,              float &                 "REAL"
-%typemap(m3wrapouttype) double,             double *,             double &                "LONGREAL"
-%typemap(m3wrapouttype) long double,        long double *,        long double &           "EXTENDED"
-%typemap(m3wrapouttype) char *, char []    "TEXT"
-%typemap(m3wrapouttype,numinputs=0) void   ""
-
-%typemap(m3wraprettype) bool,               const bool &               "BOOLEAN"
-%typemap(m3wraprettype) char,               const char &               "CHAR"
-%typemap(m3wraprettype) signed char,        const signed char &        "CHAR"
-%typemap(m3wraprettype) unsigned char,      const unsigned char &      "CHAR"
-%typemap(m3wraprettype) short,              const short &              "INTEGER"
-%typemap(m3wraprettype) unsigned short,     const unsigned short &     "CARDINAL"
-%typemap(m3wraprettype) int,                const int &                "INTEGER"
-%typemap(m3wraprettype) unsigned int,       const unsigned int &       "CARDINAL"
-%typemap(m3wraprettype) long,               const long &               "INTEGER"
-%typemap(m3wraprettype) unsigned long,      const unsigned long &      "CARDINAL"
-%typemap(m3wraprettype) long long,          const long long &          "INTEGER"
-%typemap(m3wraprettype) unsigned long long, const unsigned long long & "CARDINAL"
-%typemap(m3wraprettype) float,              const float &              "REAL"
-%typemap(m3wraprettype) double,             const double &             "LONGREAL"
-%typemap(m3wraprettype) long double,        const long double &        "EXTENDED"
-%typemap(m3wraprettype) char *                                         "TEXT"
-%typemap(m3wraprettype) void                                           ""
-%typemap(m3wraprettype) FILE            "Cstdio.FILE";
-%typemap(m3wraprettype) FILE *          "Cstdio.FILE_star";
-
-
-%typemap(ctype)          char[ANY]               "char *"
-%typemap(m3rawtype)      char[ANY]               "C.char_star"
-%typemap(m3rawintype)    char[ANY]               "C.char_star"
-%typemap(m3rawrettype)   char[ANY]               "C.char_star"
-%typemap(m3wraptype)     char[ANY]               "TEXT"
-%typemap(m3wrapintype)   char[ANY]               "TEXT"
-%typemap(m3wrapouttype)  char[ANY]               "TEXT"
-%typemap(m3wraprettype)  char[ANY]               "TEXT"
-
-%typemap(m3wrapinmode)  const char * %{%}
-%typemap(m3wrapargvar)  const char * %{$1 : C.char_star;%}
-%typemap(m3wrapinconv)  const char * %{$1 := M3toC.SharedTtoS($1_name);%}
-%typemap(m3wrapfreearg) const char * %{M3toC.FreeSharedS($1_name,$1);%}
-%typemap(m3wrapargraw)  const char * %{$1%}
-%typemap("m3wrapargvar:import")  const char * "Ctypes AS C"
-%typemap("m3wrapinconv:import")  const char * "M3toC"
-%typemap("m3wrapfreearg:import") const char * "M3toC"
-
-%typemap(m3wrapretvar)  char * %{result : C.char_star;%}
-%typemap(m3wrapretraw)  char * %{result%}
-%typemap(m3wrapretconv) char * %{M3toC.CopyStoT(result)%}
-%typemap("m3wrapretvar:import")  char * "Ctypes AS C"
-%typemap("m3wrapretconv:import") char * "M3toC"
-
-%typemap(m3wrapinmode)  FILE * %{%}
-
-
-%typemap("m3wraptype:import")
-  FILE,   FILE *
-    "Cstdio";
-
-%typemap("m3wrapintype:import")
-  FILE,   FILE *
-    "Cstdio";
-
-%typemap("m3wraprettype:import")
-  FILE,   FILE *
-    "Cstdio";
-
-
-/* Composed types */
-%typemap(ctype)                SWIGTYPE "$1_type"
-%typemap(m3rawtype)            SWIGTYPE "$1_basetype"
-%typemap(m3rawrettype)         SWIGTYPE "UNTRACED REF $1_basetype"
-%typemap(m3wraptype)           SWIGTYPE "$1_basetype"
-%typemap(m3wrapintype)         SWIGTYPE "$1_basetype"
-%typemap(m3wrapouttype)        SWIGTYPE "$1_basetype"
-%typemap(m3wraprettype)        SWIGTYPE "$1_basetype"
-
-%typemap(ctype)                SWIGTYPE [] "$1_type"
-%typemap(m3rawtype)      const SWIGTYPE [] "UNTRACED REF ARRAY INTEGER OF $1_basetype"
-%typemap(m3rawtype)            SWIGTYPE [] "UNTRACED REF ARRAY INTEGER OF $1_basetype"
-%typemap(m3rawintype)    const SWIGTYPE [] "(*ARRAY OF*) $1_basetype"
-%typemap(m3rawinmode)    const SWIGTYPE [] "READONLY"
-%typemap(m3rawintype)          SWIGTYPE [] "(*ARRAY OF*) $1_basetype"
-%typemap(m3rawinmode)          SWIGTYPE [] "VAR"
-%typemap(m3rawrettype)   const SWIGTYPE [] "UNTRACED REF ARRAY INTEGER OF $1_basetype"
-%typemap(m3rawrettype)         SWIGTYPE [] "UNTRACED REF ARRAY INTEGER OF $1_basetype"
-%typemap(m3wraptype)           SWIGTYPE [] "$1_basetype"
-%typemap(m3wrapintype)   const SWIGTYPE [] "ARRAY OF $1_basetype"
-%typemap(m3wrapinmode)   const SWIGTYPE [] "READONLY"
-%typemap(m3wrapintype)         SWIGTYPE [] "ARRAY OF $1_basetype"
-%typemap(m3wrapinmode)         SWIGTYPE [] "VAR"
-%typemap(m3wrapouttype)        SWIGTYPE [] "ARRAY OF $1_basetype"
-%typemap(m3wraprettype)        SWIGTYPE [] "REF ARRAY OF $1_basetype"
-
-%typemap(ctype)                SWIGTYPE * "$1_type"
-%typemap(m3rawtype)      const SWIGTYPE * "UNTRACED REF $1_basetype"
-%typemap(m3rawtype)            SWIGTYPE * "UNTRACED REF $1_basetype"
-%typemap(m3rawintype)    const SWIGTYPE * "$1_basetype"
-%typemap(m3rawinmode)    const SWIGTYPE * "READONLY"
-%typemap(m3rawintype)          SWIGTYPE * "$1_basetype"
-%typemap(m3rawinmode)          SWIGTYPE * "VAR"
-%typemap(m3rawrettype)   const SWIGTYPE * "UNTRACED REF $1_basetype"
-%typemap(m3rawrettype)         SWIGTYPE * "UNTRACED REF $1_basetype"
-%typemap(m3wraptype)           SWIGTYPE * "$1_basetype"
-%typemap(m3wrapintype)   const SWIGTYPE * "$1_basetype"
-%typemap(m3wrapinmode)   const SWIGTYPE * "READONLY"
-%typemap(m3wrapintype)         SWIGTYPE * "$1_basetype"
-%typemap(m3wrapinmode)         SWIGTYPE * "VAR"
-%typemap(m3wrapouttype)        SWIGTYPE * "$1_basetype"
-%typemap(m3wraprettype)        SWIGTYPE * "UNTRACED REF $1_basetype"
-
-%typemap(ctype)                SWIGTYPE & "$1_type"
-%typemap(m3rawtype)      const SWIGTYPE & "UNTRACED REF $1_basetype"
-%typemap(m3rawtype)            SWIGTYPE & "UNTRACED REF $1_basetype"
-%typemap(m3rawintype)    const SWIGTYPE & "$1_basetype"
-%typemap(m3rawinmode)    const SWIGTYPE & "READONLY"
-%typemap(m3rawintype)          SWIGTYPE & "$1_basetype"
-%typemap(m3rawinmode)          SWIGTYPE & "VAR"
-%typemap(m3rawrettype)   const SWIGTYPE & "UNTRACED REF $1_basetype"
-%typemap(m3rawrettype)         SWIGTYPE & "UNTRACED REF $1_basetype"
-%typemap(m3wraptype)           SWIGTYPE & "$1_basetype"
-%typemap(m3wrapintype)   const SWIGTYPE & "$1_basetype"
-%typemap(m3wrapinmode)   const SWIGTYPE & "READONLY"
-%typemap(m3wrapintype)         SWIGTYPE & "$1_basetype"
-%typemap(m3wrapinmode)         SWIGTYPE & "VAR"
-%typemap(m3wrapouttype)        SWIGTYPE & "$1_basetype"
-%typemap(m3wraprettype)        SWIGTYPE & "UNTRACED REF $1_basetype"
-
-%typemap(ctype)                SWIGTYPE && "$1_type"
-%typemap(m3rawtype)      const SWIGTYPE && "UNTRACED REF $1_basetype"
-%typemap(m3rawtype)            SWIGTYPE && "UNTRACED REF $1_basetype"
-%typemap(m3rawintype)    const SWIGTYPE && "$1_basetype"
-%typemap(m3rawinmode)    const SWIGTYPE && "READONLY"
-%typemap(m3rawintype)          SWIGTYPE && "$1_basetype"
-%typemap(m3rawinmode)          SWIGTYPE && "VAR"
-%typemap(m3rawrettype)   const SWIGTYPE && "UNTRACED REF $1_basetype"
-%typemap(m3rawrettype)         SWIGTYPE && "UNTRACED REF $1_basetype"
-%typemap(m3wraptype)           SWIGTYPE && "$1_basetype"
-%typemap(m3wrapintype)   const SWIGTYPE && "$1_basetype"
-%typemap(m3wrapinmode)   const SWIGTYPE && "READONLY"
-%typemap(m3wrapintype)         SWIGTYPE && "$1_basetype"
-%typemap(m3wrapinmode)         SWIGTYPE && "VAR"
-%typemap(m3wrapouttype)        SWIGTYPE && "$1_basetype"
-%typemap(m3wraprettype)        SWIGTYPE && "UNTRACED REF $1_basetype"
-
-%typemap(ctype)           enum SWIGTYPE "$1_type"
-%typemap(m3rawtype)       enum SWIGTYPE "C.int"
-%typemap(m3rawintype)     enum SWIGTYPE "C.int (* $1_type *)"
-%typemap(m3rawrettype)    enum SWIGTYPE "C.int"
-%typemap(m3wraptype)      enum SWIGTYPE "$*1_type"
-%typemap(m3wrapintype)    enum SWIGTYPE "$1_type"
-%typemap(m3wrapouttype)   enum SWIGTYPE "$1_type"
-%typemap(m3wraprettype)   enum SWIGTYPE "$*1_type"
-
-/* pointer to a class member */
-%typemap(ctype)      SWIGTYPE (CLASS::*) "$1_type"
-%typemap(m3rawtype)  SWIGTYPE (CLASS::*) "REFANY"
-%typemap(m3wraptype) SWIGTYPE (CLASS::*) "$1_basetype"
-
-/* The following are the in, out, freearg, argout typemaps.
-   These are the PInvoke code generating typemaps for converting from C# to C and visa versa. */
-
-/* primitive types */
-%typemap(in) bool
-%{ $1 = $input ? true : false; %}
-
-%typemap(in) char, 
-             signed char, 
-             unsigned char, 
-             short, 
-             unsigned short, 
-             int, 
-             unsigned int, 
-             long, 
-             unsigned long, 
-             long long, 
-             unsigned long long, 
-             float, 
-             double, 
-             enum SWIGTYPE
-%{ $1 = ($1_ltype)$input; %}
-
-%typemap(out) bool               %{ $result = $1; %}
-%typemap(out) char               %{ $result = $1; %}
-%typemap(out) signed char        %{ $result = $1; %}
-%typemap(out) unsigned char      %{ $result = $1; %}
-%typemap(out) short              %{ $result = $1; %}
-%typemap(out) unsigned short     %{ $result = $1; %}
-%typemap(out) int                %{ $result = $1; %}
-%typemap(out) unsigned int       %{ $result = $1; %}
-%typemap(out) long               %{ $result = $1; %}
-%typemap(out) unsigned long      %{ $result = $1; %}
-%typemap(out) long long          %{ $result = $1; %}
-%typemap(out) unsigned long long %{ $result = $1; %}
-%typemap(out) float              %{ $result = $1; %}
-%typemap(out) double             %{ $result = $1; %}
-%typemap(out) enum SWIGTYPE      %{ $result = $1; %}
-
-/* char * - treat as String */
-%typemap(in) char * {
-  $1 = $input;
-}
-//%typemap(freearg) char * { if ($1) JCALL2(ReleaseStringUTFChars, jenv, $input, $1); }
-//%typemap(out) char * { if($1) $result = JCALL1(NewStringUTF, jenv, $1); }
-
-%typemap(out) void ""
-
-/* primitive types by const reference */
-%typemap(in) const bool & (bool temp)
-%{ temp = $input ? true : false; 
-   $1 = &temp; %}
-
-%typemap(in) const char & (char temp), 
-             const signed char & (signed char temp), 
-             const unsigned char & (unsigned char temp), 
-             const short & (short temp), 
-             const unsigned short & (unsigned short temp), 
-             const int & (int temp), 
-             const unsigned int & (unsigned int temp), 
-             const long & (long temp), 
-             const unsigned long & (unsigned long temp), 
-             const long long & ($*1_ltype temp), 
-             const unsigned long long & ($*1_ltype temp), 
-             const float & (float temp), 
-             const double & (double temp)
-%{ temp = ($*1_ltype)$input; 
-$1 = &temp; %}
-
-%typemap(out) const bool &               %{ $result = *$1; %}
-%typemap(out) const char &               %{ $result = *$1; %}
-%typemap(out) const signed char &        %{ $result = *$1; %}
-%typemap(out) const unsigned char &      %{ $result = *$1; %}
-%typemap(out) const short &              %{ $result = *$1; %}
-%typemap(out) const unsigned short &     %{ $result = *$1; %}
-%typemap(out) const int &                %{ $result = *$1; %}
-%typemap(out) const unsigned int &       %{ $result = *$1; %}
-%typemap(out) const long &               %{ $result = *$1; %}
-%typemap(out) const unsigned long &      %{ $result = *$1; %}
-%typemap(out) const long long &          %{ $result = *$1; %}
-%typemap(out) const unsigned long long & %{ $result = *$1; %}
-%typemap(out) const float &              %{ $result = *$1; %}
-%typemap(out) const double &             %{ $result = *$1; %}
-
-/* Default handling. Object passed by value. Convert to a pointer */
-%typemap(in) SWIGTYPE ($&1_type argp)
-%{ argp = *($&1_ltype*)&$input; 
-   if (!argp) {
-//     SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "Attempt to dereference null $1_type");
-     RETURN $null;
-   }
-   $1 = *argp; %}
-%typemap(out) SWIGTYPE 
-#ifdef __cplusplus
-%{*($&1_ltype*)&$result = new $1_ltype((const $1_ltype &)$1); %}
-#else
-{
-  $&1_ltype $1ptr = ($&1_ltype) malloc(sizeof($1_ltype));
-  memmove($1ptr, &$1, sizeof($1_type));
-  *($&1_ltype*)&$result = $1ptr;
-}
-#endif
-
-/* Generic pointers and references */
-%typemap(in) SWIGTYPE *, SWIGTYPE (CLASS::*) %{ $1 = *($&1_ltype)&$input; %}
-%typemap(in) SWIGTYPE & %{ $1 = *($&1_ltype)&$input;
-  if(!$1) {
-    //SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type reference is null");
-    RETURN $null;
-  } %}
-%typemap(in) SWIGTYPE && %{ $1 = *($&1_ltype)&$input;
-  if(!$1) {
-    //SWIG_JavaThrowException(jenv, SWIG_JavaNullPointerException, "$1_type reference is null");
-    RETURN $null;
-  } %}
-%typemap(out) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE (CLASS::*) %{ *($&1_ltype)&$result = $1; %} 
-
-
-/* Default array handling */
-%typemap(in) SWIGTYPE [] %{ $1 = *($&1_ltype)&$input; %}
-%typemap(out) SWIGTYPE [] %{ *($&1_ltype)&$result = $1; %} 
-
-/* char[ANY] - treat as String */
-%typemap(in) char[ANY] { 
-    $1 = $input;
-}
-
-%typemap(argout) char[ANY] ""
-%typemap(freearg) char[ANY] ""//{ if ($1) JCALL2(ReleaseStringUTFChars, jenv, $input, $1); }
-%typemap(out) char[ANY] { if($1) $result = $1; }
-
-
-/* Typecheck typemaps - The purpose of these is merely to issue a warning for overloaded C++ functions 
- * that cannot be overloaded in C# as more than one C++ type maps to a single C# type */
-
-%typecheck(SWIG_TYPECHECK_BOOL) /* Java boolean */
-    bool,
-    const bool &
-    ""
-
-%typecheck(SWIG_TYPECHECK_CHAR) /* Java char */
-    char, 
-    const char &
-    ""
-
-%typecheck(SWIG_TYPECHECK_INT8) /* Java byte */
-    signed char,
-    const signed char &
-    ""
-
-%typecheck(SWIG_TYPECHECK_INT16) /* Java short */
-    unsigned char, 
-    short, 
-    const unsigned char &, 
-    const short &
-    ""
-
-%typecheck(SWIG_TYPECHECK_INT32) /* Java int */
-    unsigned short, 
-    int, 
-    long, 
-    const unsigned short &, 
-    const int &, 
-    const long &,
-    enum SWIGTYPE
-    ""
-
-%typecheck(SWIG_TYPECHECK_INT64) /* Java long */
-    unsigned int, 
-    unsigned long, 
-    long long, 
-    const unsigned int &, 
-    const unsigned long &, 
-    const long long &
-    ""
-
-%typecheck(SWIG_TYPECHECK_INT128) /* Java BigInteger */
-    unsigned long long
-    ""
-
-%typecheck(SWIG_TYPECHECK_FLOAT) /* Java float */
-    float,
-    const float &
-    ""
-
-%typecheck(SWIG_TYPECHECK_DOUBLE) /* Java double */
-    double,
-    const double &
-    ""
-
-%typecheck(SWIG_TYPECHECK_STRING) /* Java String */
-    char *,
-    char[ANY]
-    ""
-
-%typecheck(SWIG_TYPECHECK_POINTER) /* Default */
-    SWIGTYPE, 
-    SWIGTYPE *, 
-    SWIGTYPE &, 
-    SWIGTYPE &&, 
-    SWIGTYPE [],
-    SWIGTYPE (CLASS::*)
-    ""
-
-/* Exception handling */
-
-%typemap(throws) int, 
-                 long, 
-                 short, 
-                 unsigned int, 
-                 unsigned long, 
-                 unsigned short {
-  char error_msg[256];
-  sprintf(error_msg, "C++ $1_type exception thrown, value: %d", $1);
-  SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, error_msg);
-  RETURN $null;
-}
-
-%typemap(throws) SWIGTYPE {
-  (void)$1;
-  SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, "C++ $1_type exception thrown");
-  RETURN $null;
-}
-
-%typemap(throws) char * {
-  SWIG_JavaThrowException(jenv, SWIG_JavaRuntimeException, $1);
-  RETURN $null;
-}
-
-
-/* Typemaps for code generation in proxy classes and C# type wrapper classes */
-
-/* The in typemap is used for converting function parameter types from the type 
- * used in the proxy, module or type wrapper class to the type used in the PInvoke class. */
-%typemap(m3in)     bool,               const bool &,
-                 char,               const char &,
-                 signed char,        const signed char &,
-                 unsigned char,      const unsigned char &,
-                 short,              const short &,
-                 unsigned short,     const unsigned short &,
-                 int,                const int &,
-                 unsigned int,       const unsigned int &,
-                 long,               const long &,
-                 unsigned long,      const unsigned long &,
-                 long long,          const long long &,
-                 unsigned long long, const unsigned long long &,
-                 float,              const float &,
-                 double,             const double &,
-                 char *,
-                 char[ANY],
-                 enum SWIGTYPE 
-    "$input"
-%typemap(m3in) SWIGTYPE "$&*1_type.getCPtr($input)"
-%typemap(m3in) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "$1_basetype.getCPtr($input)"
-
-/* The m3out typemap is used for converting function return types from the return type
- * used in the PInvoke class to the type returned by the proxy, module or type wrapper class. */
-%typemap(m3out)   bool,               const bool &,
-                  char,               const char &,
-                  signed char,        const signed char &,
-                  unsigned char,      const unsigned char &,
-                  short,              const short &,
-                  unsigned short,     const unsigned short &,
-                  int,                const int &,
-                  unsigned int,       const unsigned int &,
-                  long,               const long &,
-                  unsigned long,      const unsigned long &,
-                  long long,          const long long &,
-                  unsigned long long, const unsigned long long &,
-                  float,              const float &,
-                  double,             const double &,
-                  char *,
-                  char[ANY],
-                  enum SWIGTYPE
-%{$imcall%}
-
-%typemap(m3out) void %{$imcall%}
-
-%typemap(m3out) SWIGTYPE %{
-    RETURN NEW(REF $1_basetype, $imcall);
-%}
-%typemap(m3out) SWIGTYPE & %{
-    RETURN NEW($1_basetype, $imcall, $owner);
-%}
-%typemap(m3out) SWIGTYPE && %{
-    RETURN NEW($1_basetype, $imcall, $owner);
-%}
-%typemap(m3out) SWIGTYPE *, SWIGTYPE [], SWIGTYPE (CLASS::*) %{
-    cPtr := $imcall;
-    RETURN (cPtr = IntPtr.Zero) ? null : NEW($1_basetype, cPtr, $owner);
-%}
-
-/* Properties */
-%typemap(m3varin) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) %{
-PROCEDURE Set$var (value: $vartype) =
-  BEGIN
-    $imcall;
-  END Set$var;
-%}
-
-%typemap(m3varout) bool,               const bool &,
-                   char,               const char &,
-                   signed char,        const signed char &,
-                   unsigned char,      const unsigned char &,
-                   short,              const short &,
-                   unsigned short,     const unsigned short &,
-                   int,                const int &,
-                   unsigned int,       const unsigned int &,
-                   long,               const long &,
-                   unsigned long,      const unsigned long &,
-                   long long,          const long long &,
-                   unsigned long long, const unsigned long long &,
-                   float,              const float &,
-                   double,             const double &,
-                   char *,
-                   char[ANY],
-                   enum SWIGTYPE %{
-PROCEDURE Get$var (): $vartype =
-  BEGIN
-    RETURN $imcall;
-  END Get$var;
-%}
-
-%typemap(m3varout) void %{
-    get {
-      $imcall;
-    } %}
-%typemap(m3varout) SWIGTYPE %{
-    get {
-      RETURN new $&*1_mangle($imcall, true);
-    } %}
-%typemap(m3varout) SWIGTYPE & %{
-    get {
-      RETURN new $1_basetype($imcall, $owner);
-    } %}
-%typemap(m3varout) SWIGTYPE && %{
-    get {
-      RETURN new $1_basetype($imcall, $owner);
-    } %}
-%typemap(m3varout) SWIGTYPE *, SWIGTYPE [], SWIGTYPE (CLASS::*) %{
-    get {
-      IntPtr cPtr = $imcall;
-      RETURN (cPtr == IntPtr.Zero) ? null : new $1_basetype(cPtr, $owner);
-    } %}
-
-/* Typemaps used for the generation of proxy and type wrapper class code */
-%typemap(m3base)                      SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
-%typemap(m3classmodifiers)            SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "public"
-%typemap(m3code)                      SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
-%typemap(m3imports)                   SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "using System;"
-%typemap(m3interfaces)                SWIGTYPE "IDisposable"
-%typemap(m3interfaces_derived)                  SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) ""
-%typemap(m3ptrconstructormodifiers) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) "internal"
-
-%typemap(m3finalize) SWIGTYPE %{
-  ~$1_basetype() {
-    Dispose();
-  }
-%}
-
-%typemap(m3destruct, methodname="Dispose") SWIGTYPE {
-    if(swigCPtr != IntPtr.Zero && swigCMemOwn) {
-      $imcall;
-      swigCMemOwn = false;
-    }
-    swigCPtr = IntPtr.Zero;
-    GC.SuppressFinalize(this);
-  }
-
-%typemap(m3destruct_derived, methodname="Dispose") SWIGTYPE {
-    if(swigCPtr != IntPtr.Zero && swigCMemOwn) {
-      $imcall;
-      swigCMemOwn = false;
-    }
-    swigCPtr = IntPtr.Zero;
-    GC.SuppressFinalize(this);
-    base.Dispose();
-  }
-
-%typemap(m3getcptr) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [], SWIGTYPE (CLASS::*) %{
-  internal static IntPtr getCPtr($1_basetype obj) {
-    RETURN (obj == null) ? IntPtr.Zero : obj.swigCPtr;
-  }
-%}
-
-/* M3 specific directives */
-#define %m3multiretval        %feature("modula3:multiretval")
-#define %constnumeric(num)    %feature("constnumeric","num")
-
-%pragma(modula3) moduleimports=%{
-IMPORT BlaBla;
-%}
-
-%pragma(modula3) imclassimports=%{
-FROM BlaBla IMPORT Bla;
-%}
-
-/* Some ANSI C typemaps */
-
-%apply unsigned long { size_t };
-
-/* Array reference typemaps */
-%apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) }
-%apply SWIGTYPE && { SWIGTYPE ((&&)[ANY]) }
-
-/* const pointers */
-%apply SWIGTYPE * { SWIGTYPE *const }
-%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) }
-%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) }
-
diff --git a/Lib/modula3/modula3head.swg b/Lib/modula3/modula3head.swg
deleted file mode 100644
index af96a78..0000000
--- a/Lib/modula3/modula3head.swg
+++ /dev/null
@@ -1,64 +0,0 @@
-/* -----------------------------------------------------------------------------
- * modula3head.swg
- *
- * Modula3 support code
- * ----------------------------------------------------------------------------- */
-
-%insert(runtime) %{
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-%}
-
-#if 0
-%insert(runtime) %{
-/* Support for throwing Modula3 exceptions */
-typedef enum {
-  SWIG_JavaOutOfMemoryError = 1, 
-  SWIG_JavaIOException, 
-  SWIG_JavaRuntimeException, 
-  SWIG_JavaIndexOutOfBoundsException,
-  SWIG_JavaArithmeticException,
-  SWIG_JavaIllegalArgumentException,
-  SWIG_JavaNullPointerException,
-  SWIG_JavaUnknownError
-} SWIG_JavaExceptionCodes;
-
-typedef struct {
-  SWIG_JavaExceptionCodes code;
-  const char *java_exception;
-} SWIG_JavaExceptions_t;
-
-#if defined(SWIG_NOINCLUDE)
-void SWIG_JavaThrowException(JNIEnv *jenv, SWIG_JavaExceptionCodes code, const char *msg);
-#else
-%}
-%insert(runtime) {
-void SWIG_JavaThrowException(JNIEnv *jenv, SWIG_JavaExceptionCodes code, const char *msg) {
-  jclass excep;
-  static const SWIG_JavaExceptions_t java_exceptions[] = {
-    { SWIG_JavaOutOfMemoryError, "java/lang/OutOfMemoryError" },
-    { SWIG_JavaIOException, "java/io/IOException" },
-    { SWIG_JavaRuntimeException, "java/lang/RuntimeException" },
-    { SWIG_JavaIndexOutOfBoundsException, "java/lang/IndexOutOfBoundsException" },
-    { SWIG_JavaArithmeticException, "java/lang/ArithmeticException" },
-    { SWIG_JavaIllegalArgumentException, "java/lang/IllegalArgumentException" },
-    { SWIG_JavaNullPointerException, "java/lang/NullPointerException" },
-    { SWIG_JavaUnknownError,  "java/lang/UnknownError" },
-    { (SWIG_JavaExceptionCodes)0,  "java/lang/UnknownError" } };
-  const SWIG_JavaExceptions_t *except_ptr = java_exceptions;
-
-  while (except_ptr->code != code && except_ptr->code)
-    except_ptr++;
-
-  JCALL0(ExceptionClear, jenv);
-  excep = JCALL1(FindClass, jenv, except_ptr->java_exception);
-  if (excep)
-    JCALL2(ThrowNew, jenv, excep, msg);
-}
-}
-%insert(runtime) %{
-#endif
-%}
-#endif
diff --git a/Lib/modula3/typemaps.i b/Lib/modula3/typemaps.i
deleted file mode 100644
index 1d76ab5..0000000
--- a/Lib/modula3/typemaps.i
+++ /dev/null
@@ -1,74 +0,0 @@
-/* -----------------------------------------------------------------------------
- * typemaps.i
- *
- * Pointer and reference handling typemap library
- *
- * These mappings provide support for input/output arguments and common
- * uses for C/C++ pointers and C++ references.
- * ----------------------------------------------------------------------------- */
-
-/* These typemaps will eventually probably maybe make their way into named typemaps
- * OUTPUT * and OUTPUT & as they currently break functions that return a pointer or 
- * reference. */
-
-%typemap(ctype) bool *,               bool &               "bool *"
-%typemap(ctype)                       char &               "char *"
-%typemap(ctype) signed char *,        signed char &        "signed char *"
-%typemap(ctype) unsigned char *,      unsigned char &      "unsigned short *"
-%typemap(ctype) short *,              short &              "short *"
-%typemap(ctype) unsigned short *,     unsigned short &     "unsigned short *"
-%typemap(ctype) int *,                int &                "int *"
-%typemap(ctype) unsigned int *,       unsigned int &       "unsigned int *"
-%typemap(ctype) long *,               long &               "long *"
-%typemap(ctype) unsigned long *,      unsigned long &      "unsigned long *"
-%typemap(ctype) long long *,          long long &          "long long *"
-%typemap(ctype) unsigned long long *, unsigned long long & "unsigned long long *"
-%typemap(ctype) float *,              float &              "float *"
-%typemap(ctype) double *,             double &             "double *"
-
-%typemap(imtype) bool *,               bool &               "ref bool"
-%typemap(imtype)                       char &               "ref char"
-%typemap(imtype) signed char *,        signed char &        "ref sbyte"
-%typemap(imtype) unsigned char *,      unsigned char &      "ref byte"
-%typemap(imtype) short *,              short &              "ref short"
-%typemap(imtype) unsigned short *,     unsigned short &     "ref ushort"
-%typemap(imtype) int *,                int &                "ref int"
-%typemap(imtype) unsigned int *,       unsigned int &       "ref uint"
-%typemap(imtype) long *,               long &               "ref int"
-%typemap(imtype) unsigned long *,      unsigned long &      "ref uint"
-%typemap(imtype) long long *,          long long &          "ref long"
-%typemap(imtype) unsigned long long *, unsigned long long & "ref ulong"
-%typemap(imtype) float *,              float &              "ref float"
-%typemap(imtype) double *,             double &             "ref double"
-
-%typemap(cstype) bool *,               bool &               "ref bool"
-%typemap(cstype)                       char &               "ref char"
-%typemap(cstype) signed char *,        signed char &        "ref sbyte"
-%typemap(cstype) unsigned char *,      unsigned char &      "ref byte"
-%typemap(cstype) short *,              short &              "ref short"
-%typemap(cstype) unsigned short *,     unsigned short &     "ref ushort"
-%typemap(cstype) int *,                int &                "ref int"
-%typemap(cstype) unsigned int *,       unsigned int &       "ref uint"
-%typemap(cstype) long *,               long &               "ref int"
-%typemap(cstype) unsigned long *,      unsigned long &      "ref uint"
-%typemap(cstype) long long *,          long long &          "ref long"
-%typemap(cstype) unsigned long long *, unsigned long long & "ref ulong"
-%typemap(cstype) float *,              float &              "ref float"
-%typemap(cstype) double *,             double &             "ref double"
-
-%typemap(csin)   bool *,               bool &,
-                                       char &,
-                 signed char *,        signed char &,
-                 unsigned char *,      unsigned char &,
-                 short *,              short &,
-                 unsigned short *,     unsigned short &,
-                 int *,                int &,
-                 unsigned int *,       unsigned int &,
-                 long *,               long &,
-                 unsigned long *,      unsigned long &,
-                 long long *,          long long &,
-                 unsigned long long *, unsigned long long &,
-                 float *,              float &,
-                 double *,             double &
-    "ref $csinput"
-
diff --git a/Lib/mzscheme/argcargv.i b/Lib/mzscheme/argcargv.i
new file mode 100644
index 0000000..eec1e0d
--- /dev/null
+++ b/Lib/mzscheme/argcargv.i
@@ -0,0 +1,41 @@
+/* -------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------- */
+
+%typemap(in) (int ARGC, char **ARGV) {
+  $1_ltype i, len;
+  Scheme_Object **elems;
+  SWIG_contract_assert($input != (Scheme_Object *)NULL &&
+                       $input != scheme_null &&
+                       SCHEME_TYPE($input) == scheme_vector_type, "null array");
+  len = SCHEME_VEC_SIZE($input);
+  $1 = len;
+  $2 = ($2_ltype) SWIG_MzScheme_Malloc((size_t)(len+1)*sizeof($*2_ltype), FUNC_NAME);
+  elems = SCHEME_VEC_ELS($input);
+  for (i = 0; i < len; i++) {
+    SWIG_contract_assert(SCHEME_TYPE(elems[i]) == scheme_char_string_type,
+                         "elements in array must be strings");
+    $2[i] = ($*2_ltype)SCHEME_STR_VAL(elems[i]);
+  }
+  $2[i] = NULL;
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+  if ($input != (Scheme_Object *)NULL && $input != scheme_null &&
+      SCHEME_TYPE($input) == scheme_vector_type) {
+    size_t len = SCHEME_VEC_SIZE($input);
+    size_t i;
+    Scheme_Object **elems = SCHEME_VEC_ELS($input);
+    for (i = 0; i < len; i++) {
+      if (SCHEME_TYPE(elems[i]) != scheme_char_string_type) {
+        break;
+      }
+    }
+    /* All elements are strings! */
+    $1 = (i == len);
+  }
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+  SWIG_free((void *)$2);
+}
diff --git a/Lib/mzscheme/mzrun.swg b/Lib/mzscheme/mzrun.swg
index c438c9c..8adae46 100644
--- a/Lib/mzscheme/mzrun.swg
+++ b/Lib/mzscheme/mzrun.swg
@@ -23,12 +23,15 @@
   SWIG_MzScheme_MustGetPtr(s, type, argnum, flags, FUNC_NAME, argc, argv)
 
 #define SWIG_contract_assert(expr,msg) \
- if (!(expr)) { \
-    char *m=(char *) scheme_malloc(strlen(msg)+1000); \
-    sprintf(m,"SWIG contract, assertion failed: function=%s, message=%s", \
-            (char *) FUNC_NAME,(char *) msg); \
-    scheme_signal_error(m); \
- }
+  do { \
+    if (!(expr)) { \
+      size_t len=strlen(msg)+1000; \
+      char *m=(char *) scheme_malloc(len); \
+      SWIG_snprintf2(m, len, "SWIG contract, assertion failed: function=%s, message=%s", \
+		     (char *) FUNC_NAME,(char *) msg); \
+      scheme_signal_error(m); \
+    } \
+  } while (0)
 
 /* Runtime API */
 #define SWIG_GetModule(clientdata) SWIG_MzScheme_GetModule((Scheme_Env *)(clientdata))
@@ -123,6 +126,7 @@
   Scheme_Type mztype;
   swig_type_info *type;
   void *object;
+  int own;
 };
 
 static Scheme_Type swig_type;
@@ -133,7 +137,7 @@
   if (SCHEME_NULLP((Scheme_Object*)p) || SCHEME_TYPE((Scheme_Object*)p) != swig_type)
     return;
   if (proxy->type) {
-    if (proxy->type->clientdata) {
+    if (proxy->type->clientdata && proxy->own) {
       ((Scheme_Prim *)proxy->type->clientdata)(1, (Scheme_Object **)&proxy);
     }
   }
@@ -141,42 +145,61 @@
 
 static Scheme_Object *
 SWIG_MzScheme_NewPointerObj(void *ptr, swig_type_info *type, int owner) {
-  struct swig_mz_proxy *new_proxy;
-  new_proxy = (struct swig_mz_proxy *) scheme_malloc(sizeof(struct swig_mz_proxy));
-  new_proxy->mztype = swig_type;
-  new_proxy->type = type;
-  new_proxy->object = ptr;
-  if (owner) {
-    scheme_add_finalizer(new_proxy, mz_free_swig, NULL);
+  if (ptr) {
+    struct swig_mz_proxy *new_proxy;
+    new_proxy = (struct swig_mz_proxy *) scheme_malloc(sizeof(struct swig_mz_proxy));
+    new_proxy->mztype = swig_type;
+    new_proxy->type = type;
+    new_proxy->object = ptr;
+    new_proxy->own = owner & SWIG_POINTER_OWN;
+    if (new_proxy->own) {
+      scheme_add_finalizer(new_proxy, mz_free_swig, NULL);
+    }
+    return (Scheme_Object *) new_proxy;
+  } else {
+    return scheme_make_null();
   }
-  return (Scheme_Object *) new_proxy;
 }
 
 static int
 SWIG_MzScheme_ConvertPtr(Scheme_Object *s, void **result, swig_type_info *type, int flags) {
   swig_cast_info *cast;
+  int ret = SWIG_ERROR;
 
   if (SCHEME_NULLP(s)) {
     *result = NULL;
     return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
   } else if (SCHEME_TYPE(s) == swig_type) {
     struct swig_mz_proxy *proxy = (struct swig_mz_proxy *) s;
+
+    if ((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE && !proxy->own) {
+      return SWIG_ERROR_RELEASE_NOT_OWNED;
+    }
+
     if (type) {
       cast = SWIG_TypeCheckStruct(proxy->type, type);
       if (cast) {
         int newmemory = 0;
         *result = SWIG_TypeCast(cast, proxy->object, &newmemory);
         assert(!newmemory); /* newmemory handling not yet implemented */
-        return 0;
+        ret = SWIG_OK;
       } else {
-        return 1;
+        return SWIG_ERROR;
       }
     } else {
       *result = proxy->object;
-      return 0;
+      ret = SWIG_OK;
+    }
+
+    if (flags & SWIG_POINTER_DISOWN) {
+      scheme_subtract_finalizer(proxy, mz_free_swig, NULL);
+      proxy->own = 0;
+    }
+    if (flags & SWIG_POINTER_CLEAR) {
+      proxy->object = 0;
     }
   }
-  return 1;
+  return ret;
 }
 
 static SWIGINLINE void *
@@ -195,7 +218,8 @@
   void *p = malloc(size);
   if (p == NULL) {
     scheme_signal_error("swig-memory-error");
-  } else return p;
+  }
+  return p;
 }
 
 static Scheme_Object *
@@ -398,10 +422,10 @@
 	      int L=strlen(mz_dynload_libpaths[k])+strlen("\\")+strlen(mz_dlopen_libraries[i])+1;
 	      libp=(char *) malloc(L*sizeof(char));
 #ifdef __OS_WIN32
-	      sprintf(libp,"%s\\%s",mz_dynload_libpaths[k],mz_dlopen_libraries[i]);
+	      SWIG_snprintf2(libp,L,"%s\\%s",mz_dynload_libpaths[k],mz_dlopen_libraries[i]);
 	      mz_libraries[i]=(void *) LoadLibrary(libp); 
 #else
-	      sprintf(libp,"%s/%s",mz_dynload_libpaths[k],mz_dlopen_libraries[i]);
+	      SWIG_snprintf2(libp,L,"%s/%s",mz_dynload_libpaths[k],mz_dlopen_libraries[i]);
 	      mz_libraries[i]=(void *) dlopen(libp,RTLD_LAZY); 
 #endif
 	      if (mz_dynload_debug) {
diff --git a/Lib/mzscheme/std_auto_ptr.i b/Lib/mzscheme/std_auto_ptr.i
new file mode 100644
index 0000000..c61bc8b
--- /dev/null
+++ b/Lib/mzscheme/std_auto_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      scheme_signal_error(FUNC_NAME ": cannot release ownership as memory is not owned for argument $argnum of type 'TYPE *'");
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+  %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class auto_ptr {};
+}
diff --git a/Lib/mzscheme/std_map.i b/Lib/mzscheme/std_map.i
index 1d3eec2..4d312f5 100644
--- a/Lib/mzscheme/std_map.i
+++ b/Lib/mzscheme/std_map.i
@@ -5,6 +5,7 @@
  * ----------------------------------------------------------------------------- */
 
 %include <std_common.i>
+%include <exception.i>
 
 // ------------------------------------------------------------------------
 // std::map
@@ -64,7 +65,11 @@
                         val = scheme_car(val);
                         x = (T*) SWIG_MustGetPtr(val,$descriptor(T *),$argnum, 0);
                     }
+%#ifdef __cpp_lib_map_try_emplace
+                    (($1_type &)$1).insert_or_assign(*k, *x);
+%#else
                     (($1_type &)$1)[*k] = *x;
+%#endif
                     alist = scheme_cdr(alist);
                 }
             } else {
@@ -100,7 +105,11 @@
                         val = scheme_car(val);
                         x = (T*) SWIG_MustGetPtr(val,$descriptor(T *),$argnum, 0);
                     }
+%#ifdef __cpp_lib_map_try_emplace
+                    temp.insert_or_assign(*k, *x);
+%#else
                     temp[*k] = *x;
+%#endif
                     alist = scheme_cdr(alist);
                 }
             } else {
@@ -242,7 +251,11 @@
                     throw std::out_of_range("key not found");
             }
             void __setitem__(const K& key, const T& x) {
+%#ifdef __cpp_lib_map_try_emplace
+                (*self).insert_or_assign(key, x);
+%#else
                 (*self)[key] = x;
+%#endif
             }
             void __delitem__(const K& key) throw (std::out_of_range) {
                 std::map< K, T, C >::iterator i = self->find(key);
@@ -268,1121 +281,4 @@
         }
     };
 
-
-    // specializations for built-ins
-
-    %define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO)
-
-    template<class T> class map< K, T, C > {
-        %typemap(in) map< K, T, C > (std::map< K, T, C >* m) {
-            if (SCHEME_NULLP($input)) {
-                $1 = std::map< K, T, C >();
-            } else if (SCHEME_PAIRP($input)) {
-                $1 = std::map< K, T, C >();
-                Scheme_Object* alist = $input;
-                while (!SCHEME_NULLP(alist)) {
-                    T* x;
-                    Scheme_Object *entry, *key, *val;
-                    entry = scheme_car(alist);
-                    if (!SCHEME_PAIRP(entry))
-                        SWIG_exception(SWIG_TypeError,"alist expected");
-                    key = scheme_car(entry);
-                    val = scheme_cdr(entry);
-                    if (!CHECK(key))
-                        SWIG_exception(SWIG_TypeError,
-                                       "map<" #K "," #T "," #C "> expected");
-                    if (SWIG_ConvertPtr(val,(void**) &x,
-                                    $descriptor(T *), 0) == -1) {
-                        if (!SCHEME_PAIRP(val))
-                            SWIG_exception(SWIG_TypeError,"alist expected");
-                        val = scheme_car(val);
-                        x = (T*) SWIG_MustGetPtr(val,$descriptor(T *),$argnum, 0);
-                    }
-                    (($1_type &)$1)[CONVERT_FROM(key)] = *x;
-                    alist = scheme_cdr(alist);
-                }
-            } else {
-                $1 = *(($&1_type)
-                       SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0));
-            }
-        }
-        %typemap(in) const map< K, T, C >& (std::map< K, T, C > temp,
-                                      std::map< K, T, C >* m),
-                     const map< K, T, C >* (std::map< K, T, C > temp,
-                                      std::map< K, T, C >* m) {
-            if (SCHEME_NULLP($input)) {
-                temp = std::map< K, T, C >();
-                $1 = &temp;
-            } else if (SCHEME_PAIRP($input)) {
-                temp = std::map< K, T, C >();
-                $1 = &temp;
-                Scheme_Object* alist = $input;
-                while (!SCHEME_NULLP(alist)) {
-                    T* x;
-                    Scheme_Object *entry, *key, *val;
-                    entry = scheme_car(alist);
-                    if (!SCHEME_PAIRP(entry))
-                        SWIG_exception(SWIG_TypeError,"alist expected");
-                    key = scheme_car(entry);
-                    val = scheme_cdr(entry);
-                    if (!CHECK(key))
-                        SWIG_exception(SWIG_TypeError,
-                                       "map<" #K "," #T "," #C "> expected");
-                    if (SWIG_ConvertPtr(val,(void**) &x,
-                                    $descriptor(T *), 0) == -1) {
-                        if (!SCHEME_PAIRP(val))
-                            SWIG_exception(SWIG_TypeError,"alist expected");
-                        val = scheme_car(val);
-                        x = (T*) SWIG_MustGetPtr(val,$descriptor(T *),$argnum, 0);
-                    }
-                    temp[CONVERT_FROM(key)] = *x;
-                    alist = scheme_cdr(alist);
-                }
-            } else {
-                $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0);
-            }
-        }
-        %typemap(out) map< K, T, C > {
-            Scheme_Object* alist = scheme_null;
-            for (std::map< K, T, C >::reverse_iterator i=$1.rbegin(); 
-                                                  i!=$1.rend(); ++i) {
-                T* val = new T(i->second);
-                Scheme_Object* k = CONVERT_TO(i->first);
-                Scheme_Object* x = SWIG_NewPointerObj(val,$descriptor(T *), 1);
-                Scheme_Object* entry = scheme_make_pair(k,x);
-                alist = scheme_make_pair(entry,alist);
-            }
-            $result = alist;
-        }
-        %typecheck(SWIG_TYPECHECK_MAP) map< K, T, C > {
-            // native sequence?
-            if (SCHEME_NULLP($input)) {
-                /* an empty sequence can be of any type */
-                $1 = 1;
-            } else if (SCHEME_PAIRP($input)) {
-                // check the first element only
-                T* x;
-                Scheme_Object* head = scheme_car($input);
-                if (SCHEME_PAIRP(head)) {
-                    Scheme_Object* key = scheme_car(head);
-                    Scheme_Object* val = scheme_cdr(head);
-                    if (!CHECK(key)) {
-                        $1 = 0;
-                    } else {
-                        if (SWIG_ConvertPtr(val,(void**) &x,
-                                        $descriptor(T *), 0) != -1) {
-                            $1 = 1;
-                        } else if (SCHEME_PAIRP(val)) {
-                            val = scheme_car(val);
-                            if (SWIG_ConvertPtr(val,(void**) &x,
-                                            $descriptor(T *), 0) != -1)
-                                $1 = 1;
-                            else
-                                $1 = 0;
-                        } else {
-                            $1 = 0;
-                        }
-                    }
-                } else {
-                    $1 = 0;
-                }
-            } else {
-                // wrapped map?
-                std::map< K, T, C >* m;
-                if (SWIG_ConvertPtr($input,(void **) &m,
-                                $&1_descriptor, 0) != -1)
-                    $1 = 1;
-                else
-                    $1 = 0;
-            }
-        }
-        %typecheck(SWIG_TYPECHECK_MAP) const map< K, T, C >&,
-                                       const map< K, T, C >* {
-            // native sequence?
-            if (SCHEME_NULLP($input)) {
-                /* an empty sequence can be of any type */
-                $1 = 1;
-            } else if (SCHEME_PAIRP($input)) {
-                // check the first element only
-                T* x;
-                Scheme_Object* head = scheme_car($input);
-                if (SCHEME_PAIRP(head)) {
-                    Scheme_Object* key = scheme_car(head);
-                    Scheme_Object* val = scheme_cdr(head);
-                    if (!CHECK(key)) {
-                        $1 = 0;
-                    } else {
-                        if (SWIG_ConvertPtr(val,(void**) &x,
-                                        $descriptor(T *), 0) != -1) {
-                            $1 = 1;
-                        } else if (SCHEME_PAIRP(val)) {
-                            val = scheme_car(val);
-                            if (SWIG_ConvertPtr(val,(void**) &x,
-                                            $descriptor(T *), 0) != -1)
-                                $1 = 1;
-                            else
-                                $1 = 0;
-                        } else {
-                            $1 = 0;
-                        }
-                    }
-                } else {
-                    $1 = 0;
-                }
-            } else {
-                // wrapped map?
-                std::map< K, T, C >* m;
-                if (SWIG_ConvertPtr($input,(void **) &m,
-                                $1_descriptor, 0) != -1)
-                    $1 = 1;
-                else
-                    $1 = 0;
-            }
-        }
-        %rename("length") size;
-        %rename("null?") empty;
-        %rename("clear!") clear;
-        %rename("ref") __getitem__;
-        %rename("set!") __setitem__;
-        %rename("delete!") __delitem__;
-        %rename("has-key?") has_key;
-      public:
-        typedef size_t size_type;
-        typedef ptrdiff_t difference_type;
-        typedef K key_type;
-        typedef T mapped_type;
-        typedef std::pair< const K, T > value_type;
-        typedef value_type* pointer;
-        typedef const value_type* const_pointer;
-        typedef value_type& reference;
-        typedef const value_type& const_reference;
-
-        map();
-        map(const map& other);
-        
-        unsigned int size() const;
-        bool empty() const;
-        void clear();
-        %extend {
-            T& __getitem__(K key) throw (std::out_of_range) {
-                std::map< K, T, C >::iterator i = self->find(key);
-                if (i != self->end())
-                    return i->second;
-                else
-                    throw std::out_of_range("key not found");
-            }
-            void __setitem__(K key, const T& x) {
-                (*self)[key] = x;
-            }
-            void __delitem__(K key) throw (std::out_of_range) {
-                std::map< K, T, C >::iterator i = self->find(key);
-                if (i != self->end())
-                    self->erase(i);
-                else
-                    throw std::out_of_range("key not found");
-            }
-            bool has_key(K key) {
-                std::map< K, T, C >::iterator i = self->find(key);
-                return i != self->end();
-            }
-            Scheme_Object* keys() {
-                Scheme_Object* result = scheme_null;
-                for (std::map< K, T, C >::reverse_iterator i=self->rbegin(); 
-                                                      i!=self->rend(); ++i) {
-                    Scheme_Object* k = CONVERT_TO(i->first);
-                    result = scheme_make_pair(k,result);
-                }
-                return result;
-            }
-        }
-    };
-    %enddef
-
-    %define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO)
-    template<class K> class map< K, T, C > {
-        %typemap(in) map< K, T, C > (std::map< K, T, C >* m) {
-            if (SCHEME_NULLP($input)) {
-                $1 = std::map< K, T, C >();
-            } else if (SCHEME_PAIRP($input)) {
-                $1 = std::map< K, T, C >();
-                Scheme_Object* alist = $input;
-                while (!SCHEME_NULLP(alist)) {
-                    K* k;
-                    Scheme_Object *entry, *key, *val;
-                    entry = scheme_car(alist);
-                    if (!SCHEME_PAIRP(entry))
-                        SWIG_exception(SWIG_TypeError,"alist expected");
-                    key = scheme_car(entry);
-                    val = scheme_cdr(entry);
-                    k = (K*) SWIG_MustGetPtr(key,$descriptor(K *),$argnum, 0);
-                    if (!CHECK(val)) {
-                        if (!SCHEME_PAIRP(val))
-                            SWIG_exception(SWIG_TypeError,"alist expected");
-                        val = scheme_car(val);
-                        if (!CHECK(val))
-                            SWIG_exception(SWIG_TypeError,
-                                           "map<" #K "," #T "," #C "> expected");
-                    }
-                    (($1_type &)$1)[*k] = CONVERT_FROM(val);
-                    alist = scheme_cdr(alist);
-                }
-            } else {
-                $1 = *(($&1_type)
-                       SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0));
-            }
-        }
-        %typemap(in) const map< K, T, C >& (std::map< K, T, C > temp,
-                                      std::map< K, T, C >* m),
-                     const map< K, T, C >* (std::map< K, T, C > temp,
-                                      std::map< K, T, C >* m) {
-            if (SCHEME_NULLP($input)) {
-                temp = std::map< K, T, C >();
-                $1 = &temp;
-            } else if (SCHEME_PAIRP($input)) {
-                temp = std::map< K, T, C >();
-                $1 = &temp;
-                Scheme_Object* alist = $input;
-                while (!SCHEME_NULLP(alist)) {
-                    K* k;
-                    Scheme_Object *entry, *key, *val;
-                    entry = scheme_car(alist);
-                    if (!SCHEME_PAIRP(entry))
-                        SWIG_exception(SWIG_TypeError,"alist expected");
-                    key = scheme_car(entry);
-                    val = scheme_cdr(entry);
-                    k = (K*) SWIG_MustGetPtr(key,$descriptor(K *),$argnum, 0);
-                    if (!CHECK(val)) {
-                        if (!SCHEME_PAIRP(val))
-                            SWIG_exception(SWIG_TypeError,"alist expected");
-                        val = scheme_car(val);
-                        if (!CHECK(val))
-                            SWIG_exception(SWIG_TypeError,
-                                           "map<" #K "," #T "," #C "> expected");
-                    }
-                    temp[*k] = CONVERT_FROM(val);
-                    alist = scheme_cdr(alist);
-                }
-            } else {
-                $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0);
-            }
-        }
-        %typemap(out) map< K, T, C > {
-            Scheme_Object* alist = scheme_null;
-            for (std::map< K, T, C >::reverse_iterator i=$1.rbegin(); 
-                                                  i!=$1.rend(); ++i) {
-                K* key = new K(i->first);
-                Scheme_Object* k = SWIG_NewPointerObj(key,$descriptor(K *), 1);
-                Scheme_Object* x = CONVERT_TO(i->second);
-                Scheme_Object* entry = scheme_make_pair(k,x);
-                alist = scheme_make_pair(entry,alist);
-            }
-            $result = alist;
-        }
-        %typecheck(SWIG_TYPECHECK_MAP) map< K, T, C > {
-            // native sequence?
-            if (SCHEME_NULLP($input)) {
-                /* an empty sequence can be of any type */
-                $1 = 1;
-            } else if (SCHEME_PAIRP($input)) {
-                // check the first element only
-                K* k;
-                Scheme_Object* head = scheme_car($input);
-                if (SCHEME_PAIRP(head)) {
-                    Scheme_Object* key = scheme_car(head);
-                    Scheme_Object* val = scheme_cdr(head);
-                    if (SWIG_ConvertPtr(val,(void **) &k,
-                                    $descriptor(K *), 0) == -1) {
-                        $1 = 0;
-                    } else {
-                        if (CHECK(val)) {
-                            $1 = 1;
-                        } else if (SCHEME_PAIRP(val)) {
-                            val = scheme_car(val);
-                            if (CHECK(val))
-                                $1 = 1;
-                            else
-                                $1 = 0;
-                        } else {
-                            $1 = 0;
-                        }
-                    }
-                } else {
-                    $1 = 0;
-                }
-            } else {
-                // wrapped map?
-                std::map< K, T, C >* m;
-                if (SWIG_ConvertPtr($input,(void **) &m,
-                                $&1_descriptor, 0) != -1)
-                    $1 = 1;
-                else
-                    $1 = 0;
-            }
-        }
-        %typecheck(SWIG_TYPECHECK_MAP) const map< K, T, C >&,
-                                       const map< K, T, C >* {
-            // native sequence?
-            if (SCHEME_NULLP($input)) {
-                /* an empty sequence can be of any type */
-                $1 = 1;
-            } else if (SCHEME_PAIRP($input)) {
-                // check the first element only
-                K* k;
-                Scheme_Object* head = scheme_car($input);
-                if (SCHEME_PAIRP(head)) {
-                    Scheme_Object* key = scheme_car(head);
-                    Scheme_Object* val = scheme_cdr(head);
-                    if (SWIG_ConvertPtr(val,(void **) &k,
-                                    $descriptor(K *), 0) == -1) {
-                        $1 = 0;
-                    } else {
-                        if (CHECK(val)) {
-                            $1 = 1;
-                        } else if (SCHEME_PAIRP(val)) {
-                            val = scheme_car(val);
-                            if (CHECK(val))
-                                $1 = 1;
-                            else
-                                $1 = 0;
-                        } else {
-                            $1 = 0;
-                        }
-                    }
-                } else {
-                    $1 = 0;
-                }
-            } else {
-                // wrapped map?
-                std::map< K, T, C >* m;
-                if (SWIG_ConvertPtr($input,(void **) &m,
-                                $1_descriptor, 0) != -1)
-                    $1 = 1;
-                else
-                    $1 = 0;
-            }
-        }
-        %rename("length") size;
-        %rename("null?") empty;
-        %rename("clear!") clear;
-        %rename("ref") __getitem__;
-        %rename("set!") __setitem__;
-        %rename("delete!") __delitem__;
-        %rename("has-key?") has_key;
-      public:
-        typedef size_t size_type;
-        typedef ptrdiff_t difference_type;
-        typedef K key_type;
-        typedef T mapped_type;
-        typedef std::pair< const K, T > value_type;
-        typedef value_type* pointer;
-        typedef const value_type* const_pointer;
-        typedef value_type& reference;
-        typedef const value_type& const_reference;
-
-        map();
-        map(const map& other);
-        
-        unsigned int size() const;
-        bool empty() const;
-        void clear();
-        %extend {
-            T __getitem__(const K& key) throw (std::out_of_range) {
-                std::map< K, T, C >::iterator i = self->find(key);
-                if (i != self->end())
-                    return i->second;
-                else
-                    throw std::out_of_range("key not found");
-            }
-            void __setitem__(const K& key, T x) {
-                (*self)[key] = x;
-            }
-            void __delitem__(const K& key) throw (std::out_of_range) {
-                std::map< K, T, C >::iterator i = self->find(key);
-                if (i != self->end())
-                    self->erase(i);
-                else
-                    throw std::out_of_range("key not found");
-            }
-            bool has_key(const K& key) {
-                std::map< K, T, C >::iterator i = self->find(key);
-                return i != self->end();
-            }
-            Scheme_Object* keys() {
-                Scheme_Object* result = scheme_null;
-                for (std::map< K, T, C >::reverse_iterator i=self->rbegin(); 
-                                                      i!=self->rend(); ++i) {
-                    K* key = new K(i->first);
-                    Scheme_Object* k = SWIG_NewPointerObj(key,$descriptor(K *), 1);
-                    result = scheme_make_pair(k,result);
-                }
-                return result;
-            }
-        }
-    };
-    %enddef
-
-    %define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO,
-                                       T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO)
-    template<> class map< K, T, C > {
-        %typemap(in) map< K, T, C > (std::map< K, T, C >* m) {
-            if (SCHEME_NULLP($input)) {
-                $1 = std::map< K, T, C >();
-            } else if (SCHEME_PAIRP($input)) {
-                $1 = std::map< K, T, C >();
-                Scheme_Object* alist = $input;
-                while (!SCHEME_NULLP(alist)) {
-                    Scheme_Object *entry, *key, *val;
-                    entry = scheme_car(alist);
-                    if (!SCHEME_PAIRP(entry))
-                        SWIG_exception(SWIG_TypeError,"alist expected");
-                    key = scheme_car(entry);
-                    val = scheme_cdr(entry);
-                    if (!CHECK_K(key))
-                        SWIG_exception(SWIG_TypeError,
-                                           "map<" #K "," #T "," #C "> expected");
-                    if (!CHECK_T(val)) {
-                        if (!SCHEME_PAIRP(val))
-                            SWIG_exception(SWIG_TypeError,"alist expected");
-                        val = scheme_car(val);
-                        if (!CHECK_T(val))
-                            SWIG_exception(SWIG_TypeError,
-                                           "map<" #K "," #T "," #C "> expected");
-                    }
-                    (($1_type &)$1)[CONVERT_K_FROM(key)] = 
-                                               CONVERT_T_FROM(val);
-                    alist = scheme_cdr(alist);
-                }
-            } else {
-                $1 = *(($&1_type)
-                       SWIG_MustGetPtr($input,$&1_descriptor,$argnum, 0));
-            }
-        }
-        %typemap(in) const map< K, T, C >& (std::map< K, T, C > temp,
-                                      std::map< K, T, C >* m),
-                     const map< K, T, C >* (std::map< K, T, C > temp,
-                                      std::map< K, T, C >* m) {
-            if (SCHEME_NULLP($input)) {
-                temp = std::map< K, T, C >();
-                $1 = &temp;
-            } else if (SCHEME_PAIRP($input)) {
-                temp = std::map< K, T, C >();
-                $1 = &temp;
-                Scheme_Object* alist = $input;
-                while (!SCHEME_NULLP(alist)) {
-                    Scheme_Object *entry, *key, *val;
-                    entry = scheme_car(alist);
-                    if (!SCHEME_PAIRP(entry))
-                        SWIG_exception(SWIG_TypeError,"alist expected");
-                    key = scheme_car(entry);
-                    val = scheme_cdr(entry);
-                    if (!CHECK_K(key))
-                        SWIG_exception(SWIG_TypeError,
-                                           "map<" #K "," #T "," #C "> expected");
-                    if (!CHECK_T(val)) {
-                        if (!SCHEME_PAIRP(val))
-                            SWIG_exception(SWIG_TypeError,"alist expected");
-                        val = scheme_car(val);
-                        if (!CHECK_T(val))
-                            SWIG_exception(SWIG_TypeError,
-                                           "map<" #K "," #T "," #C "> expected");
-                    }
-                    temp[CONVERT_K_FROM(key)] = CONVERT_T_FROM(val);
-                    alist = scheme_cdr(alist);
-                }
-            } else {
-                $1 = ($1_ltype) SWIG_MustGetPtr($input,$1_descriptor,$argnum, 0);
-            }
-        }
-        %typemap(out) map< K, T, C > {
-            Scheme_Object* alist = scheme_null;
-            for (std::map< K, T, C >::reverse_iterator i=$1.rbegin(); 
-                                                  i!=$1.rend(); ++i) {
-                Scheme_Object* k = CONVERT_K_TO(i->first);
-                Scheme_Object* x = CONVERT_T_TO(i->second);
-                Scheme_Object* entry = scheme_make_pair(k,x);
-                alist = scheme_make_pair(entry,alist);
-            }
-            $result = alist;
-        }
-        %typecheck(SWIG_TYPECHECK_MAP) map< K, T, C > {
-            // native sequence?
-            if (SCHEME_NULLP($input)) {
-                /* an empty sequence can be of any type */
-                $1 = 1;
-            } else if (SCHEME_PAIRP($input)) {
-                // check the first element only
-                Scheme_Object* head = scheme_car($input);
-                if (SCHEME_PAIRP(head)) {
-                    Scheme_Object* key = scheme_car(head);
-                    Scheme_Object* val = scheme_cdr(head);
-                    if (!CHECK_K(key)) {
-                        $1 = 0;
-                    } else {
-                        if (CHECK_T(val)) {
-                            $1 = 1;
-                        } else if (SCHEME_PAIRP(val)) {
-                            val = scheme_car(val);
-                            if (CHECK_T(val))
-                                $1 = 1;
-                            else
-                                $1 = 0;
-                        } else {
-                            $1 = 0;
-                        }
-                    }
-                } else {
-                    $1 = 0;
-                }
-            } else {
-                // wrapped map?
-                std::map< K, T, C >* m;
-                if (SWIG_ConvertPtr($input,(void **) &m,
-                                $&1_descriptor, 0) != -1)
-                    $1 = 1;
-                else
-                    $1 = 0;
-            }
-        }
-        %typecheck(SWIG_TYPECHECK_MAP) const map< K, T, C >&,
-                                       const map< K, T, C >* {
-            // native sequence?
-            if (SCHEME_NULLP($input)) {
-                /* an empty sequence can be of any type */
-                $1 = 1;
-            } else if (SCHEME_PAIRP($input)) {
-                // check the first element only
-                Scheme_Object* head = scheme_car($input);
-                if (SCHEME_PAIRP(head)) {
-                    Scheme_Object* key = scheme_car(head);
-                    Scheme_Object* val = scheme_cdr(head);
-                    if (!CHECK_K(key)) {
-                        $1 = 0;
-                    } else {
-                        if (CHECK_T(val)) {
-                            $1 = 1;
-                        } else if (SCHEME_PAIRP(val)) {
-                            val = scheme_car(val);
-                            if (CHECK_T(val))
-                                $1 = 1;
-                            else
-                                $1 = 0;
-                        } else {
-                            $1 = 0;
-                        }
-                    }
-                } else {
-                    $1 = 0;
-                }
-            } else {
-                // wrapped map?
-                std::map< K, T, C >* m;
-                if (SWIG_ConvertPtr($input,(void **) &m,
-                                $1_descriptor, 0) != -1)
-                    $1 = 1;
-                else
-                    $1 = 0;
-            }
-        }
-        %rename("length") size;
-        %rename("null?") empty;
-        %rename("clear!") clear;
-        %rename("ref") __getitem__;
-        %rename("set!") __setitem__;
-        %rename("delete!") __delitem__;
-        %rename("has-key?") has_key;
-      public:
-        typedef size_t size_type;
-        typedef ptrdiff_t difference_type;
-        typedef K key_type;
-        typedef T mapped_type;
-        typedef std::pair< const K, T > value_type;
-        typedef value_type* pointer;
-        typedef const value_type* const_pointer;
-        typedef value_type& reference;
-        typedef const value_type& const_reference;
-
-        map();
-        map(const map& other);
-        
-        unsigned int size() const;
-        bool empty() const;
-        void clear();
-        %extend {
-            T __getitem__(K key) throw (std::out_of_range) {
-                std::map< K, T, C >::iterator i = self->find(key);
-                if (i != self->end())
-                    return i->second;
-                else
-                    throw std::out_of_range("key not found");
-            }
-            void __setitem__(K key, T x) {
-                (*self)[key] = x;
-            }
-            void __delitem__(K key) throw (std::out_of_range) {
-                std::map< K, T, C >::iterator i = self->find(key);
-                if (i != self->end())
-                    self->erase(i);
-                else
-                    throw std::out_of_range("key not found");
-            }
-            bool has_key(K key) {
-                std::map< K, T, C >::iterator i = self->find(key);
-                return i != self->end();
-            }
-            Scheme_Object* keys() {
-                Scheme_Object* result = scheme_null;
-                for (std::map< K, T, C >::reverse_iterator i=self->rbegin(); 
-                                                      i!=self->rend(); ++i) {
-                    Scheme_Object* k = CONVERT_K_TO(i->first);
-                    result = scheme_make_pair(k,result);
-                }
-                return result;
-            }
-        }
-    };
-    %enddef
-
-
-    specialize_std_map_on_key(bool,SCHEME_BOOLP,
-                              SCHEME_TRUEP,swig_make_boolean);
-    specialize_std_map_on_key(int,SCHEME_INTP,
-                              SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_key(short,SCHEME_INTP,
-                              SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_key(long,SCHEME_INTP,
-                              SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_key(unsigned int,SCHEME_INTP,
-                              SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_key(unsigned short,SCHEME_INTP,
-                              SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_key(unsigned long,SCHEME_INTP,
-                              SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_key(double,SCHEME_REALP,
-                              scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_key(float,SCHEME_REALP,
-                              scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_key(std::string,SCHEME_STRINGP,
-                              swig_scm_to_string,swig_make_string);
-
-    specialize_std_map_on_value(bool,SCHEME_BOOLP,
-                                SCHEME_TRUEP,swig_make_boolean);
-    specialize_std_map_on_value(int,SCHEME_INTP,
-                                SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_value(short,SCHEME_INTP,
-                                SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_value(long,SCHEME_INTP,
-                                SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_value(unsigned int,SCHEME_INTP,
-                                SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_value(unsigned short,SCHEME_INTP,
-                                SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_value(unsigned long,SCHEME_INTP,
-                                SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_value(double,SCHEME_REALP,
-                                scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_value(float,SCHEME_REALP,
-                                scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_value(std::string,SCHEME_STRINGP,
-                                swig_scm_to_string,swig_make_string);
-
-    specialize_std_map_on_both(bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean,
-                               bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean);
-    specialize_std_map_on_both(bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean,
-                               int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean,
-                               short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean,
-                               long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean,
-                               unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean,
-                               unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean,
-                               unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean,
-                               double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean,
-                               float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean,
-                               std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string);
-    specialize_std_map_on_both(int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean);
-    specialize_std_map_on_both(int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string);
-    specialize_std_map_on_both(short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean);
-    specialize_std_map_on_both(short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string);
-    specialize_std_map_on_both(long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean);
-    specialize_std_map_on_both(long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string);
-    specialize_std_map_on_both(unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean);
-    specialize_std_map_on_both(unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string);
-    specialize_std_map_on_both(unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean);
-    specialize_std_map_on_both(unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string);
-    specialize_std_map_on_both(unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean);
-    specialize_std_map_on_both(unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value,
-                               std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string);
-    specialize_std_map_on_both(double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean);
-    specialize_std_map_on_both(double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string);
-    specialize_std_map_on_both(float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean);
-    specialize_std_map_on_both(float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double,
-                               std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string);
-    specialize_std_map_on_both(std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string,
-                               bool,SCHEME_BOOLP,
-                               SCHEME_TRUEP,swig_make_boolean);
-    specialize_std_map_on_both(std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string,
-                               int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string,
-                               short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string,
-                               long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string,
-                               unsigned int,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string,
-                               unsigned short,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string,
-                               unsigned long,SCHEME_INTP,
-                               SCHEME_INT_VAL,scheme_make_integer_value);
-    specialize_std_map_on_both(std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string,
-                               double,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string,
-                               float,SCHEME_REALP,
-                               scheme_real_to_double,scheme_make_double);
-    specialize_std_map_on_both(std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string,
-                               std::string,SCHEME_STRINGP,
-                               swig_scm_to_string,swig_make_string);
 }
diff --git a/Lib/mzscheme/std_string.i b/Lib/mzscheme/std_string.i
index b19e856..70673ea 100644
--- a/Lib/mzscheme/std_string.i
+++ b/Lib/mzscheme/std_string.i
@@ -52,6 +52,13 @@
         $result = scheme_make_string($1->c_str());
     }
 
+    %typemap(throws) string {
+      scheme_signal_error("%s: %s", FUNC_NAME, $1.c_str());
+    }
+
+    %typemap(throws) const string & {
+      scheme_signal_error("%s: %s", FUNC_NAME, $1.c_str());
+    }
 }
 
 
diff --git a/Lib/mzscheme/std_unique_ptr.i b/Lib/mzscheme/std_unique_ptr.i
new file mode 100644
index 0000000..53cf466
--- /dev/null
+++ b/Lib/mzscheme/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      scheme_signal_error(FUNC_NAME ": cannot release ownership as memory is not owned for argument $argnum of type 'TYPE *'");
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+  %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class unique_ptr {};
+}
diff --git a/Lib/mzscheme/std_vector.i b/Lib/mzscheme/std_vector.i
index 0ef5edb..ae886b7 100644
--- a/Lib/mzscheme/std_vector.i
+++ b/Lib/mzscheme/std_vector.i
@@ -421,6 +421,9 @@
         }
     };
     %enddef
+    %typemap(throws) std::out_of_range {
+        scheme_signal_error("%s: %s", FUNC_NAME, $1.what());
+    }
 
     specialize_std_vector(bool,SCHEME_BOOLP,SCHEME_TRUEP,\
                           swig_make_boolean);
diff --git a/Lib/mzscheme/swigmove.i b/Lib/mzscheme/swigmove.i
new file mode 100644
index 0000000..bbfcdcb
--- /dev/null
+++ b/Lib/mzscheme/swigmove.i
@@ -0,0 +1,19 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in, noblock=1) SWIGTYPE MOVE (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $&1_descriptor, SWIG_POINTER_RELEASE);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      scheme_signal_error(FUNC_NAME ": cannot release ownership as memory is not owned for argument $argnum of type '$1_type'");
+    } else {
+      %argument_fail(res, "$1_type", $symname, $argnum);
+    }
+  }
+  if (argp == NULL) scheme_signal_error(FUNC_NAME ": swig-type-error (null reference)");
+  SwigValueWrapper< $1_ltype >::reset($1, ($&1_type)argp);
+}
diff --git a/Lib/mzscheme/typemaps.i b/Lib/mzscheme/typemaps.i
index 09bda2c..7ceffb2 100644
--- a/Lib/mzscheme/typemaps.i
+++ b/Lib/mzscheme/typemaps.i
@@ -2,6 +2,12 @@
  * typemaps.i
  * ----------------------------------------------------------------------------- */
 
+#define %set_output(obj)                  $result = obj
+#define %set_varoutput(obj)               $result = obj
+#define %argument_fail(code, type, name, argn)	scheme_wrong_type(FUNC_NAME, type, argn, argc, argv)
+#define %as_voidptr(ptr)		(void*)(ptr)
+
+
 /* The MzScheme module handles all types uniformly via typemaps. Here
    are the definitions.  */
 
@@ -66,9 +72,23 @@
 
 #ifdef __cplusplus
 
-%typemap(in) SWIGTYPE &, SWIGTYPE && { 
+%typemap(in) SWIGTYPE & {
   $1 = ($ltype) SWIG_MustGetPtr($input, $descriptor, $argnum, 0);
-  if ($1 == NULL) scheme_signal_error("swig-type-error (null reference)");
+  if ($1 == NULL) scheme_signal_error(FUNC_NAME ": swig-type-error (null reference)");
+}
+
+%typemap(in, noblock=1, fragment="<memory>") SWIGTYPE && (void *argp = 0, int res = 0, std::unique_ptr<$*1_ltype> rvrdeleter) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor, SWIG_POINTER_RELEASE);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      scheme_signal_error(FUNC_NAME ": cannot release ownership as memory is not owned for argument $argnum of type '$1_type'");
+    } else {
+      %argument_fail(res, "$1_type", $symname, $argnum);
+    }
+  }
+  if (argp == NULL) scheme_signal_error(FUNC_NAME ": swig-type-error (null reference)");
+  $1 = ($1_ltype)argp;
+  rvrdeleter.reset($1);
 }
 
 %typemap(out) SWIGTYPE &, SWIGTYPE && {
@@ -105,8 +125,8 @@
   $1 = ($1_type) SWIG_convert_int($input);
 }
 
-%typemap(out) enum SWIGTYPE "$result = scheme_make_integer_value($1);";
-%typemap(varout) enum SWIGTYPE "$result = scheme_make_integer_value($1);";
+%typemap(out) enum SWIGTYPE "$result = scheme_make_integer_value($1);"
+%typemap(varout) enum SWIGTYPE "$result = scheme_make_integer_value($1);"
 
 
 /* Pass-by-value */
@@ -127,7 +147,7 @@
 #ifdef __cplusplus
 {
   $&1_ltype resultptr;
-  resultptr = new $1_ltype(($1_ltype &) $1);
+  resultptr = new $1_ltype($1);
   $result =  SWIG_NewPointerObj (resultptr, $&1_descriptor, 1);
 } 
 #else
@@ -143,7 +163,7 @@
 #ifdef __cplusplus
 {
   $&1_ltype resultptr;
-  resultptr = new $1_ltype(($1_ltype &) $1);
+  resultptr = new $1_ltype($1);
   $result =  SWIG_NewPointerObj (resultptr, $&1_descriptor, 0);
 } 
 #else
@@ -187,8 +207,6 @@
     s = C_TO_MZ(*$1);
     SWIG_APPEND_VALUE(s);
 }
-%typemap(in) C_NAME *BOTH = C_NAME *INPUT;
-%typemap(argout) C_NAME *BOTH = C_NAME *OUTPUT;
 %typemap(in) C_NAME *INOUT = C_NAME *INPUT;
 %typemap(argout) C_NAME *INOUT = C_NAME *OUTPUT;
 %enddef
@@ -270,14 +288,18 @@
 REF_MAP(double, SCHEME_REALP, scheme_real_to_double,
 	   scheme_make_double, real);
 
+%typemap(throws) char * {
+  scheme_signal_error("%s: %s", FUNC_NAME, $1);
+}
+
 /* Void */
 
-%typemap(out) void "$result = scheme_void;";
+%typemap(out) void "$result = scheme_void;"
 
 /* Pass through Scheme_Object * */
 
-%typemap (in) Scheme_Object * "$1=$input;";
-%typemap (out) Scheme_Object * "$result=$1;";
+%typemap (in) Scheme_Object * "$1=$input;"
+%typemap (out) Scheme_Object * "$result=$1;"
 %typecheck(SWIG_TYPECHECK_POINTER) Scheme_Object * "$1=1;";
 
 
@@ -291,7 +313,6 @@
 //    $2 = ($2_ltype) temp;
 //}
 
-
 /* ------------------------------------------------------------
  * Typechecking rules
  * ------------------------------------------------------------ */
diff --git a/Lib/ocaml/carray.i b/Lib/ocaml/carray.i
index 5e74c3d..71631aa 100644
--- a/Lib/ocaml/carray.i
+++ b/Lib/ocaml/carray.i
@@ -77,7 +77,7 @@
 
 %typemap(out) SWIGTYPE [] {
     int i;
-    CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr");
+    const value *fromval = caml_named_value("create_$ntype_from_ptr");
     $result = caml_array_new($1_dim0);
 
     for( i = 0; i < $1_dim0; i++ ) {
diff --git a/Lib/ocaml/cstring.i b/Lib/ocaml/cstring.i
index f1190ad..3f680a2 100644
--- a/Lib/ocaml/cstring.i
+++ b/Lib/ocaml/cstring.i
@@ -25,13 +25,13 @@
  *
  *     %cstring_bounded_output(char *outx, 512);
  *     void foo(char *outx) {
- *         sprintf(outx,"blah blah\n");
+ *         strcpy(outx,"blah blah\n");
  *     }
  *
  */
 
 %define %cstring_bounded_output(TYPEMAP,MAX)
-%typemap(ignore) TYPEMAP(char temp[MAX+1]) {
+%typemap(in,numinputs=0) TYPEMAP(char temp[MAX+1]) {
     $1 = ($1_ltype) temp;
 }
 %typemap(argout) TYPEMAP {
@@ -54,7 +54,7 @@
  */
 
 %define %cstring_chunk_output(TYPEMAP,SIZE)
-%typemap(ignore) TYPEMAP(char temp[SIZE]) {
+%typemap(in,numinputs=0) TYPEMAP(char temp[SIZE]) {
     $1 = ($1_ltype) temp;
 }
 %typemap(argout) TYPEMAP {
@@ -144,7 +144,7 @@
  *
  *     %cstring_output_maxsize(char *outx, int max) {
  *     void foo(char *outx, int max) {
- *         sprintf(outx,"blah blah\n");
+ *         strcpy(outx,"blah blah\n");
  *     }
  */
 
@@ -175,7 +175,7 @@
  *
  *     %cstring_output_maxsize(char *outx, int *max) {
  *     void foo(char *outx, int *max) {
- *         sprintf(outx,"blah blah\n");
+ *         strcpy(outx,"blah blah\n");
  *         *max = strlen(outx);  
  *     }
  */
@@ -213,12 +213,12 @@
  *     %cstring_output_allocated(char **outx, free($1));
  *     void foo(char **outx) {
  *         *outx = (char *) malloc(512);
- *         sprintf(outx,"blah blah\n");
+ *         strcpy(outx,"blah blah\n");
  *     }
  */
 
 %define %cstring_output_allocate(TYPEMAP, RELEASE)
-%typemap(ignore) TYPEMAP($*1_ltype temp = 0) {
+%typemap(in,numinputs=0) TYPEMAP($*1_ltype temp = 0) {
    $1 = &temp;
 }
 
@@ -241,13 +241,13 @@
  *     %cstring_output_allocated(char **outx, int *sz, free($1));
  *     void foo(char **outx, int *sz) {
  *         *outx = (char *) malloc(512);
- *         sprintf(outx,"blah blah\n");
+ *         strcpy(outx,"blah blah\n");
  *         *sz = strlen(outx);
  *     }
  */
 
 %define %cstring_output_allocate_size(TYPEMAP, SIZE, RELEASE)
-%typemap(ignore) (TYPEMAP, SIZE) ($*1_ltype temp = 0, $*2_ltype tempn) {
+%typemap(in,numinputs=0) (TYPEMAP, SIZE) ($*1_ltype temp = 0, $*2_ltype tempn) {
    $1 = &temp;
    $2 = &tempn;
 }
diff --git a/Lib/ocaml/director.swg b/Lib/ocaml/director.swg
index eb91aaf..4cdb0c6 100644
--- a/Lib/ocaml/director.swg
+++ b/Lib/ocaml/director.swg
@@ -67,13 +67,13 @@
   class Director {
     private:
       /* pointer to the wrapped ocaml object */
-      CAML_VALUE swig_self;
+      value swig_self;
       /* flag indicating whether the object is owned by ocaml or c++ */
       mutable bool swig_disown_flag;
 
     public:
       /* wrap a ocaml object. */
-      Director(CAML_VALUE self) : swig_self(self), swig_disown_flag(false) {
+      Director(value self) : swig_self(self), swig_disown_flag(false) {
         caml_register_global_root(&swig_self);
       }
 
@@ -85,7 +85,7 @@
       }
 
       /* return a pointer to the wrapped ocaml object */
-      CAML_VALUE swig_get_self() const {
+      value swig_get_self() const {
 	  return swig_self;
       }
 
diff --git a/Lib/ocaml/ocaml.swg b/Lib/ocaml/ocaml.swg
index ac496bd..b3ccab5 100644
--- a/Lib/ocaml/ocaml.swg
+++ b/Lib/ocaml/ocaml.swg
@@ -40,9 +40,10 @@
     $1 = ($ltype) caml_ptr_val($input,$1_descriptor);
 }
 
-%typemap(in) SWIGTYPE && {
+%typemap(in, fragment="<memory>") SWIGTYPE && (std::unique_ptr<$*1_ltype> rvrdeleter) %{
     $1 = ($ltype) caml_ptr_val($input,$1_descriptor);
-}
+    rvrdeleter.reset($1);
+%}
 
 %typemap(varin) SWIGTYPE & {
     $1 = *(($ltype) caml_ptr_val($input,$1_descriptor));
@@ -62,7 +63,7 @@
 
 #if 0
 %typemap(argout) SWIGTYPE & {
-    CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr");
+    const value *fromval = caml_named_value("create_$ntype_from_ptr");
     if( fromval ) {
 	swig_result =
 	    caml_list_append(swig_result,
@@ -75,7 +76,7 @@
     }
 }
 %typemap(argout) SWIGTYPE && {
-    CAML_VALUE *fromval = caml_named_value("create_$ntype_from_ptr");
+    const value *fromval = caml_named_value("create_$ntype_from_ptr");
     if( fromval ) {
 	swig_result =
 	    caml_list_append(swig_result,
@@ -93,10 +94,14 @@
     $1 = *(($&1_ltype) caml_ptr_val($input,$&1_descriptor)) ;
 }
 
+%typemap(varout) SWIGTYPE {
+    $result = SWIG_Ocaml_ptr_to_val("create_$ntype_from_ptr", (void *)&$1, $&1_descriptor);
+}
+
 #ifdef __cplusplus
 
 %typemap(out) SWIGTYPE {
-    $&1_ltype temp = new $ltype((const $1_ltype &) $1);
+    $&1_ltype temp = new $1_ltype($1);
     $result = SWIG_Ocaml_ptr_to_val("create_$ntype_from_ptr", (void *)temp, $&1_descriptor);
 }
 
@@ -110,8 +115,12 @@
 
 #endif
 
+%typemap(varout) SWIGTYPE * {
+    $result = SWIG_Ocaml_ptr_to_val("create_$ntype_from_ptr", (void *)$1, $1_descriptor);
+}
+
 %typemap(directorin) SWIGTYPE {
-    $&ltype temp = new $ltype((const $ltype &)$1);
+    $&ltype temp = new $1_ltype(SWIG_STD_MOVE($1));
     swig_result = SWIG_Ocaml_ptr_to_val("create_$ltype_from_ptr", (void *)temp, $&1_descriptor);
     args = caml_list_append(args, swig_result);
 }
@@ -180,12 +189,12 @@
 
 /* Void */
 
-%typemap(out) void "$result = Val_unit;";
+%typemap(out) void "$result = Val_unit;"
 
 /* Pass through value */
 
-%typemap (in) CAML_VALUE "$1=$input;";
-%typemap (out) CAML_VALUE "$result=$1;";
+%typemap (in) value "$1=$input;"
+%typemap (out) value "$result=$1;"
 
 #if 0
 %include <carray.i>
@@ -302,7 +311,7 @@
 
 /* Array reference typemaps */
 %apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) }
-%apply SWIGTYPE && { SWIGTYPE ((&)[ANY]) }
+%apply SWIGTYPE && { SWIGTYPE ((&&)[ANY]) }
 
 /* const pointers */
 %apply SWIGTYPE * { SWIGTYPE *const }
diff --git a/Lib/ocaml/ocamlrun.swg b/Lib/ocaml/ocamlrun.swg
index 3d552cc..95350ea 100644
--- a/Lib/ocaml/ocamlrun.swg
+++ b/Lib/ocaml/ocamlrun.swg
@@ -91,20 +91,20 @@
 	}
     }
 
-    SWIGINTERN void caml_print_list( CAML_VALUE v );
+    SWIGINTERN void caml_print_list( value v );
 
-    SWIGINTERN void caml_print_val( CAML_VALUE v ) {
-	switch( SWIG_Tag_val(v) ) {
+    SWIGINTERN void caml_print_val( value v ) {
+	switch( Tag_val(v) ) {
 	case C_bool:
-	    if( Bool_val(SWIG_Field(v,0)) ) fprintf( stderr, "true " );
+	    if( Bool_val(Field(v,0)) ) fprintf( stderr, "true " );
 	    else fprintf( stderr, "false " );
 	    break;
 	case C_char:
 	case C_uchar:
 	    fprintf( stderr, "'%c' (\\%03d) ", 
-		     (Int_val(SWIG_Field(v,0)) >= ' ' &&
-		      Int_val(SWIG_Field(v,0)) < 127) ? Int_val(SWIG_Field(v,0)) : '.',
-		     Int_val(SWIG_Field(v,0)) );
+		     (Int_val(Field(v,0)) >= ' ' &&
+		      Int_val(Field(v,0)) < 127) ? Int_val(Field(v,0)) : '.',
+		     Int_val(Field(v,0)) );
 	    break;
 	case C_short:
 	case C_ushort:
@@ -127,7 +127,7 @@
 	case C_ptr:
 	{
 	    void *vout = 0;
-	    swig_type_info *ty = (swig_type_info *)(long)SWIG_Int64_val(SWIG_Field(v,1));
+	    swig_type_info *ty = (swig_type_info *)(long)Int64_val(Field(v,1));
 	    caml_ptr_val_internal(v,&vout,0);
 	    fprintf( stderr, "PTR(%p,%s) ", 
 		     vout,
@@ -137,15 +137,15 @@
 	case C_array:
 	{
 	    unsigned int i;
-	    for( i = 0; i < Wosize_val( SWIG_Field(v,0) ); i++ ) 
-		caml_print_val( SWIG_Field(SWIG_Field(v,0),i) );
+	    for( i = 0; i < Wosize_val( Field(v,0) ); i++ )
+		caml_print_val( Field(Field(v,0),i) );
 	}
 	break;
 	case C_list:
-	    caml_print_list( SWIG_Field(v,0) );
+	    caml_print_list( Field(v,0) );
 	    break;
 	case C_obj:
-	    fprintf( stderr, "OBJ(%p) ", (void *)SWIG_Field(v,0) );
+	    fprintf( stderr, "OBJ(%p) ", (void *)Field(v,0) );
 	    break;
 	case C_string:
 	{
@@ -157,30 +157,30 @@
 	}
     }
 
-    SWIGINTERN void caml_print_list( CAML_VALUE v ) {
+    SWIGINTERN void caml_print_list( value v ) {
 	CAMLparam1(v);
 	while( v && Is_block(v) ) {
 	    fprintf( stderr, "[ " );
-	    caml_print_val( SWIG_Field(v,0) );
+	    caml_print_val( Field(v,0) );
 	    fprintf( stderr, "]\n" );
-	    v = SWIG_Field(v,1);
+	    v = Field(v,1);
 	}
 	CAMLreturn0;
     }
 
-    SWIGINTERN CAML_VALUE caml_list_nth( CAML_VALUE lst, int n ) {
+    SWIGINTERN value caml_list_nth( value lst, int n ) {
 	CAMLparam1(lst);
 	int i = 0;
 	while( i < n && lst && Is_block(lst) ) {
-	    i++; lst = SWIG_Field(lst,1);
+	    i++; lst = Field(lst,1);
 	}
 	if( lst == Val_unit ) CAMLreturn(Val_unit);
-	else CAMLreturn(SWIG_Field(lst,0));
+	else CAMLreturn(Field(lst,0));
     }
     
-    SWIGINTERN CAML_VALUE caml_list_append( CAML_VALUE lst, CAML_VALUE elt ) {
+    SWIGINTERN value caml_list_append( value lst, value elt ) {
 	CAMLparam2(lst,elt);
-	SWIG_CAMLlocal3(v,vt,lh);
+	CAMLlocal3(v,vt,lh);
 	lh = Val_unit;
 	v = Val_unit;
 
@@ -190,224 +190,224 @@
 	while( lst && Is_block(lst) ) {
 	    if( v && v != Val_unit ) {
 		vt = caml_alloc_tuple(2);
-		SWIG_Store_field(v,1,vt);
+		Store_field(v,1,vt);
 		v = vt;
 	    } else {
 		v = lh = caml_alloc_tuple(2);
 	    }
-	    SWIG_Store_field(v,0,SWIG_Field(lst,0));
-	    lst = SWIG_Field(lst,1);
+	    Store_field(v,0,Field(lst,0));
+	    lst = Field(lst,1);
 	}
 
 	if( v && Is_block(v) ) {
 	    vt = caml_alloc_tuple(2);
-	    SWIG_Store_field(v,1,vt);
+	    Store_field(v,1,vt);
 	    v = vt;
 	} else {
 	    v = lh = caml_alloc_tuple(2);
 	}
-	SWIG_Store_field(v,0,elt);
-	SWIG_Store_field(v,1,Val_unit);
+	Store_field(v,0,elt);
+	Store_field(v,1,Val_unit);
 
 	CAMLreturn(lh);
     }
 
-    SWIGINTERN int caml_list_length( CAML_VALUE lst ) {
+    SWIGINTERN int caml_list_length( value lst ) {
 	CAMLparam1(lst);
 	int i = 0;
-	while( lst && Is_block(lst) ) { i++; lst = SWIG_Field(lst,1); }
+	while( lst && Is_block(lst) ) { i++; lst = Field(lst,1); }
 	CAMLreturn(i);
     }
 
-    SWIGINTERN void caml_array_set( CAML_VALUE arr, int n, CAML_VALUE item ) {
+    SWIGINTERN void caml_array_set( value arr, int n, value item ) {
 	CAMLparam2(arr,item);
-	SWIG_Store_field(SWIG_Field(arr,0),n,item);
+	Store_field(Field(arr,0),n,item);
 	CAMLreturn0;
     }
 
-    SWIGINTERN value caml_array_nth( CAML_VALUE arr, int n ) {
+    SWIGINTERN value caml_array_nth( value arr, int n ) {
 	CAMLparam1(arr);
-	if( SWIG_Tag_val(arr) == C_array )
-	    CAMLreturn(SWIG_Field(SWIG_Field(arr,0),n));
-	else if( SWIG_Tag_val(arr) == C_list )
+	if( Tag_val(arr) == C_array )
+	    CAMLreturn(Field(Field(arr,0),n));
+	else if( Tag_val(arr) == C_list )
 	    CAMLreturn(caml_list_nth(arr,0));
 	else
 	    caml_failwith("Need array or list");
     }
 
-    SWIGINTERN int caml_array_len( CAML_VALUE arr ) {
+    SWIGINTERN int caml_array_len( value arr ) {
 	CAMLparam1(arr);
-	if( SWIG_Tag_val(arr) == C_array )
-	    CAMLreturn(Wosize_val(SWIG_Field(arr,0)));
-	else if( SWIG_Tag_val(arr) == C_list )
+	if( Tag_val(arr) == C_array )
+	    CAMLreturn(Wosize_val(Field(arr,0)));
+	else if( Tag_val(arr) == C_list )
 	    CAMLreturn(caml_list_length(arr));
 	else
 	    caml_failwith("Need array or list");
     }
 
-    SWIGINTERN CAML_VALUE caml_swig_alloc(int x,int y) {
+    SWIGINTERN value caml_swig_alloc(int x,int y) {
 	return caml_alloc(x,y);
     }
 
     SWIGINTERN value caml_array_new( int n ) {
 	CAMLparam0();
-	SWIG_CAMLlocal1(vv);
+	CAMLlocal1(vv);
 	vv = caml_swig_alloc(1,C_array);
-	SWIG_Store_field(vv,0,caml_alloc_tuple(n));
+	Store_field(vv,0,caml_alloc_tuple(n));
 	CAMLreturn(vv);
     }
     
-    SWIGINTERN CAML_VALUE caml_val_bool( int b ) {
+    SWIGINTERN value caml_val_bool( int b ) {
 	CAMLparam0();
-	SWIG_CAMLlocal1(bv);
+	CAMLlocal1(bv);
 	bv = caml_swig_alloc(1,C_bool);
-	SWIG_Store_field(bv,0,Val_bool(b));
+	Store_field(bv,0,Val_bool(b));
 	CAMLreturn(bv);
     }
 
-    SWIGINTERN CAML_VALUE caml_val_char( char c ) {
+    SWIGINTERN value caml_val_char( char c ) {
 	CAMLparam0();
-	SWIG_CAMLlocal1(cv);
+	CAMLlocal1(cv);
 	cv = caml_swig_alloc(1,C_char);
-	SWIG_Store_field(cv,0,Val_int(c));
+	Store_field(cv,0,Val_int(c));
 	CAMLreturn(cv);
     }
 
-    SWIGINTERN CAML_VALUE caml_val_uchar( unsigned char uc ) {
+    SWIGINTERN value caml_val_uchar( unsigned char uc ) {
 	CAMLparam0();
-	SWIG_CAMLlocal1(ucv);
+	CAMLlocal1(ucv);
 	ucv = caml_swig_alloc(1,C_uchar);
-	SWIG_Store_field(ucv,0,Val_int(uc));
+	Store_field(ucv,0,Val_int(uc));
 	CAMLreturn(ucv);
     }
 
-    SWIGINTERN CAML_VALUE caml_val_short( short s ) {
+    SWIGINTERN value caml_val_short( short s ) {
 	CAMLparam0();
-	SWIG_CAMLlocal1(sv);
+	CAMLlocal1(sv);
 	sv = caml_swig_alloc(1,C_short);
-	SWIG_Store_field(sv,0,Val_int(s));
+	Store_field(sv,0,Val_int(s));
 	CAMLreturn(sv);
     }
 
-    SWIGINTERN CAML_VALUE caml_val_ushort( unsigned short us ) {
+    SWIGINTERN value caml_val_ushort( unsigned short us ) {
 	CAMLparam0();
-	SWIG_CAMLlocal1(usv);
+	CAMLlocal1(usv);
 	usv = caml_swig_alloc(1,C_ushort);
-	SWIG_Store_field(usv,0,Val_int(us));
+	Store_field(usv,0,Val_int(us));
 	CAMLreturn(usv);
     }
 
-    SWIGINTERN CAML_VALUE caml_val_int( int i ) {
+    SWIGINTERN value caml_val_int( int i ) {
 	CAMLparam0();
-	SWIG_CAMLlocal1(iv);
+	CAMLlocal1(iv);
 	iv = caml_swig_alloc(1,C_int);
-	SWIG_Store_field(iv,0,Val_int(i));
+	Store_field(iv,0,Val_int(i));
 	CAMLreturn(iv);
     }
 
-    SWIGINTERN CAML_VALUE caml_val_uint( unsigned int ui ) {
+    SWIGINTERN value caml_val_uint( unsigned int ui ) {
 	CAMLparam0();
-	SWIG_CAMLlocal1(uiv);
+	CAMLlocal1(uiv);
 	uiv = caml_swig_alloc(1,C_int);
-	SWIG_Store_field(uiv,0,Val_int(ui));
+	Store_field(uiv,0,Val_int(ui));
 	CAMLreturn(uiv);
     }
 
-    SWIGINTERN CAML_VALUE caml_val_long( long l ) {
+    SWIGINTERN value caml_val_long( long l ) {
 	CAMLparam0();
-	SWIG_CAMLlocal1(lv);
+	CAMLlocal1(lv);
 	lv = caml_swig_alloc(1,C_int64);
-	SWIG_Store_field(lv,0,caml_copy_int64(l));
+	Store_field(lv,0,caml_copy_int64(l));
 	CAMLreturn(lv);
     }
 
-    SWIGINTERN CAML_VALUE caml_val_ulong( unsigned long ul ) {
+    SWIGINTERN value caml_val_ulong( unsigned long ul ) {
 	CAMLparam0();
-	SWIG_CAMLlocal1(ulv);
+	CAMLlocal1(ulv);
 	ulv = caml_swig_alloc(1,C_int64);
-	SWIG_Store_field(ulv,0,caml_copy_int64(ul));
+	Store_field(ulv,0,caml_copy_int64(ul));
 	CAMLreturn(ulv);
     }
 
-    SWIGINTERN CAML_VALUE caml_val_float( float f ) {
+    SWIGINTERN value caml_val_float( float f ) {
 	CAMLparam0();
-	SWIG_CAMLlocal1(fv);
+	CAMLlocal1(fv);
 	fv = caml_swig_alloc(1,C_float);
-	SWIG_Store_field(fv,0,caml_copy_double((double)f));
+	Store_field(fv,0,caml_copy_double((double)f));
 	CAMLreturn(fv);
     }
 
-    SWIGINTERN CAML_VALUE caml_val_double( double d ) {
+    SWIGINTERN value caml_val_double( double d ) {
 	CAMLparam0();
-	SWIG_CAMLlocal1(fv);
+	CAMLlocal1(fv);
 	fv = caml_swig_alloc(1,C_double);
-	SWIG_Store_field(fv,0,caml_copy_double(d));
+	Store_field(fv,0,caml_copy_double(d));
 	CAMLreturn(fv);
     }
 
-    SWIGINTERN CAML_VALUE caml_val_ptr( void *p, swig_type_info *info ) {
+    SWIGINTERN value caml_val_ptr( void *p, swig_type_info *info ) {
 	CAMLparam0();
-	SWIG_CAMLlocal1(vv);
+	CAMLlocal1(vv);
 	vv = caml_swig_alloc(2,C_ptr);
-	SWIG_Store_field(vv,0,caml_copy_int64((long)p));
-	SWIG_Store_field(vv,1,caml_copy_int64((long)info));
+	Store_field(vv,0,caml_copy_int64((long)p));
+	Store_field(vv,1,caml_copy_int64((long)info));
 	CAMLreturn(vv);
     }
 
-    SWIGINTERN CAML_VALUE caml_val_string( const char *p ) {
+    SWIGINTERN value caml_val_string( const char *p ) {
 	CAMLparam0();
-	SWIG_CAMLlocal1(vv);
+	CAMLlocal1(vv);
 	if( !p ) CAMLreturn(caml_val_ptr( (void *)p, 0 ));
 	vv = caml_swig_alloc(1,C_string);
-	SWIG_Store_field(vv,0,caml_copy_string(p));
+	Store_field(vv,0,caml_copy_string(p));
 	CAMLreturn(vv);
     }
 
-    SWIGINTERN CAML_VALUE caml_val_string_len( const char *p, int len ) {
+    SWIGINTERN value caml_val_string_len( const char *p, int len ) {
 	CAMLparam0();
-	SWIG_CAMLlocal1(vv);
+	CAMLlocal1(vv);
 	if( !p || len < 0 ) CAMLreturn(caml_val_ptr( (void *)p, 0 ));
 	vv = caml_swig_alloc(1,C_string);
-	SWIG_Store_field(vv,0,caml_alloc_string(len));
-	memcpy(String_val(SWIG_Field(vv,0)),p,len);
+	Store_field(vv,0,caml_alloc_string(len));
+	memcpy(Bp_val(Field(vv,0)),p,len);
 	CAMLreturn(vv);
     }
 
     #define caml_val_obj(v, name) caml_val_obj_helper(v, SWIG_TypeQuery((name)), name)
-    SWIGINTERN CAML_VALUE caml_val_obj_helper( void *v, swig_type_info *type, char *name) {
+    SWIGINTERN value caml_val_obj_helper( void *v, swig_type_info *type, char *name) {
 	CAMLparam0();
 	CAMLreturn(caml_callback2(*caml_named_value("caml_create_object_fn"),
 			     caml_val_ptr(v,type),
 			     caml_copy_string(name)));
     }
 
-    SWIGINTERN long caml_long_val_full( CAML_VALUE v, const char *name ) {
+    SWIGINTERN long caml_long_val_full( value v, const char *name ) {
 	CAMLparam1(v);
 	if( !Is_block(v) ) return 0;
 
-	switch( SWIG_Tag_val(v) ) {
+	switch( Tag_val(v) ) {
 	case C_bool:
 	case C_char:
 	case C_uchar:
 	case C_short:
 	case C_ushort:
 	case C_int:
-	    CAMLreturn(Int_val(SWIG_Field(v,0)));
+	    CAMLreturn(Int_val(Field(v,0)));
 	case C_uint:
 	case C_int32:
-	    CAMLreturn(Int32_val(SWIG_Field(v,0)));
+	    CAMLreturn(Int32_val(Field(v,0)));
 	case C_int64:
-	    CAMLreturn((long)SWIG_Int64_val(SWIG_Field(v,0)));
+	    CAMLreturn((long)Int64_val(Field(v,0)));
 	case C_float:
 	case C_double:
-	    CAMLreturn((long)Double_val(SWIG_Field(v,0)));
+	    CAMLreturn((long)Double_val(Field(v,0)));
 	case C_string:
-	    CAMLreturn((long)String_val(SWIG_Field(v,0)));
+	    CAMLreturn((long)String_val(Field(v,0)));
 	case C_ptr:
-	    CAMLreturn((long)SWIG_Int64_val(SWIG_Field(SWIG_Field(v,0),0)));
+	    CAMLreturn((long)Int64_val(Field(Field(v,0),0)));
 	case C_enum: {
-	    SWIG_CAMLlocal1(ret);
-	    CAML_VALUE *enum_to_int = caml_named_value(SWIG_MODULE "_enum_to_int");
+	    CAMLlocal1(ret);
+	    const value *enum_to_int = caml_named_value(SWIG_MODULE "_enum_to_int");
 	    if( !name ) caml_failwith( "Not an enum conversion" );
 	    ret = caml_callback2(*enum_to_int,*caml_named_value(name),v);
 	    CAMLreturn(caml_long_val(ret));
@@ -417,100 +417,100 @@
 	}
     }
 
-    SWIGINTERN long caml_long_val( CAML_VALUE v ) {
+    SWIGINTERN long caml_long_val( value v ) {
 	return caml_long_val_full(v,0);
     }
 
-    SWIGINTERN double caml_double_val( CAML_VALUE v ) {
+    SWIGINTERN double caml_double_val( value v ) {
 	CAMLparam1(v);
 	if( !Is_block(v) ) return 0.0;
-	switch( SWIG_Tag_val(v) ) {
+	switch( Tag_val(v) ) {
 	case C_bool:
 	case C_char:
 	case C_uchar:
 	case C_short:
 	case C_ushort:
 	case C_int:
-	    CAMLreturn_type(Int_val(SWIG_Field(v,0)));
+	    CAMLreturnT(double, Int_val(Field(v,0)));
 	case C_uint:
 	case C_int32:
-	    CAMLreturn_type(Int32_val(SWIG_Field(v,0)));
+	    CAMLreturnT(double, Int32_val(Field(v,0)));
 	case C_int64:
-	    CAMLreturn_type(SWIG_Int64_val(SWIG_Field(v,0)));
+	    CAMLreturnT(double, Int64_val(Field(v,0)));
 	case C_float:
 	case C_double:
-	    CAMLreturn_type(Double_val(SWIG_Field(v,0)));
+	    CAMLreturnT(double, Double_val(Field(v,0)));
 	default:
-	    fprintf( stderr, "Unknown block tag %d\n", SWIG_Tag_val(v) );
+	    fprintf( stderr, "Unknown block tag %d\n", Tag_val(v) );
 	    caml_failwith("No conversion to double");
 	}
     }
 
-    SWIGINTERN int caml_ptr_val_internal( CAML_VALUE v, void **out,
+    SWIGINTERN int caml_ptr_val_internal( value v, void **out,
 					  swig_type_info *descriptor ) {
 	CAMLparam1(v);
 	void *outptr = NULL;
         swig_type_info *outdescr = NULL;
-        static CAML_VALUE *func_val = NULL;
+        static const value *func_val = NULL;
 
 	if( v == Val_unit ) {
 	    *out = 0;
-	    CAMLreturn_type(0);
+	    CAMLreturnT(int, 0);
 	}
 	if( !Is_block(v) ) return -1;
-	switch( SWIG_Tag_val(v) ) {
+	switch( Tag_val(v) ) {
 	case C_obj:
 	    if (!func_val) {
 	        func_val = caml_named_value("caml_obj_ptr");
 	    }
-	    CAMLreturn_type(caml_ptr_val_internal(caml_callback(*func_val, v), out, descriptor));
+	    CAMLreturnT(int, caml_ptr_val_internal(caml_callback(*func_val, v), out, descriptor));
 	case C_string:
-	    outptr = (void *)String_val(SWIG_Field(v,0));
+	    outptr = (void *)String_val(Field(v,0));
 	    break;
 	case C_ptr:
-	    outptr = (void *)(long)SWIG_Int64_val(SWIG_Field(v,0));
-            outdescr = (swig_type_info *)(long)SWIG_Int64_val(SWIG_Field(v,1));
+	    outptr = (void *)(long)Int64_val(Field(v,0));
+	    outdescr = (swig_type_info *)(long)Int64_val(Field(v,1));
 	    break;
 	default:
 	    *out = 0;
-	    CAMLreturn_type(1);
+	    CAMLreturnT(int, 1);
 	    break;
 	}
 
-	CAMLreturn_type(SWIG_GetPtr(outptr, out, outdescr, descriptor));
+	CAMLreturnT(int, SWIG_GetPtr(outptr, out, outdescr, descriptor));
     }
 
-    SWIGINTERN void *caml_ptr_val( CAML_VALUE v, swig_type_info *descriptor ) {
+    SWIGINTERN void *caml_ptr_val( value v, swig_type_info *descriptor ) {
         CAMLparam0();
 #ifdef TYPE_CAST_VERBOSE
 	caml_print_val( v );
 #endif
 	void *out = NULL;
 	if( !caml_ptr_val_internal( v, &out, descriptor ) )
-	    CAMLreturn_type(out);
+	    CAMLreturnT(void*, out);
 	else
 	    caml_failwith( "No appropriate conversion found." );
     }
 
-    SWIGINTERN char *caml_string_val( CAML_VALUE v ) {
+    SWIGINTERN char *caml_string_val( value v ) {
 	return (char *)caml_ptr_val( v, 0 );
     }
 
-    SWIGINTERN int caml_string_len( CAML_VALUE v ) {
-	switch( SWIG_Tag_val(v) ) {
+    SWIGINTERN int caml_string_len( value v ) {
+	switch( Tag_val(v) ) {
 	case C_string:
-	    return caml_string_length(SWIG_Field(v,0));
+	    return caml_string_length(Field(v,0));
 	default:
 	    return strlen((char *)caml_ptr_val(v,0));
 	}
     }
 
-    SWIGINTERN int caml_bool_check( CAML_VALUE v ) {
+    SWIGINTERN int caml_bool_check( value v ) {
 	CAMLparam1(v);
 	
 	if( !Is_block(v) ) return 0;
 	
-	switch( SWIG_Tag_val(v) ) {
+	switch( Tag_val(v) ) {
 	case C_bool:
 	case C_ptr:
 	case C_string:
@@ -520,12 +520,12 @@
 	}
     }
 
-    SWIGINTERN int caml_int_check( CAML_VALUE v ) {
+    SWIGINTERN int caml_int_check( value v ) {
 	CAMLparam1(v);
 	
 	if( !Is_block(v) ) return 0;
 	
-	switch( SWIG_Tag_val(v) ) {
+	switch( Tag_val(v) ) {
 	case C_char:
 	case C_uchar:
 	case C_short:
@@ -541,11 +541,11 @@
 	}
     }
 
-    SWIGINTERN int caml_float_check( CAML_VALUE v ) {
+    SWIGINTERN int caml_float_check( value v ) {
 	CAMLparam1(v);
 	if( !Is_block(v) ) return 0;
 
-	switch( SWIG_Tag_val(v) ) {
+	switch( Tag_val(v) ) {
 	case C_float:
 	case C_double:
 	    CAMLreturn(1);
@@ -555,11 +555,11 @@
 	}	
     }
 
-    SWIGINTERN int caml_ptr_check( CAML_VALUE v ) {
+    SWIGINTERN int caml_ptr_check( value v ) {
 	CAMLparam1(v);
 	if( !Is_block(v) ) return 0;
 
-	switch( SWIG_Tag_val(v) ) {
+	switch( Tag_val(v) ) {
 	case C_string:
 	case C_ptr:
 	case C_int64:
@@ -570,11 +570,11 @@
 	}	
     }
 
-    SWIGINTERN CAML_VALUE SWIG_Ocaml_ptr_to_val(const char *name, void *ptr, swig_type_info *descriptor) {
+    SWIGINTERN value SWIG_Ocaml_ptr_to_val(const char *name, void *ptr, swig_type_info *descriptor) {
         CAMLparam0();
-        SWIG_CAMLlocal1(result);
+        CAMLlocal1(result);
 
-        CAML_VALUE *fromval = caml_named_value(name);
+        const value *fromval = caml_named_value(name);
         if (fromval) {
             result = caml_callback(*fromval, caml_val_ptr(ptr, descriptor));
         } else {
@@ -584,17 +584,17 @@
     }
 
     static swig_module_info *SWIG_Ocaml_GetModule(void *SWIGUNUSEDPARM(clientdata)) {
-      CAML_VALUE pointer;
+      value pointer;
 
       pointer = caml_callback(*caml_named_value("swig_find_type_info"), caml_val_int(0));
-      if (Is_block(pointer) && SWIG_Tag_val(pointer) == C_ptr) {
-        return (swig_module_info *)(void *)(long)SWIG_Int64_val(SWIG_Field(pointer,0));
+      if (Is_block(pointer) && Tag_val(pointer) == C_ptr) {
+        return (swig_module_info *)(void *)(long)Int64_val(Field(pointer,0));
       }
       return 0;
     }
 
     static void SWIG_Ocaml_SetModule(swig_module_info *pointer) {
-      CAML_VALUE mod_pointer;
+      value mod_pointer;
 
       mod_pointer = caml_val_ptr(pointer, NULL);
       caml_callback(*caml_named_value("swig_set_type_info"), mod_pointer);
@@ -603,5 +603,3 @@
 #ifdef __cplusplus
 }
 #endif
-#undef value
-
diff --git a/Lib/ocaml/ocamlrundec.swg b/Lib/ocaml/ocamlrundec.swg
index 555f9a4..4d20f34 100644
--- a/Lib/ocaml/ocamlrundec.swg
+++ b/Lib/ocaml/ocamlrundec.swg
@@ -14,8 +14,6 @@
 #else
 #define SWIGEXT 
 #endif
-#define value caml_value_t
-#define CAML_VALUE caml_value_t
 #define CAML_NAME_SPACE
 #include <caml/alloc.h>
 #include <caml/custom.h>
@@ -34,95 +32,6 @@
 
 #define caml_array_set swig_caml_array_set
 
-/* Adapted from memory.h and mlvalues.h */
-
-#define SWIG_CAMLlocal1(x) \
-  caml_value_t x = 0; \
-  CAMLxparam1 (x)
-
-#define SWIG_CAMLlocal2(x, y) \
-  caml_value_t x = 0, y = 0; \
-  CAMLxparam2 (x, y)
-
-#define SWIG_CAMLlocal3(x, y, z) \
-  caml_value_t x = 0, y = 0, z = 0; \
-  CAMLxparam3 (x, y, z)
-
-#define SWIG_CAMLlocal4(x, y, z, t) \
-  caml_value_t x = 0, y = 0, z = 0, t = 0; \
-  CAMLxparam4 (x, y, z, t)
-
-#define SWIG_CAMLlocal5(x, y, z, t, u) \
-  caml_value_t x = 0, y = 0, z = 0, t = 0, u = 0; \
-  CAMLxparam5 (x, y, z, t, u)
-
-#define SWIG_CAMLlocalN(x, size) \
-  caml_value_t x [(size)] = { 0, /* 0, 0, ... */ }; \
-  CAMLxparamN (x, (size))
-
-#define SWIG_Field(x, i) (((caml_value_t *)(x)) [i])           /* Also an l-value. */
-#define SWIG_Store_field(block, offset, val) do{ \
-  mlsize_t caml__temp_offset = (offset); \
-  caml_value_t caml__temp_val = (val); \
-  caml_modify (&SWIG_Field ((block), caml__temp_offset), caml__temp_val); \
-}while(0)
-
-#define SWIG_Data_custom_val(v) ((void *) &SWIG_Field((v), 1))
-#ifdef ARCH_BIG_ENDIAN
-#define SWIG_Tag_val(val) (((unsigned char *) (val)) [-1])
-                                                 /* Also an l-value. */
-#define SWIG_Tag_hp(hp) (((unsigned char *) (hp)) [sizeof(caml_value_t)-1])
-                                                 /* Also an l-value. */
-#else
-#define SWIG_Tag_val(val) (((unsigned char *) (val)) [-sizeof(caml_value_t)])
-                                                 /* Also an l-value. */
-#define SWIG_Tag_hp(hp) (((unsigned char *) (hp)) [0])
-                                                 /* Also an l-value. */
-#endif
-
-#ifdef CAMLreturn0
-#undef CAMLreturn0
-#endif
-#define CAMLreturn0 do{ \
-  caml_local_roots = caml__frame; \
-  return; \
-}while (0)
-
-#ifdef CAMLreturn
-#undef CAMLreturn
-#endif
-#define CAMLreturn(result) do{ \
-  caml_value_t caml__temp_result = (result); \
-  caml_local_roots = caml__frame; \
-  return (caml__temp_result); \
-}while(0)
-
-#define CAMLreturn_type(result) do{ \
-  caml_local_roots = caml__frame; \
-  return result; \
-}while(0)
-
-#ifdef CAMLnoreturn
-#undef CAMLnoreturn
-#endif
-#define CAMLnoreturn ((void) caml__frame)
-
-
-#ifndef ARCH_ALIGN_INT64
-#if OCAML_VERSION >= 40300
-#define SWIG_Int64_val(v) (*((int64_t *) SWIG_Data_custom_val(v)))
-#else
-#define SWIG_Int64_val(v) (*((int64 *) SWIG_Data_custom_val(v)))
-#endif
-#else
-#if OCAML_VERSION >= 40300
-CAMLextern int64_t Int64_val(caml_value_t v);
-#else
-CAMLextern int64 Int64_val(caml_value_t v);
-#endif
-#define SWIG_Int64_val(v) Int64_val(v)
-#endif
-
 #define SWIG_NewPointerObj(p,type,flags) caml_val_ptr(p,type)
 #define SWIG_GetModule(clientdata) SWIG_Ocaml_GetModule(clientdata)
 #define SWIG_SetModule(clientdata, pointer) SWIG_Ocaml_SetModule(pointer)
@@ -141,7 +50,7 @@
 
 SWIGINTERN void SWIG_OCamlThrowException(SWIG_OCamlExceptionCodes code, const char *msg) {
   CAMLparam0();
-  SWIG_CAMLlocal1(str);
+  CAMLlocal1(str);
 
   switch (code) {
   case SWIG_OCamlIllegalArgumentException:
@@ -164,48 +73,48 @@
   CAMLreturn0;
 }
 
-#define SWIG_contract_assert(expr, msg) if(!(expr)) {SWIG_OCamlThrowException(SWIG_OCamlRuntimeException, msg);}
+#define SWIG_contract_assert(expr, msg) do { if(!(expr)) {SWIG_OCamlThrowException(SWIG_OCamlRuntimeException, msg);} } while (0)
 
     SWIGINTERN int
     SWIG_GetPtr(void *source, void **result, swig_type_info *type, swig_type_info *result_type);
 
-    SWIGINTERN CAML_VALUE caml_list_nth( CAML_VALUE lst, int n );
-    SWIGINTERN CAML_VALUE caml_list_append( CAML_VALUE lst, CAML_VALUE elt );
-    SWIGINTERN int caml_list_length( CAML_VALUE lst );
-    SWIGINTERN CAML_VALUE caml_array_new( int n );
-    SWIGINTERN void caml_array_set( CAML_VALUE arr, int n, CAML_VALUE item );
-    SWIGINTERN CAML_VALUE caml_array_nth( CAML_VALUE arr, int n );
-    SWIGINTERN int caml_array_len( CAML_VALUE arr );
+    SWIGINTERN value caml_list_nth( value lst, int n );
+    SWIGINTERN value caml_list_append( value lst, value elt );
+    SWIGINTERN int caml_list_length( value lst );
+    SWIGINTERN value caml_array_new( int n );
+    SWIGINTERN void caml_array_set( value arr, int n, value item );
+    SWIGINTERN value caml_array_nth( value arr, int n );
+    SWIGINTERN int caml_array_len( value arr );
 
-    SWIGINTERN CAML_VALUE caml_val_char( char c );
-    SWIGINTERN CAML_VALUE caml_val_uchar( unsigned char c );
+    SWIGINTERN value caml_val_char( char c );
+    SWIGINTERN value caml_val_uchar( unsigned char c );
 
-    SWIGINTERN CAML_VALUE caml_val_short( short s );
-    SWIGINTERN CAML_VALUE caml_val_ushort( unsigned short s );
+    SWIGINTERN value caml_val_short( short s );
+    SWIGINTERN value caml_val_ushort( unsigned short s );
     
-    SWIGINTERN CAML_VALUE caml_val_int( int x );
-    SWIGINTERN CAML_VALUE caml_val_uint( unsigned int x );
+    SWIGINTERN value caml_val_int( int x );
+    SWIGINTERN value caml_val_uint( unsigned int x );
 
-    SWIGINTERN CAML_VALUE caml_val_long( long x );
-    SWIGINTERN CAML_VALUE caml_val_ulong( unsigned long x );
+    SWIGINTERN value caml_val_long( long x );
+    SWIGINTERN value caml_val_ulong( unsigned long x );
 
-    SWIGINTERN CAML_VALUE caml_val_float( float f );
-    SWIGINTERN CAML_VALUE caml_val_double( double d );
+    SWIGINTERN value caml_val_float( float f );
+    SWIGINTERN value caml_val_double( double d );
 
-    SWIGINTERN CAML_VALUE caml_val_ptr( void *p, swig_type_info *descriptor );
+    SWIGINTERN value caml_val_ptr( void *p, swig_type_info *descriptor );
 
-    SWIGINTERN CAML_VALUE caml_val_string( const char *str );
-    SWIGINTERN CAML_VALUE caml_val_string_len( const char *str, int len );
+    SWIGINTERN value caml_val_string( const char *str );
+    SWIGINTERN value caml_val_string_len( const char *str, int len );
 
-    SWIGINTERN long caml_long_val( CAML_VALUE v );
-    SWIGINTERN double caml_double_val( CAML_VALUE v );
+    SWIGINTERN long caml_long_val( value v );
+    SWIGINTERN double caml_double_val( value v );
 
-    SWIGINTERN int caml_ptr_val_internal( CAML_VALUE v, void **out,
+    SWIGINTERN int caml_ptr_val_internal( value v, void **out,
 				      swig_type_info *descriptor );
-    SWIGINTERN void *caml_ptr_val( CAML_VALUE v, swig_type_info *descriptor );
+    SWIGINTERN void *caml_ptr_val( value v, swig_type_info *descriptor );
 
-    SWIGINTERN char *caml_string_val( CAML_VALUE v );
-    SWIGINTERN int caml_string_len( CAML_VALUE v );
+    SWIGINTERN char *caml_string_val( value v );
+    SWIGINTERN int caml_string_len( value v );
 
 #ifdef __cplusplus
 }
diff --git a/Lib/ocaml/std_common.i b/Lib/ocaml/std_common.i
index 7e64607..62a8d3c 100644
--- a/Lib/ocaml/std_common.i
+++ b/Lib/ocaml/std_common.i
@@ -12,12 +12,12 @@
 %{
 #include <string>
 SWIGINTERNINLINE
-CAML_VALUE SwigString_FromString(const std::string &s) {
+value SwigString_FromString(const std::string &s) {
   return caml_val_string((char *)s.c_str());
 }
 
 SWIGINTERNINLINE
-std::string SwigString_AsString(CAML_VALUE o) {
+std::string SwigString_AsString(value o) {
   return std::string((char *)caml_ptr_val(o,0));
 }
 %}
diff --git a/Lib/ocaml/std_map.i b/Lib/ocaml/std_map.i
index 3f197ba..b6a98c6 100644
--- a/Lib/ocaml/std_map.i
+++ b/Lib/ocaml/std_map.i
@@ -47,7 +47,11 @@
                     throw std::out_of_range("key not found");
             }
             void set(const K& key, const T& x) {
+%#ifdef __cpp_lib_map_try_emplace
+                (*self).insert_or_assign(key, x);
+%#else
                 (*self)[key] = x;
+%#endif
             }
             void del(const K& key) throw (std::out_of_range) {
                 std::map< K, T, C >::iterator i = self->find(key);
@@ -63,17 +67,4 @@
         }
     };
 
-// Legacy macros (deprecated)
-%define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_key ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_value ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO)
-#warning "specialize_std_map_on_both ignored - macro is deprecated and no longer necessary"
-%enddef
-
 }
diff --git a/Lib/ocaml/std_string.i b/Lib/ocaml/std_string.i
index 712c3bb..6cf918c 100644
--- a/Lib/ocaml/std_string.i
+++ b/Lib/ocaml/std_string.i
@@ -4,18 +4,11 @@
  * SWIG typemaps for std::string
  * ----------------------------------------------------------------------------- */
 
-// ------------------------------------------------------------------------
-// std::string is typemapped by value
-// This can prevent exporting methods which return a string
-// in order for the user to modify it.
-// However, I think I'll wait until someone asks for it...
-// ------------------------------------------------------------------------
-
 %{
 #include <string>
 #include <vector>
 %}
-  
+
 %include <exception.i>
 %include <std_vector.i>
 
@@ -23,10 +16,10 @@
 
 %naturalvar string;
 %naturalvar wstring;
-  
+
 class string;
 class wstring;
-  
+
 /* Overloading check */
 %typemap(in) string {
   if (caml_ptr_check($input))
@@ -44,15 +37,6 @@
   }
 }
 
-%typemap(in) string & ($*1_ltype temp) {
-  if (caml_ptr_check($input)) {
-    temp.assign((char *)caml_ptr_val($input,0), caml_string_len($input));
-    $1 = &temp;
-  } else {
-    SWIG_exception(SWIG_TypeError, "string expected");
-  }
-}
-
 %typemap(in) string * ($*1_ltype *temp) {
   if (caml_ptr_check($input)) {
     temp = new $*1_ltype((char *)caml_ptr_val($input,0), caml_string_len($input));
@@ -66,12 +50,12 @@
   delete temp;
 }
 
-%typemap(argout) string & {
-  swig_result =	caml_list_append(swig_result,caml_val_string_len((*$1).c_str(), (*$1).size()));
+%typemap(out) const string & {
+    $result = caml_val_string_len((*$1).data(), (*$1).size());
 }
 
 %typemap(directorin) string {
-    swig_result = caml_val_string_len($1.c_str(), $1.size());
+    swig_result = caml_val_string_len($1.data(), $1.size());
     args = caml_list_append(args, swig_result);
 }
 
@@ -80,13 +64,39 @@
 }
 
 %typemap(out) string {
-  $result = caml_val_string_len($1.c_str(),$1.size());
+  $result = caml_val_string_len($1.data(),$1.size());
+}
+
+%typemap(varout) string {
+  $result = caml_val_string_len($1.data(),$1.size());
 }
 
 %typemap(out) string * {
-	$result = caml_val_string_len((*$1).c_str(),(*$1).size());
+	$result = caml_val_string_len((*$1).data(),(*$1).size());
 }
+
+%typemap(varout) string * {
+	$result = caml_val_string_len((*$1).data(),(*$1).size());
+}
+
 %typemap(typecheck) string, const string & = char *;
+
+%typemap(throws) string, const string & "SWIG_OCamlThrowException(SWIG_OCamlRuntimeException, $1.c_str());"
+
+%typemap(in) string &INPUT = const string &;
+%typemap(in, numinputs=0) string &OUTPUT ($*1_ltype temp)
+%{ $1 = &temp; %}
+%typemap(argout) string &OUTPUT {
+    swig_result = caml_list_append(swig_result, caml_val_string_len((*$1).data(), (*$1).size()));
+}
+%typemap(in) string &INOUT = const string &;
+%typemap(argout) string &INOUT = string &OUTPUT;
+
+%typemap(typecheck) string, const string & = char *;
+
+%typemap(throws) string, const string & {
+    SWIG_OCamlThrowException(SWIG_OCamlRuntimeException, $1.c_str());
+}
 }
 
 #ifdef ENABLE_CHARPTR_ARRAY
diff --git a/Lib/ocaml/swigmove.i b/Lib/ocaml/swigmove.i
new file mode 100644
index 0000000..32f9903
--- /dev/null
+++ b/Lib/ocaml/swigmove.i
@@ -0,0 +1,11 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in, noblock=1) SWIGTYPE MOVE (void *argp = 0) {
+  argp1 = ($&1_ltype) caml_ptr_val($input,$&1_descriptor);
+  SwigValueWrapper< $1_ltype >::reset($1, ($&1_type)argp);
+}
diff --git a/Lib/ocaml/typecheck.i b/Lib/ocaml/typecheck.i
index 0c0a600..1466d1c 100644
--- a/Lib/ocaml/typecheck.i
+++ b/Lib/ocaml/typecheck.i
@@ -7,7 +7,7 @@
 %typecheck(SWIG_TYPECHECK_INT8) char, signed char, const char &, const signed char & {
   if( !Is_block($input) ) $1 = 0;
   else {
-      switch( SWIG_Tag_val($input) ) {
+      switch( Tag_val($input) ) {
       case C_char: $1 = 1; break;
       default: $1 = 0; break;
       }
@@ -17,7 +17,7 @@
 %typecheck(SWIG_TYPECHECK_UINT8) unsigned char, const unsigned char & {
   if( !Is_block($input) ) $1 = 0;
   else {
-      switch( SWIG_Tag_val($input) ) {
+      switch( Tag_val($input) ) {
       case C_uchar: $1 = 1; break;
       default: $1 = 0; break;
       }
@@ -27,7 +27,7 @@
 %typecheck(SWIG_TYPECHECK_INT16) short, signed short, const short &, const signed short &, wchar_t {
   if( !Is_block($input) ) $1 = 0;
   else {
-      switch( SWIG_Tag_val($input) ) {
+      switch( Tag_val($input) ) {
       case C_short: $1 = 1; break;
       default: $1 = 0; break;
       }
@@ -37,7 +37,7 @@
 %typecheck(SWIG_TYPECHECK_UINT16) unsigned short, const unsigned short & {
   if( !Is_block($input) ) $1 = 0;
   else {
-      switch( SWIG_Tag_val($input) ) {
+      switch( Tag_val($input) ) {
       case C_ushort: $1 = 1; break;
       default: $1 = 0; break;
       }
@@ -50,7 +50,7 @@
 %typecheck(SWIG_TYPECHECK_INT32) int, signed int, const int &, const signed int &, enum SWIGTYPE {
   if( !Is_block($input) ) $1 = 0;
   else {
-      switch( SWIG_Tag_val($input) ) {
+      switch( Tag_val($input) ) {
       case C_int: $1 = 1; break;
       default: $1 = 0; break;
       }
@@ -60,7 +60,7 @@
 %typecheck(SWIG_TYPECHECK_UINT32) unsigned int, const unsigned int & {
   if( !Is_block($input) ) $1 = 0;
   else {
-      switch( SWIG_Tag_val($input) ) {
+      switch( Tag_val($input) ) {
       case C_uint: $1 = 1; break;
       case C_int32: $1 = 1; break;
       default: $1 = 0; break;
@@ -77,7 +77,7 @@
 {
   if( !Is_block($input) ) $1 = 0;
   else {
-      switch( SWIG_Tag_val($input) ) {
+      switch( Tag_val($input) ) {
       case C_int64: $1 = 1; break;
       default: $1 = 0; break;
       }
@@ -87,7 +87,7 @@
 %typecheck(SWIG_TYPECHECK_BOOL) bool, const bool & {
   if( !Is_block($input) ) $1 = 0;
   else {
-      switch( SWIG_Tag_val($input) ) {
+      switch( Tag_val($input) ) {
       case C_bool: $1 = 1; break;
       default: $1 = 0; break;
       }
@@ -97,7 +97,7 @@
 %typecheck(SWIG_TYPECHECK_FLOAT) float, const float & {
   if( !Is_block($input) ) $1 = 0;
   else {
-      switch( SWIG_Tag_val($input) ) {
+      switch( Tag_val($input) ) {
       case C_float: $1 = 1; break;
       default: $1 = 0; break;
       }
@@ -107,7 +107,7 @@
 %typecheck(SWIG_TYPECHECK_DOUBLE) double, const double & {
   if( !Is_block($input) ) $1 = 0;
   else {
-      switch( SWIG_Tag_val($input) ) {
+      switch( Tag_val($input) ) {
       case C_double: $1 = 1; break;
       default: $1 = 0; break;
       }
@@ -117,11 +117,11 @@
 %typecheck(SWIG_TYPECHECK_STRING) char * {
   if( !Is_block($input) ) $1 = 0;
   else {
-      switch( SWIG_Tag_val($input) ) {
+      switch( Tag_val($input) ) {
       case C_string: $1 = 1; break;
       case C_ptr: {
 	swig_type_info *typeinfo = 
-	    (swig_type_info *)(long)SWIG_Int64_val(SWIG_Field($input,1));
+	    (swig_type_info *)(long)Int64_val(Field($input,1));
 	$1 = SWIG_TypeCheck("char *",typeinfo) ||
 	     SWIG_TypeCheck("signed char *",typeinfo) ||
 	     SWIG_TypeCheck("unsigned char *",typeinfo) ||
@@ -136,7 +136,7 @@
 }
 
 %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] {
-  if (!Is_block($input) || !(SWIG_Tag_val($input) == C_obj || SWIG_Tag_val($input) == C_ptr)) {
+  if (!Is_block($input) || !(Tag_val($input) == C_obj || Tag_val($input) == C_ptr)) {
     $1 = 0;
   } else {
     void *ptr;
@@ -149,14 +149,14 @@
   if (!Is_block($input)) {
     $1 = 0;
   } else {
-    switch (SWIG_Tag_val($input)) {
+    switch (Tag_val($input)) {
       case C_obj: {
         void *ptr;
         $1 = !caml_ptr_val_internal($input, &ptr, $&1_descriptor);
         break;
       }
       case C_ptr: {
-        typeinfo = (swig_type_info *)SWIG_Int64_val(SWIG_Field($input, 1));
+        typeinfo = (swig_type_info *)Int64_val(Field($input, 1));
         $1 = SWIG_TypeCheck("$1_type", typeinfo) != NULL;
         break;
       }
@@ -170,7 +170,7 @@
   $1 = !caml_ptr_val_internal($input, &ptr, 0);
 }
 
-%typecheck(SWIG_TYPECHECK_SWIGOBJECT) CAML_VALUE "$1 = 1;"
+%typecheck(SWIG_TYPECHECK_SWIGOBJECT) value "$1 = 1;"
 
 /* ------------------------------------------------------------
  * Exception handling
@@ -183,7 +183,7 @@
                   unsigned long, 
                   unsigned short {
   char error_msg[256];
-  sprintf(error_msg, "C++ $1_type exception thrown, value: %d", $1);
+  SWIG_snprintf(error_msg, sizeof(error_msg), "C++ $1_type exception thrown, value: %d", $1);
   SWIG_OCamlThrowException(SWIG_OCamlRuntimeException, error_msg);
 }
 
diff --git a/Lib/octave/argcargv.i b/Lib/octave/argcargv.i
new file mode 100644
index 0000000..8ddca59
--- /dev/null
+++ b/Lib/octave/argcargv.i
@@ -0,0 +1,52 @@
+/* -------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------- */
+
+%typemap(in) (int ARGC, char **ARGV) {
+  if ($input.is_scalar_type()) {
+    $1 = 0; $2 = NULL;
+    %argument_fail(SWIG_TypeError, "'int ARGC, char **ARGV' is not a list", $symname, $argnum);
+  }
+  octave_value_list list = $input.list_value();
+  int i, len = list.length();
+  $1 = ($1_ltype) len;
+  $2 = (char **) malloc((len+1)*sizeof(char *));
+  for (i = 0; i < len; i++) {
+    if (!list(i).is_string()) {
+      $1 = 0;
+      %argument_fail(SWIG_TypeError, "'int ARGC, char **ARGV' use a non-string", $symname, $argnum);
+    }
+    const std::string & s = list(i).string_value();
+    size_t slen = s.size() + 1;
+    char * p = (char*)malloc(slen);
+    $2[i] = p;
+    memcpy(p, s.c_str(), slen);
+  }
+  $2[i] = NULL;
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+  $1 = 0;
+  const octave_value& ov = $input;
+  if (!ov.is_scalar_type()) {
+    octave_value_list list = ov.list_value();
+    int i, len = list.length();
+    $1 = 1;
+    for (i = 0; i < len; i++) {
+      if (!list(i).is_string()) {
+        $1 = 0;
+        break;
+      }
+    }
+  }
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+  if ($2 != NULL) {
+    $1_ltype i;
+    for (i = 0; i < $1; i++) {
+      free((void *)$2[i]);
+    }
+    free((void *)$2);
+  }
+}
diff --git a/Lib/octave/boost_shared_ptr.i b/Lib/octave/boost_shared_ptr.i
index 668bf43..87c89b5 100644
--- a/Lib/octave/boost_shared_ptr.i
+++ b/Lib/octave/boost_shared_ptr.i
@@ -35,7 +35,7 @@
   }
 }
 %typemap(out) CONST TYPE {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
@@ -54,12 +54,12 @@
   }
 }
 %typemap(varout) CONST TYPE {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
 %typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
-  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(SWIG_STD_MOVE($1)));
   $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
 %}
 %typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
diff --git a/Lib/octave/director.swg b/Lib/octave/director.swg
index bf71d18..5b9cd86 100644
--- a/Lib/octave/director.swg
+++ b/Lib/octave/director.swg
@@ -7,8 +7,6 @@
 
 # define SWIG_DIRECTOR_CAST(ARG) dynamic_cast<Swig::Director *>(ARG)
 
-#include <exception>
-
 namespace Swig {
 
   class Director {
diff --git a/Lib/octave/extra-install.list b/Lib/octave/extra-install.list
new file mode 100644
index 0000000..41ef947
--- /dev/null
+++ b/Lib/octave/extra-install.list
@@ -0,0 +1,2 @@
+# see top-level Makefile.in
+octheaders.hpp
diff --git a/Lib/octave/octcomplex.swg b/Lib/octave/octcomplex.swg
index a3e9ebf..553c25a 100644
--- a/Lib/octave/octcomplex.swg
+++ b/Lib/octave/octcomplex.swg
@@ -2,7 +2,7 @@
   Defines the As/From conversors for double/float complex, you need to
   provide complex Type, the Name you want to use in the conversors,
   the complex Constructor method, and the Real and Imag complex
-  accesor methods.
+  accessor methods.
 
   See the std_complex.i and ccomplex.i for concrete examples.
 */
@@ -73,7 +73,7 @@
 	int res = SWIG_AddCast(SWIG_AsVal(float)(ov, &d));
 	if (SWIG_IsOK(res)) {
 	  if (val)
-	    *val = Constructor(d, 0.0);
+	    *val = Constructor(d, 0.0f);
 	  return res;
 	}
       }
diff --git a/Lib/octave/octcontainer.swg b/Lib/octave/octcontainer.swg
index 310a849..97a345e 100644
--- a/Lib/octave/octcontainer.swg
+++ b/Lib/octave/octcontainer.swg
@@ -11,12 +11,6 @@
  * be the case.
  * ----------------------------------------------------------------------------- */
 
-%{
-#include <climits>
-#include <iostream>
-%}
-
-
 #if !defined(SWIG_NO_EXPORT_ITERATOR_METHODS)
 # if !defined(SWIG_EXPORT_ITERATOR_METHODS)
 #  define SWIG_EXPORT_ITERATOR_METHODS SWIG_EXPORT_ITERATOR_METHODS
@@ -64,7 +58,6 @@
 
 %fragment("OctSequence_Base","header",fragment="<stddef.h>")
 {
-%#include <functional>
 
 namespace std {
   template <>
@@ -73,7 +66,11 @@
     bool
     operator()(const octave_value& v, const octave_value& w) const
     { 
+%#if SWIG_OCTAVE_PREREQ(7,0,0)
+      octave_value res = octave::binary_op(octave_value::op_le,v,w);
+%#else
       octave_value res = do_binary_op(octave_value::op_le,v,w);
+%#endif
       return res.is_true();
     }
   };
@@ -109,7 +106,7 @@
 
   template <class Sequence, class Difference>
   inline typename Sequence::iterator
-  getpos(Sequence* self, Difference i)  {
+  getpos(Sequence* self, Difference i) {
     typename Sequence::iterator pos = self->begin();
     std::advance(pos, check_index(i,self->size()));
     return pos;
@@ -117,7 +114,7 @@
 
   template <class Sequence, class Difference>
   inline typename Sequence::const_iterator
-  cgetpos(const Sequence* self, Difference i)  {
+  cgetpos(const Sequence* self, Difference i) {
     typename Sequence::const_iterator pos = self->begin();
     std::advance(pos, check_index(i,self->size()));
     return pos;
@@ -143,25 +140,29 @@
 
   template <class Sequence, class Difference, class InputSeq>
   inline void
-  setslice(Sequence* self, Difference i, Difference j, const InputSeq& v) {
+  setslice(Sequence* self, Difference i, Difference j, const InputSeq& is) {
     typename Sequence::size_type size = self->size();
     typename Sequence::size_type ii = swig::check_index(i, size, true);
     typename Sequence::size_type jj = swig::slice_index(j, size);
     if (jj < ii) jj = ii;
     size_t ssize = jj - ii;
-    if (ssize <= v.size()) {
+    if (ssize <= is.size()) {
+      // expanding/staying the same size
       typename Sequence::iterator sb = self->begin();
-      typename InputSeq::const_iterator vmid = v.begin();
+      typename InputSeq::const_iterator vmid = is.begin();
       std::advance(sb,ii);
       std::advance(vmid, jj - ii);
-      self->insert(std::copy(v.begin(), vmid, sb), vmid, v.end());
+      self->insert(std::copy(is.begin(), vmid, sb), vmid, is.end());
     } else {
+      // shrinking
       typename Sequence::iterator sb = self->begin();
       typename Sequence::iterator se = self->begin();
       std::advance(sb,ii);
       std::advance(se,jj);
       self->erase(sb,se);
-      self->insert(sb, v.begin(), v.end());
+      sb = self->begin();
+      std::advance(sb,ii);
+      self->insert(sb, is.begin(), is.end());
     }
   }
 
@@ -205,7 +206,7 @@
 	return swig::as<T>(item);
       } catch (const std::exception& e) {
 	char msg[1024];
-	sprintf(msg, "in sequence element %d ", _index);
+	SWIG_snprintf(msg, sizeof(msg), "in sequence element %d ", _index);
 	if (!Octave_Error_Occurred()) {
 	  %type_error(swig::type_name<T>());
 	}
@@ -576,8 +577,17 @@
 	  } else {
 	    return octseq.check() ? SWIG_OK : SWIG_ERROR;
 	  }
-	} catch (std::exception& e) {
+	}
+%#if SWIG_OCTAVE_PREREQ(6,0,0)
+        catch (octave::execution_exception& exec) {
+        }
+%#endif
+        catch (std::exception& e) {
+%#if SWIG_OCTAVE_PREREQ(6,0,0)
+          if (seq) // Know that octave is not in an error state
+%#else
 	  if (seq&&!error_state)
+%#endif
 	    error("swig type error: %s",e.what());
 	  return SWIG_ERROR;
 	}
diff --git a/Lib/octave/octheaders.hpp b/Lib/octave/octheaders.hpp
new file mode 100644
index 0000000..26e5564
--- /dev/null
+++ b/Lib/octave/octheaders.hpp
@@ -0,0 +1,130 @@
+//
+// This header includes all C++ headers required for generated Octave wrapper code.
+// Using a single header file allows pre-compilation of Octave headers, as follows:
+// * Check out this header file:
+//     swig -octave -co octheaders.hpp
+// * Pre-compile header file into octheaders.hpp.gch:
+//     g++ -c ... octheaders.hpp
+// * Use pre-compiled header file:
+//     g++ -c -include octheaders.hpp ...
+//
+
+#if !defined(SWIG_OCTAVE_OCTHEADERS_HPP)
+#define SWIG_OCTAVE_OCTHEADERS_HPP
+
+// Required C++ headers
+#include <cstdlib>
+#include <climits>
+#include <iostream>
+#include <exception>
+#include <functional>
+#include <complex>
+#include <string>
+#include <vector>
+#include <map>
+
+// Minimal headers to define Octave version
+#include <octave/oct.h>
+#include <octave/version.h>
+
+// Macro for enabling features which require Octave version >= major.minor.patch
+// - Use (OCTAVE_PATCH_VERSION + 0) to handle both '<digit>' (released) and '<digit>+' (in development) patch numbers
+#define SWIG_OCTAVE_PREREQ(major, minor, patch) \
+  ( (OCTAVE_MAJOR_VERSION<<16) + (OCTAVE_MINOR_VERSION<<8) + (OCTAVE_PATCH_VERSION + 0) >= ((major)<<16) + ((minor)<<8) + (patch) )
+
+// Reconstruct Octave major, minor, and patch versions for releases prior to 3.8.1
+#if !defined(OCTAVE_MAJOR_VERSION)
+
+# if !defined(OCTAVE_API_VERSION_NUMBER)
+
+// Hack to distinguish between Octave 3.8.0, which removed OCTAVE_API_VERSION_NUMBER but did not yet
+// introduce OCTAVE_MAJOR_VERSION, and Octave <= 3.2, which did not define OCTAVE_API_VERSION_NUMBER
+#  include <octave/ov.h>
+#  if defined(octave_ov_h)
+#   define OCTAVE_MAJOR_VERSION 3
+#   define OCTAVE_MINOR_VERSION 8
+#   define OCTAVE_PATCH_VERSION 0
+#  else
+
+// Hack to distinguish between Octave 3.2 and earlier versions, before OCTAVE_API_VERSION_NUMBER existed
+#   define ComplexLU __ignore
+#   include <octave/CmplxLU.h>
+#   undef ComplexLU
+#   if defined(octave_Complex_LU_h)
+
+// We know only that this version is prior to Octave 3.2, i.e. OCTAVE_API_VERSION_NUMBER < 37
+#    define OCTAVE_MAJOR_VERSION 3
+#    define OCTAVE_MINOR_VERSION 1
+#    define OCTAVE_PATCH_VERSION 99
+
+#   else
+
+// OCTAVE_API_VERSION_NUMBER == 37
+#    define OCTAVE_MAJOR_VERSION 3
+#    define OCTAVE_MINOR_VERSION 2
+#    define OCTAVE_PATCH_VERSION 0
+
+#   endif // defined(octave_Complex_LU_h)
+
+#  endif // defined(octave_ov_h)
+
+// Correlation between Octave API and version numbers extracted from Octave's
+// ChangeLogs; version is the *earliest* released Octave with that API number
+# elif OCTAVE_API_VERSION_NUMBER >= 48
+#  define OCTAVE_MAJOR_VERSION 3
+#  define OCTAVE_MINOR_VERSION 6
+#  define OCTAVE_PATCH_VERSION 0
+
+# elif OCTAVE_API_VERSION_NUMBER >= 45
+#  define OCTAVE_MAJOR_VERSION 3
+#  define OCTAVE_MINOR_VERSION 4
+#  define OCTAVE_PATCH_VERSION 1
+
+# elif OCTAVE_API_VERSION_NUMBER >= 42
+#  define OCTAVE_MAJOR_VERSION 3
+#  define OCTAVE_MINOR_VERSION 3
+#  define OCTAVE_PATCH_VERSION 54
+
+# elif OCTAVE_API_VERSION_NUMBER >= 41
+#  define OCTAVE_MAJOR_VERSION 3
+#  define OCTAVE_MINOR_VERSION 3
+#  define OCTAVE_PATCH_VERSION 53
+
+# elif OCTAVE_API_VERSION_NUMBER >= 40
+#  define OCTAVE_MAJOR_VERSION 3
+#  define OCTAVE_MINOR_VERSION 3
+#  define OCTAVE_PATCH_VERSION 52
+
+# elif OCTAVE_API_VERSION_NUMBER >= 39
+#  define OCTAVE_MAJOR_VERSION 3
+#  define OCTAVE_MINOR_VERSION 3
+#  define OCTAVE_PATCH_VERSION 51
+
+# else // OCTAVE_API_VERSION_NUMBER == 38
+#  define OCTAVE_MAJOR_VERSION 3
+#  define OCTAVE_MINOR_VERSION 3
+#  define OCTAVE_PATCH_VERSION 50
+
+# endif // !defined(OCTAVE_API_VERSION_NUMBER)
+
+#endif // !defined(OCTAVE_MAJOR_VERSION)
+
+// Required Octave headers
+#include <octave/Cell.h>
+#include <octave/dynamic-ld.h>
+#include <octave/oct-env.h>
+#include <octave/oct-map.h>
+#include <octave/ov-scalar.h>
+#include <octave/ov-fcn-handle.h>
+#include <octave/parse.h>
+#if SWIG_OCTAVE_PREREQ(4,2,0)
+#include <octave/interpreter.h>
+#else
+#include <octave/toplev.h>
+#endif
+#include <octave/unwind-prot.h>
+#if SWIG_OCTAVE_PREREQ(4,2,0)
+#include <octave/call-stack.h>
+#endif
+
+#endif // !defined(SWIG_OCTAVE_OCTHEADERS_HPP)
diff --git a/Lib/octave/octrun.swg b/Lib/octave/octrun.swg
index ff614e6..5865c92 100644
--- a/Lib/octave/octrun.swg
+++ b/Lib/octave/octrun.swg
@@ -89,10 +89,6 @@
 
 // Runtime API implementation
 
-#include <map>
-#include <vector>
-#include <string>
-
 typedef octave_value_list(*octave_func) (const octave_value_list &, int);
 class octave_swig_type;
 
@@ -175,7 +171,16 @@
 
     octave_function* function_value(bool = false) { return this; }
 
+#if SWIG_OCTAVE_PREREQ(6,0,0)
     octave_value_list call(octave::tree_evaluator& tw, int nargout = 0, const octave_value_list& args = octave_value_list()) {
+      return execute(tw,nargout,args);
+    }
+#endif
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+    octave_value_list execute(octave::tree_evaluator& tw, int nargout = 0, const octave_value_list& args = octave_value_list()) {
+#else
+    octave_value_list call(octave::tree_evaluator& tw, int nargout = 0, const octave_value_list& args = octave_value_list()) {
+#endif
       octave_value_list all_args;
       all_args.append(first_args);
       all_args.append(args);
@@ -203,11 +208,7 @@
 
     std::set<std::string> dispatch_classes;
 
-  private:
-
-    DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA
   };
-  DEFINE_OV_TYPEID_FUNCTIONS_AND_DATA(octave_swig_bound_func, "octave_swig_bound_func", "octave_swig_bound_func");
 #else
 #define SWIG_OCTAVE_BOUND_FUNC(func, args) octave_value(func)
 #endif
@@ -231,7 +232,7 @@
 
     const swig_type_info *construct_type;	// type of special type object
     std::vector < type_ptr_pair > types;	// our c++ base classes
-    int own;			// whether we call c++ destructors when we die
+    int thisown; // whether we call c++ destructors when we die
 
     typedef std::pair < const swig_octave_member *, octave_value > member_value_pair;
     typedef std::map < std::string, member_value_pair > member_map;
@@ -401,7 +402,11 @@
     }
 
     static octave_value make_value_hack(const octave_base_value &x) {
+#if SWIG_OCTAVE_PREREQ(9,0,0)
+      ((octave_swig_type &) x).m_count++;
+#else
       ((octave_swig_type &) x).count++;
+#endif
       return octave_value((octave_base_value *) &x);
     }
 
@@ -411,7 +416,7 @@
 
     octave_swig_type(void *_ptr = 0, const swig_type_info *_type = 0, int _own = 0,
 		     bool _always_static = false)
-      :	module(0), construct_type(_ptr ? 0 : _type), own(_own), 
+      :	module(0), construct_type(_ptr ? 0 : _type), thisown(_own), 
       always_static(_always_static) {
       if (_type || _ptr)
 	types.push_back(std::make_pair(_type, _ptr));
@@ -425,8 +430,12 @@
     }
 
     ~octave_swig_type() {
-      if (own) {
+      if (thisown) {
+#if SWIG_OCTAVE_PREREQ(9,0,0)
+	++m_count;
+#else
 	++count;
+#endif
 	for (unsigned int j = 0; j < types.size(); ++j) {
 	  if (!types[j].first || !types[j].first->clientdata)
 	    continue;
@@ -464,10 +473,20 @@
         // Fill in dim_vector 
         for (int k=0;k<ndim;k++) {
           const octave_value& obj = c(k);
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+          try {
+            d.elem(k) = obj.int_value();
+          }
+          catch (octave::execution_exception& oee) {
+            // __dims__ should return a cell filled with integers
+            return dim_vector(1,1);
+          }
+#else
           d.elem(k) = obj.int_value();
           
           // __dims__ should return a cell filled with integers
           if (error_state) return dim_vector(1,1);
+#endif
         }
         return d;
 #if SWIG_OCTAVE_PREREQ(4,4,0)
@@ -476,8 +495,18 @@
       } else if (out.is_matrix_type() || out.is_numeric_type() ) {
 #endif
         if (out.rows()==1 || out.columns()==1) {
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+           Array<int> a;
+           try {
+             a = out.int_vector_value();
+           }
+           catch (octave::execution_exception& oee) {
+             return dim_vector(1,1);
+           }
+#else
            Array<int> a = out.int_vector_value();
            if (error_state) return dim_vector(1,1);
+#endif
            dim_vector d;
            d.resize(a.numel() < 2 ? 2 : a.numel());
            d(0) = d(1) = 1;
@@ -494,23 +523,35 @@
     }
 
     octave_value as_value() {
+#if SWIG_OCTAVE_PREREQ(9,0,0)
+      ++m_count;
+#else
       ++count;
+#endif
       return Swig::swig_value_ref(this);
     }
 
     void incref() {
+#if SWIG_OCTAVE_PREREQ(9,0,0)
+      ++m_count;
+#else
       ++count;
+#endif
     }
 
     void decref() {
+#if SWIG_OCTAVE_PREREQ(9,0,0)
+      if (!--m_count)
+#else
       if (!--count)
+#endif
 	delete this;
     }
 
-    long swig_this() const {
+    size_t swig_this() const {
       if (!types.size())
-	return (long) this;
-      return (long) types[0].second.ptr;
+	return (size_t) this;
+      return (size_t) types[0].second.ptr;
     }
     const char* help_text() const {
       if (!types.size())
@@ -538,7 +579,7 @@
     }
 
     void merge(octave_swig_type &rhs) {
-      rhs.own = 0;
+      rhs.thisown = 0;
       for (unsigned int j = 0; j < rhs.types.size(); ++j) {
 	assert(!rhs.types[j].second.destroyed);
 #ifdef SWIG_DIRECTORS
@@ -561,35 +602,56 @@
     swig_member_const_iterator swig_members_begin() { return members.begin(); }
     swig_member_const_iterator swig_members_end() { return members.end(); }
 
-    int cast(void **vptr, swig_type_info *type, int *_own, int flags) {
+    int cast(void **vptr, swig_type_info *type, int *own, int flags) {
       int res = SWIG_ERROR;
-      if (_own)
-	*_own = own;
-      if (flags &SWIG_POINTER_DISOWN)
-	own = 0;
+      int clear_pointer = 0;
+
+      if (own)
+	*own = 0;
+      if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !thisown) {
+	return SWIG_ERROR_RELEASE_NOT_OWNED;
+      } else {
+	if (own)
+	  *own = *own | thisown;
+	if (flags & SWIG_POINTER_DISOWN) {
+	  thisown = 0;
+	}
+	if (flags & SWIG_POINTER_CLEAR) {
+	  clear_pointer = 1;
+	}
+      }
+
       if (!type && types.size()) {
-	if(vptr)
+	if (vptr) {
           *vptr = types[0].second.ptr;
+	  if (clear_pointer)
+	    types[0].second.ptr = 0;
+        }
         return SWIG_OK;
       }
       for (unsigned int j = 0; j < types.size(); ++j)
 	if (type == types[j].first) {
-	  if(vptr)
+	  if (vptr) {
             *vptr = types[j].second.ptr;
+	    if (clear_pointer)
+	      types[j].second.ptr = 0;
+	  }
           return SWIG_OK;
         }
       for (unsigned int j = 0; j < types.size(); ++j) {
 	swig_cast_info *tc = SWIG_TypeCheck(types[j].first->name, type);
 	if (!tc)
 	  continue;
-        if(vptr) {
+	if (vptr) {
 	  int newmemory = 0;
 	  *vptr = SWIG_TypeCast(tc, types[j].second.ptr, &newmemory);
-	    if (newmemory == SWIG_CAST_NEW_MEMORY) {
-              assert(_own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
-              if (_own)
-                *_own = *_own | SWIG_CAST_NEW_MEMORY;
-            }
+	  if (newmemory == SWIG_CAST_NEW_MEMORY) {
+	    assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
+	    if (own)
+	      *own = *own | SWIG_CAST_NEW_MEMORY;
+	  }
+	  if (clear_pointer)
+	    types[j].second.ptr = 0;
         }
         res = SWIG_OK;
         break;
@@ -598,7 +660,7 @@
     }
 
     bool is_owned() const {
-      return own;
+      return thisown;
     }
 
 #ifdef SWIG_DIRECTORS
@@ -639,7 +701,11 @@
       return true;
     }
 
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+    virtual bool isstruct() const {
+#else
     virtual bool is_map() const {
+#endif
       return true;
     }
 
@@ -787,7 +853,11 @@
       return as_value();
     }
 
+#if SWIG_OCTAVE_PREREQ(4,4,0)
+    virtual bool isobject() const {
+#else
     virtual bool is_object() const {
+#endif
       return true;
     }
 
@@ -882,7 +952,11 @@
     }
 
     virtual bool load_binary (std::istream& is, bool swap, 
-			      oct_mach_info::float_format fmt) {
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+			      octave::mach_info::float_format fmt) {
+#else
+                             oct_mach_info::float_format fmt) {
+#endif
       return true;
     }
 
@@ -1066,7 +1140,18 @@
     octave_swig_type *ptr;
   public:
     octave_swig_ref(octave_swig_type *_ptr = 0)
-      :ptr(_ptr) { }
+      :ptr(_ptr)
+      {
+        // Ensure type_id() is set correctly
+#if SWIG_OCTAVE_PREREQ(9,0,0)
+        if (s_t_id == -1) {
+          s_t_id = octave_swig_ref::static_type_id();
+#else
+        if (t_id == -1) {
+          t_id = octave_swig_ref::static_type_id();
+#endif
+        }
+      }
 
     ~octave_swig_ref()
       { if (ptr) ptr->decref(); }
@@ -1086,8 +1171,13 @@
     bool is_defined() const
       { return ptr->is_defined(); }
 
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+    virtual bool isstruct() const
+      { return ptr->isstruct(); }
+#else
     virtual bool is_map() const 
       { return ptr->is_map(); }
+#endif
 
     virtual octave_value subsref(const std::string &ops, const std::list < octave_value_list > &idx) 
       { return ptr->subsref(ops, idx); }
@@ -1098,8 +1188,13 @@
     octave_value subsasgn(const std::string &ops, const std::list < octave_value_list > &idx, const octave_value &rhs)
       { return ptr->subsasgn(ops, idx, rhs); }
 
+#if SWIG_OCTAVE_PREREQ(4,4,0)
+    virtual bool isobject() const
+      { return ptr->isobject(); }
+#else
     virtual bool is_object() const 
       { return ptr->is_object(); }
+#endif
 
     virtual bool is_string() const 
       { return ptr->is_string(); }
@@ -1144,7 +1239,11 @@
       { return ptr->save_binary(os, save_as_floats); }
 
     virtual bool load_binary (std::istream& is, bool swap, 
-			      oct_mach_info::float_format fmt)
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+			      octave::mach_info::float_format fmt)
+#else
+                             oct_mach_info::float_format fmt)
+#endif
       { return ptr->load_binary(is, swap, fmt); }
 
 #if defined (HAVE_HDF5)
@@ -1180,6 +1279,14 @@
 #endif
       { return ptr->print(os, pr_as_read_syntax); }
 
+#if SWIG_OCTAVE_PREREQ(9,0,0)
+      static void set_type_id(int type_id) { s_t_id=type_id; }
+#else
+# if SWIG_OCTAVE_PREREQ(4,4,0)
+      static void set_type_id(int type_id) { t_id=type_id; }
+# endif
+#endif
+
     virtual type_conv_info numeric_conversion_function(void) const {
       return octave_base_value::type_conv_info (default_numeric_conversion_function,
                                                 octave_scalar::static_type_id ());
@@ -1207,8 +1314,18 @@
   public:
 
     octave_swig_packed(swig_type_info *_type = 0, const void *_buf = 0, size_t _buf_len = 0)
-      :	type(_type), buf((const char*)_buf, (const char*)_buf + _buf_len) {
-    }
+      :	type(_type), buf((const char*)_buf, (const char*)_buf + _buf_len)
+      {
+        // Ensure type_id() is set correctly
+#if SWIG_OCTAVE_PREREQ(9,0,0)
+        if (s_t_id == -1) {
+          s_t_id = octave_swig_packed::static_type_id();
+#else
+        if (t_id == -1) {
+          t_id = octave_swig_packed::static_type_id();
+#endif
+        }
+      }
 
     bool copy(swig_type_info *outtype, void *ptr, size_t sz) const {
       if (outtype && outtype != type)
@@ -1254,7 +1371,11 @@
     }
 
     virtual bool load_binary (std::istream& is, bool swap, 
-			      oct_mach_info::float_format fmt) {
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+			      octave::mach_info::float_format fmt) {
+#else
+                             oct_mach_info::float_format fmt) {
+#endif
       return true;
     }
 
@@ -1282,6 +1403,14 @@
 # endif
 #endif
 
+#if SWIG_OCTAVE_PREREQ(9,0,0)
+    static void set_type_id(int type_id) { s_t_id=type_id; }
+#else
+# if SWIG_OCTAVE_PREREQ(4,4,0)
+    static void set_type_id(int type_id) { t_id=type_id; }
+# endif
+#endif
+
   private:
 #if !SWIG_OCTAVE_PREREQ(4,0,0)
     DECLARE_OCTAVE_ALLOCATOR;
@@ -1456,12 +1585,15 @@
 SWIGRUNTIME octave_value SWIG_Octave_NewPointerObj(void *ptr, swig_type_info *type, int flags) {
   int own = (flags &SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0;
 
+  if (ptr) {
 #ifdef SWIG_DIRECTORS
-  Swig::Director *d = Swig::get_rtdir(ptr);
-  if (d && Swig::swig_director_get_self(d))
-    return Swig::swig_director_get_self(d)->as_value();
+    Swig::Director *d = Swig::get_rtdir(ptr);
+    if (d && Swig::swig_director_get_self(d))
+      return Swig::swig_director_get_self(d)->as_value();
 #endif
-  return Swig::swig_value_ref(new octave_swig_type(ptr, type, own));
+    return Swig::swig_value_ref(new octave_swig_type(ptr, type, own));
+  }
+  return octave_value(Matrix()); // null matrix
 }
 
 SWIGRUNTIME int SWIG_Octave_ConvertPtrAndOwn(octave_value ov, void **ptr, swig_type_info *type, int flags, int *own) {
@@ -1504,16 +1636,24 @@
 }
 
 SWIGRUNTIMEINLINE octave_value SWIG_Octave_GetGlobalValue(std::string name) {
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+  octave::interpreter *interp = octave::interpreter::the_interpreter ();
+  return interp->global_varval(name);
+#else
 #if SWIG_OCTAVE_PREREQ(4,4,0)
   octave::symbol_table& symtab = octave::interpreter::the_interpreter()->get_symbol_table();
   return symtab.global_varval(name);
 #else
   return get_global_value(name, true);
 #endif
+#endif
 }
 
 SWIGRUNTIME void SWIG_Octave_SetGlobalValue(std::string name, const octave_value& value) {
-#if SWIG_OCTAVE_PREREQ(4,4,0)
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+  octave::interpreter *interp = octave::interpreter::the_interpreter ();
+  interp->global_assign(name, value);
+#elif SWIG_OCTAVE_PREREQ(4,4,0)
   octave::symbol_table& symtab = octave::interpreter::the_interpreter()->get_symbol_table();
   symtab.global_assign(name, value);
 #else
@@ -1523,10 +1663,24 @@
 
 SWIGRUNTIME void SWIG_Octave_LinkGlobalValue(std::string name) {
 #if SWIG_OCTAVE_PREREQ(4,4,0)
-  octave::symbol_table& symtab = octave::interpreter::the_interpreter()->get_symbol_table();
   octave::symbol_scope symscope = octave::interpreter::the_interpreter()->get_current_scope();
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+  octave::interpreter *interp = octave::interpreter::the_interpreter ();
+  interp->assign(name, interp->global_varval(name));
+  octave::tree_evaluator& tree_eval = interp->get_evaluator();
+#if SWIG_OCTAVE_PREREQ(8,0,0)
+  std::shared_ptr<octave::stack_frame> stackFrame = tree_eval.get_current_stack_frame();
+#else
+  octave::call_stack& callStack = tree_eval.get_call_stack();
+  std::shared_ptr<octave::stack_frame> stackFrame = tree_eval.get_current_stack_frame();
+#endif
+  octave::symbol_record sym=symscope.lookup_symbol(name);
+  stackFrame->mark_global(sym);
+#else
+  octave::symbol_table& symtab = octave::interpreter::the_interpreter()->get_symbol_table();
   symscope.assign(name, symtab.global_varval(name));
   symscope.mark_global(name);
+#endif
 #else
 #if !SWIG_OCTAVE_PREREQ(3,2,0)
   link_to_global_variable(curr_sym_tab->lookup(name, true));
diff --git a/Lib/octave/octruntime.swg b/Lib/octave/octruntime.swg
index f98bf4f..94e2ca4 100644
--- a/Lib/octave/octruntime.swg
+++ b/Lib/octave/octruntime.swg
@@ -1,111 +1,10 @@
+#ifdef SWIG_OCTAVE_EXTERNAL_OCTHEADERS
 %insert(runtime) %{
-
-#include <cstdlib>
-#include <iostream>
-
-#include <octave/oct.h>
-#include <octave/version.h>
-
-// Macro for enabling features which require Octave version >= major.minor.patch
-// - Use (OCTAVE_PATCH_VERSION + 0) to handle both '<digit>' (released) and '<digit>+' (in development) patch numbers
-#define SWIG_OCTAVE_PREREQ(major, minor, patch) \
-  ( (OCTAVE_MAJOR_VERSION<<16) + (OCTAVE_MINOR_VERSION<<8) + (OCTAVE_PATCH_VERSION + 0) >= ((major)<<16) + ((minor)<<8) + (patch) )
-
-// Reconstruct Octave major, minor, and patch versions for releases prior to 3.8.1
-#if !defined(OCTAVE_MAJOR_VERSION)
-
-# if !defined(OCTAVE_API_VERSION_NUMBER)
-
-// Hack to distinguish between Octave 3.8.0, which removed OCTAVE_API_VERSION_NUMBER but did not yet
-// introduce OCTAVE_MAJOR_VERSION, and Octave <= 3.2, which did not define OCTAVE_API_VERSION_NUMBER
-#  include <octave/ov.h>
-#  if defined(octave_ov_h)
-#   define OCTAVE_MAJOR_VERSION 3
-#   define OCTAVE_MINOR_VERSION 8
-#   define OCTAVE_PATCH_VERSION 0
-#  else
-
-// Hack to distinguish between Octave 3.2 and earlier versions, before OCTAVE_API_VERSION_NUMBER existed
-#   define ComplexLU __ignore
-#   include <octave/CmplxLU.h>
-#   undef ComplexLU
-#   if defined(octave_Complex_LU_h)
-
-// We know only that this version is prior to Octave 3.2, i.e. OCTAVE_API_VERSION_NUMBER < 37
-#    define OCTAVE_MAJOR_VERSION 3
-#    define OCTAVE_MINOR_VERSION 1
-#    define OCTAVE_PATCH_VERSION 99
-
-#   else
-
-// OCTAVE_API_VERSION_NUMBER == 37
-#    define OCTAVE_MAJOR_VERSION 3
-#    define OCTAVE_MINOR_VERSION 2
-#    define OCTAVE_PATCH_VERSION 0
-
-#   endif // defined(octave_Complex_LU_h)
-
-#  endif // defined(octave_ov_h)
-
-// Correlation between Octave API and version numbers extracted from Octave's
-// ChangeLogs; version is the *earliest* released Octave with that API number
-# elif OCTAVE_API_VERSION_NUMBER >= 48
-#  define OCTAVE_MAJOR_VERSION 3
-#  define OCTAVE_MINOR_VERSION 6
-#  define OCTAVE_PATCH_VERSION 0
-
-# elif OCTAVE_API_VERSION_NUMBER >= 45
-#  define OCTAVE_MAJOR_VERSION 3
-#  define OCTAVE_MINOR_VERSION 4
-#  define OCTAVE_PATCH_VERSION 1
-
-# elif OCTAVE_API_VERSION_NUMBER >= 42
-#  define OCTAVE_MAJOR_VERSION 3
-#  define OCTAVE_MINOR_VERSION 3
-#  define OCTAVE_PATCH_VERSION 54
-
-# elif OCTAVE_API_VERSION_NUMBER >= 41
-#  define OCTAVE_MAJOR_VERSION 3
-#  define OCTAVE_MINOR_VERSION 3
-#  define OCTAVE_PATCH_VERSION 53
-
-# elif OCTAVE_API_VERSION_NUMBER >= 40
-#  define OCTAVE_MAJOR_VERSION 3
-#  define OCTAVE_MINOR_VERSION 3
-#  define OCTAVE_PATCH_VERSION 52
-
-# elif OCTAVE_API_VERSION_NUMBER >= 39
-#  define OCTAVE_MAJOR_VERSION 3
-#  define OCTAVE_MINOR_VERSION 3
-#  define OCTAVE_PATCH_VERSION 51
-
-# else // OCTAVE_API_VERSION_NUMBER == 38
-#  define OCTAVE_MAJOR_VERSION 3
-#  define OCTAVE_MINOR_VERSION 3
-#  define OCTAVE_PATCH_VERSION 50
-
-# endif // !defined(OCTAVE_API_VERSION_NUMBER)
-
-#endif // !defined(OCTAVE_MAJOR_VERSION)
-
-#include <octave/Cell.h>
-#include <octave/dynamic-ld.h>
-#include <octave/oct-env.h>
-#include <octave/oct-map.h>
-#include <octave/ov-scalar.h>
-#include <octave/ov-fcn-handle.h>
-#include <octave/parse.h>
-#if SWIG_OCTAVE_PREREQ(4,2,0)
-#include <octave/interpreter.h>
-#else
-#include <octave/toplev.h>
-#endif
-#include <octave/unwind-prot.h>
-#if SWIG_OCTAVE_PREREQ(4,2,0)
-#include <octave/call-stack.h>
-#endif
-
+#include "octheaders.hpp"
 %}
+#else
+%insert(runtime) "octheaders.hpp";
+#endif
 
 %insert(runtime) "swigrun.swg";
 %insert(runtime) "swigerrors.swg";
@@ -120,7 +19,8 @@
 SWIGINTERN bool SWIG_Octave_LoadModule(std::string name) {
   bool retn = false;
   {
-#if SWIG_OCTAVE_PREREQ(4,2,0)
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+#elif SWIG_OCTAVE_PREREQ(4,2,0)
     octave::unwind_protect frame;
     frame.protect_var(discard_error_messages);          discard_error_messages = true;
     frame.protect_var(discard_warning_messages);        discard_warning_messages = true;
@@ -163,7 +63,8 @@
 SWIGINTERN bool SWIG_Octave_InstallFunction(octave_function *octloadfcn, std::string name) {
   bool retn = false;
   {
-#if SWIG_OCTAVE_PREREQ(4,2,0)
+#if SWIG_OCTAVE_PREREQ(6,0,0)
+#elif SWIG_OCTAVE_PREREQ(4,2,0)
     octave::unwind_protect frame;
     frame.protect_var(discard_error_messages);          discard_error_messages = true;
     frame.protect_var(discard_warning_messages);        discard_warning_messages = true;
@@ -315,13 +216,29 @@
   return octave_value(prereq);
 }
 
+static const char *const swig_exit_usage = "-*- texinfo -*- \n\
+@deftypefn {Loadable Function} {} swig_exit([@var{exit_status}])\n\
+Exit Octave without performing any memory cleanup.\n\
+@end deftypefn";
+
+DEFUN_DLD( swig_exit, args, nargout, swig_exit_usage ) {
+  if (args.length() > 1) {
+    error("swig_exit: must be called with at most one arguments");
+    return octave_value_list();
+  }
+  int exit_status = 0;
+  if (args.length() == 1) {
+    exit_status = args(0).int_value();
+  }
+  ::_Exit(exit_status);
+  return octave_value();
+}
+
 static const char *const SWIG_name_usage = "-*- texinfo -*- \n\
 @deftypefn {Loadable Module} {} " SWIG_name_d "\n\
 Loads the SWIG-generated module `" SWIG_name_d "'.\n\
 @end deftypefn";
 
-void __swig_atexit__(void) { ::_Exit(0); }
-
 DEFUN_DLD( SWIG_name, args, nargout, SWIG_name_usage ) {
 
   static octave_swig_type* module_ns = 0;
@@ -329,15 +246,16 @@
   // workaround to prevent octave seg-faulting on exit: set Octave exit function
   // octave_exit to _Exit, which exits immediately without trying to cleanup memory.
   // definitely affected version 3.2.*, not sure about 3.3.*, seems to be fixed in
-  // version 3.4.*, but reappeared in 4.2.*, so turn on for all versions after 3.2.*.
+  // version 3.4.*, reappeared in 4.2.*, hack not possible in 4.4.* or later due to
+  // removal of octave_exit, so turn on for all versions between 3.2.*. and 4.4.*.
   // can be turned off with macro definition.
 #ifndef SWIG_OCTAVE_NO_SEGFAULT_HACK
-#if SWIG_OCTAVE_PREREQ(4,4,0)
-  atexit(__swig_atexit__);
-#elif SWIG_OCTAVE_PREREQ(3,2,0)
+#if !SWIG_OCTAVE_PREREQ(4,4,0)
+#if SWIG_OCTAVE_PREREQ(3,2,0)
   octave_exit = ::_Exit;
 #endif
 #endif
+#endif
 
   // check for no input and output args
   if (args.length() != 0 || nargout != 0) {
@@ -376,16 +294,14 @@
       string_vector types = typeinfo.installed_type_names();
       bool register_octave_swig_ref = true;
       bool register_octave_swig_packed = true;
-      bool register_octave_swig_bound_func = true;
       for (int i = 0; i < types.numel(); ++i) {
         if (types(i) == octave_swig_ref::static_type_name()) {
           register_octave_swig_ref = false;
+          octave_swig_ref::set_type_id(i);
         }
         if (types(i) == octave_swig_packed::static_type_name()) {
           register_octave_swig_packed = false;
-        }
-        if (types(i) == octave_swig_bound_func::static_type_name()) {
-          register_octave_swig_bound_func = false;
+	  octave_swig_packed::set_type_id(i);
         }
       }
       if (register_octave_swig_ref) {
@@ -394,9 +310,6 @@
       if (register_octave_swig_packed) {
         octave_swig_packed::register_type();
       }
-      if (register_octave_swig_bound_func) {
-        octave_swig_bound_func::register_type();
-      }
     }
 #else
     octave_swig_ref::register_type();
@@ -405,7 +318,14 @@
     SWIG_InitializeModule(0);
     SWIG_PropagateClientData();
 
-#if SWIG_OCTAVE_PREREQ(4,4,0)
+#if SWIG_OCTAVE_PREREQ(8,0,0)
+    octave::tree_evaluator& tree_eval = octave::interpreter::the_interpreter()->get_evaluator();
+    octave_function *me = tree_eval.current_function();
+#elif SWIG_OCTAVE_PREREQ(6,0,0)
+    octave::tree_evaluator& tree_eval = octave::interpreter::the_interpreter()->get_evaluator();
+    octave::call_stack& stack = tree_eval.get_call_stack();
+    octave_function *me = stack.current_function();
+#elif SWIG_OCTAVE_PREREQ(4,4,0)
     octave::call_stack& stack = octave::interpreter::the_interpreter()->get_call_stack();
     octave_function *me = stack.current();
 #else
@@ -427,6 +347,9 @@
     if (!SWIG_Octave_InstallFunction(me, "swig_octave_prereq")) {
       return octave_value_list();
     }
+    if (!SWIG_Octave_InstallFunction(me, "swig_exit")) {
+      return octave_value_list();
+    }
 
     octave_swig_type* cvar_ns=0;
     if (std::string(SWIG_global_name) != ".") {
diff --git a/Lib/octave/octtypemaps.swg b/Lib/octave/octtypemaps.swg
index 4acf8e0..4984fdd 100644
--- a/Lib/octave/octtypemaps.swg
+++ b/Lib/octave/octtypemaps.swg
@@ -32,8 +32,15 @@
 #define SWIG_SetConstant(name, obj)     SWIG_Octave_SetConstant(module_ns,name,obj) 
 
 // raise
-#define SWIG_Octave_Raise(OBJ, TYPE, DESC) error("C++ side threw an exception of type " TYPE)
-#define SWIG_Raise(obj, type, desc)     SWIG_Octave_Raise(obj, type, desc)
+%runtime %{
+SWIGINTERN void SWIG_Octave_Raise(const octave_value &obj, const char *type) {
+  if (obj.is_string())
+    error("%s", obj.string_value().c_str());
+  else
+    error("C++ side threw an exception of type %s", type);
+}
+%}
+#define SWIG_Raise(obj, type, desc)     SWIG_Octave_Raise(obj, type)
 
 // Include the unified typemap library
 %include <typemaps/swigtypemaps.swg>
diff --git a/Lib/octave/std_auto_ptr.i b/Lib/octave/std_auto_ptr.i
new file mode 100644
index 0000000..3d7ae8b
--- /dev/null
+++ b/Lib/octave/std_auto_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+  %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class auto_ptr {};
+}
diff --git a/Lib/octave/std_carray.i b/Lib/octave/std_carray.i
deleted file mode 100644
index e69de29..0000000
--- a/Lib/octave/std_carray.i
+++ /dev/null
diff --git a/Lib/octave/std_complex.i b/Lib/octave/std_complex.i
index 30c1882..461e2fd 100644
--- a/Lib/octave/std_complex.i
+++ b/Lib/octave/std_complex.i
@@ -4,10 +4,6 @@
 
 %include <octcomplex.swg>
 
-%{
-#include <complex> 
-%}
-
 namespace std {
   %naturalvar complex;
   template<typename T> class complex;
diff --git a/Lib/octave/std_unique_ptr.i b/Lib/octave/std_unique_ptr.i
new file mode 100644
index 0000000..f988714
--- /dev/null
+++ b/Lib/octave/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+  %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class unique_ptr {};
+}
diff --git a/Lib/octave/swigmove.i b/Lib/octave/swigmove.i
new file mode 100644
index 0000000..62ecca7
--- /dev/null
+++ b/Lib/octave/swigmove.i
@@ -0,0 +1 @@
+%include <typemaps/swigmove.swg>
diff --git a/Lib/perl5/argcargv.i b/Lib/perl5/argcargv.i
new file mode 100644
index 0000000..ee23813
--- /dev/null
+++ b/Lib/perl5/argcargv.i
@@ -0,0 +1,30 @@
+/* -------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------- */
+
+%typemap(in) (int ARGC, char **ARGV) {
+  int i;
+  SSize_t len;
+  AV *av = (AV *)SvRV($input);
+  if (SvTYPE(av) != SVt_PVAV) {
+    SWIG_croak("in method '$symname', Expecting reference to argv array");
+    goto fail;
+  }
+  len = av_len(av) + 1;
+  $1 = ($1_ltype) len;
+  $2 = (char **) malloc((len+1)*sizeof(char *));
+  for (i = 0; i < len; i++) {
+    SV **tv = av_fetch(av, i, 0);
+    $2[i] = SvPV_nolen(*tv);
+  }
+  $2[i] = NULL;
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+  AV *av = (AV *)SvRV($input);
+  $1 = SvTYPE(av) == SVt_PVAV;
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+  free((void *)$2);
+}
diff --git a/Lib/perl5/carrays.i b/Lib/perl5/carrays.i
index 8be67ab..c1e6db3 100644
--- a/Lib/perl5/carrays.i
+++ b/Lib/perl5/carrays.i
@@ -1,2 +1 @@
 %include <typemaps/carrays.swg>
-
diff --git a/Lib/perl5/perlhead.swg b/Lib/perl5/perlhead.swg
index 5437af5..11ea50a 100644
--- a/Lib/perl5/perlhead.swg
+++ b/Lib/perl5/perlhead.swg
@@ -4,26 +4,27 @@
 #include <stdlib.h>
 extern "C" {
 #endif
+
+#if __GNUC__ >= 10
+#if defined(__cplusplus)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wvolatile"
+#endif
+#endif
+
 #include "EXTERN.h"
 #include "perl.h"
 #include "XSUB.h"
 
-/* Add in functionality missing in older versions of Perl. Much of this is based on Devel-PPPort on cpan. */
+#if __GNUC__ >= 10
+#if defined(__cplusplus)
+#pragma GCC diagnostic pop
+#endif
+#endif
 
-/* Add PERL_REVISION, PERL_VERSION, PERL_SUBVERSION if missing */
-#ifndef PERL_REVISION
-#  if !defined(__PATCHLEVEL_H_INCLUDED__) && !(defined(PATCHLEVEL) && defined(SUBVERSION))
-#    define PERL_PATCHLEVEL_H_IMPLICIT
-#    include <patchlevel.h>
-#  endif
-#  if !(defined(PERL_VERSION) || (defined(SUBVERSION) && defined(PATCHLEVEL)))
-#    include <could_not_find_Perl_patchlevel.h>
-#  endif
-#  ifndef PERL_REVISION
-#    define PERL_REVISION       (5)
-#    define PERL_VERSION        PATCHLEVEL
-#    define PERL_SUBVERSION     SUBVERSION
-#  endif
+/* PERL_REVISION was added in Perl 5.6. */
+#if !defined PERL_REVISION || (PERL_REVISION-0 == 5 && PERL_VERSION-0 < 8)
+# error SWIG requires Perl >= 5.8.0
 #endif
 
 #if defined(WIN32) && defined(PERL_OBJECT) && !defined(PerlIO_exportFILE)
@@ -38,15 +39,6 @@
 # define SvUOK(sv)           SvIOK_UV(sv)
 #endif
 
-#if ((PERL_VERSION < 4) || ((PERL_VERSION == 4) && (PERL_SUBVERSION <= 5)))
-#  define PL_sv_undef               sv_undef
-#  define PL_na	                    na
-#  define PL_errgv                  errgv
-#  define PL_sv_no                  sv_no
-#  define PL_sv_yes                 sv_yes
-#  define PL_markstack_ptr          markstack_ptr
-#endif
-
 #ifndef IVSIZE
 #  ifdef LONGSIZE
 #    define IVSIZE LONGSIZE
diff --git a/Lib/perl5/perlinit.swg b/Lib/perl5/perlinit.swg
index b49040d..c26b93f 100644
--- a/Lib/perl5/perlinit.swg
+++ b/Lib/perl5/perlinit.swg
@@ -4,15 +4,11 @@
 #ifdef __cplusplus
 extern "C"
 #endif
-#ifndef PERL_OBJECT
 #ifndef MULTIPLICITY
 SWIGEXPORT void SWIG_init (CV* cv);
 #else
 SWIGEXPORT void SWIG_init (pTHXo_ CV* cv);
 #endif
-#else
-SWIGEXPORT void SWIG_init (CV *cv, CPerlObj *);
-#endif
 %}
 
 /* Module initialization function */
diff --git a/Lib/perl5/perlmain.i b/Lib/perl5/perlmain.i
index 18ecb7e..14f1cf2 100644
--- a/Lib/perl5/perlmain.i
+++ b/Lib/perl5/perlmain.i
@@ -4,25 +4,20 @@
  * Code to statically rebuild perl5.
  * ----------------------------------------------------------------------------- */
 
-#ifdef AUTODOC
-%subsection "perlmain.i"
-%text %{
-This module provides support for building a new version of the
-Perl executable.  This will be necessary on systems that do
-not support shared libraries and may be necessary with C++
-extensions.  
-
-This module may only build a stripped down version of the
-Perl executable.   Thus, it may be necessary (or desirable)
-to hand-edit this file for your particular application.  To
-do this, simply copy this file from swig_lib/perl5/perlmain.i
-to your working directory and make the appropriate modifications.
-
-This library file works with Perl 5.003.  It may work with earlier
-versions, but it hasn't been tested.  As far as I know, this
-library is C++ safe.
-%}
-#endif
+// This module provides support for building a new version of the
+// Perl executable.  This will be necessary on systems that do
+// not support shared libraries and may be necessary with C++
+// extensions.
+//
+// This module may only build a stripped down version of the
+// Perl executable.   Thus, it may be necessary (or desirable)
+// to hand-edit this file for your particular application.  To
+// do this, simply copy this file from swig_lib/perl5/perlmain.i
+// to your working directory and make the appropriate modifications.
+//
+// This library file works with Perl 5.003.  It may work with earlier
+// versions, but it hasn't been tested.  As far as I know, this
+// library is C++ safe.
 
 %{
 
diff --git a/Lib/perl5/perlprimtypes.swg b/Lib/perl5/perlprimtypes.swg
index 4cb6756..57f390a 100644
--- a/Lib/perl5/perlprimtypes.swg
+++ b/Lib/perl5/perlprimtypes.swg
@@ -179,7 +179,7 @@
   else {
     //sv = newSVpvf("%lld", value); doesn't work in non 64bit Perl
     char temp[256];
-    sprintf(temp, "%lld", value);
+    SWIG_snprintf(temp, sizeof(temp), "%lld", value);
     sv = newSVpv(temp, 0);
   }
   return sv_2mortal(sv);
@@ -259,7 +259,7 @@
   else {
     //sv = newSVpvf("%llu", value); doesn't work in non 64bit Perl
     char temp[256];
-    sprintf(temp, "%llu", value);
+    SWIG_snprintf(temp, sizeof(temp), "%llu", value);
     sv = newSVpv(temp, 0);
   }
   return sv_2mortal(sv);
@@ -280,7 +280,7 @@
      * (UVSIZE <= sizeof(*val) || v <= ULLONG_MAX) */
     if (val) *val = SvUV(obj);
     return SWIG_OK;
-  } else  if (SvIOK(obj)) {
+  } else if (SvIOK(obj)) {
     IV v = SvIV(obj);
     if (v >= 0 && (IVSIZE <= sizeof(*val) || v <= ULLONG_MAX)) {
       if (val) *val = v;
diff --git a/Lib/perl5/perlrun.swg b/Lib/perl5/perlrun.swg
index b04002f..dfb2c8e 100644
--- a/Lib/perl5/perlrun.swg
+++ b/Lib/perl5/perlrun.swg
@@ -6,13 +6,8 @@
  * type checking.
  * ----------------------------------------------------------------------------- */
 
-#ifdef PERL_OBJECT
-#define SWIG_PERL_OBJECT_DECL CPerlObj *SWIGUNUSEDPARM(pPerl),
-#define SWIG_PERL_OBJECT_CALL pPerl,
-#else
 #define SWIG_PERL_OBJECT_DECL
 #define SWIG_PERL_OBJECT_CALL
-#endif
 
 /* Common SWIG API */
 
@@ -88,31 +83,11 @@
 #endif
 
 /* Macro to call an XS function */
-#ifdef PERL_OBJECT 
-#  define SWIG_CALLXS(_name) _name(cv,pPerl) 
-#else 
-#  ifndef MULTIPLICITY 
-#    define SWIG_CALLXS(_name) _name(cv) 
-#  else 
-#    define SWIG_CALLXS(_name) _name(PERL_GET_THX, cv) 
-#  endif 
-#endif 
-
-#ifdef PERL_OBJECT
-#define MAGIC_PPERL  CPerlObj *pPerl = (CPerlObj *) this;
-
-#ifdef __cplusplus
-extern "C" {
+#ifndef MULTIPLICITY
+#  define SWIG_CALLXS(_name) _name(cv)
+#else
+#  define SWIG_CALLXS(_name) _name(PERL_GET_THX, cv)
 #endif
-typedef int (CPerlObj::*SwigMagicFunc)(SV *, MAGIC *);
-#ifdef __cplusplus
-}
-#endif
-
-#define SWIG_MAGIC(a,b) (SV *a, MAGIC *b)
-#define SWIGCLASS_STATIC
-
-#else /* PERL_OBJECT */
 
 #define MAGIC_PPERL
 #define SWIGCLASS_STATIC static SWIGUNUSED
@@ -141,24 +116,14 @@
 #endif
 
 #endif /* MULTIPLICITY */
-#endif /* PERL_OBJECT */
 
-#  ifdef PERL_OBJECT
-#    define SWIG_croak_null() SWIG_Perl_croak_null(pPerl)
-static void SWIGUNUSED SWIG_Perl_croak_null(CPerlObj *pPerl)
-#  else
 static void SWIGUNUSED SWIG_croak_null()
-#  endif
 {
   SV *err = get_sv("@", GV_ADD);
-#  if (PERL_VERSION < 6)
-  croak("%_", err);
-#  else
   if (sv_isobject(err))
     croak(0);
   else
     croak("%s", SvPV_nolen(err));
-#  endif
 }
 
 
@@ -233,7 +198,7 @@
 /* Acquire a pointer value */
 
 SWIGRUNTIME int
-SWIG_Perl_AcquirePtr(SWIG_MAYBE_PERL_OBJECT SV *sv, int own) {
+SWIG_Perl_AcquirePtr(SWIG_MAYBE_PERL_OBJECT SV *SWIGUNUSEDPARM(sv), int SWIGUNUSEDPARM(own)) {
   /* TODO */
   return 0;
 }
@@ -245,6 +210,7 @@
   swig_cast_info *tc;
   void *voidptr = (void *)0;
   SV *tsv = 0;
+  int check_owned_pointer_release = (flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE;
 
   if (own)
     *own = 0;
@@ -321,13 +287,14 @@
   /* 
    *  DISOWN implementation: we need a perl guru to check this one.
    */
-  if (tsv && (flags & SWIG_POINTER_DISOWN)) {
+  if (tsv && ((flags & SWIG_POINTER_DISOWN) || check_owned_pointer_release)) {
     /* 
      *  almost copy paste code from below SWIG_POINTER_OWN setting
      */
     SV *obj = sv;
     HV *stash = SvSTASH(SvRV(obj));
     GV *gv = *(GV**)hv_fetch(stash, "OWNER", 5, TRUE);
+    int owned = 0;
     if (isGV(gv)) {
       HV *hv = GvHVn(gv);
       /*
@@ -335,10 +302,21 @@
        * Hence, to remove ownership, we delete the entry.
        */
       if (hv_exists_ent(hv, obj, 0)) {
-	hv_delete_ent(hv, obj, 0, 0);
+        owned = 1;
+        if (flags & SWIG_POINTER_DISOWN) {
+          hv_delete_ent(hv, obj, 0, 0);
+        }
       }
     }
+    if (check_owned_pointer_release && !owned) {
+      return SWIG_ERROR_RELEASE_NOT_OWNED;
+    }
   }
+
+  if (tsv && (flags & SWIG_POINTER_CLEAR)) {
+    SvIV_set(tsv, 0);
+  }
+
   return SWIG_OK;
 }
 
@@ -462,24 +440,19 @@
 } swig_variable_info;
 
 /* Magic variable code */
-#ifndef PERL_OBJECT
-# ifdef __cplusplus
+#ifdef __cplusplus
 #  define swig_create_magic(s,a,b,c) _swig_create_magic(s,const_cast<char*>(a),b,c)
-# else
-#  define swig_create_magic(s,a,b,c) _swig_create_magic(s,(char*)(a),b,c)
-# endif
-# ifndef MULTIPLICITY
-SWIGRUNTIME void _swig_create_magic(SV *sv, char *name, int (*set)(SV *, MAGIC *), int (*get)(SV *,MAGIC *)) 
-# else
-SWIGRUNTIME void _swig_create_magic(SV *sv, char *name, int (*set)(struct interpreter*, SV *, MAGIC *), int (*get)(struct interpreter*, SV *,MAGIC *)) 
-# endif
 #else
-#  define swig_create_magic(s,a,b,c) _swig_create_magic(pPerl,s,a,b,c)
-SWIGRUNTIME void _swig_create_magic(CPerlObj *pPerl, SV *sv, const char *name, int (CPerlObj::*set)(SV *, MAGIC *), int (CPerlObj::*get)(SV *, MAGIC *)) 
+#  define swig_create_magic(s,a,b,c) _swig_create_magic(s,(char*)(a),b,c)
+#endif
+#ifndef MULTIPLICITY
+SWIGRUNTIME void _swig_create_magic(SV *sv, char *name, int (*set)(SV *, MAGIC *), int (*get)(SV *,MAGIC *))
+#else
+SWIGRUNTIME void _swig_create_magic(SV *sv, char *name, int (*set)(struct interpreter*, SV *, MAGIC *), int (*get)(struct interpreter*, SV *,MAGIC *))
 #endif
 {
   MAGIC *mg;
-  sv_magic(sv,sv,'U',name,strlen(name));
+  sv_magic(sv,sv,'U',name,(I32)strlen(name));
   mg = mg_find(sv,'U');
   mg->mg_virtual = (MGVTBL *) malloc(sizeof(MGVTBL));
   mg->mg_virtual->svt_get = (SwigMagicFunc) get;
diff --git a/Lib/perl5/perlstrings.swg b/Lib/perl5/perlstrings.swg
index 242a9c9..d21b75a 100644
--- a/Lib/perl5/perlstrings.swg
+++ b/Lib/perl5/perlstrings.swg
@@ -15,7 +15,7 @@
     STRLEN len = 0;
     char *cstr = SvPV(obj, len); 
     size_t size = len + 1;
-    if (cptr)  {
+    if (cptr) {
       if (alloc) {
 	if (*alloc == SWIG_NEWOBJ) {
 	  *cptr = %new_copy_array(cstr, size, char);
diff --git a/Lib/perl5/perltypemaps.swg b/Lib/perl5/perltypemaps.swg
index bf1596e..42f8887 100644
--- a/Lib/perl5/perltypemaps.swg
+++ b/Lib/perl5/perltypemaps.swg
@@ -56,7 +56,9 @@
 %define %set_output(obj) $result = obj; argvi++ %enddef
 
 /* append output */
-%define %append_output(obj) if (argvi >= items) EXTEND(sp, argvi+1); %set_output(obj) %enddef
+%define %append_output(obj)
+if (argvi >= items) EXTEND(sp, argvi+1);
+%set_output(obj) %enddef
 
 /* variable output */
 %define %set_varoutput(obj) sv_setsv($result,obj)  %enddef
@@ -95,7 +97,7 @@
     "sv_setiv(SvRV($result), PTR2IV(&$1));";
 
 %typemap(varout,type="$1_descriptor") SWIGTYPE (CLASS::*) {
-  SWIG_MakePackedObj($result, (void *) &$1, sizeof($1_type), $1_descriptor);
+  SWIG_MakePackedObj($result, (void *) &$1, sizeof($1), $1_descriptor);
 }
 
 %typemap(varout) SWIGTYPE *const = SWIGTYPE *;
diff --git a/Lib/perl5/std_auto_ptr.i b/Lib/perl5/std_auto_ptr.i
new file mode 100644
index 0000000..3d7ae8b
--- /dev/null
+++ b/Lib/perl5/std_auto_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+  %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class auto_ptr {};
+}
diff --git a/Lib/perl5/std_list.i b/Lib/perl5/std_list.i
index 36678ad..76f789b 100644
--- a/Lib/perl5/std_list.i
+++ b/Lib/perl5/std_list.i
@@ -55,7 +55,7 @@
                     SWIG_croak("Type error in argument $argnum of $symname. "
                                "Expected an array of " #T);
                 SV **tv;
-                I32 len = av_len(av) + 1;
+                SSize_t len = av_len(av) + 1;
                 T* obj;
                 for (int i=0; i<len; i++) {
                     tv = av_fetch(av, i, 0);
@@ -86,7 +86,7 @@
                     SWIG_croak("Type error in argument $argnum of $symname. "
                                "Expected an array of " #T);
                 SV **tv;
-                I32 len = av_len(av) + 1;
+                SSize_t len = av_len(av) + 1;
                 T* obj;
                 for (int i=0; i<len; i++) {
                     tv = av_fetch(av, i, 0);
@@ -134,7 +134,7 @@
                     AV *av = (AV *)SvRV($input);
                     if (SvTYPE(av) == SVt_PVAV) {
                         SV **tv;
-                        I32 len = av_len(av) + 1;
+                        SSize_t len = av_len(av) + 1;
                         if (len == 0) {
                             /* an empty sequence can be of any type */
                             $1 = 1;
@@ -167,7 +167,7 @@
                     AV *av = (AV *)SvRV($input);
                     if (SvTYPE(av) == SVt_PVAV) {
                         SV **tv;
-                        I32 len = av_len(av) + 1;
+                        SSize_t len = av_len(av) + 1;
                         if (len == 0) {
                             /* an empty sequence can be of any type */
                             $1 = 1;
@@ -221,7 +221,7 @@
                     SWIG_croak("Type error in argument $argnum of $symname. "
                                "Expected an array of " #T);
                 SV **tv;
-                I32 len = av_len(av) + 1;
+                SSize_t len = av_len(av) + 1;
                 for (int i=0; i<len; i++) {
                     tv = av_fetch(av, i, 0);
                     if (CHECK_T(*tv)) {
@@ -250,7 +250,7 @@
                     SWIG_croak("Type error in argument $argnum of $symname. "
                                "Expected an array of " #T);
                 SV **tv;
-                I32 len = av_len(av) + 1;
+                SSize_t len = av_len(av) + 1;
                 T* obj;
                 for (int i=0; i<len; i++) {
                     tv = av_fetch(av, i, 0);
@@ -295,7 +295,7 @@
                     AV *av = (AV *)SvRV($input);
                     if (SvTYPE(av) == SVt_PVAV) {
                         SV **tv;
-                        I32 len = av_len(av) + 1;
+                        SSize_t len = av_len(av) + 1;
                         if (len == 0) {
                             /* an empty sequence can be of any type */
                             $1 = 1;
@@ -326,7 +326,7 @@
                     AV *av = (AV *)SvRV($input);
                     if (SvTYPE(av) == SVt_PVAV) {
                         SV **tv;
-                        I32 len = av_len(av) + 1;
+                        SSize_t len = av_len(av) + 1;
                         if (len == 0) {
                             /* an empty sequence can be of any type */
                             $1 = 1;
diff --git a/Lib/perl5/std_map.i b/Lib/perl5/std_map.i
index 1b37318..7d8103c 100644
--- a/Lib/perl5/std_map.i
+++ b/Lib/perl5/std_map.i
@@ -48,7 +48,11 @@
                     throw std::out_of_range("key not found");
             }
             void set(const K& key, const T& x) {
+%#ifdef __cpp_lib_map_try_emplace
+                (*self).insert_or_assign(key, x);
+%#else
                 (*self)[key] = x;
+%#endif
             }
             void del(const K& key) throw (std::out_of_range) {
                 std::map< K, T, C >::iterator i = self->find(key);
@@ -64,17 +68,4 @@
         }
     };
 
-// Legacy macros (deprecated)
-%define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_key ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_value ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO)
-#warning "specialize_std_map_on_both ignored - macro is deprecated and no longer necessary"
-%enddef
-
 }
diff --git a/Lib/perl5/std_string_view.i b/Lib/perl5/std_string_view.i
new file mode 100644
index 0000000..b1afffc
--- /dev/null
+++ b/Lib/perl5/std_string_view.i
@@ -0,0 +1,2 @@
+%include <perlstrings.swg>
+%include <typemaps/std_string_view.swg>
diff --git a/Lib/perl5/std_unique_ptr.i b/Lib/perl5/std_unique_ptr.i
new file mode 100644
index 0000000..f988714
--- /dev/null
+++ b/Lib/perl5/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+  %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class unique_ptr {};
+}
diff --git a/Lib/perl5/std_vector.i b/Lib/perl5/std_vector.i
index 5bfd2c5..06bc6f3 100644
--- a/Lib/perl5/std_vector.i
+++ b/Lib/perl5/std_vector.i
@@ -51,7 +51,7 @@
                     SWIG_croak("Type error in argument $argnum of $symname. "
                                "Expected an array of " #T);
                 SV **tv;
-                I32 len = av_len(av) + 1;
+                SSize_t len = av_len(av) + 1;
                 T* obj;
                 for (int i=0; i<len; i++) {
                     tv = av_fetch(av, i, 0);
@@ -82,7 +82,7 @@
                     SWIG_croak("Type error in argument $argnum of $symname. "
                                "Expected an array of " #T);
                 SV **tv;
-                I32 len = av_len(av) + 1;
+                SSize_t len = av_len(av) + 1;
                 T* obj;
                 for (int i=0; i<len; i++) {
                     tv = av_fetch(av, i, 0);
@@ -127,7 +127,7 @@
                     /* native sequence? */
                     AV *av = (AV *)SvRV($input);
                     if (SvTYPE(av) == SVt_PVAV) {
-                        I32 len = av_len(av) + 1;
+                        SSize_t len = av_len(av) + 1;
                         if (len == 0) {
                             /* an empty sequence can be of any type */
                             $1 = 1;
@@ -159,7 +159,7 @@
                     /* native sequence? */
                     AV *av = (AV *)SvRV($input);
                     if (SvTYPE(av) == SVt_PVAV) {
-                        I32 len = av_len(av) + 1;
+                        SSize_t len = av_len(av) + 1;
                         if (len == 0) {
                             /* an empty sequence can be of any type */
                             $1 = 1;
@@ -233,7 +233,7 @@
                 if (SvTYPE(av) != SVt_PVAV)
                     SWIG_croak("Type error in argument $argnum of $symname. "
                                "Expected an array of " #T);
-                I32 len = av_len(av) + 1;
+                SSize_t len = av_len(av) + 1;
                 for (int i=0; i<len; i++) {
 		    void *v;
 		    SV **tv = av_fetch(av, i, 0);
@@ -261,7 +261,7 @@
                 if (SvTYPE(av) != SVt_PVAV)
                     SWIG_croak("Type error in argument $argnum of $symname. "
                                "Expected an array of " #T);
-                I32 len = av_len(av) + 1;
+                SSize_t len = av_len(av) + 1;
                 for (int i=0; i<len; i++) {
 		    void *v;
 		    SV **tv = av_fetch(av, i, 0);
@@ -305,7 +305,7 @@
                     /* native sequence? */
                     AV *av = (AV *)SvRV($input);
                     if (SvTYPE(av) == SVt_PVAV) {
-                        I32 len = av_len(av) + 1;
+                        SSize_t len = av_len(av) + 1;
                         if (len == 0) {
                             /* an empty sequence can be of any type */
                             $1 = 1;
@@ -336,7 +336,7 @@
                     /* native sequence? */
                     AV *av = (AV *)SvRV($input);
                     if (SvTYPE(av) == SVt_PVAV) {
-                        I32 len = av_len(av) + 1;
+                        SSize_t len = av_len(av) + 1;
                         if (len == 0) {
                             /* an empty sequence can be of any type */
                             $1 = 1;
@@ -414,7 +414,7 @@
                     SWIG_croak("Type error in argument $argnum of $symname. "
                                "Expected an array of " #T);
                 SV **tv;
-                I32 len = av_len(av) + 1;
+                SSize_t len = av_len(av) + 1;
                 for (int i=0; i<len; i++) {
                     tv = av_fetch(av, i, 0);
                     if (CHECK_T(*tv)) {
@@ -443,7 +443,7 @@
                     SWIG_croak("Type error in argument $argnum of $symname. "
                                "Expected an array of " #T);
                 SV **tv;
-                I32 len = av_len(av) + 1;
+                SSize_t len = av_len(av) + 1;
                 for (int i=0; i<len; i++) {
                     tv = av_fetch(av, i, 0);
                     if (CHECK_T(*tv)) {
@@ -484,7 +484,7 @@
                     /* native sequence? */
                     AV *av = (AV *)SvRV($input);
                     if (SvTYPE(av) == SVt_PVAV) {
-                        I32 len = av_len(av) + 1;
+                        SSize_t len = av_len(av) + 1;
                         if (len == 0) {
                             /* an empty sequence can be of any type */
                             $1 = 1;
@@ -514,7 +514,7 @@
                     /* native sequence? */
                     AV *av = (AV *)SvRV($input);
                     if (SvTYPE(av) == SVt_PVAV) {
-                        I32 len = av_len(av) + 1;
+                        SSize_t len = av_len(av) + 1;
                         if (len == 0) {
                             /* an empty sequence can be of any type */
                             $1 = 1;
diff --git a/Lib/perl5/swigmove.i b/Lib/perl5/swigmove.i
new file mode 100644
index 0000000..62ecca7
--- /dev/null
+++ b/Lib/perl5/swigmove.i
@@ -0,0 +1 @@
+%include <typemaps/swigmove.swg>
diff --git a/Lib/perl5/typemaps.i b/Lib/perl5/typemaps.i
index 3e1f60d..078f24c 100644
--- a/Lib/perl5/typemaps.i
+++ b/Lib/perl5/typemaps.i
@@ -206,7 +206,7 @@
     if (argvi >= items) {
 	EXTEND(sp, argvi+1);
     }
-    sprintf(temp,"%lld", (long long)*($1));
+    SWIG_snprintf(temp, sizeof(temp),"%lld", (long long)*($1));
     $result = sv_newmortal();
     sv_setpv($result,temp);
     argvi++;
@@ -217,7 +217,7 @@
     if (argvi >= items) {
 	EXTEND(sp, argvi+1);
     }
-    sprintf(temp,"%llu", (unsigned long long)*($1));
+    SWIG_snprintf(temp, sizeof(temp),"%llu", (unsigned long long)*($1));
     $result = sv_newmortal();
     sv_setpv($result,temp);
     argvi++;
diff --git a/Lib/php/argcargv.i b/Lib/php/argcargv.i
new file mode 100644
index 0000000..2a0d745
--- /dev/null
+++ b/Lib/php/argcargv.i
@@ -0,0 +1,38 @@
+/* -------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------- */
+
+%typemap(in) (int ARGC, char **ARGV) {
+  int len, i;
+  zval *val;
+  zend_array *ar;
+  if (Z_TYPE($input) != IS_ARRAY) {
+    SWIG_PHP_Error(E_ERROR, "Type error in '$symname'. Expected array");
+    goto fail;
+  }
+  ar = Z_ARR($input);
+  len = zend_array_count(ar);
+  $1 = ($1_ltype) len;
+  $2 = (char **) malloc((len+1)*sizeof(char *));
+  i = 0;
+  ZEND_HASH_FOREACH_VAL(ar, val) {
+    if (Z_TYPE(*val) != IS_STRING) {
+      SWIG_PHP_Error(E_ERROR, "Array must use strings only, in '$symname'.");
+      goto fail;
+    }
+    if (i == len) {
+      SWIG_PHP_Error(E_ERROR, "Array is bigger than zend report in '$symname'.");
+      goto fail;
+    }
+    $2[i++] = Z_STRVAL(*val);
+  } ZEND_HASH_FOREACH_END();
+  $2[i] = NULL;
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+  $1 = Z_TYPE($input) == IS_ARRAY;
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+  free((void *)$2);
+}
diff --git a/Lib/php/const.i b/Lib/php/const.i
index 32b4b9b..1e1fe9c 100644
--- a/Lib/php/const.i
+++ b/Lib/php/const.i
@@ -3,6 +3,58 @@
  *
  * Typemaps for constants
  * ----------------------------------------------------------------------------- */
+%typemap(classconsttab) int,
+                        unsigned int,
+                        short,
+                        unsigned short,
+                        long,
+                        unsigned long,
+                        unsigned char,
+                        signed char,
+                        enum SWIGTYPE %{
+  zend_declare_class_constant_long(SWIG_Php_ce_$class, "$const_name", sizeof("$const_name") - 1, ($1_type)($value));
+%}
+
+%typemap(classconsttab) bool %{
+  zend_declare_class_constant_bool(SWIG_Php_ce_$class, "$const_name", sizeof("$const_name") - 1, ($1_type)($value));
+%}
+
+%typemap(classconsttab) float,
+                        double %{
+  zend_declare_class_constant_double(SWIG_Php_ce_$class, "$const_name", sizeof("$const_name") - 1, $value);
+%}
+
+%typemap(classconsttab) char %{
+{
+  char swig_char = $value;
+  zend_declare_class_constant_stringl(SWIG_Php_ce_$class, "$const_name", sizeof("$const_name") - 1, &swig_char, 1);
+}
+%}
+
+%typemap(classconsttab) char *,
+                        const char *,
+                        char [],
+                        const char [] %{
+  zend_declare_class_constant_string(SWIG_Php_ce_$class, "$const_name", sizeof("$const_name") - 1, $value);
+%}
+
+// This creates a zend_object to wrap the pointer, and we can't do that
+// before the Zend runtime has been initialised so we delay it until
+// RINIT.  The downside is it then happens for every request.
+%typemap(classconsttab,rinit=1) SWIGTYPE *,
+                        SWIGTYPE &,
+                        SWIGTYPE &&,
+                        SWIGTYPE [] %{
+{
+  zval z;
+  ZVAL_UNDEF(&z);
+  SWIG_SetPointerZval(&z, (void*)($value), $1_descriptor, 0);
+  zval_copy_ctor(&z);
+  zend_declare_class_constant(SWIG_Php_ce_$class, "$const_name", sizeof("$const_name") - 1, &z);
+}
+%}
+
+%typemap(classconsttab) SWIGTYPE (CLASS::*) ""
 
 %typemap(consttab) int,
                    unsigned int,
@@ -13,10 +65,10 @@
                    unsigned char,
                    signed char,
                    enum SWIGTYPE
-  "SWIG_LONG_CONSTANT($symname, ($1_type)$value);";
+  "SWIG_LONG_CONSTANT($symname, ($1_type)($value));";
 
 %typemap(consttab) bool
-  "SWIG_BOOL_CONSTANT($symname, ($1_type)$value);";
+  "SWIG_BOOL_CONSTANT($symname, ($1_type)($value));";
 
 %typemap(consttab) float,
                    double
@@ -31,17 +83,21 @@
                    const char []
   "SWIG_STRING_CONSTANT($symname, $value);";
 
-%typemap(consttab) SWIGTYPE *,
+// This creates a zend_object to wrap the pointer, and we can't do that
+// before the Zend runtime has been initialised so we delay it until
+// RINIT.  The downside is it then happens for every request.
+%typemap(consttab,rinit=1) SWIGTYPE *,
                    SWIGTYPE &,
                    SWIGTYPE &&,
                    SWIGTYPE [] {
   zend_constant c;
-  SWIG_SetPointerZval(&c.value, (void*)$value, $1_descriptor, 0);
+  ZVAL_UNDEF(&c.value);
+  SWIG_SetPointerZval(&c.value, (void*)($value), $1_descriptor, 0);
   zval_copy_ctor(&c.value);
   c.name = zend_string_init("$symname", sizeof("$symname") - 1, 0);
-  SWIG_ZEND_CONSTANT_SET_FLAGS(&c, CONST_CS, module_number);
+  ZEND_CONSTANT_SET_FLAGS(&c, CONST_CS, module_number);
   zend_register_constant(&c);
 }
 
 /* Handled as a global variable. */
-%typemap(consttab) SWIGTYPE (CLASS::*) "";
+%typemap(consttab) SWIGTYPE (CLASS::*) ""
diff --git a/Lib/php/director.swg b/Lib/php/director.swg
index ea0eba8..55ffff5 100644
--- a/Lib/php/director.swg
+++ b/Lib/php/director.swg
@@ -8,6 +8,8 @@
 #ifndef SWIG_DIRECTOR_PHP_HEADER_
 #define SWIG_DIRECTOR_PHP_HEADER_
 
+#define SWIG_DIRECTOR_CAST(ARG) dynamic_cast<Swig::Director *>(ARG)
+
 #include <string>
 #include <exception>
 #include <map>
@@ -76,31 +78,34 @@
   };
 
   class Director {
+    private:
+      /* flag indicating whether the object is owned by PHP or C++ */
+      mutable bool swig_disown_flag;
+
     protected:
       // "mutable" so we can get a non-const pointer to it in const methods.
       mutable zval swig_self;
       typedef std::map<void *, GCItem_var> swig_ownership_map;
       mutable swig_ownership_map swig_owner;
+
     public:
-      Director(zval *self) {
+      Director(zval *self) : swig_disown_flag(false) {
         ZVAL_COPY_VALUE(&swig_self, self);
       }
 
-      static bool swig_is_overridden_method(const char *cname, const char *lc_fname) {
-        bool result = false;
-        zend_string * cname_str = zend_string_init(cname, strlen(cname), 0);
-        zend_class_entry *ce = zend_lookup_class(cname_str);
-        if (ce) {
-          zval * mptr = zend_hash_str_find(&ce->function_table, lc_fname, strlen(lc_fname));
-          if (mptr) {
-            // common.scope points to zend_class_entry for the declaring class,
-            // and there's only one of those per class, so we can just use a
-            // pointer compare here.
-            result = Z_FUNC_P(mptr)->common.scope != ce;
-          }
+      ~Director() {
+        if (swig_disown_flag) {
+          Z_DELREF(swig_self);
+	}
+      }
+
+      zend_object *swig_get_self() const { return Z_OBJ(swig_self); }
+
+      void swig_disown() const {
+        if (!swig_disown_flag) {
+          swig_disown_flag = true;
+          Z_ADDREF(swig_self);
         }
-        zend_string_release(cname_str);
-        return result;
       }
 
       template <typename Type>
@@ -109,6 +114,12 @@
           swig_owner[vptr] = new GCItem_T<Type>(vptr);
         }
       }
+
+      void swig_acquire_ownership_obj(void *vptr, int own) const {
+        if (vptr && own) {
+          swig_owner[vptr] = new GCItem_Object(own);
+        }
+      }
   };
 
   /* base class for director exceptions */
@@ -121,8 +132,8 @@
         swig_msg += " ";
         swig_msg += msg;
       }
-      SWIG_ErrorCode() = code;
-      SWIG_ErrorMsg() = swig_msg.c_str();
+      // Don't replace an already active PHP exception.
+      if (!EG(exception)) zend_throw_exception(NULL, swig_msg.c_str(), code);
     }
 
     virtual ~DirectorException() throw() {
@@ -150,8 +161,7 @@
   };
 
   /* any php exception that occurs during a director method call */
-  class DirectorMethodException : public DirectorException
-  {
+  class DirectorMethodException : public DirectorException {
   public:
     DirectorMethodException()
       : DirectorException(E_ERROR, "SWIG director method error", NULL) {
diff --git a/Lib/php/factory.i b/Lib/php/factory.i
index c4e082d..5f2b397 100644
--- a/Lib/php/factory.i
+++ b/Lib/php/factory.i
@@ -3,41 +3,41 @@
   you have:
 
   ----  geometry.h --------
-       struct Geometry {                          
-         enum GeomType{			     
-           POINT,				     
-           CIRCLE				     
-         };					     
-         					     
-         virtual ~Geometry() {}    		     
+       struct Geometry {
+         enum GeomType{
+           POINT,
+           CIRCLE
+         };
+
+         virtual ~Geometry() {}
          virtual int draw() = 0;
-	 
+
 	 //
 	 // Factory method for all the Geometry objects
 	 //
-         static Geometry *create(GeomType i);     
-       };					     
-       					     
-       struct Point : Geometry  {		     
-         int draw() { return 1; }		     
-         double width() { return 1.0; }    	     
-       };					     
-       					     
-       struct Circle : Geometry  {		     
-         int draw() { return 2; }		     
-         double radius() { return 1.5; }          
-       }; 					     
-       
+         static Geometry *create(GeomType i);
+       };
+
+       struct Point : Geometry  {
+         int draw() { return 1; }
+         double width() { return 1.0; }
+       };
+
+       struct Circle : Geometry  {
+         int draw() { return 2; }
+         double radius() { return 1.5; }
+       };
+
        //
        // Factory method for all the Geometry objects
        //
        Geometry *Geometry::create(GeomType type) {
-         switch (type) {			     
-         case POINT: return new Point();	     
-         case CIRCLE: return new Circle(); 	     
-         default: return 0;			     
-         }					     
-       }					    
+         switch (type) {
+         case POINT: return new Point();
+         case CIRCLE: return new Circle();
+         default: return 0;
+         }
+       }
   ----  geometry.h --------
 
 
@@ -57,16 +57,16 @@
 
   NOTES: remember to fully qualify all the type names and don't
   use %factory inside a namespace declaration, ie, instead of
-  
+
      namespace Foo {
        %factory(Geometry *Geometry::create, Point, Circle);
      }
 
   use
 
-     %factory(Foo::Geometry *Foo::Geometry::create, Foo::Point,  Foo::Circle);   
+     %factory(Foo::Geometry *Foo::Geometry::create, Foo::Point,  Foo::Circle);
 
-     
+
 */
 
 /* for loop for macro with one argument */
@@ -90,20 +90,20 @@
 /* for loop for macro with two arguments */
 %define %formacro_2(macro,...)%_formacro_2(macro, __VA_ARGS__, __fordone__)%enddef
 
-%define %_factory_dispatch(Type) 
+%define %_factory_dispatch(Type)
 if (!dcast) {
   Type *dobj = dynamic_cast<Type *>($1);
   if (dobj) {
     dcast = 1;
-    SWIG_SetPointerZval(return_value, SWIG_as_voidptr(dobj),$descriptor(Type *), $owner);
-  }   
+    SWIG_SetPointerZval(return_value, SWIG_as_voidptr(dobj), $descriptor(Type *), $owner);
+  }
 }%enddef
 
 %define %factory(Method,Types...)
-%typemap(out) Method {
+%typemap(out, phptype="?SWIGTYPE") Method {
   int dcast = 0;
   %formacro(%_factory_dispatch, Types)
   if (!dcast) {
-    SWIG_SetPointerZval(return_value, SWIG_as_voidptr($1),$descriptor, $owner);
+    SWIG_SetPointerZval(return_value, SWIG_as_voidptr($1), $descriptor, $owner);
   }
 }%enddef
diff --git a/Lib/php/globalvar.i b/Lib/php/globalvar.i
deleted file mode 100644
index 6b31207..0000000
--- a/Lib/php/globalvar.i
+++ /dev/null
@@ -1,293 +0,0 @@
-/* -----------------------------------------------------------------------------
- * globalvar.i
- *
- * Global variables - add the variable to PHP
- * ----------------------------------------------------------------------------- */
-
-%typemap(varinit) char *
-{
-  zval z_var;
-  if ($1) {
-    ZVAL_STRING(&z_var, $1);
-  } else {
-    ZVAL_STR(&z_var, ZSTR_EMPTY_ALLOC());
-  }
-  zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &z_var);
-}
-
-%typemap(varinit) char []
-{
-  zval z_var;
-  ZVAL_STRING(&z_var, $1);
-  zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &z_var);
-}
-
-%typemap(varinit) int,
-	          unsigned int,
-                  unsigned short,
-                  short,
-                  unsigned short,
-                  long,
-                  unsigned long,
-                  signed char,
-                  unsigned char,
-                  enum SWIGTYPE
-{
-  zval z_var;
-  ZVAL_LONG(&z_var, (long)$1);
-  zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &z_var);
-}
-
-%typemap(varinit) bool
-{
-  zval z_var;
-  ZVAL_BOOL(&z_var, ($1)?1:0);
-  zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &z_var);
-}
-
-%typemap(varinit) float, double
-{
-  zval z_var;
-  ZVAL_DOUBLE(&z_var, (double)$1);
-  zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &z_var);
-}
-
-%typemap(varinit) char
-{
-  zval z_var;
-  char c = $1;
-  ZVAL_STRINGL(&z_var, &c, 1);
-  zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &z_var);
-}
-
-%typemap(varinit) SWIGTYPE *, SWIGTYPE []
-{
-  zval z_var;
-  SWIG_SetPointerZval(&z_var, (void*)$1, $1_descriptor, 0);
-  zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &z_var);
-}
-
-%typemap(varinit) SWIGTYPE, SWIGTYPE &, SWIGTYPE &&
-{
-  zval z_var;
-  SWIG_SetPointerZval(&z_var, (void*)&$1, $&1_descriptor, 0);
-  zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &z_var);
-}
-
-%typemap(varinit) char [ANY]
-{
-  zval z_var;
-  /* varinit char [ANY] */
-  ZVAL_STRINGL(&z_var, $1, $1_dim0);
-  zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &z_var);
-}
-
-%typemap(varinit, fragment="swig_php_init_member_ptr") SWIGTYPE (CLASS::*)
-{
-  zval resource;
-  void * p = emalloc(sizeof($1));
-  memcpy(p, &$1, sizeof($1));
-  ZVAL_RES(&resource, zend_register_resource(p, swig_member_ptr));
-  zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &resource);
-}
-
-%typemap(varin) int, unsigned int, short, unsigned short, long, unsigned long, signed char, unsigned char,  enum SWIGTYPE
-{
-  zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
-  $1 = zval_get_long(z_var);
-}
-
-%typemap(varin) bool
-{
-  zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
-  convert_to_boolean(z_var);
-  $1 = (Z_TYPE_P(z_var) == IS_TRUE);
-}
-
-%typemap(varin) double,float
-{
-  zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
-  $1 = zval_get_double(z_var);
-}
-
-%typemap(varin) char
-{
-  zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
-  convert_to_string(z_var);
-  if ($1 != Z_STRVAL_P(z_var)[0]) {
-    $1 = Z_STRVAL_P(z_var)[0];
-  }
-}
-
-%typemap(varin) char *
-{
-  zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
-  char *s1;
-  convert_to_string(z_var);
-  s1 = Z_STRVAL_P(z_var);
-  if ((s1 == NULL) || ($1 == NULL) || strcmp(s1, $1)) {
-    if (s1)
-      $1 = estrdup(s1);
-    else
-      $1 = NULL;
-  }
-}
-
-
-%typemap(varin) SWIGTYPE []
-{
-  if ($1) {
-    zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
-    SWIG_SetPointerZval(z_var, (void*)$1, $1_descriptor, $owner);
-  }
-}
-
-%typemap(varin) char [ANY]
-{
-  zval **z_var;
-  char *s1;
-
-  zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1, (void**)&z_var);
-  s1 = Z_STRVAL_P(z_var);
-  if ((s1 == NULL) || ($1 == NULL) || strcmp(s1, $1)) {
-    if (s1)
-      strncpy($1, s1, $1_dim0);
-  }
-}
-
-%typemap(varin) SWIGTYPE
-{
-  zval *z_var;
-  $&1_ltype _temp;
-
-  z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
-  if (SWIG_ConvertPtr(z_var, (void**)&_temp, $&1_descriptor, 0) < 0) {
-    SWIG_PHP_Error(E_ERROR,"Type error in value of $symname. Expected $&1_descriptor");
-  }
-
-  $1 = *($&1_ltype)_temp;
-}
-
-%typemap(varin) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&
-{
-  zval *z_var;
-  $1_ltype _temp;
-
-  z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
-  if (SWIG_ConvertPtr(z_var, (void **)&_temp, $1_descriptor, 0) < 0) {
-    SWIG_PHP_Error(E_ERROR,"Type error in value of $symname. Expected $&1_descriptor");
-  }
-
-  $1 = ($1_ltype)_temp;
-}
-
-%typemap(varin, fragment="swig_php_init_member_ptr") SWIGTYPE (CLASS::*)
-{
-  zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
-  void * p = (void*)zend_fetch_resource_ex(z_var, SWIG_MEMBER_PTR, swig_member_ptr);
-  memcpy(&$1, p, sizeof($1));
-}
-
-%typemap(varout) int,
-                 unsigned int,
-                 unsigned short,
-                 short,
-                 long,
-                 unsigned long,
-                 signed char,
-                 unsigned char,
-                 enum SWIGTYPE
-{
-  zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
-  if ($1 != ($1_ltype)Z_LVAL_P(z_var)) {
-    z_var->value.lval = (long)$1;
-  }
-}
-
-//SAMFIX need to cast zval->type, what if zend-hash_find fails? etc?
-%typemap(varout) bool
-{
-  zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
-  if ($1 != ($1_ltype)Z_LVAL_P(z_var)) {
-    z_var->value.lval = (long)$1;
-  }
-}
-
-%typemap(varout) double, float
-{
-  zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
-  if ($1 != ($1_ltype)Z_DVAL_P(z_var)) {
-    z_var->value.dval = (double)$1;
-  }
-}
-
-%typemap(varout) char
-{
-  zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
-  char c = $1;
-  if ($1 != Z_STRVAL_P(z_val)[0]) {
-    ZVAL_STRING(z_var, &c);
-  }
-}
-
-%typemap(varout) char *
-{
-  zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
-  const char *s1 = Z_STRVAL_P(z_var);
-  if ((s1 == NULL) || ($1 == NULL) || strcmp(s1, $1)) {
-    if (s1)
-      efree(s1);
-    if ($1) {
-      (z_var)->value.str.val = estrdup($1);
-      (z_var)->value.str.len = strlen($1) + 1;
-    } else {
-      (z_var)->value.str.val = 0;
-      (z_var)->value.str.len = 0;
-    }
-  }
-}
-
-%typemap(varout) SWIGTYPE
-{
-  zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
-  SWIG_SetPointerZval(z_var, (void*)&$1, $&1_descriptor, 0);
-}
-
-%typemap(varout) SWIGTYPE []
-{
-  if($1) {
-    zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
-    SWIG_SetPointerZval(z_var, (void*)$1, $1_descriptor, 0);
-  }
-}
-
-%typemap(varout) char [ANY]
-{
-  zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
-  const char *s1 = Z_STRVAL_P(z_var);
-deliberate error cos this code looks bogus to me
-  if ((s1 == NULL) || strcmp(s1, $1)) {
-    if ($1) {
-      (z_var)->value.str.val = estrdup($1);
-      (z_var)->value.str.len = strlen($1) + 1;
-    } else {
-      (z_var)->value.str.val = 0;
-      (z_var)->value.str.len = 0;
-    }
-  }
-}
-
-%typemap(varout) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&
-{
-  zval *z_var = zend_hash_str_find(&EG(symbol_table), "$1", sizeof("$1") - 1);
-  SWIG_SetPointerZval(z_var, (void*)$1, $1_descriptor, 0);
-}
-
-%typemap(varout, fragment="swig_php_init_member_ptr") SWIGTYPE (CLASS::*)
-{
-  zval resource;
-  void * p = emalloc(sizeof($1));
-  memcpy(p, &$1, sizeof($1));
-  ZVAL_RES(&resource, zend_register_resource(p, swig_member_ptr));
-  zend_hash_str_add(&EG(symbol_table), "$1", sizeof("$1") - 1, &resource);
-}
diff --git a/Lib/php/php.swg b/Lib/php/php.swg
index 4eba6be..ca8704f 100644
--- a/Lib/php/php.swg
+++ b/Lib/php/php.swg
@@ -4,13 +4,19 @@
  * PHP configuration file
  * ----------------------------------------------------------------------------- */
 
+%include <typemaps/fragments.swg>
+
+// Default to generating PHP type declarations (for PHP >= 8) except for
+// cases which are liable to cause compatibility issues with existing
+// bindings.
+%feature("php:type", "compat");
+
 %runtime "swigrun.swg"  // Common C API type-checking code
 %runtime "swigerrors.swg"    // SWIG errors
 %runtime "phprun.swg"	// PHP runtime functions
 
 %include <phpinit.swg> // PHP initialization routine.
 
-%include <globalvar.i>	// Global variables.
 %include <const.i>
 
 // use %init %{ "/*code goes here*/ " %}
@@ -35,107 +41,142 @@
 
 %include <utils.i>
 
-%pass_by_val(bool,CONVERT_BOOL_IN);
+%pass_by_val(bool, "bool", CONVERT_BOOL_IN);
 
-%pass_by_val(size_t, CONVERT_INT_IN);
+%pass_by_val(size_t, "int", CONVERT_INT_IN);
 
-%pass_by_val(enum SWIGTYPE, CONVERT_INT_IN);
+%pass_by_val(enum SWIGTYPE, "int", CONVERT_INT_IN);
 
-%pass_by_val(signed int, CONVERT_INT_IN);
-%pass_by_val(int,CONVERT_INT_IN);
-%pass_by_val(unsigned int,CONVERT_INT_IN);
+%pass_by_val(signed int, "int", CONVERT_INT_IN);
+%pass_by_val(int,"int", CONVERT_INT_IN);
+%pass_by_val(unsigned int,"int", CONVERT_INT_IN);
 
-%pass_by_val(signed short, CONVERT_INT_IN);
-%pass_by_val(short,CONVERT_INT_IN);
-%pass_by_val(unsigned short, CONVERT_INT_IN);
+%pass_by_val(signed short, "int", CONVERT_INT_IN);
+%pass_by_val(short,"int", CONVERT_INT_IN);
+%pass_by_val(unsigned short, "int", CONVERT_INT_IN);
 
-%pass_by_val(signed long, CONVERT_INT_IN);
-%pass_by_val(long, CONVERT_INT_IN);
-%pass_by_val(unsigned long, CONVERT_INT_IN);
+%pass_by_val(signed long, "int", CONVERT_INT_IN);
+%pass_by_val(long, "int", CONVERT_INT_IN);
+%pass_by_val(unsigned long, "int", CONVERT_INT_IN);
 
-%pass_by_val(signed long long, CONVERT_LONG_LONG_IN);
-%pass_by_val(long long, CONVERT_LONG_LONG_IN);
-%pass_by_val(unsigned long long, CONVERT_UNSIGNED_LONG_LONG_IN);
+%pass_by_val(signed long long, "int|string", CONVERT_LONG_LONG_IN);
+%pass_by_val(long long, "int|string", CONVERT_LONG_LONG_IN);
+%pass_by_val(unsigned long long, "int|string", CONVERT_UNSIGNED_LONG_LONG_IN);
 
-%pass_by_val(signed char, CONVERT_INT_IN);
-%pass_by_val(char, CONVERT_CHAR_IN);
-%pass_by_val(unsigned char, CONVERT_INT_IN);
+%pass_by_val(signed char, "int", CONVERT_INT_IN);
+%pass_by_val(char, "string", CONVERT_CHAR_IN);
+%pass_by_val(unsigned char, "int", CONVERT_INT_IN);
 
-%pass_by_val(float, CONVERT_FLOAT_IN);
+%pass_by_val(float, "float", CONVERT_FLOAT_IN);
 
-%pass_by_val(double, CONVERT_FLOAT_IN);
+%pass_by_val(double, "float", CONVERT_FLOAT_IN);
 
-%pass_by_val(char *, CONVERT_STRING_IN);
+%pass_by_val(char *, "string", CONVERT_STRING_IN);
 %typemap(in) char *& = const char *&;
 %typemap(directorout) char *& = const char *&;
 
 // char array can be in/out, though the passed string may not be big enough...
 // so we have to size it
-%typemap(in) char[ANY]
+%typemap(in, phptype="string") char[ANY]
 %{
    convert_to_string(&$input);
    $1 = ($1_ltype) Z_STRVAL($input);
 %}
 
-%typemap(in) (char *STRING, int LENGTH), (char *STRING, size_t LENGTH) %{
+%typemap(in, phptype="string") (char *STRING, int LENGTH), (char *STRING, size_t LENGTH) %{
    convert_to_string(&$input);
    $1 = ($1_ltype) Z_STRVAL($input);
    $2 = ($2_ltype) Z_STRLEN($input);
 %}
 
 /* Object passed by value. Convert to a pointer */
-%typemap(in) SWIGTYPE ($&1_ltype tmp)
+%typemap(in, phptype="SWIGTYPE") SWIGTYPE ($&1_ltype tmp)
 %{
-	if (SWIG_ConvertPtr(&$input, (void **) &tmp, $&1_descriptor, 0) < 0 || tmp == NULL) {
-          SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $&1_descriptor");
-	}
-	$1 = *tmp;
+  if (SWIG_ConvertPtr(&$input, (void **) &tmp, $&1_descriptor, 0) < 0 || tmp == NULL) {
+    zend_type_error("Expected $&1_descriptor for argument $argnum of $symname");
+    return;
+  }
+  $1 = *tmp;
 %}
 
 %typemap(directorout) SWIGTYPE ($&1_ltype tmp)
 %{
-	/* If exit was via exception, PHP NULL is returned so skip the conversion. */
-	if (!EG(exception)) {
-	  if (SWIG_ConvertPtr($input, (void **) &tmp, $&1_descriptor, 0) < 0 || tmp == NULL)
-	    SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $&1_descriptor");
-	  $result = *tmp;
-	}
+  if (SWIG_ConvertPtr($input, (void **) &tmp, $&1_descriptor, 0) < 0 || tmp == NULL) {
+    zend_type_error("Expected $&1_descriptor for argument $argnum of $symname");
+    SWIG_fail;
+  }
+  $result = *tmp;
 %}
 
-%typemap(in) SWIGTYPE *,
+%typemap(in, phptype="?SWIGTYPE") SWIGTYPE *,
 	     SWIGTYPE []
 %{
-	if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0) {
-            SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor");
-	}
+  if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0) {
+    zend_type_error("Expected $1_descriptor for argument $argnum of $symname");
+    return;
+  }
 %}
 
-%typemap(in) SWIGTYPE &
+%typemap(directorout) SWIGTYPE * (swig_owntype own),
+		      SWIGTYPE [] (swig_owntype own)
 %{
-	if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0 || $1 == NULL) {
-	    SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor");
-	}
+  if (SWIG_ConvertPtrAndOwn($input, (void **)&$result, $1_descriptor, SWIG_POINTER_DISOWN, &own) < 0) {
+    zend_type_error("Expected $1_descriptor for argument $argnum of $symname");
+    SWIG_fail;
+  }
+  swig_acquire_ownership_obj((void*)$result, own);
 %}
 
-%typemap(in) SWIGTYPE &&
+%typemap(in, phptype="SWIGTYPE") SWIGTYPE &
 %{
-	if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0 || $1 == NULL) {
-	    SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor");
-	}
+  if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, 0) < 0 || $1 == NULL) {
+    zend_type_error("Expected $1_descriptor for argument $argnum of $symname");
+    return;
+  }
+%}
+%typemap(in, fragment="<memory>") SWIGTYPE && (void *argp = 0, int res = 0, std::unique_ptr<$*1_ltype> rvrdeleter) %{
+  res = SWIG_ConvertPtr(&$input, &argp, $descriptor, SWIG_POINTER_RELEASE);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      zend_type_error("Cannot release ownership as memory is not owned for argument $argnum of $1_descriptor of $symname");
+      return;
+    } else {
+      zend_type_error("Expected $1_descriptor for argument $argnum of $symname");
+      return;
+    }
+  }
+  if (!argp) {
+    zend_type_error("Invalid null reference for argument $argnum of $1_descriptor of $symname");
+    return;
+  }
+  $1 = ($1_ltype)argp;
+  rvrdeleter.reset($1);
 %}
 
-%typemap(in) SWIGTYPE *const& ($*ltype temp)
+%typemap(directorout) SWIGTYPE & ($1_ltype tmp),
+		      SWIGTYPE && ($1_ltype tmp)
 %{
-	if (SWIG_ConvertPtr(&$input, (void **) &temp, $*1_descriptor, 0) < 0) {
-            SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $*1_descriptor");
-	}
-	$1 = ($1_ltype)&temp;
+  if (SWIG_ConvertPtr($input, (void **) &tmp, $1_descriptor, 0) < 0 || tmp == NULL) {
+    zend_type_error("Expected $1_descriptor for argument $argnum of $symname");
+    SWIG_fail;
+  }
+  $result = tmp;
 %}
 
-%typemap(in) SWIGTYPE *DISOWN
+%typemap(in, phptype="?SWIGTYPE") SWIGTYPE *const& ($*ltype temp)
 %{
-  if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, SWIG_POINTER_DISOWN ) < 0) {
-    SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor");
+  if (SWIG_ConvertPtr(&$input, (void **) &temp, $*1_descriptor, 0) < 0) {
+    zend_type_error("Expected $*1_descriptor for argument $argnum of $symname");
+    return;
+  }
+  $1 = ($1_ltype)&temp;
+%}
+
+%typemap(in, phptype="?SWIGTYPE") SWIGTYPE *DISOWN
+%{
+  if (SWIG_ConvertPtr(&$input, (void **) &$1, $1_descriptor, SWIG_POINTER_DISOWN) < 0) {
+    zend_type_error("Expected $1_descriptor for argument $argnum of $symname");
+    return;
   }
 %}
 
@@ -144,19 +185,22 @@
                  SWIGTYPE &,
                  SWIGTYPE &&;
 
-%typemap(in) void *
+%typemap(in, phptype="?SWIGTYPE") void *
 %{
-	if (SWIG_ConvertPtr(&$input, (void **) &$1, 0, 0) < 0) {
-	  /* Allow NULL from php for void* */
-	  if (Z_ISNULL($input)) $1=0;
-	else
-	  SWIG_PHP_Error(E_ERROR, "Type error in argument $argnum of $symname. Expected $1_descriptor");
-	}
+  if (SWIG_ConvertPtr(&$input, (void **) &$1, 0, 0) < 0) {
+    /* Allow NULL from php for void* */
+    if (Z_ISNULL($input)) {
+      $1=0;
+    } else {
+      zend_type_error("Expected $1_descriptor for argument $argnum of $symname");
+      return;
+    }
+  }
 %}
 
 /* Special case when void* is passed by reference so it can be made to point
    to opaque api structs */
-%typemap(in) void ** ($*1_ltype ptr, int force),
+%typemap(in, phptype="?SWIG\\_p_void", byref=1) void ** ($*1_ltype ptr, int force),
              void *& ($*1_ltype ptr, int force)
 {
   /* If they pass NULL by reference, make it into a void*
@@ -165,7 +209,8 @@
     /* So... we didn't get a ref or ptr, but we'll accept NULL by reference */
     if (!(Z_ISREF($input) && Z_ISNULL_P(Z_REFVAL($input)))) {
       /* wasn't a pre/ref/thing, OR anything like an int thing */
-      SWIG_PHP_Error(E_ERROR, "Type error in argument $arg of $symname.");
+      zend_throw_exception(zend_ce_type_error, "Type error in argument $arg of $symname", 0);
+      goto fail;
     }
   }
   force=0;
@@ -183,14 +228,15 @@
 %typemap(argout) void **,
                  void *&
 %{
-  if (force$argnum) {
-    SWIG_SetPointerZval(&$input, (void*) ptr$argnum, $*1_descriptor, 1);
+  if (force$argnum && Z_ISREF($input)) {
+    SWIG_SetPointerZval(Z_REFVAL($input), (void*) ptr$argnum, $*1_descriptor, 1);
   }
 %}
 
 /* Typemap for output values */
 
-%typemap(out) int,
+%typemap(out, phptype="int")
+              int,
               unsigned int,
               short,
               unsigned short,
@@ -198,39 +244,35 @@
               unsigned long,
               signed char,
               unsigned char,
-              bool,
               size_t
 %{
   RETVAL_LONG($1);
 %}
 
-%typemap(out) enum SWIGTYPE
+%typemap(out, phptype="int") enum SWIGTYPE
 %{
   RETVAL_LONG((long)$1);
 %}
 
-%typemap(out) long long
+%typemap(out, phptype="int|string") long long
 %{
   if ((long long)LONG_MIN <= $1 && $1 <= (long long)LONG_MAX) {
     RETVAL_LONG((long)($1));
   } else {
-    char temp[256];
-    sprintf(temp, "%lld", (long long)$1);
-    RETVAL_STRING(temp);
+    RETVAL_NEW_STR(zend_strpprintf(0, "%lld", (long long)$1));
   }
 %}
-%typemap(out) unsigned long long
+%typemap(out, phptype="int|string") unsigned long long
 %{
   if ($1 <= (unsigned long long)LONG_MAX) {
     RETVAL_LONG((long)($1));
   } else {
-    char temp[256];
-    sprintf(temp, "%llu", (unsigned long long)$1);
-    RETVAL_STRING(temp);
+    RETVAL_NEW_STR(zend_strpprintf(0, "%llu", (unsigned long long)$1));
   }
 %}
 
-%typemap(out) const int &,
+%typemap(out, phptype="int")
+              const int &,
               const unsigned int &,
               const short &,
               const unsigned short &,
@@ -244,34 +286,30 @@
   RETVAL_LONG(*$1);
 %}
 
-%typemap(out) const enum SWIGTYPE &
+%typemap(out, phptype="int") const enum SWIGTYPE &
 %{
   RETVAL_LONG((long)*$1);
 %}
 
-%typemap(out) const enum SWIGTYPE &&
+%typemap(out, phptype="int") const enum SWIGTYPE &&
 %{
   RETVAL_LONG((long)*$1);
 %}
 
-%typemap(out) const long long &
+%typemap(out, phptype="int|string") const long long &
 %{
   if ((long long)LONG_MIN <= *$1 && *$1 <= (long long)LONG_MAX) {
     RETVAL_LONG((long)(*$1));
   } else {
-    char temp[256];
-    sprintf(temp, "%lld", (long long)(*$1));
-    RETVAL_STRING(temp);
+    RETVAL_NEW_STR(zend_strpprintf(0, "%lld", (long long)(*$1)));
   }
 %}
-%typemap(out) const unsigned long long &
+%typemap(out, phptype="int|string") const unsigned long long &
 %{
   if (*$1 <= (unsigned long long)LONG_MAX) {
     RETVAL_LONG((long)(*$1));
   } else {
-    char temp[256];
-    sprintf(temp, "%llu", (unsigned long long)(*$1));
-    RETVAL_STRING(temp);
+    RETVAL_NEW_STR(zend_strpprintf(0, "%llu", (unsigned long long)(*$1)));
   }
 %}
 
@@ -303,12 +341,12 @@
     }
 %}
 
-%typemap(out) bool
+%typemap(out, phptype="bool") bool
 %{
   RETVAL_BOOL(($1) ? 1 : 0);
 %}
 
-%typemap(out) const bool &
+%typemap(out, phptype="bool") const bool &
 %{
   RETVAL_BOOL((*$1) ? 1 : 0);
 %}
@@ -318,13 +356,13 @@
   ZVAL_BOOL($input, ($1) ? 1 : 0);
 %}
 
-%typemap(out) float,
+%typemap(out, phptype="float") float,
               double
 %{
   RETVAL_DOUBLE($1);
 %}
 
-%typemap(out) const float &,
+%typemap(out, phptype="float") const float &,
               const double &
 %{
   RETVAL_DOUBLE(*$1);
@@ -336,18 +374,22 @@
   ZVAL_DOUBLE($input, $1);
 %}
 
-%typemap(out) char
+%typemap(out, phptype="string") char
 %{
   RETVAL_STRINGL(&$1, 1);
 %}
 
-%typemap(out) const char &
+%typemap(out, phptype="string") const char &
 %{
   RETVAL_STRINGL(&*$1, 1);
 %}
 
-%typemap(out) char *,
-              char []
+%typemap(out, phptype="string") char []
+%{
+  RETVAL_STRING((const char *)$1);
+%}
+
+%typemap(out, phptype="?string") char *
 %{
   if (!$1) {
     RETVAL_NULL();
@@ -356,7 +398,7 @@
   }
 %}
 
-%typemap(out) char *&
+%typemap(out, phptype="?string") char *&
 %{
   if (!*$1) {
     RETVAL_NULL();
@@ -365,17 +407,22 @@
   }
 %}
 
-%typemap(out) SWIGTYPE *,
+%typemap(out, phptype="?SWIGTYPE") SWIGTYPE *
+%{
+  SWIG_SetPointerZval($result, (void *)$1, $1_descriptor, $owner);
+%}
+
+%typemap(out, phptype="SWIGTYPE")
               SWIGTYPE [],
               SWIGTYPE &,
               SWIGTYPE &&
 %{
-  SWIG_SetPointerZval(return_value, (void *)$1, $1_descriptor, $owner);
+  SWIG_SetPointerZval($result, (void *)$1, $1_descriptor, $owner);
 %}
 
-%typemap(out) SWIGTYPE *const&
+%typemap(out, phptype="?SWIGTYPE") SWIGTYPE *const&
 %{
-  SWIG_SetPointerZval(return_value, (void *)*$1, $*1_descriptor, $owner);
+  SWIG_SetPointerZval($result, (void *)*$1, $*1_descriptor, $owner);
 %}
 
 %typemap(directorin) SWIGTYPE *,
@@ -383,53 +430,57 @@
                      SWIGTYPE &,
                      SWIGTYPE &&
 %{
-  SWIG_SetPointerZval($input, (void *)&$1, $1_descriptor, ($owner)|2);
+  ZVAL_UNDEF($input);
+  SWIG_SetPointerZval($input, (void *)&$1, $1_descriptor, $owner);
 %}
 
-%typemap(out, fragment="swig_php_init_member_ptr") SWIGTYPE (CLASS::*)
+%typemap(out, phptype="SWIGTYPE") SWIGTYPE (CLASS::*)
 {
   void * p = emalloc(sizeof($1));
   memcpy(p, &$1, sizeof($1));
-  RETVAL_RES(zend_register_resource(p, swig_member_ptr));
+  SWIG_SetPointerZval($result, (void *)p, $&1_descriptor, 1);
 }
 
-%typemap(in, fragment="swig_php_init_member_ptr") SWIGTYPE (CLASS::*)
+%typemap(in, phptype="SWIGTYPE") SWIGTYPE (CLASS::*)
 {
-  void * p = (void*)zend_fetch_resource_ex(&$input, SWIG_MEMBER_PTR, swig_member_ptr);
+  void * p = SWIG_Z_FETCH_OBJ_P(&$input)->ptr;
   memcpy(&$1, p, sizeof($1));
 }
 
-%typemap(out) SWIGTYPE *DYNAMIC,
-              SWIGTYPE &DYNAMIC
+%typemap(out, phptype="?SWIGTYPE") SWIGTYPE *DYNAMIC
 {
   swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1);
-  SWIG_SetPointerZval(return_value, (void *)$1, ty, $owner);
+  SWIG_SetPointerZval($result, (void *)$1, ty, $owner);
 }
 
-%typemap(out) SWIGTYPE
+%typemap(out, phptype="SWIGTYPE") SWIGTYPE &DYNAMIC
+{
+  swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1);
+  SWIG_SetPointerZval($result, (void *)$1, ty, $owner);
+}
+
+%typemap(out, phptype="SWIGTYPE") SWIGTYPE
+{
 #ifdef __cplusplus
-{
-  $&1_ltype resultobj = new $1_ltype((const $1_ltype &) $1);
-  SWIG_SetPointerZval(return_value, (void *)resultobj, $&1_descriptor, 1);
-}
+  $&1_ltype resultobj = new $1_ltype($1);
 #else
-{
-  $&1_ltype resultobj = ($&1_ltype) emalloc(sizeof($1_type));
+  $&1_ltype resultobj = ($&1_ltype) malloc(sizeof($1_type));
   memcpy(resultobj, &$1, sizeof($1_type));
-  SWIG_SetPointerZval(return_value, (void *)resultobj, $&1_descriptor, 1);
-}
 #endif
+  SWIG_SetPointerZval($result, (void *)resultobj, $&1_descriptor, 1);
+}
 
 %typemap(directorin) SWIGTYPE
 %{
-  SWIG_SetPointerZval($input, SWIG_as_voidptr(new $1_ltype((const $1_ltype &)$1)), $&1_descriptor, 1|2);
+  ZVAL_UNDEF($input);
+  SWIG_SetPointerZval($input, (new $1_ltype(SWIG_STD_MOVE($1))), $&1_descriptor, 1);
 %}
 
-%typemap(out) void "";
+%typemap(out, phptype="void") void ""
 
-%typemap(out) char [ANY]
+%typemap(out, phptype="string") char [ANY]
 {
-  int len = 0;
+  size_t len = 0;
   while (len < $1_dim0 && $1[len]) ++len;
   RETVAL_STRINGL($1, len);
 }
@@ -448,24 +499,38 @@
  " $1 = (Z_TYPE($input) == is1 || Z_TYPE($input) == is2);"
 %enddef
 
-%php_typecheck(int,SWIG_TYPECHECK_INTEGER,IS_LONG)
-%php_typecheck(unsigned int,SWIG_TYPECHECK_UINT32,IS_LONG)
-%php_typecheck(short,SWIG_TYPECHECK_INT16,IS_LONG)
-%php_typecheck(unsigned short,SWIG_TYPECHECK_UINT16,IS_LONG)
-%php_typecheck(long,SWIG_TYPECHECK_INT32,IS_LONG)
-%php_typecheck(unsigned long,SWIG_TYPECHECK_UINT32,IS_LONG)
-%php_typecheck(long long,SWIG_TYPECHECK_INT64,IS_LONG)
-%php_typecheck(unsigned long long,SWIG_TYPECHECK_UINT64,IS_LONG)
-%php_typecheck(signed char,SWIG_TYPECHECK_INT8,IS_LONG)
-%php_typecheck(unsigned char,SWIG_TYPECHECK_UINT8,IS_LONG)
-%php_typecheck(size_t,SWIG_TYPECHECK_SIZE,IS_LONG)
+%define %php_typecheck_long(_type,_prec,_min,_max)
+%typemap(typecheck,precedence=_prec) _type, const _type & %{
+  $1 = (Z_TYPE($input) == IS_LONG &&
+        (_min <= ZEND_LONG_MIN || (zend_long)_min <= Z_LVAL($input)) &&
+        (_max >= ZEND_LONG_MAX || (zend_long)_max >= Z_LVAL($input)));
+%}
+%enddef
+
+%php_typecheck_long(int,SWIG_TYPECHECK_INTEGER,INT_MIN,INT_MAX)
+%php_typecheck_long(unsigned int,SWIG_TYPECHECK_UINT32,0,UINT_MAX)
+%php_typecheck_long(short,SWIG_TYPECHECK_INT16,SHRT_MIN,SHRT_MAX)
+%php_typecheck_long(unsigned short,SWIG_TYPECHECK_UINT16,0,USHRT_MAX)
+%php_typecheck_long(long,SWIG_TYPECHECK_INT32,LONG_MIN,LONG_MAX)
+%php_typecheck_long(unsigned long,SWIG_TYPECHECK_UINT32,0,ULONG_MAX)
+%php_typecheck_long(long long,SWIG_TYPECHECK_INT64,LLONG_MIN,LLONG_MAX)
+%php_typecheck_long(unsigned long long,SWIG_TYPECHECK_UINT64,0,ULLONG_MAX)
+%php_typecheck_long(signed char,SWIG_TYPECHECK_INT8,SCHAR_MIN,SCHAR_MAX)
+%php_typecheck_long(unsigned char,SWIG_TYPECHECK_UINT8,0,UCHAR_MAX)
+%php_typecheck_long(size_t,SWIG_TYPECHECK_SIZE,0,(size_t)-1)
 %php_typecheck(enum SWIGTYPE,SWIG_TYPECHECK_INTEGER,IS_LONG)
 %php_typecheck2(bool,SWIG_TYPECHECK_BOOL,IS_TRUE,IS_FALSE)
-%php_typecheck(float,SWIG_TYPECHECK_FLOAT,IS_DOUBLE)
+%typemap(typecheck,precedence=SWIG_TYPECHECK_FLOAT,fragment="SWIG_Float_Overflow_Check") float, const float & %{
+  $1 = (Z_TYPE($input) == IS_DOUBLE && !SWIG_Float_Overflow_Check(Z_DVAL($input)));
+%}
+/* Don't range check here since PHP stores this as C/C++ double. */
 %php_typecheck(double,SWIG_TYPECHECK_DOUBLE,IS_DOUBLE)
 %php_typecheck(char,SWIG_TYPECHECK_CHAR,IS_STRING)
 
-%typemap(typecheck,precedence=SWIG_TYPECHECK_STRING) char *, char *&, char []
+%typemap(typecheck,precedence=SWIG_TYPECHECK_STRING) char *, char *&
+ " $1 = (Z_TYPE($input) == IS_STRING || Z_TYPE($input) == IS_NULL); "
+
+%typemap(typecheck,precedence=SWIG_TYPECHECK_STRING) char []
  " $1 = (Z_TYPE($input) == IS_STRING); "
 
 %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE
@@ -512,18 +577,18 @@
                  unsigned long,
                  unsigned short %{
   zend_throw_exception(NULL, "C++ $1_type exception thrown", $1);
-  return;
+  goto fail;
 %}
 
 %typemap(throws) SWIGTYPE, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE *, SWIGTYPE [], SWIGTYPE [ANY] %{
   (void)$1;
   zend_throw_exception(NULL, "C++ $1_type exception thrown", 0);
-  return;
+  goto fail;
 %}
 
 %typemap(throws) char * %{
   zend_throw_exception(NULL, $1, 0);
-  return;
+  goto fail;
 %}
 
 /* Array reference typemaps */
@@ -537,3 +602,6 @@
 
 /* php keywords */
 %include <phpkw.swg>
+
+/* PHP known interfaces */
+%include <phpinterfaces.i>
diff --git a/Lib/php/phpinit.swg b/Lib/php/phpinit.swg
index 1665f5d..ae72a10 100644
--- a/Lib/php/phpinit.swg
+++ b/Lib/php/phpinit.swg
@@ -7,19 +7,10 @@
 
 %init %{
 SWIG_php_minit {
+  zend_class_entry SWIGUNUSED internal_ce;
   SWIG_InitializeModule((void*)&module_number);
-%}
-
-%fragment("swig_php_init_member_ptr2", "header") %{
-#define SWIG_MEMBER_PTR "CLASS::*"
-
-static void swig_member_ptr_dtor(zend_resource *res) {
-  efree(res->ptr);
-}
-
-static int swig_member_ptr = 0;
-%}
-
-%fragment("swig_php_init_member_ptr", "init", fragment="swig_php_init_member_ptr2") %{
-  swig_member_ptr = zend_register_list_destructors_ex(swig_member_ptr_dtor, NULL, SWIG_MEMBER_PTR, module_number);
+#if PHP_MAJOR_VERSION == 8 && PHP_MINOR_VERSION == 0
+  /* This hack is needed to avoid segfaults. */
+  EG(class_table) = CG(class_table);
+#endif
 %}
diff --git a/Lib/php/phpinterfaces.i b/Lib/php/phpinterfaces.i
new file mode 100644
index 0000000..e1029b6
--- /dev/null
+++ b/Lib/php/phpinterfaces.i
@@ -0,0 +1,60 @@
+/* -----------------------------------------------------------------------------
+ * phpinterfaces.i
+ *
+ * Define "known" PHP interfaces.
+ *
+ * These can be added at MINIT time (which is when PHP loads the extension
+ * module).
+ *
+ * Any interface can be added via phpinterfaces, but looking up the
+ * zend_class_entry by name has to wait until RINIT time, which means it
+ * happens for every request.
+ * ----------------------------------------------------------------------------- */
+
+// Note: Abstract interfaces such as "Traversable" can't be used in
+// "implements" so are not relevant here.
+
+%insert(header) %{
+
+#define SWIG_PHP_INTERFACE_Iterator_CE zend_ce_iterator
+#define SWIG_PHP_INTERFACE_Iterator_HEADER "zend_interfaces.h"
+
+#define SWIG_PHP_INTERFACE_IteratorAggregate_CE zend_ce_aggregate
+#define SWIG_PHP_INTERFACE_IteratorAggregate_HEADER "zend_interfaces.h"
+
+#define SWIG_PHP_INTERFACE_ArrayAccess_CE zend_ce_arrayaccess
+#define SWIG_PHP_INTERFACE_ArrayAccess_HEADER "zend_interfaces.h"
+
+#define SWIG_PHP_INTERFACE_Serializable_CE zend_ce_serializable
+#define SWIG_PHP_INTERFACE_Serializable_HEADER "zend_interfaces.h"
+
+#define SWIG_PHP_INTERFACE_Countable_CE zend_ce_countable
+#define SWIG_PHP_INTERFACE_Countable_HEADER "zend_interfaces.h"
+
+#define SWIG_PHP_INTERFACE_OuterIterator_CE spl_ce_OuterIterator
+#define SWIG_PHP_INTERFACE_OuterIterator_HEADER "ext/spl/spl_iterators.h"
+
+#define SWIG_PHP_INTERFACE_RecursiveIterator_CE spl_ce_RecursiveIterator
+#define SWIG_PHP_INTERFACE_RecursiveIterator_HEADER "ext/spl/spl_iterators.h"
+
+#define SWIG_PHP_INTERFACE_SeekableIterator_CE spl_ce_SeekableIterator
+#define SWIG_PHP_INTERFACE_SeekableIterator_HEADER "ext/spl/spl_iterators.h"
+
+#define SWIG_PHP_INTERFACE_SplObserver_CE spl_ce_SplObserver
+#define SWIG_PHP_INTERFACE_SplObserver_HEADER "ext/spl/spl_observer.h"
+
+#define SWIG_PHP_INTERFACE_SplSubject_CE spl_ce_SplSubject
+#define SWIG_PHP_INTERFACE_SplSubject_HEADER "ext/spl/spl_observer.h"
+
+#define SWIG_PHP_INTERFACE_DateTimeInterface_CE php_date_get_interface_ce()
+#define SWIG_PHP_INTERFACE_DateTimeInterface_HEADER "ext/date/php_date.h"
+
+// The "json" extension needs to be loaded earlier that us for this to work.
+#define SWIG_PHP_INTERFACE_JsonSerializable_CE php_json_serializable_ce
+#define SWIG_PHP_INTERFACE_JsonSerializable_HEADER "ext/json/php_json.h"
+
+// New in PHP 8.0.
+#define SWIG_PHP_INTERFACE_Stringable_CE zend_ce_stringable
+#define SWIG_PHP_INTERFACE_Stringable_HEADER "zend_interfaces.h"
+
+%}
diff --git a/Lib/php/phpkw.swg b/Lib/php/phpkw.swg
index 5c5296a..443ac8b 100644
--- a/Lib/php/phpkw.swg
+++ b/Lib/php/phpkw.swg
@@ -3,10 +3,13 @@
  * ----------------------------------------------------------------------------- */
 
 /* Keyword (case insensitive) */
-#define PHPKW(x) %keywordwarn("'" `x` "' is a PHP keyword, renaming to 'c_" `x` "'",sourcefmt="%(lower)s",rename="c_%s") `x`
+#define PHPKW(x) %keywordwarn("'" `x` "' is a PHP keyword",sourcefmt="%(lower)s",rename="c_%s") `x`
+
+/* Keyword, except ok as a function */
+#define PHPKW_ok_as_function(x) %keywordwarn("'" `x` "' is a PHP keyword, renaming to 'c_" `x` "'",%$not %$isfunction,sourcefmt="%(lower)s",rename="c_%s") `x`
 
 /* Class (case insensitive) */
-#define PHPCN(x) %keywordwarn("'" `x` "' is a PHP reserved class name, renaming to 'c_" `x` "'",%$isclass,sourcefmt="%(lower)s",rename="c_%s") `x`
+#define PHPCN(x) %keywordwarn("'" `x` "' is a PHP reserved class name",%$isclass,sourcefmt="%(lower)s",rename="c_%s") `x`
 
 /* Constant (case insensitive) */
 #define PHPBN1a(x) %namewarn(%warningmsg(SWIGWARN_PARSE_BUILTIN_NAME, "enum conflicts with a built-in constant '"`x`"' in PHP"),%$isenumitem,sourcefmt="%(lower)s") `x`
@@ -22,7 +25,7 @@
  PHPBN2a(X); PHPBN2b(X)
 %enddef
 
-#define PHPFN(x) %keywordwarn("'" `x` "' is a PHP built-in function, renaming to 'c_" `x` "'",sourcefmt="%(lower)s",%$isfunction,%$not %$ismember,rename="c_%s") `x`
+#define PHPFN(x) %keywordwarn("'" `x` "' is a PHP built-in function",sourcefmt="%(lower)s",%$isfunction,%$not %$ismember,rename="c_%s") `x`
 
 /* From: http://php.net/manual/en/reserved.keywords.php
  * "You cannot use any of the following words as constants, class names,
@@ -55,6 +58,7 @@
 PHPKW(extends);
 PHPKW(final);
 PHPKW(finally);
+PHPKW(fn); // as of PHP 7.4
 PHPKW(for);
 PHPKW(foreach);
 PHPKW(function);
@@ -65,6 +69,7 @@
 PHPKW(instanceof);
 PHPKW(insteadof);
 PHPKW(interface);
+PHPKW(match); // as of PHP 8.0
 PHPKW(namespace);
 PHPKW(new);
 PHPKW(or);
@@ -82,6 +87,11 @@
 PHPKW(xor);
 PHPKW(yield);
 
+/* PHP 8.1 made `readonly` a keyword, but (unlike any other keyword it seems)
+ * it may still be used as a function name.
+ */
+PHPKW_ok_as_function(readonly);
+
 // Compile-time "magic" constants
 // From: http://php.net/manual/en/reserved.keywords.php
 // also at: http://php.net/manual/en/language.constants.predefined.php
@@ -119,6 +129,10 @@
 PHPBN2(PHP_EOL);
 PHPBN2(PHP_INT_MAX);
 PHPBN2(PHP_INT_SIZE);
+PHPBN2(PHP_FLOAT_DIG); // Since 7.2.0
+PHPBN2(PHP_FLOAT_EPSILON); // Since 7.2.0
+PHPBN2(PHP_FLOAT_MIN); // Since 7.2.0
+PHPBN2(PHP_FLOAT_MAX); // Since 7.2.0
 PHPBN2(DEFAULT_INCLUDE_PATH);
 PHPBN2(PEAR_INSTALL_DIR);
 PHPBN2(PEAR_EXTENSION_DIR);
@@ -134,6 +148,7 @@
 PHPBN2(PHP_CONFIG_FILE_PATH);
 PHPBN2(PHP_CONFIG_FILE_SCAN_DIR);
 PHPBN2(PHP_SHLIB_SUFFIX);
+PHPBN2(PHP_FD_SETSIZE); // Since 7.1.0
 PHPBN2(E_ERROR);
 PHPBN2(E_WARNING);
 PHPBN2(E_PARSE);
@@ -145,6 +160,7 @@
 PHPBN2(E_USER_ERROR);
 PHPBN2(E_USER_WARNING);
 PHPBN2(E_USER_NOTICE);
+PHPBN2(E_RECOVERABLE_ERROR);
 PHPBN2(E_DEPRECATED);
 PHPBN2(E_USER_DEPRECATED);
 PHPBN2(E_ALL);
@@ -156,6 +172,9 @@
 PHPBN2(PHP_OUTPUT_HANDLER_START);
 PHPBN2(PHP_OUTPUT_HANDLER_CONT);
 PHPBN2(PHP_OUTPUT_HANDLER_END);
+/* Since 7.4.0 (Microsoft Windows only) */
+PHPBN2(PHP_WINDOWS_EVENT_CTRL_C);
+PHPBN2(PHP_WINDOWS_EVENT_CTRL_BREAK);
 /* These don't actually seem to be set (tested on Linux, I guess they're
  * Windows only?) */
 PHPBN2(PHP_WINDOWS_NT_DOMAIN_CONTROLLER);
@@ -402,21 +421,6 @@
 PHPBN2(CURLOPT_TIMEOUT_MS);
 PHPBN2(CURLOPT_CONNECTTIMEOUT_MS);
 PHPBN2(GMP_VERSION);
-PHPBN2(SWFTEXTFIELD_USEFONT);
-PHPBN2(SWFTEXTFIELD_AUTOSIZE);
-PHPBN2(SWF_SOUND_NOT_COMPRESSED);
-PHPBN2(SWF_SOUND_ADPCM_COMPRESSED);
-PHPBN2(SWF_SOUND_MP3_COMPRESSED);
-PHPBN2(SWF_SOUND_NOT_COMPRESSED_LE);
-PHPBN2(SWF_SOUND_NELLY_COMPRESSED);
-PHPBN2(SWF_SOUND_5KHZ);
-PHPBN2(SWF_SOUND_11KHZ);
-PHPBN2(SWF_SOUND_22KHZ);
-PHPBN2(SWF_SOUND_44KHZ);
-PHPBN2(SWF_SOUND_8BITS);
-PHPBN2(SWF_SOUND_16BITS);
-PHPBN2(SWF_SOUND_MONO);
-PHPBN2(SWF_SOUND_STEREO);
 PHPBN2(OPENSSL_VERSION_NUMBER);
 PHPBN2(SNMP_OID_OUTPUT_FULL);
 PHPBN2(SNMP_OID_OUTPUT_NUMERIC);
@@ -627,27 +631,26 @@
 PHPBN2(PGSQL_POLLING_READING);
 PHPBN2(PGSQL_POLLING_WRITING);
 
-/* Class names reserved by PHP (case insensitive) */
+/* Class names reserved by PHP. */
+/* Check is case insensitive - these *MUST* be listed in lower case here. */
 PHPCN(directory);
 PHPCN(stdclass);
 PHPCN(__php_incomplete_class);
-/* Added in PHP5. */
 PHPCN(exception);
 PHPCN(errorexception);
 PHPCN(php_user_filter);
 PHPCN(closure);
 PHPCN(generator);
 PHPCN(self);
-PHPCN(static);
 PHPCN(parent);
 /* http://php.net/manual/en/migration70.incompatible.php#migration70.incompatible.other.classes */
 PHPCN(bool); // As of PHP 7.0
 PHPCN(int); // As of PHP 7.0
 PHPCN(float); // As of PHP 7.0
 PHPCN(string); // As of PHP 7.0
-PHPCN(NULL); // As of PHP 7.0
-PHPCN(TRUE); // As of PHP 7.0
-PHPCN(FALSE); // As of PHP 7.0
+PHPCN(null); // As of PHP 7.0
+PHPCN(true); // As of PHP 7.0
+PHPCN(false); // As of PHP 7.0
 PHPCN(resource); // As of PHP 7.0 (currently works but reserved)
 PHPCN(object); // As of PHP 7.0 (currently works but reserved)
 PHPCN(mixed); // As of PHP 7.0 (currently works but reserved)
@@ -655,6 +658,14 @@
 /* http://php.net/manual/en/migration71.incompatible.php#migration71.incompatible.invalid-class-names */
 PHPCN(iterable); // As of PHP 7.1
 PHPCN(void); // As of PHP 7.1
+/* Predefined interfaces and classes, introduced in PHP 7.0.0 */
+PHPCN(arithmeticerror);
+PHPCN(assertionerror);
+PHPCN(divisionbyzeroerror);
+PHPCN(error);
+PHPCN(throwable);
+PHPCN(parseerror);
+PHPCN(typeerror);
 /* From extensions (which of these are actually predefined depends which
  * extensions are loaded by default). */
 PHPCN(xmlwriter);
@@ -866,6 +877,7 @@
 PHPFN(usort);
 
 #undef PHPKW
+#undef PHPKW_ok_as_function
 #undef PHPBN1a
 #undef PHPBN1b
 #undef PHPBN1
diff --git a/Lib/php/phppointers.i b/Lib/php/phppointers.i
index d79697b..a4ff3c0 100644
--- a/Lib/php/phppointers.i
+++ b/Lib/php/phppointers.i
@@ -1,16 +1,12 @@
-%define %pass_by_ref( TYPE, CONVERT_IN, CONVERT_OUT )
-%typemap(in, byref=1) TYPE *REF ($*1_ltype tmp),
+%define %pass_by_ref( TYPE, PHP_TYPE, CONVERT_IN, CONVERT_OUT )
+%typemap(in,byref=1,phptype=PHP_TYPE) TYPE *REF ($*1_ltype tmp),
              TYPE &REF ($*1_ltype tmp)
 %{
-  /* First Check for SWIG wrapped type */
-  if (Z_ISNULL($input)) {
-      $1 = 0;
-  } else if (Z_ISREF($input)) {
-      /* Not swig wrapped type, so we check if it's a PHP reference type */
-      CONVERT_IN(tmp, $*1_ltype, $input);
-      $1 = &tmp;
+  if (Z_ISREF($input)) {
+    CONVERT_IN(tmp, $*1_ltype, $input);
+    $1 = &tmp;
   } else {
-      SWIG_PHP_Error(E_ERROR, SWIG_PHP_Arg_Error_Msg($argnum, Expected a reference));
+    zend_type_error(SWIG_PHP_Arg_Error_Msg($argnum, Expected a reference));
   }
 %}
 %typemap(argout) TYPE *REF,
@@ -22,25 +18,25 @@
 %}
 %enddef
 
-%pass_by_ref( size_t, CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( size_t, "int", CONVERT_INT_IN, ZVAL_LONG );
 
-%pass_by_ref( signed int, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( int, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( unsigned int, CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( signed int, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( int, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( unsigned int, "int", CONVERT_INT_IN, ZVAL_LONG );
 
-%pass_by_ref( signed short, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( short, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( unsigned short, CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( signed short, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( short, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( unsigned short, "int", CONVERT_INT_IN, ZVAL_LONG );
 
-%pass_by_ref( signed long, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( long, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( unsigned long, CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( signed long, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( long, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( unsigned long, "int", CONVERT_INT_IN, ZVAL_LONG );
 
-%pass_by_ref( signed char, CONVERT_INT_IN, ZVAL_LONG );
-%pass_by_ref( char, CONVERT_CHAR_IN, ZVAL_STRING );
-%pass_by_ref( unsigned char, CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( signed char, "int", CONVERT_INT_IN, ZVAL_LONG );
+%pass_by_ref( char, "string", CONVERT_CHAR_IN, ZVAL_STRING );
+%pass_by_ref( unsigned char, "int", CONVERT_INT_IN, ZVAL_LONG );
 
-%pass_by_ref( float, CONVERT_FLOAT_IN, ZVAL_DOUBLE );
-%pass_by_ref( double, CONVERT_FLOAT_IN, ZVAL_DOUBLE );
+%pass_by_ref( float, "float", CONVERT_FLOAT_IN, ZVAL_DOUBLE );
+%pass_by_ref( double, "float", CONVERT_FLOAT_IN, ZVAL_DOUBLE );
 
-%pass_by_ref( char *, CONVERT_CHAR_IN, ZVAL_STRING );
+%pass_by_ref( char *, "string", CONVERT_CHAR_IN, ZVAL_STRING );
diff --git a/Lib/php/phprun.swg b/Lib/php/phprun.swg
index a07a1b9..588701f 100644
--- a/Lib/php/phprun.swg
+++ b/Lib/php/phprun.swg
@@ -4,24 +4,21 @@
  * PHP runtime library
  * ----------------------------------------------------------------------------- */
 
+#define swig_owntype                                    int
+
 #ifdef __cplusplus
 extern "C" {
 #endif
-#include "zend.h"
-#include "zend_API.h"
-#include "zend_exceptions.h"
-#include "php.h"
 
-#if PHP_MAJOR_VERSION != 7
-# error These bindings need PHP7 - to generate PHP5 bindings use: SWIG < 4.0.0 and swig -php5
+#if PHP_MAJOR_VERSION < 8
+# error These bindings need PHP 8 or later - to generate PHP7 bindings use SWIG < 4.1.0; to generate PHP5 bindings use: SWIG < 4.0.0 and swig -php5
 #endif
 
-#include "ext/standard/php_string.h"
-#include <stdlib.h> /* for abort(), used in generated code. */
+#include "zend_inheritance.h"
+#include "zend_exceptions.h"
+#include "zend_inheritance.h"
 
-/* This indirection is to work around const correctness issues in older PHP.
- * FIXME: Remove for PHP7?  Or might user code be using it? */
-#define SWIG_ZEND_NAMED_FE(ZN, N, A) ZEND_NAMED_FE(ZN, N, A)
+#include <stdlib.h> /* for abort(), used in generated code. */
 
 #define SWIG_BOOL_CONSTANT(N, V) REGISTER_BOOL_CONSTANT(#N, V, CONST_CS | CONST_PERSISTENT)
 #define SWIG_LONG_CONSTANT(N, V) REGISTER_LONG_CONSTANT(#N, V, CONST_CS | CONST_PERSISTENT)
@@ -32,13 +29,6 @@
     REGISTER_STRINGL_CONSTANT(#N, &swig_char, 1, CONST_CS | CONST_PERSISTENT);\
 } while (0)
 
-/* ZEND_CONSTANT_SET_FLAGS is new in PHP 7.3. */
-#ifdef ZEND_CONSTANT_SET_FLAGS
-# define SWIG_ZEND_CONSTANT_SET_FLAGS ZEND_CONSTANT_SET_FLAGS
-#else
-# define SWIG_ZEND_CONSTANT_SET_FLAGS(C, F, N) do { (C)->flags = (F); (C)->module_number = (N); } while (0)
-#endif
-
 #ifdef __cplusplus
 }
 #endif
@@ -50,178 +40,125 @@
 
 #define SWIG_PHP_Arg_Error_Msg(argnum,extramsg) "Error in argument " #argnum " "#extramsg
 
-#define SWIG_PHP_Error(code,msg) do { SWIG_ErrorCode() = code; SWIG_ErrorMsg() = msg; SWIG_fail; } while (0)
+#define SWIG_PHP_Error(code,msg) do { zend_throw_exception(NULL, msg, code); SWIG_fail; } while (0)
 
 #define SWIG_contract_assert(expr,msg) \
-  if (!(expr) ) { zend_printf("Contract Assert Failed %s\n",msg ); } else
+  do { if (!(expr)) zend_printf("Contract Assert Failed %s\n", msg); } while (0)
 
 /* Standard SWIG API */
 #define SWIG_GetModule(clientdata) SWIG_Php_GetModule()
 #define SWIG_SetModule(clientdata, pointer) SWIG_Php_SetModule(pointer, *(int*)clientdata)
 
+static zend_class_entry SWIG_Php_swig_wrapped_interface_ce;
+
 /* used to wrap returned objects in so we know whether they are newobject
    and need freeing, or not */
 typedef struct {
   void * ptr;
   int newobject;
+  const swig_type_info * type;
+  zend_object std;
 } swig_object_wrapper;
 
+#define SWIG_Z_FETCH_OBJ_P(zv) swig_php_fetch_object(Z_OBJ_P(zv))
+
+static inline
+swig_object_wrapper * swig_php_fetch_object(zend_object *obj) {
+  return (swig_object_wrapper *)((char *)obj - XtOffsetOf(swig_object_wrapper, std));
+}
+
 #define SWIG_as_voidptr(a) const_cast< void * >(static_cast< const void * >(a))
 
 static void
 SWIG_SetPointerZval(zval *z, void *ptr, swig_type_info *type, int newobject) {
-  /*
-   * First test for Null pointers.  Return those as PHP native NULL
-   */
-  if (!ptr ) {
+  // Return PHP NULL for a C/C++ NULL pointer.
+  if (!ptr) {
     ZVAL_NULL(z);
     return;
   }
-  if (type->clientdata) {
-    swig_object_wrapper *value;
-    if (! (*(int *)(type->clientdata)))
-      zend_error(E_ERROR, "Type: %s failed to register with zend",type->name);
-    value=(swig_object_wrapper *)emalloc(sizeof(swig_object_wrapper));
-    value->ptr=ptr;
-    value->newobject=(newobject & 1);
-    if ((newobject & 2) == 0) {
-      /* Just register the pointer as a resource. */
-      ZVAL_RES(z, zend_register_resource(value, *(int *)(type->clientdata)));
-    } else {
-      /*
-       * Wrap the resource in an object, the resource will be accessible
-       * via the "_cPtr" member. This is currently only used by
-       * directorin typemaps.
-       */
-      zval resource;
-      zend_class_entry *ce = NULL;
-      const char *type_name = type->name+3; /* +3 so: _p_Foo -> Foo */
-      size_t type_name_len;
-      const char * p;
-      HashTable * ht;
 
-      /* Namespace__Foo -> Foo */
-      /* FIXME: ugly and goes wrong for classes with __ in their names. */
-      while ((p = strstr(type_name, "__")) != NULL) {
-        type_name = p + 2;
-      }
-      type_name_len = strlen(type_name);
-
-      ZVAL_RES(&resource, zend_register_resource(value, *(int *)(type->clientdata)));
-      if (SWIG_PREFIX_LEN > 0) {
-        zend_string * classname = zend_string_alloc(SWIG_PREFIX_LEN + type_name_len, 0);
-        memcpy(classname->val, SWIG_PREFIX, SWIG_PREFIX_LEN);
-        memcpy(classname->val + SWIG_PREFIX_LEN, type_name, type_name_len);
-        ce = zend_lookup_class(classname);
-        zend_string_release(classname);
-      } else {
-        zend_string * classname = zend_string_init(type_name, type_name_len, 0);
-        ce = zend_lookup_class(classname);
-        zend_string_release(classname);
-      }
-      if (ce == NULL) {
-        /* class does not exist */
-        ce = zend_standard_class_def;
-      }
-
-      ALLOC_HASHTABLE(ht);
-      zend_hash_init(ht, 1, NULL, NULL, 0);
-      zend_hash_str_update(ht, "_cPtr", sizeof("_cPtr") - 1, &resource);
-      object_and_properties_init(z, ce, ht);
-    }
+  if (!type->clientdata) {
+    zend_type_error("Type: %s not registered with zend", type->name);
     return;
   }
-  zend_error(E_ERROR, "Type: %s not registered with zend",type->name);
+
+  {
+    zend_object *obj;
+    swig_object_wrapper *value;
+    if (Z_TYPE_P(z) == IS_OBJECT) {
+      /* The PHP object is already initialised - this is the case when wrapping
+       * the return value from a PHP constructor. */
+      obj = Z_OBJ_P(z);
+    } else {
+      zend_class_entry *ce = (zend_class_entry*)(type->clientdata);
+      obj = ce->create_object(ce);
+      ZVAL_OBJ(z, obj);
+    }
+    value = swig_php_fetch_object(obj);
+    value->ptr = ptr;
+    value->newobject = (newobject & 1);
+    value->type = type;
+  }
 }
 
-/* This pointer conversion routine takes the native pointer p (along with
-   its type name) and converts it by calling appropriate casting functions
-   according to ty.  The resultant pointer is returned, or NULL is returned
-   if the pointer can't be cast.
-
-   Sadly PHP has no API to find a type name from a type id, only from an
-   instance of a resource of the type id, so we have to pass type_name as well.
-
-   The two functions which might call this are:
-   SWIG_ConvertResourcePtr which gets the type name from the resource
-   and the registered zend destructors for which we have one per type each
-   with the type name hard wired in. */
-static void *
-SWIG_ConvertResourceData(void * p, const char *type_name, swig_type_info *ty) {
-  swig_cast_info *tc;
-  void *result = 0;
-
-  if (!ty) {
-    /* They don't care about the target type, so just pass on the pointer! */
-    return p;
-  }
-
-  if (! type_name) {  
-    /* can't convert p to ptr type ty if we don't know what type p is */
-    return NULL;
-  }
-
-  /* convert and cast p from type_name to ptr as ty. */
-  tc = SWIG_TypeCheck(type_name, ty);
-  if (tc) {
-    int newmemory = 0;
-    result = SWIG_TypeCast(tc, p, &newmemory);
-    assert(!newmemory); /* newmemory handling not yet implemented */
-  }
-  return result;
-}
-
-/* This function returns a pointer of type ty by extracting the pointer
-   and type info from the resource in z.  z must be a resource.
-   If it fails, NULL is returned.
-   It uses SWIG_ConvertResourceData to do the real work. */
-static void *
-SWIG_ConvertResourcePtr(zval *z, swig_type_info *ty, int flags) {
-  swig_object_wrapper *value;
-  void *p;
-  const char *type_name;
-
-  if (Z_RES_TYPE_P(z) == -1) return NULL;
-  value = (swig_object_wrapper *) Z_RES_VAL_P(z);
-  if (flags & SWIG_POINTER_DISOWN) {
-    value->newobject = 0;
-  }
-  p = value->ptr;
-
-  type_name=zend_rsrc_list_get_rsrc_type(Z_RES_P(z));
-
-  return SWIG_ConvertResourceData(p, type_name, ty);
-}
-
-/* We allow passing of a RESOURCE pointing to the object or an OBJECT whose
-   _cPtr is a resource pointing to the object */
+/* We wrap C/C++ pointers as PHP objects. */
 static int
-SWIG_ConvertPtr(zval *z, void **ptr, swig_type_info *ty, int flags) {
+SWIG_ConvertPtrAndOwn(zval *z, void **ptr, swig_type_info *ty, int flags, swig_owntype *own) {
+  if (own)
+    *own = 0;
+
   if (z == NULL) {
     *ptr = 0;
-    return 0;
+    return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
   }
 
   switch (Z_TYPE_P(z)) {
     case IS_OBJECT: {
-      HashTable * ht = Z_OBJ_HT_P(z)->get_properties(z);
-      if (ht) {
-        zval * _cPtr = zend_hash_str_find(ht, "_cPtr", sizeof("_cPtr") - 1);
-        if (_cPtr) {
-          if (Z_TYPE_P(_cPtr) == IS_INDIRECT) {
-            _cPtr = Z_INDIRECT_P(_cPtr);
-          }
-          if (Z_TYPE_P(_cPtr) == IS_RESOURCE) {
-            *ptr = SWIG_ConvertResourcePtr(_cPtr, ty, flags);
-            return (*ptr == NULL ? -1 : 0);
-          }
+      zend_object *obj = Z_OBJ_P(z);
+      swig_object_wrapper *value;
+      if (ty && ty->clientdata == (void*)obj->ce) {
+	// Object is exactly the class asked for - this handles common cases cheaply,
+	// and in particular the PHP classes we use to wrap a pointer to a non-class.
+      } else if (!zend_class_implements_interface(obj->ce, &SWIG_Php_swig_wrapped_interface_ce)) {
+	// Not an object we've wrapped.
+	return -1;
+      }
+
+      /* convert and cast value->ptr from value->type to ptr as ty. */
+      value = swig_php_fetch_object(obj);
+      if (!ty) {
+	/* They don't care about the target type, so just pass on the pointer! */
+	*ptr = value->ptr;
+      } else {
+	swig_cast_info *tc = SWIG_TypeCheck(value->type->name, ty);
+	if (tc) {
+	  int newmemory = 0;
+	  *ptr = SWIG_TypeCast(tc, value->ptr, &newmemory);
+	  if (newmemory == SWIG_CAST_NEW_MEMORY) {
+	    assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
+	    if (own)
+	      *own |= SWIG_CAST_NEW_MEMORY;
+	  }
+	} else {
+	  *ptr = NULL;
+	}
+      }
+
+      if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !value->newobject) {
+        return SWIG_ERROR_RELEASE_NOT_OWNED;
+      } else {
+        if (*ptr == NULL)
+          return SWIG_ERROR; /* should be SWIG_NullReferenceError?? */
+        if (flags & SWIG_POINTER_DISOWN) {
+          value->newobject = 0;
+        }
+        if (flags & SWIG_POINTER_CLEAR) {
+          value->ptr = 0;
         }
       }
-      break;
+
+      return SWIG_OK;
     }
-    case IS_RESOURCE:
-      *ptr = SWIG_ConvertResourcePtr(z, ty, flags);
-      return (*ptr == NULL ? -1 : 0);
     case IS_NULL:
       *ptr = 0;
       return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
@@ -230,17 +167,43 @@
   return -1;
 }
 
+static int
+SWIG_ConvertPtr(zval *z, void **ptr, swig_type_info *ty, int flags) {
+  return SWIG_ConvertPtrAndOwn(z, ptr, ty, flags, 0);
+}
+
 static const char const_name[] = "swig_runtime_data_type_pointer";
-static swig_module_info *SWIG_Php_GetModule() {
+static swig_module_info *SWIG_Php_GetModule(void) {
   zval *pointer = zend_get_constant_str(const_name, sizeof(const_name) - 1);
   if (pointer) {
     if (Z_TYPE_P(pointer) == IS_LONG) {
       return (swig_module_info *) pointer->value.lval;
     }
-  } 
+  }
   return NULL;
 }
 
 static void SWIG_Php_SetModule(swig_module_info *pointer, int module_number) {
   REGISTER_LONG_CONSTANT(const_name, (long) pointer, CONST_CS | CONST_PERSISTENT);
 }
+
+/* Common parts of the "create_object" object handler. */
+static zend_object *SWIG_Php_do_create_object(zend_class_entry *ce, zend_object_handlers *handlers) {
+  swig_object_wrapper *obj = (swig_object_wrapper*)zend_object_alloc(sizeof(swig_object_wrapper), ce);
+  zend_object_std_init(&obj->std, ce);
+  object_properties_init(&obj->std, ce);
+  obj->std.handlers = handlers;
+  obj->newobject = 1;
+  return &obj->std;
+}
+
+/* Common parts of the "free_obj" object handler.
+   Returns void* pointer if the C/C++ object should be destroyed. */
+static void* SWIG_Php_free_obj(zend_object *object) {
+  if (object) {
+    swig_object_wrapper *obj = swig_php_fetch_object(object);
+    zend_object_std_dtor(&obj->std);
+    if (obj->newobject) return obj->ptr;
+  }
+  return NULL;
+}
diff --git a/Lib/php/std_auto_ptr.i b/Lib/php/std_auto_ptr.i
new file mode 100644
index 0000000..2840916
--- /dev/null
+++ b/Lib/php/std_auto_ptr.i
@@ -0,0 +1,41 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr(&$input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      zend_type_error("Cannot release ownership as memory is not owned for argument $argnum of $descriptor(TYPE *) of $symname");
+      return;
+    } else {
+      zend_type_error("Expected $descriptor(TYPE *) for argument $argnum of $symname");
+      return;
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+  SWIG_SetPointerZval($result, (void *)$1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN);
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr(&$input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class auto_ptr {};
+}
diff --git a/Lib/php/std_common.i b/Lib/php/std_common.i
index 092bf01..1b69fc7 100644
--- a/Lib/php/std_common.i
+++ b/Lib/php/std_common.i
@@ -7,4 +7,3 @@
 %include <std/std_except.i>
 
 %apply size_t { std::size_t };
-
diff --git a/Lib/php/std_map.i b/Lib/php/std_map.i
index 7c01573..6904efc 100644
--- a/Lib/php/std_map.i
+++ b/Lib/php/std_map.i
@@ -35,7 +35,7 @@
 
         map();
         map(const map& other);
-        
+
         unsigned int size() const;
         void clear();
         %extend {
@@ -47,7 +47,11 @@
                     throw std::out_of_range("key not found");
             }
             void set(const K& key, const T& x) {
+%#ifdef __cpp_lib_map_try_emplace
+                (*self).insert_or_assign(key, x);
+%#else
                 (*self)[key] = x;
+%#endif
             }
             void del(const K& key) throw (std::out_of_range) {
                 std::map< K, T, C >::iterator i = self->find(key);
@@ -66,17 +70,4 @@
         }
     };
 
-// Legacy macros (deprecated)
-%define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_key ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_value ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO)
-#warning "specialize_std_map_on_both ignored - macro is deprecated and no longer necessary"
-%enddef
-
 }
diff --git a/Lib/php/std_string.i b/Lib/php/std_string.i
index b55751f..5abbbbb 100644
--- a/Lib/php/std_string.i
+++ b/Lib/php/std_string.i
@@ -4,19 +4,21 @@
  * SWIG typemaps for std::string types
  * ----------------------------------------------------------------------------- */
 
-// ------------------------------------------------------------------------
-// std::string is typemapped by value
-// This can prevent exporting methods which return a string
-// in order for the user to modify it.
-// However, I think I'll wait until someone asks for it...
-// ------------------------------------------------------------------------
-
-%include <exception.i>
-
 %{
 #include <string>
 %}
 
+/* std::string and const std::string& are converted to/from PHP string
+ * automatically.
+ *
+ * A C++ std::string& parameter is wrapped as a pass-by-reference PHP
+ * string parameter by default, but the INPUT/INOUT/OUTPUT typemaps
+ * below provide other options (see below).
+ *
+ * std::string* is not wrapped by default, but INPUT/INOUT/OUTPUT typemaps
+ * are provided (see below).
+ */
+
 namespace std {
 
     %naturalvar string;
@@ -27,19 +29,17 @@
         $1 = (Z_TYPE($input) == IS_STRING) ? 1 : 0;
     %}
 
-    %typemap(in) string %{
+    %typemap(in, phptype="string") string %{
         convert_to_string(&$input);
         $1.assign(Z_STRVAL($input), Z_STRLEN($input));
     %}
 
     %typemap(directorout) string %{
-      if (!EG(exception)) {
         convert_to_string($input);
         $result.assign(Z_STRVAL_P($input), Z_STRLEN_P($input));
-      }
     %}
 
-    %typemap(out) string %{
+    %typemap(out, phptype="string") string %{
         ZVAL_STRINGL($result, $1.data(), $1.size());
     %}
 
@@ -47,24 +47,31 @@
         ZVAL_STRINGL($input, $1.data(), $1.size());
     %}
 
-    %typemap(out) const string & %{
+    %typemap(out, phptype="string") const string& %{
         ZVAL_STRINGL($result, $1->data(), $1->size());
     %}
 
     %typemap(throws) string, const string& %{
         zend_throw_exception(NULL, $1.c_str(), 0);
-        return;
+        goto fail;
     %}
 
-    %typemap(in) const string & ($*1_ltype temp) %{
+    %typemap(throws) string*, const string* %{
+        zend_throw_exception(NULL, $1->c_str(), 0);
+        goto fail;
+    %}
+
+    %typemap(in, phptype="string") const string& ($*1_ltype temp) %{
         convert_to_string(&$input);
         temp.assign(Z_STRVAL($input), Z_STRLEN($input));
         $1 = &temp;
     %}
 
-    /* These next two handle a function which takes a non-const reference to
-     * a std::string and modifies the string. */
-    %typemap(in,byref=1) string & ($*1_ltype temp) %{
+    /*************************************************************************/
+
+    /* These next four typemaps handle a function which takes a non-const
+     * reference to a std::string and modifies the string. */
+    %typemap(in,byref=1, phptype="string") string& ($*1_ltype temp) %{
         {
           zval * p = Z_ISREF($input) ? Z_REFVAL($input) : &$input;
           convert_to_string(p);
@@ -73,16 +80,14 @@
         }
     %}
 
-    %typemap(directorout) string & ($*1_ltype *temp) %{
-      if (!EG(exception)) {
+    %typemap(directorout) string& ($*1_ltype *temp) %{
         convert_to_string($input);
         temp = new $*1_ltype(Z_STRVAL_P($input), Z_STRLEN_P($input));
         swig_acquire_ownership(temp);
         $result = temp;
-      }
     %}
 
-    %typemap(argout) string & %{
+    %typemap(argout) string& %{
       if (Z_ISREF($input)) {
         ZVAL_STRINGL(Z_REFVAL($input), $1->data(), $1->size());
       }
@@ -90,5 +95,27 @@
 
     /* SWIG will apply the non-const typemap above to const string& without
      * this more specific typemap. */
-    %typemap(argout) const string & "";
+    %typemap(argout) const string& ""
+
+    /*************************************************************************/
+
+    /* Alternative ways to handle string& - you can specify how to wrap based
+     * on the parameter name, e.g. this handles parameters named `str` as
+     * INOUT:
+     *
+     * %apply (std::string& INOUT) (std::string& str);
+     */
+
+    %typemap(in) string& INPUT = const string&;
+    %typemap(in, numinputs=0) string& OUTPUT ($*1_ltype temp)
+    %{ $1 = &temp; %}
+    %typemap(argout,fragment="t_output_helper") string& OUTPUT
+    {
+      zval o;
+      ZVAL_STRINGL(&o, $1->data(), $1->size());
+      t_output_helper($result, &o);
+    }
+    %typemap(in) string& INOUT = const string&;
+    %typemap(argout) string& INOUT = string& OUTPUT;
+
 }
diff --git a/Lib/php/std_string_view.i b/Lib/php/std_string_view.i
new file mode 100644
index 0000000..8fff6e1
--- /dev/null
+++ b/Lib/php/std_string_view.i
@@ -0,0 +1,69 @@
+/* -----------------------------------------------------------------------------
+ * std_string_view.i
+ *
+ * SWIG typemaps for std::string_view types
+ * ----------------------------------------------------------------------------- */
+
+%include <exception.i>
+
+%{
+#include <string_view>
+%}
+
+namespace std {
+
+    %naturalvar string_view;
+
+    class string_view;
+
+    %typemap(typecheck,precedence=SWIG_TYPECHECK_STRINGVIEW) string_view, const string_view& %{
+        $1 = (Z_TYPE($input) == IS_STRING) ? 1 : 0;
+    %}
+
+    %typemap(in, phptype="string") string_view %{
+        convert_to_string(&$input);
+        $1 = std::string_view(Z_STRVAL($input), Z_STRLEN($input));
+    %}
+
+    %typemap(in, phptype="string") const string_view& ($*1_ltype temp) %{
+        convert_to_string(&$input);
+        temp = std::string_view(Z_STRVAL($input), Z_STRLEN($input));
+        $1 = &temp;
+    %}
+
+    %typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) string_view %{
+        convert_to_string($input);
+        $result = std::string_view(Z_STRVAL_P($input), Z_STRLEN_P($input));
+    %}
+
+    %typemap(out, phptype="string") string_view %{
+        ZVAL_STRINGL($result, $1.data(), $1.size());
+    %}
+
+    %typemap(directorin) string_view, const string_view& %{
+        ZVAL_STRINGL($input, $1.data(), $1.size());
+    %}
+
+    %typemap(out, phptype="string") const string_view& %{
+        ZVAL_STRINGL($result, $1->data(), $1->size());
+    %}
+
+    %typemap(throws) string_view, const string_view& %{
+        {
+            zval swig_exception;
+            ZVAL_STRINGL(&swig_exception, $1.data(), $1.size());
+            zend_throw_exception_object(&swig_exception);
+            goto fail;
+        }
+    %}
+
+    %typemap(throws) string_view*, const string_view* %{
+        {
+            zval swig_exception;
+            ZVAL_STRINGL(&swig_exception, $1->data(), $1->size());
+            zend_throw_exception_object(&swig_exception);
+            goto fail;
+        }
+    %}
+
+}
diff --git a/Lib/php/std_unique_ptr.i b/Lib/php/std_unique_ptr.i
new file mode 100644
index 0000000..1bf3159
--- /dev/null
+++ b/Lib/php/std_unique_ptr.i
@@ -0,0 +1,41 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr(&$input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      zend_type_error("Cannot release ownership as memory is not owned for argument $argnum of $descriptor(TYPE *) of $symname");
+      return;
+    } else {
+      zend_type_error("Expected $descriptor(TYPE *) for argument $argnum of $symname");
+      return;
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+  SWIG_SetPointerZval($result, (void *)$1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN);
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr(&$input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class unique_ptr {};
+}
diff --git a/Lib/php/std_vector.i b/Lib/php/std_vector.i
index e633bc3..382b37c 100644
--- a/Lib/php/std_vector.i
+++ b/Lib/php/std_vector.i
@@ -112,5 +112,3 @@
 %define specialize_std_vector(T)
 #warning "specialize_std_vector - specialization for type T no longer needed"
 %enddef
-
-
diff --git a/Lib/php/stl.i b/Lib/php/stl.i
index 04f8601..38aba67 100644
--- a/Lib/php/stl.i
+++ b/Lib/php/stl.i
@@ -7,4 +7,3 @@
 %include <std_vector.i>
 %include <std_map.i>
 %include <std_pair.i>
-
diff --git a/Lib/php/swigmove.i b/Lib/php/swigmove.i
new file mode 100644
index 0000000..b16a3c5
--- /dev/null
+++ b/Lib/php/swigmove.i
@@ -0,0 +1,24 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.i
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in, noblock=1) SWIGTYPE MOVE (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr(&$input, &argp, $&1_descriptor, SWIG_POINTER_RELEASE);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      zend_type_error("Cannot release ownership as memory is not owned for argument $argnum of $&1_descriptor of $symname");
+      return;
+    } else {
+      zend_type_error("Expected $&1_descriptor for argument $argnum of $symname");
+      return;
+    }
+  }
+  if (!argp) {
+    zend_type_error("Invalid null reference for argument $argnum of $&1_descriptor of $symname");
+    return;
+  }
+  SwigValueWrapper< $1_ltype >::reset($1, ($&1_type)argp);
+}
diff --git a/Lib/php/typemaps.i b/Lib/php/typemaps.i
index c248a58..718469e 100644
--- a/Lib/php/typemaps.i
+++ b/Lib/php/typemaps.i
@@ -25,21 +25,21 @@
  * ----------------------------------------------------------------------------- */
 
 %define BOOL_TYPEMAP(TYPE)
-%typemap(in) TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
+%typemap(in, phptype="bool") TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
 %{
   convert_to_boolean(&$input);
   temp = (Z_TYPE($input) == IS_TRUE);
   $1 = &temp;
 %}
-%typemap(argout) TYPE *INPUT, TYPE &INPUT "";
-%typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;";
+%typemap(argout) TYPE *INPUT, TYPE &INPUT ""
+%typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;"
 %typemap(argout,fragment="t_output_helper") TYPE *OUTPUT, TYPE &OUTPUT
 {
   zval o;
   ZVAL_BOOL(&o, temp$argnum);
   t_output_helper($result, &o);
 }
-%typemap(in) TYPE *REFERENCE (TYPE lvalue), TYPE &REFERENCE (TYPE lvalue)
+%typemap(in, phptype="float") TYPE *REFERENCE (TYPE lvalue), TYPE &REFERENCE (TYPE lvalue)
 %{
   convert_to_boolean($input);
   lvalue = (Z_TYPE_P($input) == IS_TRUE);
@@ -52,20 +52,20 @@
 %enddef
 
 %define DOUBLE_TYPEMAP(TYPE)
-%typemap(in) TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
+%typemap(in, phptype="float") TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
 %{
   temp = (TYPE) zval_get_double(&$input);
   $1 = &temp;
 %}
-%typemap(argout) TYPE *INPUT, TYPE &INPUT "";
-%typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;";
+%typemap(argout) TYPE *INPUT, TYPE &INPUT ""
+%typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;"
 %typemap(argout,fragment="t_output_helper") TYPE *OUTPUT, TYPE &OUTPUT
 {
   zval o;
   ZVAL_DOUBLE(&o, temp$argnum);
   t_output_helper($result, &o);
 }
-%typemap(in) TYPE *REFERENCE (TYPE dvalue), TYPE &REFERENCE (TYPE dvalue)
+%typemap(in, phptype="float") TYPE *REFERENCE (TYPE dvalue), TYPE &REFERENCE (TYPE dvalue)
 %{
   dvalue = (TYPE) zval_get_double(&$input);
   $1 = &dvalue;
@@ -77,20 +77,20 @@
 %enddef
 
 %define INT_TYPEMAP(TYPE)
-%typemap(in) TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
+%typemap(in, phptype="int") TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
 %{
   temp = (TYPE) zval_get_long(&$input);
   $1 = &temp;
 %}
-%typemap(argout) TYPE *INPUT, TYPE &INPUT "";
-%typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;";
+%typemap(argout) TYPE *INPUT, TYPE &INPUT ""
+%typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;"
 %typemap(argout,fragment="t_output_helper") TYPE *OUTPUT, TYPE &OUTPUT
 {
   zval o;
   ZVAL_LONG(&o, temp$argnum);
   t_output_helper($result, &o);
 }
-%typemap(in) TYPE *REFERENCE (TYPE lvalue), TYPE &REFERENCE (TYPE lvalue)
+%typemap(in, phptype="int") TYPE *REFERENCE (TYPE lvalue), TYPE &REFERENCE (TYPE lvalue)
 %{
   lvalue = (TYPE) zval_get_long(&$input);
   $1 = &lvalue;
@@ -122,13 +122,11 @@
   if ((long long)LONG_MIN <= temp$argnum && temp$argnum <= (long long)LONG_MAX) {
     ZVAL_LONG(&o, (long)temp$argnum);
   } else {
-    char temp[256];
-    sprintf(temp, "%lld", (long long)temp$argnum);
-    ZVAL_STRING(&o, temp);
+    ZVAL_NEW_STR(&o, zend_strpprintf(0, "%lld", (long long)temp$argnum));
   }
   t_output_helper($result, &o);
 }
-%typemap(in) TYPE *REFERENCE (long long lvalue)
+%typemap(in, phptype="int|string") TYPE *REFERENCE (long long lvalue)
 %{
   CONVERT_LONG_LONG_IN(lvalue, long long, $input)
   $1 = &lvalue;
@@ -138,9 +136,7 @@
   if ((long long)LONG_MIN <= lvalue$argnum && lvalue$argnum <= (long long)LONG_MAX) {
     ZVAL_LONG(&$arg, (long)temp$argnum);
   } else {
-    char temp[256];
-    sprintf(temp, "%lld", (long long)lvalue$argnum);
-    ZVAL_STRING(&$arg, temp);
+    ZVAL_NEW_STR(&$arg, zend_strpprintf(0, "%lld", (long long)lvalue$argnum));
   }
 %}
 %typemap(argout) long long &OUTPUT
@@ -148,11 +144,10 @@
   if ((long long)LONG_MIN <= *arg$argnum && *arg$argnum <= (long long)LONG_MAX) {
     ZVAL_LONG($result, (long)(*arg$argnum));
   } else {
-    char temp[256];
-    sprintf(temp, "%lld", (long long)(*arg$argnum));
-    ZVAL_STRING($result, temp);
+    ZVAL_NEW_STR($result, zend_strpprintf(0, "%lld", (long long)(*arg$argnum)));
   }
 %}
+
 INT_TYPEMAP(unsigned long long);
 %typemap(argout,fragment="t_output_helper") unsigned long long *OUTPUT
 {
@@ -160,13 +155,11 @@
   if (temp$argnum <= (unsigned long long)LONG_MAX) {
     ZVAL_LONG(&o, temp$argnum);
   } else {
-    char temp[256];
-    sprintf(temp, "%llu", (unsigned long long)temp$argnum);
-    ZVAL_STRING(&o, temp);
+    ZVAL_NEW_STR(&o, zend_strpprintf(0, "%llu", (unsigned long long)temp$argnum));
   }
   t_output_helper($result, &o);
 }
-%typemap(in) TYPE *REFERENCE (unsigned long long lvalue)
+%typemap(in, phptype="int|string") TYPE *REFERENCE (unsigned long long lvalue)
 %{
   CONVERT_UNSIGNED_LONG_LONG_IN(lvalue, unsigned long long, $input)
   $1 = &lvalue;
@@ -176,9 +169,7 @@
   if (lvalue$argnum <= (unsigned long long)LONG_MAX) {
     ZVAL_LONG($arg, (long)(lvalue$argnum));
   } else {
-    char temp[256];
-    sprintf(temp, "%llu", (unsigned long long)lvalue$argnum);
-    ZVAL_STRING((*$arg), temp);
+    ZVAL_NEW_STR((*$arg), zend_strpprintf(0, "%llu", (unsigned long long)lvalue$argnum));
   }
 %}
 %typemap(argout) unsigned long long &OUTPUT
@@ -186,9 +177,7 @@
   if (*arg$argnum <= (unsigned long long)LONG_MAX) {
     ZVAL_LONG($result, (long)(*arg$argnum));
   } else {
-    char temp[256];
-    sprintf(temp, "%llu", (unsigned long long)(*arg$argnum));
-    ZVAL_STRING($result, temp);
+    ZVAL_NEW_STR($result, zend_strpprintf(0, "%llu", (unsigned long long)(*arg$argnum)));
   }
 %}
 
@@ -252,7 +241,7 @@
 %typemap(argout) unsigned long long &INOUT = unsigned long long *OUTPUT;
 %typemap(argout) signed char &INOUT = signed char *OUTPUT;
 
-%typemap(in) char INPUT[ANY] ( char temp[$1_dim0] )
+%typemap(in, phptype="string") char INPUT[ANY] ( char temp[$1_dim0] )
 %{
   convert_to_string(&$input);
   strncpy(temp, Z_STRVAL($input), $1_dim0);
@@ -267,7 +256,7 @@
   t_output_helper($result, &o);
 }
 
-%typemap(in,numinputs=0) void **OUTPUT (int force),
+%typemap(in,numinputs=0,phptype="?SWIGTYPE") void **OUTPUT (int force),
                          void *&OUTPUT (int force)
 %{
   /* If they pass NULL by reference, make it into a void*
@@ -276,7 +265,8 @@
     /* So... we didn't get a ref or ptr, but we'll accept NULL by reference */
     if (!(Z_ISREF($input) && Z_ISNULL_P(Z_REFVAL($input)))) {
       /* wasn't a pre/ref/thing, OR anything like an int thing */
-      SWIG_PHP_Error(E_ERROR, "Type error in argument $arg of $symname.");
+      zend_type_error("Expected reference or NULL for argument $arg of $symname");
+      return;
     }
   }
   force=0;
diff --git a/Lib/php/utils.i b/Lib/php/utils.i
index ed6e08f..33db942 100644
--- a/Lib/php/utils.i
+++ b/Lib/php/utils.i
@@ -16,9 +16,9 @@
           char * endptr;
           errno = 0;
           lvar = (t) strtoll(Z_STRVAL(invar), &endptr, 10);
-          if (*endptr && !errno) break;
-          /* FALL THRU */
+          if (*endptr == '\0' && !errno) break;
       }
+      /* FALL THRU */
       default:
           lvar = (t) zval_get_long(&invar);
   }
@@ -33,9 +33,9 @@
           char * endptr;
           errno = 0;
           lvar = (t) strtoull(Z_STRVAL(invar), &endptr, 10);
-          if (*endptr && !errno) break;
-          /* FALL THRU */
+          if (*endptr == '\0' && !errno) break;
       }
+      /* FALL THRU */
       default:
           lvar = (t) zval_get_long(&invar);
   }
@@ -63,28 +63,33 @@
   }
 %enddef
 
-%define %pass_by_val( TYPE, CONVERT_IN )
-%typemap(in) TYPE
+%define %pass_by_val( TYPE, PHP_TYPE, CONVERT_IN )
+%typemap(in, phptype=PHP_TYPE) TYPE
 %{
   CONVERT_IN($1,$1_ltype,$input);
 %}
-%typemap(in) const TYPE & ($*1_ltype temp)
+%typemap(in, phptype=PHP_TYPE) const TYPE & ($*1_ltype temp)
 %{
   CONVERT_IN(temp,$*1_ltype,$input);
   $1 = &temp;
 %}
 %typemap(directorout) TYPE
 %{
-  if (!EG(exception)) {
-    CONVERT_IN($result, $1_ltype, *$input);
-  }
+  CONVERT_IN($result, $1_ltype, *$input);
 %}
-%typemap(directorout) const TYPE & ($*1_ltype temp)
+%typemap(directorout) const TYPE &
 %{
-  if (!EG(exception)) {
-    CONVERT_IN(temp, $*1_ltype, *$input);
+  $*1_ltype swig_val;
+  CONVERT_IN(swig_val, $*1_ltype, *$input);
+  $1_ltype temp = new $*1_ltype(swig_val);
+  swig_acquire_ownership(temp);
+  $result = temp;
+%}
+%typemap(directorfree) const TYPE &
+%{
+  if (director) {
+    director->swig_release_ownership(%as_voidptr($input));
   }
-  $result = &temp;
 %}
 %enddef
 
diff --git a/Lib/pike/pike.swg b/Lib/pike/pike.swg
deleted file mode 100644
index a36bf3a..0000000
--- a/Lib/pike/pike.swg
+++ /dev/null
@@ -1,326 +0,0 @@
-/* -----------------------------------------------------------------------------
- * pike.swg
- *
- * Pike configuration module.
- * ----------------------------------------------------------------------------- */
-
-%insert(runtime) "swigrun.swg";            // Common C API type-checking code
-%insert(runtime) "pikerun.swg";         // Pike run-time code
-
-%insert(runtime) %{
-#ifdef __cplusplus
-extern "C" {
-#endif
-#include <pike/global.h>
-#include <pike/module.h>
-#include <pike/interpret.h>
-#ifdef __cplusplus
-}
-#endif
-%}
-
-/* -----------------------------------------------------------------------------
- *                          standard typemaps
- * ----------------------------------------------------------------------------- */
-
-/* --- Input arguments --- */
-
-/* Primitive datatypes. */
-
-%typemap(in, pikedesc="tInt")
-    int, unsigned int, short, unsigned short,
-    long, unsigned long, char, signed char, unsigned char,
-    bool, enum SWIGTYPE, long long, unsigned long long
-{
-    if ($input.type != T_INT)
-        Pike_error("Bad argument: Expected an integer.\n");
-    $1 = ($1_ltype) $input.u.integer;
-}
-
-%typemap(in, pikedesc="tFloat") float, double {
-    if ($input.type != T_FLOAT)
-        Pike_error("Bad argument: Expected a float.\n");
-    $1 = ($1_ltype) $input.u.float_number;
-}
-
-%typemap(in, pikedesc="tStr") char *, char [ANY] {
-    if ($input.type != T_STRING)
-        Pike_error("Bad argument: Expected a string.\n");
-    $1 = ($1_ltype) STR0($input.u.string);
-}
-
-/* Pointers, references and arrays */
-
-%typemap(in) SWIGTYPE *,
-             SWIGTYPE &,
-             SWIGTYPE &&,
-             SWIGTYPE []
-	"SWIG_ConvertPtr($input.u.object, (void **) &$1, $1_descriptor, 1);"
-	
-/* Void pointer.  Accepts any kind of pointer */
-%typemap(in) void * "/* FIXME */";
-
-/* Object passed by value. Convert to a pointer */
-%typemap(in) SWIGTYPE ($&1_ltype argp) "/* FIXME */";
-
-/* Pointer to a class member */
-%typemap(in) SWIGTYPE (CLASS::*) "/* FIXME */";
-
-/* Const primitive references.  Passed by value */
-
-%typemap(in, pikedesc="tInt") const int & (int temp),
-	     const short & (short temp),
-             const long  & (long temp),
-             const unsigned int & (unsigned int temp),
-             const unsigned short & (unsigned short temp),
-             const unsigned long & (unsigned long temp),
-	     const char & (char temp),
-             const signed char & (signed char temp),
-             const unsigned char & (unsigned char temp),
-             const bool & (bool temp),
-	     const long long & ($*1_ltype temp),
-	     const unsigned long long & ($*1_ltype temp),
-             const enum SWIGTYPE & ($*1_ltype temp),
-             const enum SWIGTYPE && ($*1_ltype temp)
-{
-  if ($input.type != T_INT)
-    Pike_error("Bad argument: Expected an integer.\n");
-    temp = ($*1_ltype) $input.u.integer;
-    $1 = &temp;
-}
-
-%typemap(in, pikedesc="tFloat") const float & (float temp),
-	     const double & (double temp)
-{
-  if ($input.type != T_FLOAT)
-    Pike_error("Bad argument: Expected a float.\n");
-    temp = ($*1_ltype) $input.u.float_number;
-    $1 = &temp;
-}
-
-/* -----------------------------------------------------------------------------
- * Output Typemaps
- * ----------------------------------------------------------------------------- */
-%typemap(out, pikedesc="tInt")
-    int, unsigned int,
-    short, unsigned short,
-    long, unsigned long,
-    char, signed char, unsigned char, 
-    bool, enum SWIGTYPE
-	"push_int($1);";
-
-%typemap(out, pikedesc="tInt") long long	"push_int64($1);";
-%typemap(out, pikedesc="tInt") unsigned long long	"push_int64($1);";
-%typemap(out, pikedesc="tFloat") float, double	"push_float($1);";
-%typemap(out, pikedesc="tStr") char *		"push_text($1);";
-
-/* Pointers, references, and arrays */
-%typemap(out, pikedesc="tObj") SWIGTYPE*, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] "push_object(SWIG_NewPointerObj((void *) $1, $1_descriptor, $owner));";
-
-/* Void return value; don't push anything */
-%typemap(out, pikedesc="tVoid") void		"";
-
-/* Dynamic casts */
-
-%typemap(out) SWIGTYPE *DYNAMIC, SWIGTYPE &DYNAMIC "/* FIXME */";
-
-/* Member pointer */
-%typemap(out) SWIGTYPE (CLASS::*) "/* FIXME */";
-
-/* Special typemap for character array return values */
-%typemap(out, pikedesc="tStr") char [ANY], const char [ANY] "push_text($1);";
-
-/* Primitive types--return by value */
-%typemap(out, pikedesc="tObj") SWIGTYPE 
-#ifdef __cplusplus
-{
-  $&1_ltype resultptr;
-  resultptr = new $1_ltype((const $1_ltype &) $1);
-  push_object(SWIG_NewPointerObj((void *) resultptr, $&1_descriptor, 1));
-}
-#else
-{
-  $&1_ltype resultptr;
-  resultptr = ($&1_ltype) malloc(sizeof($1_type));
-  memmove(resultptr, &$1, sizeof($1_type));
-  push_object(SWIG_NewPointerObj((void *) resultptr, $&1_descriptor, 1));
-}
-#endif
-
-/* References to primitive types.  Return by value */
-
-%typemap(out, pikedesc="tInt") const int &, const unsigned int &,
-              const short &, const unsigned short &,
-              const long &, const unsigned long &,
-              const char &, const signed char &, const unsigned char &,
-              const bool &,
-	      const long long &, const unsigned long long &,
-              const enum SWIGTYPE & ($*1_ltype temp),
-              const enum SWIGTYPE && ($*1_ltype temp)
-      "push_int(*($1));";
-
-%typemap(out, pikedesc="tFloat") const float &, const double &  "push_float(*($1));";
-
-/************************ Constant Typemaps *****************************/
-
-%typemap(constant)
-    int, unsigned int,
-    short, unsigned short,
-    long, unsigned long,
-    signed char, unsigned char, 
-    bool, enum SWIGTYPE,
-    long long, unsigned long long
-    	"add_integer_constant(\"$symname\", $1, 0);";
-
-%typemap(constant) char
-	"add_integer_constant(\"$symname\", '$1', 0);";
-
-%typemap(constant) long long, unsigned long long
-	"add_integer_constant(\"$symname\", $1, 0);";
-
-%typemap(constant) float, double
-	"add_float_constant(\"$symname\", $1, 0);";
-
-%typemap(constant) char *
-	"add_string_constant(\"$symname\", \"$1\", 0);";
-
-/* ------------------------------------------------------------
- * String & length
- * ------------------------------------------------------------ */
-
-%typemap(in) (char *STRING, int LENGTH), (char *STRING, size_t LENGTH) {
-    if ($input.type != T_STRING)
-        Pike_error("Bad argument: Expected a string.\n");
-    $1 = ($1_ltype) STR0($input.u.string);
-    $2 = ($2_ltype) $input.u.string->length;
-}
-
-/* ------------------------------------------------------------
- * ANSI C typemaps
- * ------------------------------------------------------------ */
-
-%typemap(in, pikedesc="tInt") size_t {
-    if ($input.type != T_INT)
-        Pike_error("Bad argument: Expected an integer.\n");
-    $1 = ($1_ltype) $input.u.integer;
-}
-
-%typemap(out)      size_t = long;
-
-/* ------------------------------------------------------------
- * Typechecking rules
- * ------------------------------------------------------------ */
-
-%typecheck(SWIG_TYPECHECK_INTEGER)
-	 int, short, long,
- 	 unsigned int, unsigned short, unsigned long,
-	 signed char, unsigned char,
-	 long long, unsigned long long,
-	 const int &, const short &, const long &,
- 	 const unsigned int &, const unsigned short &, const unsigned long &,
-	 const long long &, const unsigned long long &,
-	 enum SWIGTYPE, enum SWIGTYPE &, SWIGTYPE &&,
-         bool, const bool & 
-{
-  $1 = ($input.type == T_INT) ? 1 : 0;
-}
-
-%typecheck(SWIG_TYPECHECK_DOUBLE)
-	float, double,
-	const float &, const double &
-{
-  $1 = (($input.type == T_FLOAT) || ($input.type == T_INT)) ? 1 : 0;
-}
-
-%typecheck(SWIG_TYPECHECK_CHAR) char {
-  $1 = ($input.type == T_INT) ? 1 : 0;
-}
-
-%typecheck(SWIG_TYPECHECK_STRING) char * {
-  $1 = ($input.type == T_STRING) ? 1 : 0;
-}
-
-%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE &, SWIGTYPE &&, SWIGTYPE [] {
-  void *ptr;
-  if (SWIG_ConvertPtr($input.u.object, (void **) &ptr, $1_descriptor, 0) == -1) {
-    $1 = 0;
-  } else {
-    $1 = 1;
-  }
-}
-
-%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE {
-  void *ptr;
-  if (SWIG_ConvertPtr($input.u.object, (void **) &ptr, $&1_descriptor, 0) == -1) {
-    $1 = 0;
-  } else {
-    $1 = 1;
-  }
-}
-
-%typecheck(SWIG_TYPECHECK_VOIDPTR) void * {
-  void *ptr;
-  if (SWIG_ConvertPtr($input.u.object, (void **) &ptr, 0, 0) == -1) {
-    $1 = 0;
-  } else {
-    $1 = 1;
-  }
-}
-
-/* Array reference typemaps */
-%apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) }
-%apply SWIGTYPE && { SWIGTYPE ((&&)[ANY]) }
-
-/* const pointers */
-%apply SWIGTYPE * { SWIGTYPE *const }
-%apply SWIGTYPE (CLASS::*) { SWIGTYPE (CLASS::*const) }
-%apply SWIGTYPE & { SWIGTYPE (CLASS::*const&) }
-
-/* ------------------------------------------------------------
- * Overloaded operator support
- * ------------------------------------------------------------ */
-
-#ifdef __cplusplus
-%rename("`+")      *::operator+;
-%rename("`-")      *::operator-;
-%rename("`*")      *::operator*;
-%rename("`/")      *::operator/;
-%rename("`%")      *::operator%;
-%rename("`<<")     *::operator<<;
-%rename("`>>")     *::operator>>;
-%rename("`&")      *::operator&;
-%rename("`|")      *::operator|;
-%rename("`^")      *::operator^;
-%rename("`~")      *::operator~;
-%rename("`<")      *::operator<;
-%rename("`>")      *::operator>;
-%rename("`==")     *::operator==;
-
-/* Special cases */
-%rename("`()")     *::operator();
-
-#endif
-
-/* ------------------------------------------------------------
- * The start of the Pike initialization function
- * ------------------------------------------------------------ */
-
-%init "swiginit.swg"
-
-%init %{
-#ifdef __cplusplus
-extern "C"
-#endif
-PIKE_MODULE_EXIT {}
-
-#ifdef __cplusplus
-extern "C"
-#endif
-PIKE_MODULE_INIT
-{
-    struct program *pr;
-    SWIG_InitializeModule(0);
-%}
-
-/* pike keywords */
-%include <pikekw.swg>
diff --git a/Lib/pike/pikekw.swg b/Lib/pike/pikekw.swg
deleted file mode 100644
index 844b1f1..0000000
--- a/Lib/pike/pikekw.swg
+++ /dev/null
@@ -1,55 +0,0 @@
-#ifndef PIKE_PIKEKW_SWG_
-#define PIKE_PIKEKW_SWG_
-
-/* Warnings for Pike keywords */
-#define PIKEKW(x) %namewarn("314: '" #x "' is a pike keyword")  #x
-
-/*
-   from
-   http://www.http://docs.linux.cz/pike/tutorial_C.html
-
-*/
-
-
-PIKEKW(array);
-PIKEKW(break);
-PIKEKW(case);
-PIKEKW(catch);
-PIKEKW(continue);
-PIKEKW(default);
-PIKEKW(do);
-PIKEKW(else);
-PIKEKW(float);
-PIKEKW(for);
-PIKEKW(foreach);
-PIKEKW(function);
-PIKEKW(gauge);
-PIKEKW(if);
-PIKEKW(inherit);
-PIKEKW(inline);
-PIKEKW(int);
-PIKEKW(lambda);
-PIKEKW(mapping);
-PIKEKW(mixed);
-PIKEKW(multiset);
-PIKEKW(nomask);
-PIKEKW(object);
-PIKEKW(predef);
-PIKEKW(private);
-PIKEKW(program);
-PIKEKW(protected);
-PIKEKW(public);
-PIKEKW(return);
-PIKEKW(sscanf);
-PIKEKW(static);
-PIKEKW(string);
-PIKEKW(switch);
-PIKEKW(typeof);
-PIKEKW(varargs);
-PIKEKW(void);
-PIKEKW(while);
-
-
-#undef PIKEKW
-
-#endif //PIKE_PIKEKW_SWG_
diff --git a/Lib/pike/pikerun.swg b/Lib/pike/pikerun.swg
deleted file mode 100644
index 6ec1143..0000000
--- a/Lib/pike/pikerun.swg
+++ /dev/null
@@ -1,71 +0,0 @@
-/* -----------------------------------------------------------------------------
- * pikerun.swg
- *
- * This file contains the runtime support for Pike modules
- * and includes code for managing global variables and pointer
- * type checking.
- * ----------------------------------------------------------------------------- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#include "pike/object.h"
-#include "pike/program.h"
-#ifdef __cplusplus
-}
-#endif
-#include <assert.h>
-
-/* Stores information about a wrapped object */
-typedef struct swig_object_wrapper {
-    void *self;
-    swig_type_info *type;
-} swig_object_wrapper;
-
-#ifdef THIS
-#undef THIS
-#endif
-#define THIS (((swig_object_wrapper *) Pike_fp->current_storage)->self)
-
-#define SWIG_ConvertPtr SWIG_Pike_ConvertPtr
-#define SWIG_NewPointerObj SWIG_Pike_NewPointerObj
-#define SWIG_GetModule(clientdata) SWIG_Pike_GetModule(clientdata)
-#define SWIG_SetModule(clientdata, pointer) SWIG_Pike_SetModule(pointer)
-
-/* These need to be filled in before type sharing between modules will work */
-static swig_module_info *SWIG_Pike_GetModule(void *SWIGUNUSEDPARM(clientdata)) {
-  return 0;
-}
-
-static void SWIG_Pike_SetModule(swig_module_info *pointer) {
-
-}
-
-/* Convert a pointer value */
-static int
-SWIG_Pike_ConvertPtr(struct object *obj, void **ptr, swig_type_info *ty, int flags) {
-    struct program *pr;
-    swig_cast_info *tc;
-    swig_object_wrapper *obj_wrapper;
-    
-    if (ty) {
-        pr = (struct program *) ty->clientdata;
-        obj_wrapper = (swig_object_wrapper *) get_storage(obj, pr);
-        if (obj_wrapper && obj_wrapper->type) {
-            tc = SWIG_TypeCheckStruct(obj_wrapper->type, ty);
-            if (tc) {
-                int newmemory = 0;
-                *ptr = SWIG_TypeCast(tc, obj_wrapper->self, &newmemory);
-                assert(!newmemory); /* newmemory handling not yet implemented */
-                return 0;
-            }
-        }
-    }
-    return -1;
-}
-
-/* Create a new pointer object */
-static struct object *
-SWIG_Pike_NewPointerObj(void *ptr, swig_type_info *type, int own) {
-    return 0;
-}
diff --git a/Lib/pike/std_string.i b/Lib/pike/std_string.i
deleted file mode 100644
index b32b3c1..0000000
--- a/Lib/pike/std_string.i
+++ /dev/null
@@ -1,60 +0,0 @@
-/* -----------------------------------------------------------------------------
- * std_string.i
- *
- * SWIG typemaps for std::string
- * ----------------------------------------------------------------------------- */
-
-%{
-#include <string>
-%}
-
-namespace std {
-
-    %naturalvar string;
-
-    class string;
-
-    /* Overloading check */
-
-    %typemap(typecheck) string = char *;
-    %typemap(typecheck) const string & = char *;
-
-    %typemap(in, pikedesc="tStr") string {
-      if ($input.type != T_STRING)
-        Pike_error("Bad argument: Expected a string.\n");
-      $1.assign(STR0($input.u.string));
-    }
-
-    %typemap(in, pikedesc="tStr") const string & ($*1_ltype temp) {
-      if ($input.type != T_STRING)
-        Pike_error("Bad argument: Expected a string.\n");
-      temp.assign(STR0($input.u.string));
-      $1 = &temp;
-    }
-
-    %typemap(out, pikedesc="tStr") string "push_text($1.c_str());";
-
-    %typemap(out, pikedesc="tStr") const string & "push_text($1->c_str());";
-    
-    %typemap(directorin) string, const string &, string & "$1.c_str()";
-
-    %typemap(directorin) string *, const string * "$1->c_str()";
-    
-    %typemap(directorout) string {
-      if ($input.type == T_STRING)
-        $result.assign(STR0($input.u.string));
-      else
-        throw Swig::DirectorTypeMismatchException("string expected");
-    }
-    
-    %typemap(directorout) const string & ($*1_ltype temp) {
-      if ($input.type == T_STRING) {
-        temp.assign(STR0($input.u.string));
-        $result = &temp;
-      } else {
-        throw Swig::DirectorTypeMismatchException("string expected");
-      }
-    }
-
-}
-
diff --git a/Lib/pointer.i b/Lib/pointer.i
deleted file mode 100644
index ea8e535..0000000
--- a/Lib/pointer.i
+++ /dev/null
@@ -1,11 +0,0 @@
-/* -----------------------------------------------------------------------------
- * pointer.i
- * ----------------------------------------------------------------------------- */
-
-
-%echo "pointer.i is deprecated.  Use cpointer.i instead."
-%echo "See http://www.swig.org/Doc3.0/Library.html"
-
-
-
-
diff --git a/Lib/python/README b/Lib/python/README
index fa8ef61..70968e7 100644
--- a/Lib/python/README
+++ b/Lib/python/README
@@ -101,4 +101,3 @@
 
 std_vectora.i		vector + allocator (allocators are now supported in STD/STL)
 typemaps.i		old in/out typemaps (doesn't need to be included)
-defarg.swg		for processing default arguments with shadow classes
diff --git a/Lib/python/argcargv.i b/Lib/python/argcargv.i
index 717fe73..af71840 100644
--- a/Lib/python/argcargv.i
+++ b/Lib/python/argcargv.i
@@ -1,13 +1,10 @@
-/* ------------------------------------------------------------
- * --- Argc & Argv ---
- * ------------------------------------------------------------ */
+/* -------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------- */
 
 %fragment("SWIG_AsArgcArgv","header",fragment="SWIG_AsCharPtrAndSize") {
 SWIGINTERN int
-SWIG_AsArgcArgv(PyObject *input,
-		swig_type_info *ppchar_info,
-		size_t *argc, char ***argv, int *owner)
-{  
+SWIG_AsArgcArgv(PyObject *input, swig_type_info *ppchar_info, size_t *argc, char ***argv, int *owner) {
   void *vptr;
   int res = SWIG_ConvertPtr(input, &vptr, ppchar_info, 0);
   if (!SWIG_IsOK(res)) {
@@ -51,7 +48,7 @@
   } else {
     /* seems dangerous, but the user asked for it... */
     size_t i = 0;
-    if (argv) { while (*argv[i] != 0) ++i;}    
+    if (argv) { while (*argv[i] != 0) ++i;}
     if (argc) *argc = i;
     if (owner) *owner = 0;
     return SWIG_OK;
@@ -66,10 +63,10 @@
 
 %typemap(in,noblock=0,fragment="SWIG_AsArgcArgv") (int ARGC, char **ARGV) (int res,char **argv = 0, size_t argc = 0, int owner= 0) {
   res = SWIG_AsArgcArgv($input, $descriptor(char**), &argc, &argv, &owner);
-  if (!SWIG_IsOK(res)) { 
+  if (!SWIG_IsOK(res)) {
     $1 = 0; $2 = 0;
     %argument_fail(SWIG_TypeError, "int ARGC, char **ARGV", $symname, $argnum);
-  } else {  
+  } else {
     $1 = %static_cast(argc,$1_ltype);
     $2 = %static_cast(argv, $2_ltype);
   }
diff --git a/Lib/python/boost_shared_ptr.i b/Lib/python/boost_shared_ptr.i
index 709e781..bfd8787 100644
--- a/Lib/python/boost_shared_ptr.i
+++ b/Lib/python/boost_shared_ptr.i
@@ -39,7 +39,7 @@
   }
 }
 %typemap(out) CONST TYPE {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
@@ -58,12 +58,12 @@
   }
 }
 %typemap(varout) CONST TYPE {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
 %typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
-  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(SWIG_STD_MOVE($1)));
   $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
 %}
 %typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
diff --git a/Lib/python/builtin.swg b/Lib/python/builtin.swg
index 28051e6..6c2c311 100644
--- a/Lib/python/builtin.swg
+++ b/Lib/python/builtin.swg
@@ -6,7 +6,11 @@
 SwigPyObject_hash(PyObject *obj) {
   SwigPyObject *sobj = (SwigPyObject *)obj;
   void *ptr = sobj->ptr;
+#if PY_VERSION_HEX < 0x03020000
+  return (Py_hash_t)(Py_ssize_t)ptr;
+#else
   return (Py_hash_t)ptr;
+#endif
 }
 
 SWIGINTERN Py_hash_t
@@ -211,7 +215,11 @@
       sizeof(PyGetSetDescrObject),              /* tp_basicsize */
       0,                                        /* tp_itemsize */
       (destructor)SwigPyStaticVar_dealloc,      /* tp_dealloc */
-      0,                                        /* tp_print */
+#if PY_VERSION_HEX < 0x030800b4
+      (printfunc)0,                             /* tp_print */
+#else
+      (Py_ssize_t)0,                            /* tp_vectorcall_offset */
+#endif
       0,                                        /* tp_getattr */
       0,                                        /* tp_setattr */
       0,                                        /* tp_compare */
@@ -256,6 +264,15 @@
 #if PY_VERSION_HEX >= 0x03040000
       0,                                        /* tp_finalize */
 #endif
+#if PY_VERSION_HEX >= 0x03080000
+      0,                                        /* tp_vectorcall */
+#endif
+#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)
+      0,                                        /* tp_print */
+#endif
+#if PY_VERSION_HEX >= 0x030c0000
+      0,                                        /* tp_watched */
+#endif
 #ifdef COUNT_ALLOCS
       0,                                        /* tp_allocs */
       0,                                        /* tp_frees */
@@ -289,7 +306,11 @@
       PyType_Type.tp_basicsize,                 /* tp_basicsize */
       0,                                        /* tp_itemsize */
       0,                                        /* tp_dealloc */
-      0,                                        /* tp_print */
+#if PY_VERSION_HEX < 0x030800b4
+      (printfunc)0,                             /* tp_print */
+#else
+      (Py_ssize_t)0,                            /* tp_vectorcall_offset */
+#endif
       0,                                        /* tp_getattr */
       0,                                        /* tp_setattr */
       0,                                        /* tp_compare */
@@ -334,6 +355,15 @@
 #if PY_VERSION_HEX >= 0x03040000
       0,                                        /* tp_finalize */
 #endif
+#if PY_VERSION_HEX >= 0x03080000
+      0,                                        /* tp_vectorcall */
+#endif
+#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)
+      0,                                        /* tp_print */
+#endif
+#if PY_VERSION_HEX >= 0x030c0000
+      0,                                        /* tp_watched */
+#endif
 #ifdef COUNT_ALLOCS
       0,                                        /* tp_allocs */
       0,                                        /* tp_frees */
@@ -402,10 +432,10 @@
 SWIGINTERN void
 SwigPyBuiltin_SetMetaType (PyTypeObject *type, PyTypeObject *metatype)
 {
-#if PY_VERSION_HEX >= 0x03000000
-    type->ob_base.ob_base.ob_type = metatype;
+#if PY_VERSION_HEX >= 0x030900a4
+    Py_SET_TYPE(type, metatype);
 #else
-    type->ob_type = metatype;
+    Py_TYPE(type) = metatype;
 #endif
 }
 
@@ -510,8 +540,10 @@
   assert(tuple);
   Py_INCREF(b);
   PyTuple_SET_ITEM(tuple, 0, b);
-  Py_INCREF(c);
-  PyTuple_SET_ITEM(tuple, 1, c);
+  if (c) {
+    Py_INCREF(c);
+    PyTuple_SET_ITEM(tuple, 1, c);
+  }
   result = wrapper(a, tuple);
   Py_DECREF(tuple);
   return result;
@@ -626,8 +658,10 @@
   tuple = PyTuple_New(2);
   assert(tuple);
   PyTuple_SET_ITEM(tuple, 0, _PyLong_FromSsize_t(b));
-  Py_INCREF(c);
-  PyTuple_SET_ITEM(tuple, 1, c);
+  if (c) {
+    Py_INCREF(c);
+    PyTuple_SET_ITEM(tuple, 1, c);
+  }
   resultobj = wrapper(a, tuple);
   result = resultobj ? 0 : -1;
   Py_XDECREF(resultobj);
diff --git a/Lib/python/carrays.i b/Lib/python/carrays.i
index 74b2be9..a7b6120 100644
--- a/Lib/python/carrays.i
+++ b/Lib/python/carrays.i
@@ -7,7 +7,3 @@
 %enddef
 
 %include <typemaps/carrays.swg>
-
-
-
-
diff --git a/Lib/python/ccomplex.i b/Lib/python/ccomplex.i
index 28872b9..b99f96a 100644
--- a/Lib/python/ccomplex.i
+++ b/Lib/python/ccomplex.i
@@ -12,15 +12,16 @@
 #include <complex.h>
 %}
 
+#define complex _Complex
 
 /* C complex constructor */
 #define CCplxConst(r, i) ((r) + I*(i))
 
-%swig_cplxflt_convn(float complex, CCplxConst, creal, cimag);
-%swig_cplxdbl_convn(double complex, CCplxConst, creal, cimag);
-%swig_cplxdbl_convn(complex, CCplxConst, creal, cimag);
+%swig_cplxflt_convn(float _Complex, CCplxConst, creal, cimag);
+%swig_cplxdbl_convn(double _Complex, CCplxConst, creal, cimag);
+%swig_cplxdbl_convn(_Complex, CCplxConst, creal, cimag);
 
 /* declaring the typemaps */
-%typemaps_primitive(SWIG_TYPECHECK_CPLXFLT, float complex);
-%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, double complex);
-%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, complex);
+%typemaps_primitive(SWIG_TYPECHECK_CPLXFLT, float _Complex);
+%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, double _Complex);
+%typemaps_primitive(SWIG_TYPECHECK_CPLXDBL, _Complex);
diff --git a/Lib/python/defarg.swg b/Lib/python/defarg.swg
deleted file mode 100644
index 59450bd..0000000
--- a/Lib/python/defarg.swg
+++ /dev/null
@@ -1,37 +0,0 @@
-/* This file defines an internal function for processing default arguments
-   with proxy classes.
-
-   There seems to be no straightforward way to write proxy functions
-   involving default arguments. For example :
-
-             def foo(arg1,arg2,*args):
-                     proxyc.foo(arg1,arg2,args)
-
-   This fails because args is now a tuple and SWIG doesn't know what to
-   do with it.
-
-   This file allows a different approach :
-
-            def foo(arg1,arg2,*args):
-                    proxyc.__call_defarg(proxyc.foo,(arg1,arg2,)+args)
-
-   Basically, we form a new tuple from the object, call this special
-   __call_defarg method and it passes control to the real wrapper function.
-   An ugly hack, but it works.
-*/
-
-SWIGINTERN PyObject *swig_call_defargs(PyObject *self, PyObject *args) {
-  PyObject *func;
-  PyObject *parms;
-  
-  if (!PyArg_ParseTuple(args, "OO", &func, &parms))
-    return NULL;
-  
-  if (!PyCallable_Check(func)) {
-    SWIG_PYTHON_THREAD_BEGIN_BLOCK;
-    PyErr_SetString(PyExc_TypeError, "__call_defarg : Need a callable object!");
-    SWIG_PYTHON_THREAD_END_BLOCK;
-    return NULL;
-  }
-  return PyEval_CallObject(func,parms);
-}
diff --git a/Lib/python/director.swg b/Lib/python/director.swg
index 9694c62..a1dd00f 100644
--- a/Lib/python/director.swg
+++ b/Lib/python/director.swg
@@ -14,6 +14,24 @@
 #include <vector>
 #include <map>
 
+#if defined(SWIG_PYTHON_THREADS)
+/*  __THREAD__ is the old macro to activate some thread support */
+# if !defined(__THREAD__)
+#   define __THREAD__ 1
+# endif
+#endif
+
+#ifdef __THREAD__
+#ifndef Py_LIMITED_API
+# include "pythread.h"
+#else
+# if defined(_WIN32)
+#   include <windows.h>
+# else
+#   include <pthread.h>
+# endif
+#endif
+#endif
 
 /*
   Use -DSWIG_PYTHON_DIRECTOR_NO_VTABLE if you don't want to generate a 'virtual
@@ -173,7 +191,7 @@
         swig_msg += msg;
       }
       if (!PyErr_Occurred()) {
-        PyErr_SetString(error, what());
+        PyErr_SetString(error, swig_msg.c_str());
       }
       SWIG_PYTHON_THREAD_END_BLOCK;
     }
@@ -244,25 +262,89 @@
   };
 
 
-#if defined(SWIG_PYTHON_THREADS)
-/*  __THREAD__ is the old macro to activate some thread support */
-# if !defined(__THREAD__)
-#   define __THREAD__ 1
-# endif
-#endif
-
 #ifdef __THREAD__
-# include "pythread.h"
+#ifndef Py_LIMITED_API
+   class Mutex
+   {
+   public:
+       Mutex() {
+           mutex_ = PyThread_allocate_lock();
+       }
+
+       ~Mutex() {
+           PyThread_release_lock(mutex_);
+       }
+
+   private:
+       void Lock() {
+           PyThread_acquire_lock(mutex_, WAIT_LOCK);
+       }
+
+       void Unlock() {
+           PyThread_free_lock(mutex_);
+       }
+
+       PyThread_type_lock mutex_;
+
+       friend class Guard;
+   };
+#elif defined(_WIN32)
+    class Mutex : private CRITICAL_SECTION {
+    public:
+        Mutex() {
+            InitializeCriticalSection(this);
+        }
+
+        ~Mutex() {
+            DeleteCriticalSection(this);
+        }
+
+    private:
+        void Lock() {
+            EnterCriticalSection(this);
+        }
+
+        void Unlock() {
+            LeaveCriticalSection(this);
+        }
+
+        friend class Guard;
+    };
+#else
+    class Mutex {
+    public:
+        Mutex() {
+            pthread_mutex_init(&mutex_, NULL);
+        }
+
+        ~Mutex() {
+            pthread_mutex_destroy(&mutex_);
+        }
+
+    private:
+        void Lock() {
+            pthread_mutex_lock(&mutex_);
+        }
+
+        void Unlock() {
+            pthread_mutex_unlock(&mutex_);
+        }
+
+        friend class Guard;
+
+        pthread_mutex_t mutex_;
+    };
+#endif
   class Guard {
-    PyThread_type_lock &mutex_;
+    Mutex &mutex_;
 
   public:
-    Guard(PyThread_type_lock & mutex) : mutex_(mutex) {
-      PyThread_acquire_lock(mutex_, WAIT_LOCK);
+    Guard(Mutex & mutex) : mutex_(mutex) {
+      mutex_.Lock();
     }
 
     ~Guard() {
-      PyThread_release_lock(mutex_);
+      mutex_.Unlock();
     }
   };
 # define SWIG_GUARD(mutex) Guard _guard(mutex)
@@ -330,7 +412,7 @@
     typedef std::map<void *, GCItem_var> swig_ownership_map;
     mutable swig_ownership_map swig_owner;
 #ifdef __THREAD__
-    static PyThread_type_lock swig_mutex_own;
+    static Mutex swig_mutex_own;
 #endif
 
   public:
@@ -382,7 +464,7 @@
   };
 
 #ifdef __THREAD__
-  PyThread_type_lock Director::swig_mutex_own = PyThread_allocate_lock();
+  Mutex Director::swig_mutex_own;
 #endif
 }
 
diff --git a/Lib/python/embed.i b/Lib/python/embed.i
index efd0487..e5ee601 100644
--- a/Lib/python/embed.i
+++ b/Lib/python/embed.i
@@ -2,36 +2,43 @@
 // embed.i
 // SWIG file embedding the Python interpreter in something else.
 // This file is deprecated and no longer actively maintained, but it still
-// seems to work with Python 2.7.  Status with Python 3 is unknown.
+// seems to work with Python 2.7.  It doesn't work with Python 3.
 //
 // This file makes it possible to extend Python and all of its
 // built-in functions without having to hack its setup script.
 //
-
-
-#ifdef AUTODOC
-%subsection "embed.i"
-%text %{
-This module provides support for building a new version of the
-Python executable.  This will be necessary on systems that do
-not support shared libraries and may be necessary with C++
-extensions.  This file contains everything you need to build
-a new version of Python from include files and libraries normally
-installed with the Python language.
-
-This module will automatically grab all of the Python modules
-present in your current Python executable (including any special
-purpose modules you have enabled such as Tkinter).   Thus, you
-may need to provide additional link libraries when compiling.
-
-As far as I know, this module is C++ safe.
-%}
-#endif
+// This module provides support for building a new version of the
+// Python executable.  This will be necessary on systems that do
+// not support shared libraries and may be necessary with C++
+// extensions.  This file contains everything you need to build
+// a new version of Python from include files and libraries normally
+// installed with the Python language.
+//
+// This module will automatically grab all of the Python modules
+// present in your current Python executable (including any special
+// purpose modules you have enabled such as Tkinter).   Thus, you
+// may need to provide additional link libraries when compiling.
+//
+// As far as I know, this module is C++ safe.
 
 %wrapper %{
+#if !defined(PY_SSIZE_T_CLEAN) && !defined(SWIG_NO_PY_SSIZE_T_CLEAN)
+#define PY_SSIZE_T_CLEAN
+#endif
+
+#if __GNUC__ >= 7
+#pragma GCC diagnostic push
+#if defined(__cplusplus) && __cplusplus >=201703L
+#pragma GCC diagnostic ignored "-Wregister" /* For python-2.7 headers that use register */
+#endif
+#endif
 
 #include <Python.h>
 
+#if __GNUC__ >= 7
+#pragma GCC diagnostic pop
+#endif
+
 #ifdef __cplusplus
 extern "C"
 #endif
diff --git a/Lib/python/pyabc.i b/Lib/python/pyabc.i
index fbd91dc..cae1e70 100644
--- a/Lib/python/pyabc.i
+++ b/Lib/python/pyabc.i
@@ -1,10 +1,14 @@
 %define %pythonabc(Type, Abc)
-  %feature("python:abc", #Abc) Type;
+  %feature("python:abc", Abc) Type;
 %enddef
-%pythoncode %{import collections.abc%}
-%pythonabc(std::vector, collections.abc.MutableSequence);
-%pythonabc(std::list, collections.abc.MutableSequence);
-%pythonabc(std::map, collections.abc.MutableMapping);
-%pythonabc(std::multimap, collections.abc.MutableMapping);
-%pythonabc(std::set, collections.abc.MutableSet);
-%pythonabc(std::multiset, collections.abc.MutableSet);
+%pythoncode %{if _swig_python_version_info[0:2] >= (3, 3):
+    import collections.abc
+else:
+    import collections
+%}
+%pythonabc(std::vector, "collections.abc.MutableSequence if _swig_python_version_info >= (3, 3) else collections.MutableSequence");
+%pythonabc(std::list, "collections.abc.MutableSequence if _swig_python_version_info >= (3, 3) else collections.MutableSequence");
+%pythonabc(std::map, "collections.abc.MutableMapping if _swig_python_version_info >= (3, 3) else collections.MutableMapping");
+%pythonabc(std::multimap, "collections.abc.MutableMapping if _swig_python_version_info >= (3, 3) else collections.MutableMapping");
+%pythonabc(std::set, "collections.abc.MutableSet if _swig_python_version_info >= (3, 3) else collections.MutableSet");
+%pythonabc(std::multiset, "collections.abc.MutableSet if _swig_python_version_info >= (3, 3) else collections.MutableSet");
diff --git a/Lib/python/pybuffer.i b/Lib/python/pybuffer.i
index 577eb69..9ebc36a 100644
--- a/Lib/python/pybuffer.i
+++ b/Lib/python/pybuffer.i
@@ -12,18 +12,43 @@
  *      }
  */
 
+/* Note that in Py_LIMITED_API case we have no choice, but to use deprecated
+ * functions, as they provides the only way to access buffer data with limited
+ * API, which doesn't include Py_buffer definition. We also disable the
+ * warnings about doing this because they're not useful in our case.
+ */
+
 %define %pybuffer_mutable_binary(TYPEMAP, SIZE)
 %typemap(in) (TYPEMAP, SIZE) {
   int res; Py_ssize_t size = 0; void *buf = 0;
+%#ifndef Py_LIMITED_API
   Py_buffer view;
   res = PyObject_GetBuffer($input, &view, PyBUF_WRITABLE);
-  size = view.len;
-  buf = view.buf;
-  PyBuffer_Release(&view);
+%#else
+  %#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+    %#pragma GCC diagnostic push
+    %#pragma GCC diagnostic ignored "-Wdeprecated"
+    %#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+  %#elif defined(_MSC_VER)
+    %#pragma warning(push)
+    %#pragma warning(disable: 4996)
+  %#endif
+  res = PyObject_AsWriteBuffer($input, &buf, &size);
+  %#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+    %#pragma GCC diagnostic pop
+  %#elif defined(_MSC_VER)
+    %#pragma warning(pop)
+  %#endif
+%#endif
   if (res < 0) {
     PyErr_Clear();
     %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
   }
+%#ifndef Py_LIMITED_API
+  size = view.len;
+  buf = view.buf;
+  PyBuffer_Release(&view);
+%#endif
   $1 = ($1_ltype) buf;
   $2 = ($2_ltype) (size/sizeof($*1_type));
 }
@@ -45,14 +70,34 @@
 %define %pybuffer_mutable_string(TYPEMAP)
 %typemap(in) (TYPEMAP) {
   int res; void *buf = 0;
+%#ifndef Py_LIMITED_API
   Py_buffer view;
   res = PyObject_GetBuffer($input, &view, PyBUF_WRITABLE);
-  buf = view.buf;
-  PyBuffer_Release(&view);
+%#else
+  %#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+    %#pragma GCC diagnostic push
+    %#pragma GCC diagnostic ignored "-Wdeprecated"
+    %#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+  %#elif defined(_MSC_VER)
+    %#pragma warning(push)
+    %#pragma warning(disable: 4996)
+  %#endif
+  Py_ssize_t size;
+  res = PyObject_AsWriteBuffer($input, &buf, &size);
+  %#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+    %#pragma GCC diagnostic pop
+  %#elif defined(_MSC_VER)
+    %#pragma warning(pop)
+  %#endif
+%#endif
   if (res < 0) {
     PyErr_Clear();
     %argument_fail(res, "(TYPEMAP)", $symname, $argnum);
   }
+%#ifndef Py_LIMITED_API
+  buf = view.buf;
+  PyBuffer_Release(&view);
+%#endif
   $1 = ($1_ltype) buf;
 }
 %enddef
@@ -74,15 +119,34 @@
 %define %pybuffer_binary(TYPEMAP, SIZE)
 %typemap(in) (TYPEMAP, SIZE) {
   int res; Py_ssize_t size = 0; const void *buf = 0;
+%#ifndef Py_LIMITED_API
   Py_buffer view;
   res = PyObject_GetBuffer($input, &view, PyBUF_CONTIG_RO);
-  size = view.len;
-  buf = view.buf;
-  PyBuffer_Release(&view);
+%#else
+  %#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+    %#pragma GCC diagnostic push
+    %#pragma GCC diagnostic ignored "-Wdeprecated"
+    %#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+  %#elif defined(_MSC_VER)
+    %#pragma warning(push)
+    %#pragma warning(disable: 4996)
+  %#endif
+  res = PyObject_AsReadBuffer($input, &buf, &size);
+  %#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+    %#pragma GCC diagnostic pop
+  %#elif defined(_MSC_VER)
+    %#pragma warning(pop)
+  %#endif
+%#endif
   if (res < 0) {
     PyErr_Clear();
     %argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
   }
+%#ifndef Py_LIMITED_API
+  size = view.len;
+  buf = view.buf;
+  PyBuffer_Release(&view);
+%#endif
   $1 = ($1_ltype) buf;
   $2 = ($2_ltype) (size / sizeof($*1_type));
 }
@@ -106,16 +170,34 @@
 %define %pybuffer_string(TYPEMAP)
 %typemap(in) (TYPEMAP) {
   int res; const void *buf = 0;
+%#ifndef Py_LIMITED_API
   Py_buffer view;
   res = PyObject_GetBuffer($input, &view, PyBUF_CONTIG_RO);
-  buf = view.buf;
-  PyBuffer_Release(&view);
+%#else
+  %#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+    %#pragma GCC diagnostic push
+    %#pragma GCC diagnostic ignored "-Wdeprecated"
+    %#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+  %#elif defined(_MSC_VER)
+    %#pragma warning(push)
+    %#pragma warning(disable: 4996)
+  %#endif
+  Py_ssize_t size;
+  res = PyObject_AsReadBuffer($input, &buf, &size);
+  %#if defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
+    %#pragma GCC diagnostic pop
+  %#elif defined(_MSC_VER)
+    %#pragma warning(pop)
+  %#endif
+%#endif
   if (res < 0) {
+    PyErr_Clear();
     %argument_fail(res, "(TYPEMAP)", $symname, $argnum);
   }
+%#ifndef Py_LIMITED_API
+  buf = view.buf;
+  PyBuffer_Release(&view);
+%#endif
   $1 = ($1_ltype) buf;
 }
 %enddef
-
-
-
diff --git a/Lib/python/pyclasses.swg b/Lib/python/pyclasses.swg
index 9d6299f..39c4e03 100644
--- a/Lib/python/pyclasses.swg
+++ b/Lib/python/pyclasses.swg
@@ -11,7 +11,7 @@
   or as a member variable:
   
      struct A {
-       SwigPtr_PyObject obj;
+       SwigPtr_PyObject _obj;
        A(PyObject *o) : _obj(o) {
        }
      };
@@ -43,7 +43,7 @@
   %apply PyObject * {SwigPtr_PyObject};
   %apply PyObject * const& {SwigPtr_PyObject const&};
 
-  %typemap(typecheck,precedence=SWIG_TYPECHECK_SWIGOBJECT,noblock=1) SwigPtr_PyObject const& "$1 = ($input != 0);";
+  %typemap(typecheck,precedence=SWIG_TYPECHECK_SWIGOBJECT,noblock=1) SwigPtr_PyObject const& "$1 = ($input != 0);"
 
 
   /* For output */
diff --git a/Lib/python/pycomplex.swg b/Lib/python/pycomplex.swg
index 087c50f..28c9636 100644
--- a/Lib/python/pycomplex.swg
+++ b/Lib/python/pycomplex.swg
@@ -65,7 +65,7 @@
     float re;
     int res = SWIG_AddCast(SWIG_AsVal(float)(o, &re));
     if (SWIG_IsOK(res)) {
-      if (val) *val = Constructor(re, 0.0);
+      if (val) *val = Constructor(re, 0.0f);
       return res;
     }
   }
diff --git a/Lib/python/pycontainer.swg b/Lib/python/pycontainer.swg
index fef4e9b..6916c61 100644
--- a/Lib/python/pycontainer.swg
+++ b/Lib/python/pycontainer.swg
@@ -15,9 +15,9 @@
 #include <iostream>
 
 #if PY_VERSION_HEX >= 0x03020000
-# define SWIGPY_SLICE_ARG(obj) ((PyObject*) (obj))
+# define SWIGPY_SLICEOBJECT PyObject
 #else
-# define SWIGPY_SLICE_ARG(obj) ((PySliceObject*) (obj))
+# define SWIGPY_SLICEOBJECT PySliceObject
 #endif
 %}
 
@@ -52,7 +52,7 @@
   struct container_owner {
     // By default, do not add the back-reference (for value types)
     // Specialization below will check the reference for pointer types.
-    static bool back_reference(PyObject* child, PyObject* owner) {
+    static bool back_reference(PyObject* /*child*/, PyObject* /*owner*/) {
       return false;
     }
   };
@@ -69,8 +69,7 @@
     static bool back_reference(PyObject* child, PyObject* owner) {
       SwigPyObject* swigThis = SWIG_Python_GetSwigThis(child);
       if (swigThis && (swigThis->own & SWIG_POINTER_OWN) != SWIG_POINTER_OWN) {
-        PyObject_SetAttr(child, container_owner_attribute(), owner);
-        return true;
+        return PyObject_SetAttr(child, container_owner_attribute(), owner) != -1;
       }
       return false;
     }
@@ -387,7 +386,7 @@
         size_t replacecount = (jj - ii + step - 1) / step;
         if (is.size() != replacecount) {
           char msg[1024];
-          sprintf(msg, "attempt to assign sequence of size %lu to extended slice of size %lu", (unsigned long)is.size(), (unsigned long)replacecount);
+          PyOS_snprintf(msg, sizeof(msg), "attempt to assign sequence of size %lu to extended slice of size %lu", (unsigned long)is.size(), (unsigned long)replacecount);
           throw std::invalid_argument(msg);
         }
         typename Sequence::const_iterator isit = is.begin();
@@ -403,7 +402,7 @@
       size_t replacecount = (ii - jj - step - 1) / -step;
       if (is.size() != replacecount) {
         char msg[1024];
-        sprintf(msg, "attempt to assign sequence of size %lu to extended slice of size %lu", (unsigned long)is.size(), (unsigned long)replacecount);
+        PyOS_snprintf(msg, sizeof(msg), "attempt to assign sequence of size %lu to extended slice of size %lu", (unsigned long)is.size(), (unsigned long)replacecount);
         throw std::invalid_argument(msg);
       }
       typename Sequence::const_iterator isit = is.begin();
@@ -457,239 +456,6 @@
 }
 }
 
-%fragment("SwigPySequence_Cont","header",
-	  fragment="StdTraits",
-	  fragment="SwigPySequence_Base",
-	  fragment="SwigPyIterator_T")
-{
-namespace swig
-{
-  template <class T>
-  struct SwigPySequence_Ref
-  {
-    SwigPySequence_Ref(PyObject* seq, Py_ssize_t index)
-      : _seq(seq), _index(index)
-    {
-    }
-    
-    operator T () const
-    {
-      swig::SwigVar_PyObject item = PySequence_GetItem(_seq, _index);
-      try {
-	return swig::as<T>(item);
-      } catch (const std::invalid_argument& e) {
-	char msg[1024];
-	sprintf(msg, "in sequence element %d ", (int)_index);
-	if (!PyErr_Occurred()) {
-	  ::%type_error(swig::type_name<T>());
-	}
-	SWIG_Python_AddErrorMsg(msg);
-	SWIG_Python_AddErrorMsg(e.what());
-	throw;
-      }
-    }
-
-    SwigPySequence_Ref& operator=(const T& v)
-    {
-      PySequence_SetItem(_seq, _index, swig::from<T>(v));
-      return *this;
-    }
-
-  private:
-    PyObject* _seq;
-    Py_ssize_t _index;
-  };
-
-  template <class T>
-  struct SwigPySequence_ArrowProxy
-  {
-    SwigPySequence_ArrowProxy(const T& x): m_value(x) {}
-    const T* operator->() const { return &m_value; }
-    operator const T*() const { return &m_value; }
-    T m_value;
-  };
-
-  template <class T, class Reference >
-  struct SwigPySequence_InputIterator
-  {
-    typedef SwigPySequence_InputIterator<T, Reference > self;
-
-    typedef std::random_access_iterator_tag iterator_category;
-    typedef Reference reference;
-    typedef T value_type;
-    typedef T* pointer;
-    typedef Py_ssize_t difference_type;
-
-    SwigPySequence_InputIterator()
-    {
-    }
-
-    SwigPySequence_InputIterator(PyObject* seq, Py_ssize_t index)
-      : _seq(seq), _index(index)
-    {
-    }
-
-    reference operator*() const
-    {
-      return reference(_seq, _index);
-    }
-
-    SwigPySequence_ArrowProxy<T>
-    operator->() const {
-      return SwigPySequence_ArrowProxy<T>(operator*());
-    }
-
-    bool operator==(const self& ri) const
-    {
-      return (_index == ri._index) && (_seq == ri._seq);
-    }
-
-    bool operator!=(const self& ri) const
-    {
-      return !(operator==(ri));
-    }
-
-    self& operator ++ ()
-    {
-      ++_index;
-      return *this;
-    }
-
-    self& operator -- ()
-    {
-      --_index;
-      return *this;
-    }
-
-    self& operator += (difference_type n)
-    {
-      _index += n;
-      return *this;
-    }
-
-    self operator +(difference_type n) const
-    {
-      return self(_seq, _index + n);
-    }
-
-    self& operator -= (difference_type n)
-    {
-      _index -= n;
-      return *this;
-    }
-
-    self operator -(difference_type n) const
-    {
-      return self(_seq, _index - n);
-    }
-
-    difference_type operator - (const self& ri) const
-    {
-      return _index - ri._index;
-    }
-
-    bool operator < (const self& ri) const
-    {
-      return _index < ri._index;
-    }
-
-    reference
-    operator[](difference_type n) const
-    {
-      return reference(_seq, _index + n);
-    }
-
-  private:
-    PyObject* _seq;
-    difference_type _index;
-  };
-
-  // STL container wrapper around a Python sequence
-  template <class T>
-  struct SwigPySequence_Cont
-  {
-    typedef SwigPySequence_Ref<T> reference;
-    typedef const SwigPySequence_Ref<T> const_reference;
-    typedef T value_type;
-    typedef T* pointer;
-    typedef Py_ssize_t difference_type;
-    typedef size_t size_type;
-    typedef const pointer const_pointer;
-    typedef SwigPySequence_InputIterator<T, reference> iterator;
-    typedef SwigPySequence_InputIterator<T, const_reference> const_iterator;
-
-    SwigPySequence_Cont(PyObject* seq) : _seq(0)
-    {
-      if (!PySequence_Check(seq)) {
-	throw std::invalid_argument("a sequence is expected");
-      }
-      _seq = seq;
-      Py_INCREF(_seq);
-    }
-
-    ~SwigPySequence_Cont()
-    {
-      Py_XDECREF(_seq);
-    }
-
-    size_type size() const
-    {
-      return static_cast<size_type>(PySequence_Size(_seq));
-    }
-
-    bool empty() const
-    {
-      return size() == 0;
-    }
-
-    iterator begin()
-    {
-      return iterator(_seq, 0);
-    }
-
-    const_iterator begin() const
-    {
-      return const_iterator(_seq, 0);
-    }
-
-    iterator end()
-    {
-      return iterator(_seq, size());
-    }
-
-    const_iterator end() const
-    {
-      return const_iterator(_seq, size());
-    }
-
-    reference operator[](difference_type n)
-    {
-      return reference(_seq, n);
-    }
-
-    const_reference operator[](difference_type n)  const
-    {
-      return const_reference(_seq, n);
-    }
-
-    bool check() const
-    {
-      Py_ssize_t s = size();
-      for (Py_ssize_t i = 0; i < s; ++i) {
-	swig::SwigVar_PyObject item = PySequence_GetItem(_seq, i);
-	if (!swig::check<value_type>(item))
-	  return false;
-      }
-      return true;
-    }
-
-  private:
-    PyObject* _seq;
-  };
-
-}
-}
-
 %define %swig_sequence_iterator(Sequence...)
   %swig_sequence_iterator_with_making_function(swig::make_output_iterator,Sequence...)
 %enddef
@@ -705,12 +471,12 @@
   class const_iterator;
   class const_reverse_iterator;
 
-  %typemap(out,noblock=1,fragment="SwigPySequence_Cont")
+  %typemap(out,noblock=1,fragment="SwigPyIterator_T")
     iterator, reverse_iterator, const_iterator, const_reverse_iterator {
     $result = SWIG_NewPointerObj(Make_output_iterator(%static_cast($1,const $type &)),
 				 swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
   }
-  %typemap(out,noblock=1,fragment="SwigPySequence_Cont")
+  %typemap(out,noblock=1,fragment="SwigPyIterator_T")
     std::pair<iterator, iterator>, std::pair<const_iterator, const_iterator> {
     $result = PyTuple_New(2);
     PyTuple_SetItem($result,0,SWIG_NewPointerObj(Make_output_iterator(%static_cast($1,const $type &).first),
@@ -719,7 +485,7 @@
 						 swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN));    
   }
 
-  %fragment("SwigPyPairBoolOutputIterator","header",fragment=SWIG_From_frag(bool),fragment="SwigPySequence_Cont") {}
+  %fragment("SwigPyPairBoolOutputIterator","header",fragment=SWIG_From_frag(bool),fragment="SwigPyIterator_T") {}
 
   %typemap(out,noblock=1,fragment="SwigPyPairBoolOutputIterator")
     std::pair<iterator, bool>, std::pair<const_iterator, bool> {
@@ -729,7 +495,7 @@
     PyTuple_SetItem($result,1,SWIG_From(bool)(%static_cast($1,const $type &).second));
   }
 
-  %typemap(in,noblock=1,fragment="SwigPySequence_Cont")
+  %typemap(in,noblock=1,fragment="SwigPyIterator_T")
     iterator(swig::SwigPyIterator *iter = 0, int res),
     reverse_iterator(swig::SwigPyIterator *iter = 0, int res),
     const_iterator(swig::SwigPyIterator *iter = 0, int res),
@@ -747,14 +513,14 @@
     }
   }
 
-  %typecheck(%checkcode(ITERATOR),noblock=1,fragment="SwigPySequence_Cont")
+  %typecheck(%checkcode(ITERATOR),noblock=1,fragment="SwigPyIterator_T")
     iterator, reverse_iterator, const_iterator, const_reverse_iterator {
     swig::SwigPyIterator *iter = 0;
     int res = SWIG_ConvertPtr($input, %as_voidptrptr(&iter), swig::SwigPyIterator::descriptor(), 0);
     $1 = (SWIG_IsOK(res) && iter && (dynamic_cast<swig::SwigPyIterator_T<$type > *>(iter) != 0));
   }
 
-  %fragment("SwigPySequence_Cont");
+  %fragment("SwigPyIterator_T");
 
   %newobject iterator(PyObject **PYTHON_SELF);
   %extend  {
@@ -782,7 +548,7 @@
 #if 1
   %newobject __getslice__;
 #endif
-  %newobject __getitem__(PySliceObject *slice);
+  %newobject __getitem__(SWIGPY_SLICEOBJECT *slice);
 
 #if defined(SWIGPYTHON_BUILTIN)
   %feature("python:slot", "nb_nonzero", functype="inquiry") __nonzero__;
@@ -830,13 +596,13 @@
 
   %extend {
     /* typemap for slice object support */
-    %typemap(in) PySliceObject* {
+    %typemap(in) SWIGPY_SLICEOBJECT* {
       if (!PySlice_Check($input)) {
         %argument_fail(SWIG_TypeError, "$type", $symname, $argnum);
       }
-      $1 = (PySliceObject *) $input;
+      $1 = (SWIGPY_SLICEOBJECT *) $input;
     }
-    %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER) PySliceObject* {
+    %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER) SWIGPY_SLICEOBJECT* {
       $1 = PySlice_Check($input);
     }
 
@@ -866,49 +632,49 @@
     /* Overloaded methods for Python 3 compatibility 
      * (Also useful in Python 2.x)
      */
-    Sequence* __getitem__(PySliceObject *slice) throw (std::out_of_range, std::invalid_argument) {
+    Sequence* __getitem__(SWIGPY_SLICEOBJECT *slice) throw (std::out_of_range, std::invalid_argument) {
       Py_ssize_t i, j, step;
       if( !PySlice_Check(slice) ) {
         SWIG_Error(SWIG_TypeError, "Slice object expected.");
         return NULL;
       }
-      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step);
       Sequence::difference_type id = i;
       Sequence::difference_type jd = j;
       return swig::getslice(self, id, jd, step);
     }
 
-    void __setitem__(PySliceObject *slice, const Sequence& v) throw (std::out_of_range, std::invalid_argument) {
+    void __setitem__(SWIGPY_SLICEOBJECT *slice, const Sequence& v) throw (std::out_of_range, std::invalid_argument) {
       Py_ssize_t i, j, step;
       if( !PySlice_Check(slice) ) {
         SWIG_Error(SWIG_TypeError, "Slice object expected.");
         return;
       }
-      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step);
       Sequence::difference_type id = i;
       Sequence::difference_type jd = j;
       swig::setslice(self, id, jd, step, v);
     }
 
-    void __setitem__(PySliceObject *slice) throw (std::out_of_range, std::invalid_argument) {
+    void __setitem__(SWIGPY_SLICEOBJECT *slice) throw (std::out_of_range, std::invalid_argument) {
       Py_ssize_t i, j, step;
       if( !PySlice_Check(slice) ) {
         SWIG_Error(SWIG_TypeError, "Slice object expected.");
         return;
       }
-      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step);
       Sequence::difference_type id = i;
       Sequence::difference_type jd = j;
       swig::delslice(self, id, jd, step);
     }
 
-    void __delitem__(PySliceObject *slice) throw (std::out_of_range, std::invalid_argument) {
+    void __delitem__(SWIGPY_SLICEOBJECT *slice) throw (std::out_of_range, std::invalid_argument) {
       Py_ssize_t i, j, step;
       if( !PySlice_Check(slice) ) {
         SWIG_Error(SWIG_TypeError, "Slice object expected.");
         return;
       }
-      PySlice_GetIndices(SWIGPY_SLICE_ARG(slice), (Py_ssize_t)self->size(), &i, &j, &step);
+      PySlice_GetIndices(slice, (Py_ssize_t)self->size(), &i, &j, &step);
       Sequence::difference_type id = i;
       Sequence::difference_type jd = j;
       swig::delslice(self, id, jd, step);
@@ -1000,26 +766,50 @@
 
 %fragment("StdSequenceTraits","header",
 	  fragment="StdTraits",
-	  fragment="SwigPySequence_Cont")
+	  fragment="SwigPySequence_Base")
 {
 namespace swig {
-  template <class SwigPySeq, class Seq>
-  inline void
-  assign(const SwigPySeq& swigpyseq, Seq* seq) {
-    // seq->assign(swigpyseq.begin(), swigpyseq.end()); // not used as not always implemented
-    typedef typename SwigPySeq::value_type value_type;
-    typename SwigPySeq::const_iterator it = swigpyseq.begin();
-    for (;it != swigpyseq.end(); ++it) {
-      seq->insert(seq->end(),(value_type)(*it));
+  template <class Seq, class T = typename Seq::value_type >
+  struct IteratorProtocol {
+    static void assign(PyObject *obj, Seq *seq) {
+      SwigVar_PyObject iter = PyObject_GetIter(obj);
+      if (iter) {
+        SwigVar_PyObject item = PyIter_Next(iter);
+        while (item) {
+          seq->insert(seq->end(), swig::as<T>(item));
+          item = PyIter_Next(iter);
+        }
+      }
     }
-  }
+
+    static bool check(PyObject *obj) {
+      bool ret = false;
+      SwigVar_PyObject iter = PyObject_GetIter(obj);
+      if (iter) {
+        SwigVar_PyObject item = PyIter_Next(iter);
+        ret = true;
+        while (item) {
+          ret = swig::check<T>(item);
+          item = ret ? PyIter_Next(iter) : 0;
+        }
+      }
+      return ret;
+    }
+  };
 
   template <class Seq, class T = typename Seq::value_type >
   struct traits_asptr_stdseq {
     typedef Seq sequence;
     typedef T value_type;
 
+    static bool is_iterable(PyObject *obj) {
+      SwigVar_PyObject iter = PyObject_GetIter(obj);
+      PyErr_Clear();
+      return iter != 0;
+    }
+
     static int asptr(PyObject *obj, sequence **seq) {
+      int ret = SWIG_ERROR;
       if (obj == Py_None || SWIG_Python_GetSwigThis(obj)) {
 	sequence *p;
 	swig_type_info *descriptor = swig::type_info<sequence>();
@@ -1027,27 +817,25 @@
 	  if (seq) *seq = p;
 	  return SWIG_OLDOBJ;
 	}
-      } else if (PySequence_Check(obj)) {
+      } else if (is_iterable(obj)) {
 	try {
-	  SwigPySequence_Cont<value_type> swigpyseq(obj);
 	  if (seq) {
-	    sequence *pseq = new sequence();
-	    assign(swigpyseq, pseq);
-	    *seq = pseq;
-	    return SWIG_NEWOBJ;
+	    *seq = new sequence();
+            IteratorProtocol<Seq, T>::assign(obj, *seq);
+            if (!PyErr_Occurred())
+              return SWIG_NEWOBJ;
 	  } else {
-	    return swigpyseq.check() ? SWIG_OK : SWIG_ERROR;
+	    return IteratorProtocol<Seq, T>::check(obj) ? SWIG_OK : SWIG_ERROR;
 	  }
 	} catch (std::exception& e) {
-	  if (seq) {
-	    if (!PyErr_Occurred()) {
-	      PyErr_SetString(PyExc_TypeError, e.what());
-	    }
-	  }
-	  return SWIG_ERROR;
+          if (seq && !PyErr_Occurred())
+            PyErr_SetString(PyExc_TypeError, e.what());
 	}
+        if (seq)
+          delete *seq;
+	return SWIG_ERROR;
       }
-      return SWIG_ERROR;
+      return ret;
     }
   };
 
diff --git a/Lib/python/pydocs.swg b/Lib/python/pydocs.swg
index 1eea41b..5a25423 100644
--- a/Lib/python/pydocs.swg
+++ b/Lib/python/pydocs.swg
@@ -2,43 +2,43 @@
 // Documentation for use with the autodoc feature.
 
 #ifdef SWIG_DOC_DOXYGEN_STYLE
-%typemap(doc) SWIGTYPE "@param $1_name $1_type";
-%typemap(doc) SWIGTYPE * "@param $1_name $1_type";
-%typemap(doc) const SWIGTYPE & "@param $1_name $1_type";
-%typemap(doc) const SWIGTYPE && "@param $1_name $1_type";
-%typemap(doc) enum SWIGTYPE "@param $1_name enum $1_type";
+%typemap(doc) SWIGTYPE "@param $1_name $1_type"
+%typemap(doc) SWIGTYPE * "@param $1_name $1_type"
+%typemap(doc) const SWIGTYPE & "@param $1_name $1_type"
+%typemap(doc) const SWIGTYPE && "@param $1_name $1_type"
+%typemap(doc) enum SWIGTYPE "@param $1_name enum $1_type"
 
-%typemap(doc) SWIGTYPE *INOUT, SWIGTYPE &INOUT "@param $1_name $1_type (input/output)";
-%typemap(doc) SWIGTYPE *INPUT, SWIGTYPE &INPUT "@param $1_name $1_type (input)";
-%typemap(doc) SWIGTYPE *OUTPUT, SWIGTYPE &OUTPUT "@param $1_name $1_type (output)";
+%typemap(doc) SWIGTYPE *INOUT, SWIGTYPE &INOUT "@param $1_name $1_type (input/output)"
+%typemap(doc) SWIGTYPE *INPUT, SWIGTYPE &INPUT "@param $1_name $1_type (input)"
+%typemap(doc) SWIGTYPE *OUTPUT, SWIGTYPE &OUTPUT "@param $1_name $1_type (output)"
 #else
-%typemap(doc) SWIGTYPE "$1_name: $1_type";
-%typemap(doc) SWIGTYPE * "$1_name: $1_type";
-%typemap(doc) const SWIGTYPE & "$1_name: $1_type";
-%typemap(doc) const SWIGTYPE && "$1_name: $1_type";
-%typemap(doc) enum SWIGTYPE "$1_name: enum $1_type";
+%typemap(doc) SWIGTYPE "$1_name: $1_type"
+%typemap(doc) SWIGTYPE * "$1_name: $1_type"
+%typemap(doc) const SWIGTYPE & "$1_name: $1_type"
+%typemap(doc) const SWIGTYPE && "$1_name: $1_type"
+%typemap(doc) enum SWIGTYPE "$1_name: enum $1_type"
 
-%typemap(doc) SWIGTYPE *INOUT, SWIGTYPE &INOUT "$1_name: $1_type (input/output)";
-%typemap(doc) SWIGTYPE *INPUT, SWIGTYPE &INPUT "$1_name: $1_type (input)";
-%typemap(doc) SWIGTYPE *OUTPUT, SWIGTYPE &OUTPUT "$1_name: $1_type (output)";
+%typemap(doc) SWIGTYPE *INOUT, SWIGTYPE &INOUT "$1_name: $1_type (input/output)"
+%typemap(doc) SWIGTYPE *INPUT, SWIGTYPE &INPUT "$1_name: $1_type (input)"
+%typemap(doc) SWIGTYPE *OUTPUT, SWIGTYPE &OUTPUT "$1_name: $1_type (output)"
 #endif
 
 
 // Types to use in Python documentation for the parameters of the given C++ type.
-%typemap(doctype) bool "boolean";
+%typemap(doctype) bool "boolean"
 
 %define int_doctype_for_cppint_type(cppint_type)
-    %typemap(doctype) cppint_type, unsigned cppint_type "int";
+    %typemap(doctype) cppint_type, unsigned cppint_type "int"
 %enddef
 %formacro(int_doctype_for_cppint_type, short, int, long, long long)
 
-%typemap(doctype) size_t "int";
+%typemap(doctype) size_t "int"
 
-%typemap(doctype) enum SWIGTYPE "int";
+%typemap(doctype) enum SWIGTYPE "int"
 
-%typemap(doctype) float, double, long double "float";
+%typemap(doctype) float, double, long double "float"
 
-%typemap(doctype) char*, std::string "string";
+%typemap(doctype) char*, std::string "string"
 
 %typemap(doctype) SWIGTYPE "$1_basetype"
 %typemap(doctype) SWIGTYPE * "$typemap(doctype, $*1_ltype)"
diff --git a/Lib/python/pyerrors.swg b/Lib/python/pyerrors.swg
index dcd99c9..dfa55e0 100644
--- a/Lib/python/pyerrors.swg
+++ b/Lib/python/pyerrors.swg
@@ -57,14 +57,15 @@
     PyErr_Fetch(&type, &value, &traceback);
   if (value) {
     PyObject *old_str = PyObject_Str(value);
-    const char *tmp = SWIG_Python_str_AsChar(old_str);
+    PyObject *bytes = NULL;
+    const char *tmp = SWIG_PyUnicode_AsUTF8AndSize(old_str, NULL, &bytes);
     PyErr_Clear();
     Py_XINCREF(type);
     if (tmp)
       PyErr_Format(type, "%s %s", tmp, mesg);
     else
       PyErr_Format(type, "%s", mesg);
-    SWIG_Python_str_DelForPy3(tmp);
+    Py_XDECREF(bytes);
     Py_DECREF(old_str);
     Py_DECREF(value);
   } else {
@@ -95,8 +96,12 @@
 #else
     newvalue = PyString_FromFormat("%s\nAdditional information:\n%s", PyString_AsString(value), message);
 #endif
-    Py_XDECREF(value);
-    PyErr_Restore(type, newvalue, traceback);
+    if (newvalue) {
+      Py_XDECREF(value);
+      PyErr_Restore(type, newvalue, traceback);
+    } else {
+      PyErr_Restore(type, value, traceback);
+    }
   } else {
     /* Raise TypeError using given message */
     PyErr_SetString(PyExc_TypeError, message);
diff --git a/Lib/python/pyhead.swg b/Lib/python/pyhead.swg
index c820f90..46891d9 100644
--- a/Lib/python/pyhead.swg
+++ b/Lib/python/pyhead.swg
@@ -13,7 +13,6 @@
 #define PyString_Size(str) PyBytes_Size(str)	
 #define PyString_InternFromString(key) PyUnicode_InternFromString(key)
 #define Py_TPFLAGS_HAVE_CLASS Py_TPFLAGS_BASETYPE
-#define PyString_AS_STRING(x) PyUnicode_AS_STRING(x)
 #define _PyLong_FromSsize_t(x) PyLong_FromSsize_t(x)
 
 #endif
@@ -31,36 +30,29 @@
 #endif
 
 
-/* Warning: This function will allocate a new string in Python 3,
- * so please call SWIG_Python_str_DelForPy3(x) to free the space.
- */
-SWIGINTERN char*
-SWIG_Python_str_AsChar(PyObject *str)
+/* Wrapper around PyUnicode_AsUTF8AndSize - call Py_XDECREF on the returned pbytes when finished with the returned string */
+SWIGINTERN const char *
+SWIG_PyUnicode_AsUTF8AndSize(PyObject *str, Py_ssize_t *psize, PyObject **pbytes)
 {
-#if PY_VERSION_HEX >= 0x03000000
-  char *newstr = 0;
-  str = PyUnicode_AsUTF8String(str);
-  if (str) {
-    char *cstr;
-    Py_ssize_t len;
-    PyBytes_AsStringAndSize(str, &cstr, &len);
-    newstr = (char *) malloc(len+1);
-    memcpy(newstr, cstr, len+1);
-    Py_XDECREF(str);
-  }
-  return newstr;
+#if PY_VERSION_HEX >= 0x03030000
+# if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030A0000
+  *pbytes = NULL;
+  return PyUnicode_AsUTF8AndSize(str, psize);
+# else
+   *pbytes = PyUnicode_AsUTF8String(str);
+   const char *chars = *pbytes ? PyBytes_AsString(*pbytes) : NULL;
+   if (chars && psize)
+     *psize = PyBytes_Size(*pbytes);
+  return chars;
+# endif
 #else
-  return PyString_AsString(str);
+  char *chars = NULL;
+  *pbytes = NULL;
+  PyString_AsStringAndSize(str, &chars, psize);
+  return chars;
 #endif
 }
 
-#if PY_VERSION_HEX >= 0x03000000
-#  define SWIG_Python_str_DelForPy3(x) free( (void*) (x) )
-#else
-#  define SWIG_Python_str_DelForPy3(x) 
-#endif
-
-
 SWIGINTERN PyObject*
 SWIG_Python_str_FromChar(const char *c)
 {
@@ -75,13 +67,31 @@
 # define PyObject_DEL PyObject_Del
 #endif
 
-// SWIGPY_USE_CAPSULE is no longer used within SWIG itself, but some user
-// interface files check for it.
+/* SWIGPY_USE_CAPSULE is no longer used within SWIG itself, but some user interface files check for it. */
 # define SWIGPY_USE_CAPSULE
-# define SWIGPY_CAPSULE_NAME ("swig_runtime_data" SWIG_RUNTIME_VERSION ".type_pointer_capsule" SWIG_TYPE_TABLE_NAME)
+#ifdef SWIGPYTHON_BUILTIN
+# define SWIGPY_CAPSULE_ATTR_NAME "type_pointer_capsule_builtin" SWIG_TYPE_TABLE_NAME
+#else
+# define SWIGPY_CAPSULE_ATTR_NAME "type_pointer_capsule" SWIG_TYPE_TABLE_NAME
+#endif
+# define SWIGPY_CAPSULE_NAME ("swig_runtime_data" SWIG_RUNTIME_VERSION "." SWIGPY_CAPSULE_ATTR_NAME)
 
 #if PY_VERSION_HEX < 0x03020000
 #define PyDescr_TYPE(x) (((PyDescrObject *)(x))->d_type)
 #define PyDescr_NAME(x) (((PyDescrObject *)(x))->d_name)
 #define Py_hash_t long
 #endif
+
+#ifdef Py_LIMITED_API
+# define PyTuple_GET_ITEM PyTuple_GetItem
+/* Note that PyTuple_SetItem() has different semantics from PyTuple_SET_ITEM as it decref's the original tuple item, so in general they cannot be used
+  interchangeably. However in SWIG-generated code PyTuple_SET_ITEM is only used with newly initialized tuples without any items and for them this does work. */
+# define PyTuple_SET_ITEM PyTuple_SetItem
+# define PyTuple_GET_SIZE PyTuple_Size
+# define PyCFunction_GET_FLAGS PyCFunction_GetFlags
+# define PyCFunction_GET_FUNCTION PyCFunction_GetFunction
+# define PyCFunction_GET_SELF PyCFunction_GetSelf
+# define PyList_GET_ITEM PyList_GetItem
+# define PyList_SET_ITEM PyList_SetItem
+# define PySliceObject PyObject
+#endif
diff --git a/Lib/python/pyinit.swg b/Lib/python/pyinit.swg
index dfbf40b..6833b45 100644
--- a/Lib/python/pyinit.swg
+++ b/Lib/python/pyinit.swg
@@ -8,6 +8,8 @@
 %fragment("<stddef.h>"); // For offsetof
 #endif
 
+#if defined SWIGPYTHON_FASTPROXY && !defined SWIGPYTHON_BUILTIN
+
 %insert(runtime) %{
 #ifdef __cplusplus
 extern "C" {
@@ -24,220 +26,14 @@
 #endif
 %}
 
+#endif
+
 %init %{
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/* Python-specific SWIG API */
-#define SWIG_newvarlink()                             SWIG_Python_newvarlink()
-#define SWIG_addvarlink(p, name, get_attr, set_attr)  SWIG_Python_addvarlink(p, name, get_attr, set_attr)
-#define SWIG_InstallConstants(d, constants)           SWIG_Python_InstallConstants(d, constants)
- 
-/* -----------------------------------------------------------------------------
- * global variable support code.
- * ----------------------------------------------------------------------------- */
- 
-typedef struct swig_globalvar {   
-  char       *name;                  /* Name of global variable */
-  PyObject *(*get_attr)(void);       /* Return the current value */
-  int       (*set_attr)(PyObject *); /* Set the value */
-  struct swig_globalvar *next;
-} swig_globalvar;
-
-typedef struct swig_varlinkobject {
-  PyObject_HEAD
-  swig_globalvar *vars;
-} swig_varlinkobject;
-
-SWIGINTERN PyObject *
-swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) {
-#if PY_VERSION_HEX >= 0x03000000
-  return PyUnicode_InternFromString("<Swig global variables>");
-#else
-  return PyString_FromString("<Swig global variables>");
-#endif
-}
-
-SWIGINTERN PyObject *
-swig_varlink_str(swig_varlinkobject *v) {
-#if PY_VERSION_HEX >= 0x03000000
-  PyObject *str = PyUnicode_InternFromString("(");
-  PyObject *tail;
-  PyObject *joined;
-  swig_globalvar *var;
-  for (var = v->vars; var; var=var->next) {
-    tail = PyUnicode_FromString(var->name);
-    joined = PyUnicode_Concat(str, tail);
-    Py_DecRef(str);
-    Py_DecRef(tail);
-    str = joined;
-    if (var->next) {
-        tail = PyUnicode_InternFromString(", ");
-        joined = PyUnicode_Concat(str, tail);
-        Py_DecRef(str);
-        Py_DecRef(tail);
-        str = joined;
-    }
-  }
-  tail = PyUnicode_InternFromString(")");
-  joined = PyUnicode_Concat(str, tail);
-  Py_DecRef(str);
-  Py_DecRef(tail);
-  str = joined;
-#else
-  PyObject *str = PyString_FromString("(");
-  swig_globalvar *var;
-  for (var = v->vars; var; var=var->next) {
-    PyString_ConcatAndDel(&str,PyString_FromString(var->name));
-    if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", "));
-  }
-  PyString_ConcatAndDel(&str,PyString_FromString(")"));
-#endif
-  return str;
-}
-
-SWIGINTERN void
-swig_varlink_dealloc(swig_varlinkobject *v) {
-  swig_globalvar *var = v->vars;
-  while (var) {
-    swig_globalvar *n = var->next;
-    free(var->name);
-    free(var);
-    var = n;
-  }
-}
-
-SWIGINTERN PyObject *
-swig_varlink_getattr(swig_varlinkobject *v, char *n) {
-  PyObject *res = NULL;
-  swig_globalvar *var = v->vars;
-  while (var) {
-    if (strcmp(var->name,n) == 0) {
-      res = (*var->get_attr)();
-      break;
-    }
-    var = var->next;
-  }
-  if (res == NULL && !PyErr_Occurred()) {
-    PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n);
-  }
-  return res;
-}
-
-SWIGINTERN int
-swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) {
-  int res = 1;
-  swig_globalvar *var = v->vars;
-  while (var) {
-    if (strcmp(var->name,n) == 0) {
-      res = (*var->set_attr)(p);
-      break;
-    }
-    var = var->next;
-  }
-  if (res == 1 && !PyErr_Occurred()) {
-    PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n);
-  }
-  return res;
-}
-
-SWIGINTERN PyTypeObject*
-swig_varlink_type(void) {
-  static char varlink__doc__[] = "Swig var link object";
-  static PyTypeObject varlink_type;
-  static int type_init = 0;
-  if (!type_init) {
-    const PyTypeObject tmp = {
-#if PY_VERSION_HEX >= 0x03000000
-      PyVarObject_HEAD_INIT(NULL, 0)
-#else
-      PyObject_HEAD_INIT(NULL)
-      0,                                  /* ob_size */
-#endif
-      "swigvarlink",                      /* tp_name */
-      sizeof(swig_varlinkobject),         /* tp_basicsize */
-      0,                                  /* tp_itemsize */
-      (destructor) swig_varlink_dealloc,  /* tp_dealloc */
-      0,                                  /* tp_print */
-      (getattrfunc) swig_varlink_getattr, /* tp_getattr */
-      (setattrfunc) swig_varlink_setattr, /* tp_setattr */
-      0,                                  /* tp_compare */
-      (reprfunc) swig_varlink_repr,       /* tp_repr */
-      0,                                  /* tp_as_number */
-      0,                                  /* tp_as_sequence */
-      0,                                  /* tp_as_mapping */
-      0,                                  /* tp_hash */
-      0,                                  /* tp_call */
-      (reprfunc) swig_varlink_str,        /* tp_str */
-      0,                                  /* tp_getattro */
-      0,                                  /* tp_setattro */
-      0,                                  /* tp_as_buffer */
-      0,                                  /* tp_flags */
-      varlink__doc__,                     /* tp_doc */
-      0,                                  /* tp_traverse */
-      0,                                  /* tp_clear */
-      0,                                  /* tp_richcompare */
-      0,                                  /* tp_weaklistoffset */
-      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */
-      0,                                  /* tp_del */
-      0,                                  /* tp_version_tag */
-#if PY_VERSION_HEX >= 0x03040000
-      0,                                  /* tp_finalize */
-#endif
-#ifdef COUNT_ALLOCS
-      0,                                  /* tp_allocs */
-      0,                                  /* tp_frees */
-      0,                                  /* tp_maxalloc */
-      0,                                  /* tp_prev */
-      0                                   /* tp_next */
-#endif
-    };
-    varlink_type = tmp;
-    type_init = 1;
-    if (PyType_Ready(&varlink_type) < 0)
-      return NULL;
-  }
-  return &varlink_type;
-}
-
-/* Create a variable linking object for use later */
-SWIGINTERN PyObject *
-SWIG_Python_newvarlink(void) {
-  swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type());
-  if (result) {
-    result->vars = 0;
-  }
-  return ((PyObject*) result);
-}
-
-SWIGINTERN void 
-SWIG_Python_addvarlink(PyObject *p, const char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) {
-  swig_varlinkobject *v = (swig_varlinkobject *) p;
-  swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar));
-  if (gv) {
-    size_t size = strlen(name)+1;
-    gv->name = (char *)malloc(size);
-    if (gv->name) {
-      memcpy(gv->name, name, size);
-      gv->get_attr = get_attr;
-      gv->set_attr = set_attr;
-      gv->next = v->vars;
-    }
-  }
-  v->vars = gv;
-}
-
-SWIGINTERN PyObject *
-SWIG_globals(void) {
-  static PyObject *globals = 0;
-  if (!globals) {
-    globals = SWIG_newvarlink();
-  }
-  return globals;
-}
-
 /* -----------------------------------------------------------------------------
  * constants/methods manipulation
  * ----------------------------------------------------------------------------- */
@@ -266,15 +62,12 @@
   }
 }
 
-/* -----------------------------------------------------------------------------*/
-/* Fix SwigMethods to carry the callback ptrs when needed */
-/* -----------------------------------------------------------------------------*/
+/* -----------------------------------------------------------------------------
+ * Patch %callback methods' docstrings to hold the callback ptrs
+ * -----------------------------------------------------------------------------*/
 
 SWIGINTERN void
-SWIG_Python_FixMethods(PyMethodDef *methods,
-		       swig_const_info *const_table,
-		       swig_type_info **types,
-		       swig_type_info **types_initial) {
+SWIG_Python_FixMethods(PyMethodDef *methods, const swig_const_info *const_table, swig_type_info **types, swig_type_info **types_initial) {
   size_t i;
   for (i = 0; methods[i].ml_name; ++i) {
     const char *c = methods[i].ml_doc;
@@ -282,7 +75,7 @@
     c = strstr(c, "swig_ptr: ");
     if (c) {
       int j;
-      swig_const_info *ci = 0;
+      const swig_const_info *ci = 0;
       const char *name = c + 10;
       for (j = 0; const_table[j].type; ++j) {
 	if (strncmp(const_table[j].name, name, 
@@ -314,6 +107,20 @@
   }
 } 
 
+#ifdef __cplusplus
+}
+#endif
+
+%}
+
+#if defined SWIGPYTHON_FASTPROXY && !defined SWIGPYTHON_BUILTIN
+
+%init %{
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* -----------------------------------------------------------------------------
  * Method creation and docstring support functions
  * ----------------------------------------------------------------------------- */
@@ -376,6 +183,12 @@
 }
 #endif
 
+%}
+
+#endif
+
+%init %{
+
 /* -----------------------------------------------------------------------------*
  *  Partial Init method
  * -----------------------------------------------------------------------------*/
diff --git a/Lib/python/pyname_compat.i b/Lib/python/pyname_compat.i
index a9630db..789b284 100644
--- a/Lib/python/pyname_compat.i
+++ b/Lib/python/pyname_compat.i
@@ -25,7 +25,6 @@
 */
 
 %fragment("PySequence_Base", "header", fragment="SwigPySequence_Base") {}
-%fragment("PySequence_Cont", "header", fragment="SwigPySequence_Cont") {}
 %fragment("PySwigIterator_T", "header", fragment="SwigPyIterator_T") {}
 %fragment("PyPairBoolOutputIterator", "header", fragment="SwigPyPairBoolOutputIterator") {}
 %fragment("PySwigIterator", "header", fragment="SwigPyIterator") {}
@@ -38,11 +37,6 @@
 #define PyObject_ptr SwigPtr_PyObject
 #define PyObject_var SwigVar_PyObject
 #define PyOper SwigPyOper
-#define PySeq SwigPySeq
-#define PySequence_ArrowProxy SwigPySequence_ArrowProxy
-#define PySequence_Cont SwigPySequence_Cont
-#define PySequence_InputIterator SwigPySequence_InputIterator
-#define PySequence_Ref SwigPySequence_Ref
 #define PySwigClientData SwigPyClientData
 #define PySwigClientData_Del SwigPyClientData_Del
 #define PySwigClientData_New SwigPyClientData_New
@@ -79,7 +73,6 @@
 #define PySwigPacked_repr SwigPyPacked_repr
 #define PySwigPacked_str SwigPyPacked_str
 #define PySwigPacked_type SwigPyPacked_type
-#define pyseq swigpyseq
 #define pyswigobject_type swigpyobject_type
 #define pyswigpacked_type swigpypacked_type
 %}
diff --git a/Lib/python/pyprimtypes.swg b/Lib/python/pyprimtypes.swg
index 6a01af1..7f37275 100644
--- a/Lib/python/pyprimtypes.swg
+++ b/Lib/python/pyprimtypes.swg
@@ -104,7 +104,12 @@
     if (!dispatch) {
       double d;
       int res = SWIG_AddCast(SWIG_AsVal(double)(obj,&d));
-      if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) {
+      // Largest double not larger than LONG_MAX (not portably calculated easily)
+      // Note that double(LONG_MAX) is stored in a double rounded up by one (for 64-bit long)
+      // 0x7ffffffffffffc00LL == (int64_t)std::nextafter(double(__uint128_t(LONG_MAX)+1), double(0))
+      const double long_max = sizeof(long) == 8 ? 0x7ffffffffffffc00LL : LONG_MAX;
+      // No equivalent needed for 64-bit double(LONG_MIN) is exactly LONG_MIN
+      if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, long_max)) {
 	if (val) *val = (long)(d);
 	return res;
       }
@@ -166,7 +171,11 @@
     if (!dispatch) {
       double d;
       int res = SWIG_AddCast(SWIG_AsVal(double)(obj,&d));
-      if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ULONG_MAX)) {
+      // Largest double not larger than ULONG_MAX (not portably calculated easily)
+      // Note that double(ULONG_MAX) is stored in a double rounded up by one (for 64-bit unsigned long)
+      // 0xfffffffffffff800ULL == (uint64_t)std::nextafter(double(__uint128_t(ULONG_MAX)+1), double(0))
+      const double ulong_max = sizeof(unsigned long) == 8 ? 0xfffffffffffff800ULL : ULONG_MAX;
+      if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, 0, ulong_max)) {
 	if (val) *val = (unsigned long)(d);
 	return res;
       }
diff --git a/Lib/python/pyrun.swg b/Lib/python/pyrun.swg
index 445a1e3..af60c2b 100644
--- a/Lib/python/pyrun.swg
+++ b/Lib/python/pyrun.swg
@@ -11,8 +11,8 @@
 # error "This version of SWIG only supports Python >= 2.7"
 #endif
 
-#if PY_VERSION_HEX >= 0x03000000 && PY_VERSION_HEX < 0x03020000
-# error "This version of SWIG only supports Python 3 >= 3.2"
+#if PY_VERSION_HEX >= 0x03000000 && PY_VERSION_HEX < 0x03030000
+# error "This version of SWIG only supports Python 3 >= 3.3"
 #endif
 
 /* Common SWIG API */
@@ -127,7 +127,12 @@
     if (!PyList_Check(result)) {
       PyObject *o2 = result;
       result = PyList_New(1);
-      PyList_SetItem(result, 0, o2);
+      if (result) {
+        PyList_SET_ITEM(result, 0, o2);
+      } else {
+        Py_DECREF(obj);
+        return o2;
+      }
     }
     PyList_Append(result,obj);
     Py_DECREF(obj);
@@ -183,6 +188,19 @@
   }
 }
 
+SWIGINTERN int
+SWIG_Python_CheckNoKeywords(PyObject *kwargs, const char *name) {
+  int no_kwargs = 1;
+  if (kwargs) {
+    assert(PyDict_Check(kwargs));
+    if (PyDict_Size(kwargs) > 0) {
+      PyErr_Format(PyExc_TypeError, "%s() does not take keyword arguments", name);
+      no_kwargs = 0;
+    }
+  }
+  return no_kwargs;
+}
+
 /* A functor is a function object with one single object argument */
 #define SWIG_Python_CallFunctor(functor, obj)	        PyObject_CallFunctionObjArgs(functor, obj, NULL);
 
@@ -196,6 +214,261 @@
 #define SWIG_STATIC_POINTER(var)  var = 0; if (!var) var
 #endif
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Python-specific SWIG API */
+#define SWIG_newvarlink()                             SWIG_Python_newvarlink()
+#define SWIG_addvarlink(p, name, get_attr, set_attr)  SWIG_Python_addvarlink(p, name, get_attr, set_attr)
+#define SWIG_InstallConstants(d, constants)           SWIG_Python_InstallConstants(d, constants)
+ 
+/* -----------------------------------------------------------------------------
+ * global variable support code.
+ * ----------------------------------------------------------------------------- */
+ 
+typedef struct swig_globalvar {   
+  char       *name;                  /* Name of global variable */
+  PyObject *(*get_attr)(void);       /* Return the current value */
+  int       (*set_attr)(PyObject *); /* Set the value */
+  struct swig_globalvar *next;
+} swig_globalvar;
+
+typedef struct swig_varlinkobject {
+  PyObject_HEAD
+  swig_globalvar *vars;
+} swig_varlinkobject;
+
+SWIGINTERN PyObject *
+swig_varlink_repr(PyObject *SWIGUNUSEDPARM(v)) {
+#if PY_VERSION_HEX >= 0x03000000
+  return PyUnicode_InternFromString("<Swig global variables>");
+#else
+  return PyString_FromString("<Swig global variables>");
+#endif
+}
+
+SWIGINTERN PyObject *
+swig_varlink_str(PyObject *o) {
+  swig_varlinkobject *v = (swig_varlinkobject *) o;
+#if PY_VERSION_HEX >= 0x03000000
+  PyObject *str = PyUnicode_InternFromString("(");
+  PyObject *tail;
+  PyObject *joined;
+  swig_globalvar *var;
+  for (var = v->vars; var; var=var->next) {
+    tail = PyUnicode_FromString(var->name);
+    joined = PyUnicode_Concat(str, tail);
+    Py_DecRef(str);
+    Py_DecRef(tail);
+    str = joined;
+    if (var->next) {
+        tail = PyUnicode_InternFromString(", ");
+        joined = PyUnicode_Concat(str, tail);
+        Py_DecRef(str);
+        Py_DecRef(tail);
+        str = joined;
+    }
+  }
+  tail = PyUnicode_InternFromString(")");
+  joined = PyUnicode_Concat(str, tail);
+  Py_DecRef(str);
+  Py_DecRef(tail);
+  str = joined;
+#else
+  PyObject *str = PyString_FromString("(");
+  swig_globalvar *var;
+  for (var = v->vars; var; var=var->next) {
+    PyString_ConcatAndDel(&str,PyString_FromString(var->name));
+    if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", "));
+  }
+  PyString_ConcatAndDel(&str,PyString_FromString(")"));
+#endif
+  return str;
+}
+
+SWIGINTERN void
+swig_varlink_dealloc(PyObject *o) {
+  swig_varlinkobject *v = (swig_varlinkobject *) o;
+  swig_globalvar *var = v->vars;
+  while (var) {
+    swig_globalvar *n = var->next;
+    free(var->name);
+    free(var);
+    var = n;
+  }
+}
+
+SWIGINTERN PyObject *
+swig_varlink_getattr(PyObject *o, char *n) {
+  swig_varlinkobject *v = (swig_varlinkobject *) o;
+  PyObject *res = NULL;
+  swig_globalvar *var = v->vars;
+  while (var) {
+    if (strcmp(var->name,n) == 0) {
+      res = (*var->get_attr)();
+      break;
+    }
+    var = var->next;
+  }
+  if (res == NULL && !PyErr_Occurred()) {
+    PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n);
+  }
+  return res;
+}
+
+SWIGINTERN int
+swig_varlink_setattr(PyObject *o, char *n, PyObject *p) {
+  swig_varlinkobject *v = (swig_varlinkobject *) o;
+  int res = 1;
+  swig_globalvar *var = v->vars;
+  while (var) {
+    if (strcmp(var->name,n) == 0) {
+      res = (*var->set_attr)(p);
+      break;
+    }
+    var = var->next;
+  }
+  if (res == 1 && !PyErr_Occurred()) {
+    PyErr_Format(PyExc_AttributeError, "Unknown C global variable '%s'", n);
+  }
+  return res;
+}
+
+SWIGINTERN PyTypeObject*
+swig_varlink_type(void) {
+  static char varlink__doc__[] = "Swig var link object";
+#ifndef Py_LIMITED_API
+  static PyTypeObject varlink_type;
+  static int type_init = 0;
+  if (!type_init) {
+    const PyTypeObject tmp = {
+#if PY_VERSION_HEX >= 0x03000000
+      PyVarObject_HEAD_INIT(NULL, 0)
+#else
+      PyObject_HEAD_INIT(NULL)
+      0,                                  /* ob_size */
+#endif
+      "swigvarlink",                      /* tp_name */
+      sizeof(swig_varlinkobject),         /* tp_basicsize */
+      0,                                  /* tp_itemsize */
+      (destructor) swig_varlink_dealloc,  /* tp_dealloc */
+#if PY_VERSION_HEX < 0x030800b4
+      (printfunc)0,                       /*tp_print*/
+#else
+      (Py_ssize_t)0,                      /*tp_vectorcall_offset*/
+#endif
+      (getattrfunc) swig_varlink_getattr, /* tp_getattr */
+      (setattrfunc) swig_varlink_setattr, /* tp_setattr */
+      0,                                  /* tp_compare */
+      (reprfunc) swig_varlink_repr,       /* tp_repr */
+      0,                                  /* tp_as_number */
+      0,                                  /* tp_as_sequence */
+      0,                                  /* tp_as_mapping */
+      0,                                  /* tp_hash */
+      0,                                  /* tp_call */
+      (reprfunc) swig_varlink_str,        /* tp_str */
+      0,                                  /* tp_getattro */
+      0,                                  /* tp_setattro */
+      0,                                  /* tp_as_buffer */
+      0,                                  /* tp_flags */
+      varlink__doc__,                     /* tp_doc */
+      0,                                  /* tp_traverse */
+      0,                                  /* tp_clear */
+      0,                                  /* tp_richcompare */
+      0,                                  /* tp_weaklistoffset */
+      0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */
+      0,                                  /* tp_del */
+      0,                                  /* tp_version_tag */
+#if PY_VERSION_HEX >= 0x03040000
+      0,                                  /* tp_finalize */
+#endif
+#if PY_VERSION_HEX >= 0x03080000
+      0,                                  /* tp_vectorcall */
+#endif
+#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)
+      0,                                  /* tp_print */
+#endif
+#if PY_VERSION_HEX >= 0x030C0000
+      0,                                  /* tp_watched */
+#endif
+#ifdef COUNT_ALLOCS
+      0,                                  /* tp_allocs */
+      0,                                  /* tp_frees */
+      0,                                  /* tp_maxalloc */
+      0,                                  /* tp_prev */
+      0                                   /* tp_next */
+#endif
+    };
+    varlink_type = tmp;
+    type_init = 1;
+    if (PyType_Ready(&varlink_type) < 0)
+      return NULL;
+  }
+  return &varlink_type;
+#else
+  PyType_Slot slots[] = {
+    { Py_tp_dealloc, (void *)swig_varlink_dealloc },
+    { Py_tp_repr, (void *)swig_varlink_repr },
+    { Py_tp_getattr, (void *)swig_varlink_getattr },
+    { Py_tp_setattr, (void *)swig_varlink_setattr },
+    { Py_tp_str, (void *)swig_varlink_str },
+    { Py_tp_doc, (void *)varlink__doc__ },
+    { 0, NULL }
+  };
+  PyType_Spec spec = {
+    "swigvarlink",
+    sizeof(swig_varlinkobject),
+    0,
+    Py_TPFLAGS_DEFAULT,
+    slots
+  };
+  return (PyTypeObject *)PyType_FromSpec(&spec);
+#endif
+}
+
+/* Create a variable linking object for use later */
+SWIGINTERN PyObject *
+SWIG_Python_newvarlink(void) {
+  swig_varlinkobject *result = PyObject_New(swig_varlinkobject, swig_varlink_type());
+  if (result) {
+    result->vars = 0;
+  }
+  return ((PyObject*) result);
+}
+
+SWIGINTERN void 
+SWIG_Python_addvarlink(PyObject *p, const char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) {
+  swig_varlinkobject *v = (swig_varlinkobject *) p;
+  swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar));
+  if (gv) {
+    size_t size = strlen(name)+1;
+    gv->name = (char *)malloc(size);
+    if (gv->name) {
+      memcpy(gv->name, name, size);
+      gv->get_attr = get_attr;
+      gv->set_attr = set_attr;
+      gv->next = v->vars;
+    }
+  }
+  v->vars = gv;
+}
+
+
+static PyObject *Swig_Globals_global = NULL;
+  
+SWIGINTERN PyObject *
+SWIG_globals(void) {
+  if (Swig_Globals_global == NULL) {
+    Swig_Globals_global = SWIG_newvarlink();
+  }
+  return Swig_Globals_global;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
 /* -----------------------------------------------------------------------------
  * Pointer declarations
  * ----------------------------------------------------------------------------- */
@@ -266,18 +539,25 @@
     /* the newraw method and newargs arguments used to create a new raw instance */
     if (PyClass_Check(obj)) {
       data->newraw = 0;
-      data->newargs = obj;
       Py_INCREF(obj);
+      data->newargs = obj;
     } else {
       data->newraw = PyObject_GetAttrString(data->klass, "__new__");
       if (data->newraw) {
-	Py_INCREF(data->newraw);
-	data->newargs = PyTuple_New(1);
-	PyTuple_SetItem(data->newargs, 0, obj);
+        data->newargs = PyTuple_New(1);
+        if (data->newargs) {
+          Py_INCREF(obj);
+          PyTuple_SET_ITEM(data->newargs, 0, obj);
+        } else {
+          Py_DECREF(data->newraw);
+          Py_DECREF(data->klass);
+          free(data);
+          return 0;
+        }
       } else {
-	data->newargs = obj;
+        Py_INCREF(obj);
+        data->newargs = obj;
       }
-      Py_INCREF(data->newargs);
     }
     /* the destroy method, aka as the C++ delete method */
     data->destroy = PyObject_GetAttrString(data->klass, "__swig_destroy__");
@@ -286,10 +566,7 @@
       data->destroy = 0;
     }
     if (data->destroy) {
-      int flags;
-      Py_INCREF(data->destroy);
-      flags = PyCFunction_GET_FLAGS(data->destroy);
-      data->delargs = !(flags & (METH_O));
+      data->delargs = !(PyCFunction_GET_FLAGS(data->destroy) & METH_O);
     } else {
       data->delargs = 0;
     }
@@ -300,10 +577,13 @@
 }
 
 SWIGRUNTIME void 
-SwigPyClientData_Del(SwigPyClientData *data) {
+SwigPyClientData_Del(SwigPyClientData *data)
+{
+  Py_XDECREF(data->klass);
   Py_XDECREF(data->newraw);
   Py_XDECREF(data->newargs);
   Py_XDECREF(data->destroy);
+  free(data);
 }
 
 /* =============== SwigPyObject =====================*/
@@ -330,7 +610,7 @@
   if (!sobj->dict)
     sobj->dict = PyDict_New();
 
-  Py_INCREF(sobj->dict);
+  Py_XINCREF(sobj->dict);
   return sobj->dict;
 }
 
@@ -348,18 +628,21 @@
   PyObject *res = NULL;
   PyObject *args = PyTuple_New(1);
   if (args) {
-    if (PyTuple_SetItem(args, 0, SwigPyObject_long(v)) == 0) {
-      PyObject *ofmt = SWIG_Python_str_FromChar(fmt);
+    PyObject *val = SwigPyObject_long(v);
+    if (val) {
+      PyObject *ofmt;
+      PyTuple_SET_ITEM(args, 0, val);
+      ofmt = SWIG_Python_str_FromChar(fmt);
       if (ofmt) {
 #if PY_VERSION_HEX >= 0x03000000
-	res = PyUnicode_Format(ofmt,args);
+        res = PyUnicode_Format(ofmt,args);
 #else
-	res = PyString_Format(ofmt,args);
+        res = PyString_Format(ofmt,args);
 #endif
-	Py_DECREF(ofmt);
+        Py_DECREF(ofmt);
       }
-      Py_DECREF(args);
     }
+    Py_DECREF(args);
   }
   return res;
 }
@@ -381,18 +664,23 @@
 {
   const char *name = SWIG_TypePrettyName(v->ty);
   PyObject *repr = SWIG_Python_str_FromFormat("<Swig Object of type '%s' at %p>", (name ? name : "unknown"), (void *)v);
-  if (v->next) {
+  if (repr && v->next) {
     PyObject *nrep = SwigPyObject_repr((SwigPyObject *)v->next);
+    if (nrep) {
 # if PY_VERSION_HEX >= 0x03000000
-    PyObject *joined = PyUnicode_Concat(repr, nrep);
-    Py_DecRef(repr);
-    Py_DecRef(nrep);
-    repr = joined;
+      PyObject *joined = PyUnicode_Concat(repr, nrep);
+      Py_DecRef(repr);
+      Py_DecRef(nrep);
+      repr = joined;
 # else
-    PyString_ConcatAndDel(&repr,nrep);
+      PyString_ConcatAndDel(&repr,nrep);
 # endif
+    } else {
+      Py_DecRef(repr);
+      repr = NULL;
+    }
   }
-  return repr;  
+  return repr;
 }
 
 /* We need a version taking two PyObject* parameters so it's a valid
@@ -415,12 +703,14 @@
 SWIGRUNTIME PyObject*
 SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op)
 {
-  PyObject* res;
-  if( op != Py_EQ && op != Py_NE ) {
-    Py_INCREF(Py_NotImplemented);
-    return Py_NotImplemented;
+  PyObject* res = NULL;
+  if (!PyErr_Occurred()) {
+    if (op != Py_EQ && op != Py_NE) {
+      Py_INCREF(Py_NotImplemented);
+      return Py_NotImplemented;
+    }
+    res = PyBool_FromLong( (SwigPyObject_compare(v, w)==0) == (op == Py_EQ) ? 1 : 0);
   }
-  res = PyBool_FromLong( (SwigPyObject_compare(v, w)==0) == (op == Py_EQ) ? 1 : 0);
   return res;  
 }
 
@@ -448,20 +738,34 @@
 
 SWIGRUNTIMEINLINE int
 SwigPyObject_Check(PyObject *op) {
-#ifdef SWIGPYTHON_BUILTIN
   PyTypeObject *target_tp = SwigPyObject_type();
-  if (PyType_IsSubtype(op->ob_type, target_tp))
+  PyTypeObject *op_type = Py_TYPE(op);
+#ifdef SWIGPYTHON_BUILTIN
+  if (PyType_IsSubtype(op_type, target_tp))
     return 1;
-  return (strcmp(op->ob_type->tp_name, "SwigPyObject") == 0);
+  return (strcmp(op_type->tp_name, "SwigPyObject") == 0);
 #else
-  return (Py_TYPE(op) == SwigPyObject_type())
-    || (strcmp(Py_TYPE(op)->tp_name,"SwigPyObject") == 0);
+  if (op_type == target_tp)
+    return 1;
+# ifdef Py_LIMITED_API
+  int cmp;
+  PyObject *tp_name = PyObject_GetAttrString((PyObject *)op_type, "__name__");
+  if (!tp_name)
+    return 0;
+  cmp = PyUnicode_CompareWithASCIIString(tp_name, "SwigPyObject");
+  Py_DECREF(tp_name);
+  return cmp == 0;
+# else
+  return (strcmp(op_type->tp_name, "SwigPyObject") == 0);
+# endif
 #endif
 }
 
 SWIGRUNTIME PyObject *
 SwigPyObject_New(void *ptr, swig_type_info *ty, int own);
 
+static PyObject* Swig_Capsule_global = NULL;
+
 SWIGRUNTIME void
 SwigPyObject_dealloc(PyObject *v)
 {
@@ -488,8 +792,12 @@
       if (data->delargs) {
         /* we need to create a temporary object to carry the destroy operation */
         PyObject *tmp = SwigPyObject_New(sobj->ptr, ty, 0);
-        res = SWIG_Python_CallFunctor(destroy, tmp);
-        Py_DECREF(tmp);
+        if (tmp) {
+          res = SWIG_Python_CallFunctor(destroy, tmp);
+        } else {
+          res = 0;
+        }
+        Py_XDECREF(tmp);
       } else {
         PyCFunction meth = PyCFunction_GET_FUNCTION(destroy);
         PyObject *mself = PyCFunction_GET_SELF(destroy);
@@ -508,8 +816,12 @@
       printf("swig/python detected a memory leak of type '%s', no destructor found.\n", (name ? name : "unknown"));
     }
 #endif
-  } 
+    Py_XDECREF(Swig_Capsule_global);
+  }
   Py_XDECREF(next);
+#ifdef SWIGPYTHON_BUILTIN
+  Py_XDECREF(sobj->dict);
+#endif
   PyObject_DEL(v);
 }
 
@@ -521,6 +833,7 @@
     PyErr_SetString(PyExc_TypeError, "Attempt to append a non SwigPyObject");
     return NULL;
   }
+  ((SwigPyObject *)next)->next = sobj->next;
   sobj->next = next;
   Py_INCREF(next);
   return SWIG_Py_Void();
@@ -565,9 +878,9 @@
     PyObject *obj = PyBool_FromLong(sobj->own);
     if (val) {
       if (PyObject_IsTrue(val)) {
-        SwigPyObject_acquire(v,args);
+        Py_DECREF(SwigPyObject_acquire(v,args));
       } else {
-        SwigPyObject_disown(v,args);
+        Py_DECREF(SwigPyObject_disown(v,args));
       }
     } 
     return obj;
@@ -588,7 +901,7 @@
 SWIGRUNTIME PyTypeObject*
 SwigPyObject_TypeOnce(void) {
   static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer";
-
+#ifndef Py_LIMITED_API
   static PyNumberMethods SwigPyObject_as_number = {
     (binaryfunc)0, /*nb_add*/
     (binaryfunc)0, /*nb_subtract*/
@@ -647,7 +960,11 @@
       sizeof(SwigPyObject),                 /* tp_basicsize */
       0,                                    /* tp_itemsize */
       (destructor)SwigPyObject_dealloc,     /* tp_dealloc */
-      0,                                    /* tp_print */
+#if PY_VERSION_HEX < 0x030800b4
+      (printfunc)0,                         /*tp_print*/
+#else
+      (Py_ssize_t)0,                        /*tp_vectorcall_offset*/
+#endif
       (getattrfunc)0,                       /* tp_getattr */
       (setattrfunc)0,                       /* tp_setattr */
 #if PY_VERSION_HEX >= 0x03000000
@@ -696,6 +1013,15 @@
 #if PY_VERSION_HEX >= 0x03040000
       0,                                    /* tp_finalize */
 #endif
+#if PY_VERSION_HEX >= 0x03080000
+      0,                                    /* tp_vectorcall */
+#endif
+#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)
+      0,                                    /* tp_print */
+#endif
+#if PY_VERSION_HEX >= 0x030C0000
+      0,                                    /* tp_watched */
+#endif
 #ifdef COUNT_ALLOCS
       0,                                    /* tp_allocs */
       0,                                    /* tp_frees */
@@ -706,21 +1032,50 @@
     };
     swigpyobject_type = tmp;
     type_init = 1;
-    if (PyType_Ready(&swigpyobject_type) < 0)
+    if (PyType_Ready(&swigpyobject_type) != 0)
       return NULL;
   }
   return &swigpyobject_type;
+#else
+  PyType_Slot slots[] = {
+    { Py_tp_dealloc, (void *)SwigPyObject_dealloc },
+    { Py_tp_repr, (void *)SwigPyObject_repr },
+    { Py_tp_getattro, (void *)PyObject_GenericGetAttr },
+    { Py_tp_doc, (void *)swigobject_doc },
+    { Py_tp_richcompare, (void *)SwigPyObject_richcompare },
+    { Py_tp_methods, (void *)swigobject_methods },
+    { Py_nb_int, (void *)SwigPyObject_long },
+    { 0, NULL }
+  };
+  PyType_Spec spec = {
+    "SwigPyObject",
+    sizeof(SwigPyObject),
+    0,
+    Py_TPFLAGS_DEFAULT,
+    slots
+  };
+  return (PyTypeObject *)PyType_FromSpec(&spec);
+#endif
 }
 
 SWIGRUNTIME PyObject *
 SwigPyObject_New(void *ptr, swig_type_info *ty, int own)
 {
-  SwigPyObject *sobj = PyObject_NEW(SwigPyObject, SwigPyObject_type());
+  SwigPyObject *sobj = PyObject_New(SwigPyObject, SwigPyObject_type());
   if (sobj) {
     sobj->ptr  = ptr;
     sobj->ty   = ty;
     sobj->own  = own;
     sobj->next = 0;
+#ifdef SWIGPYTHON_BUILTIN
+    sobj->dict = 0;
+#endif
+    if (own == SWIG_POINTER_OWN) {
+      /* Obtain a reference to the Python capsule wrapping the module information, so that the
+       * module information is correctly destroyed after all SWIG python objects have been freed
+       * by the GC (and corresponding destructors invoked) */
+      Py_XINCREF(Swig_Capsule_global);
+    }
   }
   return (PyObject *)sobj;
 }
@@ -777,8 +1132,20 @@
 
 SWIGRUNTIMEINLINE int
 SwigPyPacked_Check(PyObject *op) {
-  return ((op)->ob_type == SwigPyPacked_TypeOnce()) 
-    || (strcmp((op)->ob_type->tp_name,"SwigPyPacked") == 0);
+  PyTypeObject* op_type = Py_TYPE(op);
+  if (op_type == SwigPyPacked_TypeOnce())
+    return 1;
+#ifdef Py_LIMITED_API
+  int cmp;
+  PyObject *tp_name = PyObject_GetAttrString((PyObject *)op_type, "__name__");
+  if (!tp_name)
+    return 0;
+  cmp = PyUnicode_CompareWithASCIIString(tp_name, "SwigPyPacked");
+  Py_DECREF(tp_name);
+  return cmp == 0;
+#else
+  return (strcmp(op_type->tp_name, "SwigPyPacked") == 0);
+#endif
 }
 
 SWIGRUNTIME void
@@ -794,6 +1161,7 @@
 SWIGRUNTIME PyTypeObject*
 SwigPyPacked_TypeOnce(void) {
   static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer";
+#ifndef Py_LIMITED_API
   static PyTypeObject swigpypacked_type;
   static int type_init = 0;
   if (!type_init) {
@@ -808,7 +1176,11 @@
       sizeof(SwigPyPacked),                 /* tp_basicsize */
       0,                                    /* tp_itemsize */
       (destructor)SwigPyPacked_dealloc,     /* tp_dealloc */
-      0,                                    /* tp_print */
+#if PY_VERSION_HEX < 0x030800b4
+      (printfunc)0,                         /*tp_print*/
+#else
+      (Py_ssize_t)0,                        /*tp_vectorcall_offset*/
+#endif
       (getattrfunc)0,                       /* tp_getattr */
       (setattrfunc)0,                       /* tp_setattr */
 #if PY_VERSION_HEX>=0x03000000
@@ -857,6 +1229,15 @@
 #if PY_VERSION_HEX >= 0x03040000
       0,                                    /* tp_finalize */
 #endif
+#if PY_VERSION_HEX >= 0x03080000
+      0,                                    /* tp_vectorcall */
+#endif
+#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)
+      0,                                    /* tp_print */
+#endif
+#if PY_VERSION_HEX >= 0x030C0000
+      0,                                    /* tp_watched */
+#endif
 #ifdef COUNT_ALLOCS
       0,                                    /* tp_allocs */
       0,                                    /* tp_frees */
@@ -867,16 +1248,34 @@
     };
     swigpypacked_type = tmp;
     type_init = 1;
-    if (PyType_Ready(&swigpypacked_type) < 0)
+    if (PyType_Ready(&swigpypacked_type) != 0)
       return NULL;
   }
   return &swigpypacked_type;
+#else
+  PyType_Slot slots[] = {
+    { Py_tp_dealloc, (void *)SwigPyPacked_dealloc },
+    { Py_tp_repr, (void *)SwigPyPacked_repr },
+    { Py_tp_str, (void *)SwigPyPacked_str },
+    { Py_tp_getattro, (void *)PyObject_GenericGetAttr },
+    { Py_tp_doc, (void *)swigpacked_doc },
+    { 0, NULL }
+  };
+  PyType_Spec spec = {
+    "SwigPyPacked",
+    sizeof(SwigPyPacked),
+    0,
+    Py_TPFLAGS_DEFAULT,
+    slots
+  };
+  return (PyTypeObject *)PyType_FromSpec(&spec);
+#endif
 }
 
 SWIGRUNTIME PyObject *
 SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty)
 {
-  SwigPyPacked *sobj = PyObject_NEW(SwigPyPacked, SwigPyPacked_type());
+  SwigPyPacked *sobj = PyObject_New(SwigPyPacked, SwigPyPacked_type());
   if (sobj) {
     void *pack = malloc(size);
     if (pack) {
@@ -1057,12 +1456,19 @@
     }
   }
   if (sobj) {
-    if (own)
-      *own = *own | sobj->own;
-    if (flags & SWIG_POINTER_DISOWN) {
-      sobj->own = 0;
+    if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !sobj->own) {
+      res = SWIG_ERROR_RELEASE_NOT_OWNED;
+    } else {
+      if (own)
+        *own = *own | sobj->own;
+      if (flags & SWIG_POINTER_DISOWN) {
+        sobj->own = 0;
+      }
+      if (flags & SWIG_POINTER_CLEAR) {
+        sobj->ptr = 0;
+      }
+      res = SWIG_OK;
     }
-    res = SWIG_OK;
   } else {
     if (implicit_conv) {
       SwigPyClientData *data = ty ? (SwigPyClientData *) ty->clientdata : 0;
@@ -1121,10 +1527,20 @@
     swig_cast_info *tc;
 
     /* here we get the method pointer for callbacks */
+#ifndef Py_LIMITED_API
     const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc);
+#else
+    PyObject* pystr_doc = PyObject_GetAttrString(obj, "__doc__");
+    PyObject *bytes = NULL;
+    const char *doc = pystr_doc ? SWIG_PyUnicode_AsUTF8AndSize(pystr_doc, NULL, &bytes) : 0;
+#endif
     const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0;
     if (desc)
       desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0;
+#ifdef Py_LIMITED_API
+    Py_XDECREF(bytes);
+    Py_XDECREF(pystr_doc);
+#endif
     if (!desc)
       return SWIG_ERROR;
     tc = SWIG_TypeCheck(desc,ty);
@@ -1175,16 +1591,23 @@
 #if !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
       PyObject **dictptr = _PyObject_GetDictPtr(inst);
       if (dictptr != NULL) {
-	PyObject *dict = *dictptr;
-	if (dict == NULL) {
-	  dict = PyDict_New();
-	  *dictptr = dict;
-	  PyDict_SetItem(dict, SWIG_This(), swig_this);
-	}
+        PyObject *dict = *dictptr;
+        if (dict == NULL) {
+          dict = PyDict_New();
+          *dictptr = dict;
+        }
+        if (dict) {
+          PyDict_SetItem(dict, SWIG_This(), swig_this);
+        } else{
+          Py_DECREF(inst);
+          inst = 0;
+        }
       }
 #else
-      PyObject *key = SWIG_This();
-      PyObject_SetAttr(inst, key, swig_this);
+      if (PyObject_SetAttr(inst, SWIG_This(), swig_this) == -1) {
+        Py_DECREF(inst);
+        inst = 0;
+      }
 #endif
     }
   } else {
@@ -1193,11 +1616,20 @@
     if (empty_args) {
       PyObject *empty_kwargs = PyDict_New();
       if (empty_kwargs) {
-        inst = ((PyTypeObject *)data->newargs)->tp_new((PyTypeObject *)data->newargs, empty_args, empty_kwargs);
+#ifndef Py_LIMITED_API
+        newfunc newfn = ((PyTypeObject *)data->newargs)->tp_new;
+#else
+        newfunc newfn = (newfunc)PyType_GetSlot((PyTypeObject *)data->newargs, Py_tp_new);
+#endif
+        inst = newfn((PyTypeObject *)data->newargs, empty_args, empty_kwargs);
         Py_DECREF(empty_kwargs);
         if (inst) {
-          PyObject_SetAttr(inst, SWIG_This(), swig_this);
-          Py_TYPE(inst)->tp_flags &= ~Py_TPFLAGS_VALID_VERSION_TAG;
+          if (PyObject_SetAttr(inst, SWIG_This(), swig_this) == -1) {
+            Py_DECREF(inst);
+            inst = 0;
+          } else {
+            PyType_Modified(Py_TYPE(inst));
+          }
         }
       }
       Py_DECREF(empty_args);
@@ -1214,25 +1646,25 @@
   return inst;
 }
 
-SWIGRUNTIME void
+SWIGRUNTIME int
 SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this)
 {
- PyObject *dict;
 #if !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
- PyObject **dictptr = _PyObject_GetDictPtr(inst);
- if (dictptr != NULL) {
-   dict = *dictptr;
-   if (dict == NULL) {
-     dict = PyDict_New();
-     *dictptr = dict;
-   }
-   PyDict_SetItem(dict, SWIG_This(), swig_this);
-   return;
- }
+  PyObject **dictptr = _PyObject_GetDictPtr(inst);
+  if (dictptr != NULL) {
+    PyObject *dict = *dictptr;
+    if (dict == NULL) {
+      dict = PyDict_New();
+      *dictptr = dict;
+    }
+    if (dict) {
+      return PyDict_SetItem(dict, SWIG_This(), swig_this);
+    } else{
+      return -1;
+    }
+  }
 #endif
- dict = PyObject_GetAttrString(inst, "__dict__");
- PyDict_SetItem(dict, SWIG_This(), swig_this);
- Py_DECREF(dict);
+  return PyObject_SetAttr(inst, SWIG_This(), swig_this);
 } 
 
 
@@ -1244,9 +1676,10 @@
   } else {
     SwigPyObject *sthis = SWIG_Python_GetSwigThis(obj[0]);
     if (sthis) {
-      SwigPyObject_append((PyObject*) sthis, obj[1]);
+      Py_DECREF(SwigPyObject_append((PyObject*) sthis, obj[1]));
     } else {
-      SWIG_Python_SetSwigThis(obj[0], obj[1]);
+      if (SWIG_Python_SetSwigThis(obj[0], obj[1]) != 0)
+        return NULL;
     }
     return SWIG_Py_Void();
   }
@@ -1270,7 +1703,12 @@
     if (flags & SWIG_BUILTIN_TP_INIT) {
       newobj = (SwigPyObject*) self;
       if (newobj->ptr) {
-        PyObject *next_self = clientdata->pytype->tp_alloc(clientdata->pytype, 0);
+#ifndef Py_LIMITED_API
+        allocfunc alloc = clientdata->pytype->tp_alloc;
+#else
+        allocfunc alloc = (allocfunc)PyType_GetSlot(clientdata->pytype, Py_tp_alloc);
+#endif
+        PyObject *next_self = alloc(clientdata->pytype, 0);
         while (newobj->next)
 	  newobj = (SwigPyObject *) newobj->next;
         newobj->next = next_self;
@@ -1282,7 +1720,9 @@
     } else {
       newobj = PyObject_New(SwigPyObject, clientdata->pytype);
 #ifdef SWIGPYTHON_BUILTIN
-      newobj->dict = 0;
+      if (newobj) {
+        newobj->dict = 0;
+      }
 #endif
     }
     if (newobj) {
@@ -1321,39 +1761,61 @@
 void *SWIG_ReturnGlobalTypeList(void *);
 #endif
 
+static PyObject *Swig_TypeCache_global = NULL;
+
+/* The python cached type query */
+SWIGRUNTIME PyObject *
+SWIG_Python_TypeCache(void) {
+  if (Swig_TypeCache_global == NULL) {
+    Swig_TypeCache_global = PyDict_New();
+  }
+  return Swig_TypeCache_global;
+}
+
 SWIGRUNTIME swig_module_info *
 SWIG_Python_GetModule(void *SWIGUNUSEDPARM(clientdata)) {
+#ifdef SWIG_LINK_RUNTIME
   static void *type_pointer = (void *)0;
   /* first check if module already created */
   if (!type_pointer) {
-#ifdef SWIG_LINK_RUNTIME
     type_pointer = SWIG_ReturnGlobalTypeList((void *)0);
-#else
-    type_pointer = PyCapsule_Import(SWIGPY_CAPSULE_NAME, 0);
-    if (PyErr_Occurred()) {
-      PyErr_Clear();
-      type_pointer = (void *)0;
-    }
-#endif
   }
+#else
+  void *type_pointer = PyCapsule_Import(SWIGPY_CAPSULE_NAME, 0);
+  if (PyErr_Occurred()) {
+    PyErr_Clear();
+    type_pointer = (void *)0;
+  }
+#endif
   return (swig_module_info *) type_pointer;
 }
 
+
+static int interpreter_counter = 0; /* how many (sub-)interpreters are using swig_module's types */
+
 SWIGRUNTIME void
 SWIG_Python_DestroyModule(PyObject *obj)
 {
   swig_module_info *swig_module = (swig_module_info *) PyCapsule_GetPointer(obj, SWIGPY_CAPSULE_NAME);
   swig_type_info **types = swig_module->types;
   size_t i;
+  if (--interpreter_counter != 0) /* another sub-interpreter may still be using the swig_module's types */
+    return;
   for (i =0; i < swig_module->size; ++i) {
     swig_type_info *ty = types[i];
     if (ty->owndata) {
       SwigPyClientData *data = (SwigPyClientData *) ty->clientdata;
+      ty->clientdata = 0;
       if (data) SwigPyClientData_Del(data);
     }
   }
   Py_DECREF(SWIG_This());
   Swig_This_global = NULL;
+  Py_DECREF(SWIG_globals());
+  Swig_Globals_global = NULL;
+  Py_DECREF(SWIG_Python_TypeCache());
+  Swig_TypeCache_global = NULL;
+  Swig_Capsule_global = NULL;
 }
 
 SWIGRUNTIME void
@@ -1367,19 +1829,17 @@
 #endif
   PyObject *pointer = PyCapsule_New((void *) swig_module, SWIGPY_CAPSULE_NAME, SWIG_Python_DestroyModule);
   if (pointer && module) {
-    PyModule_AddObject(module, "type_pointer_capsule" SWIG_TYPE_TABLE_NAME, pointer);
+    if (PyModule_AddObject(module, SWIGPY_CAPSULE_ATTR_NAME, pointer) == 0) {
+      ++interpreter_counter;
+      Swig_Capsule_global = pointer;
+    } else {
+      Py_DECREF(pointer);
+    }
   } else {
     Py_XDECREF(pointer);
   }
 }
 
-/* The python cached type query */
-SWIGRUNTIME PyObject *
-SWIG_Python_TypeCache(void) {
-  static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New();
-  return cache;
-}
-
 SWIGRUNTIME swig_type_info *
 SWIG_Python_TypeQuery(const char *type)
 {
@@ -1394,8 +1854,10 @@
     descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type);
     if (descriptor) {
       obj = PyCapsule_New((void*) descriptor, NULL, NULL);
-      PyDict_SetItem(cache, key, obj);
-      Py_DECREF(obj);
+      if (obj) {
+        PyDict_SetItem(cache, key, obj);
+        Py_DECREF(obj);
+      }
     }
   }
   Py_DECREF(key);
@@ -1419,7 +1881,8 @@
     PyErr_Fetch(&type, &value, &traceback);
     if (value) {
       PyObject *old_str = PyObject_Str(value);
-      const char *tmp = SWIG_Python_str_AsChar(old_str);
+      PyObject *bytes = NULL;
+      const char *tmp = SWIG_PyUnicode_AsUTF8AndSize(old_str, NULL, &bytes);
       const char *errmesg = tmp ? tmp : "Invalid error message";
       Py_XINCREF(type);
       PyErr_Clear();
@@ -1428,7 +1891,7 @@
       } else {
 	PyErr_Format(type, "%s %s", errmesg, mesg);
       }
-      SWIG_Python_str_DelForPy3(tmp);
+      Py_XDECREF(bytes);
       Py_DECREF(old_str);
     }
     return 1;
@@ -1473,21 +1936,25 @@
     } else 
 #endif      
     {
+#ifndef Py_LIMITED_API
+      /* tp_name is not accessible */
       const char *otype = (obj ? obj->ob_type->tp_name : 0); 
       if (otype) {
 	PyObject *str = PyObject_Str(obj);
-	const char *cstr = str ? SWIG_Python_str_AsChar(str) : 0;
+	PyObject *bytes = NULL;
+	const char *cstr = str ? SWIG_PyUnicode_AsUTF8AndSize(str, NULL, &bytes) : 0;
 	if (cstr) {
 	  PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received",
 		       type, otype, cstr);
-          SWIG_Python_str_DelForPy3(cstr);
 	} else {
 	  PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received",
 		       type, otype);
 	}
+	Py_XDECREF(bytes);
 	Py_XDECREF(str);
 	return;
       }
+#endif
     }   
     PyErr_Format(PyExc_TypeError, "a '%s' is expected", type);
   } else {
@@ -1502,12 +1969,6 @@
   void *result;
   if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) {
     PyErr_Clear();
-#if SWIG_POINTER_EXCEPTION
-    if (flags) {
-      SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj);
-      SWIG_Python_ArgFail(argnum);
-    }
-#endif
   }
   return result;
 }
@@ -1538,7 +1999,7 @@
   }
 
   if (!tp->tp_dict) {
-    if (PyType_Ready(tp) < 0)
+    if (PyType_Ready(tp) != 0)
       goto done;
   }
 
@@ -1553,7 +2014,7 @@
     } else {
       encoded_name = PyUnicode_AsUTF8String(name);
       if (!encoded_name)
-        return -1;
+        goto done;
     }
     PyErr_Format(PyExc_AttributeError, "'%.100s' object has no attribute '%.200s'", tp->tp_name, PyString_AsString(encoded_name));
     Py_DECREF(encoded_name);
diff --git a/Lib/python/pyruntime.swg b/Lib/python/pyruntime.swg
index 751bc8d..3f45af8 100644
--- a/Lib/python/pyruntime.swg
+++ b/Lib/python/pyruntime.swg
@@ -4,14 +4,38 @@
 # include <math.h>
 #endif
 
+#if !defined(PY_SSIZE_T_CLEAN) && !defined(SWIG_NO_PY_SSIZE_T_CLEAN)
+#define PY_SSIZE_T_CLEAN
+#endif
+
+#if __GNUC__ >= 7
+#pragma GCC diagnostic push
+#if defined(__cplusplus) && __cplusplus >=201703L
+#pragma GCC diagnostic ignored "-Wregister" /* For python-2.7 headers that use register */
+#endif
+#endif
+
 #if defined(_DEBUG) && defined(SWIG_PYTHON_INTERPRETER_NO_DEBUG)
 /* Use debug wrappers with the Python release dll */
+
+#if defined(_MSC_VER) && _MSC_VER >= 1929
+/* Workaround compilation errors when redefining _DEBUG in MSVC 2019 version 16.10 and later
+ * See https://github.com/swig/swig/issues/2090 */
+# include <corecrt.h>
+#endif
+
 # undef _DEBUG
 # include <Python.h>
 # define _DEBUG 1
 #else
 # include <Python.h>
 #endif
+
+#if __GNUC__ >= 7
+#pragma GCC diagnostic pop
+#endif
+
+#include <stdio.h>
 %}
 
 %insert(runtime) "swigrun.swg";         /* SWIG API */
diff --git a/Lib/python/pystdcommon.swg b/Lib/python/pystdcommon.swg
index 0242e4d..afa7135 100644
--- a/Lib/python/pystdcommon.swg
+++ b/Lib/python/pystdcommon.swg
@@ -45,11 +45,20 @@
   template <class Type>
   struct traits_asptr {   
     static int asptr(PyObject *obj, Type **val) {
-      Type *p = 0;
+      int res = SWIG_ERROR;
       swig_type_info *descriptor = type_info<Type>();
-      int res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR;
-      if (SWIG_IsOK(res)) {
-	if (val) *val = p;
+      if (val) {
+        Type *p = 0;
+        int newmem = 0;
+        res = descriptor ? SWIG_ConvertPtrAndOwn(obj, (void **)&p, descriptor, 0, &newmem) : SWIG_ERROR;
+        if (SWIG_IsOK(res)) {
+          if (newmem & SWIG_CAST_NEW_MEMORY) {
+            res |= SWIG_NEWOBJMASK;
+          }
+          *val = p;
+        }
+      } else {
+        res = descriptor ? SWIG_ConvertPtr(obj, 0, descriptor, 0) : SWIG_ERROR;
       }
       return res;
     }
diff --git a/Lib/python/pystrings.swg b/Lib/python/pystrings.swg
index 93f48ac..1cb4e99 100644
--- a/Lib/python/pystrings.swg
+++ b/Lib/python/pystrings.swg
@@ -2,8 +2,10 @@
  *  utility methods for char strings 
  * ------------------------------------------------------------ */
 %fragment("SWIG_AsCharPtrAndSize","header",fragment="SWIG_pchar_descriptor") {
+/* Return string from Python obj. NOTE: obj must remain in scope in order
+   to use the returned cptr (but only when alloc is set to SWIG_OLDOBJ) */
 SWIGINTERN int
-SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
+SWIG_AsCharPtrAndSize(PyObject *obj, char **cptr, size_t *psize, int *alloc)
 {
 %#if PY_VERSION_HEX>=0x03000000
 %#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
@@ -16,53 +18,31 @@
 %#endif
   {
     char *cstr; Py_ssize_t len;
+    PyObject *bytes = NULL;
     int ret = SWIG_OK;
-%#if PY_VERSION_HEX>=0x03000000
-%#if !defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
-    if (!alloc && cptr) {
-        /* We can't allow converting without allocation, since the internal
-           representation of string in Python 3 is UCS-2/UCS-4 but we require
-           a UTF-8 representation.
-           TODO(bhy) More detailed explanation */
-        return SWIG_RuntimeError;
-    }
-    obj = PyUnicode_AsUTF8String(obj);
-    if (!obj)
-      return SWIG_TypeError;
     if (alloc)
-      *alloc = SWIG_NEWOBJ;
-%#endif
-    PyBytes_AsStringAndSize(obj, &cstr, &len);
+      *alloc = SWIG_OLDOBJ;
+%#if PY_VERSION_HEX>=0x03000000 && defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
+    if (PyBytes_AsStringAndSize(obj, &cstr, &len) == -1)
+      return SWIG_TypeError;
 %#else
-    PyString_AsStringAndSize(obj, &cstr, &len);
-%#endif
-    if (cptr) {
+    cstr = (char *)SWIG_PyUnicode_AsUTF8AndSize(obj, &len, &bytes);
+    if (!cstr)
+      return SWIG_TypeError;
+    /* The returned string is only duplicated if the char * returned is not owned and memory managed by obj */
+    if (bytes && cptr) {
       if (alloc) {
-	if (*alloc == SWIG_NEWOBJ) {
-	  *cptr = %new_copy_array(cstr, len + 1, char);
-	  *alloc = SWIG_NEWOBJ;
-	} else {
-	  *cptr = cstr;
-	  *alloc = SWIG_OLDOBJ;
-	}
+        cstr = %new_copy_array(cstr, len + 1, char);
+        *alloc = SWIG_NEWOBJ;
       } else {
-%#if PY_VERSION_HEX>=0x03000000
-%#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
-	*cptr = PyBytes_AsString(obj);
-%#else
-	assert(0); /* Should never reach here with Unicode strings in Python 3 */
-%#endif
-%#else
-	*cptr = SWIG_Python_str_AsChar(obj);
-        if (!*cptr)
-          ret = SWIG_TypeError;
-%#endif
+        /* alloc must be set in order to clean up allocated memory */
+        return SWIG_RuntimeError;
       }
     }
-    if (psize) *psize = len + 1;
-%#if PY_VERSION_HEX>=0x03000000 && !defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
-    Py_XDECREF(obj);
 %#endif
+    if (cptr) *cptr = cstr;
+    if (psize) *psize = len + 1;
+    Py_XDECREF(bytes);
     return ret;
   } else {
 %#if defined(SWIG_PYTHON_2_UNICODE)
diff --git a/Lib/python/pythonkw.swg b/Lib/python/pythonkw.swg
index 0138e40..a210345 100644
--- a/Lib/python/pythonkw.swg
+++ b/Lib/python/pythonkw.swg
@@ -2,7 +2,7 @@
   Warnings for Python keywords, built-in names and bad names.
 */
 
-#define PYTHONKW(x) %keywordwarn("'" `x` "' is a python keyword, renaming to '_" `x` "'", rename="_%s")  `x`
+#define PYTHONKW(x) %keywordwarn("'" `x` "' is a python keyword", rename="_%s")  `x`
 #define PYTHONBN(x) %builtinwarn("'" `x` "' conflicts with a built-in name in python")  `x`
 
 
diff --git a/Lib/python/pythreads.swg b/Lib/python/pythreads.swg
index d8797e6..96a6471 100644
--- a/Lib/python/pythreads.swg
+++ b/Lib/python/pythreads.swg
@@ -8,8 +8,12 @@
 #    define SWIG_PYTHON_USE_GIL
 #  endif
 #  if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */
-#    ifndef SWIG_PYTHON_INITIALIZE_THREADS
-#     define SWIG_PYTHON_INITIALIZE_THREADS  PyEval_InitThreads() 
+#    if !defined(SWIG_PYTHON_INITIALIZE_THREADS)
+#      if PY_VERSION_HEX < 0x03070000
+#        define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads()
+#      else
+#        define SWIG_PYTHON_INITIALIZE_THREADS
+#      endif
 #    endif
 #    ifdef __cplusplus /* C++ code */
        class SWIG_Python_Thread_Block {
@@ -24,7 +28,7 @@
          bool status;
          PyThreadState *save;
        public:
-         void end() { if (status) { PyEval_RestoreThread(save); status = false; }}
+         void end() { if (status) { status = false; PyEval_RestoreThread(save); }}
          SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {}
          ~SWIG_Python_Thread_Allow() { end(); }
        };
diff --git a/Lib/python/pytypemaps.swg b/Lib/python/pytypemaps.swg
index 0eda17c..0ae25a6 100644
--- a/Lib/python/pytypemaps.swg
+++ b/Lib/python/pytypemaps.swg
@@ -83,7 +83,7 @@
 { SWIG_PY_POINTER, "$symname", 0, 0, (void *)($value), &$descriptor }
 %typemap(consttab) SWIGTYPE ((* const)(ANY)) = SWIGTYPE ((*)(ANY));
 
-%typemap(constcode) SWIGTYPE ((*)(ANY)) "";
+%typemap(constcode) SWIGTYPE ((*)(ANY)) ""
 %typemap(constcode) SWIGTYPE ((* const)(ANY)) = SWIGTYPE ((*)(ANY));
 
 
diff --git a/Lib/python/std_array.i b/Lib/python/std_array.i
index a3de312..707b354 100644
--- a/Lib/python/std_array.i
+++ b/Lib/python/std_array.i
@@ -19,15 +19,43 @@
       }
     };
 
-    template <class SwigPySeq, class T, size_t N>
-    inline void
-    assign(const SwigPySeq& swigpyseq, std::array<T, N>* seq) {
-      if (swigpyseq.size() < seq->size())
-        throw std::invalid_argument("std::array cannot be expanded in size");
-      else if (swigpyseq.size() > seq->size())
-        throw std::invalid_argument("std::array cannot be reduced in size");
-      std::copy(swigpyseq.begin(), swigpyseq.end(), seq->begin());
-    }
+    template <class T, size_t N>
+    struct IteratorProtocol<std::array<T, N>, T> {
+
+      static void assign(PyObject *obj, std::array<T, N> *seq) {
+        SwigVar_PyObject iter = PyObject_GetIter(obj);
+        if (iter) {
+          SwigVar_PyObject item = PyIter_Next(iter);
+          size_t count = 0;
+          typename std::array<T, N>::iterator array_iter = seq->begin();
+          while (item && (count < N)) {
+            ++count;
+            *array_iter++ = swig::as<T>(item);
+            item = PyIter_Next(iter);
+          }
+          if (count != N || item)
+            throw std::invalid_argument("std::array size does not match source container size");
+        }
+      }
+
+      static bool check(PyObject *obj) {
+        bool ret = false;
+        SwigVar_PyObject iter = PyObject_GetIter(obj);
+        if (iter) {
+          SwigVar_PyObject item = PyIter_Next(iter);
+          size_t count = 0;
+          ret = true;
+          while (item && (count < N)) {
+            ++count;
+            ret = swig::check<T>(item);
+            item = ret ? PyIter_Next(iter) : 0;
+          }
+          if (count != N || item)
+            ret = false;
+        }
+        return ret;
+      }
+    };
 
     template <class T, size_t N>
     inline void
diff --git a/Lib/python/std_auto_ptr.i b/Lib/python/std_auto_ptr.i
index e310e00..3d7ae8b 100644
--- a/Lib/python/std_auto_ptr.i
+++ b/Lib/python/std_auto_ptr.i
@@ -1,17 +1,39 @@
-/*
-    The typemaps here allow to handle functions returning std::auto_ptr<>,
-    which is the most common use of this type. If you have functions taking it
-    as parameter, these typemaps can't be used for them and you need to do
-    something else (e.g. use shared_ptr<> which SWIG supports fully).
- */
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
 
 %define %auto_ptr(TYPE)
-%typemap (out) std::auto_ptr<TYPE > %{
-   %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+  %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
 %}
-%template() std::auto_ptr<TYPE >;
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
 %enddef
 
 namespace std {
-   template <class T> class auto_ptr {};
-} 
+  template <class T> class auto_ptr {};
+}
diff --git a/Lib/python/std_carray.i b/Lib/python/std_carray.i
deleted file mode 100644
index 680d671..0000000
--- a/Lib/python/std_carray.i
+++ /dev/null
@@ -1,54 +0,0 @@
-%include <pycontainer.swg>
-
-
-%fragment("StdCarrayTraits","header",fragment="StdSequenceTraits")
-{
-namespace swig {
-  template <class T, size_t S>
-  struct traits_asptr<std::carray<T, S> >  {
-    static int asptr(PyObject *obj, std::carray<T, S> **array) {
-      return traits_asptr_stdseq<std::carray<T, S> >::asptr(obj, array);
-    }
-  };
-}
-}
-
-%warnfilter(SWIGWARN_IGNORE_OPERATOR_INDEX) std::carray::operator[];
-
-%extend std::carray {
-  %fragment(SWIG_Traits_frag(std::carray<_Type, _Size >), "header",
-	    fragment="SwigPyIterator_T",
-	    fragment=SWIG_Traits_frag(_Type),
-	    fragment="StdCarrayTraits") {
-    namespace swig {
-      template <>  struct traits<std::carray<_Type, _Size > > {
-	typedef pointer_category category;
-	static const char* type_name() {
-	  return "std::carray<" #_Type "," #_Size " >";
-	}
-      };
-    }
-  }
-  
-  %typemaps_asptr(SWIG_TYPECHECK_VECTOR, swig::asptr,
-		  SWIG_Traits_frag(std::carray<_Type, _Size >),
-		  std::carray<_Type, _Size >);
-
-  %typemap(out,noblock=1) iterator, const_iterator {
-    $result = SWIG_NewPointerObj(swig::make_output_iterator((const $type &)$1),
-				 swig::SwigPyIterator::descriptor(),SWIG_POINTER_OWN);
-  }
-  
-  inline size_t __len__() const { return self->size(); }
-  
-  inline const _Type& __getitem__(size_t i) const { return (*self)[i]; }
-  
-  inline void __setitem__(size_t i, const _Type& v) { (*self)[i] = v; }
-
-  
-  swig::SwigPyIterator* __iter__(PyObject **PYTHON_SELF) {
-    return swig::make_output_iterator(self->begin(), self->begin(), self->end(), *PYTHON_SELF);
-  }
-}
-
-%include <std/std_carray.swg>
diff --git a/Lib/python/std_filesystem.i b/Lib/python/std_filesystem.i
new file mode 100644
index 0000000..5b9f335
--- /dev/null
+++ b/Lib/python/std_filesystem.i
@@ -0,0 +1,121 @@
+/* -----------------------------------------------------------------------------
+ * std_filesystem.i
+ *
+ * SWIG typemaps for std::filesystem::path
+ * ----------------------------------------------------------------------------- */
+
+%{
+#include <filesystem>
+%}
+
+%fragment("SWIG_std_filesystem", "header") {
+SWIGINTERN PyObject *SWIG_std_filesystem_importPathClass() {
+  PyObject *module = PyImport_ImportModule("pathlib");
+  PyObject *cls = PyObject_GetAttrString(module, "Path");
+  Py_DECREF(module);
+  return cls;
+}
+
+SWIGINTERN bool SWIG_std_filesystem_isPathInstance(PyObject *obj) {
+  PyObject *cls = SWIG_std_filesystem_importPathClass();
+  bool is_instance = PyObject_IsInstance(obj, cls);
+  Py_DECREF(cls);
+  return is_instance;
+}
+}
+
+%typemap(in, fragment="SWIG_std_filesystem", fragment="<type_traits>") std::filesystem::path {
+  if (PyUnicode_Check($input)) {
+    PyObject *bytes = NULL;
+    const char *s = SWIG_PyUnicode_AsUTF8AndSize($input, NULL, &bytes);
+    $1 = std::filesystem::path(s);
+    Py_XDECREF(bytes);
+  } else if (SWIG_std_filesystem_isPathInstance($input)) {
+    PyObject *str_obj = PyObject_Str($input);
+    if constexpr (std::is_same_v<typename std::filesystem::path::value_type, wchar_t>) {
+      Py_ssize_t size = 0;
+      wchar_t *ws = PyUnicode_AsWideCharString(str_obj, &size);
+      if (!ws) SWIG_fail;
+      $1 = std::filesystem::path(std::wstring(ws, static_cast<size_t>(size)));
+      PyMem_Free(ws);
+    } else {
+      PyObject *bytes = NULL;
+      const char *s = SWIG_PyUnicode_AsUTF8AndSize(str_obj, NULL, &bytes);
+      $1 = std::filesystem::path(s);
+      Py_XDECREF(bytes);
+    }
+    Py_DECREF(str_obj);
+  } else {
+    void *argp = 0;
+    int res = SWIG_ConvertPtr($input, &argp, $descriptor(std::filesystem::path *), $disown | 0);
+    if (!SWIG_IsOK(res)) {
+      %argument_fail(res, "$type", $symname, $argnum);
+    }
+    std::filesystem::path *temp = %reinterpret_cast(argp, $1_ltype*);
+    $1 = *temp;
+  }
+}
+
+%typemap(in, fragment="SWIG_std_filesystem", fragment="<type_traits>") const std::filesystem::path &(std::filesystem::path temp_path) {
+  if (PyUnicode_Check($input)) {
+    PyObject *bytes = NULL;
+    const char *s = SWIG_PyUnicode_AsUTF8AndSize($input, NULL, &bytes);
+    temp_path = std::filesystem::path(s);
+    $1 = &temp_path;
+    Py_XDECREF(bytes);
+  } else if (SWIG_std_filesystem_isPathInstance($input)) {
+    PyObject *str_obj = PyObject_Str($input);
+    if constexpr (std::is_same_v<typename std::filesystem::path::value_type, wchar_t>) {
+      Py_ssize_t size = 0;
+      wchar_t *ws = PyUnicode_AsWideCharString(str_obj, &size);
+      if (!ws) SWIG_fail;
+      temp_path = std::filesystem::path(std::wstring(ws, static_cast<size_t>(size)));
+      $1 = &temp_path;
+      PyMem_Free(ws);
+    } else {
+      PyObject *bytes = NULL;
+      const char *s = SWIG_PyUnicode_AsUTF8AndSize(str_obj, NULL, &bytes);
+      temp_path = std::filesystem::path(s);
+      $1 = &temp_path;
+      Py_XDECREF(bytes);
+    }
+    Py_DECREF(str_obj);
+  } else {
+    void *argp = 0;
+    int res = SWIG_ConvertPtr($input, &argp, $descriptor, $disown | 0);
+    if (!SWIG_IsOK(res)) {
+      %argument_fail(res, "$type", $symname, $argnum);
+    }
+    $1 = %reinterpret_cast(argp, $1_ltype);
+  }
+}
+
+%typemap(out, fragment="SWIG_std_filesystem", fragment="<type_traits>") std::filesystem::path {
+  PyObject *args;
+  if constexpr (std::is_same_v<typename std::filesystem::path::value_type, wchar_t>) {
+    std::wstring s = $1.generic_wstring();
+    args = Py_BuildValue("(u)", s.data());
+  } else {
+    std::string s = $1.generic_string();
+    args = Py_BuildValue("(s)", s.data());
+  }
+  PyObject *cls = SWIG_std_filesystem_importPathClass();
+  $result = PyObject_CallObject(cls, args);
+  Py_DECREF(cls);
+  Py_DECREF(args);
+}
+
+%typemap(out, fragment="SWIG_std_filesystem", fragment="<type_traits>") const std::filesystem::path & {
+  PyObject *args;
+  if constexpr (std::is_same_v<typename std::filesystem::path::value_type, wchar_t>) {
+    std::wstring s = $1->generic_wstring();
+    args = Py_BuildValue("(u)", s.data());
+  } else {
+    std::string s = $1->generic_string();
+    args = Py_BuildValue("(s)", s.data());
+  }
+  PyObject *cls = SWIG_std_filesystem_importPathClass();
+  $result = PyObject_CallObject(cls, args);
+  Py_DECREF(cls);
+  Py_DECREF(args);
+}
diff --git a/Lib/python/std_map.i b/Lib/python/std_map.i
index 8ae483c..954e7eb 100644
--- a/Lib/python/std_map.i
+++ b/Lib/python/std_map.i
@@ -2,7 +2,7 @@
   Maps
 */
 
-%fragment("StdMapCommonTraits","header",fragment="StdSequenceTraits")
+%fragment("StdMapCommonTraits","header",fragment="StdSequenceTraits",fragment="SwigPyIterator_T")
 {
   namespace swig {
     template <class ValueType>
@@ -77,16 +77,6 @@
 %fragment("StdMapTraits","header",fragment="StdMapCommonTraits")
 {
   namespace swig {
-    template <class SwigPySeq, class K, class T, class Compare, class Alloc >
-    inline void
-    assign(const SwigPySeq& swigpyseq, std::map<K,T,Compare,Alloc > *map) {
-      typedef typename std::map<K,T,Compare,Alloc >::value_type value_type;
-      typename SwigPySeq::const_iterator it = swigpyseq.begin();
-      for (;it != swigpyseq.end(); ++it) {
-	map->insert(value_type(it->first, it->second));
-      }
-    }
-
     template <class K, class T, class Compare, class Alloc>
     struct traits_asptr<std::map<K,T,Compare,Alloc > >  {
       typedef std::map<K,T,Compare,Alloc > map_type;
@@ -101,7 +91,7 @@
 %#endif
 	  res = traits_asptr_stdseq<map_type, std::pair<K, T> >::asptr(items, val);
 	} else {
-	  map_type *p;
+	  map_type *p = 0;
 	  swig_type_info *descriptor = swig::type_info<map_type>();
 	  res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR;
 	  if (SWIG_IsOK(res) && val)  *val = p;
@@ -295,7 +285,11 @@
     }
 
     void __setitem__(const key_type& key, const mapped_type& x) throw (std::out_of_range) {
+%#ifdef __cpp_lib_map_try_emplace
+      (*self).insert_or_assign(key, x);
+%#else
       (*self)[key] = x;
+%#endif
     }
 
     PyObject* asdict() {
diff --git a/Lib/python/std_multimap.i b/Lib/python/std_multimap.i
index f78a527..75b4d7f 100644
--- a/Lib/python/std_multimap.i
+++ b/Lib/python/std_multimap.i
@@ -6,16 +6,6 @@
 %fragment("StdMultimapTraits","header",fragment="StdMapCommonTraits")
 {
   namespace swig {
-    template <class SwigPySeq, class K, class T >
-    inline void 
-    assign(const SwigPySeq& swigpyseq, std::multimap<K,T > *multimap) {
-      typedef typename std::multimap<K,T>::value_type value_type;
-      typename SwigPySeq::const_iterator it = swigpyseq.begin();
-      for (;it != swigpyseq.end(); ++it) {
-	multimap->insert(value_type(it->first, it->second));
-      }
-    }
-
     template <class K, class T>
     struct traits_asptr<std::multimap<K,T> >  {
       typedef std::multimap<K,T> multimap_type;
@@ -29,7 +19,7 @@
 %#endif
 	  res = traits_asptr_stdseq<std::multimap<K,T>, std::pair<K, T> >::asptr(items, val);
 	} else {
-	  multimap_type *p;
+	  multimap_type *p = 0;
 	  swig_type_info *descriptor = swig::type_info<multimap_type>();
 	  res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR;
 	  if (SWIG_IsOK(res) && val)  *val = p;
diff --git a/Lib/python/std_multiset.i b/Lib/python/std_multiset.i
index ac43033..b79f64e 100644
--- a/Lib/python/std_multiset.i
+++ b/Lib/python/std_multiset.i
@@ -7,17 +7,6 @@
 %fragment("StdMultisetTraits","header",fragment="StdSequenceTraits")
 %{
   namespace swig {
-    template <class SwigPySeq, class T> 
-    inline void
-    assign(const SwigPySeq& swigpyseq, std::multiset<T>* seq) {
-      // seq->insert(swigpyseq.begin(), swigpyseq.end()); // not used as not always implemented
-      typedef typename SwigPySeq::value_type value_type;
-      typename SwigPySeq::const_iterator it = swigpyseq.begin();
-      for (;it != swigpyseq.end(); ++it) {
-	seq->insert(seq->end(),(value_type)(*it));
-      }
-    }
-
     template <class T>
     struct traits_asptr<std::multiset<T> >  {
       static int asptr(PyObject *obj, std::multiset<T> **m) {
diff --git a/Lib/python/std_pair.i b/Lib/python/std_pair.i
index 172572b..cf463cb 100644
--- a/Lib/python/std_pair.i
+++ b/Lib/python/std_pair.i
@@ -47,7 +47,7 @@
 	    res = get_pair(first, second, val);
 	  }
 	} else {
-	  value_type *p;
+	  value_type *p = 0;
 	  swig_type_info *descriptor = swig::type_info<value_type>();
 	  res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR;
 	  if (SWIG_IsOK(res) && val)  *val = *p;
@@ -104,7 +104,7 @@
 	    res = get_pair(first, second, val);
 	  }
 	} else {
-	  value_type *p;
+	  value_type *p = 0;
 	  swig_type_info *descriptor = swig::type_info<value_type>();
 	  res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR;
 	  if (SWIG_IsOK(res) && val)  *val = p;
diff --git a/Lib/python/std_set.i b/Lib/python/std_set.i
index 0ef0119..3f80daf 100644
--- a/Lib/python/std_set.i
+++ b/Lib/python/std_set.i
@@ -5,17 +5,6 @@
 %fragment("StdSetTraits","header",fragment="StdSequenceTraits")
 %{
   namespace swig {
-    template <class SwigPySeq, class T> 
-    inline void 
-    assign(const SwigPySeq& swigpyseq, std::set<T>* seq) {
-      // seq->insert(swigpyseq.begin(), swigpyseq.end()); // not used as not always implemented
-      typedef typename SwigPySeq::value_type value_type;
-      typename SwigPySeq::const_iterator it = swigpyseq.begin();
-      for (;it != swigpyseq.end(); ++it) {
-	seq->insert(seq->end(),(value_type)(*it));
-      }
-    }
-
     template <class T>
     struct traits_asptr<std::set<T> >  {
       static int asptr(PyObject *obj, std::set<T> **s) {
diff --git a/Lib/python/std_string_view.i b/Lib/python/std_string_view.i
new file mode 100644
index 0000000..a3069f8
--- /dev/null
+++ b/Lib/python/std_string_view.i
@@ -0,0 +1,135 @@
+/* -----------------------------------------------------------------------------
+ * std_string_view.i
+ *
+ * SWIG typemaps for std::string_view types
+ * ----------------------------------------------------------------------------- */
+
+%include <exception.i>
+
+%{
+#include <string_view>
+
+#if PY_VERSION_HEX < 0x03000000
+# error std_string_view.i not supported for Python 2
+#endif
+%}
+
+namespace std {
+
+    %naturalvar string_view;
+
+    class string_view;
+
+    %typemap(typecheck,precedence=SWIG_TYPECHECK_STRINGVIEW) string_view, const string_view & %{
+#ifdef SWIG_PYTHON_STRICT_BYTE_CHAR
+        $1 = PyBytes_Check($input);
+#else
+        $1 = PyUnicode_Check($input) || PyBytes_Check($input);
+#endif
+    %}
+
+    %typemap(in) string_view (PyObject *bytes = NULL) %{
+        Py_ssize_t len;
+#ifdef SWIG_PYTHON_STRICT_BYTE_CHAR
+        const char *p = PyBytes_AsString($input);
+        if (!p) SWIG_fail;
+        len = PyBytes_Size($input);
+#else
+        const char *p;
+        if (PyUnicode_Check($input)) {
+          p = SWIG_PyUnicode_AsUTF8AndSize($input, &len, &bytes);
+          if (!p) SWIG_fail;
+        } else {
+          p = PyBytes_AsString($input);
+          if (!p) SWIG_fail;
+          len = PyBytes_Size($input);
+        }
+#endif
+        $1 = std::string_view(p, len);
+    %}
+
+    %typemap(freearg) string_view %{
+        Py_XDECREF(bytes$argnum);
+    %}
+
+    %typemap(in) const string_view & ($*1_ltype temp, PyObject *bytes = NULL) %{
+        Py_ssize_t len;
+#ifdef SWIG_PYTHON_STRICT_BYTE_CHAR
+        const char *p = PyBytes_AsString($input);
+        if (!p) SWIG_fail;
+        len = PyBytes_Size($input);
+#else
+        const char *p;
+        if (PyUnicode_Check($input)) {
+          p = SWIG_PyUnicode_AsUTF8AndSize($input, &len, &bytes);
+          if (!p) SWIG_fail;
+        } else {
+          p = PyBytes_AsString($input);
+          if (!p) SWIG_fail;
+          len = PyBytes_Size($input);
+        }
+#endif
+        temp = std::string_view(p, len);
+        $1 = &temp;
+    %}
+
+    %typemap(freearg) const string_view & %{
+        Py_XDECREF(bytes$argnum);
+    %}
+
+    %typemap(directorout, warning=SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG) string_view {
+        Py_ssize_t len;
+%#ifdef SWIG_PYTHON_STRICT_BYTE_CHAR
+        const char *p = PyBytes_AsString($input);
+        if (p) len = PyBytes_Size($input);
+%#else
+        const char *p;
+        PyObject *bytes = NULL;
+        if (PyUnicode_Check($input)) {
+          p = SWIG_PyUnicode_AsUTF8AndSize($input, &len, &bytes);
+          // Avoid undefined behaviour (p will be pointing to a temporary
+          // if bytes is not NULL which happens when Py_LIMITED_API is defined
+          // and < 0x030A0000) and just leak by not calling Py_XDECREF.
+          // Py_XDECREF(bytes);
+        } else {
+          p = PyBytes_AsString($input);
+          if (p) len = PyBytes_Size($input);
+        }
+%#endif
+        if (p) $result = std::string_view(p, len);
+    }
+
+
+    %typemap(out) string_view %{
+#ifdef SWIG_PYTHON_STRICT_BYTE_CHAR
+        $result = PyBytes_FromStringAndSize($1.data(), $1.size());
+#else
+        $result = PyUnicode_FromStringAndSize($1.data(), $1.size());
+#endif
+    %}
+
+    %typemap(varout) string_view %{
+#ifdef SWIG_PYTHON_STRICT_BYTE_CHAR
+        $result = PyBytes_FromStringAndSize($1.data(), $1.size());
+#else
+        $result = PyUnicode_FromStringAndSize($1.data(), $1.size());
+#endif
+    %}
+
+    %typemap(directorin) string_view, const string_view & %{
+#ifdef SWIG_PYTHON_STRICT_BYTE_CHAR
+        $input = PyBytes_FromStringAndSize($1.data(), $1.size());
+#else
+        $input = PyUnicode_FromStringAndSize($1.data(), $1.size());
+#endif
+    %}
+
+    %typemap(out) const string_view & %{
+#ifdef SWIG_PYTHON_STRICT_BYTE_CHAR
+        $result = PyBytes_FromStringAndSize($1->data(), $1->size());
+#else
+        $result = PyUnicode_FromStringAndSize($1->data(), $1->size());
+#endif
+    %}
+
+}
diff --git a/Lib/python/std_unique_ptr.i b/Lib/python/std_unique_ptr.i
new file mode 100644
index 0000000..f988714
--- /dev/null
+++ b/Lib/python/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+  %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class unique_ptr {};
+}
diff --git a/Lib/python/std_unordered_map.i b/Lib/python/std_unordered_map.i
index 042d5b6..4321735 100644
--- a/Lib/python/std_unordered_map.i
+++ b/Lib/python/std_unordered_map.i
@@ -56,16 +56,6 @@
 %fragment("StdUnorderedMapTraits","header",fragment="StdMapCommonTraits",fragment="StdUnorderedMapForwardIteratorTraits")
 {
   namespace swig {
-    template <class SwigPySeq, class K, class T, class Hash, class Compare, class Alloc>
-    inline void
-    assign(const SwigPySeq& swigpyseq, std::unordered_map<K,T,Hash,Compare,Alloc> *unordered_map) {
-      typedef typename std::unordered_map<K,T,Hash,Compare,Alloc>::value_type value_type;
-      typename SwigPySeq::const_iterator it = swigpyseq.begin();
-      for (;it != swigpyseq.end(); ++it) {
-	unordered_map->insert(value_type(it->first, it->second));
-      }
-    }
-
     template <class K, class T, class Hash, class Compare, class Alloc>
     struct traits_reserve<std::unordered_map<K,T,Hash,Compare,Alloc> > {
       static void reserve(std::unordered_map<K,T,Hash,Compare,Alloc> &seq, typename std::unordered_map<K,T,Hash,Compare,Alloc>::size_type n) {
@@ -87,7 +77,7 @@
 %#endif
 	  res = traits_asptr_stdseq<std::unordered_map<K,T,Hash,Compare,Alloc>, std::pair<K, T> >::asptr(items, val);
 	} else {
-	  unordered_map_type *p;
+	  unordered_map_type *p = 0;
 	  swig_type_info *descriptor = swig::type_info<unordered_map_type>();
 	  res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR;
 	  if (SWIG_IsOK(res) && val)  *val = p;
@@ -281,7 +271,11 @@
     }
 
     void __setitem__(const key_type& key, const mapped_type& x) throw (std::out_of_range) {
+%#ifdef __cpp_lib_unordered_map_try_emplace
+      (*self).insert_or_assign(key, x);
+%#else
       (*self)[key] = x;
+%#endif
     }
 
     PyObject* asdict() {
diff --git a/Lib/python/std_unordered_multimap.i b/Lib/python/std_unordered_multimap.i
index 2811404..816ec09 100644
--- a/Lib/python/std_unordered_multimap.i
+++ b/Lib/python/std_unordered_multimap.i
@@ -6,16 +6,6 @@
 %fragment("StdUnorderedMultimapTraits","header",fragment="StdMapCommonTraits",fragment="StdUnorderedMapForwardIteratorTraits")
 {
   namespace swig {
-    template <class SwigPySeq, class K, class T, class Hash, class Compare, class Alloc>
-    inline void 
-    assign(const SwigPySeq& swigpyseq, std::unordered_multimap<K,T,Hash,Compare,Alloc> *unordered_multimap) {
-      typedef typename std::unordered_multimap<K,T,Hash,Compare,Alloc>::value_type value_type;
-      typename SwigPySeq::const_iterator it = swigpyseq.begin();
-      for (;it != swigpyseq.end(); ++it) {
-	unordered_multimap->insert(value_type(it->first, it->second));
-      }
-    }
-
     template <class K, class T, class Hash, class Compare, class Alloc>
     struct traits_reserve<std::unordered_multimap<K,T,Hash,Compare,Alloc> >  {
       static void reserve(std::unordered_multimap<K,T,Hash,Compare,Alloc> &seq, typename std::unordered_multimap<K,T,Hash,Compare,Alloc>::size_type n) {
@@ -36,7 +26,7 @@
 %#endif
 	  res = traits_asptr_stdseq<std::unordered_multimap<K,T,Hash,Compare,Alloc>, std::pair<K, T> >::asptr(items, val);
 	} else {
-	  unordered_multimap_type *p;
+	  unordered_multimap_type *p = 0;
 	  swig_type_info *descriptor = swig::type_info<unordered_multimap_type>();
 	  res = descriptor ? SWIG_ConvertPtr(obj, (void **)&p, descriptor, 0) : SWIG_ERROR;
 	  if (SWIG_IsOK(res) && val)  *val = p;
diff --git a/Lib/python/std_unordered_multiset.i b/Lib/python/std_unordered_multiset.i
index b0f3f09..0542247 100644
--- a/Lib/python/std_unordered_multiset.i
+++ b/Lib/python/std_unordered_multiset.i
@@ -7,17 +7,6 @@
 %fragment("StdUnorderedMultisetTraits","header",fragment="StdSequenceTraits")
 %{
   namespace swig {
-    template <class SwigPySeq, class Key, class Hash, class Compare, class Alloc>
-    inline void
-    assign(const SwigPySeq& swigpyseq, std::unordered_multiset<Key,Hash,Compare,Alloc>* seq) {
-      // seq->insert(swigpyseq.begin(), swigpyseq.end()); // not used as not always implemented
-      typedef typename SwigPySeq::value_type value_type;
-      typename SwigPySeq::const_iterator it = swigpyseq.begin();
-      for (;it != swigpyseq.end(); ++it) {
-	seq->insert(seq->end(),(value_type)(*it));
-      }
-    }
-
     template <class Key, class Hash, class Compare, class Alloc>
     struct traits_reserve<std::unordered_multiset<Key,Hash,Compare,Alloc> >  {
       static void reserve(std::unordered_multiset<Key,Hash,Compare,Alloc> &seq, typename std::unordered_multiset<Key,Hash,Compare,Alloc>::size_type n) {
diff --git a/Lib/python/std_unordered_set.i b/Lib/python/std_unordered_set.i
index 79fca6c..fd866b1 100644
--- a/Lib/python/std_unordered_set.i
+++ b/Lib/python/std_unordered_set.i
@@ -5,17 +5,6 @@
 %fragment("StdUnorderedSetTraits","header",fragment="StdSequenceTraits")
 %{
   namespace swig {
-    template <class SwigPySeq, class Key, class Hash, class Compare, class Alloc>
-    inline void 
-    assign(const SwigPySeq& swigpyseq, std::unordered_set<Key,Hash,Compare,Alloc>* seq) {
-      // seq->insert(swigpyseq.begin(), swigpyseq.end()); // not used as not always implemented
-      typedef typename SwigPySeq::value_type value_type;
-      typename SwigPySeq::const_iterator it = swigpyseq.begin();
-      for (;it != swigpyseq.end(); ++it) {
-	seq->insert(seq->end(),(value_type)(*it));
-      }
-    }
-
     template <class Key, class Hash, class Compare, class Alloc>
     struct traits_reserve<std::unordered_set<Key,Hash,Compare,Alloc> >  {
       static void reserve(std::unordered_set<Key,Hash,Compare,Alloc> &seq, typename std::unordered_set<Key,Hash,Compare,Alloc>::size_type n) {
diff --git a/Lib/python/swigmove.i b/Lib/python/swigmove.i
new file mode 100644
index 0000000..62ecca7
--- /dev/null
+++ b/Lib/python/swigmove.i
@@ -0,0 +1 @@
+%include <typemaps/swigmove.swg>
diff --git a/Lib/python/typemaps.i b/Lib/python/typemaps.i
index 5d438ec..7559203 100644
--- a/Lib/python/typemaps.i
+++ b/Lib/python/typemaps.i
@@ -72,7 +72,7 @@
          
 For example, suppose you were trying to wrap the modf() function in the
 C math library which splits x into integral and fractional parts (and
-returns the integer part in one of its parameters).K:
+returns the integer part in one of its parameters) :
 
         double modf(double x, double *ip);
 
@@ -139,10 +139,6 @@
 
        x = neg(x)
 
-Note : previous versions of SWIG used the symbol 'BOTH' to mark
-input/output arguments.   This is still supported, but will be slowly
-phased out in future releases.
-
 */
 
 %include <typemaps/typemaps.swg>
diff --git a/Lib/r/argcargv.i b/Lib/r/argcargv.i
new file mode 100644
index 0000000..1753f6e
--- /dev/null
+++ b/Lib/r/argcargv.i
@@ -0,0 +1,38 @@
+/* -------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------- */
+
+/* Preserve string vector as is */
+%typemap(scoercein) (int ARGC, char **ARGV) ""
+/* Verify we pass the proper string vector */
+%typemap(scheck) (int ARGC, char **ARGV) %{
+  assert(is.null($input) || (is.vector($input) && is.character($input)))
+%}
+/* Check argument is null or a string vector for dispatcher */
+%typemap(rtypecheck) (int ARGC, char **ARGV) %{
+  is.null($arg) || (is.vector($arg) && is.character($arg))
+%}
+%typemap(in) (int ARGC, char **ARGV) {
+  $1_ltype i;
+  SEXP *pstr;
+  if ($input == R_NilValue) {
+    /* Empty array */
+    $1 = 0;
+  } else if (!Rf_isVectorAtomic($input) || TYPEOF($input) != STRSXP) {
+    SWIG_exception_fail(SWIG_RuntimeError, "Wrong array type.");
+  } else {
+    $1 = Rf_length($input);
+    pstr = CHARACTER_POINTER($input);
+  }
+  $2 = ($2_ltype) malloc(($1+1)*sizeof($*2_ltype));
+  if ($2 == SWIG_NULLPTR) {
+    SWIG_exception_fail(SWIG_MemoryError, "Memory allocation failed.");
+  }
+  for (i = 0; i < $1; i++) {
+    $2[i] = ($*2_ltype)STRING_VALUE(pstr[i]);
+  }
+  $2[i] = SWIG_NULLPTR;
+}
+%typemap(freearg,noblock=1) (int ARGC, char **ARGV) {
+  free((void *)$2);
+}
diff --git a/Lib/r/boost_shared_ptr.i b/Lib/r/boost_shared_ptr.i
index 668bf43..fde6ae5 100644
--- a/Lib/r/boost_shared_ptr.i
+++ b/Lib/r/boost_shared_ptr.i
@@ -35,7 +35,7 @@
   }
 }
 %typemap(out) CONST TYPE {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
@@ -54,12 +54,12 @@
   }
 }
 %typemap(varout) CONST TYPE {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
 %typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
-  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(SWIG_STD_MOVE($1)));
   $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
 %}
 %typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
@@ -394,6 +394,31 @@
 #error "typemaps for $1_type not available"
 %}
 
+%typemap(rtype)      SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >,
+                     SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &,
+                     SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *,
+                     SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *&
+  "$typemap(rtype, TYPE)"
+
+%typemap(rtypecheck) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >,
+                     SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &,
+                     SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *,
+                     SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *&
+  "(extends($argtype, '$typemap(rtype, TYPE)') && length($arg) == 1) || is.null($arg)"
+
+%typemap(scoercein)  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >,
+                     SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &,
+                     SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *,
+                     SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *&
+ %{ if (inherits($input, "ExternalReference")) $input = slot($input,"ref"); %}
+
+%typemap(scoerceout) SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >,
+                     SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > &,
+                     SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *,
+                     SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *&
+  %{ $result <- if (is.null($result)) $result
+  else new("$typemap(rtype, TYPE)", ref=$result); %}
+
 
 %template() SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >;
 
diff --git a/Lib/r/r.swg b/Lib/r/r.swg
index 8cf8cdf..c1ce37c 100644
--- a/Lib/r/r.swg
+++ b/Lib/r/r.swg
@@ -26,9 +26,13 @@
    assign(name, _obj);
 %end_block %enddef
 
-%define %raise(obj,type,desc) 
-return R_NilValue;
-%enddef
+%runtime %{
+SWIGINTERN void SWIG_R_Raise(SEXP obj, const char *msg) {
+  Rf_error(Rf_isString(obj) ? CHAR(Rf_asChar(obj)) : msg);
+}
+%}
+
+#define %raise(OBJ, TYPE, DESC) SWIG_R_Raise(OBJ, "C/C++ exception of type " TYPE); return R_NilValue
 
 %insert("sinit") "srun.swg"
 
@@ -53,7 +57,7 @@
       assert(all(sapply($input, class) == "$R_class"));
   %}
 
-%typemap(out) void "";
+%typemap(out) void ""
 
 %typemap(in) int *, int[ANY],
 	     signed int *, signed int[ANY],
diff --git a/Lib/r/rcontainer.swg b/Lib/r/rcontainer.swg
index 54b31b3..84a6c69 100644
--- a/Lib/r/rcontainer.swg
+++ b/Lib/r/rcontainer.swg
@@ -75,25 +75,29 @@
 
   template <class Sequence, class Difference, class InputSeq>
   inline void
-  setslice(Sequence* self, Difference i, Difference j, const InputSeq& v) {
+  setslice(Sequence* self, Difference i, Difference j, const InputSeq& is) {
     typename Sequence::size_type size = self->size();
     typename Sequence::size_type ii = swig::check_index(i, size, true);
     typename Sequence::size_type jj = swig::slice_index(j, size);
     if (jj < ii) jj = ii;
     size_t ssize = jj - ii;
-    if (ssize <= v.size()) {
+    if (ssize <= is.size()) {
+      // expanding/staying the same size
       typename Sequence::iterator sb = self->begin();
-      typename InputSeq::const_iterator vmid = v.begin();
+      typename InputSeq::const_iterator vmid = is.begin();
       std::advance(sb,ii);
       std::advance(vmid, jj - ii);
-      self->insert(std::copy(v.begin(), vmid, sb), vmid, v.end());
+      self->insert(std::copy(is.begin(), vmid, sb), vmid, is.end());
     } else {
+      // shrinking
       typename Sequence::iterator sb = self->begin();
       typename Sequence::iterator se = self->begin();
       std::advance(sb,ii);
       std::advance(se,jj);
       self->erase(sb,se);
-      self->insert(sb, v.begin(), v.end());
+      sb = self->begin();
+      std::advance(sb,ii);
+      self->insert(sb, is.begin(), is.end());
     }
   }
 
@@ -148,9 +152,9 @@
       return swig::getslice(self, i, j);
     }
 
-    void __setslice__(difference_type i, difference_type j, const Sequence& v) 
+    void __setslice__(difference_type i, difference_type j, const Sequence& is)
       throw (std::out_of_range, std::invalid_argument) {
-      swig::setslice(self, i, j, v);
+      swig::setslice(self, i, j, is);
     }
 
     void __delslice__(difference_type i, difference_type j) throw (std::out_of_range) {
diff --git a/Lib/r/rfragments.swg b/Lib/r/rfragments.swg
index b89212b..c3b40a9 100644
--- a/Lib/r/rfragments.swg
+++ b/Lib/r/rfragments.swg
@@ -1,7 +1,3 @@
-#define SWIG_Error(code, msg) Rf_warning(msg); return Rf_ScalarLogical(NA_LOGICAL)
-
-#define SWIG_fail return Rf_ScalarLogical(NA_LOGICAL)
-
 /* for raw pointers */
 #define SWIG_ConvertPtr(oc, ptr, ty, flags)             SWIG_R_ConvertPtr(oc, ptr, ty, flags)
 #define SWIG_ConvertFunctionPtr(oc, ptr, ty)            SWIG_R_ConvertPtr(oc, ptr, ty, 0)
diff --git a/Lib/r/rkw.swg b/Lib/r/rkw.swg
index 074d7df..c4af708 100644
--- a/Lib/r/rkw.swg
+++ b/Lib/r/rkw.swg
@@ -2,8 +2,8 @@
   Warnings for R keywords, built-in names and bad names.
 */
 
-#define RKW(x) %keywordwarn("'" `x` "' is a R keyword, renaming to '_" `x`"'", rename="_%s")  `x`
-#define RSWIGKW(x) %keywordwarn("'" `x` "' is a SWIG R reserved parameter name, renaming to '_" `x`"'", rename="_%s")  `x`
+#define RKW(x) %keywordwarn("'" `x` "' is a R keyword", rename="_%s")  `x`
+#define RSWIGKW(x) %keywordwarn("'" `x` "' is a SWIG R reserved parameter name", rename="_%s")  `x`
 
 /*
   Warnings for R reserved words taken from
diff --git a/Lib/r/rrun.swg b/Lib/r/rrun.swg
index c341321..3ffc02f 100644
--- a/Lib/r/rrun.swg
+++ b/Lib/r/rrun.swg
@@ -1,4 +1,3 @@
-
 /* Remove global namespace pollution */
 #if !defined(SWIG_NO_R_NO_REMAP)
 # define R_NO_REMAP
@@ -16,13 +15,15 @@
 #endif
 
 /* for raw pointer */
+#define SWIG_R_ConvertPtr(obj, pptr, type, flags)       SWIG_R_ConvertPtrAndOwn(obj, pptr, type, flags, 0)
 #define SWIG_ConvertPtr(obj, pptr, type, flags)         SWIG_R_ConvertPtr(obj, pptr, type, flags)
-#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own)  SWIG_R_ConvertPtr(obj, pptr, type, flags)
+#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own)  SWIG_R_ConvertPtrAndOwn(obj, pptr, type, flags, own)
 #define SWIG_NewPointerObj(ptr, type, flags)            SWIG_R_NewPointerObj(ptr, type, flags)
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <assert.h>
+#include <stdarg.h>
 
 #if R_VERSION >= R_Version(2,6,0)
 #define VMAXTYPE void *
@@ -30,6 +31,47 @@
 #define VMAXTYPE char *
 #endif
 
+/* Last error */
+static int SWIG_lasterror_code = 0;
+static char SWIG_lasterror_msg[1024];
+SWIGRUNTIME void SWIG_Error(int code, const char *format, ...) {
+  va_list arg;
+  SWIG_lasterror_code = code;
+  va_start(arg, format);
+  vsnprintf(SWIG_lasterror_msg, sizeof(SWIG_lasterror_msg), format, arg);
+  va_end(arg);
+}
+
+SWIGRUNTIME const char *SWIG_ErrorType(int code) {
+  switch (code) {
+  case SWIG_MemoryError:
+    return "SWIG:MemoryError";
+  case SWIG_IOError:
+    return "SWIG:IOError";
+  case SWIG_RuntimeError:
+    return "SWIG:RuntimeError";
+  case SWIG_IndexError:
+    return "SWIG:IndexError";
+  case SWIG_TypeError:
+    return "SWIG:TypeError";
+  case SWIG_DivisionByZero:
+    return "SWIG:DivisionByZero";
+  case SWIG_OverflowError:
+    return "SWIG:OverflowError";
+  case SWIG_SyntaxError:
+    return "SWIG:SyntaxError";
+  case SWIG_ValueError:
+    return "SWIG:ValueError";
+  case SWIG_SystemError:
+    return "SWIG:SystemError";
+  case SWIG_AttributeError:
+    return "SWIG:AttributeError";
+  }
+  return "SWIG:UnknownError";
+}
+
+#define SWIG_fail goto fail
+
 /*
   This is mainly a way to avoid having lots of local variables that may 
   conflict with those in the routine.
@@ -273,9 +315,11 @@
 
 /* Convert a pointer value */
 SWIGRUNTIMEINLINE int
-SWIG_R_ConvertPtr(SEXP obj, void **ptr, swig_type_info *ty, int flags) {
+SWIG_R_ConvertPtrAndOwn(SEXP obj, void **ptr, swig_type_info *ty, int flags, int *own) {
   void *vptr;
   if (!obj) return SWIG_ERROR;
+  if (own)
+    *own = 0;
   if (obj == R_NilValue) {
     if (ptr) *ptr = NULL;
     return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
@@ -290,8 +334,15 @@
     } else {
       swig_cast_info *tc = SWIG_TypeCheck(to->name,ty);
       int newmemory = 0;
-      if (ptr) *ptr = SWIG_TypeCast(tc,vptr,&newmemory);
-      assert(!newmemory); /* newmemory handling not yet implemented */
+      if (ptr) {
+        int newmemory = 0;
+        *ptr = SWIG_TypeCast(tc, vptr, &newmemory);
+        if (newmemory == SWIG_CAST_NEW_MEMORY) {
+          assert(own); /* badly formed typemap which will lead to a memory leak - it must set and use own to delete *ptr */
+          if (own)
+            *own = *own | SWIG_CAST_NEW_MEMORY;
+        }
+      }
     }
   } else {
       if (ptr) *ptr = vptr;
diff --git a/Lib/r/rtype.swg b/Lib/r/rtype.swg
index bdc48c2..1d66632 100644
--- a/Lib/r/rtype.swg
+++ b/Lib/r/rtype.swg
@@ -3,34 +3,34 @@
    for use in class representations. 
  */
 
-%typemap("rtype") int, int *, int &      "integer";
-%typemap("rtype") long, long *, long &      "integer";
-%typemap("rtype") float, float*, float & "numeric";
-%typemap("rtype") double, double*, double & "numeric";
-%typemap("rtype") char *, char ** "character";
-%typemap("rtype") char            "character";
-%typemap("rtype") string, string *, string & "character";
-%typemap("rtype") std::string, std::string *, std::string & "character";
-%typemap("rtype") bool, bool *    "logical";
-%typemap("rtype") enum SWIGTYPE   "character";
-%typemap("rtype") enum SWIGTYPE *   "character";
-%typemap("rtype") enum SWIGTYPE *const   "character";
-%typemap("rtype") enum SWIGTYPE &  "character";
-%typemap("rtype") const enum SWIGTYPE &  "character";
-%typemap("rtype") enum SWIGTYPE &&  "character";
-%typemap("rtype") SWIGTYPE * "$R_class";
-%typemap("rtype") SWIGTYPE *const "$R_class";
-%typemap("rtype") SWIGTYPE & "$R_class";
-%typemap("rtype") SWIGTYPE && "$R_class";
-%typemap("rtype") SWIGTYPE "$&R_class";
+%typemap("rtype") bool, bool * "logical"
+%typemap("rtype") int, int *, int & "integer"
+%typemap("rtype") long, long *, long & "integer"
+%typemap("rtype") float, float*, float & "numeric"
+%typemap("rtype") double, double*, double & "numeric"
+%typemap("rtype") char *, char ** "character"
+%typemap("rtype") char "character"
+%typemap("rtype") string, string *, string & "character"
+%typemap("rtype") std::string, std::string *, std::string & "character"
+%typemap("rtype") enum SWIGTYPE "character"
+%typemap("rtype") enum SWIGTYPE * "character"
+%typemap("rtype") enum SWIGTYPE *const& "character"
+%typemap("rtype") enum SWIGTYPE & "character"
+%typemap("rtype") const enum SWIGTYPE & "character"
+%typemap("rtype") enum SWIGTYPE && "character"
+%typemap("rtype") SWIGTYPE * "$R_class"
+%typemap("rtype") SWIGTYPE *const "$R_class"
+%typemap("rtype") SWIGTYPE *const& "$*R_class"
+%typemap("rtype") SWIGTYPE & "$R_class"
+%typemap("rtype") SWIGTYPE && "$R_class"
+%typemap("rtype") SWIGTYPE "$&R_class"
 
 %typemap("rtypecheck") int, int &, long, long &
   %{ (is.integer($arg) || is.numeric($arg)) && length($arg) == 1 %}
 %typemap("rtypecheck") int *, long *
   %{ is.integer($arg) || is.numeric($arg) %}
 
-
-%typemap("rtypecheck") float, double
+%typemap("rtypecheck") float, float &, double, double &
   %{ is.numeric($arg) && length($arg) == 1 %}
 %typemap("rtypecheck") float *, double *
   %{ is.numeric($arg) %}
@@ -40,6 +40,38 @@
 %typemap("rtypecheck") bool *
   %{ is.logical($arg) %}
 
+%typemap("rtypecheck") char
+  %{ is.character($arg) && length($arg) == 1 %}
+%typemap("rtypecheck") char *, char **
+  %{ is.character($arg) %}
+
+%typemap("rtypecheck") string, string &
+  %{ is.character($arg) && length($arg) == 1 %}
+%typemap("rtypecheck") string *
+  %{ is.character($arg) %}
+
+%typemap("rtypecheck") std::string, std::string &
+  %{ is.character($arg) && length($arg) == 1 %}
+%typemap("rtypecheck") std::string *
+  %{ is.character($arg) %}
+
+%typemap("rtypecheck") enum SWIGTYPE, enum SWIGTYPE *const&, enum SWIGTYPE &, const enum SWIGTYPE &, enum SWIGTYPE &&
+  %{ is.character($arg) && length($arg) == 1 %}
+%typemap("rtypecheck") enum SWIGTYPE *
+  %{ is.character($arg) %}
+
+%typemap("rtypecheck") SWIGTYPE *
+  %{ extends($argtype, '$R_class') || is.null($arg) %}
+
+%typemap("rtypecheck") SWIGTYPE &, SWIGTYPE &&
+  %{ extends($argtype, '$R_class') && length($arg) == 1 %}
+
+%typemap("rtypecheck") SWIGTYPE *const&
+  %{ extends($argtype, '$*R_class') && length($arg) == 1 %}
+
+%typemap("rtypecheck") SWIGTYPE
+  %{ extends($argtype, '$&R_class') && length($arg) == 1 %}
+
 /*
   Set up type checks to insure overloading precedence.
   We would like non pointer items to shadow pointer items, so that 
@@ -93,21 +125,21 @@
 %typemap(scoercein) enum SWIGTYPE *const
   %{  $input = enumToInteger($input, "$R_class"); %}
 
-%typemap(scoercein) SWIGTYPE, SWIGTYPE *, SWIGTYPE *const, SWIGTYPE &, SWIGTYPE &&
- %{ if (inherits($input, "ExternalReference")) $input = slot($input,"ref") %}
+%typemap(scoercein) SWIGTYPE, SWIGTYPE *, SWIGTYPE *const, SWIGTYPE *const&, SWIGTYPE &, SWIGTYPE &&
+ %{ if (inherits($input, "ExternalReference")) $input = slot($input,"ref"); %}
 
 /*
 %typemap(scoercein) SWIGTYPE *, SWIGTYPE *const
-  %{ $input = coerceIfNotSubclass($input, "$R_class") %}
+  %{ $input = coerceIfNotSubclass($input, "$R_class"); %}
 
 %typemap(scoercein) SWIGTYPE & 
-  %{ $input = coerceIfNotSubclass($input, "$R_class") %}
+  %{ $input = coerceIfNotSubclass($input, "$R_class"); %}
 
 %typemap(scoercein) SWIGTYPE && 
-  %{ $input = coerceIfNotSubclass($input, "$R_class") %}
+  %{ $input = coerceIfNotSubclass($input, "$R_class"); %}
 
 %typemap(scoercein) SWIGTYPE  
-  %{ $input = coerceIfNotSubclass($input, "$&R_class") %}
+  %{ $input = coerceIfNotSubclass($input, "$&R_class"); %}
 */
 
 %typemap(scoercein) SWIGTYPE[ANY]  
@@ -172,6 +204,10 @@
   %{ $result <- if (is.null($result)) $result
   else new("$R_class", ref=$result); %}
 
+%typemap(scoerceout) SWIGTYPE *const&
+  %{ $result <- if (is.null($result)) $result
+  else new("$*R_class", ref=$result); %}
+
 
 /* Override the SWIGTYPE * above. */
 %typemap(scoerceout) char,
diff --git a/Lib/r/std_vector.i b/Lib/r/std_vector.i
index 4ec51dc..98840c5 100644
--- a/Lib/r/std_vector.i
+++ b/Lib/r/std_vector.i
@@ -544,7 +544,7 @@
   struct traits_asptr < std::vector<T> > {
     static int asptr(SEXP obj, std::vector<T> **val) {
       std::vector<T> *p;
-      int res = SWIG_R_ConvertPtr(obj, (void**)&p, type_info< std::vector<T> >(), 0);
+      int res = SWIG_ConvertPtr(obj, (void**)&p, type_info< std::vector<T> >(), 0);
       if (SWIG_IsOK(res)) {
         if (val) *val = p;
       }
@@ -660,6 +660,27 @@
       }
     };
 
+  template <>
+    struct traits_from_ptr<std::vector<std::vector<std::basic_string<char> > > > {
+      static SEXP from (std::vector< std::vector<std::basic_string<char> > > *val, int owner = 0) {
+        SEXP result;
+        // allocate the R list
+        PROTECT(result = Rf_allocVector(VECSXP, val->size()));
+        for (unsigned pos = 0; pos < val->size(); pos++)
+          {
+            // allocate the R vector
+            SET_VECTOR_ELT(result, pos, Rf_allocVector(STRSXP, val->at(pos).size()));
+            // Fill the R vector
+            for (unsigned vpos = 0; vpos < val->at(pos).size(); ++vpos)
+              {
+                CHARACTER_POINTER(VECTOR_ELT(result, pos))[vpos] = Rf_mkChar(val->at(pos).at(vpos).c_str());
+              }
+          }
+        UNPROTECT(1);
+        return(result);
+      }
+    };
+
   template <typename T>
     struct traits_from_ptr< std::vector < std::vector< T > > > {
     static SEXP from (std::vector < std::vector< T > > *val, int owner = 0) {
@@ -806,7 +827,7 @@
     static int asptr(SEXP obj, std::vector< std::vector<T> > **val) {
       std::vector< std::vector<T> > *p;
       Rprintf("vector of vectors - unsupported content\n");
-      int res = SWIG_R_ConvertPtr(obj, (void**)&p, type_info< std::vector< std::vector<T> > > (), 0);
+      int res = SWIG_ConvertPtr(obj, (void**)&p, type_info< std::vector< std::vector<T> > > (), 0);
       if (SWIG_IsOK(res)) {
         if (val) *val = p;
       }
@@ -841,7 +862,7 @@
 %typemap("rtypecheck") std::vector<double>, std::vector<double> *, std::vector<double> &
     %{ is.numeric($arg) %}
 %typemap("rtype") std::vector<double> "numeric"
-%typemap("scoercein") std::vector<double>, std::vector<double> *, std::vector<double> & "$input = as.numeric($input);";
+%typemap("scoercein") std::vector<double>, std::vector<double> *, std::vector<double> & "$input = as.numeric($input);"
 
 %typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<float>)
 %traits_type_name(std::vector<float>)
@@ -857,7 +878,7 @@
 %typemap("rtypecheck") std::vector<bool>, std::vector<bool> *, std::vector<bool> &
    %{ is.logical($arg) %}
 %typemap("rtype") std::vector<bool> "logical"
-%typemap("scoercein") std::vector<bool> , std::vector<bool> & "$input = as.logical($input);";
+%typemap("scoercein") std::vector<bool> , std::vector<bool> & "$input = as.logical($input);"
 
 
 %typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<int>);
@@ -866,7 +887,7 @@
    %{ is.integer($arg) || is.numeric($arg) %}
 
 %typemap("rtype") std::vector<int> "integer"
-%typemap("scoercein") std::vector<int> , std::vector<int> *, std::vector<int> & "$input = as.integer($input);";
+%typemap("scoercein") std::vector<int> , std::vector<int> *, std::vector<int> & "$input = as.integer($input);"
 
 // strings
 %typemap("rtype") std::vector< std::basic_string<char> >,  
@@ -887,8 +908,6 @@
    std::vector< std::basic_string<char> > & 
 %{    %}
 
-%apply std::vector< std::basic_string<char> > { std::vector< std::string> };
-
 // all the related integer vectors
 // signed
 %typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<signed char>);
@@ -974,21 +993,21 @@
 %typemap("rtypecheck") std::vector<std::vector<int> >, std::vector<std::vector<int> > *, std::vector<std::vector<int> > &
    %{ is.list($arg) && all(sapply($arg , is.integer) || sapply($arg, is.numeric)) %}
 %typemap("rtype") std::vector<std::vector<int> >, std::vector<std::vector<int> > *, std::vector<std::vector<int> > & "list"
-%typemap("scoercein") std::vector< std::vector<int> >, std::vector<std::vector<int> > *, std::vector<std::vector<int> > & "$input = lapply($input, as.integer);";
+%typemap("scoercein") std::vector< std::vector<int> >, std::vector<std::vector<int> > *, std::vector<std::vector<int> > & "$input = lapply($input, as.integer);"
 
 %typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<std::vector<unsigned int> >);
 %traits_type_name(std::vector< std::vector<unsigned int> >);
 %typemap("rtypecheck") std::vector<std::vector<unsigned int> >, std::vector<std::vector<unsigned int> > *, std::vector<std::vector<unsigned int> > &
    %{ is.list($arg) && all(sapply($arg , is.integer) || sapply($arg, is.numeric)) %}
 %typemap("rtype") std::vector<std::vector<unsigned int> >, std::vector<std::vector<unsigned int> > *, std::vector<std::vector<unsigned int> > & "list"
-%typemap("scoercein") std::vector< std::vector<unsigned int> >, std::vector<std::vector<int> > *, std::vector<std::vector<unsigned int> > & "$input = lapply($input, as.integer);";
+%typemap("scoercein") std::vector< std::vector<unsigned int> >, std::vector<std::vector<int> > *, std::vector<std::vector<unsigned int> > & "$input = lapply($input, as.integer);"
 
 %typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<std::vector<float> >);
 %traits_type_name(std::vector< std::vector<float> >);
 %typemap("rtypecheck") std::vector<std::vector<float> >, std::vector<std::vector<float> > *, std::vector<std::vector<float> > &
    %{ is.list($arg) && all(sapply($arg , is.integer) || sapply($arg, is.numeric)) %}
 %typemap("rtype") std::vector<std::vector<float> >, std::vector<std::vector<float> > *, std::vector<std::vector<float> > "list"
-%typemap("scoercein") std::vector< std::vector<float> >, std::vector<std::vector<float> > *, std::vector<std::vector<float> > & "$input = lapply($input, as.numeric);";
+%typemap("scoercein") std::vector< std::vector<float> >, std::vector<std::vector<float> > *, std::vector<std::vector<float> > & "$input = lapply($input, as.numeric);"
 
 %typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<std::vector<double> >);
 %traits_type_name(std::vector< std::vector<double> >);
@@ -1003,7 +1022,14 @@
 %typemap("rtypecheck") std::vector<std::vector<bool> >, std::vector<std::vector<bool> > *, std::vector<std::vector<bool> > &
    %{ is.list($arg) && all(sapply($arg , is.integer) || sapply($arg, is.numeric)) %}
 %typemap("rtype") std::vector<std::vector<bool> >, std::vector<std::vector<bool> > *, std::vector<std::vector<bool> > & "list"
-%typemap("scoercein") std::vector< std::vector<bool> >, std::vector<std::vector<bool> > *, std::vector<std::vector<bool> > & "$input = lapply($input, as.logical);";
+%typemap("scoercein") std::vector< std::vector<bool> >, std::vector<std::vector<bool> > *, std::vector<std::vector<bool> > & "$input = lapply($input, as.logical);"
+
+%typemap_traits_ptr(SWIG_TYPECHECK_VECTOR, std::vector<std::vector<std::basic_string<char> > >);
+%traits_type_name(std::vector< std::vector<std::basic_string<char> > >);
+%typemap("rtypecheck") std::vector<std::vector<std::basic_string<char> > >, std::vector<std::vector<std::basic_string<char> > > *, std::vector<std::vector<std::basic_string<char> > > &
+   %{ is.list($arg) && all(sapply($arg , is.character)) %}
+%typemap("rtype") std::vector<std::vector<std::basic_string<char> > >, std::vector<std::vector<std::basic_string<char> > > *, std::vector<std::vector<std::basic_string<char> > > & "list"
+%typemap("scoercein") std::vector< std::vector<std::basic_string<char> > >, std::vector<std::vector<std::basic_string<char> > > *, std::vector<std::vector<std::basic_string<char> > > & "$input = lapply($input, as.character);"
 
 // we don't want these to be given R classes as they
 // have already been turned into R vectors.
@@ -1049,7 +1075,10 @@
    std::vector< std::vector<double> >&,
    std::vector< std::vector<bool> >,
    std::vector< std::vector<bool> >*,
-   std::vector< std::vector<bool> >&
+   std::vector< std::vector<bool> >&,
+   std::vector< std::vector<std::basic_string<char> > >,
+   std::vector< std::vector<std::basic_string<char> > >*,
+   std::vector< std::vector<std::basic_string<char> > >&
  %{    %}
 
 #if defined(SWIGWORDSIZE64)
@@ -1071,3 +1100,6 @@
  %{    %}
 
 #endif
+
+%apply std::vector< std::basic_string<char> > { std::vector<std::string> };
+%apply std::vector< std::vector< std::basic_string<char> > > { std::vector< std::vector<std::string> > };
diff --git a/Lib/r/swigmove.i b/Lib/r/swigmove.i
new file mode 100644
index 0000000..62ecca7
--- /dev/null
+++ b/Lib/r/swigmove.i
@@ -0,0 +1 @@
+%include <typemaps/swigmove.swg>
diff --git a/Lib/ruby/argcargv.i b/Lib/ruby/argcargv.i
index fc0bc40..b8efcff 100644
--- a/Lib/ruby/argcargv.i
+++ b/Lib/ruby/argcargv.i
@@ -1,26 +1,22 @@
-/* ------------------------------------------------------------
- * --- Argc & Argv ---
- * ------------------------------------------------------------ */
- 
-/* ------------------------------------------------------------
+/* -------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
 
-   Use it as follow:
+   Use it as follows:
 
      %apply (int ARGC, char **ARGV) { (size_t argc, const char **argv) }
 
      %inline %{
 
-     int mainApp(size_t argc, const char **argv) 
-     {
+     int mainApp(size_t argc, const char **argv) {
        return argc;
      }
 
-   then in the ruby side:
+   then from ruby:
 
-     args = ["asdf", "asdf2"]
-     mainApp(args);
+     $args = ["asdf", "asdf2"]
+     mainApp(args)
 
- * ------------------------------------------------------------ */
+ * ------------------------------------------------------------- */
 
 %typemap(in) (int ARGC, char **ARGV) {
   if (rb_obj_is_kind_of($input,rb_cArray)) {
@@ -31,7 +27,7 @@
     VALUE *ptr = RARRAY_PTR($input);
     for (i=0; i < size; i++, ptr++) {
       $2[i]= StringValuePtr(*ptr);
-    }    
+    }
     $2[i]=NULL;
   } else {
     $1 = 0; $2 = 0;
diff --git a/Lib/ruby/boost_shared_ptr.i b/Lib/ruby/boost_shared_ptr.i
index 9676bf9..70deae4 100644
--- a/Lib/ruby/boost_shared_ptr.i
+++ b/Lib/ruby/boost_shared_ptr.i
@@ -35,7 +35,7 @@
   }
 }
 %typemap(out) CONST TYPE {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
@@ -54,12 +54,12 @@
   }
 }
 %typemap(varout) CONST TYPE {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
 %typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
-  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(SWIG_STD_MOVE($1)));
   $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
 %}
 %typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
diff --git a/Lib/ruby/carrays.i b/Lib/ruby/carrays.i
index 8f74cd9..7e1e66a 100644
--- a/Lib/ruby/carrays.i
+++ b/Lib/ruby/carrays.i
@@ -3,4 +3,3 @@
 %enddef
 
 %include <typemaps/carrays.swg>
-
diff --git a/Lib/ruby/progargcargv.i b/Lib/ruby/progargcargv.i
index a2843c3..36f1c9a 100644
--- a/Lib/ruby/progargcargv.i
+++ b/Lib/ruby/progargcargv.i
@@ -3,7 +3,7 @@
 char **PROG_ARGV
 
     Some C function receive argc and argv from C main function.
-    This typemap provides ignore typemap which pass Ruby ARGV contents
+    This file provides typemaps which pass Ruby ARGV contents
     as argc and argv to C function.
 */
 
diff --git a/Lib/ruby/ruby.swg b/Lib/ruby/ruby.swg
index d133597..cf7c109 100644
--- a/Lib/ruby/ruby.swg
+++ b/Lib/ruby/ruby.swg
@@ -17,7 +17,7 @@
 /* SWIG only considers static class members with inline initializers
 	 to be constants.  For examples of what is and isn't considered
 	 a constant by SWIG see naming.i in the Ruby test suite. */
-%rename("%(uppercase)s", %$ismember, %$isvariable,%$isimmutable,%$isstatic,%$hasvalue,%$hasconsttype) ""; 
+%rename("%(uppercase)s", %$ismember, %$isvariable, %$isstatic, %$hasvalue, %$hasconsttype) "";
 
 /* Enums are mapped to constants but all we do is make sure the
    first letter is uppercase */
diff --git a/Lib/ruby/rubyautodoc.swg b/Lib/ruby/rubyautodoc.swg
index 1e6b0d9..6b0472c 100644
--- a/Lib/ruby/rubyautodoc.swg
+++ b/Lib/ruby/rubyautodoc.swg
@@ -77,7 +77,7 @@
 AUTODOC(operator<<, "Left shifting or appending operator");
 AUTODOC(operator>>, "Right shifting operator or extracting operator");
 AUTODOC(operator+, "Add operator");
-AUTODOC(operator-, "Substraction operator");
+AUTODOC(operator-, "Subtraction operator");
 AUTODOC(operator+(), "Positive operator");
 AUTODOC(operator-(), "Negation operator");
 AUTODOC(operator&, "AND operator");
@@ -93,7 +93,7 @@
 AUTODOC(__lshift__, "Left shifting or appending operator");
 AUTODOC(__rshift__, "Right shifting operator or extracting operator");
 AUTODOC(__add___, "Add operator");
-AUTODOC(__sub__, "Substraction operator");
+AUTODOC(__sub__, "Subtraction operator");
 AUTODOC(__pos__, "Positive operator");
 AUTODOC(__neg__, "Negation operator");
 AUTODOC(__and__, "AND operator");
diff --git a/Lib/ruby/rubyclasses.swg b/Lib/ruby/rubyclasses.swg
index f7b51bd..c43f38f 100644
--- a/Lib/ruby/rubyclasses.swg
+++ b/Lib/ruby/rubyclasses.swg
@@ -174,7 +174,7 @@
       return rb_inspect(_obj);
     }
 
-    static VALUE swig_rescue_swallow(VALUE)
+    static VALUE swig_rescue_swallow(VALUE, VALUE)
     {
       /*
       VALUE errstr = rb_obj_as_string(rb_errinfo());
@@ -203,12 +203,12 @@
         args.id     = op_id;
         args.nargs  = 1;
         args.target = VALUE(other);
-        ret = rb_rescue(RUBY_METHOD_FUNC(swig_rescue_funcall), VALUE(&args),
-                       (RUBY_METHOD_FUNC(swig_rescue_swallow)), Qnil);
+        ret = rb_rescue(VALUEFUNC(swig_rescue_funcall), VALUE(&args),
+                       (VALUEFUNC(swig_rescue_swallow)), Qnil);
       }
       if (ret == Qnil) {
-        VALUE a = rb_funcall(         _obj, hash_id, 0 );
-        VALUE b = rb_funcall( VALUE(other), hash_id, 0 );
+        VALUE a = rb_funcall2(         _obj, hash_id, 0, 0 );
+        VALUE b = rb_funcall2( VALUE(other), hash_id, 0, 0 );
         res = op_func(a, b);
       } else {
         res = RTEST(ret);
@@ -243,8 +243,8 @@
       args.id     = op_id;
       args.nargs  = 0;
       args.target = Qnil;
-      ret = rb_rescue(RUBY_METHOD_FUNC(swig_rescue_funcall), VALUE(&args),
-                     (RUBY_METHOD_FUNC(swig_rescue_swallow)), Qnil);
+      ret = rb_rescue(VALUEFUNC(swig_rescue_funcall), VALUE(&args),
+                     (VALUEFUNC(swig_rescue_swallow)), Qnil);
       SWIG_RUBY_THREAD_END_BLOCK;
       return ret;
     }
@@ -262,8 +262,8 @@
       args.id     = op_id;
       args.nargs  = 1;
       args.target = VALUE(other);
-      ret = rb_rescue(RUBY_METHOD_FUNC(swig_rescue_funcall), VALUE(&args),
-                     (RUBY_METHOD_FUNC(swig_rescue_swallow)), Qnil);
+      ret = rb_rescue(VALUEFUNC(swig_rescue_funcall), VALUE(&args),
+                     (VALUEFUNC(swig_rescue_swallow)), Qnil);
       SWIG_RUBY_THREAD_END_BLOCK;
       return GC_VALUE(ret);
     }
diff --git a/Lib/ruby/rubycomplex.swg b/Lib/ruby/rubycomplex.swg
index 4e249c7..d2aaf6c 100644
--- a/Lib/ruby/rubycomplex.swg
+++ b/Lib/ruby/rubycomplex.swg
@@ -36,12 +36,12 @@
 
 SWIGINTERN VALUE SWIG_Complex_Real(VALUE obj) {
   static ID real_id = rb_intern("real");
-  return rb_funcall(obj, real_id, 0);
+  return rb_funcall2(obj, real_id, 0, 0);
 }
 
 SWIGINTERN VALUE SWIG_Complex_Imaginary(VALUE obj) {
   static ID imag_id = rb_intern("imag");
-  return rb_funcall(obj, imag_id, 0);
+  return rb_funcall2(obj, imag_id, 0, 0);
 }
 }
 
@@ -127,7 +127,7 @@
     float re;
     int res = SWIG_AddCast(SWIG_AsVal(float)(o, &re));
     if (SWIG_IsOK(res)) {
-      if (val) *val = Constructor(re, 0.0);
+      if (val) *val = Constructor(re, 0.0f);
       return res;
     }
   }
diff --git a/Lib/ruby/rubycontainer.swg b/Lib/ruby/rubycontainer.swg
index 9fa205b..cd912d9 100644
--- a/Lib/ruby/rubycontainer.swg
+++ b/Lib/ruby/rubycontainer.swg
@@ -101,7 +101,7 @@
   inline Sequence*
   getslice(const Sequence* self, Difference i, Difference j) {
     typename Sequence::size_type size = self->size();
-    typename Sequence::size_type ii = swig::check_index(i, size, (i == size && j == size));
+    typename Sequence::size_type ii = swig::check_index(i, size, (i == (Difference)size && j == (Difference)size));
     typename Sequence::size_type jj = swig::slice_index(j, size);
 
     if (jj > ii) {
@@ -117,25 +117,29 @@
 
   template <class Sequence, class Difference, class InputSeq>
   inline void
-  setslice(Sequence* self, Difference i, Difference j, const InputSeq& v) {
+  setslice(Sequence* self, Difference i, Difference j, const InputSeq& is) {
     typename Sequence::size_type size = self->size();
     typename Sequence::size_type ii = swig::check_index(i, size, true);
     typename Sequence::size_type jj = swig::slice_index(j, size);
     if (jj < ii) jj = ii;
     size_t ssize = jj - ii;
-    if (ssize <= v.size()) {
+    if (ssize <= is.size()) {
+      // expanding/staying the same size
       typename Sequence::iterator sb = self->begin();
-      typename InputSeq::const_iterator vmid = v.begin();
+      typename InputSeq::const_iterator vmid = is.begin();
       std::advance(sb,ii);
       std::advance(vmid, jj - ii);
-      self->insert(std::copy(v.begin(), vmid, sb), vmid, v.end());
+      self->insert(std::copy(is.begin(), vmid, sb), vmid, is.end());
     } else {
+      // shrinking
       typename Sequence::iterator sb = self->begin();
       typename Sequence::iterator se = self->begin();
       std::advance(sb,ii);
       std::advance(se,jj);
       self->erase(sb,se);
-      self->insert(sb, v.begin(), v.end());
+      sb = self->begin();
+      std::advance(sb,ii);
+      self->insert(sb, is.begin(), is.end());
     }
   }
 
@@ -186,7 +190,7 @@
 	return swig::as<T>(item);
       } catch (const std::invalid_argument& e) {
 	char msg[1024];
-	sprintf(msg, "in sequence element %d ", _index);
+	SWIG_snprintf(msg, sizeof(msg), "in sequence element %d ", _index);
 	VALUE lastErr = rb_gv_get("$!");
 	if ( lastErr == Qnil ) {
 	  %type_error(swig::type_name<T>());
@@ -338,7 +342,7 @@
     typedef T value_type;
     typedef T* pointer;
     typedef int difference_type;
-    typedef int size_type;
+    typedef std::size_t size_type;
     typedef const pointer const_pointer;
     typedef RubySequence_InputIterator<T, reference> iterator;
     typedef RubySequence_InputIterator<T, const_reference> const_iterator;
@@ -628,7 +632,7 @@
       try {
 	r = swig::from< const Sequence* >( swig::getslice(self, i, j) );
       }
-      catch( std::out_of_range ) {
+      catch( const std::out_of_range& ) {
       }
       return r;
     }
@@ -687,9 +691,8 @@
 	r = swig::from< Sequence::value_type >( *(at) );
 	$self->erase(at); 
       }
-      catch (std::out_of_range)
-	{
-	}
+      catch (const std::out_of_range&) {
+      }
       return r;
     }
   }
@@ -757,7 +760,7 @@
       try {
 	r = swig::from< Sequence::value_type >( *(swig::cgetpos(self, i)) );
       }
-      catch( std::out_of_range ) {
+      catch( const std::out_of_range& ) {
       }
       return r;
     }
@@ -780,7 +783,7 @@
       try {
 	r = swig::from< const Sequence* >( swig::getslice(self, i, j) );
       }
-      catch( std::out_of_range ) {
+      catch( const std::out_of_range& ) {
       }
       return r;
     }
@@ -790,7 +793,7 @@
       try {
 	r = swig::from< Sequence::value_type >( *(swig::cgetpos(self, i)) );
       }
-      catch( std::out_of_range ) {
+      catch( const std::out_of_range& ) {
       }
       return r;
     }
@@ -804,9 +807,9 @@
       static ID id_start = rb_intern("begin");
       static ID id_noend = rb_intern("exclude_end?");
 
-      VALUE start = rb_funcall( i, id_start, 0 );
-      VALUE end   = rb_funcall( i, id_end, 0 );
-      bool  noend = ( rb_funcall( i, id_noend, 0 ) == Qtrue );
+      VALUE start = rb_funcall2( i, id_start, 0, 0 );
+      VALUE end   = rb_funcall2( i, id_end, 0, 0 );
+      bool  noend = ( rb_funcall2( i, id_noend, 0, 0 ) == Qtrue );
 
       int len = $self->size();
 
@@ -838,7 +841,7 @@
 	return swig::from< Sequence::value_type >( x );
       }
 
-    VALUE __setitem__(difference_type i, difference_type length, const Sequence& v) throw (std::invalid_argument) {
+    VALUE __setitem__(difference_type i, difference_type length, const Sequence& is) throw (std::invalid_argument) {
 
       if ( length < 0 )
         return Qnil;
@@ -850,13 +853,13 @@
           i = len + i;
       }
       Sequence::difference_type j = length + i;
-      if ( j > static_cast<Sequence::difference_type>(len) ) {
-        swig::resize( $self, j, *(v.begin()) );
+      if ( j > static_cast<Sequence::difference_type>(len) && is.size() > 0 ) {
+        swig::resize( $self, j, *(is.begin()) );
       }
 
       VALUE r = Qnil;
-      swig::setslice($self, i, j, v);
-      r = swig::from< const Sequence* >( &v );
+      swig::setslice($self, i, j, is);
+      r = swig::from< const Sequence* >( &is );
       return r;
     }
  }
@@ -1017,7 +1020,7 @@
 	  } else {
 	    return rubyseq.check() ? SWIG_OK : SWIG_ERROR;
 	  }
-	} catch (std::exception& e) {
+	} catch (const std::exception& e) {
 	  if (seq) {
 	    VALUE lastErr = rb_gv_get("$!");
 	    if (lastErr == Qnil) {
@@ -1057,7 +1060,7 @@
 	  } else {
 	    return true;
 	  }
-	} catch (std::exception& e) {
+	} catch (const std::exception& e) {
 	  if (seq) {
 	    VALUE lastErr = rb_gv_get("$!");
 	    if (lastErr == Qnil) {
diff --git a/Lib/ruby/rubyerrors.swg b/Lib/ruby/rubyerrors.swg
index 434544b..ad71d1d 100644
--- a/Lib/ruby/rubyerrors.swg
+++ b/Lib/ruby/rubyerrors.swg
@@ -110,7 +110,7 @@
     }
 
   str = rb_str_cat2( str, "Expected argument " );
-  sprintf( buf, "%d of type ", argn-1 );
+  SWIG_snprintf( buf, sizeof( buf), "%d of type ", argn-1 );
   str = rb_str_cat2( str, buf );
   str = rb_str_cat2( str, type );
   str = rb_str_cat2( str, ", but got " );
diff --git a/Lib/ruby/rubyhead.swg b/Lib/ruby/rubyhead.swg
index 90f07cf..39196d4 100644
--- a/Lib/ruby/rubyhead.swg
+++ b/Lib/ruby/rubyhead.swg
@@ -1,4 +1,22 @@
+#if __GNUC__ >= 7
+#pragma GCC diagnostic push
+#if defined(__cplusplus)
+#pragma GCC diagnostic ignored "-Wregister"
+#if __GNUC__ >= 10
+#pragma GCC diagnostic ignored "-Wvolatile"
+#if __GNUC__ >= 11
+#pragma GCC diagnostic ignored "-Wdeprecated-enum-enum-conversion"
+#endif
+#endif
+#endif
+#endif
+
 #include <ruby.h>
+#include <ruby/version.h> /* For RUBY_API_VERSION_CODE */
+
+#if __GNUC__ >= 7
+#pragma GCC diagnostic pop
+#endif
 
 /* Ruby 1.9.1 has a "memoisation optimisation" when compiling with GCC which
  * breaks using rb_intern as an lvalue, as SWIG does.  We work around this
@@ -98,38 +116,46 @@
 
 
 /*
- * Need to be very careful about how these macros are defined, especially
- * when compiling C++ code or C code with an ANSI C compiler.
+ * The following macros are used for providing the correct type of a
+ * function pointer to the Ruby C API.
  *
- * VALUEFUNC(f) is a macro used to typecast a C function that implements
- * a Ruby method so that it can be passed as an argument to API functions
- * like rb_define_method() and rb_define_singleton_method().
+ * Starting with Ruby 2.7 these macros act transparently due to Ruby's moving
+ * moving away from ANYARGS and instead employing strict function signatures.
  *
- * VOIDFUNC(f) is a macro used to typecast a C function that implements
- * either the "mark" or "free" stuff for a Ruby Data object, so that it
- * can be passed as an argument to API functions like Data_Wrap_Struct()
+ * Note: In case of C (not C++) the macros are transparent even before
+ * Ruby 2.7 due to the fact that the Ruby C API used function declarators
+ * with empty parentheses, which allows for an unspecified number of
+ * arguments.
+ *
+ * PROTECTFUNC(f) is used for the function pointer argument of the Ruby
+ * C API function rb_protect().
+ *
+ * VALUEFUNC(f) is used for the function pointer argument(s) of Ruby C API
+ * functions like rb_define_method() and rb_define_singleton_method().
+ *
+ * VOIDFUNC(f) is used to typecast a C function that implements either
+ * the "mark" or "free" stuff for a Ruby Data object, so that it can be
+ * passed as an argument to Ruby C API functions like Data_Wrap_Struct()
  * and Data_Make_Struct().
+ *
+ * SWIG_RUBY_VOID_ANYARGS_FUNC(f) is used for the function pointer
+ * argument(s) of Ruby C API functions like rb_define_virtual_variable().
+ *
+ * SWIG_RUBY_INT_ANYARGS_FUNC(f) is used for the function pointer
+ * argument(s) of Ruby C API functions like st_foreach().
  */
- 
-#ifdef __cplusplus
-#  ifndef RUBY_METHOD_FUNC /* These definitions should work for Ruby 1.4.6 */
-#    define PROTECTFUNC(f) ((VALUE (*)()) f)
-#    define VALUEFUNC(f) ((VALUE (*)()) f)
-#    define VOIDFUNC(f)  ((void (*)()) f)
-#  else
-#    ifndef ANYARGS /* These definitions should work for Ruby 1.6 */
-#      define PROTECTFUNC(f) ((VALUE (*)()) f)
-#      define VALUEFUNC(f) ((VALUE (*)()) f)
-#      define VOIDFUNC(f)  ((RUBY_DATA_FUNC) f)
-#    else /* These definitions should work for Ruby 1.7+ */
-#      define PROTECTFUNC(f) ((VALUE (*)(VALUE)) f)
-#      define VALUEFUNC(f) ((VALUE (*)(ANYARGS)) f)
-#      define VOIDFUNC(f)  ((RUBY_DATA_FUNC) f)
-#    endif
-#  endif
+#if defined(__cplusplus) && RUBY_API_VERSION_CODE < 20700
+#  define PROTECTFUNC(f) ((VALUE (*)(VALUE)) f)
+#  define VALUEFUNC(f) ((VALUE (*)(ANYARGS)) f)
+#  define VOIDFUNC(f) ((RUBY_DATA_FUNC) f)
+#  define SWIG_RUBY_VOID_ANYARGS_FUNC(f) ((void (*)(ANYARGS))(f))
+#  define SWIG_RUBY_INT_ANYARGS_FUNC(f) ((int (*)(ANYARGS))(f))
 #else
+#  define PROTECTFUNC(f) (f)
 #  define VALUEFUNC(f) (f)
 #  define VOIDFUNC(f) (f)
+#  define SWIG_RUBY_VOID_ANYARGS_FUNC(f) (f)
+#  define SWIG_RUBY_INT_ANYARGS_FUNC(f) (f)
 #endif
 
 /* Don't use for expressions have side effect */
diff --git a/Lib/ruby/rubykw.swg b/Lib/ruby/rubykw.swg
index 194687b..6b4685e 100644
--- a/Lib/ruby/rubykw.swg
+++ b/Lib/ruby/rubykw.swg
@@ -2,7 +2,7 @@
 #define RUBY_RUBYKW_SWG_
 
 /* Warnings for Ruby keywords */
-#define RUBYKW(x) %keywordwarn("'" `x` "' is a ruby keyword, renaming to 'C_" `x` "'",rename="C_%s",fullname=1)  `x`
+#define RUBYKW(x) %keywordwarn("'" `x` "' is a ruby keyword",rename="C_%s",fullname=1)  `x`
 
 /*
 
diff --git a/Lib/ruby/rubyprimtypes.swg b/Lib/ruby/rubyprimtypes.swg
index 3a84819..d5d9d73 100644
--- a/Lib/ruby/rubyprimtypes.swg
+++ b/Lib/ruby/rubyprimtypes.swg
@@ -10,15 +10,16 @@
 %fragment("SWIG_ruby_failed","header")
 {
 SWIGINTERN VALUE
-SWIG_ruby_failed(void)
+SWIG_ruby_failed(VALUE SWIGUNUSEDPARM(arg1), VALUE SWIGUNUSEDPARM(arg2))
 {
   return Qnil;
 } 
 }
 
 %define %ruby_aux_method(Type, Method, Action)
-SWIGINTERN VALUE SWIG_AUX_##Method##(VALUE *args)
+SWIGINTERN VALUE SWIG_AUX_##Method##(VALUE arg)
 {
+  VALUE *args = (VALUE *)arg;
   VALUE obj = args[0];
   VALUE type = TYPE(obj);
   Type *res = (Type *)(args[1]);
@@ -79,7 +80,7 @@
     VALUE a[2];
     a[0] = obj;
     a[1] = (VALUE)(&v);
-    if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2LONG), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) {
+    if (rb_rescue(VALUEFUNC(SWIG_AUX_NUM2LONG), (VALUE)a, VALUEFUNC(SWIG_ruby_failed), 0) != Qnil) {
       if (val) *val = v;
       return SWIG_OK;
     }
@@ -111,7 +112,9 @@
     VALUE a[2];
     a[0] = obj;
     a[1] = (VALUE)(&v);
-    if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2ULONG), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) {
+    if (rb_rescue(VALUEFUNC(SWIG_AUX_NUM2ULONG), (VALUE)a, VALUEFUNC(SWIG_ruby_failed), 0) != Qnil) {
+      if (rb_funcall(obj, swig_lowerthan_id, 1, INT2FIX(0)) != Qfalse)
+        return SWIG_OverflowError;
       if (val) *val = v;
       return SWIG_OK;
     }
@@ -149,7 +152,7 @@
     VALUE a[2];
     a[0] = obj;
     a[1] = (VALUE)(&v);
-    if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2LL), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) {
+    if (rb_rescue(VALUEFUNC(SWIG_AUX_NUM2LL), (VALUE)a, VALUEFUNC(SWIG_ruby_failed), 0) != Qnil) {
       if (val) *val = v;
       return SWIG_OK;
     }
@@ -187,7 +190,9 @@
     VALUE a[2];
     a[0] = obj;
     a[1] = (VALUE)(&v);
-    if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2ULL), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) {
+    if (rb_rescue(VALUEFUNC(SWIG_AUX_NUM2ULL), (VALUE)a, VALUEFUNC(SWIG_ruby_failed), 0) != Qnil) {
+      if (rb_funcall(obj, swig_lowerthan_id, 1, INT2FIX(0)) != Qfalse)
+        return SWIG_OverflowError;
       if (val) *val = v;
       return SWIG_OK;
     }
@@ -215,7 +220,7 @@
     VALUE a[2];
     a[0] = obj;
     a[1] = (VALUE)(&v);
-    if (rb_rescue(RUBY_METHOD_FUNC(SWIG_AUX_NUM2DBL), (VALUE)a, RUBY_METHOD_FUNC(SWIG_ruby_failed), 0) != Qnil) {
+    if (rb_rescue(VALUEFUNC(SWIG_AUX_NUM2DBL), (VALUE)a, VALUEFUNC(SWIG_ruby_failed), 0) != Qnil) {
       if (val) *val = v;
       return SWIG_OK;
     }
diff --git a/Lib/ruby/rubyrun.swg b/Lib/ruby/rubyrun.swg
index 4b2ffe4..d72102a 100644
--- a/Lib/ruby/rubyrun.swg
+++ b/Lib/ruby/rubyrun.swg
@@ -80,6 +80,7 @@
 /* Global IDs used to keep some internal SWIG stuff */
 static ID swig_arity_id = 0;
 static ID swig_call_id  = 0;
+static ID swig_lowerthan_id = 0;
 
 /*
   If your swig extension is to be run within an embedded ruby and has
@@ -131,7 +132,7 @@
   VALUE exceptionClass = getExceptionClass();
   if (rb_obj_is_kind_of(obj, exceptionClass)) {
     return obj;
-  }  else {
+  } else {
     return rb_exc_new3(rb_eRuntimeError, rb_obj_as_string(obj));
   }
 }
@@ -144,6 +145,7 @@
     _mSWIG = rb_define_module("SWIG");
     swig_call_id  = rb_intern("call");
     swig_arity_id = rb_intern("arity");
+    swig_lowerthan_id = rb_intern("<");
   }
 }
 
@@ -151,13 +153,14 @@
 SWIGRUNTIME void
 SWIG_Ruby_define_class(swig_type_info *type)
 {
-  char *klass_name = (char *) malloc(4 + strlen(type->name) + 1);
-  sprintf(klass_name, "TYPE%s", type->name);
+  size_t klass_len = 4 + strlen(type->name) + 1;
+  char *klass_name = (char *) malloc(klass_len);
+  SWIG_snprintf(klass_name, klass_len, "TYPE%s", type->name);
   if (NIL_P(_cSWIG_Pointer)) {
     _cSWIG_Pointer = rb_define_class_under(_mSWIG, "Pointer", rb_cObject);
     rb_undef_method(CLASS_OF(_cSWIG_Pointer), "new");
   }
-  rb_define_class_under(_mSWIG, klass_name, _cSWIG_Pointer);
+  rb_undef_alloc_func(rb_define_class_under(_mSWIG, klass_name, _cSWIG_Pointer));
   free((void *) klass_name);
 }
 
@@ -208,8 +211,9 @@
       SWIG_RubyAddTracking(ptr, obj);
     }
   } else {
-    klass_name = (char *) malloc(4 + strlen(type->name) + 1);
-    sprintf(klass_name, "TYPE%s", type->name);
+    size_t klass_len = 4 + strlen(type->name) + 1;
+    klass_name = (char *) malloc(klass_len);
+    SWIG_snprintf(klass_name, klass_len, "TYPE%s", type->name);
     klass = rb_const_get(_mSWIG, rb_intern(klass_name));
     free((void *) klass_name);
     obj = Data_Wrap_Struct(klass, 0, 0, ptr);
@@ -235,6 +239,8 @@
 SWIG_Ruby_MangleStr(VALUE obj)
 {
   VALUE stype = rb_iv_get(obj, "@__swigtype__");
+  if (NIL_P(stype))
+    return NULL;
   return StringValuePtr(stype);
 }
 
@@ -279,6 +285,11 @@
     own->own = 0;
   }
     
+  if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE)) {
+    if (!RDATA(obj)->dfree)
+      return SWIG_ERROR_RELEASE_NOT_OWNED;
+  }
+
   /* Check to see if the input object is giving up ownership
      of the underlying C struct or C++ object.  If so then we
      need to reset the destructor since the Ruby object no 
@@ -290,7 +301,7 @@
       swig_class *sklass = (swig_class *) ty->clientdata;
       track = sklass->trackObjects;
     }
-		
+
     if (track) {
       /* We are tracking objects for this class.  Thus we change the destructor
        * to SWIG_RubyRemoveTracking.  This allows us to
@@ -304,6 +315,10 @@
     }
   }
 
+  if (flags & SWIG_POINTER_CLEAR) {
+    DATA_PTR(obj) = 0;
+  }
+
   /* Do type-checking if type info was provided */
   if (ty) {
     if (ty->clientdata) {
@@ -411,6 +426,7 @@
 {
   /* register a new class */
   VALUE cl = rb_define_class("swig_runtime_data", rb_cObject);
+  rb_undef_alloc_func(cl);
   /* create and store the structure pointer to a global variable */
   swig_runtime_data_type_pointer = Data_Wrap_Struct(cl, 0, 0, pointer);
   rb_define_readonly_variable("$swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME, &swig_runtime_data_type_pointer);
@@ -441,7 +457,7 @@
 {
   if ( rb_respond_to( proc, swig_arity_id ) )
     {
-      VALUE num = rb_funcall( proc, swig_arity_id, 0 );
+      VALUE num = rb_funcall2( proc, swig_arity_id, 0, 0 );
       int arity = NUM2INT(num);
       if ( arity < 0 && (arity+1) < -minimal ) return 1;
       if ( arity == minimal ) return 1;
diff --git a/Lib/ruby/rubytracking.swg b/Lib/ruby/rubytracking.swg
index b9fb249..1edcc56 100644
--- a/Lib/ruby/rubytracking.swg
+++ b/Lib/ruby/rubytracking.swg
@@ -32,7 +32,7 @@
 */
 static st_table* swig_ruby_trackings = NULL;
 
-static VALUE swig_ruby_trackings_count(ANYARGS) {
+static VALUE swig_ruby_trackings_count(ID id, VALUE *var) {
   return SWIG2NUM(swig_ruby_trackings->num_entries);
 }
 
@@ -69,7 +69,9 @@
     swig_ruby_trackings = (st_table*)NUM2SWIG(trackings_value);
   }
 
-  rb_define_virtual_variable("SWIG_TRACKINGS_COUNT", swig_ruby_trackings_count, NULL);
+  rb_define_virtual_variable("SWIG_TRACKINGS_COUNT",
+                             VALUEFUNC(swig_ruby_trackings_count),
+                             SWIG_RUBY_VOID_ANYARGS_FUNC((rb_gvar_setter_t*)NULL));
 }
 
 /* Add a Tracking from a C/C++ struct to a Ruby object */
@@ -118,13 +120,15 @@
    to the passed callback function. */
 
 /* Proxy method to abstract the internal trackings datatype */
-static int swig_ruby_internal_iterate_callback(void* ptr, VALUE obj, void(*meth)(void* ptr, VALUE obj)) {
-  (*meth)(ptr, obj);
+static int swig_ruby_internal_iterate_callback(st_data_t ptr, st_data_t obj, st_data_t meth) {
+  ((void (*) (void *, VALUE))meth)((void *)ptr, (VALUE)obj);
   return ST_CONTINUE;
 }
 
 SWIGRUNTIME void SWIG_RubyIterateTrackings( void(*meth)(void* ptr, VALUE obj) ) {
-  st_foreach(swig_ruby_trackings, (int (*)(ANYARGS))&swig_ruby_internal_iterate_callback, (st_data_t)meth);
+  st_foreach(swig_ruby_trackings,
+             SWIG_RUBY_INT_ANYARGS_FUNC(swig_ruby_internal_iterate_callback),
+             (st_data_t)meth);
 }
 
 #ifdef __cplusplus
diff --git a/Lib/ruby/std_array.i b/Lib/ruby/std_array.i
index a4d3ef5..c00685f 100644
--- a/Lib/ruby/std_array.i
+++ b/Lib/ruby/std_array.i
@@ -41,7 +41,7 @@
     getslice(const std::array<T, N>* self, Difference i, Difference j) {
       typedef std::array<T, N> Sequence;
       typename Sequence::size_type size = self->size();
-      typename Sequence::size_type ii = swig::check_index(i, size, (i == size && j == size));
+      typename Sequence::size_type ii = swig::check_index(i, size, (i == (Difference)size && j == (Difference)size));
       typename Sequence::size_type jj = swig::slice_index(j, size);
 
       if (ii == 0 && jj == size) {
diff --git a/Lib/ruby/std_auto_ptr.i b/Lib/ruby/std_auto_ptr.i
new file mode 100644
index 0000000..3d7ae8b
--- /dev/null
+++ b/Lib/ruby/std_auto_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+  %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class auto_ptr {};
+}
diff --git a/Lib/ruby/std_map.i b/Lib/ruby/std_map.i
index 7077fa1..99e3d40 100644
--- a/Lib/ruby/std_map.i
+++ b/Lib/ruby/std_map.i
@@ -96,7 +96,7 @@
 	int res = SWIG_ERROR;
 	if ( TYPE(obj) == T_HASH ) {
 	  static ID id_to_a = rb_intern("to_a");
-	  VALUE items = rb_funcall(obj, id_to_a, 0);
+	  VALUE items = rb_funcall2(obj, id_to_a, 0, 0);
 	  res = traits_asptr_stdseq<std::map<K,T>, std::pair<K, T> >::asptr(items, val);
 	} else {
 	  map_type *p;
@@ -344,7 +344,11 @@
     }
 
     void __setitem__(const key_type& key, const mapped_type& x) throw (std::out_of_range) {
+%#ifdef __cpp_lib_map_try_emplace
+      (*self).insert_or_assign(key, x);
+%#else
       (*self)[key] = x;
+%#endif
     }
 
   VALUE inspect()
diff --git a/Lib/ruby/std_multimap.i b/Lib/ruby/std_multimap.i
index 762a876..5d8e33e 100644
--- a/Lib/ruby/std_multimap.i
+++ b/Lib/ruby/std_multimap.i
@@ -23,7 +23,7 @@
 	int res = SWIG_ERROR;
 	if ( TYPE(obj) == T_HASH ) {
 	  static ID id_to_a = rb_intern("to_a");
-	  VALUE items = rb_funcall(obj, id_to_a, 0);
+	  VALUE items = rb_funcall2(obj, id_to_a, 0, 0);
 	  return traits_asptr_stdseq<std::multimap<K,T>, std::pair<K, T> >::asptr(items, val);
 	} else {
 	  multimap_type *p;
diff --git a/Lib/ruby/std_set.i b/Lib/ruby/std_set.i
index e38702e..1b425c6 100644
--- a/Lib/ruby/std_set.i
+++ b/Lib/ruby/std_set.i
@@ -180,17 +180,14 @@
 
 // Redefine std::set iterator/reverse_iterator typemap
 %typemap(out,noblock=1) iterator, reverse_iterator {
-  $result = SWIG_NewPointerObj(swig::make_set_nonconst_iterator(%static_cast($1,const $type &),
-								self),
-			          swig::Iterator::descriptor(),SWIG_POINTER_OWN);
+  $result = SWIG_NewPointerObj((swig::make_set_nonconst_iterator<$type>($1, self)), swig::Iterator::descriptor(), SWIG_POINTER_OWN);
  }
 
 // Redefine std::set std::pair<iterator, bool> typemap
   %typemap(out,noblock=1,fragment="RubyPairBoolOutputIterator")
   std::pair<iterator, bool> {
     $result = rb_ary_new2(2);
-    rb_ary_push($result, SWIG_NewPointerObj(swig::make_set_nonconst_iterator(%static_cast($1,$type &).first),
-                                            swig::Iterator::descriptor(),SWIG_POINTER_OWN));
+    rb_ary_push($result, SWIG_NewPointerObj((swig::make_set_nonconst_iterator($1.first)), swig::Iterator::descriptor(), SWIG_POINTER_OWN));
     rb_ary_push($result, SWIG_From(bool)(%static_cast($1,const $type &).second));
    }
 
diff --git a/Lib/ruby/std_shared_ptr.i b/Lib/ruby/std_shared_ptr.i
index dee35ec..086e308 100644
--- a/Lib/ruby/std_shared_ptr.i
+++ b/Lib/ruby/std_shared_ptr.i
@@ -13,24 +13,27 @@
   template <class Type>
   struct traits_asptr<std::shared_ptr<Type> > {
     static int asptr(VALUE obj, std::shared_ptr<Type> **val) {
-      std::shared_ptr<Type> *p = 0;
+      int res = SWIG_ERROR;
       swig_type_info *descriptor = type_info<std::shared_ptr<Type> >();
-      swig_ruby_owntype newmem = {0, 0};
-      int res = descriptor ? SWIG_ConvertPtrAndOwn(obj, (void **)&p, descriptor, 0, &newmem) : SWIG_ERROR;
-      if (SWIG_IsOK(res)) {
-	if (val) {
-	  if (*val) {
-	    **val = p ? *p : std::shared_ptr<Type>();
-	  } else {
-	    *val = p;
-	    if (newmem.own & SWIG_CAST_NEW_MEMORY) {
-	      // Upcast for pointers to shared_ptr in this generic framework has not been implemented
-	      res = SWIG_ERROR;
-	    }
-	  }
-	}
-	if (newmem.own & SWIG_CAST_NEW_MEMORY)
-	  delete p;
+      if (val) {
+        std::shared_ptr<Type> *p = 0;
+        swig_ruby_owntype newmem = {0, 0};
+        res = descriptor ? SWIG_ConvertPtrAndOwn(obj, (void **)&p, descriptor, 0, &newmem) : SWIG_ERROR;
+        if (SWIG_IsOK(res)) {
+          if (*val) {
+            **val = p ? *p : std::shared_ptr<Type>();
+          } else {
+            *val = p;
+            if (newmem.own & SWIG_CAST_NEW_MEMORY) {
+              // Upcast for pointers to shared_ptr in this generic framework has not been implemented
+              res = SWIG_ERROR;
+            }
+          }
+          if (newmem.own & SWIG_CAST_NEW_MEMORY)
+            delete p;
+        }
+      } else {
+        res = descriptor ? SWIG_ConvertPtr(obj, 0, descriptor, 0) : SWIG_ERROR;
       }
       return res;
     }
diff --git a/Lib/ruby/std_string_view.i b/Lib/ruby/std_string_view.i
new file mode 100644
index 0000000..cbfc428
--- /dev/null
+++ b/Lib/ruby/std_string_view.i
@@ -0,0 +1,6 @@
+
+%warnfilter(SWIGWARN_RUBY_WRONG_NAME) std::basic_string_view<char>;
+
+AUTODOC(substr, "Return a portion of the String");
+
+%include <typemaps/std_string_view.swg>
diff --git a/Lib/ruby/std_unique_ptr.i b/Lib/ruby/std_unique_ptr.i
new file mode 100644
index 0000000..f988714
--- /dev/null
+++ b/Lib/ruby/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+  %set_output(SWIG_NewPointerObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN | %newpointer_flags));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class unique_ptr {};
+}
diff --git a/Lib/ruby/std_unordered_map.i b/Lib/ruby/std_unordered_map.i
index 48c8752..3c6b650 100644
--- a/Lib/ruby/std_unordered_map.i
+++ b/Lib/ruby/std_unordered_map.i
@@ -23,7 +23,7 @@
 	int res = SWIG_ERROR;
 	if (TYPE(obj) == T_HASH) {
 	  static ID id_to_a = rb_intern("to_a");
-	  VALUE items = rb_funcall(obj, id_to_a, 0);
+	  VALUE items = rb_funcall2(obj, id_to_a, 0, 0);
 	  res = traits_asptr_stdseq<std::unordered_map<K,T,Hash,Compare,Alloc>, std::pair<K, T> >::asptr(items, val);
 	} else {
 	  map_type *p;
diff --git a/Lib/ruby/std_unordered_multimap.i b/Lib/ruby/std_unordered_multimap.i
index ebc53b5..c3261f9 100644
--- a/Lib/ruby/std_unordered_multimap.i
+++ b/Lib/ruby/std_unordered_multimap.i
@@ -23,7 +23,7 @@
 	int res = SWIG_ERROR;
 	if ( TYPE(obj) == T_HASH ) {
 	  static ID id_to_a = rb_intern("to_a");
-	  VALUE items = rb_funcall(obj, id_to_a, 0);
+	  VALUE items = rb_funcall2(obj, id_to_a, 0, 0);
 	  return traits_asptr_stdseq<std::unordered_multimap<K,T,Hash,Compare,Alloc>, std::pair<K, T> >::asptr(items, val);
 	} else {
 	  multimap_type *p;
diff --git a/Lib/ruby/std_wstring.i b/Lib/ruby/std_wstring.i
index 2b63343..c5d168a 100644
--- a/Lib/ruby/std_wstring.i
+++ b/Lib/ruby/std_wstring.i
@@ -1,4 +1,15 @@
 %{
+#if defined(__linux__)
+#include <endian.h>
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define SWIG_RUBY_ENDIAN "LE"
+#elif BYTE_ORDER == BIG_ENDIAN
+#define SWIG_RUBY_ENDIAN "BE"
+#endif
+#else
+#define SWIG_RUBY_ENDIAN "LE"
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -15,9 +26,9 @@
 #ifndef SWIG_RUBY_WSTRING_ENCODING
 
 #if WCHAR_MAX == 0x7fff || WCHAR_MAX == 0xffff
-#define SWIG_RUBY_WSTRING_ENCODING "UTF-16LE"
+#define SWIG_RUBY_WSTRING_ENCODING "UTF-16" SWIG_RUBY_ENDIAN
 #elif WCHAR_MAX == 0x7fffffff || WCHAR_MAX == 0xffffffff
-#define SWIG_RUBY_WSTRING_ENCODING "UTF-32LE"
+#define SWIG_RUBY_WSTRING_ENCODING "UTF-32" SWIG_RUBY_ENDIAN
 #else
 #error unsupported wchar_t size. SWIG_RUBY_WSTRING_ENCODING must be given.
 #endif
diff --git a/Lib/ruby/swigmove.i b/Lib/ruby/swigmove.i
new file mode 100644
index 0000000..62ecca7
--- /dev/null
+++ b/Lib/ruby/swigmove.i
@@ -0,0 +1 @@
+%include <typemaps/swigmove.swg>
diff --git a/Lib/ruby/timeval.i b/Lib/ruby/timeval.i
index e7bc2d3..94a75c8 100644
--- a/Lib/ruby/timeval.i
+++ b/Lib/ruby/timeval.i
@@ -55,7 +55,7 @@
     if (NIL_P($input))
 	$1 = (time_t)-1;
     else
-	$1 = NUM2LONG(rb_funcall($input, rb_intern("tv_sec"), 0));
+	$1 = NUM2LONG(rb_funcall2($input, rb_intern("tv_sec"), 0, 0));
 }
 
 %typemap(typecheck) time_t
diff --git a/Lib/ruby/typemaps.i b/Lib/ruby/typemaps.i
index c4db821..a3eaa0c 100644
--- a/Lib/ruby/typemaps.i
+++ b/Lib/ruby/typemaps.i
@@ -119,7 +119,7 @@
          
 For example, suppose you were trying to wrap the modf() function in the
 C math library which splits x into integral and fractional parts (and
-returns the integer part in one of its parameters).K:
+returns the integer part in one of its parameters) :
 
         double modf(double x, double *ip);
 
@@ -139,7 +139,7 @@
 */
 
 %define OUTPUT_TYPEMAP(type, converter, convtype)
-%typemap(in,numinputs=0) type *OUTPUT($*1_ltype temp), type &OUTPUT($*1_ltype temp) "$1 = &temp;";
+%typemap(in,numinputs=0) type *OUTPUT($*1_ltype temp), type &OUTPUT($*1_ltype temp) "$1 = &temp;"
 %typemap(argout, fragment="output_helper") type *OUTPUT, type &OUTPUT {
    VALUE o = converter(convtype (*$1));
    $result = output_helper($result, o);
@@ -161,7 +161,7 @@
 
 #undef OUTPUT_TYPEMAP
 
-%typemap(in,numinputs=0) bool *OUTPUT(bool temp), bool &OUTPUT(bool temp) "$1 = &temp;";
+%typemap(in,numinputs=0) bool *OUTPUT(bool temp), bool &OUTPUT(bool temp) "$1 = &temp;"
 %typemap(argout, fragment="output_helper") bool *OUTPUT, bool &OUTPUT {
     VALUE o = (*$1) ? Qtrue : Qfalse;
     $result = output_helper($result, o);
@@ -214,10 +214,6 @@
 
        x = neg(x)
 
-Note : previous versions of SWIG used the symbol 'BOTH' to mark
-input/output arguments.   This is still supported, but will be slowly
-phased out in future releases.
-
 */
 
 %typemap(in) int *INOUT = int *INPUT;
diff --git a/Lib/scilab/argcargv.i b/Lib/scilab/argcargv.i
new file mode 100644
index 0000000..9aeda1a
--- /dev/null
+++ b/Lib/scilab/argcargv.i
@@ -0,0 +1,109 @@
+/* -------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------- */
+
+%{
+SWIGINTERN int SWIG_AsVal_strings (SwigSciObject iVar, int **array, int report) {
+  int iType = 0;
+  SciErr sciErr = getVarAddressFromPosition(pvApiCtx, iVar, array);
+  if (sciErr.iErr) {
+    if (report) printError(&sciErr, 0);
+    return SWIG_ERROR;
+  }
+  sciErr = getVarType(pvApiCtx, *array, &iType);
+  if (sciErr.iErr) {
+    if (report) printError(&sciErr, 0);
+    return SWIG_ERROR;
+  }
+  if (iType != sci_strings) {
+    /* An empty matrix has type sci_matrix. */
+    if (!isEmptyMatrix(pvApiCtx, *array)) {
+      return SWIG_TypeError;
+    }
+    *array = SWIG_NULLPTR;
+  }
+  return SWIG_OK;
+}
+%}
+
+%typemap(in) (int ARGC, char **ARGV) {
+  SciErr sciErr;
+  size_t memsize;
+  int i, rows, cols, res, len, *aLen, *array;
+  res = SWIG_AsVal_strings ($input, &array, 1);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_TypeError) {
+      SWIG_exception_fail(SWIG_TypeError, "not a string matrix");
+    }
+    SWIG_fail;
+  }
+
+  if (array == SWIG_NULLPTR) {
+    /* Special case for empty matrix. */
+    $1 = 0;
+    $2 = ($2_ltype) malloc(sizeof($*2_ltype));
+    $2[0] = SWIG_NULLPTR;
+  } else {
+    /* first call to retrieve dimensions */
+    rows = 0;
+    cols = 0;
+    sciErr = getMatrixOfString(pvApiCtx, array, &rows, &cols, SWIG_NULLPTR, SWIG_NULLPTR);
+    if (sciErr.iErr) {
+      printError(&sciErr, 0);
+      SWIG_fail;
+    }
+    len = rows * cols;
+    memsize = sizeof(int) * len;
+    aLen = (int*)malloc(memsize);
+    if (aLen == SWIG_NULLPTR) {
+      SWIG_exception_fail(SWIG_MemoryError, "fail allocate sizes array");
+    }
+    memset(aLen, 0, memsize);
+    /*second call to retrieve length of each string */
+    sciErr = getMatrixOfString(pvApiCtx, array, &rows, &cols, aLen, SWIG_NULLPTR);
+    if (sciErr.iErr) {
+      printError(&sciErr, 0);
+      free((void *)aLen);
+      SWIG_fail;
+    }
+    memsize = sizeof($*2_ltype) * (len + 1);
+    $1 = ($1_ltype) len;
+    $2 = ($2_ltype) malloc(memsize);
+    if ($2 == SWIG_NULLPTR) {
+      free((void *)aLen);
+      SWIG_exception_fail(SWIG_MemoryError, "fail allocate array");
+    }
+    memset($2, 0, memsize);
+    for(i = 0 ; i < len ; i++) {
+      $2[i] = ($*2_ltype)malloc(aLen[i] + 1);
+      if ($2[i] == SWIG_NULLPTR) {
+        free((void *)aLen);
+        SWIG_exception_fail(SWIG_MemoryError, "fail allocate array string element");
+      }
+    }
+    /* third call to retrieve data */
+    sciErr = getMatrixOfString(pvApiCtx, array, &rows, &cols, aLen, $2);
+    if(sciErr.iErr) {
+      printError(&sciErr, 0);
+      free((void *)aLen);
+      SWIG_fail;
+    }
+    $2[len] = SWIG_NULLPTR;
+    free((void *)aLen);
+  }
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+  int *array;
+  $1 = SWIG_IsOK(SWIG_AsVal_strings ($input, &array, 0));
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+  if ($2 != SWIG_NULLPTR) {
+    $1_ltype i;
+    for (i = 0; i < $1; i++) {
+      free((void *)$2[i]);
+    }
+    free((void *)$2);
+  }
+}
diff --git a/Lib/scilab/boost_shared_ptr.i b/Lib/scilab/boost_shared_ptr.i
index 668bf43..87c89b5 100644
--- a/Lib/scilab/boost_shared_ptr.i
+++ b/Lib/scilab/boost_shared_ptr.i
@@ -35,7 +35,7 @@
   }
 }
 %typemap(out) CONST TYPE {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
   %set_output(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
@@ -54,12 +54,12 @@
   }
 }
 %typemap(varout) CONST TYPE {
-  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartresult = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype($1));
   %set_varoutput(SWIG_NewPointerObj(%as_voidptr(smartresult), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN));
 }
 
 %typemap(directorin,noblock=1) CONST TYPE (SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE > *smartarg = 0) %{
-  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(($1_ltype &)$1));
+  smartarg = new SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< CONST TYPE >(new $1_ltype(SWIG_STD_MOVE($1)));
   $input = SWIG_NewPointerObj(%as_voidptr(smartarg), $descriptor(SWIG_SHARED_PTR_QNAMESPACE::shared_ptr< TYPE > *), SWIG_POINTER_OWN | %newpointer_flags);
 %}
 %typemap(directorout,noblock=1) CONST TYPE (void *swig_argp, int swig_res = 0) {
diff --git a/Lib/scilab/sciarray.swg b/Lib/scilab/sciarray.swg
index c00e383..97b30a2 100644
--- a/Lib/scilab/sciarray.swg
+++ b/Lib/scilab/sciarray.swg
@@ -40,8 +40,8 @@
   }
   else {
     char errmsg[100];
-    sprintf(errmsg, "Size of input data (%d) is too big (maximum is %d)",
-      iRows*iCols, $1_dim0);
+    SWIG_snprintf2(errmsg, sizeof(errmsg), "Size of input data (%d) is too big (maximum is %d)",
+                   iRows*iCols, $1_dim0);
     SWIG_exception_fail(SWIG_OverflowError, errmsg);
   }
 }
diff --git a/Lib/scilab/scidouble.swg b/Lib/scilab/scidouble.swg
index 1b82633..e14c846 100644
--- a/Lib/scilab/scidouble.swg
+++ b/Lib/scilab/scidouble.swg
@@ -56,6 +56,7 @@
 SWIGINTERN int
 SWIG_SciDouble_AsDoubleArrayAndSize(void *pvApiCtx, int iVar, int *iRows, int *iCols, double **pdValue, char *fname) {
   SciErr sciErr;
+  int iType = 0;
   int *piAddrVar = NULL;
 
   sciErr = getVarAddressFromPosition(pvApiCtx, iVar, &piAddrVar);
@@ -64,13 +65,24 @@
     return SWIG_ERROR;
   }
 
-  if (isDoubleType(pvApiCtx, piAddrVar) && !isVarComplex(pvApiCtx, piAddrVar)) {
+  sciErr = getVarType(pvApiCtx, piAddrVar, &iType);
+  if (sciErr.iErr) {
+    printError(&sciErr, 0);
+    return SWIG_ERROR;
+  }
+
+  if (iType == sci_matrix && !isVarComplex(pvApiCtx, piAddrVar)) {
     sciErr = getMatrixOfDouble(pvApiCtx, piAddrVar, iRows, iCols, pdValue);
     if (sciErr.iErr) {
       printError(&sciErr, 0);
       return SWIG_ERROR;
     }
   }
+  else if (iType == sci_implicit_poly) {
+    *iRows = -1;
+    *iCols = 0;
+    *pdValue = NULL;
+  }
   else {
     Scierror(SCILAB_API_ARGUMENT_ERROR, _("%s: Wrong type for input argument #%d: A real matrix expected.\n"), fname, iVar);
     return SWIG_ERROR;
diff --git a/Lib/scilab/scienum.swg b/Lib/scilab/scienum.swg
index 54ec1f8..cc1f7c9 100644
--- a/Lib/scilab/scienum.swg
+++ b/Lib/scilab/scienum.swg
@@ -18,7 +18,7 @@
 }
 
 %fragment(SWIG_From_frag(Enum), "header", fragment="SWIG_Int_FromEnum") {
-%#define SWIG_From_Enum(scilabValue) SWIG_Int_FromEnum(pvApiCtx, SWIG_Scilab_GetOutputPosition(), scilabValue, SWIG_Scilab_GetFuncName())
+%#define SWIG_From_Enum(scilabValue) SWIG_Int_FromEnum(pvApiCtx, SWIG_Scilab_GetOutputPosition(), (int)scilabValue, SWIG_Scilab_GetFuncName())
 }
 %fragment("SWIG_Int_FromEnum", "header", fragment="SWIG_SciDouble_FromInt") {
 SWIGINTERN int
diff --git a/Lib/scilab/sciexception.swg b/Lib/scilab/sciexception.swg
index 1d653b3..9b842cf 100644
--- a/Lib/scilab/sciexception.swg
+++ b/Lib/scilab/sciexception.swg
@@ -17,20 +17,20 @@
                             size_t, size_t&,
                             ptrdiff_t, ptrdiff_t& {
   char obj[20];
-  sprintf(obj, "%d", (int)$1);
+  SWIG_snprintf(obj, sizeof(obj), "%d", (int)$1);
   SWIG_Scilab_Raise_Ex(obj, "$type", $descriptor);
 }
 
 %typemap(throws, noblock=1) enum SWIGTYPE {
   char obj[20];
-  sprintf(obj, "%d", (int)$1);
+  SWIG_snprintf(obj, sizeof(obj), "%d", (int)$1);
   SWIG_Scilab_Raise_Ex(obj, "$type", $descriptor);
 }
 
 %typemap(throws, noblock=1) float, double,
                             float&, double& {
   char obj[20];
-  sprintf(obj, "%5.3f", (double)$1);
+  SWIG_snprintf(obj, sizeof(obj), "%5.3f", (double)$1);
   SWIG_Scilab_Raise_Ex(obj, "$type", $descriptor);
 }
 
@@ -44,7 +44,8 @@
 
 %typemap(throws, noblock=1) char, char& {
   char obj[2];
-  sprintf(obj, "%c", (char)$1);
+  obj[0] = (char)$1;
+  obj[1] = 0;
   SWIG_Scilab_Raise_Ex(obj, "$type", $descriptor);
 }
 
diff --git a/Lib/scilab/sciint.swg b/Lib/scilab/sciint.swg
index 2d69935..b7b2563 100644
--- a/Lib/scilab/sciint.swg
+++ b/Lib/scilab/sciint.swg
@@ -157,6 +157,11 @@
       return SWIG_ERROR;
     }
   }
+  else if (iType == sci_implicit_poly) {
+    *iRows = -1;
+    *iCols = 0;
+    *piValue = NULL;
+  }
   else {
     Scierror(SCILAB_API_ARGUMENT_ERROR, _("%s: Wrong type for input argument #%d: A 32-bit signed integer or a double matrix expected.\n"), fname, iVar);
     return SWIG_ERROR;
diff --git a/Lib/scilab/scimatrixdouble.swg b/Lib/scilab/scimatrixdouble.swg
index 9444a80..bb9403e 100644
--- a/Lib/scilab/scimatrixdouble.swg
+++ b/Lib/scilab/scimatrixdouble.swg
@@ -28,7 +28,11 @@
 %typemap(in, noblock=1, fragment="SWIG_SciDouble_AsDoubleArrayAndSize") (double *IN, int IN_SIZE) (int rowCount, int colCount)
 {
   if (SWIG_SciDouble_AsDoubleArrayAndSize(pvApiCtx, $input, &rowCount, &colCount, &$1, fname) == SWIG_OK) {
-	$2 = rowCount * colCount;
+    if (rowCount < 0) {
+      $2 = rowCount;
+    } else {
+      $2 = rowCount * colCount;
+    }
   }
   else {
 	return SWIG_ERROR;
@@ -40,7 +44,11 @@
 %typemap(in, noblock=1, fragment="SWIG_SciDouble_AsDoubleArrayAndSize") (int IN_SIZE, double *IN) (int rowCount, int colCount)
 {
   if (SWIG_SciDouble_AsDoubleArrayAndSize(pvApiCtx, $input, &rowCount, &colCount, &$2, fname) == SWIG_OK) {
-    $1 = rowCount * colCount;
+    if (rowCount < 0) {
+      $1 = rowCount;
+    } else {
+      $1 = rowCount * colCount;
+    }
   }
   else {
     return SWIG_ERROR;
diff --git a/Lib/scilab/scimatrixint.swg b/Lib/scilab/scimatrixint.swg
index e304d4f..0577107 100644
--- a/Lib/scilab/scimatrixint.swg
+++ b/Lib/scilab/scimatrixint.swg
@@ -30,7 +30,11 @@
 %typemap(in, noblock=1, fragment="SWIG_SciDoubleOrInt32_AsIntArrayAndSize") (int *IN, int IN_SIZE) (int rowCount, int colCount)
 {
   if (SWIG_SciDoubleOrInt32_AsIntArrayAndSize(pvApiCtx, $input, &rowCount, &colCount, &$1, fname) == SWIG_OK) {
-    $2 = rowCount * colCount;
+    if (rowCount < 0) {
+      $2 = rowCount;
+    } else {
+      $2 = rowCount * colCount;
+    }
   }
   else {
     return SWIG_ERROR;
@@ -43,7 +47,11 @@
 %typemap(in, noblock=1, fragment="SWIG_SciDoubleOrInt32_AsIntArrayAndSize") (int IN_SIZE, int *IN) (int rowCount, int colCount)
 {
   if (SWIG_SciDoubleOrInt32_AsIntArrayAndSize(pvApiCtx, $input, &rowCount, &colCount, &$2, fname) == SWIG_OK) {
-	$1 = rowCount * colCount;
+    if (rowCount < 0) {
+      $1 = rowCount;
+    } else {
+      $1 = rowCount * colCount;
+    }
   }
   else {
 	return SWIG_ERROR;
diff --git a/Lib/scilab/scirun.swg b/Lib/scilab/scirun.swg
index 51df9a5..481aac7 100644
--- a/Lib/scilab/scirun.swg
+++ b/Lib/scilab/scirun.swg
@@ -5,7 +5,6 @@
 /* Scilab version macro */
 
 #include "version.h"
-#define SWIG_SCILAB_VERSION (SCI_VERSION_MAJOR * 100) + (SCI_VERSION_MINOR * 10) + SCI_VERSION_MAINTENANCE
 
 /* Scilab standard headers */
 
@@ -13,11 +12,11 @@
 extern "C" {
 #endif
 #include "api_scilab.h"
-#if SWIG_SCILAB_VERSION < 540
+#if SCI_VERSION_MAJOR < 5 || SCI_VERSION_MAJOR == 5 && SCI_VERSION_MINOR < 4
 #define __USE_DEPRECATED_STACK_FUNCTIONS__
 #include "stack-c.h"
 #endif
-#if SWIG_SCILAB_VERSION < 600
+#if SCI_VERSION_MAJOR < 6
 #include "MALLOC.h"
 #endif
 #include "Scierror.h"
@@ -31,12 +30,12 @@
 
 /* Gateway signature */
 
-#if SWIG_SCILAB_VERSION >= 600
-#define SWIG_GatewayParameters char* fname, void *pvApiCtx
-#define SWIG_GatewayArguments fname, pvApiCtx
-#else
+#if SCI_VERSION_MAJOR < 6
 #define SWIG_GatewayParameters char* fname, unsigned long fname_len
 #define SWIG_GatewayArguments fname, fname_len
+# else
+#define SWIG_GatewayParameters char* fname, void *pvApiCtx
+#define SWIG_GatewayArguments fname, pvApiCtx
 #endif
 
 /* Function name management functions */
@@ -47,10 +46,8 @@
   return SwigFuncName;
 }
 static void SWIG_Scilab_SetFuncName(char *funcName) {
-  if (SwigFuncName != NULL) {
-    free(SwigFuncName);
-    SwigFuncName = NULL;
-  }
+  free(SwigFuncName);
+  SwigFuncName = NULL;
   if (funcName) {
     SwigFuncName = (char *)malloc(strlen(funcName) + 1);
     if (SwigFuncName)
@@ -60,29 +57,29 @@
 
 /* Api context management functions */
 
-#if SWIG_SCILAB_VERSION >= 600
+#if SCI_VERSION_MAJOR < 6
+#define SWIG_Scilab_SetApiContext(apiCtx)
+#else
 static void *pvApiCtx = NULL;
 static void SWIG_Scilab_SetApiContext(void *apiCtx) {
   pvApiCtx = apiCtx;
 }
-#else
-#define SWIG_Scilab_SetApiContext(apiCtx)
 #endif
 
 /* Argument management functions */
 
-#if SWIG_SCILAB_VERSION >= 540
-#define SWIG_CheckInputArgument(pvApiCtx, minInputArgument, maxInputArgument) CheckInputArgument(pvApiCtx, minInputArgument, maxInputArgument)
-#define SWIG_CheckInputArgumentAtLeast(pvApiCtx, minInputArgument) CheckInputArgumentAtLeast(pvApiCtx, minInputArgument)
-#define SWIG_CheckOutputArgument(pvApiCtx, minOutputArgument, maxOutputArgument) CheckOutputArgument(pvApiCtx, minOutputArgument, maxOutputArgument)
-#define SWIG_NbInputArgument(pvApiCtx) nbInputArgument(pvApiCtx)
-#define SWIG_AssignOutputArgument(pvApiCtx, outputArgumentPos, argumentPos) AssignOutputVariable(pvApiCtx, outputArgumentPos) = argumentPos
-#else
+#if SCI_VERSION_MAJOR < 5 || SCI_VERSION_MAJOR == 5 && SCI_VERSION_MINOR < 4
 #define SWIG_CheckInputArgument(pvApiCtx, minInputArgument, maxInputArgument) CheckRhs(minInputArgument, maxInputArgument)
 #define SWIG_CheckInputArgumentAtLeast(pvApiCtx, minInputArgument) CheckRhs(minInputArgument, 256)
 #define SWIG_CheckOutputArgument(pvApiCtx, minOutputArgument, maxOutputArgument) CheckLhs(minOutputArgument, maxOutputArgument)
 #define SWIG_NbInputArgument(pvApiCtx) Rhs
 #define SWIG_AssignOutputArgument(pvApiCtx, outputArgumentPos, argumentPos) LhsVar(outputArgumentPos) = argumentPos
+#else
+#define SWIG_CheckInputArgument(pvApiCtx, minInputArgument, maxInputArgument) CheckInputArgument(pvApiCtx, minInputArgument, maxInputArgument)
+#define SWIG_CheckInputArgumentAtLeast(pvApiCtx, minInputArgument) CheckInputArgumentAtLeast(pvApiCtx, minInputArgument)
+#define SWIG_CheckOutputArgument(pvApiCtx, minOutputArgument, maxOutputArgument) CheckOutputArgument(pvApiCtx, minOutputArgument, maxOutputArgument)
+#define SWIG_NbInputArgument(pvApiCtx) nbInputArgument(pvApiCtx)
+#define SWIG_AssignOutputArgument(pvApiCtx, outputArgumentPos, argumentPos) AssignOutputVariable(pvApiCtx, outputArgumentPos) = argumentPos
 #endif
 
 typedef int SwigSciObject;
@@ -436,7 +433,7 @@
 #ifdef __cplusplus
 extern "C"
 #endif
-int SWIG_this(SWIG_GatewayParameters) {
+SWIGEXPORT int SWIG_this(SWIG_GatewayParameters) {
   void *ptrValue = NULL;
   if (SwigScilabPtrToObject(pvApiCtx, 1, &ptrValue, NULL, 0, fname) == SWIG_OK) {
     SWIG_Scilab_SetOutputPosition(1);
@@ -453,7 +450,7 @@
 #ifdef __cplusplus
 extern "C"
 #endif
-int SWIG_ptr(SWIG_GatewayParameters) {
+SWIGEXPORT int SWIG_ptr(SWIG_GatewayParameters) {
   if (SWIG_NbInputArgument(pvApiCtx) > 0) {
     SciErr sciErr;
     int *piAddrVar1 = NULL;
diff --git a/Lib/scilab/sciruntime.swg b/Lib/scilab/sciruntime.swg
index 3de138e..e772926 100644
--- a/Lib/scilab/sciruntime.swg
+++ b/Lib/scilab/sciruntime.swg
@@ -40,7 +40,7 @@
 #ifdef __cplusplus
 extern "C"
 #endif
-int <module>_Init(SWIG_GatewayParameters) {
+SWIGEXPORT int SWIG_<module>_Init(SWIG_GatewayParameters) {
   SWIG_InitializeModule(NULL);
   SWIG_CreateScilabVariables(pvApiCtx);
   swig_module_initialized = 1;
diff --git a/Lib/scilab/std_map.i b/Lib/scilab/std_map.i
index 07eb63f..aeede60 100644
--- a/Lib/scilab/std_map.i
+++ b/Lib/scilab/std_map.i
@@ -47,7 +47,11 @@
                     throw std::out_of_range("key not found");
             }
             void set(const K& key, const T& x) {
+%#ifdef __cpp_lib_map_try_emplace
+                (*self).insert_or_assign(key, x);
+%#else
                 (*self)[key] = x;
+%#endif
             }
             void del(const K& key) throw (std::out_of_range) {
                 std::map< K, T, C >::iterator i = self->find(key);
@@ -63,17 +67,4 @@
         }
     };
 
-// Legacy macros (deprecated)
-%define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_key ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_value ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO)
-#warning "specialize_std_map_on_both ignored - macro is deprecated and no longer necessary"
-%enddef
-
 }
diff --git a/Lib/scilab/std_string.i b/Lib/scilab/std_string.i
index 71ac6d2..8736c2a 100644
--- a/Lib/scilab/std_string.i
+++ b/Lib/scilab/std_string.i
@@ -37,3 +37,11 @@
 }
 
 %include <typemaps/std_string.swg>
+
+%typemap(throws, noblock=1) std::string {
+  SWIG_Scilab_Raise_Ex($1.c_str(), "$type", $&descriptor);
+}
+
+%typemap(throws, noblock=1) const std::string & {
+  SWIG_Scilab_Raise_Ex($1.c_str(), "$type", $descriptor);
+}
diff --git a/Lib/scilab/swigmove.i b/Lib/scilab/swigmove.i
new file mode 100644
index 0000000..62ecca7
--- /dev/null
+++ b/Lib/scilab/swigmove.i
@@ -0,0 +1 @@
+%include <typemaps/swigmove.swg>
diff --git a/Lib/shared_ptr.i b/Lib/shared_ptr.i
index eada0b9..b450229 100644
--- a/Lib/shared_ptr.i
+++ b/Lib/shared_ptr.i
@@ -55,15 +55,3 @@
 SWIG_SHARED_PTR_TYPEMAPS(, TYPE)
 SWIG_SHARED_PTR_TYPEMAPS(const, TYPE)
 %enddef
-
-// Legacy macros
-%define SWIG_SHARED_PTR(PROXYCLASS, TYPE...)
-#warning "SWIG_SHARED_PTR(PROXYCLASS, TYPE) is deprecated. Please use %shared_ptr(TYPE) instead."
-%shared_ptr(TYPE)
-%enddef
-
-%define SWIG_SHARED_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE...)
-#warning "SWIG_SHARED_PTR_DERIVED(PROXYCLASS, BASECLASSTYPE, TYPE) is deprecated. Please use %shared_ptr(TYPE) instead."
-%shared_ptr(TYPE)
-%enddef
-
diff --git a/Lib/std/std_basic_string.i b/Lib/std/std_basic_string.i
index fb7afc1..e95cb47 100644
--- a/Lib/std/std_basic_string.i
+++ b/Lib/std/std_basic_string.i
@@ -55,7 +55,16 @@
 
     size_type capacity() const;
 
-    void reserve(size_type __res_arg = 0);
+    void reserve(size_type __res_arg);
+    %extend {
+      void shrink_to_fit() {
+        %#if __cplusplus >= 202002L
+          self->shrink_to_fit();
+        %#else
+          self->reserve();
+        %#endif
+      }
+    }
 
 
     // Modifiers:
diff --git a/Lib/std/std_carray.swg b/Lib/std/std_carray.swg
deleted file mode 100644
index de2a076..0000000
--- a/Lib/std/std_carray.swg
+++ /dev/null
@@ -1,64 +0,0 @@
-%{
-#include <algorithm>
-%}
-
-//
-// std::carray - is really an extension to the 'std' namespace.
-// 
-// A simple fix C array wrapper, more or less as presented in
-//
-//   "The C++ Standarf Library", by Nicolai M. Josuttis
-//
-// which is also derived from the example in
-//
-//   "The C++ Programming Language", by Bjarne Stroustup.
-//
-
-%inline %{
-namespace std {    
-  template <class _Type, size_t _Size>
-  class carray 
-  {
-  public:
-    typedef _Type value_type;    
-    typedef size_t size_type;
-    
-    typedef _Type * iterator;
-    typedef const _Type * const_iterator;
-    
-    carray() { }
-    
-    carray(const carray& other) {
-      std::copy(other.v, other.v + size(), v);
-    }
-    
-    template <class _Iterator>
-    carray(_Iterator first, _Iterator last) {
-      assign(first, last);
-    }
-
-    iterator begin() { return v; }
-    iterator end() { return v + _Size; }
-
-    const_iterator begin() const { return v; }
-    const_iterator end() const { return v + _Size; }
-    
-    _Type& operator[](size_t i) { return v[i]; }
-    const _Type& operator[](size_t i) const { return v[i]; }
-
-    static size_t size() { return _Size; }    
-
-    template <class _Iterator>
-    void assign(_Iterator first, _Iterator last)  {
-      if (std::distance(first,last) == size()) {
-	std::copy(first, last, v);
-      } else {
-	throw std::length_error("bad range length");
-      }
-    }
-      
-  private:
-    _Type v[_Size];
-  };
-}
-%}
diff --git a/Lib/std/std_iostream.i b/Lib/std/std_iostream.i
index 38a2296..4c12698 100644
--- a/Lib/std/std_iostream.i
+++ b/Lib/std/std_iostream.i
@@ -264,6 +264,14 @@
     seekg(off_type, ios_base::seekdir);
   };  
 
+  %template(ostream) basic_ostream<char>;
+  %template(istream) basic_istream<char>;
+
+#if defined(SWIG_WCHAR)
+  %template(wostream) basic_ostream<wchar_t>;
+  %template(wistream) basic_istream<wchar_t>;
+#endif
+
   // 27.6.1.5 Template class basic_iostream
   template<typename _CharT, typename _Traits = char_traits<_CharT> >
   class basic_iostream
@@ -318,8 +326,6 @@
 }
 
 namespace std {
-  %template(ostream) basic_ostream<char>;
-  %template(istream) basic_istream<char>;
   %template(iostream) basic_iostream<char>;
 
   %template(endl) endl<char, std::char_traits<char> >;
@@ -327,8 +333,6 @@
   %template(flush) flush<char, std::char_traits<char> >;
 
 #if defined(SWIG_WCHAR)
-  %template(wostream) basic_ostream<wchar_t>;
-  %template(wistream) basic_istream<wchar_t>;
   %template(wiostream) basic_iostream<wchar_t>;  
 
   %template(wendl) endl<wchar_t, std::char_traits<wchar_t> >;
diff --git a/Lib/swig.swg b/Lib/swig.swg
index 6dc215d..db7e08c 100644
--- a/Lib/swig.swg
+++ b/Lib/swig.swg
@@ -9,20 +9,6 @@
  * User Directives 
  * ----------------------------------------------------------------------------- */
 
-/* Deprecated SWIG-1.1 directives */
-
-#define %disabledoc     %warn "104:%disabledoc is deprecated"
-#define %enabledoc      %warn "105:%enabledoc is deprecated"
-#define %doconly        %warn "106:%doconly is deprecated"
-#define %style          %warn "107:%style is deprecated" /##/
-#define %localstyle     %warn "108:%localstyle is deprecated" /##/
-#define %title          %warn "109:%title is deprecated" /##/
-#define %section        %warn "110:%section is deprecated" /##/
-#define %subsection     %warn "111:%subsection is deprecated" /##/
-#define %subsubsection  %warn "112:%subsubsection is deprecated" /##/
-#define %new            %warn "117:%new is deprecated. Use %newobject"
-#define %text           %insert("null")
-
 /* Code insertion directives such as %wrapper %{ ... %} */
 
 #define %begin       %insert("begin")
@@ -31,10 +17,6 @@
 #define %wrapper     %insert("wrapper")
 #define %init        %insert("init")
 
-/* Class extension */
-
-#define %addmethods  %warn "113:%addmethods is now %extend" %extend
-
 /* %ignore directive */
 
 #define %ignore         %rename($ignore)
@@ -42,9 +24,6 @@
 
 /* Access control directives */
 
-#define %readonly    %warn "114:%readonly is deprecated. Use %immutable; " %feature("immutable");
-#define %readwrite   %warn "115:%readwrite is deprecated. Use %mutable; " %feature("immutable","");
-
 #define %immutable       %feature("immutable")
 #define %noimmutable     %feature("immutable","0")
 #define %clearimmutable  %feature("immutable","")
@@ -172,7 +151,7 @@
 #define %novaluewrapper      %feature("novaluewrapper")
 #define %clearnovaluewrapper %feature("novaluewrapper","")
 
-/* Contract support - Experimental and undocumented */
+/* Contract support - Experimental */
 #define %contract      %feature("contract")
 #define %nocontract    %feature("contract","0")
 #define %clearcontract %feature("contract","")
@@ -268,7 +247,9 @@
 
 */
 
-%define %$not            "not" %enddef 
+/* Note that when %$not is used with another macro, say %enum as follows: %$not %$enum, the result is "notmatch=enum" */
+%define %$not            "not" %enddef
+
 %define %$isenum         "match"="enum"  %enddef
 %define %$isenumitem     "match"="enumitem"  %enddef
 %define %$isaccess       "match"="access"   %enddef
@@ -279,6 +260,7 @@
 %define %$isnamespace    "match"="namespace"  %enddef
 %define %$istemplate     "match"="template"  %enddef
 %define %$isconstant     "match"="constant"  %enddef  /* %constant definition */
+%define %$isusing        "match"="using"  %enddef
 
 %define %$isunion        "match$kind"="union"  %enddef
 %define %$isfunction     "match$kind"="function"  %enddef
@@ -358,6 +340,11 @@
 %define SWIG_TYPECHECK_STDUNISTRING 115    %enddef
 %define SWIG_TYPECHECK_UNISTRING    120    %enddef
 %define SWIG_TYPECHECK_CHAR         130    %enddef
+/* Give std::string_view a slightly higher precedence because if there are
+ * overloaded forms then it may be more efficient to pass as std::string_view
+ * (e.g. to pass as std::string requires copying the data into a std::string).
+ */
+%define SWIG_TYPECHECK_STRINGVIEW   134    %enddef
 %define SWIG_TYPECHECK_STDSTRING    135    %enddef
 %define SWIG_TYPECHECK_STRING       140    %enddef
 %define SWIG_TYPECHECK_PAIR         150    %enddef
@@ -445,15 +432,15 @@
 /* Set up the typemap for handling new return strings */
 
 #ifdef __cplusplus
-%typemap(newfree) char * "delete [] $1;";
+%typemap(newfree) char * "delete [] $1;"
 #else
-%typemap(newfree) char * "free($1);";
+%typemap(newfree) char * "free($1);"
 #endif
 
 /* Default typemap for handling char * members */
 
 #ifdef __cplusplus
-%typemap(memberin) char * {
+%typemap(memberin,fragment="<string.h>") char * {
   delete [] $1;
   if ($input) {
      $1 = ($1_type) (new char[strlen((const char *)$input)+1]);
@@ -462,7 +449,7 @@
      $1 = 0;
   }
 }
-%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const char * {
+%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * {
   if ($input) {
      $1 = ($1_type) (new char[strlen((const char *)$input)+1]);
      strcpy((char *)$1, (const char *)$input);
@@ -470,7 +457,7 @@
      $1 = 0;
   }
 }
-%typemap(globalin) char * {
+%typemap(globalin,fragment="<string.h>") char * {
   delete [] $1;
   if ($input) {
      $1 = ($1_type) (new char[strlen((const char *)$input)+1]);
@@ -479,7 +466,7 @@
      $1 = 0;
   }
 }
-%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const char * {
+%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * {
   if ($input) {
      $1 = ($1_type) (new char[strlen((const char *)$input)+1]);
      strcpy((char *)$1, (const char *)$input);
@@ -488,7 +475,7 @@
   }
 }
 #else
-%typemap(memberin) char * {
+%typemap(memberin,fragment="<string.h>") char * {
   free($1);
   if ($input) {
      $1 = ($1_type) malloc(strlen((const char *)$input)+1);
@@ -497,7 +484,7 @@
      $1 = 0;
   }
 }
-%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const char * {
+%typemap(memberin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * {
   if ($input) {
      $1 = ($1_type) malloc(strlen((const char *)$input)+1);
      strcpy((char *)$1, (const char *)$input);
@@ -505,7 +492,7 @@
      $1 = 0;
   }
 }
-%typemap(globalin) char * {
+%typemap(globalin,fragment="<string.h>") char * {
   free($1);
   if ($input) {
      $1 = ($1_type) malloc(strlen((const char *)$input)+1);
@@ -514,7 +501,7 @@
      $1 = 0;
   }
 }
-%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const char * {
+%typemap(globalin,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG,fragment="<string.h>") const char * {
   if ($input) {
      $1 = ($1_type) malloc(strlen((const char *)$input)+1);
      strcpy((char *)$1, (const char *)$input);
@@ -527,7 +514,7 @@
 
 /* Character array handling */
 
-%typemap(memberin) char [ANY] {
+%typemap(memberin,fragment="<string.h>") char [ANY] {
   if($input) {
     strncpy((char*)$1, (const char *)$input, $1_dim0-1);
     $1[$1_dim0-1] = 0;
@@ -536,7 +523,7 @@
   }
 }
 
-%typemap(globalin) char [ANY] {
+%typemap(globalin,fragment="<string.h>") char [ANY] {
   if($input) {
     strncpy((char*)$1, (const char *)$input, $1_dim0-1);
     $1[$1_dim0-1] = 0;
@@ -545,12 +532,12 @@
   }
 }
 
-%typemap(memberin) char [] {
+%typemap(memberin,fragment="<string.h>") char [] {
   if ($input) strcpy((char *)$1, (const char *)$input);
   else $1[0] = 0;
 }
 
-%typemap(globalin) char [] {
+%typemap(globalin,fragment="<string.h>") char [] {
   if ($input) strcpy((char *)$1, (const char *)$input);
   else $1[0] = 0;
 }
@@ -599,6 +586,10 @@
  *  Runtime code
  * ----------------------------------------------------------------------------- */
 
+
+%insert("runtime") "swiglabels.swg"
+
+
 /*  The SwigValueWrapper class  */
 
 /*  
@@ -649,33 +640,53 @@
  *       arg1 = *inarg1;       // Assignment from a pointer
  *       arg1 = Vector(1,2,3); // Assignment from a value  
  *
+ * SwigValueWrapper is a drop in replacement to modify normal value semantics by
+ * using the heap instead of the stack to copy/move the underlying object it is
+ * managing. Smart pointers also manage an underlying object on the heap, so
+ * SwigValueWrapper has characteristics of a smart pointer. The reset function
+ * is specific smart pointer functionality, but cannot be a non-static member as
+ * when SWIG modifies typemap code it assumes non-static member function calls
+ * are routed to the underlying object, changing for example $1.f() to (&x)->f().
+ * The reset function was added as an optimisation to avoid some copying/moving
+ * and to take ownership of an object already created on the heap.
+ *
  * The class offers a strong guarantee of exception safety.
- * With regards to the implementation, the private SwigMovePointer nested class is 
- * a simple smart pointer with move semantics, much like std::auto_ptr.
+ * With regards to the implementation, the private SwigSmartPointer nested class is
+ * a simple smart pointer providing exception safety, much like std::auto_ptr.
  *
  * This wrapping technique was suggested by William Fulton and is henceforth
  * known as the "Fulton Transform" :-).
  */
 
 #ifdef __cplusplus
-%insert("runtime") %{
+// Placed in the header section to ensure the language specific header files are
+// the first included headers and not <utility>
+%insert("header") %{
 #ifdef __cplusplus
+#include <utility>
 /* SwigValueWrapper is described in swig.swg */
 template<typename T> class SwigValueWrapper {
-  struct SwigMovePointer {
+  struct SwigSmartPointer {
     T *ptr;
-    SwigMovePointer(T *p) : ptr(p) { }
-    ~SwigMovePointer() { delete ptr; }
-    SwigMovePointer& operator=(SwigMovePointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; }
+    SwigSmartPointer(T *p) : ptr(p) { }
+    ~SwigSmartPointer() { delete ptr; }
+    SwigSmartPointer& operator=(SwigSmartPointer& rhs) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = rhs.ptr; rhs.ptr = 0; return *this; }
+    void reset(T *p) { T* oldptr = ptr; ptr = 0; delete oldptr; ptr = p; }
   } pointer;
   SwigValueWrapper& operator=(const SwigValueWrapper<T>& rhs);
   SwigValueWrapper(const SwigValueWrapper<T>& rhs);
 public:
   SwigValueWrapper() : pointer(0) { }
-  SwigValueWrapper& operator=(const T& t) { SwigMovePointer tmp(new T(t)); pointer = tmp; return *this; }
+  SwigValueWrapper& operator=(const T& t) { SwigSmartPointer tmp(new T(t)); pointer = tmp; return *this; }
+#if __cplusplus >=201103L
+  SwigValueWrapper& operator=(T&& t) { SwigSmartPointer tmp(new T(std::move(t))); pointer = tmp; return *this; }
+  operator T&&() const { return std::move(*pointer.ptr); }
+#else
   operator T&() const { return *pointer.ptr; }
-  T *operator&() { return pointer.ptr; }
-};%}
+#endif
+  T *operator&() const { return pointer.ptr; }
+  static void reset(SwigValueWrapper& t, T *p) { t.pointer.reset(p); }
+};
 
 /*
  * SwigValueInit() is a generic initialisation solution as the following approach:
@@ -686,16 +697,18 @@
  * 
  *       unsigned int c_result = unsigned int();
  */
-%insert("runtime") %{
 template <typename T> T SwigValueInit() {
   return T();
 }
+
+#if __cplusplus >=201103L
+# define SWIG_STD_MOVE(OBJ) std::move(OBJ)
+#else
+# define SWIG_STD_MOVE(OBJ) OBJ
+#endif
+
 #endif
 %}
 #endif
 
-/*  The swiglabels  */
-
-%insert("runtime") "swiglabels.swg"
-
-
+%insert("runtime") "swigcompat.swg"
diff --git a/Lib/swigarch.i b/Lib/swigarch.i
index bf4ee8e..2f76149 100644
--- a/Lib/swigarch.i
+++ b/Lib/swigarch.i
@@ -6,57 +6,28 @@
  * Use only in extreme cases, when no arch. independent code can be
  * generated
  * 
- * To activate architecture specific code, use
+ * To activate 32-bit architecture checks, use
  *
  *     swig -DSWIGWORDSIZE32
  *
- * or
+ * This adds checks that long is 32-bits when compiling the generated wrappers.
+ *
+ * To activate 64-bit architecture specific code, use
  *
  *     swig -DSWIGWORDSIZE64
  *
- * Note that extra checking code will be added to the wrapped code,
- * which will prevent the compilation in a different architecture.
+ * This adds checks that long is 64-bits when compiling the generated wrappers.
+ * Some target languages also generate code that expects long to be 64-bits.
  *
- * If you don't specify the SWIGWORDSIZE (the default case), swig will
+ * If you don't specify the SWIGWORDSIZE (the default case), SWIG will
  * generate architecture independent and/or 32bits code, with no extra
- * checking code added.
+ * checks for the sizeof long.
  * ----------------------------------------------------------------------------- */
 
-#if !defined(SWIGWORDSIZE32) &&  !defined(SWIGWORDSIZE64)
-# if (__WORDSIZE == 32)
-#  define SWIGWORDSIZE32
-# endif
-#endif
-  
-#if !defined(SWIGWORDSIZE64) &&  !defined(SWIGWORDSIZE32) 
-# if defined(__x86_64) || defined(__x86_64__) || (__WORDSIZE == 64)
-#  define SWIGWORDSIZE64
-# endif
-#endif
-
-
 #ifdef SWIGWORDSIZE32
-%{
-#define SWIGWORDSIZE32
-#ifndef LONG_MAX
-#include <limits.h>
-#endif
-#if (__WORDSIZE == 64) || (LONG_MAX != INT_MAX)
-# error "SWIG wrapped code invalid in 64 bit architecture, regenerate code using -DSWIGWORDSIZE64"
-#endif
-%}
+%fragment("long_check_wordsize32");
 #endif
 
 #ifdef SWIGWORDSIZE64
-%{
-#define SWIGWORDSIZE64
-#ifndef LONG_MAX
-#include <limits.h>
+%fragment("long_check_wordsize64");
 #endif
-#if (__WORDSIZE == 32) || (LONG_MAX == INT_MAX)
-# error "SWIG wrapped code invalid in 32 bit architecture, regenerate code using -DSWIGWORDSIZE32"
-#endif
-%}
-#endif
-  
-
diff --git a/Lib/swigcompat.swg b/Lib/swigcompat.swg
new file mode 100644
index 0000000..7d29b75
--- /dev/null
+++ b/Lib/swigcompat.swg
@@ -0,0 +1,23 @@
+/* -----------------------------------------------------------------------------
+ * swigcompat.swg
+ *
+ * Macros to provide support compatibility with older C and C++ standards.
+ * ----------------------------------------------------------------------------- */
+
+/* C99 and C++11 should provide snprintf, but define SWIG_NO_SNPRINTF
+ * if you're missing it.
+ */
+#if ((defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) || \
+     (defined __cplusplus && __cplusplus >= 201103L) || \
+     defined SWIG_HAVE_SNPRINTF) && \
+    !defined SWIG_NO_SNPRINTF
+# define SWIG_snprintf(O,S,F,A) snprintf(O,S,F,A)
+# define SWIG_snprintf2(O,S,F,A,B) snprintf(O,S,F,A,B)
+#else
+/* Fallback versions ignore the buffer size, but most of our uses either have a
+ * fixed maximum possible size or dynamically allocate a buffer that's large
+ * enough.
+ */
+# define SWIG_snprintf(O,S,F,A) sprintf(O,F,A)
+# define SWIG_snprintf2(O,S,F,A,B) sprintf(O,F,A,B)
+#endif
diff --git a/Lib/swigerrors.swg b/Lib/swigerrors.swg
index 1a6d203..4d5a8e4 100644
--- a/Lib/swigerrors.swg
+++ b/Lib/swigerrors.swg
@@ -1,4 +1,4 @@
-/*  Errors in SWIG */
+/* SWIG Errors applicable to all language modules, values are reserved from -1 to -99 */
 #define  SWIG_UnknownError    	   -1
 #define  SWIG_IOError        	   -2
 #define  SWIG_RuntimeError   	   -3
@@ -13,4 +13,3 @@
 #define  SWIG_MemoryError    	   -12
 #define  SWIG_NullReferenceError   -13
 
-
diff --git a/Lib/swigfragments.swg b/Lib/swigfragments.swg
index 2cbef7c..75f05bc 100644
--- a/Lib/swigfragments.swg
+++ b/Lib/swigfragments.swg
@@ -29,6 +29,10 @@
 #include <math.h>
 %}
 
+%fragment("<string.h>", "header") %{
+#include <string.h>
+%}
+
 %fragment("<stddef.h>", "header") %{
 #include <stddef.h>
 %}
@@ -73,6 +77,10 @@
 #include <algorithm>
 %}
 
+%fragment("<memory>", "header") %{
+#include <memory>
+%}
+
 %fragment("<stdexcept>", "header") %{
 #include <stdexcept>
 %}
@@ -81,6 +89,41 @@
 #include <string>
 %}
 
-%fragment("<memory>", "header") %{
-#include <memory>
+%fragment("<string_view>", "header") %{
+#include <string_view>
 %}
+
+%fragment("<type_traits>", "header") %{
+#include <type_traits>
+%}
+
+%fragment("<iostream>", "header") %{
+#include <iostream>
+%}
+
+/* -----------------------------------------------------------------------------
+ * Other common fragments
+ * ----------------------------------------------------------------------------- */
+
+%fragment("long_check_wordsize32", "header", fragment="<limits.h>") %{
+#if !defined(SWIG_NO_WORDSIZE32_CHECK)
+#if (__WORDSIZE == 64) || (LONG_MAX != INT_MAX)
+# error "SWIG generated code is invalid on this 64-bit architecture, please regenerate without defining SWIGWORDSIZE32 or define SWIGWORDSIZE64"
+#endif
+#endif
+%}
+
+%fragment("long_check_wordsize64", "header", fragment="<limits.h>") %{
+#if !defined(SWIG_NO_WORDSIZE64_CHECK)
+#if (__WORDSIZE == 32) || (LONG_MAX == INT_MAX)
+# error "SWIG generated code is invalid on this 32-bit architecture, please regenerate without defining SWIGWORDSIZE64 or define SWIGWORDSIZE32"
+#endif
+#endif
+%}
+
+#ifdef SWIGWORDSIZE64
+%fragment("long_check_wordsize", "header", fragment="long_check_wordsize64") {}
+#else
+%fragment("long_check_wordsize", "header", fragment="long_check_wordsize32") {}
+#endif
+
diff --git a/Lib/swiginit.swg b/Lib/swiginit.swg
index 33926b1..e50b1b4 100644
--- a/Lib/swiginit.swg
+++ b/Lib/swiginit.swg
@@ -50,9 +50,12 @@
 #define SWIGRUNTIME_DEBUG
 #endif
 
+#ifndef SWIG_INIT_CLIENT_DATA_TYPE
+#define SWIG_INIT_CLIENT_DATA_TYPE void *
+#endif
 
 SWIGRUNTIME void
-SWIG_InitializeModule(void *clientdata) {
+SWIG_InitializeModule(SWIG_INIT_CLIENT_DATA_TYPE clientdata) {
   size_t i;
   swig_module_info *module_head, *iter;
   int init;
diff --git a/Lib/swiglabels.swg b/Lib/swiglabels.swg
index b385566..58d87e9 100644
--- a/Lib/swiglabels.swg
+++ b/Lib/swiglabels.swg
@@ -121,3 +121,9 @@
 #ifdef __INTEL_COMPILER
 # pragma warning disable 592
 #endif
+
+#if defined(__cplusplus) && __cplusplus >=201103L
+# define SWIG_NULLPTR nullptr
+#else
+# define SWIG_NULLPTR NULL
+#endif 
diff --git a/Lib/swigrun.swg b/Lib/swigrun.swg
index 59118ec..824185c 100644
--- a/Lib/swigrun.swg
+++ b/Lib/swigrun.swg
@@ -44,6 +44,8 @@
 #define SWIG_POINTER_DISOWN        0x1
 #define SWIG_CAST_NEW_MEMORY       0x2
 #define SWIG_POINTER_NO_NULL       0x4
+#define SWIG_POINTER_CLEAR         0x8
+#define SWIG_POINTER_RELEASE       (SWIG_POINTER_CLEAR | SWIG_POINTER_DISOWN)
 
 /* Flags for new pointer objects */
 #define SWIG_POINTER_OWN           0x1
@@ -115,7 +117,7 @@
    SWIG errors code.
 
    Finally, if the SWIG_CASTRANK_MODE is enabled, the result code
-   allows to return the 'cast rank', for example, if you have this
+   allows returning the 'cast rank', for example, if you have this
 
        int food(double)
        int fooi(int);
@@ -129,7 +131,13 @@
 */
 
 #define SWIG_OK                    (0)
+/* Runtime errors are < 0 */
 #define SWIG_ERROR                 (-1)
+/* Errors in range -1 to -99 are in swigerrors.swg (errors for all languages including those not using the runtime) */
+/* Errors in range -100 to -199 are language specific errors defined in *errors.swg */
+/* Errors < -200 are generic runtime specific errors */
+#define SWIG_ERROR_RELEASE_NOT_OWNED (-200)
+
 #define SWIG_IsOK(r)               (r >= 0)
 #define SWIG_ArgError(r)           ((r != SWIG_ERROR) ? r : SWIG_TypeError)
 
@@ -137,14 +145,14 @@
 #define SWIG_CASTRANKLIMIT         (1 << 8)
 /* The NewMask denotes the object was created (using new/malloc) */
 #define SWIG_NEWOBJMASK            (SWIG_CASTRANKLIMIT  << 1)
-/* The TmpMask is for in/out typemaps that use temporal objects */
+/* The TmpMask is for in/out typemaps that use temporary objects */
 #define SWIG_TMPOBJMASK            (SWIG_NEWOBJMASK << 1)
 /* Simple returning values */
 #define SWIG_BADOBJ                (SWIG_ERROR)
 #define SWIG_OLDOBJ                (SWIG_OK)
 #define SWIG_NEWOBJ                (SWIG_OK | SWIG_NEWOBJMASK)
 #define SWIG_TMPOBJ                (SWIG_OK | SWIG_TMPOBJMASK)
-/* Check, add and del mask methods */
+/* Check, add and del object mask methods */
 #define SWIG_AddNewMask(r)         (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r)
 #define SWIG_DelNewMask(r)         (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r)
 #define SWIG_IsNewObj(r)           (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK))
@@ -290,7 +298,7 @@
   Identical to SWIG_TypeCheck, except strcmp is replaced with a pointer comparison
 */
 SWIGRUNTIME swig_cast_info *
-SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *ty) {
+SWIG_TypeCheckStruct(const swig_type_info *from, swig_type_info *ty) {
   if (ty) {
     swig_cast_info *iter = ty->cast;
     while (iter) {
@@ -350,9 +358,9 @@
 SWIGRUNTIME const char *
 SWIG_TypePrettyName(const swig_type_info *type) {
   /* The "str" field contains the equivalent pretty names of the
-     type, separated by vertical-bar characters.  We choose
-     to print the last name, as it is often (?) the most
-     specific. */
+     type, separated by vertical-bar characters.  Choose the last
+     name. It should be the most specific; a fully resolved name
+     but not necessarily with default template parameters expanded. */
   if (!type) return NULL;
   if (type->str != NULL) {
     const char *last_name = type->str;
diff --git a/Lib/swigwarn.swg b/Lib/swigwarn.swg
index 1e195af..09b4be6 100644
--- a/Lib/swigwarn.swg
+++ b/Lib/swigwarn.swg
@@ -5,31 +5,31 @@
 
 /* -- Deprecated features -- */
 
-%define SWIGWARN_DEPRECATED_EXTERN        101 %enddef
-%define SWIGWARN_DEPRECATED_VAL           102 %enddef
-%define SWIGWARN_DEPRECATED_OUT           103 %enddef
-%define SWIGWARN_DEPRECATED_DISABLEDOC    104 %enddef
-%define SWIGWARN_DEPRECATED_ENABLEDOC     105 %enddef
-%define SWIGWARN_DEPRECATED_DOCONLY       106 %enddef
-%define SWIGWARN_DEPRECATED_STYLE         107 %enddef
-%define SWIGWARN_DEPRECATED_LOCALSTYLE    108 %enddef
-%define SWIGWARN_DEPRECATED_TITLE         109 %enddef
-%define SWIGWARN_DEPRECATED_SECTION       110 %enddef
-%define SWIGWARN_DEPRECATED_SUBSECTION    111 %enddef
-%define SWIGWARN_DEPRECATED_SUBSUBSECTION 112 %enddef
-%define SWIGWARN_DEPRECATED_ADDMETHODS    113 %enddef
-%define SWIGWARN_DEPRECATED_READONLY      114 %enddef
-%define SWIGWARN_DEPRECATED_READWRITE     115 %enddef
-%define SWIGWARN_DEPRECATED_EXCEPT        116 %enddef
-%define SWIGWARN_DEPRECATED_NEW           117 %enddef
-%define SWIGWARN_DEPRECATED_EXCEPT_TM     118 %enddef
-%define SWIGWARN_DEPRECATED_IGNORE_TM     119 %enddef
-%define SWIGWARN_DEPRECATED_OPTC          120 %enddef
-%define SWIGWARN_DEPRECATED_NAME          121 %enddef
-%define SWIGWARN_DEPRECATED_NOEXTERN      122 %enddef
-%define SWIGWARN_DEPRECATED_NODEFAULT     123 %enddef
-%define SWIGWARN_DEPRECATED_TYPEMAP_LANG  124 %enddef
-%define SWIGWARN_DEPRECATED_INPUT_FILE    125 %enddef
+/* Unused since 4.2.0: #define WARN_DEPRECATED_EXTERN        101 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_VAL           102 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_OUT           103 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_DISABLEDOC    104 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_ENABLEDOC     105 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_DOCONLY       106 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_STYLE         107 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_LOCALSTYLE    108 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_TITLE         109 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_SECTION       110 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_SUBSECTION    111 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_SUBSUBSECTION 112 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_ADDMETHODS    113 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_READONLY      114 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_READWRITE     115 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_EXCEPT        116 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_NEW           117 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_EXCEPT_TM     118 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_IGNORE_TM     119 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_OPTC          120 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_NAME          121 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_NOEXTERN      122 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_NODEFAULT     123 */
+/* Unused since 4.1.0: #define WARN_DEPRECATED_TYPEMAP_LANG  124 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_INPUT_FILE    125 */
 %define SWIGWARN_DEPRECATED_NESTED_WORKAROUND 126 %enddef
 
 /* -- Preprocessor -- */
@@ -48,17 +48,17 @@
 %define SWIGWARN_PARSE_EXTEND_UNDEF       303 %enddef
 %define SWIGWARN_PARSE_UNSUPPORTED_VALUE  304 %enddef
 %define SWIGWARN_PARSE_BAD_VALUE          305 %enddef
-%define SWIGWARN_PARSE_PRIVATE            306 %enddef
-%define SWIGWARN_PARSE_BAD_DEFAULT        307 %enddef
+/* Unused since 1.3.32: #define WARN_PARSE_PRIVATE            306 */
+/* Unused since 4.2.0: #define WARN_PARSE_BAD_DEFAULT        307 */
 %define SWIGWARN_PARSE_NAMESPACE_ALIAS    308 %enddef
 %define SWIGWARN_PARSE_PRIVATE_INHERIT    309 %enddef
-%define SWIGWARN_PARSE_TEMPLATE_REPEAT    310 %enddef
-%define SWIGWARN_PARSE_TEMPLATE_PARTIAL   311 %enddef
+/* Unused since 1.3.18: #define WARN_PARSE_TEMPLATE_REPEAT    310 */
+/* Unused since 1.3.18: #define WARN_PARSE_TEMPLATE_PARTIAL   311 */
 %define SWIGWARN_PARSE_UNNAMED_NESTED_CLASS 312 %enddef
 %define SWIGWARN_PARSE_UNDEFINED_EXTERN   313 %enddef
 %define SWIGWARN_PARSE_KEYWORD            314 %enddef
 %define SWIGWARN_PARSE_USING_UNDEF        315 %enddef
-%define SWIGWARN_PARSE_MODULE_REPEAT      316 %enddef
+/* Unused since 1.3.18: #define WARN_PARSE_MODULE_REPEAT      316 */
 %define SWIGWARN_PARSE_TEMPLATE_SP_UNDEF  317 %enddef
 %define SWIGWARN_PARSE_TEMPLATE_AMBIG     318 %enddef
 %define SWIGWARN_PARSE_NO_ACCESS          319 %enddef
@@ -69,11 +69,17 @@
 %define SWIGWARN_PARSE_NESTED_TEMPLATE    324 %enddef
 %define SWIGWARN_PARSE_NAMED_NESTED_CLASS 325 %enddef
 %define SWIGWARN_PARSE_EXTEND_NAME        326 %enddef
+%define SWIGWARN_PARSE_EXTERN_TEMPLATE    327 %enddef
+%define SWIGWARN_PARSE_ASSIGNED_VALUE     328 %enddef
+%define SWIGWARN_PARSE_USING_CONSTRUCTOR  329 %enddef
 
 %define SWIGWARN_CPP11_LAMBDA             340 %enddef
-%define SWIGWARN_CPP11_ALIAS_DECLARATION  341 %enddef  /* redundant now */
-%define SWIGWARN_CPP11_ALIAS_TEMPLATE     342 %enddef  /* redundant now */
-%define SWIGWARN_CPP11_VARIADIC_TEMPLATE  343 %enddef
+/* Unused since 3.0.11: #define WARN_CPP11_ALIAS_DECLARATION  341 */
+/* Unused since 3.0.11: #define WARN_CPP11_ALIAS_TEMPLATE     342 */
+/* Unused since 4.2.0: #define WARN_CPP11_VARIADIC_TEMPLATE  343 */
+%define SWIGWARN_CPP11_DECLTYPE           344 %enddef
+%define SWIGWARN_CPP14_AUTO               345 %enddef
+%define SWIGWARN_CPP11_AUTO               346 %enddef
 
 %define SWIGWARN_IGNORE_OPERATOR_NEW        350 %enddef	/* new */
 %define SWIGWARN_IGNORE_OPERATOR_DELETE     351 %enddef	/* delete */
@@ -122,8 +128,9 @@
 %define SWIGWARN_IGNORE_OPERATOR_NEWARR     394 %enddef	/* new [] */
 %define SWIGWARN_IGNORE_OPERATOR_DELARR     395 %enddef	/* delete [] */
 %define SWIGWARN_IGNORE_OPERATOR_REF        396 %enddef	/* operator *() */
+%define SWIGWARN_IGNORE_OPERATOR_LTEQUALGT  397 %enddef	/* <=> */
 
-/* 394-399 are reserved */
+/* please leave 350-399 free for WARN_IGNORE_OPERATOR_* */
 
 /* -- Type system and typemaps -- */
 
@@ -133,11 +140,12 @@
 %define SWIGWARN_TYPE_REDEFINED           404 %enddef
 %define SWIGWARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405 %enddef
 
-%define SWIGWARN_TYPEMAP_SOURCETARGET     450 %enddef
+/* Unused since 4.1.0: #define WARN_TYPEMAP_SOURCETARGET     450 */
 %define SWIGWARN_TYPEMAP_CHARLEAK         451 %enddef
-%define SWIGWARN_TYPEMAP_SWIGTYPE         452 %enddef
+/* Unused since 1.3.32: #define WARN_TYPEMAP_SWIGTYPE         452 */
 %define SWIGWARN_TYPEMAP_APPLY_UNDEF      453 %enddef
 %define SWIGWARN_TYPEMAP_SWIGTYPELEAK     454 %enddef
+%define SWIGWARN_TYPEMAP_WCHARLEAK        455 %enddef
 
 %define SWIGWARN_TYPEMAP_IN_UNDEF         460 %enddef
 %define SWIGWARN_TYPEMAP_OUT_UNDEF        461 %enddef
@@ -172,7 +180,7 @@
 %define SWIGWARN_LANG_NATIVE_UNIMPL       507 %enddef
 %define SWIGWARN_LANG_DEREF_SHADOW        508 %enddef
 %define SWIGWARN_LANG_OVERLOAD_SHADOW     509 %enddef
-%define SWIGWARN_LANG_FRIEND_IGNORE       510 %enddef
+%define SWIGWARN_LANG_FRIEND_IGNORE       510 %enddef /* No longer issued */
 %define SWIGWARN_LANG_OVERLOAD_KEYWORD    511 %enddef
 %define SWIGWARN_LANG_OVERLOAD_CONST      512 %enddef
 %define SWIGWARN_LANG_CLASS_UNNAMED       513 %enddef
@@ -188,6 +196,7 @@
 %define SWIGWARN_LANG_EXTEND_DESTRUCTOR   523 %enddef
 %define SWIGWARN_LANG_EXPERIMENTAL        524 %enddef
 %define SWIGWARN_LANG_DIRECTOR_FINAL      525 %enddef
+%define SWIGWARN_LANG_USING_NAME_DIFFERENT 526 %enddef
 
 /* -- Doxygen comments -- */
 
@@ -199,7 +208,7 @@
 %define SWIGWARN_DOXYGEN_UNKNOWN_CHARACTER        565 %enddef
 %define SWIGWARN_DOXYGEN_UNEXPECTED_ITERATOR_VALUE  566 %enddef
 
-/* -- Reserved (600-799) -- */
+/* -- Reserved (600-699) -- */
 
 /* -- Language module specific warnings (700 - 899) -- */
 
@@ -227,7 +236,12 @@
 
 %define SWIGWARN_PYTHON_INDENT_MISMATCH           740 %enddef
 
-/* please leave 740-759 free for Python */
+/* please leave 740-749 free for Python */
+
+/* Unused since 4.2.0: #define WARN_R_MISSING_RTYPECHECK_TYPEMAP     750 */
+%define SWIGWARN_R_TYPEMAP_RTYPECHECK_UNDEF       751 %enddef
+
+/* please leave 750-759 free for R */
 
 %define SWIGWARN_RUBY_WRONG_NAME                  801 %enddef
 %define SWIGWARN_RUBY_MULTIPLE_INHERITANCE        802 %enddef
@@ -251,6 +265,7 @@
 %define SWIGWARN_JAVA_TYPEMAP_DIRECTORIN_NODESC   824 %enddef
 %define SWIGWARN_JAVA_NO_DIRECTORCONNECT_ATTR     825 %enddef
 %define SWIGWARN_JAVA_NSPACE_WITHOUT_PACKAGE      826 %enddef
+%define SWIGWARN_JAVA_TYPEMAP_INTERFACEMODIFIERS_UNDEF 827 %enddef
 
 /* please leave 810-829 free for Java */
 
@@ -271,26 +286,15 @@
 %define SWIGWARN_CSHARP_EXCODE                    844 %enddef
 %define SWIGWARN_CSHARP_CANTHROW                  845 %enddef
 %define SWIGWARN_CSHARP_NO_DIRECTORCONNECT_ATTR   846 %enddef
+%define SWIGWARN_CSHARP_TYPEMAP_INTERFACEMODIFIERS_UNDEF 847 %enddef
 
 /* please leave 830-849 free for C# */
 
-%define SWIGWARN_MODULA3_TYPEMAP_TYPE_UNDEF        850 %enddef
-%define SWIGWARN_MODULA3_TYPEMAP_GETCPTR_UNDEF     851 %enddef
-%define SWIGWARN_MODULA3_TYPEMAP_CLASSMOD_UNDEF    852 %enddef
-%define SWIGWARN_MODULA3_TYPEMAP_PTRCONSTMOD_UNDEF 853 %enddef
-%define SWIGWARN_MODULA3_TYPEMAP_MULTIPLE_RETURN   854 %enddef
-%define SWIGWARN_MODULA3_MULTIPLE_INHERITANCE      855 %enddef
-%define SWIGWARN_MODULA3_TYPECONSTRUCTOR_UNKNOWN   856 %enddef
-%define SWIGWARN_MODULA3_UNKNOWN_PRAGMA            857 %enddef
-%define SWIGWARN_MODULA3_BAD_ENUMERATION           858 %enddef
-%define SWIGWARN_MODULA3_DOUBLE_ID                 859 %enddef
-%define SWIGWARN_MODULA3_BAD_IMPORT                860 %enddef
-
-/* please leave 850-869 free for Modula 3 */
+/* 850-860 were used by Modula 3 (removed in SWIG 4.1.0) - avoid reusing for now */
 
 %define SWIGWARN_PHP_MULTIPLE_INHERITANCE         870 %enddef
 %define SWIGWARN_PHP_UNKNOWN_PRAGMA               871 %enddef
-%define SWIGWARN_PHP_PUBLIC_BASE                  872 %enddef
+/* Unused since 4.1.0: define WARN_PHP_PUBLIC_BASE                  872 */
 
 /* please leave 870-889 free for PHP */
 
diff --git a/Lib/swigwarnings.swg b/Lib/swigwarnings.swg
index 34c98fb..2dfea66 100644
--- a/Lib/swigwarnings.swg
+++ b/Lib/swigwarnings.swg
@@ -52,8 +52,9 @@
 
 %define SWIGWARN_TYPEMAP_CHARLEAK_MSG         "451:Setting a const char * variable may leak memory." %enddef
 %define SWIGWARN_TYPEMAP_SWIGTYPELEAK_MSG     "454:Setting a pointer/reference variable may leak memory." %enddef
+%define SWIGWARN_TYPEMAP_WCHARLEAK_MSG        "455:Setting a const wchar_t * variable may leak memory." %enddef
 %define SWIGWARN_TYPEMAP_THREAD_UNSAFE_MSG    "470:Thread/reentrant unsafe wrapping, consider returning by value instead." %enddef
-%define SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG  "473:Returning a pointer or reference in a director method is not recommended." %enddef
+%define SWIGWARN_TYPEMAP_DIRECTOROUT_PTR_MSG  "473:Returning a reference, pointer or pointer wrapper in a director method is not recommended." %enddef
 %define SWIGWARN_TYPEMAP_INITIALIZER_LIST_MSG "476:Initialization using std::initializer_list." %enddef
 
 /* -----------------------------------------------------------------------------
@@ -107,6 +108,7 @@
 %define SWIGWARN_IGNORE_OPERATOR_NEWARR_MSG     "394:operator new[] ignored"  %enddef
 %define SWIGWARN_IGNORE_OPERATOR_DELARR_MSG     "395:operator delete[] ignored"  %enddef
 %define SWIGWARN_IGNORE_OPERATOR_REF_MSG        "396:operator*() ignored" %enddef
+%define SWIGWARN_IGNORE_OPERATOR_LTEQUALGT_MSG  "397:operator<=> ignored" %enddef
 
 #define %ignoreoperator(Oper) %ignorewarn(SWIGWARN_IGNORE_OPERATOR_##Oper##_MSG)
 
diff --git a/Lib/tcl/Makefile.in b/Lib/tcl/Makefile.in
index 13d7d46..019091c 100644
--- a/Lib/tcl/Makefile.in
+++ b/Lib/tcl/Makefile.in
@@ -45,7 +45,7 @@
 #     SWIGCC    = Compiler used to compile the wrapper file
 
 SWIG          = $(exec_prefix)/bin/swig
-SWIGOPT       = -tcl # use -tcl8 for Tcl 8.0
+SWIGOPT       = -tcl
 SWIGCC        = $(CC)
 
 # SWIG Library files.  Uncomment if rebuilding tclsh
diff --git a/Lib/tcl/argcargv.i b/Lib/tcl/argcargv.i
new file mode 100644
index 0000000..e93f691
--- /dev/null
+++ b/Lib/tcl/argcargv.i
@@ -0,0 +1,27 @@
+/* -------------------------------------------------------------
+ * SWIG library containing argc and argv multi-argument typemaps
+ * ------------------------------------------------------------- */
+
+%typemap(in) (int ARGC, char **ARGV) {
+  Tcl_Size i, nitems;
+  Tcl_Obj **listobjv;
+  if (Tcl_ListObjGetElements(interp, $input, &nitems, &listobjv) == TCL_ERROR) {
+     SWIG_exception_fail(SWIG_ValueError, "in method '$symname', Expecting list of argv");
+     goto fail;
+  }
+  $1 = ($1_ltype) nitems;
+  $2 = (char **) malloc((nitems+1)*sizeof(char *));
+  for (i = 0; i < nitems; i++) {
+    $2[i] = Tcl_GetString(listobjv[i]);
+  }
+  $2[i] = NULL;
+}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_STRING_ARRAY) (int ARGC, char **ARGV) {
+  Tcl_Size len;
+  $1 = Tcl_ListObjLength(interp, $input, &len) == TCL_OK;
+}
+
+%typemap(freearg) (int ARGC, char **ARGV) {
+  free((void *)$2);
+}
diff --git a/Lib/tcl/carrays.i b/Lib/tcl/carrays.i
index 0236672..c1e6db3 100644
--- a/Lib/tcl/carrays.i
+++ b/Lib/tcl/carrays.i
@@ -1,4 +1 @@
 %include <typemaps/carrays.swg>
-
-
-
diff --git a/Lib/tcl/mactkinit.c b/Lib/tcl/mactkinit.c
deleted file mode 100644
index 8d14200..0000000
--- a/Lib/tcl/mactkinit.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/* -----------------------------------------------------------------------------
- * mactkinit.c
- *
- * This is a support file needed to build a new version of Wish.
- * Normally, this capability is found in TkAppInit.c, but this creates
- * tons of namespace problems for many applications.
- * ----------------------------------------------------------------------------- */
-   
-#include <Gestalt.h>
-#include <ToolUtils.h>
-#include <Fonts.h>
-#include <Dialogs.h>
-#include <SegLoad.h>
-#include <Traps.h>
-
-#include "tk.h"
-#include "tkInt.h"
-#include "tkMacInt.h"
-
-typedef int (*TclMacConvertEventPtr) _ANSI_ARGS_((EventRecord *eventPtr));
-Tcl_Interp *gStdoutInterp = NULL;
-
-void 	TclMacSetEventProc _ANSI_ARGS_((TclMacConvertEventPtr procPtr));
-int 	TkMacConvertEvent _ANSI_ARGS_((EventRecord *eventPtr));
-
-/*
- * Prototypes for functions the ANSI library needs to link against.
- */
-short			InstallConsole _ANSI_ARGS_((short fd));
-void			RemoveConsole _ANSI_ARGS_((void));
-long			WriteCharsToConsole _ANSI_ARGS_((char *buff, long n));
-long			ReadCharsFromConsole _ANSI_ARGS_((char *buff, long n));
-char *			__ttyname _ANSI_ARGS_((long fildes));
-short			SIOUXHandleOneEvent _ANSI_ARGS_((EventRecord *event));
-
-/*
- * Forward declarations for procedures defined later in this file:
- */
-
-/*
- *----------------------------------------------------------------------
- *
- * MacintoshInit --
- *
- *	This procedure calls Mac specific initialization calls.  Most of
- *	these calls must be made as soon as possible in the startup
- *	process.
- *
- * Results:
- *	Returns TCL_OK if everything went fine.  If it didn't the 
- *	application should probably fail.
- *
- * Side effects:
- *	Inits the application.
- *
- *----------------------------------------------------------------------
- */
-
-int
-MacintoshInit()
-{
-    int i;
-    long result, mask = 0x0700; 		/* mask = system 7.x */
-
-    /*
-     * Tk needs us to set the qd pointer it uses.  This is needed
-     * so Tk doesn't have to assume the availiblity of the qd global
-     * variable.  Which in turn allows Tk to be used in code resources.
-     */
-    tcl_macQdPtr = &qd;
-
-    InitGraf(&tcl_macQdPtr->thePort);
-    InitFonts();
-    InitWindows();
-    InitMenus();
-    InitDialogs((long) NULL);		
-    InitCursor();
-
-    /*
-     * Make sure we are running on system 7 or higher
-     */
-     
-    if ((NGetTrapAddress(_Gestalt, ToolTrap) == 
-    	    NGetTrapAddress(_Unimplemented, ToolTrap))
-    	    || (((Gestalt(gestaltSystemVersion, &result) != noErr)
-	    || (mask != (result & mask))))) {
-	panic("Tcl/Tk requires System 7 or higher.");
-    }
-
-    /*
-     * Make sure we have color quick draw 
-     * (this means we can't run on 68000 macs)
-     */
-     
-    if (((Gestalt(gestaltQuickdrawVersion, &result) != noErr)
-	    || (result < gestalt32BitQD13))) {
-	panic("Tk requires Color QuickDraw.");
-    }
-
-    
-    FlushEvents(everyEvent, 0);
-    SetEventMask(everyEvent);
-
-    /*
-     * Set up stack & heap sizes
-     */
-    /* TODO: stack size
-       size = StackSpace();
-       SetAppLimit(GetAppLimit() - 8192);
-     */
-    MaxApplZone();
-    for (i = 0; i < 4; i++) {
-	(void) MoreMasters();
-    }
-
-    TclMacSetEventProc(TkMacConvertEvent);
-    TkConsoleCreate();
-
-    return TCL_OK;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * SetupMainInterp --
- *
- *	This procedure calls initialization routines require a Tcl 
- *	interp as an argument.  This call effectively makes the passed
- *	iterpreter the "main" interpreter for the application.
- *
- * Results:
- *	Returns TCL_OK if everything went fine.  If it didn't the 
- *	application should probably fail.
- *
- * Side effects:
- *	More initialization.
- *
- *----------------------------------------------------------------------
- */
-
-int
-SetupMainInterp(
-    Tcl_Interp *interp)
-{
-    /*
-     * Initialize the console only if we are running as an interactive
-     * application.
-     */
-
-    TkMacInitAppleEvents(interp);
-    TkMacInitMenus(interp);
-
-    if (strcmp(Tcl_GetVar(interp, "tcl_interactive", TCL_GLOBAL_ONLY), "1")
-	    == 0) {
-	if (TkConsoleInit(interp) == TCL_ERROR) {
-	    goto error;
-	}
-    }
-
-    /*
-     * Attach the global interpreter to tk's expected global console
-     */
-
-    gStdoutInterp = interp;
-
-    return TCL_OK;
-
-error:
-    panic(interp->result);
-    return TCL_ERROR;
-}
-
-/*
- *----------------------------------------------------------------------
- *
- * InstallConsole, RemoveConsole, etc. --
- *
- *	The following functions provide the UI for the console package.
- *	Users wishing to replace SIOUX with their own console package 
- *	need only provide the four functions below in a library.
- *
- * Results:
- *	See SIOUX documentation for details.
- *
- * Side effects:
- *	See SIOUX documentation for details.
- *
- *----------------------------------------------------------------------
- */
-
-short 
-InstallConsole(short fd)
-{
-#pragma unused (fd)
-
-	return 0;
-}
-
-void 
-RemoveConsole(void)
-{
-}
-
-long 
-WriteCharsToConsole(char *buffer, long n)
-{
-    TkConsolePrint(gStdoutInterp, TCL_STDOUT, buffer, n);
-    return n;
-}
-
-long 
-ReadCharsFromConsole(char *buffer, long n)
-{
-    return 0;
-}
-
-extern char *
-__ttyname(long fildes)
-{
-    static char *devicename = "null device";
-
-    if (fildes >= 0 && fildes <= 2) {
-	return (devicename);
-    }
-    
-    return (0L);
-}
-
-short
-SIOUXHandleOneEvent(EventRecord *event)
-{
-    return 0;
-}
diff --git a/Lib/tcl/std_auto_ptr.i b/Lib/tcl/std_auto_ptr.i
new file mode 100644
index 0000000..b24809a
--- /dev/null
+++ b/Lib/tcl/std_auto_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_auto_ptr.i
+ *
+ * SWIG library file for handling std::auto_ptr.
+ * Memory ownership is passed from the std::auto_ptr C++ layer to the proxy
+ * class when returning a std::auto_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::auto_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %auto_ptr(TYPE)
+%typemap(in, noblock=1) std::auto_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::auto_ptr< TYPE > %{
+  Tcl_SetObjResult(interp, SWIG_NewInstanceObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::auto_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::auto_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class auto_ptr {};
+}
diff --git a/Lib/tcl/std_map.i b/Lib/tcl/std_map.i
index 2c7f40a..5c8bc75 100644
--- a/Lib/tcl/std_map.i
+++ b/Lib/tcl/std_map.i
@@ -47,7 +47,11 @@
                     throw std::out_of_range("key not found");
             }
             void set(const K& key, const T& x) {
+%#ifdef __cpp_lib_map_try_emplace
+                (*self).insert_or_assign(key, x);
+%#else
                 (*self)[key] = x;
+%#endif
             }
             void del(const K& key) throw (std::out_of_range) {
                 std::map< K, T, C >::iterator i = self->find(key);
@@ -63,17 +67,4 @@
         }
     };
 
-// Legacy macros (deprecated)
-%define specialize_std_map_on_key(K,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_key ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_value(T,CHECK,CONVERT_FROM,CONVERT_TO)
-#warning "specialize_std_map_on_value ignored - macro is deprecated and no longer necessary"
-%enddef
-
-%define specialize_std_map_on_both(K,CHECK_K,CONVERT_K_FROM,CONVERT_K_TO, T,CHECK_T,CONVERT_T_FROM,CONVERT_T_TO)
-#warning "specialize_std_map_on_both ignored - macro is deprecated and no longer necessary"
-%enddef
-
 }
diff --git a/Lib/tcl/std_string_view.i b/Lib/tcl/std_string_view.i
new file mode 100644
index 0000000..9d922bc
--- /dev/null
+++ b/Lib/tcl/std_string_view.i
@@ -0,0 +1,2 @@
+%include <typemaps/std_string_view.swg>
+
diff --git a/Lib/tcl/std_unique_ptr.i b/Lib/tcl/std_unique_ptr.i
new file mode 100644
index 0000000..0ea324c
--- /dev/null
+++ b/Lib/tcl/std_unique_ptr.i
@@ -0,0 +1,39 @@
+/* -----------------------------------------------------------------------------
+ * std_unique_ptr.i
+ *
+ * SWIG library file for handling std::unique_ptr.
+ * Memory ownership is passed from the std::unique_ptr C++ layer to the proxy
+ * class when returning a std::unique_ptr from a function.
+ * Memory ownership is passed from the proxy class to the std::unique_ptr in the
+ * C++ layer when passed as a parameter to a wrapped function.
+ * ----------------------------------------------------------------------------- */
+
+%define %unique_ptr(TYPE)
+%typemap(in, noblock=1) std::unique_ptr< TYPE > (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor(TYPE *), SWIG_POINTER_RELEASE | %convertptr_flags);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "TYPE *", $symname, $argnum);
+    } else {
+      %argument_fail(res, "TYPE *", $symname, $argnum);
+    }
+  }
+  $1.reset((TYPE *)argp);
+}
+
+%typemap (out) std::unique_ptr< TYPE > %{
+  Tcl_SetObjResult(interp, SWIG_NewInstanceObj($1.release(), $descriptor(TYPE *), SWIG_POINTER_OWN));
+%}
+
+%typemap(typecheck, precedence=SWIG_TYPECHECK_POINTER, equivalent="TYPE *", noblock=1) std::unique_ptr< TYPE > {
+  void *vptr = 0;
+  int res = SWIG_ConvertPtr($input, &vptr, $descriptor(TYPE *), 0);
+  $1 = SWIG_CheckState(res);
+}
+
+%template() std::unique_ptr< TYPE >;
+%enddef
+
+namespace std {
+  template <class T> class unique_ptr {};
+}
diff --git a/Lib/tcl/std_vector.i b/Lib/tcl/std_vector.i
index 5fba537..f950ee3 100644
--- a/Lib/tcl/std_vector.i
+++ b/Lib/tcl/std_vector.i
@@ -34,11 +34,11 @@
 %{
 #include <vector>
 
-Tcl_Obj* SwigString_FromString(const std::string &s) {
-    return Tcl_NewStringObj(s.data(), (int)s.length());
+SWIGINTERN Tcl_Obj* SwigString_FromString(const std::string &s) {
+    return Tcl_NewStringObj(s.data(), (Tcl_Size)s.length());
 }
 
-int Tcl_GetBoolFromObj(Tcl_Interp *interp, Tcl_Obj *o, bool *val) {
+SWIGINTERN int SWIG_Tcl_GetBoolFromObj(Tcl_Interp *interp, Tcl_Obj *o, bool *val) {
   int v;
   int res = Tcl_GetBooleanFromObj(interp, o, &v);
   if (res == TCL_OK) {
@@ -47,9 +47,10 @@
   return res;  
 }
  
-int SwigString_AsString(Tcl_Interp *interp, Tcl_Obj *o, std::string *val) {
-    int len;
+SWIGINTERN int SwigString_AsString(Tcl_Interp *interp, Tcl_Obj *o, std::string *val) {
+    Tcl_Size len;
     const char* temp = Tcl_GetStringFromObj(o, &len);
+    (void)interp;
     if (temp == NULL)
         return TCL_ERROR;
     val->assign(temp, len);
@@ -84,16 +85,16 @@
     template<class T> class vector {
         %typemap(in) vector< T > (std::vector< T > *v) {
             Tcl_Obj **listobjv;
-            int       nitems;
-            int       i;
+            Tcl_Size  nitems;
+            Tcl_Size  i;
             T*        temp;
 
-            if (SWIG_ConvertPtr($input, (void **) &v, \
+            if (SWIG_ConvertPtr($input, (void **) &v,
                                 $&1_descriptor, 0) == 0){
                 $1 = *v;
             } else {
                 // It isn't a vector< T > so it should be a list of T's
-                if(Tcl_ListObjGetElements(interp, $input, \
+                if(Tcl_ListObjGetElements(interp, $input,
                                           &nitems, &listobjv) == TCL_ERROR)
                     return TCL_ERROR;
                 $1 = std::vector< T >();
@@ -113,12 +114,12 @@
         %typemap(in) const vector< T >* (std::vector< T > *v, std::vector< T > w),
                      const vector< T >& (std::vector< T > *v, std::vector< T > w) {
             Tcl_Obj **listobjv;
-            int       nitems;
-            int       i;
+            Tcl_Size  nitems;
+            Tcl_Size  i;
             T*        temp;
 
-            if(SWIG_ConvertPtr($input, (void **) &v, \
-                               $&1_descriptor, 0) == 0) {
+            if(SWIG_ConvertPtr($input, (void **) &v,
+                               $1_descriptor, 0) == 0) {
                 $1 = v;
             } else {
                 // It isn't a vector< T > so it should be a list of T's
@@ -143,7 +144,7 @@
         %typemap(out) vector< T > {
             for (unsigned int i=0; i<$1.size(); i++) {
                 T* ptr = new T((($1_type &)$1)[i]);
-                Tcl_ListObjAppendElement(interp, $result, \
+                Tcl_ListObjAppendElement(interp, $result,
                                          SWIG_NewInstanceObj(ptr, 
                                                              $descriptor(T *), 
                                                              0));
@@ -152,11 +153,11 @@
 
         %typecheck(SWIG_TYPECHECK_VECTOR) vector< T > {
             Tcl_Obj **listobjv;
-            int       nitems;
+            Tcl_Size  nitems;
             T*        temp;
             std::vector< T > *v;
             
-            if(SWIG_ConvertPtr($input, (void **) &v, \
+            if(SWIG_ConvertPtr($input, (void **) &v,
                                $&1_descriptor, 0) == 0) {
                 /* wrapped vector */
                 $1 = 1;
@@ -168,7 +169,7 @@
                 else
                     if (nitems == 0)
                         $1 = 1;
-                //check the first value to see if it is of correct type
+                    //check the first value to see if it is of correct type
                     else if ((SWIG_ConvertPtr(listobjv[0],
                                               (void **) &temp, 
                                               $descriptor(T *),0)) != 0)
@@ -181,11 +182,11 @@
         %typecheck(SWIG_TYPECHECK_VECTOR) const vector< T >&,
                                           const vector< T >* {
             Tcl_Obj **listobjv;
-            int       nitems;
+            Tcl_Size   nitems;
             T*         temp;
             std::vector< T > *v;
 
-            if(SWIG_ConvertPtr($input, (void **) &v, \
+            if(SWIG_ConvertPtr($input, (void **) &v,
                                $1_descriptor, 0) == 0){
                 /* wrapped vector */
                 $1 = 1;
@@ -197,7 +198,7 @@
                 else
                     if (nitems == 0)
                         $1 = 1;
-                //check the first value to see if it is of correct type
+                    //check the first value to see if it is of correct type
                     else if ((SWIG_ConvertPtr(listobjv[0],
                                               (void **) &temp,
                                               $descriptor(T *),0)) != 0)
@@ -260,11 +261,11 @@
 
         %typemap(in) vector< T > (std::vector< T > *v){
             Tcl_Obj **listobjv;
-            int       nitems;
-            int       i;
+            Tcl_Size  nitems;
+            Tcl_Size  i;
             T         temp;
 
-            if(SWIG_ConvertPtr($input, (void **) &v, \
+            if(SWIG_ConvertPtr($input, (void **) &v,
                                $&1_descriptor, 0) == 0) {
                 $1 = *v;
             } else {
@@ -284,11 +285,11 @@
         %typemap(in) const vector< T >& (std::vector< T > *v,std::vector< T > w),
                      const vector< T >* (std::vector< T > *v,std::vector< T > w) {
             Tcl_Obj **listobjv;
-            int       nitems;
-            int       i;
+            Tcl_Size  nitems;
+            Tcl_Size  i;
             T         temp;
 
-            if(SWIG_ConvertPtr($input, (void **) &v, \
+            if(SWIG_ConvertPtr($input, (void **) &v,
                                $1_descriptor, 0) == 0) {
                 $1 = v;
             } else {
@@ -308,18 +309,18 @@
 
         %typemap(out) vector< T > {
             for (unsigned int i=0; i<$1.size(); i++) {
-                Tcl_ListObjAppendElement(interp, $result, \
+                Tcl_ListObjAppendElement(interp, $result,
                                          CONVERT_TO((($1_type &)$1)[i]));
             }
         }
        
         %typecheck(SWIG_TYPECHECK_VECTOR) vector< T > {
             Tcl_Obj **listobjv;
-            int       nitems;
+            Tcl_Size  nitems;
             T         temp;
             std::vector< T > *v;
 
-            if(SWIG_ConvertPtr($input, (void **) &v, \
+            if(SWIG_ConvertPtr($input, (void **) &v,
                                $&1_descriptor, 0) == 0){
                 /* wrapped vector */
                 $1 = 1;
@@ -331,22 +332,22 @@
                 else
                     if (nitems == 0)
                         $1 = 1;
-                //check the first value to see if it is of correct type
-                if (CONVERT_FROM(interp, listobjv[0], &temp) == TCL_ERROR)
-                    $1 = 0;
-                else
-                    $1 = 1;
+                    //check the first value to see if it is of correct type
+                    else if (CONVERT_FROM(interp, listobjv[0], &temp) == TCL_ERROR)
+                        $1 = 0;
+                    else
+                        $1 = 1;
             }
         }      
 
         %typecheck(SWIG_TYPECHECK_VECTOR) const vector< T >&,
 	                                      const vector< T >*{
             Tcl_Obj **listobjv;
-            int       nitems;
+            Tcl_Size  nitems;
             T         temp;
             std::vector< T > *v;
 
-            if(SWIG_ConvertPtr($input, (void **) &v, \
+            if(SWIG_ConvertPtr($input, (void **) &v,
                                $1_descriptor, 0) == 0){
                 /* wrapped vector */
                 $1 = 1;
@@ -358,11 +359,11 @@
                 else
                     if (nitems == 0)
                         $1 = 1;
-                //check the first value to see if it is of correct type
-                if (CONVERT_FROM(interp, listobjv[0], &temp) == TCL_ERROR)
-                    $1 = 0;
-                else
-                    $1 = 1;
+                    //check the first value to see if it is of correct type
+                    else if (CONVERT_FROM(interp, listobjv[0], &temp) == TCL_ERROR)
+                        $1 = 0;
+                    else
+                        $1 = 1;
             }
         }
         
@@ -412,7 +413,7 @@
     };
     %enddef
 
-    specialize_std_vector(bool, Tcl_GetBoolFromObj, Tcl_NewBooleanObj);
+    specialize_std_vector(bool, SWIG_Tcl_GetBoolFromObj, Tcl_NewBooleanObj);
     specialize_std_vector(char, SwigInt_As<char>,Tcl_NewIntObj);
     specialize_std_vector(int, Tcl_GetIntFromObj,Tcl_NewIntObj);
     specialize_std_vector(short, SwigInt_As<short>, Tcl_NewIntObj);
diff --git a/Lib/tcl/swigmove.i b/Lib/tcl/swigmove.i
new file mode 100644
index 0000000..62ecca7
--- /dev/null
+++ b/Lib/tcl/swigmove.i
@@ -0,0 +1 @@
+%include <typemaps/swigmove.swg>
diff --git a/Lib/tcl/tclapi.swg b/Lib/tcl/tclapi.swg
index 2187de5..03c3967 100644
--- a/Lib/tcl/tclapi.swg
+++ b/Lib/tcl/tclapi.swg
@@ -23,8 +23,8 @@
     swig_type_info **ptype;
 } swig_const_info;
 
-typedef int   (*swig_wrapper)(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []);
-typedef int   (*swig_wrapper_func)(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []);
+typedef int   (*swig_wrapper)(ClientData, Tcl_Interp *, int, Tcl_Obj *const []);
+typedef int   (*swig_wrapper_func)(ClientData, Tcl_Interp *, int, Tcl_Obj *const []);
 typedef char *(*swig_variable_func)(ClientData, Tcl_Interp *, char *, char *, int);
 typedef void  (*swig_delete_func)(ClientData);
 
@@ -63,7 +63,7 @@
 /* Structure for command table */
 typedef struct {
   const char *name;
-  int       (*wrapper)(ClientData, Tcl_Interp *, int, Tcl_Obj *CONST []);
+  int       (*wrapper)(ClientData, Tcl_Interp *, int, Tcl_Obj *const []);
   ClientData  clientdata;
 } swig_command_info;
 
diff --git a/Lib/tcl/tclerrors.swg b/Lib/tcl/tclerrors.swg
index 889d3ad..73d73f8 100644
--- a/Lib/tcl/tclerrors.swg
+++ b/Lib/tcl/tclerrors.swg
@@ -51,15 +51,15 @@
 {
   Tcl_ResetResult(interp);
   Tcl_SetObjResult(interp, obj);
-  Tcl_SetErrorCode(interp, "SWIG", ctype, NULL);
+  Tcl_SetErrorCode(interp, "SWIG", ctype, (char *)NULL);
 }
 
 SWIGINTERN void
 SWIG_Tcl_SetErrorMsg(Tcl_Interp *interp, const char *ctype, const char *mesg)
 {
   Tcl_ResetResult(interp);
-  Tcl_SetErrorCode(interp, "SWIG", ctype, NULL);
-  Tcl_AppendResult(interp, ctype, " ", mesg, NULL);
+  Tcl_SetErrorCode(interp, "SWIG", ctype, (char *)NULL);
+  Tcl_AppendResult(interp, ctype, " ", mesg, (char *)NULL);
   /*
   Tcl_AddErrorInfo(interp, ctype);
   Tcl_AddErrorInfo(interp, " ");
diff --git a/Lib/tcl/tclinit.swg b/Lib/tcl/tclinit.swg
index 3140bdc..eb9e3ec 100644
--- a/Lib/tcl/tclinit.swg
+++ b/Lib/tcl/tclinit.swg
@@ -24,7 +24,7 @@
 
 /* Compatibility version for TCL stubs */
 #ifndef SWIG_TCL_STUBS_VERSION
-#define SWIG_TCL_STUBS_VERSION "8.1"
+#define SWIG_TCL_STUBS_VERSION "8.4-"
 #endif
 
 %}
@@ -100,8 +100,7 @@
   size_t i;
   if (interp == 0) return TCL_ERROR;
 #ifdef USE_TCL_STUBS
-  /* (char*) cast is required to avoid compiler warning/error for Tcl < 8.4. */
-  if (Tcl_InitStubs(interp, (char*)SWIG_TCL_STUBS_VERSION, 0) == NULL) {
+  if (Tcl_InitStubs(interp, SWIG_TCL_STUBS_VERSION, 0) == NULL) {
     return TCL_ERROR;
   }
 #endif  
diff --git a/Lib/tcl/tclprimtypes.swg b/Lib/tcl/tclprimtypes.swg
index 3b6d04f..ddefa7d 100644
--- a/Lib/tcl/tclprimtypes.swg
+++ b/Lib/tcl/tclprimtypes.swg
@@ -61,7 +61,7 @@
     return SWIG_From(long)(%numeric_cast(value, long));
   } else {
     char temp[256]; 
-    sprintf(temp, "%lu", value);
+    SWIG_snprintf(temp, sizeof(temp), "%lu", value);
     return Tcl_NewStringObj(temp,-1);
   }
 }
@@ -82,7 +82,7 @@
        get it as a string so we can distinguish these cases. */
   }
   {
-    int len = 0;
+    Tcl_Size len = 0;
     const char *nptr = Tcl_GetStringFromObj(obj, &len);
     if (nptr && len > 0) {
       char *endptr;
@@ -122,7 +122,7 @@
     return SWIG_From(long)(%numeric_cast(value,long));
   } else {    
     char temp[256]; 
-    sprintf(temp, "%lld", value);
+    SWIG_snprintf(temp, sizeof(temp), "%lld", value);
     return Tcl_NewStringObj(temp,-1);
   }
 }
@@ -136,30 +136,13 @@
 SWIGINTERN int
 SWIG_AsVal_dec(long long)(Tcl_Obj *obj, long long *val)
 {
-  long v;
-  if (Tcl_GetLongFromObj(0,obj, &v) == TCL_OK) {
+  Tcl_WideInt v;
+  if (Tcl_GetWideIntFromObj(0, obj, &v) == TCL_OK) {
+    if (sizeof(v) > sizeof(*val) && (v < LLONG_MIN || v > LLONG_MAX)) {
+      return SWIG_OverflowError;
+    }
     if (val) *val = v;
     return SWIG_OK;
-  } else {
-    int len = 0;
-    const char *nptr = Tcl_GetStringFromObj(obj, &len);
-    if (nptr && len > 0) {
-      char *endptr;
-      long long v;
-      errno = 0;
-      v = strtoll(nptr, &endptr,0);
-      if (nptr[0] == '\0' || *endptr != '\0')
-	return SWIG_TypeError;
-      if ((v == LLONG_MAX || v == LLONG_MIN) && errno == ERANGE) {
-	errno = 0;
-	return SWIG_OverflowError;
-      } else {
-	if (*endptr == '\0') {
-	  if (val) *val = v;
-	  return SWIG_OK;
-	}
-      }
-    }
   }
   return SWIG_TypeError;
 }
@@ -180,7 +163,7 @@
     return SWIG_From(long long)(%numeric_cast(value, long long));
   } else {
     char temp[256]; 
-    sprintf(temp, "%llu", value);
+    SWIG_snprintf(temp, sizeof(temp), "%llu", value);
     return Tcl_NewStringObj(temp,-1);
   }
 }
@@ -200,7 +183,7 @@
     if (val) *val = (unsigned long) v;
     return SWIG_OK;
   } else {
-    int len = 0;
+    Tcl_Size len = 0;
     const char *nptr = Tcl_GetStringFromObj(obj, &len);
     if (nptr && len > 0) {
       char *endptr;
diff --git a/Lib/tcl/tclrun.swg b/Lib/tcl/tclrun.swg
index 9010b9c..debbd09 100644
--- a/Lib/tcl/tclrun.swg
+++ b/Lib/tcl/tclrun.swg
@@ -67,8 +67,8 @@
 #define SWIG_GetConstant        SWIG_GetConstantObj
 #define SWIG_Tcl_GetConstant    SWIG_Tcl_GetConstantObj
 
-#if TCL_MAJOR_VERSION >= 8 && TCL_MINOR_VERSION >= 5
-#define SWIG_TCL_HASHTABLE_INIT {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
+#if TCL_MAJOR_VERSION > 8 || (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION >= 5)
+#define SWIG_TCL_HASHTABLE_INIT {0, {0, 0, 0, 0}, 0, 0, 0, 0, 0, 0, 0, 0, 0}
 #else
 #define SWIG_TCL_HASHTABLE_INIT {0}
 #endif
@@ -118,10 +118,13 @@
   return 0;
 }
 
+SWIGRUNTIME void SWIG_Tcl_ObjectDelete(ClientData clientData);
+
 /* Convert a pointer value */
 SWIGRUNTIME int
 SWIG_Tcl_ConvertPtrFromString(Tcl_Interp *interp, const char *c, void **ptr, swig_type_info *ty, int flags) {
   swig_cast_info *tc;
+  const char *cmd_name;
   /* Pointer values must start with leading underscore */
   while (*c != '_') {
     *ptr = (void *) 0;
@@ -137,7 +140,7 @@
     /* from being called when c is not a command, firing the unknown proc */
     if (Tcl_VarEval(interp,"info commands ", c, (char *) NULL) == TCL_OK) {
       Tcl_Obj *result = Tcl_GetObjResult(interp);
-      if (*(Tcl_GetStringFromObj(result, NULL)) == 0) {
+      if (*(Tcl_GetString(result)) == 0) {
         /* It's not a command, so it can't be a pointer */
         Tcl_ResetResult(interp);
         return SWIG_ERROR;
@@ -155,32 +158,55 @@
       return SWIG_ERROR;
     }
 
-    c = Tcl_GetStringFromObj(Tcl_GetObjResult(interp), NULL);
+    c = Tcl_GetString(Tcl_GetObjResult(interp));
   }
+  cmd_name = c;
 
   c++;
   c = SWIG_UnpackData(c,ptr,sizeof(void *));
+
   if (ty) {
+    Tcl_CmdInfo info;
     tc = c ? SWIG_TypeCheck(c,ty) : 0;
     if (!tc) {
       return SWIG_ERROR;
     }
-    if (flags & SWIG_POINTER_DISOWN) {
-      SWIG_Disown((void *) *ptr);
-    }
-    {
-      int newmemory = 0;
-      *ptr = SWIG_TypeCast(tc,(void *) *ptr,&newmemory);
-      assert(!newmemory); /* newmemory handling not yet implemented */
+    if (Tcl_GetCommandInfo(interp, cmd_name, &info)) {
+      /* When creating a pointer string, SWIG_Tcl_NewInstanceObj calls Tcl_CreateObjCommand and sets
+       * info.objClientData to an instance of swig_instance. Detecting when we can cast any info.objClientData
+       * to swig_instance is not simple as it may be an unrelated command; we use deleteProc to determine this. */
+      if (info.deleteProc == SWIG_Tcl_ObjectDelete) {
+        swig_instance *inst = (swig_instance *)info.objClientData;
+        if (!inst->thisvalue) {
+          *ptr = 0;
+        }
+        assert(inst->thisvalue == *ptr);
+        if (((flags & SWIG_POINTER_RELEASE) == SWIG_POINTER_RELEASE) && !SWIG_Thisown(inst->thisvalue)) {
+          return SWIG_ERROR_RELEASE_NOT_OWNED;
+        } else {
+          if (flags & SWIG_POINTER_DISOWN) {
+            SWIG_Disown((void *) *ptr);
+          }
+          if (flags & SWIG_POINTER_CLEAR) {
+            inst->thisvalue = 0;
+          }
+          {
+            int newmemory = 0;
+            *ptr = SWIG_TypeCast(tc,(void *) *ptr, &newmemory);
+            assert(!newmemory); /* newmemory handling not yet implemented */
+          }
+        }
+      }
     }
   }
+
   return SWIG_OK;
 }
 
 /* Convert a pointer value */
 SWIGRUNTIMEINLINE int
 SWIG_Tcl_ConvertPtr(Tcl_Interp *interp, Tcl_Obj *oc, void **ptr, swig_type_info *ty, int flags) {
-  return SWIG_Tcl_ConvertPtrFromString(interp, Tcl_GetStringFromObj(oc,NULL), ptr, ty, flags);
+  return SWIG_Tcl_ConvertPtrFromString(interp, Tcl_GetString(oc), ptr, ty, flags);
 }
 
 /* Convert a pointer value */
@@ -207,7 +233,7 @@
   const char  *c;
 
   if (!obj) goto type_error;
-  c = Tcl_GetStringFromObj(obj,NULL);
+  c = Tcl_GetString(obj);
   /* Pointer values must start with leading underscore */
   if (*c != '_') goto type_error;
   c++;
@@ -306,7 +332,7 @@
 
 /* Function to invoke object methods given an instance */
 SWIGRUNTIME int
-SWIG_Tcl_MethodCommand(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST _objv[]) {
+SWIG_Tcl_MethodCommand(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const _objv[]) {
   char *method,   *attrname;
   swig_instance   *inst = (swig_instance *) clientData;
   swig_method     *meth;
@@ -326,7 +352,7 @@
     Tcl_SetResult(interp, (char *) "wrong # args.", TCL_STATIC);
     return TCL_ERROR;
   }
-  method = Tcl_GetStringFromObj(objv[1],NULL);
+  method = Tcl_GetString(objv[1]);
   if (strcmp(method,"-acquire") == 0) {
     inst->destroy = 1;
     SWIG_Acquire(inst->thisvalue);
@@ -389,7 +415,7 @@
         Tcl_SetResult(interp, (char *) "wrong # args.", TCL_STATIC);
         return TCL_ERROR;
       }
-      attrname = Tcl_GetStringFromObj(objv[2],NULL);
+      attrname = Tcl_GetString(objv[2]);
       attr = cls->attributes;
       while (attr && attr->name) {
         if ((strcmp(attr->name, attrname) == 0) && (attr->getmethod)) {
@@ -423,7 +449,7 @@
       }
       i = 2;
       while (i < objc) {
-        attrname = Tcl_GetStringFromObj(objv[i],NULL);
+        attrname = Tcl_GetString(objv[i]);
         attr = cls->attributes;
         while (attr && attr->name) {
           if ((strcmp(attr->name, attrname) == 0) && (attr->setmethod)) {
@@ -490,19 +516,30 @@
   /* Check to see if this pointer belongs to a class or not */
   if (thisvalue && (type->clientdata) && (interp)) {
     Tcl_CmdInfo    ci;
+    int has_command;
     char          *name;
-    name = Tcl_GetStringFromObj(robj,NULL);
-    if (!Tcl_GetCommandInfo(interp,name, &ci) || (flags)) {
+    name = Tcl_GetString(robj);
+    has_command = Tcl_GetCommandInfo(interp, name, &ci);
+    if (!has_command || flags) {
       swig_instance *newinst = (swig_instance *) malloc(sizeof(swig_instance));
       newinst->thisptr = Tcl_DuplicateObj(robj);
       Tcl_IncrRefCount(newinst->thisptr);
       newinst->thisvalue = thisvalue;
       newinst->classptr = (swig_class *) type->clientdata;
       newinst->destroy = flags;
-      newinst->cmdtok = Tcl_CreateObjCommand(interp, Tcl_GetStringFromObj(robj,NULL), (swig_wrapper_func) SWIG_MethodCommand, (ClientData) newinst, (swig_delete_func) SWIG_ObjectDelete);
+      newinst->cmdtok = Tcl_CreateObjCommand(interp, Tcl_GetString(robj), (swig_wrapper_func) SWIG_Tcl_MethodCommand, (ClientData) newinst, (swig_delete_func) SWIG_Tcl_ObjectDelete);
       if (flags) {
         SWIG_Acquire(thisvalue);
       }
+    } else {
+      swig_instance *inst = (swig_instance *)ci.objClientData;
+      /* Restore thisvalue as SWIG_POINTER_CLEAR may have been used to set it to zero.
+         Occurs when the C pointer is re-used by the memory allocator and the command has
+         been created and not destroyed - bug?? - see cpp11_std_unique_ptr_runme.tcl test. */
+      if (inst->thisvalue != thisvalue) {
+        assert(inst->thisvalue == 0);
+        inst->thisvalue = thisvalue;
+      }
     }
   }
   return robj;
@@ -510,7 +547,7 @@
 
 /* Function to create objects */
 SWIGRUNTIME int
-SWIG_Tcl_ObjectConstructor(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {
+SWIG_Tcl_ObjectConstructor(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) {
   Tcl_Obj          *newObj = 0;
   void             *thisvalue = 0;
   swig_instance   *newinst = 0;
@@ -527,7 +564,7 @@
   }
   cons = classptr->constructor;
   if (objc > 1) {
-    char *s = Tcl_GetStringFromObj(objv[1],NULL);
+    char *s = Tcl_GetString(objv[1]);
     if (strcmp(s,"-this") == 0) {
       thisarg = 2;
       cons = 0;
@@ -539,7 +576,7 @@
     } else if (objc >= 3) {
       char *s1;
       name = s;
-      s1 = Tcl_GetStringFromObj(objv[2],NULL);
+      s1 = Tcl_GetString(objv[2]);
       if (strcmp(s1,"-this") == 0) {
 	thisarg = 3;
 	cons = 0;
@@ -555,12 +592,12 @@
       return result;
     }
     newObj = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
-    if (!name) name = Tcl_GetStringFromObj(newObj,NULL);
+    if (!name) name = Tcl_GetString(newObj);
   } else if (thisarg > 0) {
     if (thisarg < objc) {
       destroy = 0;
       newObj = Tcl_DuplicateObj(objv[thisarg]);
-      if (!name) name = Tcl_GetStringFromObj(newObj,NULL);
+      if (!name) name = Tcl_GetString(newObj);
     } else {
       Tcl_SetResult(interp, (char *) "wrong # args.", TCL_STATIC);
       return TCL_ERROR;
@@ -582,7 +619,7 @@
   if (destroy) {
     SWIG_Acquire(thisvalue);
   }
-  newinst->cmdtok = Tcl_CreateObjCommand(interp,name, (swig_wrapper) SWIG_MethodCommand, (ClientData) newinst, (swig_delete_func) SWIG_ObjectDelete);
+  newinst->cmdtok = Tcl_CreateObjCommand(interp,name, (swig_wrapper) SWIG_Tcl_MethodCommand, (ClientData) newinst, (swig_delete_func) SWIG_Tcl_ObjectDelete);
   return TCL_OK;
 }
 
@@ -590,7 +627,7 @@
  *   Get arguments 
  * -----------------------------------------------------------------------------*/
 SWIGRUNTIME int
-SWIG_Tcl_GetArgs(Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[], const char *fmt, ...) {
+SWIG_Tcl_GetArgs(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], const char *fmt, ...) {
   int        argno = 0, opt = 0;
   long       tempi;
   double     tempd;
@@ -619,7 +656,7 @@
     vptr = va_arg(ap,void *);
     if (vptr) {
       if (isupper(*c)) {
-        obj = SWIG_Tcl_GetConstantObj(Tcl_GetStringFromObj(objv[argno+1],0));
+        obj = SWIG_Tcl_GetConstantObj(Tcl_GetString(objv[argno+1]));
         if (!obj) obj = objv[argno+1];
       } else {
         obj = objv[argno+1];
@@ -643,15 +680,15 @@
         break;
       case 's': case 'S':
         if (*(c+1) == '#') {
-          int *vlptr = (int *) va_arg(ap, void *);
+          Tcl_Size *vlptr = (Tcl_Size *) va_arg(ap, void *);
           *((char **) vptr) = Tcl_GetStringFromObj(obj, vlptr);
           c++;
         } else {
-          *((char **)vptr) = Tcl_GetStringFromObj(obj,NULL);
+          *((char **)vptr) = Tcl_GetString(obj);
         }
         break;
       case 'c': case 'C':
-        *((char *)vptr) = *(Tcl_GetStringFromObj(obj,NULL));
+        *((char *)vptr) = *(Tcl_GetString(obj));
         break;
       case 'p': case 'P':
         ty = (swig_type_info *) va_arg(ap, void *);
@@ -676,11 +713,11 @@
  argerror:
   {
     char temp[32];
-    sprintf(temp,"%d", argno+1);
+    SWIG_snprintf(temp, sizeof(temp), "%d", argno+1);
     c = strchr(fmt,':');
     if (!c) c = strchr(fmt,';');
     if (!c) c = (char *)"";
-    Tcl_AppendResult(interp,c," argument ", temp, NULL);
+    Tcl_AppendResult(interp,c," argument ", temp, (char *)NULL);
     va_end(ap);
     return TCL_ERROR;
   }
diff --git a/Lib/tcl/tclruntime.swg b/Lib/tcl/tclruntime.swg
index bb4edd7..3b34a76 100644
--- a/Lib/tcl/tclruntime.swg
+++ b/Lib/tcl/tclruntime.swg
@@ -6,6 +6,22 @@
 #include <stdlib.h>
 #include <stdarg.h>
 #include <ctype.h>
+
+/* Check, if Tcl version supports Tcl_Size,
+   which was introduced in Tcl 8.7 and 9.
+*/
+#ifndef TCL_SIZE_MAX
+    #include <limits.h>
+    #define TCL_SIZE_MAX INT_MAX
+
+    #ifndef Tcl_Size
+        typedef int Tcl_Size;
+    #endif
+
+    #define TCL_SIZE_MODIFIER ""
+    #define Tcl_GetSizeIntFromObj Tcl_GetIntFromObj
+    #define Tcl_NewSizeIntObj     Tcl_NewIntObj
+#endif
 %}
 
 %insert(runtime) "swigrun.swg";         /* Common C API type-checking code */
diff --git a/Lib/tcl/tclsh.i b/Lib/tcl/tclsh.i
index 160ba8d..e908756 100644
--- a/Lib/tcl/tclsh.i
+++ b/Lib/tcl/tclsh.i
@@ -4,20 +4,15 @@
  * SWIG File for building new tclsh program
  * ----------------------------------------------------------------------------- */
 
-#ifdef AUTODOC
-%subsection "tclsh.i"
-%text %{
-This module provides the Tcl_AppInit() function needed to build a 
-new version of the tclsh executable.   This file should not be used
-when using dynamic loading.   To make an interface file work with
-both static and dynamic loading, put something like this in your
-interface file :
-
-     #ifdef STATIC
-     %include <tclsh.i>
-     #endif
-%}
-#endif
+// This module provides the Tcl_AppInit() function needed to build a
+// new version of the tclsh executable.   This file should not be used
+// when using dynamic loading.   To make an interface file work with
+// both static and dynamic loading, put something like this in your
+// interface file :
+//
+//      #ifdef STATIC
+//      %include <tclsh.i>
+//      #endif
 
 %{
 
@@ -33,10 +28,6 @@
 #endif
 
 
-#ifdef MAC_TCL
-extern int		MacintoshInit _ANSI_ARGS_((void));
-#endif
-
 int Tcl_AppInit(Tcl_Interp *interp){
 
   if (Tcl_Init(interp) == TCL_ERROR) 
@@ -46,40 +37,16 @@
 
   if (SWIG_init(interp) == TCL_ERROR)
     return TCL_ERROR;
-#if TCL_MAJOR_VERSION > 7 || TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION >= 5
-   Tcl_SetVar(interp, (char *) "tcl_rcFileName",SWIG_RcFileName,TCL_GLOBAL_ONLY);
-#else
-   tcl_RcFileName = SWIG_RcFileName;
-#endif
-#ifdef SWIG_RcRsrcName
-  Tcl_SetVar(interp, (char *) "tcl_rcRsrcName",SWIG_RcRsrcName,TCL_GLOBAL);
-#endif
-  
+  Tcl_SetVar(interp, (char *) "tcl_rcFileName",SWIG_RcFileName,TCL_GLOBAL_ONLY);
+
   return TCL_OK;
 }
 
-#if TCL_MAJOR_VERSION > 7 || TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION >= 4
 int main(int argc, char **argv) {
-#ifdef MAC_TCL
-    char *newArgv[2];
-    
-    if (MacintoshInit()  != TCL_OK) {
-	Tcl_Exit(1);
-    }
-
-    argc = 1;
-    newArgv[0] = "tclsh";
-    newArgv[1] = NULL;
-    argv = newArgv;
-#endif
-
   Tcl_Main(argc, argv, Tcl_AppInit);
   return(0);
 
 }
-#else
-extern int main();
-#endif
 
 %}
 
diff --git a/Lib/tcl/tclstrings.swg b/Lib/tcl/tclstrings.swg
index 540d627..738c813 100644
--- a/Lib/tcl/tclstrings.swg
+++ b/Lib/tcl/tclstrings.swg
@@ -6,7 +6,7 @@
 SWIGINTERN int
 SWIG_AsCharPtrAndSize(Tcl_Obj *obj, char** cptr, size_t* psize, int *alloc)
 { 
-  int len = 0;
+  Tcl_Size len = 0;
   char *cstr = Tcl_GetStringFromObj(obj, &len);
   if (cstr) {
     if (cptr)  *cptr = cstr;
@@ -24,7 +24,7 @@
 SWIGINTERNINLINE Tcl_Obj *
 SWIG_FromCharPtrAndSize(const char* carray, size_t size)
 {
-  return (size < INT_MAX) ? Tcl_NewStringObj(carray, %numeric_cast(size,int)) : NULL;
+  return (size < TCL_SIZE_MAX) ? Tcl_NewStringObj(carray, %numeric_cast(size,Tcl_Size)) : NULL;
 }
 }
 
diff --git a/Lib/tcl/tcltypemaps.swg b/Lib/tcl/tcltypemaps.swg
index ad31bcf..66cce47 100644
--- a/Lib/tcl/tcltypemaps.swg
+++ b/Lib/tcl/tcltypemaps.swg
@@ -77,11 +77,6 @@
 
 #endif
 
-%typemap(throws,noblock=1) SWIGTYPE CLASS {
-  SWIG_set_result(SWIG_NewInstanceObj(%as_voidptr(SWIG_new_copy($1, $1_ltype)), $&1_descriptor, 1));
-  SWIG_fail;
-}
-
 %typemap(out)    SWIGTYPE    =  SWIGTYPE INSTANCE;
 %typemap(out)    SWIGTYPE *  =  SWIGTYPE *INSTANCE;
 %typemap(out)    SWIGTYPE *const  =  SWIGTYPE *;
diff --git a/Lib/tcl/tclwstrings.swg b/Lib/tcl/tclwstrings.swg
index b3b682e..76da2ab 100644
--- a/Lib/tcl/tclwstrings.swg
+++ b/Lib/tcl/tclwstrings.swg
@@ -12,14 +12,14 @@
 SWIGINTERN int
 SWIG_AsWCharPtrAndSize(Tcl_Obj *obj, wchar_t** cptr, size_t* psize, int *alloc)
 { 
-  int len = 0;
+  Tcl_Size len = 0;
   Tcl_UniChar *ustr = Tcl_GetUnicodeFromObj(obj, &len);
   if (ustr) {
     if (cptr)  {
       Tcl_Encoding encoding = NULL;
       char *src = (char *) ustr;
-      int srcLen = (len)*sizeof(Tcl_UniChar);
-      int dstLen = sizeof(wchar_t)*(len + 1);
+      Tcl_Size srcLen = (len)*sizeof(Tcl_UniChar);
+      Tcl_Size dstLen = sizeof(wchar_t)*(len + 1);
       char *dst = %new_array(dstLen, char);
       int flags = 0;
       Tcl_EncodingState *statePtr = 0;
@@ -29,6 +29,7 @@
       Tcl_UtfToExternal(0, encoding, src, srcLen, flags, statePtr, dst,
 			dstLen, &srcRead, &dstWrote, &dstChars);
       
+      *cptr = (wchar_t*)dst;
       if (alloc) *alloc = SWIG_NEWOBJ;
     }
     if (psize) *psize = len + 1;
@@ -43,11 +44,11 @@
 SWIG_FromWCharPtrAndSize(const wchar_t* carray, size_t size)
 {
   Tcl_Obj *res = NULL;
-  if (size < INT_MAX) {
+  if (size < TCL_SIZE_MAX) {
     Tcl_Encoding encoding = NULL;
     char *src = (char *) carray;
-    int srcLen = (int)(size*sizeof(wchar_t));
-    int dstLen = (int)(size*sizeof(Tcl_UniChar));
+    Tcl_Size srcLen = (Tcl_Size)(size*sizeof(wchar_t));
+    Tcl_Size dstLen = (Tcl_Size)(size*sizeof(Tcl_UniChar));
     char *dst = %new_array(dstLen, char);
     int flags = 0;
     Tcl_EncodingState *statePtr = 0;
@@ -58,7 +59,7 @@
     Tcl_ExternalToUtf(0, encoding, src, srcLen, flags, statePtr, dst,
 		      dstLen, &srcRead, &dstWrote, &dstChars);
     
-    res = Tcl_NewUnicodeObj((Tcl_UniChar*)dst, (int)size);
+    res = Tcl_NewUnicodeObj((Tcl_UniChar*)dst, (Tcl_Size)size);
     %delete_array(dst);
   }
   return res;
diff --git a/Lib/tcl/typemaps.i b/Lib/tcl/typemaps.i
index 04a5c78..4f42cfc 100644
--- a/Lib/tcl/typemaps.i
+++ b/Lib/tcl/typemaps.i
@@ -164,14 +164,14 @@
 %typemap(in) long long *INPUT($*1_ltype temp), 
              long long &INPUT($*1_ltype temp)
 {
-  temp = ($*1_ltype) strtoll(Tcl_GetStringFromObj($input,NULL),0,0);
+  temp = ($*1_ltype) strtoll(Tcl_GetString($input),0,0);
   $1 = &temp;
 }
 
 %typemap(in) unsigned long long *INPUT($*1_ltype temp), 
              unsigned long long &INPUT($*1_ltype temp)
 {
-  temp = ($*1_ltype) strtoull(Tcl_GetStringFromObj($input,NULL),0,0);
+  temp = ($*1_ltype) strtoull(Tcl_GetString($input),0,0);
   $1 = &temp;
 }
   
@@ -275,7 +275,7 @@
 {
   char temp[256];
   Tcl_Obj *o;
-  sprintf(temp,"%lld",(long long)*($1));
+  SWIG_snprintf(temp,sizeof(temp),"%lld",(long long)*($1));
   o = Tcl_NewStringObj(temp,-1);
   Tcl_ListObjAppendElement(interp,Tcl_GetObjResult(interp),o);
 }
@@ -284,7 +284,7 @@
 {
   char temp[256];
   Tcl_Obj *o;
-  sprintf(temp,"%llu",(unsigned long long)*($1));
+  SWIG_snprintf(temp,sizeof(temp),"%llu",(unsigned long long)*($1));
   o = Tcl_NewStringObj(temp,-1);
   Tcl_ListObjAppendElement(interp,Tcl_GetObjResult(interp),o);
 }
diff --git a/Lib/tcl/wish.i b/Lib/tcl/wish.i
index 260032a..6969b2a 100644
--- a/Lib/tcl/wish.i
+++ b/Lib/tcl/wish.i
@@ -4,25 +4,20 @@
  * SWIG File for making wish
  * ----------------------------------------------------------------------------- */
 
-#ifdef AUTODOC
-%subsection "wish.i"
-%text %{
-This module provides the Tk_AppInit() function needed to build a 
-new version of the wish executable.   Like tclsh.i, this file should
-not be used with dynamic loading.  To make an interface file work with
-both static and dynamic loading, put something like this in your
-interface file :
-
-     #ifdef STATIC
-     %include <wish.i>
-     #endif
-
-A startup file may be specified by defining the symbol SWIG_RcFileName
-as follows (this should be included in a code-block) :
-
-     #define SWIG_RcFileName    "~/.mywishrc"
-%}
-#endif
+// This module provides the Tk_AppInit() function needed to build a
+// new version of the wish executable.   Like tclsh.i, this file should
+// not be used with dynamic loading.  To make an interface file work with
+// both static and dynamic loading, put something like this in your
+// interface file :
+//
+//      #ifdef STATIC
+//      %include <wish.i>
+//      #endif
+//
+// A startup file may be specified by defining the symbol SWIG_RcFileName
+// as follows (this should be included in a code-block) :
+//
+//      #define SWIG_RcFileName    "~/.mywishrc"
 
 %{
 
@@ -35,11 +30,6 @@
 char *SWIG_RcFileName = "~/.wishrc";
 #endif
 
-#ifdef MAC_TCL
-extern int	MacintoshInit _ANSI_ARGS_((void));
-extern int	SetupMainInterp _ANSI_ARGS_((Tcl_Interp *interp));
-#endif
-
 /*
  *----------------------------------------------------------------------
  *
@@ -61,10 +51,9 @@
 
 int Tcl_AppInit(Tcl_Interp *interp)
 {
-#ifndef MAC_TCL
     Tk_Window main;
     main = Tk_MainWindow(interp);
-#endif
+
     /*
      * Call the init procedures for included packages.  Each call should
      * look like this:
@@ -93,10 +82,6 @@
       return TCL_ERROR;
     }
     
-#ifdef MAC_TCL
-    SetupMainInterp(interp);
-#endif
-        
     /*
      * Specify a user-specific startup file to invoke if the application
      * is run interactively.  Typically the startup file is "~/.apprc"
@@ -104,35 +89,12 @@
      * then no user-specific startup file will be run under any conditions.
      */
 
-#if TCL_MAJOR_VERSION >= 8 || TCL_MAJOR_VERSION == 7 && TCL_MINOR_VERSION >= 5
-   Tcl_SetVar(interp, (char *) "tcl_rcFileName",SWIG_RcFileName,TCL_GLOBAL_ONLY);
-#else
-   tcl_RcFileName = SWIG_RcFileName;
-#endif
-
-/* For Macintosh might also want this */
-
-#ifdef MAC_TCL
-#ifdef SWIG_RcRsrcName
-    Tcl_SetVar(interp, (char *) "tcl_rcRsrcName",SWIG_RcRsrcName,TCL_GLOBAL_ONLY);
-#endif
-#endif
+    Tcl_SetVar(interp, (char *) "tcl_rcFileName",SWIG_RcFileName,TCL_GLOBAL_ONLY);
     return TCL_OK;
 }
 
 #if TK_MAJOR_VERSION >= 4
 int main(int argc, char **argv) {
-
-#ifdef MAC_TCL
-  char *newArgv[2];
-  if (MacintoshInit() != TCL_OK) {
-      Tcl_Exit(1);
-  }
-  argc = 1;
-  newArgv[0] = "Wish";
-  newArgv[1] = NULL;
-  argv = newArgv;
-#endif
   Tk_Main(argc, argv, Tcl_AppInit);
   return(0);
 }
diff --git a/Lib/typemaps/attribute.swg b/Lib/typemaps/attribute.swg
index 9881139..abdf44d 100644
--- a/Lib/typemaps/attribute.swg
+++ b/Lib/typemaps/attribute.swg
@@ -7,132 +7,6 @@
 /*
   The following macros convert a pair of set/get methods
   into a "native" attribute.
-
-  Use %attribute when you have a pair of get/set methods to a primitive type
-  like in:
-
-      %attribute(A, int, a, get_a, set_a);
-
-      struct A
-      {
-        int get_a() const;
-        void set_a(int aa);
-      };
-
-  If you don't provide a 'set' method, a 'read-only' attribute
-  is generated, ie, like in:
-
-      %attribute(A, int, c, get_c);
-
-  Use %attributeref when you have const/non-const reference access methods
-  for primitive types or class/structs, like in:
-
-      %attributeref(A, int, b);
-
-      struct A
-      {
-        const int& b() const;
-        int& b();
-      };
-
-      %attributeref(B, int, c);
-
-      struct B
-      {
-        int& c();
-      };
-
-  You can also use
-
-      %attributeref(Class, AttributeType, AttributeName, AccessorMethod)
-
-  if the internal C++ reference methods have a different name from the
-  attribute you want, so
-
-      %attributeref(B, int, d, c);
-
-  is the same as the last example, but instead of the attribute 'c' being
-  called 'c', it is called 'd'.
-
-  Now you can use the attributes like so:
-
-      x = A()
-      x.a = 3        # calls A::set_a
-      print x.a      # calls A::get_a
-
-      x.b = 3        # calls A::b()
-      print x.b      # calls A::b() const
-
-  Use %attribute2 instead of %attribute to indicate that reference-pointer
-  translation is required. You use %attribute2 instead of %attribute in
-  cases like this:
- 
-  %attribute2(MyClass, MyFoo, Foo, GetFoo, SetFoo);
-  %inline %{
-    struct MyFoo { 
-      int x;
-    };
-    class MyClass {
-      MyFoo foo;
-    public:
-      MyFoo& GetFoo() { return foo; }
-      void SetFoo(const MyFoo& other) { foo = other; }
-    };
-  %}
-
-  Here, the data type of the property is a wrapped type (MyFoo) and on the
-  C++ side it is passed by reference. The problem is that the SWIG wrapper will
-  pass around a pointer (MyFoo *) which is not compatible with the reference
-  type of the accessors (MyFoo &). Therefore, if you use %attribute, you'll get
-  an error from your C/C++ compiler. %attribute2 translates between a pointer
-  and a reference to eliminate the error. In case you're confused, let's make it
-  simple: just use %attribute at first, but if the C/C++ compiler gives an error
-  while compiling the wrapper, try %attribute2 instead.
-
-  NOTE: remember that if the type contains commas, such as 'std::pair<int,int>',
-  you need to use the macro like:
-
-  %attributeref(A, %arg(std::pair<int,int>), pval);
-
-  where %arg() 'normalizes' the type to be understood as a single
-  argument, otherwise the macro will get confused by the comma.
-
-  The %attributeval is the same as %attribute, but should be used when the type
-  is a class/struct (ie a non-primitive type) and when the get and set methods 
-  return/pass by value. The following is very similar to the above example, but 
-  note that the access is by value rather than reference.
-
-    %attributeval(MyClassVal, MyFoo, ReadWriteFoo, GetFoo, SetFoo);
-    %attributeval(MyClassVal, MyFoo, ReadOnlyFoo, GetFoo);
-    %inline %{
-      class MyClassVal {
-	MyFoo foo;
-      public:
-	MyFoo GetFoo() { return foo; }
-	void SetFoo(MyFoo other) { foo = other; }
-      };
-    %} 
-
-  The %attributestring is the same as %attributeval, but should be used for string
-  class types, which are unusual as they are a class on the C++ side, but normally an
-  immutable/primitive type in the target language. Example usage for std::string:
-
-    %include <std_string.i>
-    %attributestring(MyStringyClass, std::string, ReadWriteString, GetString, SetString);
-    %attributestring(MyStringyClass, std::string, ReadOnlyString, GetString);
-    %inline %{
-      class MyStringyClass {
-	std::string str;
-      public:
-	MyStringyClass(const std::string &val) : str(val) {}
-	std::string GetString() { return str; }
-	void SetString(std::string other) { str = other; }
-      };
-    %} 
-
-  The %attributestring also works for class types that have %naturalvar turned
-  on and so is also useful for shared_ptr which has %naturalvar turned on in %shared_ptr.
-
 */
 
 //
@@ -224,20 +98,10 @@
   #if #AccessorMethod != ""
     %attribute_custom(%arg(Class), %arg(AttributeType), AttributeName, AccessorMethod, AccessorMethod, &self_->AccessorMethod(), self_->AccessorMethod() = *val_)
   #else
-    %attribute_custom(%arg(Class), %arg(AttributeType), AccessorName, AccessorName, AccessorName, &self_->AccessorName(), self_->AccessorName() = *val_)
+    %attribute_custom(%arg(Class), %arg(AttributeType), AttributeName, AttributeName, AttributeName, &self_->AttributeName(), self_->AttributeName() = *val_)
   #endif
 %enddef
 
-// deprecated (same as %attributeref, but there is an argument order inconsistency)
-%define %attribute_ref(Class, AttributeType, AccessorMethod, AttributeName...)
-  #if #AttributeName != ""
-    %attribute_custom(%arg(Class), %arg(AttributeType), AttributeName, AccessorMethod, AccessorMethod, self_->AccessorMethod(), self_->AccessorMethod() = val_)
-  #else
-    %attribute_custom(%arg(Class), %arg(AttributeType), AccessorMethod, AccessorMethod, AccessorMethod, self_->AccessorMethod(), self_->AccessorMethod() = val_)
-  #endif
-%enddef
-
-
 %define %attributeval(Class, AttributeType, AttributeName, GetMethod, SetMethod...)
   %{
     #define %mangle(Class) ##_## AttributeName ## _get(self_) new AttributeType(self_->GetMethod())
diff --git a/Lib/typemaps/carrays.swg b/Lib/typemaps/carrays.swg
index 462d60b..d02e70f 100644
--- a/Lib/typemaps/carrays.swg
+++ b/Lib/typemaps/carrays.swg
@@ -11,10 +11,10 @@
  * Generates functions for creating and accessing elements of a C array
  * (as pointers).  Creates the following functions:
  *
- *        TYPE *new_NAME(int nelements)
+ *        TYPE *new_NAME(size_t nelements)
  *        void delete_NAME(TYPE *);
- *        TYPE NAME_getitem(TYPE *, int index);
- *        void NAME_setitem(TYPE *, int index, TYPE value);
+ *        TYPE NAME_getitem(TYPE *, size_t index);
+ *        void NAME_setitem(TYPE *, size_t index, TYPE value);
  * 
  * ----------------------------------------------------------------------------- */
 
@@ -51,10 +51,10 @@
  * interface:
  *
  *          struct NAME {
- *              NAME(int nelements);
+ *              NAME(size_t nelements);
  *             ~NAME();
- *              TYPE getitem(int index);
- *              void setitem(int index, TYPE value);
+ *              TYPE getitem(size_t index);
+ *              void setitem(size_t index, TYPE value);
  *              TYPE * cast();
  *              static NAME *frompointer(TYPE *t);
  *         }
diff --git a/Lib/typemaps/cpointer.swg b/Lib/typemaps/cpointer.swg
index 94bbbd6..a5ac07d 100644
--- a/Lib/typemaps/cpointer.swg
+++ b/Lib/typemaps/cpointer.swg
@@ -55,7 +55,7 @@
     return %new_instance(TYPE);
   }
   ~NAME() {
-    if ($self) %delete($self);
+    %delete($self);
   }
 }
 
@@ -105,7 +105,7 @@
 
 %define %pointer_functions(TYPE,NAME)
 %{
-  static TYPE *new_##NAME() { 
+  static TYPE *new_##NAME(void) {
     return %new_instance(TYPE);
   }
   
@@ -114,7 +114,7 @@
   }
 
   static void delete_##NAME(TYPE *obj) { 
-    if (obj) %delete(obj);
+    %delete(obj);
   }
 
   static void NAME ##_assign(TYPE *obj, TYPE value) {
@@ -126,7 +126,7 @@
   }
 %}
 
-TYPE *new_##NAME();
+TYPE *new_##NAME(void);
 TYPE *copy_##NAME(TYPE value);
 void  delete_##NAME(TYPE *obj);
 void  NAME##_assign(TYPE *obj, TYPE value);
diff --git a/Lib/typemaps/cstrings.swg b/Lib/typemaps/cstrings.swg
index 0aca611..7a7e2c1 100644
--- a/Lib/typemaps/cstrings.swg
+++ b/Lib/typemaps/cstrings.swg
@@ -50,7 +50,7 @@
  *
  *     %cstring_bounded_output(Char *outx, 512);
  *     void foo(Char *outx) {
- *         sprintf(outx,"blah blah\n");
+ *         strcpy(outx,"blah blah\n");
  *     }
  *
  */
@@ -59,7 +59,7 @@
 %typemap(in,noblock=1,numinputs=0) TYPEMAP (Char temp[MAX+1])  {
   $1 = ($1_ltype) temp;
 }
-%typemap(freearg,match="in") TYPEMAP "";
+%typemap(freearg,match="in") TYPEMAP ""
 %typemap(argout,noblock=1,fragment= #SWIG_FromCharPtr ) TYPEMAP {
   $1[MAX] = 0;  
   %append_output(SWIG_FromCharPtr($1));
@@ -85,7 +85,7 @@
 %typemap(in,noblock=1,numinputs=0) TYPEMAP(Char temp[SIZE]) {
   $1 = ($1_ltype) temp;
 }
-%typemap(freearg,match="in") TYPEMAP "";
+%typemap(freearg,match="in") TYPEMAP ""
 %typemap(argout,noblock=1,fragment= #SWIG_FromCharPtrAndSize) TYPEMAP {
   %append_output(SWIG_FromCharPtrAndSize($1,SIZE));
 }
@@ -122,7 +122,7 @@
   temp[n - 1] = 0;                                                             
   $1 = ($1_ltype) temp;                                                    
 }
-%typemap(freearg,match="in") TYPEMAP "";
+%typemap(freearg,match="in") TYPEMAP ""
 %typemap(argout,noblock=1,fragment=#SWIG_FromCharPtr) TYPEMAP {
   $1[MAX] = 0;
   %append_output(SWIG_FromCharPtr($1));
@@ -160,7 +160,7 @@
   if (alloc == SWIG_NEWOBJ) %delete_array(t);
   $1[n-1] = 0;
 }
-%typemap(freearg,match="in") TYPEMAP "";
+%typemap(freearg,match="in") TYPEMAP ""
 %typemap(argout,noblock=1,fragment=#SWIG_FromCharPtr) TYPEMAP { 
   %append_output(SWIG_FromCharPtr($1));
   %delete_array($1);                                  
@@ -175,7 +175,7 @@
  *
  *     %cstring_output_maxsize(Char *outx, int max) {
  *     void foo(Char *outx, int max) {
- *         sprintf(outx,"blah blah\n");
+ *         strcpy(outx,"blah blah\n");
  *     }
  */
 
@@ -205,7 +205,7 @@
  *
  *     %cstring_output_withsize(Char *outx, int *max) {
  *     void foo(Char *outx, int *max) {
- *         sprintf(outx,"blah blah\n");
+ *         strcpy(outx,"blah blah\n");
  *         *max = strlen(outx);  
  *     }
  */
@@ -239,7 +239,7 @@
  *     %cstring_output_allocate(Char **outx, free($1));
  *     void foo(Char **outx) {
  *         *outx = (Char *) malloc(512);
- *         sprintf(outx,"blah blah\n");
+ *         strcpy(outx,"blah blah\n");
  *     }
  */
  
@@ -247,7 +247,7 @@
 %typemap(in,noblock=1,numinputs=0) TYPEMAP($*1_ltype temp = 0) {
   $1 = &temp;
 }
-%typemap(freearg,match="in") TYPEMAP "";
+%typemap(freearg,match="in") TYPEMAP ""
 %typemap(argout,noblock=1,fragment=#SWIG_FromCharPtr) TYPEMAP { 
   if (*$1) {
     %append_output(SWIG_FromCharPtr(*$1));
@@ -266,7 +266,7 @@
  *     %cstring_output_allocate_size(Char **outx, int *sz, free($1));
  *     void foo(Char **outx, int *sz) {
  *         *outx = (Char *) malloc(512);
- *         sprintf(outx,"blah blah\n");
+ *         strcpy(outx,"blah blah\n");
  *         *sz = strlen(outx);
  *     }
  */
@@ -275,7 +275,7 @@
 %typemap(in,noblock=1,numinputs=0) (TYPEMAP, SIZE) ($*1_ltype temp = 0, $*2_ltype tempn) {
   $1 = &temp; $2 = &tempn;
 }
-%typemap(freearg,match="in") (TYPEMAP,SIZE) "";
+%typemap(freearg,match="in") (TYPEMAP,SIZE) ""
 %typemap(argout,noblock=1,fragment=#SWIG_FromCharPtrAndSize)(TYPEMAP,SIZE) {   
   if (*$1) {
     %append_output(SWIG_FromCharPtrAndSize(*$1,*$2));
diff --git a/Lib/typemaps/enumint.swg b/Lib/typemaps/enumint.swg
index d048bb6..b7e2956 100644
--- a/Lib/typemaps/enumint.swg
+++ b/Lib/typemaps/enumint.swg
@@ -29,7 +29,7 @@
 %typemap(varin,fragment=SWIG_AsVal_frag(int),noblock=1) enum SWIGTYPE {
   if (sizeof(int) != sizeof($1)) {
     %variable_fail(SWIG_AttributeError,"$type", "arch, read-only $name");
-  }  else {
+  } else {
     int ecode = SWIG_AsVal(int)($input, %reinterpret_cast(&$1,int*));
     if (!SWIG_IsOK(ecode)) {
       %variable_fail(ecode, "$type", "$name");
diff --git a/Lib/typemaps/exception.swg b/Lib/typemaps/exception.swg
index b60a329..aece832 100644
--- a/Lib/typemaps/exception.swg
+++ b/Lib/typemaps/exception.swg
@@ -19,6 +19,7 @@
 #endif  
 #define %varnullref_fmt(_type,_name)       %nullref_fmt() %varfail_fmt(_type, _name)  		   
 #define %outnullref_fmt(_type)             %nullref_fmt() %outfail_fmt(_type)         
+#define %releasenotownedfail_fmt(_type,_name,_argn)    "in method '" `_name` "', cannot release ownership as memory is not owned for argument " `_argn`" of type '" `_type`"'"
 
 /* setting an error */
 #define %error(code,msg...)               SWIG_Error(code, msg)
@@ -30,7 +31,7 @@
 
 %define_as(SWIG_exception_fail(code, msg), %block(%error(code, msg); SWIG_fail))
 
-%define_as(SWIG_contract_assert(expr, msg), if (!(expr)) { %error(SWIG_RuntimeError, msg); SWIG_fail; } else)
+%define_as(SWIG_contract_assert(expr, msg), do { if (!(expr)) { %error(SWIG_RuntimeError, msg); SWIG_fail; } } while (0))
 
 }
 
diff --git a/Lib/typemaps/fragments.swg b/Lib/typemaps/fragments.swg
index e83f415..e76a694 100644
--- a/Lib/typemaps/fragments.swg
+++ b/Lib/typemaps/fragments.swg
@@ -120,10 +120,6 @@
 #  define SWIG_isfinite(X) (SWIG_isfinite_func(X))
 # elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
 #  define SWIG_isfinite(X) (__builtin_isfinite(X))
-# elif defined(__clang__) && defined(__has_builtin)
-#  if __has_builtin(__builtin_isfinite)
-#   define SWIG_isfinite(X) (__builtin_isfinite(X))
-#  endif
 # elif defined(_MSC_VER)
 #  define SWIG_isfinite(X) (_finite(X))
 # elif defined(__sun) && defined(__SVR4)
diff --git a/Lib/typemaps/implicit.swg b/Lib/typemaps/implicit.swg
index 2fc3108..5536e0a 100644
--- a/Lib/typemaps/implicit.swg
+++ b/Lib/typemaps/implicit.swg
@@ -27,7 +27,7 @@
     get(2.0)  ==> get(A(2.0))
     get(B())  ==> get(A(B()))
 
-   and swig will construct an 'A' temporal variable using the
+   and swig will construct an 'A' temporary variable using the
    corresponding implicit constructor.
 
 
diff --git a/Lib/typemaps/inoutlist.swg b/Lib/typemaps/inoutlist.swg
index 23fda85..6c7604a 100644
--- a/Lib/typemaps/inoutlist.swg
+++ b/Lib/typemaps/inoutlist.swg
@@ -221,10 +221,6 @@
 
        x = neg(x)
 
-Note : previous versions of SWIG used the symbol 'BOTH' to mark
-input/output arguments.   This is still supported, but will be slowly
-phased out in future releases.
-
 */
 
 %define %_value_inout_typemap(Type)
diff --git a/Lib/typemaps/primtypes.swg b/Lib/typemaps/primtypes.swg
index dd80eb7..85a0b8d 100644
--- a/Lib/typemaps/primtypes.swg
+++ b/Lib/typemaps/primtypes.swg
@@ -252,9 +252,11 @@
 SWIG_CanCastAsInteger(double *d, double min, double max) {
   double x = *d;
   if ((min <= x && x <= max)) {
-   double fx = floor(x);
-   double cx = ceil(x);
-   double rd =  ((x - fx) < 0.5) ? fx : cx; /* simple rint */
+   double fx, cx, rd;
+   errno = 0;
+   fx = floor(x);
+   cx = ceil(x);
+   rd =  ((x - fx) < 0.5) ? fx : cx; /* simple rint */
    if ((errno == EDOM) || (errno == ERANGE)) {
      errno = 0;
    } else {
diff --git a/Lib/typemaps/ptrtypes.swg b/Lib/typemaps/ptrtypes.swg
index e8439e6..8619b31 100644
--- a/Lib/typemaps/ptrtypes.swg
+++ b/Lib/typemaps/ptrtypes.swg
@@ -35,7 +35,7 @@
     $1 = *ptr;
     if (SWIG_IsNewObj(res)) %delete(ptr);
   }
-  %typemap(freearg) Type "";
+  %typemap(freearg) Type ""
   %typemap(in,fragment=frag) const Type & (int res = SWIG_OLDOBJ) {
     Type *ptr = (Type *)0;
     res = asptr_meth($input, &ptr);
@@ -184,13 +184,33 @@
 %enddef
 
 /*---------------------------------------------------------------------
+ * typemap definition for types with from method for ptr types
+ * Same as typemaps_from but without varout typemap
+ *---------------------------------------------------------------------*/
+
+%define %ptr_typemaps_from(FromMeth, FromFrag, Type...)
+  %value_out_typemap(%arg(FromMeth), %arg(FromFrag), Type);
+  /* No varout typemap */
+  %value_constcode_typemap(%arg(FromMeth), %arg(FromFrag), Type);
+  %value_directorin_typemap(%arg(FromMeth), %arg(FromFrag), Type);
+  %value_throws_typemap(%arg(FromMeth), %arg(FromFrag), Type);
+  %value_output_typemap(%arg(FromMeth), %arg(FromFrag), Type);
+%enddef
+
+/*---------------------------------------------------------------------
  * typemap definition for types with asptr/from methods
  *---------------------------------------------------------------------*/
 
 %define %typemaps_asptrfrom(CheckCode, AsPtrMeth, FromMeth, AsPtrFrag, FromFrag, Type...)
   %typemaps_asptr(%arg(CheckCode), %arg(AsPtrMeth), %arg(AsPtrFrag), Type)
+  %ptr_typemaps_from(%arg(FromMeth), %arg(FromFrag), Type);
+  %ptr_inout_typemap(Type);
+%enddef
+
+// Same as typemaps_asptrfrom but defines a varout typemap to wrap with value semantics instead of the default pointer semantics
+%define %_typemaps_asptrfrom(CheckCode, AsPtrMeth, FromMeth, AsPtrFrag, FromFrag, Type...)
+  %typemaps_asptr(%arg(CheckCode), %arg(AsPtrMeth), %arg(AsPtrFrag), Type)
   %typemaps_from(%arg(FromMeth), %arg(FromFrag), Type);
-  %value_output_typemap(%arg(FromMeth), %arg(FromFrag), Type);
   %ptr_inout_typemap(Type);
 %enddef
 
@@ -199,7 +219,7 @@
  *---------------------------------------------------------------------*/
 
 %define %typemaps_asptrfromn(CheckCode, Type...)
-%typemaps_asptrfrom(%arg(CheckCode),
+%_typemaps_asptrfrom(%arg(CheckCode),
 		   %arg(SWIG_AsPtr(Type)), 
 		   %arg(SWIG_From(Type)), 
 		   %arg(SWIG_AsPtr_frag(Type)), 
diff --git a/Lib/typemaps/std_string_view.swg b/Lib/typemaps/std_string_view.swg
new file mode 100644
index 0000000..24f57c6
--- /dev/null
+++ b/Lib/typemaps/std_string_view.swg
@@ -0,0 +1,16 @@
+//
+// string_view
+//
+
+
+%include <typemaps/std_strings.swg>
+
+%fragment("<string_view>");
+
+namespace std
+{
+  %naturalvar string_view;
+  class string_view;
+}
+
+%typemaps_std_string_view(std::string_view, char, SWIG_AsCharPtrAndSize, SWIG_FromCharPtrAndSize, %checkcode(STRINGVIEW));
diff --git a/Lib/typemaps/std_strings.swg b/Lib/typemaps/std_strings.swg
index e9c23ba..8425458 100644
--- a/Lib/typemaps/std_strings.swg
+++ b/Lib/typemaps/std_strings.swg
@@ -45,6 +45,16 @@
 }
 %enddef
 
+%define %std_string_view_from(String, SWIG_FromCharPtrAndSize, Frag)
+%fragment(SWIG_From_frag(String),"header",fragment=Frag) {
+SWIGINTERNINLINE SWIG_Object
+SWIG_From_dec(String)(const String& s)
+{
+  return SWIG_FromCharPtrAndSize(s.data() ? s.data() : "", s.size());
+}
+}
+%enddef
+
 %define %std_string_asval(String)
 %fragment(SWIG_AsVal_frag(String),"header", fragment=SWIG_AsPtr_frag(String)) {
 SWIGINTERN int
@@ -76,3 +86,18 @@
 %typemaps_asptrfromn(%arg(CheckCode), String);
 
 %enddef
+
+
+/* An empty string_view returns NULL from data() but SWIG_FromCharPtrAndSize()
+ * implementations treat that as invalid and return None/Null/undef or similar
+ * in the target language so we can't just use %typemaps_std_string.
+ */
+%define %typemaps_std_string_view(String, Char, AsPtrMethod, FromMethod, CheckCode)
+
+%std_string_asptr(String, Char, AsPtrMethod, #AsPtrMethod)
+%std_string_asval(String)
+%std_string_view_from(String, FromMethod, #FromMethod)
+
+%typemaps_asptrfromn(%arg(CheckCode), String);
+
+%enddef
diff --git a/Lib/typemaps/string.swg b/Lib/typemaps/string.swg
index 4b70723..72f4aa5 100644
--- a/Lib/typemaps/string.swg
+++ b/Lib/typemaps/string.swg
@@ -30,6 +30,7 @@
 
 %include <typemaps/strings.swg>
 %typemaps_string(%checkcode(STRING), %checkcode(CHAR),
+		 SWIGWARN_TYPEMAP_CHARLEAK_MSG,
 		 char, Char, SWIG_AsCharPtrAndSize, SWIG_FromCharPtrAndSize,
 		 strlen, SWIG_strnlen,
 		"<limits.h>", CHAR_MIN, CHAR_MAX)
diff --git a/Lib/typemaps/strings.swg b/Lib/typemaps/strings.swg
index 87e97dd..1237d98 100644
--- a/Lib/typemaps/strings.swg
+++ b/Lib/typemaps/strings.swg
@@ -19,6 +19,7 @@
 
 %define %_typemap_string(StringCode, 
 			 Char,
+			 WarningLeakMsg,
 			 SWIG_AsCharPtrAndSize,
 			 SWIG_FromCharPtrAndSize,
 			 SWIG_CharPtrLen,
@@ -78,7 +79,7 @@
   if (!SWIG_IsOK(res)) {
     %variable_fail(res,"$type","$name");
   }
-  if ($1) SWIG_DeleteCharArray($1);
+  SWIG_DeleteCharArray($1);
   if (alloc == SWIG_NEWOBJ) {
     $1 = cptr;
   } else {
@@ -86,7 +87,7 @@
   }
 }
 
-%typemap(varin,fragment=#SWIG_AsCharPtrAndSize,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const Char * {
+%typemap(varin,fragment=#SWIG_AsCharPtrAndSize,warning=WarningLeakMsg) const Char * {
   Char *cptr = 0; size_t csize = 0; int alloc = SWIG_NEWOBJ;
   int res = SWIG_AsCharPtrAndSize($input, &cptr, &csize, &alloc);
   if (!SWIG_IsOK(res)) {
@@ -108,7 +109,7 @@
 /* memberin */
 
 %typemap(memberin,noblock=1) Char * {
-  if ($1) SWIG_DeleteCharArray($1);
+  SWIG_DeleteCharArray($1);
   if ($input) {
     size_t size = SWIG_CharPtrLen(%reinterpret_cast($input, const Char *)) + 1;
     $1 = ($1_type)SWIG_NewCopyCharArray(%reinterpret_cast($input, const Char *), size, Char);
@@ -117,7 +118,7 @@
   }
 }
 
-%typemap(memberin,noblock=1,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const Char * {
+%typemap(memberin,noblock=1,warning=WarningLeakMsg) const Char * {
   if ($input) {
     size_t size = SWIG_CharPtrLen(%reinterpret_cast(%reinterpret_cast($input, const Char *), const Char *)) + 1;
     $1 = ($1_type)SWIG_NewCopyCharArray($input, size, Char);
@@ -129,7 +130,7 @@
 /* globalin */
 
 %typemap(globalin,noblock=1) Char * {
-  if ($1) SWIG_DeleteCharArray($1);
+  SWIG_DeleteCharArray($1);
   if ($input) {
     size_t size = SWIG_CharPtrLen(%reinterpret_cast(%reinterpret_cast($input, const Char *), const Char *)) + 1;
     $1 = ($1_type)SWIG_NewCopyCharArray($input, size, Char);
@@ -138,7 +139,7 @@
   }
 }
 
-%typemap(globalin,noblock=1,warning=SWIGWARN_TYPEMAP_CHARLEAK_MSG) const Char * {
+%typemap(globalin,noblock=1,warning=WarningLeakMsg) const Char * {
   if ($input) {
     size_t size = SWIG_CharPtrLen($input) + 1;
     $1 = ($1_type)SWIG_NewCopyCharArray($input, size, Char);
@@ -265,7 +266,7 @@
   }
   $1 = %reinterpret_cast(temp, $1_ltype);
 }
-%typemap(freearg) Char [ANY], const Char [ANY] "";
+%typemap(freearg) Char [ANY], const Char [ANY] ""
 
 %typemap(in,noblock=1,fragment=#SWIG_AsCharArray) const Char (&)[ANY] (Char temp[$1_dim0], int res)
 {  
@@ -275,7 +276,7 @@
   }
   $1 = &temp;
 }
-%typemap(freearg) const Char (&)[ANY] "";
+%typemap(freearg) const Char (&)[ANY] ""
 
 %typemap(out,fragment=#SWIG_FromCharPtrAndSize,fragment=#SWIG_CharBufLen)
   Char [ANY], const Char[ANY] 
@@ -501,6 +502,7 @@
 
 #ifndef %_typemap2_string
 %define %_typemap2_string(StringCode, CharCode,
+			 WarningLeakMsg,
 			 Char, CharName,
 			 SWIG_AsCharPtrAndSize,
 			 SWIG_FromCharPtrAndSize,
@@ -591,6 +593,7 @@
 
 %_typemap_string(StringCode, 
 		 Char,
+		 WarningLeakMsg,
 		 SWIG_AsCharPtrAndSize,
 		 SWIG_FromCharPtrAndSize,
 		 SWIG_CharPtrLen,
@@ -609,6 +612,7 @@
  * ------------------------------------------------------------ */
 
 %define %typemaps_string(StringCode, CharCode,
+			 WarningLeakMsg,
 			 Char, CharName,
 			 SWIG_AsCharPtrAndSize,
 			 SWIG_FromCharPtrAndSize,
@@ -616,6 +620,7 @@
 			 SWIG_CharBufLen,
 			 FragLimits, CHAR_MIN, CHAR_MAX)
 %_typemap2_string(StringCode, CharCode,
+		  WarningLeakMsg,
 		  Char, CharName,
 		  SWIG_AsCharPtrAndSize,
 		  SWIG_FromCharPtrAndSize,
@@ -631,6 +636,7 @@
  * ------------------------------------------------------------ */
 
 %define %typemaps_string_alloc(StringCode, CharCode,
+			       WarningLeakMsg,
 			       Char, CharName,
 			       SWIG_AsCharPtrAndSize,
 			       SWIG_FromCharPtrAndSize,
@@ -640,6 +646,7 @@
 			       SWIG_DeleteCharArray,
 			       FragLimits, CHAR_MIN, CHAR_MAX)
 %_typemap2_string(StringCode, CharCode,
+		  WarningLeakMsg,
 		  Char, CharName,
 		  SWIG_AsCharPtrAndSize,
 		  SWIG_FromCharPtrAndSize,
diff --git a/Lib/typemaps/swigmacros.swg b/Lib/typemaps/swigmacros.swg
index 687b068..b772eb0 100644
--- a/Lib/typemaps/swigmacros.swg
+++ b/Lib/typemaps/swigmacros.swg
@@ -109,16 +109,6 @@
 #endif
 %enddef
 
-/* insert the SWIGVERSION in the interface and the wrapper code */
-#if SWIG_VERSION
-%insert("header") {
-%define_as(SWIGVERSION,  SWIG_VERSION)
-%#define SWIG_VERSION SWIGVERSION
-}
-#endif
-
-
-
 /* -----------------------------------------------------------------------------
  * Casting operators
  * ----------------------------------------------------------------------------- */
diff --git a/Lib/typemaps/swigmove.swg b/Lib/typemaps/swigmove.swg
new file mode 100644
index 0000000..b0a2968
--- /dev/null
+++ b/Lib/typemaps/swigmove.swg
@@ -0,0 +1,19 @@
+/* -----------------------------------------------------------------------------
+ * swigmove.swg
+ *
+ * Input typemaps library for implementing full move semantics when passing
+ * parameters by value.
+ * ----------------------------------------------------------------------------- */
+
+%typemap(in, noblock=1) SWIGTYPE MOVE (void *argp = 0, int res = 0) {
+  res = SWIG_ConvertPtr($input, &argp, $&1_descriptor, SWIG_POINTER_RELEASE);
+  if (!SWIG_IsOK(res)) {
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "$1_type", $symname, $argnum);
+    } else {
+      %argument_fail(res, "$1_type", $symname, $argnum);
+    }
+  }
+  if (!argp) { %argument_nullref("$1_type", $symname, $argnum); }
+  SwigValueWrapper< $1_ltype >::reset($1, ($&1_type)argp);
+}
diff --git a/Lib/typemaps/swigobject.swg b/Lib/typemaps/swigobject.swg
index b1e6dc9..26c6ba8 100644
--- a/Lib/typemaps/swigobject.swg
+++ b/Lib/typemaps/swigobject.swg
@@ -2,7 +2,7 @@
  * Language Object *  - Just pass straight through unmodified
  * ------------------------------------------------------------ */
 
-%typemap(in)   SWIG_Object "$1 = $input;";
+%typemap(in)   SWIG_Object "$1 = $input;"
 
 %typemap(in,noblock=1)   SWIG_Object const & ($*ltype temp)
 {
@@ -30,8 +30,8 @@
 
 #if defined(SWIG_DIRECTOR_TYPEMAPS)
 
-%typemap(directorin) SWIG_Object "$input = $1;";
-%typemap(directorout) SWIG_Object "$result = $input;";
+%typemap(directorin) SWIG_Object "$input = $1;"
+%typemap(directorout) SWIG_Object "$result = $input;"
 
 #endif /* SWIG_DIRECTOR_TYPEMAPS */
 
diff --git a/Lib/typemaps/swigtype.swg b/Lib/typemaps/swigtype.swg
index 581de1a..ba8ce3c 100644
--- a/Lib/typemaps/swigtype.swg
+++ b/Lib/typemaps/swigtype.swg
@@ -9,7 +9,7 @@
   }
   $1 = %reinterpret_cast(argp, $ltype);
 }
-%typemap(freearg) SWIGTYPE * "";
+%typemap(freearg) SWIGTYPE * ""
 
 %typemap(in, noblock=1) SWIGTYPE [] (void *argp = 0, int res = 0) {
   res = SWIG_ConvertPtr($input, &argp,$descriptor, $disown | %convertptr_flags);
@@ -18,7 +18,7 @@
   } 
   $1 = %reinterpret_cast(argp, $ltype);
 }
-%typemap(freearg) SWIGTYPE [] "";
+%typemap(freearg) SWIGTYPE [] ""
 
 
 %typemap(in, noblock=1) SWIGTYPE *const&  (void *argp = 0, int res = 0, $*1_ltype temp) {
@@ -29,7 +29,7 @@
   temp = %reinterpret_cast(argp, $*ltype);
   $1 = %reinterpret_cast(&temp, $1_ltype);
 }
-%typemap(freearg) SWIGTYPE *const& "";
+%typemap(freearg) SWIGTYPE *const& ""
 
 
 /* Reference */
@@ -41,7 +41,7 @@
   if (!argp) { %argument_nullref("$type", $symname, $argnum); }
   $1 = %reinterpret_cast(argp, $ltype);
 }
-%typemap(freearg) SWIGTYPE & "";
+%typemap(freearg) SWIGTYPE & ""
 
 #if defined(__cplusplus) && defined(%implicitconv_flag)
 %typemap(in,noblock=1,implicitconv=1) const SWIGTYPE & (void *argp = 0, int res = 0) {
@@ -56,51 +56,23 @@
 {
   if (SWIG_IsNewObj(res$argnum)) %delete($1);
 }
-#else
-%typemap(in,noblock=1) const SWIGTYPE & (void *argp, int res = 0) {
-  res = SWIG_ConvertPtr($input, &argp, $descriptor, %convertptr_flags);
-  if (!SWIG_IsOK(res)) {
-    %argument_fail(res, "$type", $symname, $argnum); 
-  }
-  if (!argp) { %argument_nullref("$type", $symname, $argnum); }
-  $1 = %reinterpret_cast(argp, $ltype);
-}
 #endif
 
 /* Rvalue reference */
-%typemap(in, noblock=1) SWIGTYPE && (void *argp = 0, int res = 0) {
-  res = SWIG_ConvertPtr($input, &argp, $descriptor, %convertptr_flags);
+%typemap(in, noblock=1, fragment="<memory>") SWIGTYPE && (void *argp = 0, int res = 0, std::unique_ptr<$*1_ltype> rvrdeleter) {
+  res = SWIG_ConvertPtr($input, &argp, $descriptor, SWIG_POINTER_RELEASE | %convertptr_flags);
   if (!SWIG_IsOK(res)) {
-    %argument_fail(res, "$type", $symname, $argnum); 
+    if (res == SWIG_ERROR_RELEASE_NOT_OWNED) {
+      %releasenotowned_fail(res, "$type", $symname, $argnum);
+    } else {
+      %argument_fail(res, "$type", $symname, $argnum); 
+    }
   }
   if (!argp) { %argument_nullref("$type", $symname, $argnum); }
   $1 = %reinterpret_cast(argp, $ltype);
+  rvrdeleter.reset($1);
 }
-%typemap(freearg) SWIGTYPE && "";
-
-#if defined(__cplusplus) && defined(%implicitconv_flag)
-%typemap(in,noblock=1,implicitconv=1) const SWIGTYPE && (void *argp = 0, int res = 0) {
-  res = SWIG_ConvertPtr($input, &argp, $descriptor, %convertptr_flags | %implicitconv_flag);
-  if (!SWIG_IsOK(res)) {
-    %argument_fail(res, "$type", $symname, $argnum); 
-  }
-  if (!argp) { %argument_nullref("$type", $symname, $argnum); }
-  $1 = %reinterpret_cast(argp, $ltype);
-}
-%typemap(freearg,noblock=1,match="in",implicitconv=1) const SWIGTYPE &&
-{
-  if (SWIG_IsNewObj(res$argnum)) %delete($1);
-}
-#else
-%typemap(in,noblock=1) const SWIGTYPE && (void *argp, int res = 0) {
-  res = SWIG_ConvertPtr($input, &argp, $descriptor, %convertptr_flags);
-  if (!SWIG_IsOK(res)) {
-    %argument_fail(res, "$type", $symname, $argnum); 
-  }
-  if (!argp) { %argument_nullref("$type", $symname, $argnum); }
-  $1 = %reinterpret_cast(argp, $ltype);
-}
-#endif
+%typemap(freearg) SWIGTYPE && ""
 
 /* By value */
 #if defined(__cplusplus) && defined(%implicitconv_flag)
@@ -146,9 +118,15 @@
 }
 
 /* Return by value */
+#ifdef __cplusplus
 %typemap(out, noblock=1) SWIGTYPE {
-  %set_output(SWIG_NewPointerObj(%new_copy($1, $ltype), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags));
+  %set_output(SWIG_NewPointerObj((new $1_ltype($1)), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags));
 }
+#else
+%typemap(out, noblock=1) SWIGTYPE {
+  %set_output(SWIG_NewPointerObj(%new_copy($1, $1_ltype), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags));
+}
+#endif
 
 /* -----------------------------------------------------------------------------
  * --- Variable input --- 
@@ -194,12 +172,8 @@
   if ($input) {
     size_t ii = 0;
     for (; ii < (size_t)$1_dim0; ++ii) {
-      if ($input[ii]) {
-	size_t jj = 0;
-	for (; jj < (size_t)$1_dim1; ++jj) $1[ii][jj] = $input[ii][jj];
-      } else {
-	%variable_nullref("$type","$name");
-      }
+      size_t jj = 0;
+      for (; jj < (size_t)$1_dim1; ++jj) $1[ii][jj] = $input[ii][jj];
     }
   } else {
     %variable_nullref("$type","$name");
@@ -210,12 +184,8 @@
   if ($input) {
     size_t ii = 0;
     for (; ii < (size_t)$1_dim0; ++ii) {
-      if ($input[ii]) {
-	size_t jj = 0;
-	for (; jj < (size_t)$1_dim1; ++jj) $1[ii][jj] = $input[ii][jj];
-      } else {
-	%variable_nullref("$type","$name");
-      }
+      size_t jj = 0;
+      for (; jj < (size_t)$1_dim1; ++jj) $1[ii][jj] = $input[ii][jj];
     }
   } else {
     %variable_nullref("$type","$name");
@@ -230,12 +200,8 @@
   } else if (inp) {
     size_t ii = 0;
     for (; ii < (size_t)$1_dim0; ++ii) {
-      if (inp[ii]) {
-	size_t jj = 0;
-	for (; jj < (size_t)$1_dim1; ++jj) $1[ii][jj] = inp[ii][jj];
-      } else {
-	%variable_nullref("$type", "$name");
-      }
+      size_t jj = 0;
+      for (; jj < (size_t)$1_dim1; ++jj) $1[ii][jj] = inp[ii][jj];
     }
   } else {
     %variable_nullref("$type", "$name");
@@ -389,6 +355,7 @@
   int res = SWIG_ConvertPtr($input, &vptr, $descriptor, SWIG_POINTER_NO_NULL);
   $1 = SWIG_CheckState(res);
 }
+
 %typemap(typecheck,precedence=SWIG_TYPECHECK_POINTER,noblock=1) const SWIGTYPE && {
   void *vptr = 0;
   int res = SWIG_ConvertPtr($input, &vptr, $descriptor, SWIG_POINTER_NO_NULL);
@@ -411,7 +378,7 @@
 /* directorin */
 
 %typemap(directorin,noblock=1) SWIGTYPE {
-  $input = SWIG_NewPointerObj(%as_voidptr(new $1_ltype((const $1_ltype &)$1)), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags);
+  $input = SWIG_NewPointerObj((new $1_ltype(SWIG_STD_MOVE($1))), $&descriptor, SWIG_POINTER_OWN | %newpointer_flags);
 }
 
 %typemap(directorin,noblock=1) SWIGTYPE * {
@@ -534,7 +501,7 @@
  * ------------------------------------------------------------ */
 
 %typemap(throws,noblock=1) SWIGTYPE {
-  %raise(SWIG_NewPointerObj(%new_copy($1, $ltype),$&descriptor,SWIG_POINTER_OWN), "$type", $&descriptor);
+  %raise(SWIG_NewPointerObj(%new_copy($1, $1_ltype),$&descriptor,SWIG_POINTER_OWN), "$type", $&descriptor);
 }
 
 %typemap(throws,noblock=1) SWIGTYPE * {
@@ -562,29 +529,29 @@
  * ------------------------------------------------------------ */
 
 %typemap(in) SWIGTYPE (CLASS::*) {  
-  int res = SWIG_ConvertMember($input, %as_voidptr(&$1), sizeof($type),$descriptor);
+  int res = SWIG_ConvertMember($input, %as_voidptr(&$1), sizeof($1),$descriptor);
   if (!SWIG_IsOK(res)) {
     %argument_fail(res,"$type",$symname, $argnum); 
   }
 }
 
 %typemap(out,noblock=1) SWIGTYPE (CLASS::*) {
-  %set_output(SWIG_NewMemberObj(%as_voidptr(&$1), sizeof($type), $descriptor));
+  %set_output(SWIG_NewMemberObj(%as_voidptr(&$1), sizeof($1), $descriptor));
 }
 
 %typemap(varin) SWIGTYPE (CLASS::*) {
-  int res = SWIG_ConvertMember($input,%as_voidptr(&$1), sizeof($type), $descriptor);
+  int res = SWIG_ConvertMember($input,%as_voidptr(&$1), sizeof($1), $descriptor);
   if (!SWIG_IsOK(res)) {
     %variable_fail(res, "$type", "$name"); 
   }
 }
 
 %typemap(varout,noblock=1) SWIGTYPE (CLASS::*) {
-  %set_varoutput(SWIG_NewMemberObj(%as_voidptr(&$1), sizeof($type), $descriptor));
+  %set_varoutput(SWIG_NewMemberObj(%as_voidptr(&$1), sizeof($1), $descriptor));
 }
 
 %typemap(constcode,noblock=1) SWIGTYPE (CLASS::*) {
-  %set_constant("$symname", SWIG_NewMemberObj(%as_voidptr(&$value), sizeof($type), $descriptor));
+  %set_constant("$symname", SWIG_NewMemberObj(%as_voidptr(&$value), sizeof($value), $descriptor));
 }
 
 #if defined(SWIG_DIRECTOR_TYPEMAPS)
@@ -592,13 +559,13 @@
 /* directorin */
 
 %typemap(directorin,noblock=1) SWIGTYPE (CLASS::*) {
-  $input = SWIG_NewMemberObj(%as_voidptr(&$1), sizeof($type), $descriptor);
+  $input = SWIG_NewMemberObj(%as_voidptr(&$1), sizeof($1), $descriptor);
 }
 
 /* directorout */
 
 %typemap(directorout) SWIGTYPE (CLASS::*) {
-  int swig_res = SWIG_ConvertMember($input,%as_voidptr(&$result), sizeof($type), $descriptor);
+  int swig_res = SWIG_ConvertMember($input,%as_voidptr(&$result), sizeof($result), $descriptor);
   if (!SWIG_IsOK(swig_res)) {
     %dirout_fail(swig_res,"$type");
   }
@@ -703,9 +670,15 @@
 
 /* INSTANCE typemap */
 
+#ifdef __cplusplus
+%typemap(out,noblock=1) SWIGTYPE INSTANCE {
+  %set_output(SWIG_NewInstanceObj((new $1_ltype($1)), $&1_descriptor, SWIG_POINTER_OWN | %newinstance_flags));
+}
+#else
 %typemap(out,noblock=1) SWIGTYPE INSTANCE {
   %set_output(SWIG_NewInstanceObj(%new_copy($1, $1_ltype), $&1_descriptor, SWIG_POINTER_OWN | %newinstance_flags));
 }
+#endif
 
 %typemap(out,noblock=1) SWIGTYPE *INSTANCE, SWIGTYPE &INSTANCE, SWIGTYPE INSTANCE[] {
   %set_output(SWIG_NewInstanceObj(%as_voidptr($1), $1_descriptor, $owner | %newinstance_flags));
diff --git a/Lib/typemaps/swigtypemaps.swg b/Lib/typemaps/swigtypemaps.swg
index 4e5bb2b..733e5ac 100644
--- a/Lib/typemaps/swigtypemaps.swg
+++ b/Lib/typemaps/swigtypemaps.swg
@@ -140,6 +140,7 @@
 #define %argument_nullref(type, name, argn)    SWIG_exception_fail(SWIG_ValueError, %argnullref_fmt(type, name, argn))
 #define %variable_fail(code, type, name)       SWIG_exception_fail(%default_code(code), %varfail_fmt(type, name))
 #define %variable_nullref(type, name)          SWIG_exception_fail(SWIG_ValueError, %varnullref_fmt(type, name))
+#define %releasenotowned_fail(code, type, name, argn) SWIG_exception_fail(%default_code(code), %releasenotownedfail_fmt(type, name, argn))
 
 #if defined(SWIG_DIRECTOR_TYPEMAPS)
 #define %dirout_fail(code, type)          SWIG_DirOutFail(%default_code(code), %outfail_fmt(type))
diff --git a/Lib/typemaps/typemaps.swg b/Lib/typemaps/typemaps.swg
index 4629e8d..7d013b0 100644
--- a/Lib/typemaps/typemaps.swg
+++ b/Lib/typemaps/typemaps.swg
@@ -140,10 +140,6 @@
 
        x = neg(x)
 
-Note : previous versions of SWIG used the symbol 'BOTH' to mark
-input/output arguments.   This is still supported, but will be slowly
-phased out in future releases.
-
 */
 
 
diff --git a/Lib/typemaps/valtypes.swg b/Lib/typemaps/valtypes.swg
index 11eac59..7623ff0 100644
--- a/Lib/typemaps/valtypes.swg
+++ b/Lib/typemaps/valtypes.swg
@@ -38,7 +38,7 @@
     } 
     $1 = %static_cast(val,$ltype);
   }
-  %typemap(freearg) Type "";
+  %typemap(freearg) Type ""
   %typemap(in,noblock=1,fragment=frag) const Type & ($*ltype temp, Type val, int ecode = 0) {  
     ecode = asval_meth($input, &val);
     if (!SWIG_IsOK(ecode)) {
@@ -47,7 +47,7 @@
     temp = %static_cast(val, $*ltype);
     $1 = &temp;
   }
-  %typemap(freearg) const Type& "";
+  %typemap(freearg) const Type& ""
 %enddef
 
 /* out */
@@ -180,6 +180,7 @@
 /*---------------------------------------------------------------------
  * typemap definition for types with from method
  *---------------------------------------------------------------------*/
+
 %define %typemaps_from(FromMeth, FromFrag, Type...)
   %value_out_typemap(%arg(FromMeth), %arg(FromFrag), Type);
   %value_varout_typemap(%arg(FromMeth), %arg(FromFrag), Type);
@@ -191,7 +192,7 @@
 
 
 /*---------------------------------------------------------------------
- * typemap definition for types with alval/from method
+ * typemap definition for types with asval/from method
  *---------------------------------------------------------------------*/
 
 %define %typemaps_asvalfrom(CheckCode, AsValMeth, FromMeth,
diff --git a/Lib/typemaps/void.swg b/Lib/typemaps/void.swg
index bbd68ed..795992b 100644
--- a/Lib/typemaps/void.swg
+++ b/Lib/typemaps/void.swg
@@ -10,7 +10,7 @@
     %argument_fail(res, "$type", $symname, $argnum); 
   }
 }
-%typemap(freearg) void * "";
+%typemap(freearg) void * ""
 
 %typemap(in,noblock=1) void * const& ($*ltype temp = 0, int res) {
   res = SWIG_ConvertPtr($input, %as_voidptrptr(&temp), 0, $disown);
@@ -19,7 +19,7 @@
   }
   $1 =  &temp;
 }
-%typemap(freearg) void * const& "";
+%typemap(freearg) void * const& ""
 
 
 /* out */
diff --git a/Lib/typemaps/wstring.swg b/Lib/typemaps/wstring.swg
index cd409d1..d99c0bb 100644
--- a/Lib/typemaps/wstring.swg
+++ b/Lib/typemaps/wstring.swg
@@ -31,6 +31,7 @@
 
 %include <typemaps/strings.swg>
 %typemaps_string(%checkcode(UNISTRING), %checkcode(UNICHAR),
+		 SWIGWARN_TYPEMAP_WCHARLEAK_MSG,
 		 wchar_t, WChar, SWIG_AsWCharPtrAndSize, SWIG_FromWCharPtrAndSize,
 		 wcslen, SWIG_wcsnlen,
 		"<wchar.h>", WCHAR_MIN, WCHAR_MAX)
diff --git a/Lib/uffi/uffi.swg b/Lib/uffi/uffi.swg
deleted file mode 100644
index 41b0859..0000000
--- a/Lib/uffi/uffi.swg
+++ /dev/null
@@ -1,101 +0,0 @@
-/* Define a C preprocessor symbol that can be used in interface files
-   to distinguish between the SWIG language modules. */ 
-
-#define SWIG_UFFI
-
-/* Typespecs for basic types. */
-
-%typemap(ffitype) char ":char";
-%typemap(ffitype) unsigned char ":unsigned-char";
-%typemap(ffitype) signed char ":char";
-%typemap(ffitype) short ":short";
-%typemap(ffitype) signed short ":short";
-%typemap(ffitype) unsigned short ":unsigned-short";
-%typemap(ffitype) int ":int";
-%typemap(ffitype) signed int ":int";
-%typemap(ffitype) unsigned int ":unsigned-int";
-%typemap(ffitype) long ":long";
-%typemap(ffitype) signed long ":long";
-%typemap(ffitype) unsigned long ":unsigned-long";
-%typemap(ffitype) float ":float";
-%typemap(ffitype) double ":double";
-%typemap(ffitype) char * ":cstring";
-%typemap(ffitype) void * ":pointer-void";
-%typemap(ffitype) void ":void";
-
-// FIXME: This is guesswork
-typedef long size_t;
-
-%wrapper %{
-(eval-when (compile eval)
-
-;;; You can define your own identifier converter if you want.
-;;; Use the -identifier-converter command line argument to
-;;; specify its name. 
-  
-(defun identifier-convert-null (id &key type)
-  (declare (ignore type))
-  (read-from-string id))
-
-(defun identifier-convert-lispify (cname &key type)
-  (assert (stringp cname))
-  (if (eq type :constant)
-      (setf cname (format nil "*~A*" cname)))
-  (setf cname (replace-regexp cname "_" "-"))
-  (let ((lastcase :other)
-        newcase char res)
-    (dotimes (n (length cname))
-      (setf char (schar cname n))
-      (if* (alpha-char-p char)
-         then
-              (setf newcase (if (upper-case-p char) :upper :lower))
-
-              (when (or (and (eq lastcase :upper) (eq newcase :lower))
-                        (and (eq lastcase :lower) (eq newcase :upper)))
-                ;; case change... add a dash                                    
-                (push #\- res)
-                (setf newcase :other))
-
-              (push (char-downcase char) res)
-
-              (setf lastcase newcase)
-
-         else
-              (push char res)
-              (setf lastcase :other)))
-    (read-from-string (coerce (nreverse res) 'string))))
-
-(defun identifier-convert-low-level (cname &key type)
-  (assert (stringp cname))
-  (if (eq type :constant)
-    (setf cname (format nil "+~A+" cname)))
-  (setf cname (substitute #\- #\_ cname))
-  (if (eq type :operator)
-    (setf cname (format nil "%~A" cname)))
-  (if (eq type :constant-function)
-    nil)
-  (read-from-string cname))
-
-
-
-(defmacro swig-defconstant (string value &key (export T))
-  (let ((symbol (funcall *swig-identifier-converter* string :type :constant)))
-    `(eval-when (compile load eval)
-       (uffi:def-constant ,symbol ,value ,export))))
-
-(defmacro swig-defun (name &rest rest)
-  (let ((symbol (funcall *swig-identifier-converter* name :type :operator)))
-    `(eval-when (compile load eval)
-      (uffi:def-function (,name ,symbol) ,@rest)
-      (export (quote ,symbol)))))
-
-(defmacro swig-def-struct (name &rest fields)
-  "Declare a struct object"
-  (let ((symbol (funcall *swig-identifier-converter* name :type :type)))
-    `(eval-when (compile load eval)
-       (uffi:def-struct ,symbol ,@fields)
-       (export (quote ,symbol)))))
- 
-
-) ;; eval-when
-%}
diff --git a/METADATA b/METADATA
index fff9de7..aadd712 100644
--- a/METADATA
+++ b/METADATA
@@ -9,10 +9,10 @@
     type: GIT
     value: "https://github.com/swig/swig.git"
   }
-  version: "rel-4.0.1"
+  version: "v4.2.1"
   last_upgrade_date {
-    year: 2019
-    month: 10
-    day: 18
+    year: 2024
+    month: 04
+    day: 11
   }
 }
diff --git a/Makefile.in b/Makefile.in
index 39816be..a7019a1 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -29,7 +29,6 @@
 SOURCE      = Source
 CCACHE      = CCache
 DOCS        = Doc/Manual
-HAVE_CXX11_COMPILER = @HAVE_CXX11_COMPILER@
 
 swig: libfiles source ccache
 
@@ -59,23 +58,23 @@
 # All the languages SWIG speaks (when it wants to)
 #####################################################################
 
-skip-tcl	= test -n "@SKIP_TCL@"
-skip-perl5	= test -n "@SKIP_PERL5@"
-skip-python	= test -n "@SKIP_PYTHON@"
-skip-java	= test -n "@SKIP_JAVA@"
+skip-csharp	= test -n "@SKIP_CSHARP@"
+skip-d		= test -n "@SKIP_D@"
+skip-go		= test -n "@SKIP_GO@"
 skip-guile	= test -n "@SKIP_GUILE@"
+skip-java	= test -n "@SKIP_JAVA@"
+skip-javascript	= test -n "@SKIP_JAVASCRIPT@"
+skip-lua    	= test -n "@SKIP_LUA@"
 skip-mzscheme	= test -n "@SKIP_MZSCHEME@"
-skip-ruby	= test -n "@SKIP_RUBY@"
-skip-php	= test -n "@SKIP_PHP@"
 skip-ocaml      = test -n "@SKIP_OCAML@"
 skip-octave     = test -n "@SKIP_OCTAVE@"
-skip-csharp	= test -n "@SKIP_CSHARP@"
-skip-lua    	= test -n "@SKIP_LUA@"
+skip-perl5	= test -n "@SKIP_PERL5@"
+skip-php	= test -n "@SKIP_PHP@"
+skip-python	= test -n "@SKIP_PYTHON@"
 skip-r		= test -n "@SKIP_R@"
+skip-ruby	= test -n "@SKIP_RUBY@"
 skip-scilab     = test -n "@SKIP_SCILAB@"
-skip-go		= test -n "@SKIP_GO@"
-skip-d		= test -n "@SKIP_D@"
-skip-javascript	= test -n "@SKIP_JAVASCRIPT@"
+skip-tcl	= test -n "@SKIP_TCL@"
 
 # Additional dependencies for some tests
 skip-android    = test -n "@SKIP_ANDROID@"
@@ -100,47 +99,47 @@
 	test -x ./$(TARGET)
 	./$(TARGET) -version
 	./$(TARGET) -help
-	@$(skip-tcl)      || ./$(TARGET) -tcl        -help
-	@$(skip-perl5)    || ./$(TARGET) -perl       -help
-	@$(skip-python)   || ./$(TARGET) -python     -help
-	@$(skip-java)     || ./$(TARGET) -java       -help
+	@$(skip-csharp)   || ./$(TARGET) -csharp     -help
+	@$(skip-d) 	  || ./$(TARGET) -d          -help
+	@$(skip-go)	  || ./$(TARGET) -go         -help
 	@$(skip-guile)    || ./$(TARGET) -guile      -help
+	@$(skip-java)     || ./$(TARGET) -java       -help
+	@$(skip-javascript) || ./$(TARGET) -javascript -help
+	@$(skip-lua)      || ./$(TARGET) -lua        -help
 	@$(skip-mzscheme) || ./$(TARGET) -mzscheme   -help
-	@$(skip-ruby)     || ./$(TARGET) -ruby       -help
 	@$(skip-ocaml)    || ./$(TARGET) -ocaml      -help
 	@$(skip-octave)   || ./$(TARGET) -octave     -help
+	@$(skip-perl5)    || ./$(TARGET) -perl       -help
 	@$(skip-php)      || ./$(TARGET) -php7       -help
-	@$(skip-csharp)   || ./$(TARGET) -csharp     -help
-	@$(skip-lua)      || ./$(TARGET) -lua        -help
+	@$(skip-python)   || ./$(TARGET) -python     -help
 	@$(skip-r) 	  || ./$(TARGET) -r          -help
+	@$(skip-ruby)     || ./$(TARGET) -ruby       -help
 	@$(skip-scilab)   || ./$(TARGET) -scilab     -help
-	@$(skip-go)	  || ./$(TARGET) -go         -help
-	@$(skip-d) 	  || ./$(TARGET) -d          -help
-	@$(skip-javascript) || ./$(TARGET) -javascript -help
+	@$(skip-tcl)      || ./$(TARGET) -tcl        -help
 
 check-ccache:
 	test -z "$(ENABLE_CCACHE)" || (cd $(CCACHE) && $(MAKE) check)
 
 # Checks / displays versions of each target language
 check-versions:					\
-	check-tcl-version			\
-	check-perl5-version			\
-	check-python-version			\
-	check-java-version			\
-	check-javascript-version			\
 	check-android-version			\
+	check-csharp-version			\
+	check-d-version				\
+	check-go-version			\
 	check-guile-version			\
+	check-java-version			\
+	check-javascript-version		\
+	check-lua-version			\
 	check-mzscheme-version			\
-	check-ruby-version			\
 	check-ocaml-version			\
 	check-octave-version			\
+	check-perl5-version			\
 	check-php-version			\
-	check-csharp-version			\
-	check-lua-version			\
+	check-python-version			\
 	check-r-version				\
+	check-ruby-version			\
 	check-scilab-version			\
-	check-go-version			\
-	check-d-version
+	check-tcl-version			\
 
 # all examples
 check-%-version :
@@ -157,43 +156,43 @@
 
 # Checks examples for compilation (does not run them)
 check-examples:					\
-	check-tcl-examples			\
-	check-perl5-examples			\
-	check-python-examples			\
-	check-java-examples			\
 	check-android-examples			\
+	check-csharp-examples			\
+	check-d-examples			\
+	check-go-examples			\
 	check-guile-examples			\
+	check-java-examples			\
+	check-javascript-examples		\
+	check-lua-examples			\
 	check-mzscheme-examples			\
-	check-ruby-examples			\
 	check-ocaml-examples			\
 	check-octave-examples			\
+	check-perl5-examples			\
 	check-php-examples			\
-	check-csharp-examples                   \
-	check-lua-examples			\
+	check-python-examples			\
 	check-r-examples			\
+	check-ruby-examples			\
 	check-scilab-examples			\
-	check-go-examples			\
-	check-d-examples			\
-	check-javascript-examples
+	check-tcl-examples			\
 
-tcl_examples       :=$(shell sed '/^\#/d' $(srcdir)/Examples/tcl/check.list)
-perl5_examples     :=$(shell sed '/^\#/d' $(srcdir)/Examples/perl5/check.list)
-python_examples    :=$(shell sed '/^\#/d' $(srcdir)/Examples/python/check.list)
-java_examples      :=$(shell sed '/^\#/d' $(srcdir)/Examples/java/check.list)
 android_examples   :=$(shell sed '/^\#/d' $(srcdir)/Examples/android/check.list)
+csharp_examples    :=$(shell sed '/^\#/d' $(srcdir)/Examples/csharp/check.list)
+d_examples         :=$(shell sed '/^\#/d' $(srcdir)/Examples/d/check.list)
+go_examples        :=$(shell sed '/^\#/d' $(srcdir)/Examples/go/check.list)
 guile_examples     :=$(shell sed '/^\#/d' $(srcdir)/Examples/guile/check.list)
+java_examples      :=$(shell sed '/^\#/d' $(srcdir)/Examples/java/check.list)
+javascript_examples:=$(shell sed '/^\#/d' $(srcdir)/Examples/javascript/check.list)
+lua_examples       :=$(shell sed '/^\#/d' $(srcdir)/Examples/lua/check.list)
 mzscheme_examples  :=$(shell sed '/^\#/d' $(srcdir)/Examples/mzscheme/check.list)
-ruby_examples      :=$(shell sed '/^\#/d' $(srcdir)/Examples/ruby/check.list)
 ocaml_examples     :=$(shell sed '/^\#/d' $(srcdir)/Examples/ocaml/check.list)
 octave_examples    :=$(shell sed '/^\#/d' $(srcdir)/Examples/octave/check.list)
+perl5_examples     :=$(shell sed '/^\#/d' $(srcdir)/Examples/perl5/check.list)
 php_examples       :=$(shell sed '/^\#/d' $(srcdir)/Examples/php/check.list)
-csharp_examples    :=$(shell sed '/^\#/d' $(srcdir)/Examples/csharp/check.list)
-lua_examples       :=$(shell sed '/^\#/d' $(srcdir)/Examples/lua/check.list)
+python_examples    :=$(shell sed '/^\#/d' $(srcdir)/Examples/python/check.list)
 r_examples         :=$(shell sed '/^\#/d' $(srcdir)/Examples/r/check.list)
+ruby_examples      :=$(shell sed '/^\#/d' $(srcdir)/Examples/ruby/check.list)
 scilab_examples    :=$(shell sed '/^\#/d' $(srcdir)/Examples/scilab/check.list)
-go_examples        :=$(shell sed '/^\#/d' $(srcdir)/Examples/go/check.list)
-d_examples         :=$(shell sed '/^\#/d' $(srcdir)/Examples/d/check.list)
-javascript_examples:=$(shell sed '/^\#/d' $(srcdir)/Examples/javascript/check.list)
+tcl_examples       :=$(shell sed '/^\#/d' $(srcdir)/Examples/tcl/check.list)
 
 # all examples
 check-%-examples :
@@ -218,23 +217,23 @@
 # Checks testcases in the test-suite excluding those which are known to be broken
 check-test-suite:				\
 	check-errors-test-suite			\
-	check-tcl-test-suite			\
-	check-perl5-test-suite			\
-	check-python-test-suite			\
-	check-java-test-suite			\
+	check-csharp-test-suite			\
+	check-d-test-suite			\
+	check-go-test-suite			\
 	check-guile-test-suite			\
+	check-java-test-suite			\
+	check-javascript-test-suite		\
+	check-lua-test-suite			\
 	check-mzscheme-test-suite		\
-	check-ruby-test-suite			\
 	check-ocaml-test-suite			\
 	check-octave-test-suite			\
+	check-perl5-test-suite			\
 	check-php-test-suite			\
-	check-csharp-test-suite			\
-	check-lua-test-suite			\
+	check-python-test-suite			\
 	check-r-test-suite			\
+	check-ruby-test-suite			\
 	check-scilab-test-suite			\
-	check-go-test-suite			\
-	check-d-test-suite			\
-	check-javascript-test-suite
+	check-tcl-test-suite			\
 
 check-%-test-suite:
 	@if test -z "$(skip-$*)"; then					\
@@ -249,7 +248,7 @@
 	  echo warning: cannot $(ACTION) $* test-suite "(no dir $$dir)";\
 	else								\
 	  echo $(ACTION)ing $* test-suite;				\
-	  (cd $$dir && $(MAKE) $(FLAGS) $(ACTION) HAVE_CXX11_COMPILER=$(HAVE_CXX11_COMPILER)) \
+	  (cd $$dir && $(MAKE) $(FLAGS) $(ACTION))			\
 	  || passed=false;						\
 	fi;								\
 	test $$passed = true
@@ -265,46 +264,46 @@
 
 # Run known-to-be-broken as well as not broken testcases in the test-suite
 all-test-suite:					\
-	all-tcl-test-suite			\
-	all-perl5-test-suite			\
-	all-python-test-suite			\
-	all-java-test-suite			\
+	all-csharp-test-suite			\
+	all-d-test-suite			\
+	all-go-test-suite			\
 	all-guile-test-suite			\
+	all-java-test-suite			\
+	all-javascript-test-suite		\
+	all-lua-test-suite			\
 	all-mzscheme-test-suite			\
-	all-ruby-test-suite			\
 	all-ocaml-test-suite			\
 	all-octave-test-suite			\
+	all-perl5-test-suite			\
 	all-php-test-suite			\
-	all-csharp-test-suite			\
-	all-lua-test-suite			\
+	all-python-test-suite			\
 	all-r-test-suite			\
+	all-ruby-test-suite			\
 	all-scilab-test-suite   		\
-	all-go-test-suite			\
-	all-d-test-suite			\
-	all-javascript-test-suite
+	all-tcl-test-suite			\
 
 all-%-test-suite:
 	@$(MAKE) $(FLAGS) check-$*-test-suite ACTION=all
 
 # Run known-to-be-broken testcases in the test-suite
 broken-test-suite:				\
-	broken-tcl-test-suite			\
-	broken-perl5-test-suite			\
-	broken-python-test-suite		\
-	broken-java-test-suite			\
+	broken-csharp-test-suite		\
+	broken-d-test-suite			\
+	broken-go-test-suite			\
 	broken-guile-test-suite			\
+	broken-java-test-suite			\
+	broken-javascript-test-suite		\
+	broken-lua-test-suite			\
 	broken-mzscheme-test-suite		\
-	broken-ruby-test-suite			\
 	broken-ocaml-test-suite			\
 	broken-octave-test-suite		\
+	broken-perl5-test-suite			\
 	broken-php-test-suite			\
-	broken-csharp-test-suite		\
-	broken-lua-test-suite			\
+	broken-python-test-suite		\
 	broken-r-test-suite			\
-	broken-scilab-test-suite           	\
-	broken-go-test-suite			\
-	broken-d-test-suite			\
-	broken-javascript-test-suite
+	broken-ruby-test-suite			\
+	broken-scilab-test-suite		\
+	broken-tcl-test-suite			\
 
 broken-%-test-suite:
 	@$(MAKE) $(FLAGS) check-$*-test-suite ACTION=broken
@@ -341,7 +340,7 @@
 # DISTCLEAN - clean what configure built
 #####################################################################
 
-DISTCLEAN-DEAD = config.status config.log config.cache swig.spec Makefile mkmf.log preinst-swig
+DISTCLEAN-DEAD = config.status config.log config.cache Makefile mkmf.log preinst-swig
 
 distclean-helper: distclean-test-suite distclean-examples distclean-tools distclean-dead
 
@@ -437,7 +436,7 @@
 
 lib-languages = typemaps tcl perl5 python guile java mzscheme ruby php ocaml octave \
 	csharp lua r go d javascript javascript/jsc \
-	javascript/v8 scilab xml
+	javascript/v8 javascript/napi scilab xml
 
 lib-modules = std
 
@@ -497,24 +496,11 @@
 # DIST and other maintenance
 ############################################################################
 
-# distribution directory
-dd = @PACKAGE_NAME@-@PACKAGE_VERSION@
-srpm = @PACKAGE_NAME@-@PACKAGE_VERSION@
-
 dist:
 	@echo "'make dist' not implemented - use Tools/mkdist.py instead - e.g.:"
 	@echo "Tools/mkdist.py @VERSION@ master"
 	@false
 
-srcrpm:
-	rm -fr $(srpm) $(srpm).src.rpm
-	echo "TODO: update to use git instead of cvs"
-	cvs export -d $(srpm) -r HEAD SWIG
-	cp swig.spec $(srpm)
-	tar -cf - $(srpm) | gzip --best > $(srpm).tar.gz
-	rm -fr $(srpm)
-	rpmbuild -ts $(srpm).tar.gz
-
 # Update the autoconf files for detecting host/targets. Automake will do this in
 # version 1.10 for our case of not having a top level Makefile.am. Until then we
 # can fetch them manually and will have to commit them to Git.
diff --git a/README b/README
index 6d11833..e499e76 100644
--- a/README
+++ b/README
@@ -1,7 +1,5 @@
 SWIG (Simplified Wrapper and Interface Generator)
 
-Version: 4.0.1 (21 Aug 2019)
-
 Tagline: SWIG is a compiler that integrates C and C++ with languages
          including Perl, Python, Tcl, Ruby, PHP, Java, C#, D, Go, Lua,
          Octave, R, Scheme (Guile, MzScheme/Racket), Scilab, Ocaml.
@@ -14,7 +12,7 @@
 
 Up-to-date SWIG related information can be found at
 
-        http://www.swig.org
+        https://www.swig.org
 
 A SWIG FAQ and other hints can be found on the SWIG Wiki:
 
@@ -26,7 +24,7 @@
 further insight into the license including the license of SWIG's
 output code, please visit
 
-        http://www.swig.org/legal.html
+        https://www.swig.org/legal.html
 
 Release Notes
 =============
@@ -49,7 +47,7 @@
 Doc/Devel subdirectory.  This is not necessarily up-to-date, but it
 has some information on SWIG internals.
 
-Documentation is also online at http://www.swig.org/doc.html.
+Documentation is also online at https://www.swig.org/doc.html.
 
 Backwards Compatibility
 =======================
@@ -70,7 +68,7 @@
 using the release tarball/zip file. The INSTALL file has generic
 build and installation instructions for Unix users.
 Users wishing to build and install code from Github should
-visit http://swig.org/svn.html to obtain the more detailed
+visit https://swig.org/svn.html to obtain the more detailed
 instructions required for building code obtained from Github - extra
 steps are required compared to building from the release tarball.
 
@@ -92,7 +90,7 @@
 Known Issues
 ============
 There are minor known bugs, details of which are in the bug tracker, see
-http://www.swig.org/bugs.html.
+https://www.swig.org/bugs.html.
 
 Troubleshooting
 ===============
@@ -134,7 +132,7 @@
 
 If you would like to join the SWIG development team or contribute a
 language module to the distribution, please contact the swig-devel
-mailing list, details at http://www.swig.org/mail.html.
+mailing list, details at https://www.swig.org/mail.html.
 
 
  -- The SWIG Maintainers
diff --git a/RELEASENOTES b/RELEASENOTES
index 8633dad..e4cfb78 100644
--- a/RELEASENOTES
+++ b/RELEASENOTES
@@ -5,7 +5,80 @@
 Release Notes
 =============
 Detailed release notes are available with the release and are also
-published on the SWIG web site at http://swig.org/release.html.
+published on the SWIG web site at https://swig.org/release.html.
+
+SWIG-4.2.1 summary:
+- Tcl 9.0 support.
+- Octave 9.0 support.
+- Improvements wrapping friend functions.
+- Variadic templated functions within a template support.
+- Type deduction enhancements.
+- Stability and regression fixes.
+
+SWIG-4.2.0 summary:
+- Various template wrapping improvements: template template parameters,
+  variadic templates, partially specialized templates, const template
+  parameters and improved error checking instantiating templates.
+- Improved decltype() support for expressions.
+- C++14 auto without trailing return type and C++11 auto variables.
+- Numerous C++ using declarations improvements.
+- Numerous fixes for constructors, destructors and assignment operators:
+  implicit, default and deleted and related non-assignable variable
+  wrappers.
+- STL: std::array and std::map improvements, std::string_view support
+  added.
+- Various C preprocessor improvements.
+- Various issues fixed to do with architecture specific long type.
+- Various Doxygen improvements.
+- D1/Tango support removed.  D2/Phobos is now the supported D version
+  and SWIG now generates code which works with recent D2 releases.
+- New Javascript generator targeting Node.js binary stable ABI Node-API.
+- Octave 8.1 support added.
+- PHP7 support removed, PHP8 is now the supported PHP version.
+- Python STL container wrappers now use the Python Iterator Protocol.
+- Python stable ABI support added.
+- Python 3.12 support added.
+- Ruby 3.2 and 3.3 support.
+- Scilab 2023.* support added.
+- Various minor enhancements for C#, Go, Guile, Javascript, Lua, Ocaml,
+  Perl, PHP, R, Racket, Ruby, Scilab and Tcl.
+- A number of deprecated features have been removed.
+
+SWIG-4.1.1 summary:
+- Couple of stability fixes.
+- Stability fix in ccache-swig when calculating hashes of inputs.
+- Some template handling improvements.
+- R - minor fixes plus deprecation for rtypecheck typemaps being optional.
+
+SWIG-4.1.0 summary:
+- Add Javascript Node v12-v18 support, remove support prior to v6.
+- Octave 6.0 to 6.4 support added.
+- Add PHP 8 support.
+- PHP wrapping is now done entirely via PHP's C API - no more .php wrapper.
+- Perl 5.8.0 is now the oldest version SWIG supports.
+- Python 3.3 is now the oldest Python 3 version SWIG supports.
+- Python 3.9-3.11 support added.
+- Various memory leak fixes in Python generated code.
+- Scilab 5.5-6.1 support improved.
+- Many improvements for each and every target language.
+- Various preprocessor expression handling improvements.
+- Improved C99, C++11, C++14, C++17 support. Start adding C++20 standard.
+- Make SWIG much more move semantics friendly.
+- Add C++ std::unique_ptr support.
+- Few minor C++ template handling improvements.
+- Various C++ using declaration fixes.
+- Few fixes for handling Doxygen comments.
+- GitHub Actions is now used instead of Travis CI for continuous integration.
+- Add building SWIG using CMake as a secondary build system.
+- Update optional SWIG build dependency for regex support from PCRE to PCRE2.
+
+SWIG-4.0.2 summary:
+- A few fixes around doxygen comment handling.
+- Ruby 2.7 support added.
+- Various minor improvements to C#, D, Java, OCaml, Octave, Python,
+  R, Ruby.
+- Considerable performance improvement running SWIG on large
+  interface files.
 
 SWIG-4.0.1 summary:
 - SWIG now cleans up on error by removing all generated files.
@@ -113,7 +186,7 @@
 SWIG-3.0.0 summary:
 - This is a major new release focusing primarily on C++ improvements.
 - C++11 support added. Please see documentation for details of supported
-  features: http://www.swig.org/Doc3.0/CPlusPlus11.html
+  features: https://www.swig.org/Doc3.0/CPlusPlus11.html
 - Nested class support added. This has been taken full advantage of in
   Java and C#. Other languages can use the nested classes, but require
   further work for a more natural integration into the target language.
@@ -220,7 +293,7 @@
   and Python language modules.
 
 SWIG-2.0.0 summary:
-- License changes, see LICENSE file and http://www.swig.org/legal.html.
+- License changes, see LICENSE file and https://www.swig.org/legal.html.
 - Much better nested class/struct support.
 - Much improved template partial specialization and explicit
   specialization handling.
diff --git a/Source/CParse/cparse.h b/Source/CParse/cparse.h
index c67ffea..bda41e2 100644
--- a/Source/CParse/cparse.h
+++ b/Source/CParse/cparse.h
@@ -4,15 +4,15 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * cparse.h
  *
  * SWIG parser module.
  * ----------------------------------------------------------------------------- */
 
-#ifndef SWIG_CPARSE_H_
-#define SWIG_CPARSE_H_
+#ifndef SWIG_CPARSE_H
+#define SWIG_CPARSE_H
 
 #include "swig.h"
 #include "swigwarn.h"
@@ -34,16 +34,14 @@
   extern void Swig_cparse_cplusplusout(int);
   extern void scanner_file(File *);
   extern void scanner_next_token(int);
-  extern void skip_balanced(int startchar, int endchar);
+  extern int skip_balanced(int startchar, int endchar);
   extern String *get_raw_text_balanced(int startchar, int endchar);
   extern void skip_decl(void);
-  extern void scanner_check_typedef(void);
-  extern void scanner_ignore_typedef(void);
   extern void scanner_last_id(int);
   extern void scanner_clear_rename(void);
   extern void scanner_set_location(String *file, int line);
   extern void scanner_set_main_input_file(String *file);
-  extern String *scanner_get_main_input_file();
+  extern String *scanner_get_main_input_file(void);
   extern void Swig_cparse_follow_locators(int);
   extern void start_inline(char *, int);
   extern String *scanner_ccode;
@@ -66,8 +64,10 @@
 
 /* templ.c */
   extern int Swig_cparse_template_expand(Node *n, String *rname, ParmList *tparms, Symtab *tscope);
-  extern Node *Swig_cparse_template_locate(String *name, ParmList *tparms, Symtab *tscope);
+  extern Node *Swig_cparse_template_locate(String *name, ParmList *tparms, String *symname, Symtab *tscope);
   extern void Swig_cparse_debug_templates(int);
+  extern ParmList *Swig_cparse_template_parms_expand(ParmList *instantiated_parameters, Node *primary, Node *templ);
+  extern ParmList *Swig_cparse_template_partialargs_expand(ParmList *partially_specialized_parms, Node *primary, ParmList *templateparms);
 
 #ifdef __cplusplus
 }
diff --git a/Source/CParse/cscanner.c b/Source/CParse/cscanner.c
index cb2fdb5..03cc8c3 100644
--- a/Source/CParse/cscanner.c
+++ b/Source/CParse/cscanner.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * scanner.c
  *
@@ -46,7 +46,6 @@
 /* Private vars */
 static int scan_init = 0;
 static int num_brace = 0;
-static int last_brace = 0;
 static int last_id = 0;
 static int rename_active = 0;
 
@@ -93,7 +92,7 @@
     const size_t len = strlen(structuralTags[n]);
     if (strncmp(slashPointer, structuralTags[n], len) == 0) {
       /* Take care to avoid false positives with prefixes of other tags. */
-      if (slashPointer[len] == '\0' || isspace(slashPointer[len]))
+      if (slashPointer[len] == '\0' || isspace((int)slashPointer[len]))
 	return 1;
     }
   }
@@ -123,7 +122,7 @@
  * Initialize buffers
  * ------------------------------------------------------------------------- */
 
-void scanner_init() {
+void scanner_init(void) {
   scan = NewScanner();
   Scanner_idstart(scan,"%");
   scan_init = 1;
@@ -163,15 +162,17 @@
  *
  * Skips a piece of code enclosed in begin/end symbols such as '{...}' or
  * (...).  Ignores symbols inside comments or strings.
+ *
+ * Returns 0 if successfully skipped, -1 if EOF found first.
  * ----------------------------------------------------------------------------- */
 
-void skip_balanced(int startchar, int endchar) {
+int skip_balanced(int startchar, int endchar) {
   int start_line = Scanner_line(scan);
   Clear(scanner_ccode);
 
   if (Scanner_skip_balanced(scan,startchar,endchar) < 0) {
     Swig_error(cparse_file, start_line, "Missing '%c'. Reached end of input.\n", endchar);
-    return;
+    return -1;
   }
 
   cparse_line = Scanner_line(scan);
@@ -180,7 +181,7 @@
   Append(scanner_ccode, Scanner_text(scan));
   if (endchar == '}')
     num_brace--;
-  return;
+  return 0;
 }
 
 /* -----------------------------------------------------------------------------
@@ -214,13 +215,13 @@
     tok = Scanner_token(scan);
     if (tok == 0) {
       if (!Swig_error_count()) {
-	Swig_error(cparse_file, start_line, "Missing semicolon. Reached end of input.\n");
+	Swig_error(cparse_file, start_line, "Missing semicolon (';'). Reached end of input.\n");
       }
       return;
     }
     if (tok == SWIG_TOKEN_LBRACE) {
       if (Scanner_skip_balanced(scan,'{','}') < 0) {
-	Swig_error(cparse_file, start_line, "Missing '}'. Reached end of input.\n");
+	Swig_error(cparse_file, start_line, "Missing closing brace ('}'). Reached end of input.\n");
       }
       break;
     }
@@ -267,14 +268,13 @@
     case SWIG_TOKEN_RBRACE:
       num_brace--;
       if (num_brace < 0) {
-	Swig_error(cparse_file, cparse_line, "Syntax error. Extraneous '}'\n");
+	Swig_error(cparse_file, cparse_line, "Syntax error. Extraneous closing brace ('}')\n");
 	num_brace = 0;
       } else {
 	return RBRACE;
       }
       break;
     case SWIG_TOKEN_LBRACE:
-      last_brace = num_brace;
       num_brace++;
       return LBRACE;
     case SWIG_TOKEN_EQUAL:
@@ -325,12 +325,14 @@
       return ARROW;
     case SWIG_TOKEN_PERIOD:
       return PERIOD;
-    case SWIG_TOKEN_MODULO:
+    case SWIG_TOKEN_PERCENT:
       return MODULO;
     case SWIG_TOKEN_COLON:
       return COLON;
     case SWIG_TOKEN_DCOLONSTAR:
       return DSTAR;
+    case SWIG_TOKEN_LTEQUALGT:
+      return LESSEQUALGREATER;
       
     case SWIG_TOKEN_DCOLON:
       {
@@ -351,6 +353,23 @@
       }
       break;
       
+    case SWIG_TOKEN_ELLIPSIS:
+      return ELLIPSIS;
+
+    case SWIG_TOKEN_LLBRACKET:
+      do {
+        tok = Scanner_token(scan);
+      } while ((tok != SWIG_TOKEN_RRBRACKET) && (tok > 0));
+      if (tok <= 0) {
+        Swig_error(cparse_file, cparse_line, "Unbalanced double brackets, missing closing (']]'). Reached end of input.\n");
+      }
+      break;
+
+    case SWIG_TOKEN_RRBRACKET:
+      /* Turn an unmatched ]] back into two ] - e.g. `a[a[0]]` */
+      scanner_next_token(RBRACKET);
+      return RBRACKET;
+
       /* Look for multi-character sequences */
       
     case SWIG_TOKEN_RSTRING:
@@ -400,9 +419,14 @@
       return NUM_ULONGLONG;
       
     case SWIG_TOKEN_DOUBLE:
+      return NUM_DOUBLE;
+
     case SWIG_TOKEN_FLOAT:
       return NUM_FLOAT;
       
+    case SWIG_TOKEN_LONGDOUBLE:
+      return NUM_LONGDOUBLE;
+
     case SWIG_TOKEN_BOOL:
       return NUM_BOOL;
       
@@ -410,7 +434,6 @@
       Scanner_skip_line(scan);
       yylval.id = Swig_copy_string(Char(Scanner_text(scan)));
       return POUND;
-      break;
       
     case SWIG_TOKEN_CODEBLOCK:
       yylval.str = NewString(Scanner_text(scan));
@@ -428,17 +451,32 @@
 	/* Concatenate or skip all consecutive comments at once. */
 	do {
 	  String *cmt = Scanner_text(scan);
+	  String *cmt_modified = 0;
 	  char *loc = Char(cmt);
 	  if ((strncmp(loc, "/*@SWIG", 7) == 0) && (loc[Len(cmt)-3] == '@')) {
 	    Scanner_locator(scan, cmt);
 	  }
 	  if (scan_doxygen_comments) { /* else just skip this node, to avoid crashes in parser module*/
+
+	    int slashStyle = 0; /* Flag for "///" style doxygen comments */
+	    if (strncmp(loc, "///", 3) == 0) {
+	      slashStyle = 1;
+	      if (Len(cmt) == 3) {
+		/* Modify to make length=4 to ensure that the empty comment does
+		   get processed to preserve the newlines in the original comments. */
+		cmt_modified = NewStringf("%s ", cmt);
+		cmt = cmt_modified;
+		loc = Char(cmt);
+	      }
+	    }
+	    
 	    /* Check for all possible Doxygen comment start markers while ignoring
 	       comments starting with a row of asterisks or slashes just as
-	       Doxygen itself does. */
+	       Doxygen itself does.  Also skip empty comment (slash-star-star-slash), 
+	       which causes a crash due to begin > end. */
 	    if (Len(cmt) > 3 && loc[0] == '/' &&
 		((loc[1] == '/' && ((loc[2] == '/' && loc[3] != '/') || loc[2] == '!')) ||
-		 (loc[1] == '*' && ((loc[2] == '*' && loc[3] != '*') || loc[2] == '!')))) {
+		 (loc[1] == '*' && ((loc[2] == '*' && loc[3] != '*' && loc[3] != '/') || loc[2] == '!')))) {
 	      comment_kind_t this_comment = loc[3] == '<' ? DOX_COMMENT_POST : DOX_COMMENT_PRE;
 	      if (existing_comment != DOX_COMMENT_NONE && this_comment != existing_comment) {
 		/* We can't concatenate together Doxygen pre- and post-comments. */
@@ -461,6 +499,13 @@
 		  Setline(yylval.str, Scanner_start_line(scan));
 		  Setfile(yylval.str, Scanner_file(scan));
 		} else {
+		  if (slashStyle) {
+		    /* Add a newline to the end of each doxygen "///" comment,
+		       since they are processed individually, unlike the
+		       slash-star style, which gets processed as a block with
+		       newlines included. */
+		    Append(yylval.str, "\n");
+		  }
 		  Append(yylval.str, str);
 		}
 
@@ -471,6 +516,7 @@
 	  do {
 	    tok = Scanner_token(scan);
 	  } while (tok == SWIG_TOKEN_ENDLINE);
+	  Delete(cmt_modified);
 	} while (tok == SWIG_TOKEN_COMMENT);
 
 	Scanner_pushtoken(scan, tok, Scanner_text(scan));
@@ -496,25 +542,15 @@
   }
 }
 
-static int check_typedef = 0;
-
 void scanner_set_location(String *file, int line) {
   Scanner_set_location(scan,file,line-1);
 }
 
-void scanner_check_typedef() {
-  check_typedef = 1;
-}
-
-void scanner_ignore_typedef() {
-  check_typedef = 0;
-}
-
 void scanner_last_id(int x) {
   last_id = x;
 }
 
-void scanner_clear_rename() {
+void scanner_clear_rename(void) {
   rename_active = 0;
 }
 
@@ -528,7 +564,7 @@
   main_input_file = file;
 }
 
-String *scanner_get_main_input_file() {
+String *scanner_get_main_input_file(void) {
   return main_input_file;
 }
 
@@ -547,6 +583,9 @@
     scanner_init();
   }
 
+  Delete(cparse_unknown_directive);
+  cparse_unknown_directive = NULL;
+
   if (next_token) {
     l = next_token;
     next_token = 0;
@@ -575,29 +614,36 @@
   switch (l) {
 
   case NUM_INT:
+    yylval.dtype.type = T_INT;
+    goto num_common;
+  case NUM_DOUBLE:
+    yylval.dtype.type = T_DOUBLE;
+    goto num_common;
   case NUM_FLOAT:
+    yylval.dtype.type = T_FLOAT;
+    goto num_common;
+  case NUM_LONGDOUBLE:
+    yylval.dtype.type = T_LONGDOUBLE;
+    goto num_common;
   case NUM_ULONG:
+    yylval.dtype.type = T_ULONG;
+    goto num_common;
   case NUM_LONG:
+    yylval.dtype.type = T_LONG;
+    goto num_common;
   case NUM_UNSIGNED:
+    yylval.dtype.type = T_UINT;
+    goto num_common;
   case NUM_LONGLONG:
+    yylval.dtype.type = T_LONGLONG;
+    goto num_common;
   case NUM_ULONGLONG:
+    yylval.dtype.type = T_ULONGLONG;
+    goto num_common;
   case NUM_BOOL:
-    if (l == NUM_INT)
-      yylval.dtype.type = T_INT;
-    if (l == NUM_FLOAT)
-      yylval.dtype.type = T_DOUBLE;
-    if (l == NUM_ULONG)
-      yylval.dtype.type = T_ULONG;
-    if (l == NUM_LONG)
-      yylval.dtype.type = T_LONG;
-    if (l == NUM_UNSIGNED)
-      yylval.dtype.type = T_UINT;
-    if (l == NUM_LONGLONG)
-      yylval.dtype.type = T_LONGLONG;
-    if (l == NUM_ULONGLONG)
-      yylval.dtype.type = T_ULONGLONG;
-    if (l == NUM_BOOL)
-      yylval.dtype.type = T_BOOL;
+    yylval.dtype.type = T_BOOL;
+num_common:
+    yylval.dtype.unary_arg_type = 0;
     yylval.dtype.val = NewString(Scanner_text(scan));
     yylval.dtype.bitfield = 0;
     yylval.dtype.throws = 0;
@@ -873,15 +919,19 @@
 	  return (USING);
 	if (strcmp(yytext, "namespace") == 0)
 	  return (NAMESPACE);
-	if (strcmp(yytext, "override") == 0)
+	if (strcmp(yytext, "override") == 0) {
+	  last_id = 1;
 	  return (OVERRIDE);
-	if (strcmp(yytext, "final") == 0)
+	}
+	if (strcmp(yytext, "final") == 0) {
+	  last_id = 1;
 	  return (FINAL);
+	}
       } else {
 	if (strcmp(yytext, "class") == 0) {
 	  Swig_warning(WARN_PARSE_CLASS_KEYWORD, cparse_file, cparse_line, "class keyword used, but not in C++ mode.\n");
 	}
-	if (strcmp(yytext, "complex") == 0) {
+	if (strcmp(yytext, "_Complex") == 0) {
 	  yylval.type = NewSwigType(T_COMPLEX);
 	  return (TYPE_COMPLEX);
 	}
@@ -921,16 +971,12 @@
 	return (yylex());
 
     } else {
-      Delete(cparse_unknown_directive);
-      cparse_unknown_directive = NULL;
-
       /* SWIG directives */
+      String *stext = 0;
       if (strcmp(yytext, "%module") == 0)
 	return (MODULE);
       if (strcmp(yytext, "%insert") == 0)
 	return (INSERT);
-      if (strcmp(yytext, "%name") == 0)
-	return (NAME);
       if (strcmp(yytext, "%rename") == 0) {
 	rename_active = 1;
 	return (RENAME);
@@ -945,14 +991,6 @@
 	return (BEGINFILE);
       if (strcmp(yytext, "%endoffile") == 0)
 	return (ENDOFFILE);
-      if (strcmp(yytext, "%val") == 0) {
-	Swig_warning(WARN_DEPRECATED_VAL, cparse_file, cparse_line, "%%val directive deprecated (ignored).\n");
-	return (yylex());
-      }
-      if (strcmp(yytext, "%out") == 0) {
-	Swig_warning(WARN_DEPRECATED_OUT, cparse_file, cparse_line, "%%out directive deprecated (ignored).\n");
-	return (yylex());
-      }
       if (strcmp(yytext, "%constant") == 0)
 	return (CONSTANT);
       if (strcmp(yytext, "%typedef") == 0) {
@@ -979,8 +1017,6 @@
         rename_active = 1;
 	return (FEATURE);
       }
-      if (strcmp(yytext, "%except") == 0)
-	return (EXCEPT);
       if (strcmp(yytext, "%importfile") == 0)
 	return (IMPORT);
       if (strcmp(yytext, "%echo") == 0)
@@ -1001,18 +1037,25 @@
       if (strcmp(yytext, "%warn") == 0)
 	return (WARN);
 
-      /* Note down the apparently unknown directive for error reporting. */
+      /* Note down the apparently unknown directive for error reporting - if
+       * we end up reporting a generic syntax error we'll instead report an
+       * error for this as an unknown directive.  Then we treat it as MODULO
+       * (`%`) followed by an identifier and if that parses OK then
+       * `cparse_unknown_directive` doesn't get used.
+       *
+       * This allows `a%b` to be handled in expressions without a space after
+       * the operator.
+       */
       cparse_unknown_directive = NewString(yytext);
+      stext = NewString(yytext + 1);
+      Seek(stext,0,SEEK_SET);
+      Setfile(stext,cparse_file);
+      Setline(stext,cparse_line);
+      Scanner_push(scan,stext);
+      Delete(stext);
+      return (MODULO);
     }
-    /* Have an unknown identifier, as a last step, we'll do a typedef lookup on it. */
 
-    /* Need to fix this */
-    if (check_typedef) {
-      if (SwigType_istypedef(yytext)) {
-	yylval.type = NewString(yytext);
-	return (TYPE_TYPEDEF);
-      }
-    }
     yylval.id = Swig_copy_string(yytext);
     last_id = 1;
     return (ID);
diff --git a/Source/CParse/parser.y b/Source/CParse/parser.y
index 470b7d0..4a7040d 100644
--- a/Source/CParse/parser.y
+++ b/Source/CParse/parser.y
@@ -4,45 +4,59 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * parser.y
  *
- * YACC parser for SWIG.   The grammar is a somewhat broken subset of C/C++.
+ * Bison parser for SWIG.   The grammar is a somewhat broken subset of C/C++.
  * This file is a bit of a mess and probably needs to be rewritten at
  * some point.  Beware.
  * ----------------------------------------------------------------------------- */
 
-/* There are 6 known shift-reduce conflicts in this file, fail compilation if any
-   more are introduced.
+%require "3.5"
+
+/* There are a small number of known shift-reduce conflicts in this file, fail
+   compilation if any more are introduced.
 
    Please don't increase the number of the conflicts if at all possible. And if
    you really have no choice but to do it, make sure you clearly document each
    new conflict in this file.
  */
-%expect 6
+%expect 7
+
+/* Make the internal token numbers the same as the external token numbers
+ * which saves Bison generating a lookup table to map between them, giving
+ * a smaller and faster generated parser.
+ */
+%define api.token.raw
 
 %{
-#define yylex yylex
+/* doh.h uses #pragma GCC poison with GCC to prevent direct calls to certain
+ * standard C library functions being introduced, but those cause errors due
+ * to checks like `#if defined YYMALLOC || defined malloc` in the bison
+ * template code.  We can't easily arrange to include headers after that
+ * template code, so instead we disable the problematic poisoning for this
+ * file.
+ */
+#define DOH_NO_POISON_MALLOC_FREE
 
 #include "swig.h"
 #include "cparse.h"
 #include "preprocessor.h"
 #include <ctype.h>
 
-/* We do this for portability */
-#undef alloca
-#define alloca malloc
+#define YYMALLOC Malloc
+#define YYFREE Free
 
 /* -----------------------------------------------------------------------------
  *                               Externals
  * ----------------------------------------------------------------------------- */
 
-int  yyparse();
+int  yyparse(void);
 
 /* NEW Variables */
 
-static Node    *top = 0;      /* Top of the generated parse tree */
+static void    *top = 0;      /* Top of the generated parse tree */
 static int      unnamed = 0;  /* Unnamed datatype counter */
 static Hash    *classes = 0;        /* Hash table of classes */
 static Hash    *classes_typedefs = 0; /* Hash table of typedef classes: typedef struct X {...} Y; */
@@ -54,7 +68,7 @@
 static String  *Namespaceprefix = 0;
 static int      inclass = 0;
 static Node    *currentOuterClass = 0; /* for nested classes */
-static const char *last_cpptype = 0;
+static String  *last_cpptype = 0;
 static int      inherit_list = 0;
 static Parm    *template_parameters = 0;
 static int      parsing_template_declaration = 0;
@@ -64,12 +78,11 @@
 static int      cparse_externc = 0;
 int		ignore_nested_classes = 0;
 int		kwargs_supported = 0;
+
 /* -----------------------------------------------------------------------------
  *                            Doxygen Comment Globals
  * ----------------------------------------------------------------------------- */
 static String *currentDeclComment = NULL; /* Comment of C/C++ declaration. */
-static Node *previousNode = NULL; /* Pointer to the previous node (for post comments) */
-static Node *currentNode = NULL; /* Pointer to the current node (for post comments) */
 
 /* -----------------------------------------------------------------------------
  *                            Assist Functions
@@ -84,9 +97,6 @@
 
 static Node *new_node(const_String_or_char_ptr tag) {
   Node *n = Swig_cparse_new_node(tag);
-  /* Remember the previous node in case it will need a post-comment */
-  previousNode = currentNode;
-  currentNode = n;
   return n;
 }
 
@@ -223,6 +233,49 @@
 #define  CPLUS_PRIVATE   2
 #define  CPLUS_PROTECTED 3
 
+/* storage classes */
+
+#define SWIG_STORAGE_CLASS_EXTERNC	0x0001
+#define SWIG_STORAGE_CLASS_EXTERNCPP	0x0002
+#define SWIG_STORAGE_CLASS_EXTERN	0x0004
+#define SWIG_STORAGE_CLASS_STATIC	0x0008
+#define SWIG_STORAGE_CLASS_TYPEDEF	0x0010
+#define SWIG_STORAGE_CLASS_VIRTUAL	0x0020
+#define SWIG_STORAGE_CLASS_FRIEND	0x0040
+#define SWIG_STORAGE_CLASS_EXPLICIT	0x0080
+#define SWIG_STORAGE_CLASS_CONSTEXPR	0x0100
+#define SWIG_STORAGE_CLASS_THREAD_LOCAL	0x0200
+
+/* Test if multiple bits are set in x. */
+static int multiple_bits_set(unsigned x) { return (x & (x - 1)) != 0; }
+
+static const char* storage_class_string(int c) {
+  switch (c) {
+    case SWIG_STORAGE_CLASS_EXTERNC:
+      return "extern \"C\"";
+    case SWIG_STORAGE_CLASS_EXTERNCPP:
+      return "extern \"C++\"";
+    case SWIG_STORAGE_CLASS_EXTERN:
+      return "extern";
+    case SWIG_STORAGE_CLASS_STATIC:
+      return "static";
+    case SWIG_STORAGE_CLASS_TYPEDEF:
+      return "typedef";
+    case SWIG_STORAGE_CLASS_VIRTUAL:
+      return "virtual";
+    case SWIG_STORAGE_CLASS_FRIEND:
+      return "friend";
+    case SWIG_STORAGE_CLASS_EXPLICIT:
+      return "explicit";
+    case SWIG_STORAGE_CLASS_CONSTEXPR:
+      return "constexpr";
+    case SWIG_STORAGE_CLASS_THREAD_LOCAL:
+      return "thread_local";
+  }
+  assert(0);
+  return "<unknown>";
+}
+
 /* include types */
 static int   import_mode = 0;
 
@@ -259,7 +312,7 @@
 
 /* Forward renaming operator */
 
-static String *resolve_create_node_scope(String *cname, int is_class_definition);
+static String *resolve_create_node_scope(String *cname, int is_class_definition, int *errored);
 
 
 Hash *Swig_cparse_features(void) {
@@ -268,7 +321,14 @@
   return features_hash;
 }
 
-/* Fully qualify any template parameters */
+/* -----------------------------------------------------------------------------
+ * feature_identifier_fix()
+ *
+ * If a template, return template with all template parameters fully resolved.
+ *
+ * This is a copy and modification of typemap_identifier_fix.
+ * ----------------------------------------------------------------------------- */
+
 static String *feature_identifier_fix(String *s) {
   String *tp = SwigType_istemplate_templateprefix(s);
   if (tp) {
@@ -337,21 +397,15 @@
 }
 
 /* Generate an unnamed identifier */
-static String *make_unnamed() {
+static String *make_unnamed(void) {
   unnamed++;
   return NewStringf("$unnamed%d$",unnamed);
 }
 
-/* Return if the node is a friend declaration */
-static int is_friend(Node *n) {
-  return Cmp(Getattr(n,"storage"),"friend") == 0;
-}
-
 static int is_operator(String *name) {
   return Strncmp(name,"operator ", 9) == 0;
 }
 
-
 /* Add declaration list to symbol table */
 static int  add_only_one = 0;
 
@@ -364,38 +418,51 @@
   }
   while (n) {
     String *symname = 0;
-    /* for friends, we need to pop the scope once */
     String *old_prefix = 0;
     Symtab *old_scope = 0;
-    int isfriend = inclass && is_friend(n);
+    int isfriend = inclass && Checkattr(n, "storage", "friend");
     int iscdecl = Cmp(nodeType(n),"cdecl") == 0;
     int only_csymbol = 0;
     
     if (inclass) {
       String *name = Getattr(n, "name");
       if (isfriend) {
-	/* for friends, we need to add the scopename if needed */
+	/* For friends, set the scope to the same as the class that the friend is defined/declared in, that is, pop scope once */
 	String *prefix = name ? Swig_scopename_prefix(name) : 0;
 	old_prefix = Namespaceprefix;
 	old_scope = Swig_symbol_popscope();
 	Namespaceprefix = Swig_symbol_qualifiedscopename(0);
 	if (!prefix) {
+	  /* To check - this should probably apply to operators too */
 	  if (name && !is_operator(name) && Namespaceprefix) {
-	    String *nname = NewStringf("%s::%s", Namespaceprefix, name);
-	    Setattr(n,"name",nname);
-	    Delete(nname);
+	    String *friendusing = NewStringf("using namespace %s;", Namespaceprefix);
+	    Setattr(n, "friendusing", friendusing);
+	    Delete(friendusing);
 	  }
 	} else {
-	  Symtab *st = Swig_symbol_getscope(prefix);
-	  String *ns = st ? Getattr(st,"name") : prefix;
-	  String *base  = Swig_scopename_last(name);
-	  String *nname = NewStringf("%s::%s", ns, base);
-	  Setattr(n,"name",nname);
-	  Delete(nname);
-	  Delete(base);
-	  Delete(prefix);
+	  /* Qualified friend declarations should not be possible as they are ignored in the parse tree */
+	  /* TODO: uncomment out for swig-4.3.0
+	  assert(0);
+	  */
 	}
-	Namespaceprefix = 0;
+      } else if (Equal(nodeType(n), "using")) {
+	String *uname = Getattr(n, "uname");
+	Node *cls = current_class ? current_class : currentOuterClass; /* Current class seems to vary depending on whether it is a template class or a plain class */
+	String *nprefix = 0;
+	String *nlast = 0;
+	Swig_scopename_split(uname, &nprefix, &nlast);
+	if (Swig_item_in_list(Getattr(cls, "baselist"), nprefix) || Swig_item_in_list(Getattr(cls, "protectedbaselist"), nprefix) || Swig_item_in_list(Getattr(cls, "privatebaselist"), nprefix)) {
+	  String *plain_name = SwigType_istemplate(nprefix) ? SwigType_templateprefix(nprefix) : nprefix;
+	  if (Equal(nlast, plain_name)) {
+	    /* Using declaration looks like it is using a constructor in an immediate base class - change the constructor name for this class.
+	     * C++11 requires using declarations for inheriting base constructors to be in the immediate base class.
+	     * Note that we don't try and look up the constructor in the base class as the constructor may be an implicit/implied constructor and hence not exist. */
+	    Symtab *stab = Swig_symbol_current();
+	    String *nname = Getattr(stab, "name");
+	    Setattr(n, "name", nname);
+	    SetFlag(n, "usingctor");
+	  }
+	}
       } else {
 	/* for member functions, we need to remove the redundant
 	   class scope if provided, as in
@@ -444,9 +511,12 @@
 	  }
 	}
       } else {
-	  Setattr(n,"access", "public");
+	Setattr(n, "access", "public");
       }
+    } else if (extendmode && !inclass) {
+      Setattr(n, "access", "public");
     }
+
     if (Getattr(n,"sym:name")) {
       n = nextSibling(n);
       continue;
@@ -475,11 +545,10 @@
 	    } else {
 	      ty = type;
 	    }
-	    if (!SwigType_ismutable(ty) || (storage && Strstr(storage, "constexpr"))) {
-	      SetFlag(n,"hasconsttype");
-	      SetFlag(n,"feature:immutable");
+	    if (storage && (Strstr(storage, "constexpr") || (Strstr(storage, "static") && !SwigType_ismutable(ty)))) {
+	      SetFlag(n, "hasconsttype");
 	    }
-	    if (tmp) Delete(tmp);
+	    Delete(tmp);
 	  }
 	  if (!type) {
 	    Printf(stderr,"notype name %s\n", name);
@@ -528,6 +597,13 @@
       n = nextSibling(n);
       continue;
     }
+
+    if (GetFlag(n, "valueignored")) {
+      SWIG_WARN_NODE_BEGIN(n);
+      Swig_warning(WARN_PARSE_ASSIGNED_VALUE, Getfile(n), Getline(n), "Value assigned to %s not used due to limited parsing implementation.\n", SwigType_namestr(Getattr(n, "name")));
+      SWIG_WARN_NODE_END(n);
+    }
+
     if (cparse_cplusplus) {
       String *value = Getattr(n, "value");
       if (value && Strcmp(value, "delete") == 0) {
@@ -546,6 +622,19 @@
 	  SetFlag(n, "feature:ignore");
 	}
       }
+      if (Equal(Getattr(n, "type"), "auto")) {
+	/* Ignore functions with an auto return type and no trailing return type
+	 * Use Getattr instead of GetFlag to handle explicit ignore and explicit not ignore */
+	if (!(Getattr(n, "feature:ignore") || Strncmp(symname, "$ignore", 7) == 0)) {
+	  SWIG_WARN_NODE_BEGIN(n);
+	  if (SwigType_isfunction(Getattr(n, "decl")))
+	    Swig_warning(WARN_CPP14_AUTO, Getfile(n), Getline(n), "Unable to deduce auto return type for '%s' (ignored).\n", Swig_name_decl(n));
+	  else
+	    Swig_warning(WARN_CPP11_AUTO, Getfile(n), Getline(n), "Unable to deduce auto type for variable '%s' (ignored).\n", Swig_name_decl(n));
+	  SWIG_WARN_NODE_END(n);
+	  SetFlag(n, "feature:ignore");
+	}
+      }
     }
     if (only_csymbol || GetFlag(n, "feature:ignore") || Strncmp(symname, "$ignore", 7) == 0) {
       /* Only add to C symbol table and continue */
@@ -579,44 +668,11 @@
       c = Swig_symbol_add(symname,n);
 
       if (c != n) {
-        /* symbol conflict attempting to add in the new symbol */
-        if (Getattr(n,"sym:weak")) {
-          Setattr(n,"sym:name",symname);
-        } else {
-          String *e = NewStringEmpty();
-          String *en = NewStringEmpty();
-          String *ec = NewStringEmpty();
-          int redefined = Swig_need_redefined_warn(n,c,inclass);
-          if (redefined) {
-            Printf(en,"Identifier '%s' redefined (ignored)",symname);
-            Printf(ec,"previous definition of '%s'",symname);
-          } else {
-            Printf(en,"Redundant redeclaration of '%s'",symname);
-            Printf(ec,"previous declaration of '%s'",symname);
-          }
-          if (Cmp(symname,Getattr(n,"name"))) {
-            Printf(en," (Renamed from '%s')", SwigType_namestr(Getattr(n,"name")));
-          }
-          Printf(en,",");
-          if (Cmp(symname,Getattr(c,"name"))) {
-            Printf(ec," (Renamed from '%s')", SwigType_namestr(Getattr(c,"name")));
-          }
-          Printf(ec,".");
-	  SWIG_WARN_NODE_BEGIN(n);
-          if (redefined) {
-            Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en);
-            Swig_warning(WARN_PARSE_REDEFINED,Getfile(c),Getline(c),"%s\n",ec);
-          } else if (!is_friend(n) && !is_friend(c)) {
-            Swig_warning(WARN_PARSE_REDUNDANT,Getfile(n),Getline(n),"%s\n",en);
-            Swig_warning(WARN_PARSE_REDUNDANT,Getfile(c),Getline(c),"%s\n",ec);
-          }
-	  SWIG_WARN_NODE_END(n);
-          Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(n),Getline(n),en,
-                 Getfile(c),Getline(c),ec);
-          Setattr(n,"error",e);
-	  Delete(e);
-          Delete(en);
-          Delete(ec);
+	/* symbol conflict attempting to add in the new symbol */
+	if (Getattr(n,"sym:weak")) {
+	  Setattr(n,"sym:name",symname);
+	} else {
+	  Swig_symbol_conflict_warn(n, c, symname, inclass);
         }
       }
     }
@@ -862,7 +918,7 @@
 
 /* If the class name is qualified.  We need to create or lookup namespace entries */
 
-static Symtab *set_scope_to_global() {
+static Symtab *set_scope_to_global(void) {
   Symtab *symtab = Swig_symbol_global_scope();
   Swig_symbol_setscope(symtab);
   return symtab;
@@ -902,37 +958,45 @@
  * The scopes required for the symbol name are resolved and/or created, if required.
  * For example AA::BB::CC as input returns CC and creates the namespace AA then inner 
  * namespace BB in the current scope. */
-static String *resolve_create_node_scope(String *cname, int is_class_definition) {
+static String *resolve_create_node_scope(String *cname_in, int is_class_definition, int *errored) {
   Symtab *gscope = 0;
   Node *cname_node = 0;
+  String *cname = cname_in;
   String *last = Swig_scopename_last(cname);
   nscope = 0;
   nscope_inner = 0;  
+  *errored = 0;
 
-  if (Strncmp(cname,"::" ,2) != 0) {
+  if (Strncmp(cname, "::", 2) == 0) {
     if (is_class_definition) {
-      /* Only lookup symbols which are in scope via a using declaration but not via a using directive.
-         For example find y via 'using x::y' but not y via a 'using namespace x'. */
-      cname_node = Swig_symbol_clookup_no_inherit(cname, 0);
-      if (!cname_node) {
-	Node *full_lookup_node = Swig_symbol_clookup(cname, 0);
-	if (full_lookup_node) {
-	 /* This finds a symbol brought into scope via both a using directive and a using declaration. */
-	  Node *last_node = Swig_symbol_clookup_no_inherit(last, 0);
-	  if (last_node == full_lookup_node)
-	    cname_node = last_node;
-	}
-      }
-    } else {
-      /* For %template, the template needs to be in scope via any means. */
-      cname_node = Swig_symbol_clookup(cname, 0);
+      Swig_error(cparse_file, cparse_line, "Using the unary scope operator :: in class definition '%s' is invalid.\n", SwigType_namestr(cname));
+      *errored = 1;
+      return last;
     }
+    cname = NewString(Char(cname) + 2);
+  }
+  if (is_class_definition) {
+    /* Only lookup symbols which are in scope via a using declaration but not via a using directive.
+       For example find y via 'using x::y' but not y via a 'using namespace x'. */
+    cname_node = Swig_symbol_clookup_no_inherit(cname, 0);
+    if (!cname_node) {
+      Node *full_lookup_node = Swig_symbol_clookup(cname, 0);
+      if (full_lookup_node) {
+       /* This finds a symbol brought into scope via both a using directive and a using declaration. */
+	Node *last_node = Swig_symbol_clookup_no_inherit(last, 0);
+	if (last_node == full_lookup_node)
+	  cname_node = last_node;
+      }
+    }
+  } else {
+    /* For %template, the template needs to be in scope via any means. */
+    cname_node = Swig_symbol_clookup(cname, 0);
   }
 #if RESOLVE_DEBUG
   if (!cname_node)
-    Printf(stdout, "symbol does not yet exist (%d): [%s]\n", is_class_definition, cname);
+    Printf(stdout, "symbol does not yet exist (%d): [%s]\n", is_class_definition, cname_in);
   else
-    Printf(stdout, "symbol does exist (%d): [%s]\n", is_class_definition, cname);
+    Printf(stdout, "symbol does exist (%d): [%s]\n", is_class_definition, cname_in);
 #endif
 
   if (cname_node) {
@@ -1014,8 +1078,9 @@
 
 	if (fail) {
 	  String *cname_resolved = NewStringf("%s::%s", found_scopename, last);
-	  Swig_error(cparse_file, cparse_line, "'%s' resolves to '%s' and was incorrectly instantiated in scope '%s' instead of within scope '%s'.\n", cname, cname_resolved, current_scopename, found_scopename);
-	  cname = Copy(last);
+	  Swig_error(cparse_file, cparse_line, "'%s' resolves to '%s' and was incorrectly instantiated in scope '%s' instead of within scope '%s'.\n",
+	    SwigType_namestr(cname_in), SwigType_namestr(cname_resolved), SwigType_namestr(current_scopename), SwigType_namestr(found_scopename));
+	  *errored = 1;
 	  Delete(cname_resolved);
 	}
       }
@@ -1024,22 +1089,17 @@
       Delete(found_scopename);
     }
   } else if (!is_class_definition) {
-    /* A template instantiation requires a template to be found in scope... fail here too?
-    Swig_error(cparse_file, cparse_line, "No template found to instantiate '%s' with %%template.\n", cname);
-     */
+    /* A template instantiation requires a template to be found in scope */
+    Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", SwigType_namestr(cname_in));
+    *errored = 1;
   }
 
-  if (Swig_scopename_check(cname)) {
+  if (*errored)
+    return last;
+
+  if (Swig_scopename_check(cname) && !*errored) {
     Node   *ns;
     String *prefix = Swig_scopename_prefix(cname);
-    if (prefix && (Strncmp(prefix,"::",2) == 0)) {
-/* I don't think we can use :: global scope to declare classes and hence neither %template. - consider reporting error instead - wsfulton. */
-      /* Use the global scope */
-      String *nprefix = NewString(Char(prefix)+2);
-      Delete(prefix);
-      prefix= nprefix;
-      gscope = set_scope_to_global();
-    }
     if (Len(prefix) == 0) {
       String *base = Copy(last);
       /* Use the global scope, but we need to add a 'global' namespace.  */
@@ -1056,11 +1116,13 @@
     /* Try to locate the scope */
     ns = Swig_symbol_clookup(prefix,0);
     if (!ns) {
-      Swig_error(cparse_file,cparse_line,"Undefined scope '%s'\n", prefix);
+      Swig_error(cparse_file, cparse_line, "Undefined scope '%s'\n", SwigType_namestr(prefix));
+      *errored = 1;
     } else {
       Symtab *nstab = Getattr(ns,"symtab");
       if (!nstab) {
-	Swig_error(cparse_file,cparse_line, "'%s' is not defined as a valid scope.\n", prefix);
+	Swig_error(cparse_file, cparse_line, "'%s' is not defined as a valid scope.\n", SwigType_namestr(prefix));
+	*errored = 1;
 	ns = 0;
       } else {
 	/* Check if the node scope is the current scope */
@@ -1137,10 +1199,10 @@
 }
  
 /* look for simple typedef name in typedef list */
-static String *try_to_find_a_name_for_unnamed_structure(const char *storage, Node *decls) {
+static String *try_to_find_a_name_for_unnamed_structure(const String *storage, Node *decls) {
   String *name = 0;
   Node *n = decls;
-  if (storage && (strcmp(storage, "typedef") == 0)) {
+  if (storage && Equal(storage, "typedef")) {
     for (; n; n = nextSibling(n)) {
       if (!Len(Getattr(n, "decl"))) {
 	name = Copy(Getattr(n, "name"));
@@ -1170,7 +1232,7 @@
  * Create the nested class/struct/union as a forward declaration.
  * ----------------------------------------------------------------------------- */
 
-static Node *nested_forward_declaration(const char *storage, const char *kind, String *sname, String *name, Node *cpp_opt_declarators) {
+static Node *nested_forward_declaration(const String *storage, const String *kind, String *sname, String *name, Node *cpp_opt_declarators) {
   Node *nn = 0;
 
   if (sname) {
@@ -1187,10 +1249,10 @@
   /* Add any variable instances. Also add in any further typedefs of the nested type.
      Note that anonymous typedefs (eg typedef struct {...} a, b;) are treated as class forward declarations */
   if (cpp_opt_declarators) {
-    int storage_typedef = (storage && (strcmp(storage, "typedef") == 0));
+    int storage_typedef = (storage && Equal(storage, "typedef"));
     int variable_of_anonymous_type = !sname && !storage_typedef;
     if (!variable_of_anonymous_type) {
-      int anonymous_typedef = !sname && (storage && (strcmp(storage, "typedef") == 0));
+      int anonymous_typedef = !sname && storage_typedef;
       Node *n = cpp_opt_declarators;
       SwigType *type = name;
       while (n) {
@@ -1217,7 +1279,7 @@
       Node *n = nn;
       if (!GetFlag(n, "feature:ignore")) {
 	SWIG_WARN_NODE_BEGIN(n);
-	Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line,"Nested %s not currently supported (%s ignored)\n", kind, sname ? sname : name);
+	Swig_warning(WARN_PARSE_NAMED_NESTED_CLASS, cparse_file, cparse_line, "Nested %s not currently supported (%s ignored)\n", kind, SwigType_namestr(sname ? sname : name));
 	SWIG_WARN_NODE_END(n);
       }
     } else {
@@ -1233,7 +1295,7 @@
   scanner_file(f);
   top = 0;
   yyparse();
-  return top;
+  return (Node *)top;
 }
 
 static void single_new_feature(const char *featurename, String *val, Hash *featureattribs, char *declaratorid, SwigType *type, ParmList *declaratorparms, String *qualifier) {
@@ -1428,7 +1490,7 @@
 	  Delete(pl);
         }
 
-        /* copy specific attributes for global (or in a namespace) template functions - these are not templated class methods */
+        /* copy specific attributes for global (or in a namespace) template functions - these are not class template methods */
         if (strcmp(cntype,"template") == 0) {
           Node *templatetype = Getattr(function,"templatetype");
           Node *symtypename = Getattr(function,"sym:typename");
@@ -1546,6 +1608,11 @@
     String *val;
     String *rawval;
     int     type;
+    /* The type code for the argument when the top level operator is unary.
+     * This is useful because our grammar parses cases such as (7)*6 as a
+     * cast applied to an unary operator.
+     */
+    int	    unary_arg_type;
     String *qualifier;
     String *refqualifier;
     String *bitfield;
@@ -1587,20 +1654,23 @@
   Node         *node;
 };
 
+/* Define special token END for end of input. */
+%token END 0
+
 %token <id> ID
 %token <str> HBLOCK
 %token <id> POUND 
 %token <id> STRING WSTRING
 %token <loc> INCLUDE IMPORT INSERT
 %token <str> CHARCONST WCHARCONST
-%token <dtype> NUM_INT NUM_FLOAT NUM_UNSIGNED NUM_LONG NUM_ULONG NUM_LONGLONG NUM_ULONGLONG NUM_BOOL
+%token <dtype> NUM_INT NUM_DOUBLE NUM_FLOAT NUM_LONGDOUBLE NUM_UNSIGNED NUM_LONG NUM_ULONG NUM_LONGLONG NUM_ULONGLONG NUM_BOOL
 %token <intvalue> TYPEDEF
-%token <type> TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_WCHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL TYPE_COMPLEX TYPE_TYPEDEF TYPE_RAW TYPE_NON_ISO_INT8 TYPE_NON_ISO_INT16 TYPE_NON_ISO_INT32 TYPE_NON_ISO_INT64
-%token LPAREN RPAREN COMMA SEMI EXTERN INIT LBRACE RBRACE PERIOD
+%token <type> TYPE_INT TYPE_UNSIGNED TYPE_SHORT TYPE_LONG TYPE_FLOAT TYPE_DOUBLE TYPE_CHAR TYPE_WCHAR TYPE_VOID TYPE_SIGNED TYPE_BOOL TYPE_COMPLEX TYPE_RAW TYPE_NON_ISO_INT8 TYPE_NON_ISO_INT16 TYPE_NON_ISO_INT32 TYPE_NON_ISO_INT64
+%token LPAREN RPAREN COMMA SEMI EXTERN LBRACE RBRACE PERIOD ELLIPSIS
 %token CONST_QUAL VOLATILE REGISTER STRUCT UNION EQUAL SIZEOF MODULE LBRACKET RBRACKET
 %token BEGINFILE ENDOFFILE
 %token ILLEGAL CONSTANT
-%token NAME RENAME NAMEWARN EXTEND PRAGMA FEATURE VARARGS
+%token RENAME NAMEWARN EXTEND PRAGMA FEATURE VARARGS
 %token ENUM
 %token CLASS TYPENAME PRIVATE PUBLIC PROTECTED COLON STATIC VIRTUAL FRIEND THROW CATCH EXPLICIT
 %token STATIC_ASSERT CONSTEXPR THREAD_LOCAL DECLTYPE AUTO NOEXCEPT /* C++11 keywords */
@@ -1608,10 +1678,10 @@
 %token USING
 %token <node> NAMESPACE
 %token NATIVE INLINE
-%token TYPEMAP EXCEPT ECHO APPLY CLEAR SWIGTEMPLATE FRAGMENT
+%token TYPEMAP ECHO APPLY CLEAR SWIGTEMPLATE FRAGMENT
 %token WARN 
 %token LESSTHAN GREATERTHAN DELETE_KW DEFAULT
-%token LESSTHANOREQUALTO GREATERTHANOREQUALTO EQUALTO NOTEQUALTO
+%token LESSTHANOREQUALTO GREATERTHANOREQUALTO EQUALTO NOTEQUALTO LESSEQUALGREATER
 %token ARROW
 %token QUESTIONMARK
 %token TYPES PARMS
@@ -1624,7 +1694,7 @@
 %token <str> DOXYGENSTRING
 %token <str> DOXYGENPOSTSTRING
 
-%left  CAST
+%precedence CAST
 %left  QUESTIONMARK
 %left  LOR
 %left  LAND
@@ -1632,28 +1702,33 @@
 %left  XOR
 %left  AND
 %left  EQUALTO NOTEQUALTO
-%left  GREATERTHAN LESSTHAN GREATERTHANOREQUALTO LESSTHANOREQUALTO
+/* We don't currently allow < and > in any context where the associativity or
+ * precedence matters and Bison warns about that.
+ */
+%left  /* GREATERTHAN LESSTHAN */ GREATERTHANOREQUALTO LESSTHANOREQUALTO
+%left  LESSEQUALGREATER
 %left  LSHIFT RSHIFT
 %left  PLUS MINUS
 %left  STAR SLASH MODULO
-%left  UMINUS NOT LNOT
-%left  DCOLON
+%precedence UMINUS NOT LNOT
+%token DCOLON
 
 %type <node>     program interface declaration swig_directive ;
 
 /* SWIG directives */
 %type <node>     extend_directive apply_directive clear_directive constant_directive ;
-%type <node>     echo_directive except_directive fragment_directive include_directive inline_directive ;
-%type <node>     insert_directive module_directive name_directive native_directive ;
+%type <node>     echo_directive fragment_directive include_directive inline_directive ;
+%type <node>     insert_directive module_directive native_directive ;
 %type <node>     pragma_directive rename_directive feature_directive varargs_directive typemap_directive ;
 %type <node>     types_directive template_directive warn_directive ;
 
 /* C declarations */
-%type <node>     c_declaration c_decl c_decl_tail c_enum_key c_enum_inherit c_enum_decl c_enum_forward_decl c_constructor_decl;
+%type <node>     c_declaration c_decl c_decl_tail c_enum_inherit c_enum_decl c_enum_forward_decl c_constructor_decl;
 %type <node>     enumlist enumlist_item edecl_with_dox edecl;
+%type <id>       c_enum_key;
 
 /* C++ declarations */
-%type <node>     cpp_declaration cpp_class_decl cpp_forward_class_decl cpp_template_decl cpp_alternate_rettype;
+%type <node>     cpp_declaration cpp_class_decl cpp_forward_class_decl cpp_template_decl;
 %type <node>     cpp_members cpp_member cpp_member_no_dox;
 %type <node>     cpp_constructor_decl cpp_destructor_decl cpp_protection_decl cpp_conversion_operator cpp_static_assert;
 %type <node>     cpp_swig_directive cpp_template_possible cpp_opt_declarators ;
@@ -1663,19 +1738,21 @@
 /* Misc */
 %type <id>       identifier;
 %type <dtype>    initializer cpp_const exception_specification cv_ref_qualifier qualifiers_exception_specification;
-%type <id>       storage_class extern_string;
-%type <pl>       parms  ptail rawparms varargs_parms ;
-%type <pl>       templateparameters templateparameterstail;
+%type <str>      storage_class;
+%type <intvalue> storage_class_raw storage_class_list;
+%type <pl>       parms rawparms varargs_parms ;
+%type <pl>       templateparameterstail;
 %type <p>        parm_no_dox parm valparm rawvalparms valparms valptail ;
 %type <p>        typemap_parm tm_list tm_tail ;
 %type <p>        templateparameter ;
-%type <id>       templcpptype cpptype classkey classkeyopt access_specifier;
+%type <type>     templcpptype cpptype classkey classkeyopt;
+%type <id>       access_specifier;
 %type <node>     base_specifier;
-%type <str>      ellipsis variadic;
-%type <type>     type rawtype type_right anon_bitfield_type decltype ;
+%type <str>      variadic_opt;
+%type <type>     type rawtype type_right anon_bitfield_type decltype decltypeexpr cpp_alternate_rettype;
 %type <bases>    base_list inherit raw_inherit;
 %type <dtype>    definetype def_args etype default_delete deleted_definition explicit_default;
-%type <dtype>    expr exprnum exprcompound valexpr exprmem;
+%type <dtype>    expr exprnum exprsimple exprcompound valexpr exprmem callparms callptail;
 %type <id>       ename ;
 %type <id>       less_valparms_greater;
 %type <str>      type_qualifier;
@@ -1692,14 +1769,42 @@
 %type <str>      idcolon idcolontail idcolonnt idcolontailnt idtemplate idtemplatetemplate stringbrace stringbracesemi;
 %type <str>      string stringnum wstring;
 %type <tparms>   template_parms;
-%type <dtype>    cpp_end cpp_vend;
+%type <dtype>    cpp_vend;
 %type <intvalue> rename_namewarn;
 %type <ptype>    type_specifier primitive_type_list ;
 %type <node>     fname stringtype;
 %type <node>     featattr;
-%type <node>     lambda_introducer lambda_body;
+%type <node>     lambda_introducer lambda_body lambda_template;
 %type <pl>       lambda_tail;
 %type <str>      virt_specifier_seq virt_specifier_seq_opt;
+%type <str>      class_virt_specifier_opt;
+
+%{
+
+/* C++ decltype/auto type deduction. */
+static SwigType *deduce_type(const struct Define *dtype) {
+  Node *n;
+  if (!dtype->val) return NULL;
+  n = Swig_symbol_clookup(dtype->val, 0);
+  if (n) {
+    if (Strcmp(nodeType(n),"enumitem") == 0) {
+      /* For an enumitem, the "type" attribute gives us the underlying integer
+       * type - we want the "type" attribute from the enum itself, which is
+       * "parentNode".
+       */
+      n = Getattr(n, "parentNode");
+    }
+    return Getattr(n, "type");
+  } else if (dtype->type != T_AUTO && dtype->type != T_UNKNOWN) {
+    /* Try to deduce the type from the T_* type code. */
+    String *deduced_type = NewSwigType(dtype->type);
+    if (Len(deduced_type) > 0) return deduced_type;
+    Delete(deduced_type);
+  }
+  return NULL;
+}
+
+%}
 
 %%
 
@@ -1722,23 +1827,23 @@
 		   Setattr($1,"module",module_node);
 	           top = $1;
                }
-               | PARSETYPE parm SEMI {
+               | PARSETYPE parm END {
                  top = Copy(Getattr($2,"type"));
 		 Delete($2);
                }
                | PARSETYPE error {
                  top = 0;
                }
-               | PARSEPARM parm SEMI {
+               | PARSEPARM parm END {
                  top = $2;
                }
                | PARSEPARM error {
                  top = 0;
                }
-               | PARSEPARMS LPAREN parms RPAREN SEMI {
+               | PARSEPARMS LPAREN parms RPAREN END {
                  top = $3;
                }
-               | PARSEPARMS error SEMI {
+               | PARSEPARMS error {
                  top = 0;
                }
                ;
@@ -1763,23 +1868,22 @@
                    }
                    $$ = $1;
                }
-               | empty {
+               | %empty {
                    $$ = new_node("top");
                }
                ;
 
-declaration    : swig_directive { $$ = $1; }
-               | c_declaration { $$ = $1; } 
-               | cpp_declaration { $$ = $1; }
+declaration    : swig_directive
+               | c_declaration
+               | cpp_declaration
                | SEMI { $$ = 0; }
                | error {
-                  $$ = 0;
 		  if (cparse_unknown_directive) {
 		      Swig_error(cparse_file, cparse_line, "Unknown directive '%s'.\n", cparse_unknown_directive);
 		  } else {
 		      Swig_error(cparse_file, cparse_line, "Syntax error in input(1).\n");
 		  }
-		  SWIG_exit(EXIT_FAILURE);
+		  Exit(EXIT_FAILURE);
                }
 /* Out of class constructor/destructor declarations */
                | c_constructor_decl { 
@@ -1808,27 +1912,25 @@
  *                           SWIG DIRECTIVES 
  * ====================================================================== */
   
-swig_directive : extend_directive { $$ = $1; }
-               | apply_directive { $$ = $1; }
- 	       | clear_directive { $$ = $1; }
-               | constant_directive { $$ = $1; }
-               | echo_directive { $$ = $1; }
-               | except_directive { $$ = $1; }
-               | fragment_directive { $$ = $1; }
-               | include_directive { $$ = $1; }
-               | inline_directive { $$ = $1; }
-               | insert_directive { $$ = $1; }
-               | module_directive { $$ = $1; }
-               | name_directive { $$ = $1; }
-               | native_directive { $$ = $1; }
-               | pragma_directive { $$ = $1; }
-               | rename_directive { $$ = $1; }
-               | feature_directive { $$ = $1; }
-               | varargs_directive { $$ = $1; }
-               | typemap_directive { $$ = $1; }
-               | types_directive  { $$ = $1; }
-               | template_directive { $$ = $1; }
-               | warn_directive { $$ = $1; }
+swig_directive : extend_directive
+               | apply_directive
+ 	       | clear_directive
+               | constant_directive
+               | echo_directive
+               | fragment_directive
+               | include_directive
+               | inline_directive
+               | insert_directive
+               | module_directive
+               | native_directive
+               | pragma_directive
+               | rename_directive
+               | feature_directive
+               | varargs_directive
+               | typemap_directive
+               | types_directive
+               | template_directive
+               | warn_directive
                ;
 
 /* ------------------------------------------------------------
@@ -1860,7 +1962,7 @@
 		 } else {
 		   /* Previous typedef class definition.  Use its symbol table.
 		      Deprecated, just the real name should be used. 
-		      Note that %extend before the class typedef never worked, only %extend after the class typdef. */
+		      Note that %extend before the class typedef never worked, only %extend after the class typedef. */
 		   prev_symtab = Swig_symbol_setscope(Getattr(cls, "symtab"));
 		   current_class = cls;
 		   SWIG_WARN_NODE_BEGIN(cls);
@@ -1936,80 +2038,70 @@
 /* ------------------------------------------------------------
    %constant name = value;
    %constant type name = value;
+
+   Note: Source/Preprocessor/cpp.c injects `%constant X = Y;` for
+   each `#define X Y` so that's handled here too.
    ------------------------------------------------------------ */
 
 constant_directive :  CONSTANT identifier EQUAL definetype SEMI {
-		   if (($4.type != T_ERROR) && ($4.type != T_SYMBOL)) {
-		     SwigType *type = NewSwigType($4.type);
-		     $$ = new_node("constant");
-		     Setattr($$,"name",$2);
-		     Setattr($$,"type",type);
-		     Setattr($$,"value",$4.val);
-		     if ($4.rawval) Setattr($$,"rawval", $4.rawval);
-		     Setattr($$,"storage","%constant");
-		     SetFlag($$,"feature:immutable");
-		     add_symbols($$);
-		     Delete(type);
-		   } else {
-		     if ($4.type == T_ERROR) {
-		       Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line,"Unsupported constant value (ignored)\n");
-		     }
-		     $$ = 0;
-		   }
-
-	       }
-               | CONSTANT type declarator def_args SEMI {
-		 if (($4.type != T_ERROR) && ($4.type != T_SYMBOL)) {
-		   SwigType_push($2,$3.type);
-		   /* Sneaky callback function trick */
-		   if (SwigType_isfunction($2)) {
-		     SwigType_add_pointer($2);
-		   }
+		 SwigType *type = NewSwigType($4.type);
+		 if (Len(type) > 0) {
 		   $$ = new_node("constant");
-		   Setattr($$,"name",$3.id);
-		   Setattr($$,"type",$2);
-		   Setattr($$,"value",$4.val);
-		   if ($4.rawval) Setattr($$,"rawval", $4.rawval);
-		   Setattr($$,"storage","%constant");
-		   SetFlag($$,"feature:immutable");
+		   Setattr($$, "name", $2);
+		   Setattr($$, "type", type);
+		   Setattr($$, "value", $4.val);
+		   if ($4.rawval) Setattr($$, "rawval", $4.rawval);
+		   Setattr($$, "storage", "%constant");
+		   SetFlag($$, "feature:immutable");
 		   add_symbols($$);
+		   Delete(type);
 		 } else {
-		   if ($4.type == T_ERROR) {
-		     Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line, "Unsupported constant value\n");
-		   }
+		   Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE, cparse_file, cparse_line, "Unsupported constant value (ignored)\n");
 		   $$ = 0;
 		 }
+	       }
+               | CONSTANT type declarator def_args SEMI {
+		 SwigType_push($2, $3.type);
+		 /* Sneaky callback function trick */
+		 if (SwigType_isfunction($2)) {
+		   SwigType_add_pointer($2);
+		 }
+		 $$ = new_node("constant");
+		 Setattr($$, "name", $3.id);
+		 Setattr($$, "type", $2);
+		 Setattr($$, "value", $4.val);
+		 if ($4.rawval) Setattr($$, "rawval", $4.rawval);
+		 Setattr($$, "storage", "%constant");
+		 SetFlag($$, "feature:immutable");
+		 add_symbols($$);
                }
 	       /* Member function pointers with qualifiers. eg.
 	         %constant short (Funcs::*pmf)(bool) const = &Funcs::F; */
 	       | CONSTANT type direct_declarator LPAREN parms RPAREN cv_ref_qualifier def_args SEMI {
-		 if (($8.type != T_ERROR) && ($8.type != T_SYMBOL)) {
-		   SwigType_add_function($2, $5);
-		   SwigType_push($2, $7.qualifier);
-		   SwigType_push($2, $3.type);
-		   /* Sneaky callback function trick */
-		   if (SwigType_isfunction($2)) {
-		     SwigType_add_pointer($2);
-		   }
-		   $$ = new_node("constant");
-		   Setattr($$, "name", $3.id);
-		   Setattr($$, "type", $2);
-		   Setattr($$, "value", $8.val);
-		   if ($8.rawval) Setattr($$, "rawval", $8.rawval);
-		   Setattr($$, "storage", "%constant");
-		   SetFlag($$, "feature:immutable");
-		   add_symbols($$);
-		 } else {
-		   if ($8.type == T_ERROR) {
-		     Swig_warning(WARN_PARSE_UNSUPPORTED_VALUE,cparse_file,cparse_line, "Unsupported constant value\n");
-		   }
-		   $$ = 0;
+		 SwigType_add_function($2, $5);
+		 SwigType_push($2, $7.qualifier);
+		 SwigType_push($2, $3.type);
+		 /* Sneaky callback function trick */
+		 if (SwigType_isfunction($2)) {
+		   SwigType_add_pointer($2);
 		 }
+		 $$ = new_node("constant");
+		 Setattr($$, "name", $3.id);
+		 Setattr($$, "type", $2);
+		 Setattr($$, "value", $8.val);
+		 if ($8.rawval) Setattr($$, "rawval", $8.rawval);
+		 Setattr($$, "storage", "%constant");
+		 SetFlag($$, "feature:immutable");
+		 add_symbols($$);
 	       }
                | CONSTANT error SEMI {
 		 Swig_warning(WARN_PARSE_BAD_VALUE,cparse_file,cparse_line,"Bad constant value (ignored).\n");
 		 $$ = 0;
 	       }
+	       | CONSTANT error END {
+		 Swig_error(cparse_file,cparse_line,"Missing semicolon (';') after %%constant.\n");
+		 Exit(EXIT_FAILURE);
+	       }
                ;
 
 /* ------------------------------------------------------------
@@ -2038,36 +2130,6 @@
                }
                ;
 
-/* ------------------------------------------------------------
-   %except(lang) { ... }
-   %except { ... }
-   %except(lang);   
-   %except;
-   ------------------------------------------------------------ */
-
-except_directive : EXCEPT LPAREN identifier RPAREN LBRACE {
-                    skip_balanced('{','}');
-		    $$ = 0;
-		    Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated.  Use %%exception instead.\n");
-	       }
-
-               | EXCEPT LBRACE {
-                    skip_balanced('{','}');
-		    $$ = 0;
-		    Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated.  Use %%exception instead.\n");
-               }
-
-               | EXCEPT LPAREN identifier RPAREN SEMI {
-		 $$ = 0;
-		 Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated.  Use %%exception instead.\n");
-               }
-
-               | EXCEPT SEMI {
-		 $$ = 0;
-		 Swig_warning(WARN_DEPRECATED_EXCEPT,cparse_file, cparse_line, "%%except is deprecated.  Use %%exception instead.\n");
-	       }
-               ;
-
 /* fragment keyword arguments */
 stringtype    : string LBRACE parm RBRACE {		 
                  $$ = NewHash();
@@ -2080,9 +2142,7 @@
                  $$ = NewHash();
                  Setattr($$,"value",$1);
               }
-              | stringtype {
-                $$ = $1;
-              }
+              | stringtype
               ;
 
 /* ------------------------------------------------------------
@@ -2105,7 +2165,7 @@
                  | FRAGMENT LPAREN fname COMMA kwargs RPAREN LBRACE {
 		   Hash *p = $5;
 		   String *code;
-                   skip_balanced('{','}');
+		   if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
 		   $$ = new_node("fragment");
 		   Setattr($$,"value",Getattr($3,"value"));
 		   Setattr($$,"type",Getattr($3,"type"));
@@ -2130,9 +2190,9 @@
    %importfile(option1="xyz", ...) "filename" [ declarations ]
    ------------------------------------------------------------ */
 
-include_directive: includetype options string BEGINFILE {
-                     $1.filename = Copy(cparse_file);
-		     $1.line = cparse_line;
+include_directive: includetype options string BEGINFILE <loc>{
+		     $$.filename = Copy(cparse_file);
+		     $$.line = cparse_line;
 		     scanner_set_location($3,1);
                      if ($2) { 
 		       String *maininput = Getattr($2, "maininput");
@@ -2142,7 +2202,7 @@
                } interface ENDOFFILE {
                      String *mname = 0;
                      $$ = $6;
-		     scanner_set_location($1.filename,$1.line+1);
+		     scanner_set_location($5.filename, $5.line + 1);
 		     if (strcmp($1.type,"include") == 0) set_nodeType($$,"include");
 		     if (strcmp($1.type,"import") == 0) {
 		       mname = $2 ? Getattr($2,"module") : 0;
@@ -2216,10 +2276,11 @@
                | INLINE LBRACE {
                  String *cpps;
 		 int start_line = cparse_line;
-		 skip_balanced('{','}');
 		 if (Namespaceprefix) {
 		   Swig_error(cparse_file, cparse_start_line, "%%inline directive inside a namespace is disallowed.\n");
-		   
+		 }
+		 if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
+		 if (Namespaceprefix) {
 		   $$ = 0;
 		 } else {
 		   String *code;
@@ -2265,7 +2326,7 @@
                }
                | INSERT LPAREN idstring RPAREN LBRACE {
 		 String *code;
-                 skip_balanced('{','}');
+		 if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
 		 $$ = new_node("insert");
 		 Setattr($$,"section",$3);
 		 Delitem(scanner_ccode,0);
@@ -2320,25 +2381,6 @@
                ;
 
 /* ------------------------------------------------------------
-   %name(newname)    declaration
-   %name("newname")  declaration
-   ------------------------------------------------------------ */
-
-name_directive : NAME LPAREN idstring RPAREN {
-                 Swig_warning(WARN_DEPRECATED_NAME,cparse_file,cparse_line, "%%name is deprecated.  Use %%rename instead.\n");
-		 Delete(yyrename);
-                 yyrename = NewString($3);
-		 $$ = 0;
-               }
-               | NAME LPAREN RPAREN {
-		 Swig_warning(WARN_DEPRECATED_NAME,cparse_file,cparse_line, "%%name is deprecated.  Use %%rename instead.\n");
-		 $$ = 0;
-		 Swig_error(cparse_file,cparse_line,"Missing argument to %%name directive.\n");
-	       }
-               ;
-
-
-/* ------------------------------------------------------------
    %native(scriptname) name;
    %native(scriptname) type name (parms);
    ------------------------------------------------------------ */
@@ -2347,6 +2389,7 @@
                  $$ = new_node("native");
 		 Setattr($$,"name",$3);
 		 Setattr($$,"wrap:name",$6);
+		 Delete($5);
 	         add_symbols($$);
 	       }
                | NATIVE LPAREN identifier RPAREN storage_class type declarator SEMI {
@@ -2364,6 +2407,7 @@
 		     Setattr($$,"parms",$7.parms);
 		     Setattr($$,"decl",$7.type);
 		 }
+		 Delete($5);
 	         add_symbols($$);
 	       }
                ;
@@ -2388,12 +2432,12 @@
 	      }
               ;
 
-pragma_arg    : string { $$ = $1; }
-              | HBLOCK { $$ = $1; }
+pragma_arg    : string
+              | HBLOCK
               ;
 
 pragma_lang   : LPAREN identifier RPAREN { $$ = $2; }
-              | empty { $$ = (char *) "swig"; }
+              | %empty { $$ = "swig"; }
               ;
 
 /* ------------------------------------------------------------
@@ -2585,7 +2629,7 @@
                   }
                   ;
 
-stringbracesemi : stringbrace { $$ = $1; }
+stringbracesemi : stringbrace
                 | SEMI { $$ = 0; }
                 | PARMS LPAREN parms RPAREN SEMI { $$ = $3; } 
                 ;
@@ -2641,7 +2685,7 @@
 		 $$ = 0;
               };
 
-varargs_parms   : parms { $$ = $1; }
+varargs_parms   : parms
                 | NUM_INT COMMA parm { 
 		  int i;
 		  int n;
@@ -2716,26 +2760,23 @@
 /* typemap method type (lang,method) or (method) */
 
 typemap_type   : kwargs {
-		 Hash *p;
-		 String *name;
-		 p = nextSibling($1);
-		 if (p && (!Getattr(p,"value"))) {
- 		   /* this is the deprecated two argument typemap form */
- 		   Swig_warning(WARN_DEPRECATED_TYPEMAP_LANG,cparse_file, cparse_line,
-				"Specifying the language name in %%typemap is deprecated - use #ifdef SWIG<LANG> instead.\n");
-		   /* two argument typemap form */
-		   name = Getattr($1,"name");
-		   if (!name || (Strcmp(name,typemap_lang))) {
-		     $$.method = 0;
-		     $$.kwargs = 0;
-		   } else {
-		     $$.method = Getattr(p,"name");
-		     $$.kwargs = nextSibling(p);
+		 String *name = Getattr($1, "name");
+		 Hash *p = nextSibling($1);
+		 $$.method = name;
+		 $$.kwargs = p;
+		 if (Getattr($1, "value")) {
+		   Swig_error(cparse_file, cparse_line,
+			      "%%typemap method shouldn't have a value specified.\n");
+		 }
+		 while (p) {
+		   if (!Getattr(p, "value")) {
+		     Swig_error(cparse_file, cparse_line,
+				"%%typemap attribute '%s' is missing its value.  If this is specifying the target language, that's no longer supported: use #ifdef SWIG<LANG> instead.\n",
+				Getattr(p, "name"));
+		     /* Set to empty value to avoid segfaults later. */
+		     Setattr(p, "value", NewStringEmpty());
 		   }
-		 } else {
-		   /* one-argument typemap-form */
-		   $$.method = Getattr($1,"name");
-		   $$.kwargs = p;
+		   p = nextSibling(p);
 		 }
                 }
                ;
@@ -2750,7 +2791,7 @@
                  $$ = $2;
 		 set_nextSibling($$,$3);
                 }
-               | empty { $$ = 0;}
+               | %empty { $$ = 0;}
                ;
 
 typemap_parm   : type plain_declarator {
@@ -2795,33 +2836,35 @@
    ------------------------------------------------------------ */
 
 template_directive: SWIGTEMPLATE LPAREN idstringopt RPAREN idcolonnt LESSTHAN valparms GREATERTHAN SEMI {
-                  Parm *p, *tp;
-		  Node *n;
+                  Parm *p;
+		  Node *n = 0;
 		  Node *outer_class = currentOuterClass;
 		  Symtab *tscope = 0;
-		  int     specialized = 0;
-		  int     variadic = 0;
+		  String *symname = $3 ? NewString($3) : 0;
+		  int errored_flag = 0;
+		  String *idcolonnt;
 
 		  $$ = 0;
 
 		  tscope = Swig_symbol_current();          /* Get the current scope */
 
 		  /* If the class name is qualified, we need to create or lookup namespace entries */
-		  $5 = resolve_create_node_scope($5, 0);
+		  idcolonnt = resolve_create_node_scope($5, 0, &errored_flag);
 
-		  if (nscope_inner && Strcmp(nodeType(nscope_inner), "class") == 0) {
-		    outer_class	= nscope_inner;
+		  if (!errored_flag) {
+		    if (nscope_inner && Strcmp(nodeType(nscope_inner), "class") == 0)
+		      outer_class = nscope_inner;
+
+		    /*
+		      We use the new namespace entry 'nscope' only to
+		      emit the template node. The template parameters are
+		      resolved in the current 'tscope'.
+
+		      This is closer to the C++ (typedef) behavior.
+		    */
+		    n = Swig_cparse_template_locate(idcolonnt, $7, symname, tscope);
 		  }
 
-		  /*
-		    We use the new namespace entry 'nscope' only to
-		    emit the template node. The template parameters are
-		    resolved in the current 'tscope'.
-
-		    This is closer to the C++ (typedef) behavior.
-		  */
-		  n = Swig_cparse_template_locate($5,$7,tscope);
-
 		  /* Patch the argument types to respect namespaces */
 		  p = $7;
 		  while (p) {
@@ -2856,83 +2899,17 @@
                     Node *linkliststart = 0;
                     while (nn) {
                       Node *templnode = 0;
-                      if (Strcmp(nodeType(nn),"template") == 0) {
-                        int nnisclass = (Strcmp(Getattr(nn,"templatetype"),"class") == 0); /* if not a templated class it is a templated function */
-                        Parm *tparms = Getattr(nn,"templateparms");
-                        if (!tparms) {
-                          specialized = 1;
-                        } else if (Getattr(tparms,"variadic") && strncmp(Char(Getattr(tparms,"variadic")), "1", 1)==0) {
-                          variadic = 1;
-                        }
-                        if (nnisclass && !variadic && !specialized && (ParmList_len($7) > ParmList_len(tparms))) {
-                          Swig_error(cparse_file, cparse_line, "Too many template parameters. Maximum of %d.\n", ParmList_len(tparms));
-                        } else if (nnisclass && !specialized && ((ParmList_len($7) < (ParmList_numrequired(tparms) - (variadic?1:0))))) { /* Variadic parameter is optional */
-                          Swig_error(cparse_file, cparse_line, "Not enough template parameters specified. %d required.\n", (ParmList_numrequired(tparms)-(variadic?1:0)) );
-                        } else if (!nnisclass && ((ParmList_len($7) != ParmList_len(tparms)))) {
-                          /* must be an overloaded templated method - ignore it as it is overloaded with a different number of template parameters */
-                          nn = Getattr(nn,"sym:nextSibling"); /* repeat for overloaded templated functions */
-                          continue;
-                        } else {
-			  String *tname = Copy($5);
-                          int def_supplied = 0;
-                          /* Expand the template */
-			  Node *templ = Swig_symbol_clookup($5,0);
-			  Parm *targs = templ ? Getattr(templ,"templateparms") : 0;
+                      if (GetFlag(nn, "instantiate")) {
+			Delattr(nn, "instantiate");
+			{
+			  int nnisclass = (Strcmp(Getattr(nn, "templatetype"), "class") == 0); /* if not a class template it is a function template */
+			  Parm *tparms = Getattr(nn, "templateparms");
+			  int specialized = !tparms; /* fully specialized (an explicit specialization) */
+			  String *tname = Copy(idcolonnt);
+			  Node *primary_template = Swig_symbol_clookup(tname, 0);
 
-                          ParmList *temparms;
-                          if (specialized) temparms = CopyParmList($7);
-                          else temparms = CopyParmList(tparms);
-
-                          /* Create typedef's and arguments */
-                          p = $7;
-                          tp = temparms;
-                          if (!p && ParmList_len(p) != ParmList_len(temparms)) {
-                            /* we have no template parameters supplied in %template for a template that has default args*/
-                            p = tp;
-                            def_supplied = 1;
-                          }
-
-                          while (p) {
-                            String *value = Getattr(p,"value");
-                            if (def_supplied) {
-                              Setattr(p,"default","1");
-                            }
-                            if (value) {
-                              Setattr(tp,"value",value);
-                            } else {
-                              SwigType *ty = Getattr(p,"type");
-                              if (ty) {
-                                Setattr(tp,"type",ty);
-                              }
-                              Delattr(tp,"value");
-                            }
-			    /* fix default arg values */
-			    if (targs) {
-			      Parm *pi = temparms;
-			      Parm *ti = targs;
-			      String *tv = Getattr(tp,"value");
-			      if (!tv) tv = Getattr(tp,"type");
-			      while(pi != tp && ti && pi) {
-				String *name = Getattr(ti,"name");
-				String *value = Getattr(pi,"value");
-				if (!value) value = Getattr(pi,"type");
-				Replaceid(tv, name, value);
-				pi = nextSibling(pi);
-				ti = nextSibling(ti);
-			      }
-			    }
-                            p = nextSibling(p);
-                            tp = nextSibling(tp);
-                            if (!p && tp) {
-                              p = tp;
-                              def_supplied = 1;
-                            } else if (p && !tp) { /* Variadic template - tp < p */
-			      SWIG_WARN_NODE_BEGIN(nn);
-                              Swig_warning(WARN_CPP11_VARIADIC_TEMPLATE,cparse_file, cparse_line,"Only the first variadic template argument is currently supported.\n");
-			      SWIG_WARN_NODE_END(nn);
-                              break;
-                            }
-                          }
+			  /* Expand the template */
+			  ParmList *temparms = Swig_cparse_template_parms_expand($7, primary_template, nn);
 
                           templnode = copy_node(nn);
 			  update_nested_classes(templnode); /* update classes nested within template */
@@ -2945,7 +2922,7 @@
                             Setattr(templnode,"sym:typename","1");
                           }
 			  /* for now, nested %template is allowed only in the same scope as the template declaration */
-                          if ($3 && !(nnisclass && ((outer_class && (outer_class != Getattr(nn, "nested:outer")))
+                          if (symname && !(nnisclass && ((outer_class && (outer_class != Getattr(nn, "nested:outer")))
 			    ||(extendmode && current_class && (current_class != Getattr(nn, "nested:outer")))))) {
 			    /*
 			       Comment this out for 1.3.28. We need to
@@ -2953,19 +2930,19 @@
 			       move %ignore from using %rename to use
 			       %feature(ignore).
 
-			       String *symname = Swig_name_make(templnode,0,$3,0,0);
+			       String *symname = Swig_name_make(templnode, 0, symname, 0, 0);
 			    */
-			    String *symname = NewString($3);
-                            Swig_cparse_template_expand(templnode,symname,temparms,tscope);
-                            Setattr(templnode,"sym:name",symname);
+                            Swig_cparse_template_expand(templnode, symname, temparms, tscope);
+                            Setattr(templnode, "sym:name", symname);
                           } else {
                             static int cnt = 0;
                             String *nname = NewStringf("__dummy_%d__", cnt++);
                             Swig_cparse_template_expand(templnode,nname,temparms,tscope);
                             Setattr(templnode,"sym:name",nname);
+                            SetFlag(templnode,"hidden");
 			    Delete(nname);
                             Setattr(templnode,"feature:onlychildren", "typemap,typemapitem,typemapcopy,typedef,types,fragment,apply");
-			    if ($3) {
+			    if (symname) {
 			      Swig_warning(WARN_PARSE_NESTED_TEMPLATE, cparse_file, cparse_line, "Named nested template instantiations not supported. Processing as if no name was given to %%template().\n");
 			    }
                           }
@@ -3055,7 +3032,7 @@
                           }
                         }
 
-                        /* all the overloaded templated functions are added into a linked list */
+                        /* all the overloaded function templates are added into a linked list */
                         if (!linkliststart)
                           linkliststart = templnode;
                         if (nscope_inner) {
@@ -3076,7 +3053,7 @@
                           linklistend = templnode;
                         }
                       }
-                      nn = Getattr(nn,"sym:nextSibling"); /* repeat for overloaded templated functions. If a templated class there will never be a sibling. */
+                      nn = Getattr(nn,"sym:nextSibling"); /* repeat for overloaded function templates. If a class template there will never be a sibling. */
                     }
                     update_defaultargs(linkliststart);
                     update_abstracts(linkliststart);
@@ -3084,6 +3061,7 @@
 	          Swig_symbol_setscope(tscope);
 		  Delete(Namespaceprefix);
 		  Namespaceprefix = Swig_symbol_qualifiedscopename(0);
+		  Delete(symname);
                 }
                ;
 
@@ -3109,8 +3087,8 @@
                       default_arguments($$);
    	            }
                 }
-                | c_enum_decl { $$ = $1; }
-                | c_enum_forward_decl { $$ = $1; }
+                | c_enum_decl
+                | c_enum_forward_decl
 
 /* An extern C type declaration, disable cparse_cplusplus if needed. */
 
@@ -3126,14 +3104,22 @@
 		    Setattr($$,"name",$2);
 		    appendChild($$,n);
 		    while (n) {
-		      SwigType *decl = Getattr(n,"decl");
-		      if (SwigType_isfunction(decl) && !Equal(Getattr(n, "storage"), "typedef")) {
+		      String *s = Getattr(n, "storage");
+		      if (s) {
+			if (Strstr(s, "thread_local")) {
+			  Insert(s,0,"externc ");
+			} else if (!Equal(s, "typedef")) {
+			  Setattr(n,"storage","externc");
+			}
+		      } else {
 			Setattr(n,"storage","externc");
 		      }
 		      n = nextSibling(n);
 		    }
 		  } else {
-		     Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2);
+		    if (!Equal($2,"C++")) {
+		      Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2);
+		    }
 		    $$ = new_node("extern");
 		    Setattr($$,"name",$2);
 		    appendChild($$,firstChild($5));
@@ -3167,9 +3153,7 @@
 		  SetFlag($$,"aliastemplate");
 		  add_symbols($$);
 		}
-                | cpp_static_assert {
-                   $$ = $1;
-                }
+                | cpp_static_assert
                 ;
 
 /* ------------------------------------------------------------
@@ -3195,10 +3179,13 @@
 	      if ($5.val && $5.type) {
 		/* store initializer type as it might be different to the declared type */
 		SwigType *valuetype = NewSwigType($5.type);
-		if (Len(valuetype) > 0)
-		  Setattr($$,"valuetype",valuetype);
-		else
-		  Delete(valuetype);
+		if (Len(valuetype) > 0) {
+		  Setattr($$, "valuetype", valuetype);
+		} else {
+		  /* If we can't determine the initializer type use the declared type. */
+		  Setattr($$, "valuetype", $2);
+		}
+		Delete(valuetype);
 	      }
 	      if (!$6) {
 		if (Len(scanner_ccode)) {
@@ -3222,27 +3209,26 @@
 	      }
 
 	      if ($3.id) {
-		/* Look for "::" declarations (ignored) */
-		if (Strstr($3.id, "::")) {
+		/* Ignore all scoped declarations, could be 1. out of class function definition 2. friend function declaration 3. ... */
+		String *p = Swig_scopename_prefix($3.id);
+		if (p) {
 		  /* This is a special case. If the scope name of the declaration exactly
 		     matches that of the declaration, then we will allow it. Otherwise, delete. */
-		  String *p = Swig_scopename_prefix($3.id);
-		  if (p) {
-		    if ((Namespaceprefix && Strcmp(p, Namespaceprefix) == 0) ||
-			(Classprefix && Strcmp(p, Classprefix) == 0)) {
-		      String *lstr = Swig_scopename_last($3.id);
-		      Setattr($$, "name", lstr);
-		      Delete(lstr);
-		      set_nextSibling($$, $6);
-		    } else {
-		      Delete($$);
-		      $$ = $6;
-		    }
-		    Delete(p);
+		  if ((Namespaceprefix && Strcmp(p, Namespaceprefix) == 0) ||
+		      (Classprefix && Strcmp(p, Classprefix) == 0)) {
+		    String *lstr = Swig_scopename_last($3.id);
+		    Setattr($$, "name", lstr);
+		    Delete(lstr);
+		    set_nextSibling($$, $6);
 		  } else {
 		    Delete($$);
 		    $$ = $6;
 		  }
+		  Delete(p);
+		} else if (Strncmp($3.id, "::", 2) == 0) {
+		  /* global scope declaration/definition ignored */
+		  Delete($$);
+		  $$ = $6;
 		} else {
 		  set_nextSibling($$, $6);
 		}
@@ -3254,6 +3240,51 @@
 	      if ($4.qualifier && $1 && Strstr($1, "static"))
 		Swig_error(cparse_file, cparse_line, "Static function %s cannot have a qualifier.\n", Swig_name_decl($$));
            }
+	   | storage_class type declarator cpp_const EQUAL error SEMI {
+	      String *decl = $3.type;
+	      $$ = new_node("cdecl");
+	      if ($4.qualifier)
+	        decl = add_qualifier_to_declarator($3.type, $4.qualifier);
+	      Setattr($$, "refqualifier", $4.refqualifier);
+	      Setattr($$, "type", $2);
+	      Setattr($$, "storage", $1);
+	      Setattr($$, "name", $3.id);
+	      Setattr($$, "decl", decl);
+	      Setattr($$, "parms", $3.parms);
+
+	      /* Set dummy value to avoid adding in code for handling missing value in later stages */
+	      Setattr($$, "value", "*parse error*");
+	      SetFlag($$, "valueignored");
+
+	      Setattr($$, "throws", $4.throws);
+	      Setattr($$, "throw", $4.throwf);
+	      Setattr($$, "noexcept", $4.nexcept);
+	      Setattr($$, "final", $4.final);
+
+	      if ($3.id) {
+		/* Ignore all scoped declarations, could be 1. out of class function definition 2. friend function declaration 3. ... */
+		String *p = Swig_scopename_prefix($3.id);
+		if (p) {
+		  if ((Namespaceprefix && Strcmp(p, Namespaceprefix) == 0) ||
+		      (Classprefix && Strcmp(p, Classprefix) == 0)) {
+		    String *lstr = Swig_scopename_last($3.id);
+		    Setattr($$, "name", lstr);
+		    Delete(lstr);
+		  } else {
+		    Delete($$);
+		    $$ = 0;
+		  }
+		  Delete(p);
+		} else if (Strncmp($3.id, "::", 2) == 0) {
+		  /* global scope declaration/definition ignored */
+		  Delete($$);
+		  $$ = 0;
+		}
+	      }
+
+	      if ($4.qualifier && $1 && Strstr($1, "static"))
+		Swig_error(cparse_file, cparse_line, "Static function %s cannot have a qualifier.\n", Swig_name_decl($$));
+	   }
            /* Alternate function syntax introduced in C++11:
               auto funcName(int x, int y) -> int; */
            | storage_class AUTO declarator cpp_const ARROW cpp_alternate_rettype virt_specifier_seq_opt initializer c_decl_tail {
@@ -3265,7 +3296,6 @@
 	      Setattr($$,"name",$3.id);
 	      Setattr($$,"decl",$3.type);
 	      Setattr($$,"parms",$3.parms);
-	      Setattr($$,"value",$4.val);
 	      Setattr($$,"throws",$4.throws);
 	      Setattr($$,"throw",$4.throwf);
 	      Setattr($$,"noexcept",$4.nexcept);
@@ -3286,12 +3316,10 @@
 		  Delete(type);
 		}
 	      }
-	      if ($4.bitfield) {
-		Setattr($$,"bitfield", $4.bitfield);
-	      }
 
-	      if (Strstr($3.id,"::")) {
-                String *p = Swig_scopename_prefix($3.id);
+	      if ($3.id) {
+		/* Ignore all scoped declarations, could be 1. out of class function definition 2. friend function declaration 3. ... */
+		String *p = Swig_scopename_prefix($3.id);
 		if (p) {
 		  if ((Namespaceprefix && Strcmp(p, Namespaceprefix) == 0) ||
 		      (Classprefix && Strcmp(p, Classprefix) == 0)) {
@@ -3304,7 +3332,8 @@
 		    $$ = $9;
 		  }
 		  Delete(p);
-		} else {
+		} else if (Strncmp($3.id, "::", 2) == 0) {
+		  /* global scope declaration/definition ignored */
 		  Delete($$);
 		  $$ = $9;
 		}
@@ -3315,7 +3344,67 @@
 	      if ($4.qualifier && $1 && Strstr($1, "static"))
 		Swig_error(cparse_file, cparse_line, "Static function %s cannot have a qualifier.\n", Swig_name_decl($$));
            }
-           ;
+           /* C++14 allows the trailing return type to be omitted.  It's
+            * probably not feasible for SWIG to deduce it but we should
+            * at least support parsing this so that the rest of an API
+            * can be wrapped.  This also means you can provide declaration
+            * with an explicit return type in the interface file for SWIG
+            * to wrap.
+            */
+	   | storage_class AUTO declarator cpp_const LBRACE {
+	      if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
+
+              $$ = new_node("cdecl");
+	      if ($4.qualifier) SwigType_push($3.type, $4.qualifier);
+	      Setattr($$, "refqualifier", $4.refqualifier);
+	      Setattr($$, "type", NewString("auto"));
+	      Setattr($$, "storage", $1);
+	      Setattr($$, "name", $3.id);
+	      Setattr($$, "decl", $3.type);
+	      Setattr($$, "parms", $3.parms);
+	      Setattr($$, "throws", $4.throws);
+	      Setattr($$, "throw", $4.throwf);
+	      Setattr($$, "noexcept", $4.nexcept);
+	      Setattr($$, "final", $4.final);
+
+	      if ($3.id) {
+		/* Ignore all scoped declarations, could be 1. out of class function definition 2. friend function declaration 3. ... */
+		String *p = Swig_scopename_prefix($3.id);
+		if (p) {
+		  if ((Namespaceprefix && Strcmp(p, Namespaceprefix) == 0) ||
+		      (Classprefix && Strcmp(p, Classprefix) == 0)) {
+		    String *lstr = Swig_scopename_last($3.id);
+		    Setattr($$, "name", lstr);
+		    Delete(lstr);
+		  } else {
+		    Delete($$);
+		    $$ = 0;
+		  }
+		  Delete(p);
+		} else if (Strncmp($3.id, "::", 2) == 0) {
+		  /* global scope declaration/definition ignored */
+		  Delete($$);
+		  $$ = 0;
+		}
+	      }
+
+	      if ($4.qualifier && $1 && Strstr($1, "static"))
+		Swig_error(cparse_file, cparse_line, "Static function %s cannot have a qualifier.\n", Swig_name_decl($$));
+	   }
+	   /* C++11 auto variable declaration. */
+	   | storage_class AUTO idcolon EQUAL definetype SEMI {
+	      SwigType *type = deduce_type(&$5);
+	      if (!type)
+		type = NewString("auto");
+	      $$ = new_node("cdecl");
+	      Setattr($$, "type", type);
+	      Setattr($$, "storage", $1);
+	      Setattr($$, "name", $3);
+	      Setattr($$, "decl", NewStringEmpty());
+	      Setattr($$, "value", $5.val);
+	      Setattr($$, "valuetype", type);
+	   }
+	   ;
 
 /* Allow lists of variables and functions to be built up */
 
@@ -3349,34 +3438,33 @@
 		 }
 	       }
                | LBRACE { 
-                   skip_balanced('{','}');
+                   if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
                    $$ = 0;
                }
                | error {
 		   $$ = 0;
 		   if (yychar == RPAREN) {
-		       Swig_error(cparse_file, cparse_line, "Unexpected ')'.\n");
+		       Swig_error(cparse_file, cparse_line, "Unexpected closing parenthesis (')').\n");
 		   } else {
-		       Swig_error(cparse_file, cparse_line, "Syntax error - possibly a missing semicolon.\n");
+		       Swig_error(cparse_file, cparse_line, "Syntax error - possibly a missing semicolon (';').\n");
 		   }
-		   SWIG_exit(EXIT_FAILURE);
+		   Exit(EXIT_FAILURE);
                }
               ;
 
-initializer   : def_args {
-                   $$ = $1;
-              }
+initializer   : def_args
               ;
 
-cpp_alternate_rettype : primitive_type { $$ = $1; }
-              | TYPE_BOOL { $$ = $1; }
-              | TYPE_VOID { $$ = $1; }
-/*
-              | TYPE_TYPEDEF template_decl { $$ = NewStringf("%s%s",$1,$2); }
-*/
-              | TYPE_RAW { $$ = $1; }
+cpp_alternate_rettype : primitive_type
+              | TYPE_BOOL
+              | TYPE_VOID
+              | TYPE_RAW
               | idcolon { $$ = $1; }
-              | decltype { $$ = $1; }
+              | idcolon AND {
+                $$ = $1;
+                SwigType_add_reference($$);
+              }
+              | decltype
               ;
 
 /* ------------------------------------------------------------
@@ -3387,31 +3475,41 @@
    auto myFunc = [](int x, int y) throw() -> int { return x+y; };
    auto six = [](int x, int y) { return x+y; }(4, 2);
    ------------------------------------------------------------ */
-cpp_lambda_decl : storage_class AUTO idcolon EQUAL lambda_introducer LPAREN parms RPAREN cpp_const lambda_body lambda_tail {
+cpp_lambda_decl : storage_class AUTO idcolon EQUAL lambda_introducer lambda_template LPAREN parms RPAREN cpp_const lambda_body lambda_tail {
 		  $$ = new_node("lambda");
 		  Setattr($$,"name",$3);
+		  Delete($1);
 		  add_symbols($$);
 	        }
-                | storage_class AUTO idcolon EQUAL lambda_introducer LPAREN parms RPAREN cpp_const ARROW type lambda_body lambda_tail {
+                | storage_class AUTO idcolon EQUAL lambda_introducer lambda_template LPAREN parms RPAREN cpp_const ARROW type lambda_body lambda_tail {
 		  $$ = new_node("lambda");
 		  Setattr($$,"name",$3);
+		  Delete($1);
 		  add_symbols($$);
 		}
-                | storage_class AUTO idcolon EQUAL lambda_introducer lambda_body lambda_tail {
+                | storage_class AUTO idcolon EQUAL lambda_introducer lambda_template lambda_body lambda_tail {
 		  $$ = new_node("lambda");
 		  Setattr($$,"name",$3);
+		  Delete($1);
 		  add_symbols($$);
 		}
                 ;
 
 lambda_introducer : LBRACKET {
-		  skip_balanced('[',']');
+		  if (skip_balanced('[',']') < 0) Exit(EXIT_FAILURE);
 		  $$ = 0;
 	        }
 		;
 
+lambda_template : LESSTHAN {
+		  if (skip_balanced('<','>') < 0) Exit(EXIT_FAILURE);
+		  $$ = 0;
+		}
+		| %empty { $$ = 0; }
+		;
+
 lambda_body : LBRACE {
-		  skip_balanced('{','}');
+		  if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
 		  $$ = 0;
 		}
 
@@ -3419,7 +3517,7 @@
 		  $$ = 0;
 		}
 		| LPAREN {
-		  skip_balanced('(',')');
+		  if (skip_balanced('(',')') < 0) Exit(EXIT_FAILURE);
 		} SEMI {
 		  $$ = 0;
 		}
@@ -3432,13 +3530,13 @@
    ------------------------------------------------------------ */
 
 c_enum_key : ENUM {
-		   $$ = (char *)"enum";
+		   $$ = "enum";
 	      }
 	      | ENUM CLASS {
-		   $$ = (char *)"enum class";
+		   $$ = "enum class";
 	      }
 	      | ENUM STRUCT {
-		   $$ = (char *)"enum struct";
+		   $$ = "enum struct";
 	      }
 	      ;
 
@@ -3449,7 +3547,7 @@
 c_enum_inherit : COLON type_right {
                    $$ = $2;
               }
-              | empty { $$ = 0; }
+              | %empty { $$ = 0; }
               ;
 /* ------------------------------------------------------------
    enum [class] Name;
@@ -3465,7 +3563,7 @@
 		   if (scopedenum)
 		     SetFlag($$, "scopedenum");
 		   Setattr($$,"name",$3);
-		   Setattr($$,"inherit",$4);
+		   Setattr($$, "enumbase", $4);
 		   Setattr($$,"type",ty);
 		   Setattr($$,"sym:weak", "1");
 		   add_symbols($$);
@@ -3487,7 +3585,7 @@
 		  if (scopedenum)
 		    SetFlag($$, "scopedenum");
 		  Setattr($$,"name",$3);
-		  Setattr($$,"inherit",$4);
+		  Setattr($$, "enumbase", $4);
 		  Setattr($$,"type",ty);
 		  appendChild($$,$6);
 		  add_symbols($$);      /* Add to tag space */
@@ -3518,7 +3616,7 @@
 		 Setattr($$,"enumkey",$2);
 		 if (scopedenum)
 		   SetFlag($$, "scopedenum");
-		 Setattr($$,"inherit",$4);
+		 Setattr($$, "enumbase", $4);
 		 if ($3) {
 		   Setattr($$,"name",$3);
 		   ty = NewStringf("enum %s", $3);
@@ -3646,10 +3744,12 @@
 			Setattr($$,"final",$6.final);
 			err = 0;
 		      }
+		    } else {
+		      Delete($1);
 		    }
 		    if (err) {
 		      Swig_error(cparse_file,cparse_line,"Syntax error in input(2).\n");
-		      SWIG_exit(EXIT_FAILURE);
+		      Exit(EXIT_FAILURE);
 		    }
                 }
                 ;
@@ -3658,72 +3758,75 @@
  *                       C++ Support
  * ====================================================================== */
 
-cpp_declaration : cpp_class_decl {  $$ = $1; }
-                | cpp_forward_class_decl { $$ = $1; }
-                | cpp_template_decl { $$ = $1; }
-                | cpp_using_decl { $$ = $1; }
-                | cpp_namespace_decl { $$ = $1; }
-                | cpp_catch_decl { $$ = 0; }
+cpp_declaration : cpp_class_decl
+                | cpp_forward_class_decl
+                | cpp_template_decl
+                | cpp_using_decl
+                | cpp_namespace_decl
+                | cpp_catch_decl
                 ;
 
 
 /* A simple class/struct/union definition */
-cpp_class_decl  : storage_class cpptype idcolon inherit LBRACE {
+
+/* Note that class_virt_specifier_opt for supporting final classes introduces one shift-reduce conflict
+   with C style variable declarations, such as: struct X final; */
+
+cpp_class_decl: storage_class cpptype idcolon class_virt_specifier_opt inherit LBRACE <node>{
                    String *prefix;
                    List *bases = 0;
 		   Node *scope = 0;
+		   int errored_flag = 0;
 		   String *code;
-		   $<node>$ = new_node("class");
-		   Setline($<node>$,cparse_start_line);
-		   Setattr($<node>$,"kind",$2);
-		   if ($4) {
-		     Setattr($<node>$,"baselist", Getattr($4,"public"));
-		     Setattr($<node>$,"protectedbaselist", Getattr($4,"protected"));
-		     Setattr($<node>$,"privatebaselist", Getattr($4,"private"));
+		   $$ = new_node("class");
+		   Setattr($$,"kind",$2);
+		   if ($5) {
+		     Setattr($$,"baselist", Getattr($5,"public"));
+		     Setattr($$,"protectedbaselist", Getattr($5,"protected"));
+		     Setattr($$,"privatebaselist", Getattr($5,"private"));
 		   }
-		   Setattr($<node>$,"allows_typedef","1");
+		   Setattr($$,"allows_typedef","1");
 
 		   /* preserve the current scope */
-		   Setattr($<node>$,"prev_symtab",Swig_symbol_current());
+		   Setattr($$,"prev_symtab",Swig_symbol_current());
 		  
 		   /* If the class name is qualified.  We need to create or lookup namespace/scope entries */
-		   scope = resolve_create_node_scope($3, 1);
+		   scope = resolve_create_node_scope($3, 1, &errored_flag);
 		   /* save nscope_inner to the class - it may be overwritten in nested classes*/
-		   Setattr($<node>$, "nested:innerscope", nscope_inner);
-		   Setattr($<node>$, "nested:nscope", nscope);
+		   Setattr($$, "nested:innerscope", nscope_inner);
+		   Setattr($$, "nested:nscope", nscope);
 		   Setfile(scope,cparse_file);
 		   Setline(scope,cparse_line);
-		   $3 = scope;
-		   Setattr($<node>$,"name",$3);
+		   Setattr($$, "name", scope);
 
 		   if (currentOuterClass) {
-		     SetFlag($<node>$, "nested");
-		     Setattr($<node>$, "nested:outer", currentOuterClass);
-		     set_access_mode($<node>$);
+		     SetFlag($$, "nested");
+		     Setattr($$, "nested:outer", currentOuterClass);
+		     set_access_mode($$);
 		   }
-		   Swig_features_get(Swig_cparse_features(), Namespaceprefix, Getattr($<node>$, "name"), 0, $<node>$);
+		   Swig_features_get(Swig_cparse_features(), Namespaceprefix, Getattr($$, "name"), 0, $$);
 		   /* save yyrename to the class attribute, to be used later in add_symbols()*/
-		   Setattr($<node>$, "class_rename", make_name($<node>$, $3, 0));
-		   Setattr($<node>$, "Classprefix", $3);
-		   Classprefix = NewString($3);
+		   Setattr($$, "class_rename", make_name($$, scope, 0));
+		   Setattr($$, "Classprefix", scope);
+		   Classprefix = NewString(scope);
 		   /* Deal with inheritance  */
-		   if ($4)
-		     bases = Swig_make_inherit_list($3,Getattr($4,"public"),Namespaceprefix);
-		   prefix = SwigType_istemplate_templateprefix($3);
+		   if ($5)
+		     bases = Swig_make_inherit_list(scope, Getattr($5, "public"), Namespaceprefix);
+		   prefix = SwigType_istemplate_templateprefix(scope);
 		   if (prefix) {
 		     String *fbase, *tbase;
 		     if (Namespaceprefix) {
-		       fbase = NewStringf("%s::%s", Namespaceprefix,$3);
+		       fbase = NewStringf("%s::%s", Namespaceprefix, scope);
 		       tbase = NewStringf("%s::%s", Namespaceprefix, prefix);
 		     } else {
-		       fbase = Copy($3);
+		       fbase = Copy(scope);
 		       tbase = Copy(prefix);
 		     }
 		     Swig_name_inherit(tbase,fbase);
 		     Delete(fbase);
 		     Delete(tbase);
 		   }
-                   if (strcmp($2,"class") == 0) {
+                   if (Strcmp($2, "class") == 0) {
 		     cplus_mode = CPLUS_PRIVATE;
 		   } else {
 		     cplus_mode = CPLUS_PUBLIC;
@@ -3732,7 +3835,7 @@
 		     set_scope_to_global();
 		   }
 		   Swig_symbol_newscope();
-		   Swig_symbol_setscopename($3);
+		   Swig_symbol_setscopename(scope);
 		   Swig_inherit_base_symbols(bases);
 		   Delete(Namespaceprefix);
 		   Namespaceprefix = Swig_symbol_qualifiedscopename(0);
@@ -3754,11 +3857,11 @@
 		   }
 		   Delete(prefix);
 		   inclass = 1;
-		   currentOuterClass = $<node>$;
+		   currentOuterClass = $$;
 		   if (cparse_cplusplusout) {
 		     /* save the structure declaration to declare it in global scope for C++ to see */
 		     code = get_raw_text_balanced('{', '}');
-		     Setattr($<node>$, "code", code);
+		     Setattr($$, "code", code);
 		     Delete(code);
 		   }
                } cpp_members RBRACE cpp_opt_declarators {
@@ -3767,20 +3870,19 @@
 		   Symtab *cscope;
 		   Node *am = 0;
 		   String *scpname = 0;
-		   (void) $<node>6;
 		   $$ = currentOuterClass;
 		   currentOuterClass = Getattr($$, "nested:outer");
-		   nscope_inner = Getattr($<node>$, "nested:innerscope");
-		   nscope = Getattr($<node>$, "nested:nscope");
-		   Delattr($<node>$, "nested:innerscope");
-		   Delattr($<node>$, "nested:nscope");
+		   nscope_inner = Getattr($$, "nested:innerscope");
+		   nscope = Getattr($$, "nested:nscope");
+		   Delattr($$, "nested:innerscope");
+		   Delattr($$, "nested:nscope");
 		   if (nscope_inner && Strcmp(nodeType(nscope_inner), "class") == 0) { /* actual parent class for this class */
-		     Node* forward_declaration = Swig_symbol_clookup_no_inherit(Getattr($<node>$,"name"), Getattr(nscope_inner, "symtab"));
+		     Node* forward_declaration = Swig_symbol_clookup_no_inherit(Getattr($$,"name"), Getattr(nscope_inner, "symtab"));
 		     if (forward_declaration) {
-		       Setattr($<node>$, "access", Getattr(forward_declaration, "access"));
+		       Setattr($$, "access", Getattr(forward_declaration, "access"));
 		     }
-		     Setattr($<node>$, "nested:outer", nscope_inner);
-		     SetFlag($<node>$, "nested");
+		     Setattr($$, "nested:outer", nscope_inner);
+		     SetFlag($$, "nested");
                    }
 		   if (!currentOuterClass)
 		     inclass = 0;
@@ -3788,7 +3890,7 @@
 		   Delattr($$, "prev_symtab");
 		   
 		   /* Check for pure-abstract class */
-		   Setattr($$,"abstracts", pure_abstracts($7));
+		   Setattr($$,"abstracts", pure_abstracts($8));
 		   
 		   /* This bit of code merges in a previously defined %extend directive (if any) */
 		   {
@@ -3804,12 +3906,12 @@
 		   scpname = Swig_symbol_qualifiedscopename(0);
 		   Setattr(classes, scpname, $$);
 
-		   appendChild($$, $7);
+		   appendChild($$, $8);
 		   
 		   if (am) 
 		     Swig_extend_append_previous($$, am);
 
-		   p = $9;
+		   p = $10;
 		   if (p && !nscope_inner) {
 		     if (!cparse_cplusplus && currentOuterClass)
 		       appendChild(currentOuterClass, p);
@@ -3820,21 +3922,20 @@
 		   if (nscope_inner) {
 		     ty = NewString(scpname); /* if the class is declared out of scope, let the declarator use fully qualified type*/
 		   } else if (cparse_cplusplus && !cparse_externc) {
-		     ty = NewString($3);
+		     ty = NewString(Getattr($7, "name"));
 		   } else {
-		     ty = NewStringf("%s %s", $2, $3);
+		     ty = NewStringf("%s %s", $2, Getattr($7, "name"));
 		   }
 		   while (p) {
 		     Setattr(p, "storage", $1);
 		     Setattr(p, "type" ,ty);
 		     if (!cparse_cplusplus && currentOuterClass && (!Getattr(currentOuterClass, "name"))) {
 		       SetFlag(p, "hasconsttype");
-		       SetFlag(p, "feature:immutable");
 		     }
 		     p = nextSibling(p);
 		   }
-		   if ($9 && Cmp($1,"typedef") == 0)
-		     add_typedef_name($$, $9, $3, cscope, scpname);
+		   if ($10 && Cmp($1,"typedef") == 0)
+		     add_typedef_name($$, $10, Getattr($7, "name"), cscope, scpname);
 		   Delete(scpname);
 
 		   if (cplus_mode != CPLUS_PUBLIC) {
@@ -3849,38 +3950,38 @@
 		   if (currentOuterClass)
 		     restore_access_mode($$);
 		   Setattr($$, "symtab", Swig_symbol_popscope());
-		   Classprefix = Getattr($<node>$, "Classprefix");
-		   Delattr($<node>$, "Classprefix");
+		   Classprefix = Getattr($$, "Classprefix");
+		   Delattr($$, "Classprefix");
 		   Delete(Namespaceprefix);
 		   Namespaceprefix = Swig_symbol_qualifiedscopename(0);
 		   if (cplus_mode == CPLUS_PRIVATE) {
 		     $$ = 0; /* skip private nested classes */
 		   } else if (cparse_cplusplus && currentOuterClass && ignore_nested_classes && !GetFlag($$, "feature:flatnested")) {
-		     $$ = nested_forward_declaration($1, $2, $3, Copy($3), $9);
+		     $$ = nested_forward_declaration($1, $2, Getattr($7, "name"), Copy(Getattr($7, "name")), $10);
 		   } else if (nscope_inner) {
 		     /* this is tricky */
 		     /* we add the declaration in the original namespace */
 		     if (Strcmp(nodeType(nscope_inner), "class") == 0 && cparse_cplusplus && ignore_nested_classes && !GetFlag($$, "feature:flatnested"))
-		       $$ = nested_forward_declaration($1, $2, $3, Copy($3), $9);
+		       $$ = nested_forward_declaration($1, $2, Getattr($7, "name"), Copy(Getattr($7, "name")), $10);
 		     appendChild(nscope_inner, $$);
 		     Swig_symbol_setscope(Getattr(nscope_inner, "symtab"));
 		     Delete(Namespaceprefix);
 		     Namespaceprefix = Swig_symbol_qualifiedscopename(0);
-		     yyrename = Copy(Getattr($<node>$, "class_rename"));
+		     yyrename = Copy(Getattr($$, "class_rename"));
 		     add_symbols($$);
 		     Delattr($$, "class_rename");
 		     /* but the variable definition in the current scope */
 		     Swig_symbol_setscope(cscope);
 		     Delete(Namespaceprefix);
 		     Namespaceprefix = Swig_symbol_qualifiedscopename(0);
-		     add_symbols($9);
+		     add_symbols($10);
 		     if (nscope) {
 		       $$ = nscope; /* here we return recreated namespace tower instead of the class itself */
-		       if ($9) {
-			 appendSibling($$, $9);
+		       if ($10) {
+			 appendSibling($$, $10);
 		       }
 		     } else if (!SwigType_istemplate(ty) && template_parameters == 0) { /* for template we need the class itself */
-		       $$ = $9;
+		       $$ = $10;
 		     }
 		   } else {
 		     Delete(yyrename);
@@ -3891,20 +3992,20 @@
 			 outer = Getattr(outer, "nested:outer");
 		       appendSibling(outer, $$);
 		       Swig_symbol_setscope(cscope); /* declaration goes in the parent scope */
-		       add_symbols($9);
+		       add_symbols($10);
 		       set_scope_to_global();
 		       Delete(Namespaceprefix);
 		       Namespaceprefix = Swig_symbol_qualifiedscopename(0);
-		       yyrename = Copy(Getattr($<node>$, "class_rename"));
+		       yyrename = Copy(Getattr($$, "class_rename"));
 		       add_symbols($$);
 		       if (!cparse_cplusplusout)
 			 Delattr($$, "nested:outer");
 		       Delattr($$, "class_rename");
 		       $$ = 0;
 		     } else {
-		       yyrename = Copy(Getattr($<node>$, "class_rename"));
+		       yyrename = Copy(Getattr($$, "class_rename"));
 		       add_symbols($$);
-		       add_symbols($9);
+		       add_symbols($10);
 		       Delattr($$, "class_rename");
 		     }
 		   }
@@ -3917,44 +4018,43 @@
 
 /* An unnamed struct, possibly with a typedef */
 
-             | storage_class cpptype inherit LBRACE {
+             | storage_class cpptype inherit LBRACE <node>{
 	       String *unnamed;
 	       String *code;
 	       unnamed = make_unnamed();
-	       $<node>$ = new_node("class");
-	       Setline($<node>$,cparse_start_line);
-	       Setattr($<node>$,"kind",$2);
+	       $$ = new_node("class");
+	       Setattr($$,"kind",$2);
 	       if ($3) {
-		 Setattr($<node>$,"baselist", Getattr($3,"public"));
-		 Setattr($<node>$,"protectedbaselist", Getattr($3,"protected"));
-		 Setattr($<node>$,"privatebaselist", Getattr($3,"private"));
+		 Setattr($$,"baselist", Getattr($3,"public"));
+		 Setattr($$,"protectedbaselist", Getattr($3,"protected"));
+		 Setattr($$,"privatebaselist", Getattr($3,"private"));
 	       }
-	       Setattr($<node>$,"storage",$1);
-	       Setattr($<node>$,"unnamed",unnamed);
-	       Setattr($<node>$,"allows_typedef","1");
+	       Setattr($$,"storage",$1);
+	       Setattr($$,"unnamed",unnamed);
+	       Setattr($$,"allows_typedef","1");
 	       if (currentOuterClass) {
-		 SetFlag($<node>$, "nested");
-		 Setattr($<node>$, "nested:outer", currentOuterClass);
-		 set_access_mode($<node>$);
+		 SetFlag($$, "nested");
+		 Setattr($$, "nested:outer", currentOuterClass);
+		 set_access_mode($$);
 	       }
-	       Swig_features_get(Swig_cparse_features(), Namespaceprefix, 0, 0, $<node>$);
+	       Swig_features_get(Swig_cparse_features(), Namespaceprefix, 0, 0, $$);
 	       /* save yyrename to the class attribute, to be used later in add_symbols()*/
-	       Setattr($<node>$, "class_rename", make_name($<node>$,0,0));
-	       if (strcmp($2,"class") == 0) {
+	       Setattr($$, "class_rename", make_name($$,0,0));
+	       if (Strcmp($2, "class") == 0) {
 		 cplus_mode = CPLUS_PRIVATE;
 	       } else {
 		 cplus_mode = CPLUS_PUBLIC;
 	       }
 	       Swig_symbol_newscope();
 	       cparse_start_line = cparse_line;
-	       currentOuterClass = $<node>$;
+	       currentOuterClass = $$;
 	       inclass = 1;
 	       Classprefix = 0;
 	       Delete(Namespaceprefix);
 	       Namespaceprefix = Swig_symbol_qualifiedscopename(0);
 	       /* save the structure declaration to make a typedef for it later*/
 	       code = get_raw_text_balanced('{', '}');
-	       Setattr($<node>$, "code", code);
+	       Setattr($$, "code", code);
 	       Delete(code);
 	     } cpp_members RBRACE cpp_opt_declarators {
 	       String *unnamed;
@@ -3962,7 +4062,7 @@
 	       String *name = 0;
 	       Node *n;
 	       Classprefix = 0;
-	       (void)$<node>5;
+	       (void)$5;
 	       $$ = currentOuterClass;
 	       currentOuterClass = Getattr($$, "nested:outer");
 	       if (!currentOuterClass)
@@ -4006,7 +4106,6 @@
 		     Setattr(n, "type", ty);
 		     if (!cparse_cplusplus && currentOuterClass && (!Getattr(currentOuterClass, "name"))) {
 		       SetFlag(n,"hasconsttype");
-		       SetFlag(n,"feature:immutable");
 		     }
 		     n = nextSibling(n);
 		   }
@@ -4043,7 +4142,7 @@
 		 Setattr($$,"symtab",Swig_symbol_popscope());
 		 if (name) {
 		   Delete(yyrename);
-		   yyrename = Copy(Getattr($<node>$, "class_rename"));
+		   yyrename = Copy(Getattr($$, "class_rename"));
 		   Delete(Namespaceprefix);
 		   Namespaceprefix = Swig_symbol_qualifiedscopename(0);
 		   add_symbols($$);
@@ -4078,7 +4177,7 @@
    ------------------------------------------------------------ */
 
 cpp_forward_class_decl : storage_class cpptype idcolon SEMI {
-              if ($1 && (Strcmp($1,"friend") == 0)) {
+	      if ($1 && Strstr($1, "friend")) {
 		/* Ignore */
                 $$ = 0; 
 	      } else {
@@ -4088,6 +4187,7 @@
 		Setattr($$,"sym:weak", "1");
 		add_symbols($$);
 	      }
+	      Delete($1);
              }
              ;
 
@@ -4119,10 +4219,11 @@
 			  Swig_symbol_setscope(sti);
 			  Delete(Namespaceprefix);
 			  Namespaceprefix = Swig_symbol_qualifiedscopename(0);
-			  $6 = ni;
+			  $$ = ni;
+			} else {
+			  $$ = $6;
 			}
 
-			$$ = $6;
 			if ($$) tname = Getattr($$,"name");
 			
 			/* Check if the class is a template specialization */
@@ -4145,120 +4246,42 @@
 			  Setattr($$,"templatetype",nodeType($$));
 			  set_nodeType($$,"template");
 			  /* Template partial specialization */
-			  if (tempn && ($3) && ($6)) {
-			    List   *tlist;
-			    String *targs = SwigType_templateargs(tname);
-			    tlist = SwigType_parmlist(targs);
-			    /*			  Printf(stdout,"targs = '%s' %s\n", targs, tlist); */
+			  if (tempn && ($3) && ($$)) {
+			    ParmList *primary_templateparms = Getattr(tempn, "templateparms");
+			    String *targs = SwigType_templateargs(tname); /* tname contains name and specialized template parameters, for example: X<(p.T,TT)> */
+			    List *tlist = SwigType_parmlist(targs);
+			    int specialization_parms_len = Len(tlist);
 			    if (!Getattr($$,"sym:weak")) {
 			      Setattr($$,"sym:typename","1");
 			    }
+			    Setattr($$, "primarytemplate", tempn);
+			    Setattr($$, "templateparms", $3);
+			    Delattr($$, "specialization");
+			    Setattr($$, "partialspecialization", "1");
 			    
-			    if (Len(tlist) != ParmList_len(Getattr(tempn,"templateparms"))) {
-			      Swig_error(Getfile($$),Getline($$),"Inconsistent argument count in template partial specialization. %d %d\n", Len(tlist), ParmList_len(Getattr(tempn,"templateparms")));
+			    if (specialization_parms_len > ParmList_len(primary_templateparms)) {
+			      Swig_error(Getfile($$), Getline($$), "Template partial specialization has more arguments than primary template %d %d.\n", specialization_parms_len, ParmList_len(primary_templateparms));
 			      
+			    } else if (specialization_parms_len < ParmList_numrequired(primary_templateparms)) {
+			      Swig_error(Getfile($$), Getline($$), "Template partial specialization has fewer arguments than primary template %d %d.\n", specialization_parms_len, ParmList_len(primary_templateparms));
 			    } else {
-
-			    /* This code builds the argument list for the partial template
-			       specialization.  This is a little hairy, but the idea is as
-			       follows:
-
-			       $3 contains a list of arguments supplied for the template.
-			       For example template<class T>.
-
-			       tlist is a list of the specialization arguments--which may be
-			       different.  For example class<int,T>.
-
-			       tp is a copy of the arguments in the original template definition.
-       
-			       The patching algorithm walks through the list of supplied
-			       arguments ($3), finds the position in the specialization arguments
-			       (tlist), and then patches the name in the argument list of the
-			       original template.
-			    */
-
-			    {
-			      String *pn;
-			      Parm *p, *p1;
-			      int i, nargs;
-			      Parm *tp = CopyParmList(Getattr(tempn,"templateparms"));
-			      nargs = Len(tlist);
-			      p = $3;
-			      while (p) {
-				for (i = 0; i < nargs; i++){
-				  pn = Getattr(p,"name");
-				  if (Strcmp(pn,SwigType_base(Getitem(tlist,i))) == 0) {
-				    int j;
-				    Parm *p1 = tp;
-				    for (j = 0; j < i; j++) {
-				      p1 = nextSibling(p1);
-				    }
-				    Setattr(p1,"name",pn);
-				    Setattr(p1,"partialarg","1");
-				  }
-				}
-				p = nextSibling(p);
-			      }
-			      p1 = tp;
-			      i = 0;
-			      while (p1) {
-				if (!Getattr(p1,"partialarg")) {
-				  Delattr(p1,"name");
-				  Setattr(p1,"type", Getitem(tlist,i));
-				} 
-				i++;
-				p1 = nextSibling(p1);
-			      }
-			      Setattr($$,"templateparms",tp);
-			      Delete(tp);
-			    }
-  #if 0
-			    /* Patch the parameter list */
-			    if (tempn) {
-			      Parm *p,*p1;
-			      ParmList *tp = CopyParmList(Getattr(tempn,"templateparms"));
-			      p = $3;
-			      p1 = tp;
-			      while (p && p1) {
-				String *pn = Getattr(p,"name");
-				Printf(stdout,"pn = '%s'\n", pn);
-				if (pn) Setattr(p1,"name",pn);
-				else Delattr(p1,"name");
-				pn = Getattr(p,"type");
-				if (pn) Setattr(p1,"type",pn);
-				p = nextSibling(p);
-				p1 = nextSibling(p1);
-			      }
-			      Setattr($$,"templateparms",tp);
-			      Delete(tp);
-			    } else {
-			      Setattr($$,"templateparms",$3);
-			    }
-  #endif
-			    Delattr($$,"specialization");
-			    Setattr($$,"partialspecialization","1");
-			    /* Create a specialized name for matching */
-			    {
+			      /* Create a specialized name with template parameters replaced with $ variables, such as, X<(T1,p.T2) => X<($1,p.$2)> */
 			      Parm *p = $3;
-			      String *fname = NewString(Getattr($$,"name"));
+			      String *fname = NewString(tname);
 			      String *ffname = 0;
 			      ParmList *partialparms = 0;
 
 			      char   tmp[32];
-			      int    i, ilen;
+			      int i = 0;
 			      while (p) {
-				String *n = Getattr(p,"name");
-				if (!n) {
+				String *name = Getattr(p,"name");
+				++i;
+				if (!name) {
 				  p = nextSibling(p);
 				  continue;
 				}
-				ilen = Len(tlist);
-				for (i = 0; i < ilen; i++) {
-				  if (Strstr(Getitem(tlist,i),n)) {
-				    sprintf(tmp,"$%d",i+1);
-				    Replaceid(fname,n,tmp);
-				  }
-				}
+				sprintf(tmp, "$%d", i);
+				Replaceid(fname, name, tmp);
 				p = nextSibling(p);
 			      }
 			      /* Patch argument names with typedef */
@@ -4289,6 +4312,27 @@
 				Append(ffname,")>");
 			      }
 			      {
+				/* Replace each primary template parameter's name and value with $ variables, such as, class Y,class T=Y => class $1,class $2=$1 */
+				ParmList *primary_templateparms_copy = CopyParmList(primary_templateparms);
+				p = primary_templateparms_copy;
+				i = 0;
+				while (p) {
+				  String *name = Getattr(p, "name");
+				  Parm *pp = nextSibling(p);
+				  ++i;
+				  sprintf(tmp, "$%d", i);
+				  while (pp) {
+				    Replaceid(Getattr(pp, "value"), name, tmp);
+				    pp = nextSibling(pp);
+				  }
+				  Setattr(p, "name", NewString(tmp));
+				  p = nextSibling(p);
+				}
+				/* Modify partialparms by adding in missing default values ($ variables) from primary template parameters */
+				partialparms = Swig_cparse_template_partialargs_expand(partialparms, tempn, primary_templateparms_copy);
+				Delete(primary_templateparms_copy);
+			      }
+			      {
 				Node *new_partial = NewHash();
 				String *partials = Getattr(tempn,"partials");
 				if (!partials) {
@@ -4304,7 +4348,6 @@
 			      Setattr($$,"partialargs",ffname);
 			      Swig_symbol_cadd(ffname,$$);
 			    }
-			    }
 			    Delete(tlist);
 			    Delete(targs);
 			  } else {
@@ -4316,8 +4359,8 @@
 			    Delete(ty);
 			    Delete(fname);
 			  }
-			}  else if ($$) {
-			  Setattr($$,"templatetype",nodeType($6));
+			} else if ($$) {
+			  Setattr($$, "templatetype", nodeType($$));
 			  set_nodeType($$,"template");
 			  Setattr($$,"templateparms", $3);
 			  if (!Getattr($$,"sym:weak")) {
@@ -4355,87 +4398,90 @@
 			parsing_template_declaration = 0;
                 }
 
-		/* Explicit template instantiation */
+		/* Class template explicit instantiation definition */
                 | TEMPLATE cpptype idcolon {
 		  Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n");
                   $$ = 0; 
 		}
 
-		/* Explicit template instantiation without the translation unit */
+		/* Function template explicit instantiation definition */
+		| TEMPLATE cpp_alternate_rettype idcolon LPAREN parms RPAREN {
+			Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n");
+                  $$ = 0; 
+		}
+
+		/* Class template explicit instantiation declaration (extern template) */
 		| EXTERN TEMPLATE cpptype idcolon {
-		  Swig_warning(WARN_PARSE_EXPLICIT_TEMPLATE, cparse_file, cparse_line, "Explicit template instantiation ignored.\n");
+		  Swig_warning(WARN_PARSE_EXTERN_TEMPLATE, cparse_file, cparse_line, "Extern template ignored.\n");
                   $$ = 0; 
                 }
-                ;
 
-cpp_template_possible:  c_decl {
-		  $$ = $1;
-                }
-                | cpp_class_decl {
-                   $$ = $1;
-                }
-                | cpp_constructor_decl {
-                   $$ = $1;
-                }
+		/* Function template explicit instantiation declaration (extern template) */
+		| EXTERN TEMPLATE cpp_alternate_rettype idcolon LPAREN parms RPAREN {
+			Swig_warning(WARN_PARSE_EXTERN_TEMPLATE, cparse_file, cparse_line, "Extern template ignored.\n");
+                  $$ = 0; 
+		}
+		;
+
+cpp_template_possible:  c_decl
+                | cpp_class_decl
+                | cpp_constructor_decl
                 | cpp_template_decl {
 		  $$ = 0;
                 }
-                | cpp_forward_class_decl {
-                  $$ = $1;
-                }
-                | cpp_conversion_operator {
-                  $$ = $1;
-                }
+                | cpp_forward_class_decl
+                | cpp_conversion_operator
                 ;
 
-template_parms  : templateparameters {
-		   /* Rip out the parameter names */
-		  Parm *p = $1;
-		  $$ = $1;
-
-		  while (p) {
-		    String *name = Getattr(p,"name");
-		    if (!name) {
-		      /* Hmmm. Maybe it's a 'class T' parameter */
-		      char *type = Char(Getattr(p,"type"));
-		      /* Template template parameter */
-		      if (strncmp(type,"template<class> ",16) == 0) {
-			type += 16;
-		      }
-		      if ((strncmp(type,"class ",6) == 0) || (strncmp(type,"typename ", 9) == 0)) {
-			char *t = strchr(type,' ');
-			Setattr(p,"name", t+1);
-		      } else 
-                      /* Variadic template args */
-		      if ((strncmp(type,"class... ",9) == 0) || (strncmp(type,"typename... ", 12) == 0)) {
-			char *t = strchr(type,' ');
-			Setattr(p,"name", t+1);
-			Setattr(p,"variadic", "1");
-		      } else {
-			/*
-			 Swig_error(cparse_file, cparse_line, "Missing template parameter name\n");
-			 $$.rparms = 0;
-			 $$.parms = 0;
-			 break; */
-		      }
-		    }
-		    p = nextSibling(p);
-		  }
-                 }
-                 ;
-
-templateparameters : templateparameter templateparameterstail {
+template_parms : templateparameter templateparameterstail {
                       set_nextSibling($1,$2);
                       $$ = $1;
                    }
-                   | empty { $$ = 0; }
+                   | %empty { $$ = 0; }
                    ;
 
-templateparameter : templcpptype {
-		    $$ = NewParmWithoutFileLineInfo(NewString($1), 0);
-                  }
-                  | parm {
-                    $$ = $1;
+templateparameter : templcpptype def_args {
+		    $$ = NewParmWithoutFileLineInfo($1, 0);
+		    Setfile($$, cparse_file);
+		    Setline($$, cparse_line);
+		    Setattr($$, "value", $2.rawval ? $2.rawval : $2.val);
+		  }
+		  | TEMPLATE LESSTHAN template_parms GREATERTHAN cpptype idcolon def_args {
+		    $$ = NewParmWithoutFileLineInfo(NewStringf("template< %s > %s %s", ParmList_str_defaultargs($3), $5, $6), $6);
+		    Setfile($$, cparse_file);
+		    Setline($$, cparse_line);
+		    if ($7.val) {
+		      Setattr($$, "value", $7.val);
+		    }
+		  }
+		  | TEMPLATE LESSTHAN template_parms GREATERTHAN cpptype def_args {
+		    $$ = NewParmWithoutFileLineInfo(NewStringf("template< %s > %s", ParmList_str_defaultargs($3), $5), 0);
+		    Setfile($$, cparse_file);
+		    Setline($$, cparse_line);
+		    if ($6.val) {
+		      Setattr($$, "value", $6.val);
+		    }
+		  }
+		  | parm {
+		    Parm *p = $1;
+		    String *name = Getattr(p, "name");
+		    $$ = $1;
+
+		    /* Correct the 'type name' parameter string, split into the appropriate "name" and "type" attributes */
+		    if (!name) {
+		      String *type = Getattr(p, "type");
+		      if ((Strncmp(type, "class ", 6) == 0) || (Strncmp(type, "typename ", 9) == 0)) {
+			/* A 'class T' parameter */
+			const char *t = Strchr(type, ' ');
+			Setattr(p, "name", t + 1);
+			Setattr(p, "type", NewStringWithSize(type, (int)(t - Char(type))));
+		      } else if ((Strncmp(type, "v.class ", 8) == 0) || (Strncmp(type, "v.typename ", 11) == 0)) {
+			/* Variadic template args */
+			const char *t = Strchr(type, ' ');
+			Setattr(p, "name", t + 1);
+			Setattr(p, "type", NewStringWithSize(type, (int)(t - Char(type))));
+		      }
+		    }
                   }
                   ;
 
@@ -4443,13 +4489,14 @@
                          set_nextSibling($2,$3);
                          $$ = $2;
                        }
-                       | empty { $$ = 0; }
+                       | %empty { $$ = 0; }
                        ;
 
 /* Namespace support */
 
 cpp_using_decl : USING idcolon SEMI {
                   String *uname = Swig_symbol_type_qualify($2,0);
+                  /* Possible TODO: In testcase using_member_multiple_inherit class Susing3, uname is "Susing1::usingmethod" instead of "Susing2::usingmethod" */
 		  String *name = Swig_scopename_last($2);
                   $$ = new_node("using");
 		  Setattr($$,"uname",uname);
@@ -4458,10 +4505,20 @@
 		  Delete(name);
 		  add_symbols($$);
              }
+	     | USING TYPENAME idcolon SEMI {
+		  String *uname = Swig_symbol_type_qualify($3,0);
+		  String *name = Swig_scopename_last($3);
+		  $$ = new_node("using");
+		  Setattr($$,"uname",uname);
+		  Setattr($$,"name", name);
+		  Delete(uname);
+		  Delete(name);
+		  add_symbols($$);
+	     }
              | USING NAMESPACE idcolon SEMI {
 	       Node *n = Swig_symbol_clookup($3,0);
 	       if (!n) {
-		 Swig_error(cparse_file, cparse_line, "Nothing known about namespace '%s'\n", $3);
+		 Swig_error(cparse_file, cparse_line, "Nothing known about namespace '%s'\n", SwigType_namestr($3));
 		 $$ = 0;
 	       } else {
 
@@ -4479,7 +4536,7 @@
 		       Swig_symbol_inherit(symtab);
 		     }
 		   } else {
-		     Swig_error(cparse_file, cparse_line, "'%s' is not a namespace.\n", $3);
+		     Swig_error(cparse_file, cparse_line, "'%s' is not a namespace.\n", SwigType_namestr($3));
 		     $$ = 0;
 		   }
 		 } else {
@@ -4489,7 +4546,7 @@
              }
              ;
 
-cpp_namespace_decl : NAMESPACE idcolon LBRACE { 
+cpp_namespace_decl : NAMESPACE idcolon LBRACE <node>{
                 Hash *h;
 		Node *parent_ns = 0;
 		List *scopes = Swig_scopename_tolist($2);
@@ -4499,13 +4556,13 @@
 /*
 Printf(stdout, "==== Namespace %s creation...\n", $2);
 */
-		$<node>$ = 0;
+		$$ = 0;
 		for (i = 0; i < ilen; i++) {
 		  Node *ns = new_node("namespace");
 		  Symtab *current_symtab = Swig_symbol_current();
 		  String *scopename = Getitem(scopes, i);
 		  Setattr(ns, "name", scopename);
-		  $<node>$ = ns;
+		  $$ = ns;
 		  if (parent_ns)
 		    appendChild(parent_ns, ns);
 		  parent_ns = ns;
@@ -4533,7 +4590,7 @@
 		}
 		Delete(scopes);
              } interface RBRACE {
-		Node *n = $<node>4;
+		Node *n = $4;
 		Node *top_ns = 0;
 		do {
 		  Setattr(n, "symtab", Swig_symbol_popscope());
@@ -4543,13 +4600,13 @@
 		  top_ns = n;
 		  n = parentNode(n);
 		} while(n);
-		appendChild($<node>4, firstChild($5));
+		appendChild($4, firstChild($5));
 		Delete($5);
 		$$ = top_ns;
              } 
-             | NAMESPACE LBRACE {
+             | NAMESPACE LBRACE <node>{
 	       Hash *h;
-	       $1 = Swig_symbol_current();
+	       $$ = Swig_symbol_current();
 	       h = Swig_symbol_clookup("    ",0);
 	       if (h && (Strcmp(nodeType(h),"namespace") == 0)) {
 		 Swig_symbol_setscope(Getattr(h,"symtab"));
@@ -4564,7 +4621,7 @@
 	       set_nodeType($$,"namespace");
 	       Setattr($$,"unnamed","1");
 	       Setattr($$,"symtab", Swig_symbol_popscope());
-	       Swig_symbol_setscope($1);
+	       Swig_symbol_setscope($3);
 	       Delete(Namespaceprefix);
 	       Namespaceprefix = Swig_symbol_qualifiedscopename(0);
 	       add_symbols($$);
@@ -4577,11 +4634,11 @@
 	       Setattr($$,"alias",$4);
 	       n = Swig_symbol_clookup($4,0);
 	       if (!n) {
-		 Swig_error(cparse_file, cparse_line, "Unknown namespace '%s'\n", $4);
+		 Swig_error(cparse_file, cparse_line, "Unknown namespace '%s'\n", SwigType_namestr($4));
 		 $$ = 0;
 	       } else {
 		 if (Strcmp(nodeType(n),"namespace") != 0) {
-		   Swig_error(cparse_file, cparse_line, "'%s' is not a namespace\n",$4);
+		   Swig_error(cparse_file, cparse_line, "'%s' is not a namespace\n", SwigType_namestr($4));
 		   $$ = 0;
 		 } else {
 		   while (Getattr(n,"alias")) {
@@ -4612,7 +4669,8 @@
 		   } else {
 		     $$ = $2;
 		   }
-             }
+	     }
+	     | cpp_member DOXYGENSTRING /* Misplaced doxygen string after a member, quietly ignore, like Doxygen does */
              | EXTEND LBRACE { 
 	       extendmode = 1;
 	       if (cplus_mode != CPLUS_PUBLIC) {
@@ -4626,16 +4684,12 @@
 	       appendChild($$,$4);
 	       set_nextSibling($$,$7);
 	     }
-             | include_directive { $$ = $1; }
-             | empty { $$ = 0;}
+             | include_directive
+             | %empty { $$ = 0;}
 	     | error {
-	       int start_line = cparse_line;
-	       skip_decl();
-	       Swig_error(cparse_file,start_line,"Syntax error in input(3).\n");
-	       SWIG_exit(EXIT_FAILURE);
-	       } cpp_members { 
-		 $$ = $3;
-   	     }
+	       Swig_error(cparse_file,cparse_line,"Syntax error in input(3).\n");
+	       Exit(EXIT_FAILURE);
+	     }
              ;
 
 /* ======================================================================
@@ -4644,7 +4698,7 @@
 
 /* A class member.  May be data or a function. Static or virtual as well */
 
-cpp_member_no_dox : c_declaration { $$ = $1; }
+cpp_member_no_dox : c_declaration
              | cpp_constructor_decl { 
                  $$ = $1; 
 		 if (extendmode && current_class) {
@@ -4662,26 +4716,24 @@
 		 add_symbols($$);
                  default_arguments($$);
              }
-             | cpp_destructor_decl { $$ = $1; }
-             | cpp_protection_decl { $$ = $1; }
-             | cpp_swig_directive { $$ = $1; }
-             | cpp_conversion_operator { $$ = $1; }
-             | cpp_forward_class_decl { $$ = $1; }
-	     | cpp_class_decl { $$ = $1; }
-             | storage_class idcolon SEMI { $$ = 0; }
-             | cpp_using_decl { $$ = $1; }
-             | cpp_template_decl { $$ = $1; }
-             | cpp_catch_decl { $$ = 0; }
-             | template_directive { $$ = $1; }
-             | warn_directive { $$ = $1; }
+             | cpp_destructor_decl
+             | cpp_protection_decl
+             | cpp_swig_directive
+             | cpp_conversion_operator
+             | cpp_forward_class_decl
+	     | cpp_class_decl
+             | storage_class idcolon SEMI { $$ = 0; Delete($1); }
+             | cpp_using_decl
+             | cpp_template_decl
+             | cpp_catch_decl
+             | template_directive
+             | warn_directive
              | anonymous_bitfield { $$ = 0; }
-             | fragment_directive {$$ = $1; }
-             | types_directive {$$ = $1; }
+             | fragment_directive
+             | types_directive
              | SEMI { $$ = 0; }
 
-cpp_member   : cpp_member_no_dox {
-		$$ = $1;
-	     }
+cpp_member   : cpp_member_no_dox
              | DOXYGENSTRING cpp_member_no_dox {
 	         $$ = $2;
 		 set_comment($2, $1);
@@ -4699,11 +4751,15 @@
 */
   
 cpp_constructor_decl : storage_class type LPAREN parms RPAREN ctor_end {
-              if (inclass || extendmode) {
+	      /* Cannot be a constructor declaration/definition if parsed as a friend destructor/constructor
+	         or a badly declared friend function without return type */
+	      int isfriend = Strstr($1, "friend") != NULL;
+	      if (!isfriend && (inclass || extendmode)) {
+	        String *name = SwigType_templateprefix($2); /* A constructor can optionally be declared with template parameters before C++20, strip these off */
 		SwigType *decl = NewStringEmpty();
 		$$ = new_node("constructor");
 		Setattr($$,"storage",$1);
-		Setattr($$,"name",$2);
+		Setattr($$, "name", name);
 		Setattr($$,"parms",$4);
 		SwigType_add_function(decl,$4);
 		Setattr($$,"decl",decl);
@@ -4721,71 +4777,49 @@
 		  Setattr($$,"value",$6.defarg);
 	      } else {
 		$$ = 0;
+		Delete($1);
               }
               }
               ;
 
-/* A destructor (hopefully) */
+/* A destructor */
 
-cpp_destructor_decl : NOT idtemplate LPAREN parms RPAREN cpp_end {
-               String *name = NewStringf("%s",$2);
-	       if (*(Char(name)) != '~') Insert(name,0,"~");
-               $$ = new_node("destructor");
-	       Setattr($$,"name",name);
+cpp_destructor_decl : storage_class NOT idtemplate LPAREN parms RPAREN cpp_vend {
+	       String *name = SwigType_templateprefix($3); /* A destructor can optionally be declared with template parameters before C++20, strip these off */
+	       Insert(name, 0, "~");
+	       $$ = new_node("destructor");
+	       Setattr($$, "storage", $1);
+	       Setattr($$, "name", name);
 	       Delete(name);
 	       if (Len(scanner_ccode)) {
 		 String *code = Copy(scanner_ccode);
-		 Setattr($$,"code",code);
+		 Setattr($$, "code", code);
 		 Delete(code);
 	       }
 	       {
 		 String *decl = NewStringEmpty();
-		 SwigType_add_function(decl,$4);
-		 Setattr($$,"decl",decl);
+		 SwigType_add_function(decl, $5);
+		 Setattr($$, "decl", decl);
 		 Delete(decl);
 	       }
-	       Setattr($$,"throws",$6.throws);
-	       Setattr($$,"throw",$6.throwf);
-	       Setattr($$,"noexcept",$6.nexcept);
-	       Setattr($$,"final",$6.final);
-	       if ($6.val)
-	         Setattr($$,"value",$6.val);
-	       if ($6.qualifier)
-		 Swig_error(cparse_file, cparse_line, "Destructor %s %s cannot have a qualifier.\n", Swig_name_decl($$), SwigType_str($6.qualifier, 0));
+	       Setattr($$, "throws", $7.throws);
+	       Setattr($$, "throw", $7.throwf);
+	       Setattr($$, "noexcept", $7.nexcept);
+	       Setattr($$, "final", $7.final);
+	       if ($7.val) {
+		 if (Equal($7.val, "0")) {
+		   if (!Strstr($1, "virtual"))
+		     Swig_error(cparse_file, cparse_line, "Destructor %s uses a pure specifier but is not virtual.\n", Swig_name_decl($$));
+		 } else if (!(Equal($7.val, "delete") || Equal($7.val, "default"))) {
+		   Swig_error(cparse_file, cparse_line, "Destructor %s has an invalid pure specifier, only = 0 is allowed.\n", Swig_name_decl($$));
+		 }
+		 Setattr($$, "value", $7.val);
+	       }
+	       /* TODO: check all storage decl-specifiers are valid */
+	       if ($7.qualifier)
+		 Swig_error(cparse_file, cparse_line, "Destructor %s %s cannot have a qualifier.\n", Swig_name_decl($$), SwigType_str($7.qualifier, 0));
 	       add_symbols($$);
 	      }
-
-/* A virtual destructor */
-
-              | VIRTUAL NOT idtemplate LPAREN parms RPAREN cpp_vend {
-		String *name;
-		$$ = new_node("destructor");
-		Setattr($$,"storage","virtual");
-	        name = NewStringf("%s",$3);
-		if (*(Char(name)) != '~') Insert(name,0,"~");
-		Setattr($$,"name",name);
-		Delete(name);
-		Setattr($$,"throws",$7.throws);
-		Setattr($$,"throw",$7.throwf);
-		Setattr($$,"noexcept",$7.nexcept);
-		Setattr($$,"final",$7.final);
-		if ($7.val)
-		  Setattr($$,"value",$7.val);
-		if (Len(scanner_ccode)) {
-		  String *code = Copy(scanner_ccode);
-		  Setattr($$,"code",code);
-		  Delete(code);
-		}
-		{
-		  String *decl = NewStringEmpty();
-		  SwigType_add_function(decl,$5);
-		  Setattr($$,"decl",decl);
-		  Delete(decl);
-		}
-		if ($7.qualifier)
-		  Swig_error(cparse_file, cparse_line, "Destructor %s %s cannot have a qualifier.\n", Swig_name_decl($$), SwigType_str($7.qualifier, 0));
-		add_symbols($$);
-	      }
               ;
 
 
@@ -4800,6 +4834,9 @@
 		 if ($8.qualifier) {
 		   SwigType_push($4,$8.qualifier);
 		 }
+		 if ($8.val) {
+		   Setattr($$,"value",$8.val);
+		 }
 		 Setattr($$,"refqualifier",$8.refqualifier);
 		 Setattr($$,"decl",$4);
 		 Setattr($$,"parms",$6);
@@ -4818,6 +4855,9 @@
 		 if ($8.qualifier) {
 		   SwigType_push(decl,$8.qualifier);
 		 }
+		 if ($8.val) {
+		   Setattr($$,"value",$8.val);
+		 }
 		 Setattr($$,"refqualifier",$8.refqualifier);
 		 Setattr($$,"decl",decl);
 		 Setattr($$,"parms",$6);
@@ -4836,6 +4876,9 @@
 		 if ($8.qualifier) {
 		   SwigType_push(decl,$8.qualifier);
 		 }
+		 if ($8.val) {
+		   Setattr($$,"value",$8.val);
+		 }
 		 Setattr($$,"refqualifier",$8.refqualifier);
 		 Setattr($$,"decl",decl);
 		 Setattr($$,"parms",$6);
@@ -4856,6 +4899,9 @@
 		 if ($9.qualifier) {
 		   SwigType_push(decl,$9.qualifier);
 		 }
+		 if ($9.val) {
+		   Setattr($$,"value",$9.val);
+		 }
 		 Setattr($$,"refqualifier",$9.refqualifier);
 		 Setattr($$,"decl",decl);
 		 Setattr($$,"parms",$7);
@@ -4873,7 +4919,10 @@
 		if ($7.qualifier) {
 		  SwigType_push(t,$7.qualifier);
 		}
-		 Setattr($$,"refqualifier",$7.refqualifier);
+		if ($7.val) {
+		  Setattr($$,"value",$7.val);
+		}
+		Setattr($$,"refqualifier",$7.refqualifier);
 		Setattr($$,"decl",t);
 		Setattr($$,"parms",$5);
 		Setattr($$,"conversion_operator","1");
@@ -4884,7 +4933,7 @@
 /* isolated catch clause. */
 
 cpp_catch_decl : CATCH LPAREN parms RPAREN LBRACE {
-                 skip_balanced('{','}');
+                 if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
                  $$ = 0;
                }
                ;
@@ -4892,7 +4941,7 @@
 /* static_assert(bool, const char*); (C++11)
  * static_assert(bool); (C++17) */
 cpp_static_assert : STATIC_ASSERT LPAREN {
-                skip_balanced('(',')');
+                if (skip_balanced('(',')') < 0) Exit(EXIT_FAILURE);
                 $$ = 0;
               }
               ;
@@ -4921,61 +4970,21 @@
               ;
 /* These directives can be included inside a class definition */
 
-cpp_swig_directive: pragma_directive { $$ = $1; }
+cpp_swig_directive: pragma_directive
 
 /* A constant (includes #defines) inside a class */
-             | constant_directive { $$ = $1; }
+             | constant_directive
 
-/* This is the new style rename */
-
-             | name_directive { $$ = $1; }
-
-/* rename directive */
-             | rename_directive { $$ = $1; }
-             | feature_directive { $$ = $1; }
-             | varargs_directive { $$ = $1; }
-             | insert_directive { $$ = $1; }
-             | typemap_directive { $$ = $1; }
-             | apply_directive { $$ = $1; }
-             | clear_directive { $$ = $1; }
-             | echo_directive { $$ = $1; }
+             | rename_directive
+             | feature_directive
+             | varargs_directive
+             | insert_directive
+             | typemap_directive
+             | apply_directive
+             | clear_directive
+             | echo_directive
              ;
 
-cpp_end        : cpp_const SEMI {
-	            Clear(scanner_ccode);
-		    $$.val = 0;
-		    $$.qualifier = $1.qualifier;
-		    $$.refqualifier = $1.refqualifier;
-		    $$.bitfield = 0;
-		    $$.throws = $1.throws;
-		    $$.throwf = $1.throwf;
-		    $$.nexcept = $1.nexcept;
-		    $$.final = $1.final;
-               }
-               | cpp_const EQUAL default_delete SEMI {
-	            Clear(scanner_ccode);
-		    $$.val = $3.val;
-		    $$.qualifier = $1.qualifier;
-		    $$.refqualifier = $1.refqualifier;
-		    $$.bitfield = 0;
-		    $$.throws = $1.throws;
-		    $$.throwf = $1.throwf;
-		    $$.nexcept = $1.nexcept;
-		    $$.final = $1.final;
-               }
-               | cpp_const LBRACE { 
-		    skip_balanced('{','}'); 
-		    $$.val = 0;
-		    $$.qualifier = $1.qualifier;
-		    $$.refqualifier = $1.refqualifier;
-		    $$.bitfield = 0;
-		    $$.throws = $1.throws;
-		    $$.throwf = $1.throwf;
-		    $$.nexcept = $1.nexcept;
-		    $$.final = $1.final;
-	       }
-               ;
-
 cpp_vend       : cpp_const SEMI { 
                      Clear(scanner_ccode);
                      $$.val = 0;
@@ -4999,7 +5008,7 @@
                      $$.final = $1.final;
                }
                | cpp_const LBRACE { 
-                     skip_balanced('{','}');
+                     if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
                      $$.val = 0;
                      $$.qualifier = $1.qualifier;
                      $$.refqualifier = $1.refqualifier;
@@ -5012,61 +5021,94 @@
                ;
 
 
-anonymous_bitfield :  storage_class anon_bitfield_type COLON expr SEMI { };
+anonymous_bitfield :  storage_class anon_bitfield_type COLON expr SEMI { Delete($1); };
 
 /* Equals type_right without the ENUM keyword and cpptype (templates etc.): */
-anon_bitfield_type : primitive_type { $$ = $1;
-                  /* Printf(stdout,"primitive = '%s'\n", $$);*/
-                }
-               | TYPE_BOOL { $$ = $1; }
-               | TYPE_VOID { $$ = $1; }
-/*
-               | TYPE_TYPEDEF template_decl { $$ = NewStringf("%s%s",$1,$2); }
-*/
-               | TYPE_RAW { $$ = $1; }
+anon_bitfield_type : primitive_type
+               | TYPE_BOOL
+               | TYPE_VOID
+               | TYPE_RAW
 
-               | idcolon {
-		  $$ = $1;
-               }
+               | idcolon { $$ = $1; }
                ;
 
 /* ====================================================================== 
  *                       PRIMITIVES
  * ====================================================================== */
-extern_string :  EXTERN string {
-                   if (Strcmp($2,"C") == 0) {
-		     $$ = "externc";
-                   } else if (Strcmp($2,"C++") == 0) {
-		     $$ = "extern";
+storage_class  : storage_class_list {
+		 String *r = NewStringEmpty();
+
+		 /* Check for invalid combinations. */
+		 if (multiple_bits_set($1 & (SWIG_STORAGE_CLASS_EXTERN |
+					     SWIG_STORAGE_CLASS_STATIC))) {
+		   Swig_error(cparse_file, cparse_line, "Storage class can't be both 'static' and 'extern'");
+		 }
+		 if (multiple_bits_set($1 & (SWIG_STORAGE_CLASS_EXTERNC |
+					     SWIG_STORAGE_CLASS_EXTERN |
+					     SWIG_STORAGE_CLASS_EXTERNCPP))) {
+		   Swig_error(cparse_file, cparse_line, "Declaration can only be one of 'extern', 'extern \"C\"' and 'extern \"C++\"'");
+		 }
+
+		 if ($1 & SWIG_STORAGE_CLASS_TYPEDEF) {
+		   Append(r, "typedef ");
+		 } else {
+		   if ($1 & SWIG_STORAGE_CLASS_EXTERNC)
+		     Append(r, "externc ");
+		   if ($1 & (SWIG_STORAGE_CLASS_EXTERN|SWIG_STORAGE_CLASS_EXTERNCPP))
+		     Append(r, "extern ");
+		   if ($1 & SWIG_STORAGE_CLASS_STATIC)
+		     Append(r, "static ");
+		 }
+		 if ($1 & SWIG_STORAGE_CLASS_VIRTUAL)
+		   Append(r, "virtual ");
+		 if ($1 & SWIG_STORAGE_CLASS_FRIEND)
+		   Append(r, "friend ");
+		 if ($1 & SWIG_STORAGE_CLASS_EXPLICIT)
+		   Append(r, "explicit ");
+		 if ($1 & SWIG_STORAGE_CLASS_CONSTEXPR)
+		   Append(r, "constexpr ");
+		 if ($1 & SWIG_STORAGE_CLASS_THREAD_LOCAL)
+		   Append(r, "thread_local ");
+		 if (Len(r) == 0) {
+		   Delete(r);
+		   $$ = 0;
+		 } else {
+		   Chop(r);
+		   $$ = r;
+		 }
+	       }
+	       | %empty { $$ = 0; }
+	       ;
+
+storage_class_list: storage_class_raw
+	       | storage_class_list storage_class_raw {
+		  if ($1 & $2) {
+		    Swig_error(cparse_file, cparse_line, "Repeated storage class or type specifier '%s'\n", storage_class_string($2));
+		  }
+		  $$ = $1 | $2;
+	       }
+	       ;
+
+storage_class_raw  : EXTERN { $$ = SWIG_STORAGE_CLASS_EXTERN; }
+	       | EXTERN string {
+		   if (Strcmp($2,"C") == 0) {
+		     $$ = SWIG_STORAGE_CLASS_EXTERNC;
+		   } else if (Strcmp($2,"C++") == 0) {
+		     $$ = SWIG_STORAGE_CLASS_EXTERNCPP;
 		   } else {
 		     Swig_warning(WARN_PARSE_UNDEFINED_EXTERN,cparse_file, cparse_line,"Unrecognized extern type \"%s\".\n", $2);
 		     $$ = 0;
 		   }
-               }
+	       }
+	       | STATIC { $$ = SWIG_STORAGE_CLASS_STATIC; }
+	       | TYPEDEF { $$ = SWIG_STORAGE_CLASS_TYPEDEF; }
+	       | VIRTUAL { $$ = SWIG_STORAGE_CLASS_VIRTUAL; }
+	       | FRIEND { $$ = SWIG_STORAGE_CLASS_FRIEND; }
+	       | EXPLICIT { $$ = SWIG_STORAGE_CLASS_EXPLICIT; }
+	       | CONSTEXPR { $$ = SWIG_STORAGE_CLASS_CONSTEXPR; }
+	       | THREAD_LOCAL { $$ = SWIG_STORAGE_CLASS_THREAD_LOCAL; }
 	       ;
 
-storage_class  : EXTERN { $$ = "extern"; }
-	       | extern_string { $$ = $1; }
-	       | extern_string THREAD_LOCAL { $$ = "thread_local"; }
-	       | extern_string TYPEDEF { $$ = "typedef"; }
-               | STATIC { $$ = "static"; }
-               | TYPEDEF { $$ = "typedef"; }
-               | VIRTUAL { $$ = "virtual"; }
-               | FRIEND { $$ = "friend"; }
-               | EXPLICIT { $$ = "explicit"; }
-               | CONSTEXPR { $$ = "constexpr"; }
-               | EXPLICIT CONSTEXPR { $$ = "explicit constexpr"; }
-               | CONSTEXPR EXPLICIT { $$ = "explicit constexpr"; }
-               | STATIC CONSTEXPR { $$ = "static constexpr"; }
-               | CONSTEXPR STATIC { $$ = "static constexpr"; }
-               | THREAD_LOCAL { $$ = "thread_local"; }
-               | THREAD_LOCAL STATIC { $$ = "static thread_local"; }
-               | STATIC THREAD_LOCAL { $$ = "static thread_local"; }
-               | EXTERN THREAD_LOCAL { $$ = "extern thread_local"; }
-               | THREAD_LOCAL EXTERN { $$ = "extern thread_local"; }
-               | empty { $$ = 0; }
-               ;
-
 /* ------------------------------------------------------------------------------
    Function parameter lists
    ------------------------------------------------------------------------------ */
@@ -5082,73 +5124,64 @@
                }
     	       ;
 
-rawparms          : parm ptail {
-                  set_nextSibling($1,$2);
-                  $$ = $1;
+/* rawparms constructs parameter lists and deal with quirks of doxygen post strings (after the parameter's comma */
+rawparms	: parm { $$ = $1; }
+		| parm DOXYGENPOSTSTRING {
+		  set_comment($1, $2);
+		  $$ = $1;
 		}
-               | empty {
+		| parm DOXYGENSTRING {
+		  /* Misplaced doxygen string, attach it to previous parameter, like Doxygen does */
+		  set_comment($1, $2);
+		  $$ = $1;
+		}
+		| parm COMMA parms {
+		  if ($3) {
+		    set_nextSibling($1, $3);
+		  }
+		  $$ = $1;
+		}
+		| parm DOXYGENPOSTSTRING COMMA parms {
+		  if ($4) {
+		    set_nextSibling($1, $4);
+		  }
+		  set_comment($1, $2);
+		  $$ = $1;
+		}
+		| parm COMMA DOXYGENPOSTSTRING parms {
+		  if ($4) {
+		    set_nextSibling($1, $4);
+		  }
+		  set_comment($1, $3);
+		  $$ = $1;
+		}
+		| %empty {
 		  $$ = 0;
-		  previousNode = currentNode;
-		  currentNode=0;
-	       }
-               ;
-
-ptail          : COMMA parm ptail {
-                 set_nextSibling($2,$3);
-		 $$ = $2;
-                }
-	       | COMMA DOXYGENPOSTSTRING parm ptail {
-		 set_comment(previousNode, $2);
-                 set_nextSibling($3, $4);
-		 $$ = $3;
-               }
-               | empty { $$ = 0; }
-               ;
-
+		}
+		;
 
 parm_no_dox	: rawtype parameter_declarator {
                    SwigType_push($1,$2.type);
 		   $$ = NewParmWithoutFileLineInfo($1,$2.id);
-		   previousNode = currentNode;
-		   currentNode = $$;
 		   Setfile($$,cparse_file);
 		   Setline($$,cparse_line);
 		   if ($2.defarg) {
 		     Setattr($$,"value",$2.defarg);
 		   }
 		}
-
-                | TEMPLATE LESSTHAN cpptype GREATERTHAN cpptype idcolon def_args {
-                  $$ = NewParmWithoutFileLineInfo(NewStringf("template<class> %s %s", $5,$6), 0);
-		  previousNode = currentNode;
-		  currentNode = $$;
-		  Setfile($$,cparse_file);
-		  Setline($$,cparse_line);
-                  if ($7.val) {
-                    Setattr($$,"value",$7.val);
-                  }
-                }
-                | PERIOD PERIOD PERIOD {
+                | ELLIPSIS {
 		  SwigType *t = NewString("v(...)");
 		  $$ = NewParmWithoutFileLineInfo(t, 0);
-		  previousNode = currentNode;
-		  currentNode = $$;
 		  Setfile($$,cparse_file);
 		  Setline($$,cparse_line);
 		}
 		;
 
-parm		: parm_no_dox {
-		  $$ = $1;
-		}
+parm		: parm_no_dox
 		| DOXYGENSTRING parm_no_dox {
 		  $$ = $2;
 		  set_comment($2, $1);
 		}
-		| parm_no_dox DOXYGENPOSTSTRING {
-		  $$ = $1;
-		  set_comment($1, $2);
-		}
 		;
 
 valparms        : rawvalparms {
@@ -5168,14 +5201,14 @@
                   set_nextSibling($1,$2);
                   $$ = $1;
 		}
-               | empty { $$ = 0; }
+               | %empty { $$ = 0; }
                ;
 
 valptail       : COMMA valparm valptail {
                  set_nextSibling($2,$3);
 		 $$ = $2;
                 }
-               | empty { $$ = 0; }
+               | %empty { $$ = 0; }
                ;
 
 
@@ -5215,40 +5248,33 @@
                }
                ;
 
+callparms      : valexpr callptail {
+		 $$ = $1;
+		 Printf($$.val, "%s", $2.val);
+	       }
+	       | %empty { $$.val = NewStringEmpty(); }
+	       ;
+
+callptail      : COMMA valexpr callptail {
+		 $$.val = NewStringf(",%s%s", $2.val, $3.val);
+		 $$.type = 0;
+	       }
+	       | %empty { $$.val = NewStringEmpty(); }
+	       ;
+
 def_args       : EQUAL definetype { 
-                  $$ = $2; 
-		  if ($2.type == T_ERROR) {
-		    Swig_warning(WARN_PARSE_BAD_DEFAULT,cparse_file, cparse_line, "Can't set default argument (ignored)\n");
-		    $$.val = 0;
-		    $$.rawval = 0;
-		    $$.bitfield = 0;
-		    $$.throws = 0;
-		    $$.throwf = 0;
-		    $$.nexcept = 0;
-		    $$.final = 0;
-		  }
+                 $$ = $2;
                }
                | EQUAL definetype LBRACKET expr RBRACKET { 
-		  $$ = $2;
-		  if ($2.type == T_ERROR) {
-		    Swig_warning(WARN_PARSE_BAD_DEFAULT,cparse_file, cparse_line, "Can't set default argument (ignored)\n");
-		    $$ = $2;
-		    $$.val = 0;
-		    $$.rawval = 0;
-		    $$.bitfield = 0;
-		    $$.throws = 0;
-		    $$.throwf = 0;
-		    $$.nexcept = 0;
-		    $$.final = 0;
-		  } else {
-		    $$.val = NewStringf("%s[%s]",$2.val,$4.val); 
-		  }		  
+		 $$ = $2;
+		 $$.val = NewStringf("%s[%s]", $2.val, $4.val);
                }
                | EQUAL LBRACE {
-		 skip_balanced('{','}');
+		 if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
 		 $$.val = NewString(scanner_ccode);
 		 $$.rawval = 0;
-                 $$.type = T_INT;
+		 $$.type = T_UNKNOWN;
+		 $$.unary_arg_type = 0;
 		 $$.bitfield = 0;
 		 $$.throws = 0;
 		 $$.throwf = 0;
@@ -5265,10 +5291,11 @@
 		 $$.nexcept = 0;
 		 $$.final = 0;
 	       }
-               | empty {
+               | %empty {
                  $$.val = 0;
                  $$.rawval = 0;
-                 $$.type = T_INT;
+                 $$.type = T_UNKNOWN;
+		 $$.unary_arg_type = 0;
 		 $$.bitfield = 0;
 		 $$.throws = 0;
 		 $$.throwf = 0;
@@ -5369,7 +5396,7 @@
 		$$.type = t;
 	      }
 	    }
-            | empty {
+            | %empty {
    	      $$.type = 0;
               $$.id = 0;
 	      $$.parms = 0;
@@ -5473,71 +5500,74 @@
            
            /* Variadic versions eg. MyClasses&... myIds */
            
-           |  pointer PERIOD PERIOD PERIOD notso_direct_declarator {
-              $$ = $5;
+           |  pointer ELLIPSIS notso_direct_declarator {
+              $$ = $3;
 	      if ($$.type) {
 		SwigType_push($1,$$.type);
 		Delete($$.type);
 	      }
 	      $$.type = $1;
+	      SwigType_add_variadic($$.type);
            }
-           | pointer AND PERIOD PERIOD PERIOD notso_direct_declarator {
-              $$ = $6;
+           | pointer AND ELLIPSIS notso_direct_declarator {
+              $$ = $4;
 	      SwigType_add_reference($1);
               if ($$.type) {
 		SwigType_push($1,$$.type);
 		Delete($$.type);
 	      }
 	      $$.type = $1;
+	      SwigType_add_variadic($$.type);
            }
-           | pointer LAND PERIOD PERIOD PERIOD notso_direct_declarator {
-              $$ = $6;
+           | pointer LAND ELLIPSIS notso_direct_declarator {
+              $$ = $4;
 	      SwigType_add_rvalue_reference($1);
               if ($$.type) {
 		SwigType_push($1,$$.type);
 		Delete($$.type);
 	      }
 	      $$.type = $1;
+	      SwigType_add_variadic($$.type);
            }
-           | PERIOD PERIOD PERIOD direct_declarator {
-              $$ = $4;
-	      if (!$$.type) $$.type = NewStringEmpty();
-           }
-           | AND PERIOD PERIOD PERIOD notso_direct_declarator {
-	     $$ = $5;
+           | AND ELLIPSIS notso_direct_declarator {
+	     $$ = $3;
 	     $$.type = NewStringEmpty();
 	     SwigType_add_reference($$.type);
-	     if ($5.type) {
-	       SwigType_push($$.type,$5.type);
-	       Delete($5.type);
+	     SwigType_add_variadic($$.type);
+	     if ($3.type) {
+	       SwigType_push($$.type,$3.type);
+	       Delete($3.type);
 	     }
            }
-           | LAND PERIOD PERIOD PERIOD notso_direct_declarator {
+           | LAND ELLIPSIS notso_direct_declarator {
 	     /* Introduced in C++11, move operator && */
              /* Adds one S/R conflict */
-	     $$ = $5;
+	     $$ = $3;
 	     $$.type = NewStringEmpty();
 	     SwigType_add_rvalue_reference($$.type);
-	     if ($5.type) {
-	       SwigType_push($$.type,$5.type);
-	       Delete($5.type);
+	     SwigType_add_variadic($$.type);
+	     if ($3.type) {
+	       SwigType_push($$.type,$3.type);
+	       Delete($3.type);
 	     }
            }
-           | idcolon DSTAR PERIOD PERIOD PERIOD notso_direct_declarator { 
+           | idcolon DSTAR ELLIPSIS notso_direct_declarator {
 	     SwigType *t = NewStringEmpty();
 
-	     $$ = $6;
+	     $$ = $4;
 	     SwigType_add_memberpointer(t,$1);
+	     SwigType_add_variadic(t);
 	     if ($$.type) {
 	       SwigType_push(t,$$.type);
 	       Delete($$.type);
 	     }
 	     $$.type = t;
 	     } 
-           | pointer idcolon DSTAR PERIOD PERIOD PERIOD notso_direct_declarator { 
+           | pointer idcolon DSTAR ELLIPSIS notso_direct_declarator {
 	     SwigType *t = NewStringEmpty();
-	     $$ = $7;
+	     $$ = $5;
 	     SwigType_add_memberpointer(t,$2);
+	     SwigType_add_variadic(t);
 	     SwigType_push($1,t);
 	     if ($$.type) {
 	       SwigType_push($1,$$.type);
@@ -5546,42 +5576,46 @@
 	     $$.type = $1;
 	     Delete(t);
 	   }
-           | pointer idcolon DSTAR AND PERIOD PERIOD PERIOD notso_direct_declarator { 
-	     $$ = $8;
+           | pointer idcolon DSTAR AND ELLIPSIS notso_direct_declarator {
+	     $$ = $6;
 	     SwigType_add_memberpointer($1,$2);
 	     SwigType_add_reference($1);
+	     SwigType_add_variadic($1);
 	     if ($$.type) {
 	       SwigType_push($1,$$.type);
 	       Delete($$.type);
 	     }
 	     $$.type = $1;
 	   }
-           | pointer idcolon DSTAR LAND PERIOD PERIOD PERIOD notso_direct_declarator { 
-	     $$ = $8;
+           | pointer idcolon DSTAR LAND ELLIPSIS notso_direct_declarator {
+	     $$ = $6;
 	     SwigType_add_memberpointer($1,$2);
 	     SwigType_add_rvalue_reference($1);
+	     SwigType_add_variadic($1);
 	     if ($$.type) {
 	       SwigType_push($1,$$.type);
 	       Delete($$.type);
 	     }
 	     $$.type = $1;
 	   }
-           | idcolon DSTAR AND PERIOD PERIOD PERIOD notso_direct_declarator { 
+           | idcolon DSTAR AND ELLIPSIS notso_direct_declarator {
 	     SwigType *t = NewStringEmpty();
-	     $$ = $7;
+	     $$ = $5;
 	     SwigType_add_memberpointer(t,$1);
 	     SwigType_add_reference(t);
+	     SwigType_add_variadic(t);
 	     if ($$.type) {
 	       SwigType_push(t,$$.type);
 	       Delete($$.type);
 	     } 
 	     $$.type = t;
 	   }
-           | idcolon DSTAR LAND PERIOD PERIOD PERIOD notso_direct_declarator { 
+           | idcolon DSTAR LAND ELLIPSIS notso_direct_declarator {
 	     SwigType *t = NewStringEmpty();
-	     $$ = $7;
+	     $$ = $5;
 	     SwigType_add_memberpointer(t,$1);
 	     SwigType_add_rvalue_reference(t);
+	     SwigType_add_variadic(t);
 	     if ($$.type) {
 	       SwigType_push(t,$$.type);
 	       Delete($$.type);
@@ -5837,11 +5871,12 @@
 		  }
                   ;
 
-abstract_declarator : pointer {
+abstract_declarator : pointer variadic_opt {
 		    $$.type = $1;
                     $$.id = 0;
 		    $$.parms = 0;
 		    $$.have_parms = 0;
+		    if ($2) SwigType_add_variadic($$.type);
                   }
                   | pointer direct_abstract_declarator { 
                      $$ = $2;
@@ -5849,19 +5884,21 @@
 		     $$.type = $1;
 		     Delete($2.type);
                   }
-                  | pointer AND {
+                  | pointer AND variadic_opt {
 		    $$.type = $1;
 		    SwigType_add_reference($$.type);
 		    $$.id = 0;
 		    $$.parms = 0;
 		    $$.have_parms = 0;
+		    if ($3) SwigType_add_variadic($$.type);
 		  }
-                  | pointer LAND {
+                  | pointer LAND variadic_opt {
 		    $$.type = $1;
 		    SwigType_add_rvalue_reference($$.type);
 		    $$.id = 0;
 		    $$.parms = 0;
 		    $$.have_parms = 0;
+		    if ($3) SwigType_add_variadic($$.type);
 		  }
                   | pointer AND direct_abstract_declarator {
 		    $$ = $3;
@@ -5881,9 +5918,7 @@
 		    }
 		    $$.type = $1;
                   }
-                  | direct_abstract_declarator {
-		    $$ = $1;
-                  }
+                  | direct_abstract_declarator
                   | AND direct_abstract_declarator {
 		    $$ = $2;
 		    $$.type = NewStringEmpty();
@@ -5902,19 +5937,21 @@
 		      Delete($2.type);
 		    }
                   }
-                  | AND {
+                  | AND variadic_opt {
                     $$.id = 0;
                     $$.parms = 0;
 		    $$.have_parms = 0;
                     $$.type = NewStringEmpty();
 		    SwigType_add_reference($$.type);
+		    if ($2) SwigType_add_variadic($$.type);
                   }
-                  | LAND {
+                  | LAND variadic_opt {
                     $$.id = 0;
                     $$.parms = 0;
 		    $$.have_parms = 0;
                     $$.type = NewStringEmpty();
 		    SwigType_add_rvalue_reference($$.type);
+		    if ($2) SwigType_add_variadic($$.type);
                   }
                   | idcolon DSTAR { 
 		    $$.type = NewStringEmpty();
@@ -6105,7 +6142,7 @@
 /* Data type must be a built in type or an identifier for user-defined types
    This type can be preceded by a modifier. */
 
-type            : rawtype {
+type            : rawtype %expect 4 {
                    $$ = $1;
                    Replace($$,"typename ","", DOH_REPLACE_ANY);
                 }
@@ -6115,7 +6152,7 @@
                    $$ = $2;
 	           SwigType_push($$,$1);
                }
-               | type_right { $$ = $1; }
+	       | type_right
                | type_right type_qualifier {
 		  $$ = $1;
 	          SwigType_push($$,$2);
@@ -6125,49 +6162,69 @@
 	          SwigType_push($$,$3);
 	          SwigType_push($$,$1);
 	       }
+	       | rawtype ELLIPSIS {
+		  $$ = $1;
+		  SwigType_add_variadic($$);
+	       }
                ;
 
-type_right     : primitive_type { $$ = $1;
-                  /* Printf(stdout,"primitive = '%s'\n", $$);*/
-               }
-               | TYPE_BOOL { $$ = $1; }
-               | TYPE_VOID { $$ = $1; }
-/*
-               | TYPE_TYPEDEF template_decl { $$ = NewStringf("%s%s",$1,$2); }
-*/
+type_right     : primitive_type
+               | TYPE_BOOL
+               | TYPE_VOID
                | c_enum_key idcolon { $$ = NewStringf("enum %s", $2); }
-               | TYPE_RAW { $$ = $1; }
+               | TYPE_RAW
 
-               | idcolon {
+               | idcolon %expect 1 {
 		  $$ = $1;
                }
-               | cpptype idcolon { 
+               | cpptype idcolon %expect 1 {
 		 $$ = NewStringf("%s %s", $1, $2);
                }
-               | decltype {
-                 $$ = $1;
-               }
+               | decltype
                ;
 
-decltype       : DECLTYPE LPAREN idcolon RPAREN {
-                 Node *n = Swig_symbol_clookup($3,0);
-                 if (!n) {
-		   Swig_error(cparse_file, cparse_line, "Identifier %s not defined.\n", $3);
-                   $$ = $3;
-                 } else {
-                   $$ = Getattr(n, "type");
-                 }
-               }
-               ;
+decltype       : DECLTYPE LPAREN <str>{
+		 $$ = get_raw_text_balanced('(', ')');
+	       } decltypeexpr {
+		 String *expr = $3;
+		 if ($4) {
+		   $$ = $4;
+		 } else {
+		   $$ = NewStringf("decltype%s", expr);
+		   /* expr includes parentheses but don't include them in the warning message. */
+		   Delitem(expr, 0);
+		   Delitem(expr, DOH_END);
+		   Swig_warning(WARN_CPP11_DECLTYPE, cparse_file, cparse_line, "Unable to deduce decltype for '%s'.\n", expr);
+		 }
+		 Delete(expr);
+	       }
+	       ;
+
+decltypeexpr   : expr RPAREN {
+		 $$ = deduce_type(&$1);
+	       }
+	       | error RPAREN {
+		 /* Avoid a parse error if we can't parse the expression
+		  * decltype() is applied to.
+		  *
+		  * Set $$ to 0 here to trigger the decltype rule above to
+		  * issue a warning.
+		  */
+		 $$ = 0;
+		 if (skip_balanced('(',')') < 0) Exit(EXIT_FAILURE);
+		 Clear(scanner_ccode);
+	       }
+	       ;
 
 primitive_type : primitive_type_list {
-		 if (!$1.type) $1.type = NewString("int");
+		 String *type = $1.type;
+		 if (!type) type = NewString("int");
 		 if ($1.us) {
-		   $$ = NewStringf("%s %s", $1.us, $1.type);
+		   $$ = NewStringf("%s %s", $1.us, type);
 		   Delete($1.us);
-                   Delete($1.type);
+                   Delete(type);
 		 } else {
-                   $$ = $1.type;
+                   $$ = type;
 		 }
 		 if (Cmp($$,"signed int") == 0) {
 		   Delete($$);
@@ -6185,9 +6242,7 @@
                }
                ;
 
-primitive_type_list : type_specifier { 
-                 $$ = $1;
-               }
+primitive_type_list : type_specifier
                | type_specifier primitive_type_list {
                     if ($1.us && $2.us) {
 		      Swig_error(cparse_file, cparse_line, "Extra %s specifier.\n", $2.us);
@@ -6217,19 +6272,19 @@
 			} else if (Cmp($1.type,"double") == 0) {
 			  if (Cmp($2.type,"long") == 0) {
 			    $$.type = NewString("long double");
-			  } else if (Cmp($2.type,"complex") == 0) {
-			    $$.type = NewString("double complex");
+			  } else if (Cmp($2.type,"_Complex") == 0) {
+			    $$.type = NewString("double _Complex");
 			  } else {
 			    err = 1;
 			  }
 			} else if (Cmp($1.type,"float") == 0) {
-			  if (Cmp($2.type,"complex") == 0) {
-			    $$.type = NewString("float complex");
+			  if (Cmp($2.type,"_Complex") == 0) {
+			    $$.type = NewString("float _Complex");
 			  } else {
 			    err = 1;
 			  }
-			} else if (Cmp($1.type,"complex") == 0) {
-			  $$.type = NewStringf("%s complex", $2.type);
+			} else if (Cmp($1.type,"_Complex") == 0) {
+			  $$.type = NewStringf("%s _Complex", $2.type);
 			} else {
 			  err = 1;
 			}
@@ -6279,7 +6334,7 @@
                     $$.type = 0;
                 }
                | TYPE_COMPLEX { 
-                    $$.type = NewString("complex");
+                    $$.type = NewString("_Complex");
                     $$.us = 0;
                 }
                | TYPE_NON_ISO_INT8 { 
@@ -6300,8 +6355,8 @@
                 }
                ;
 
-definetype     : { /* scanner_check_typedef(); */ } expr {
-                   $$ = $2;
+definetype     : expr {
+                   $$ = $1;
 		   if ($$.type == T_STRING) {
 		     $$.rawval = NewStringf("\"%(escape)s\"",$$.val);
 		   } else if ($$.type != T_CHAR && $$.type != T_WSTRING && $$.type != T_WCHAR) {
@@ -6314,19 +6369,12 @@
 		   $$.throwf = 0;
 		   $$.nexcept = 0;
 		   $$.final = 0;
-		   scanner_ignore_typedef();
                 }
-                | default_delete {
-		  $$ = $1;
-		}
+                | default_delete
                 ;
 
-default_delete : deleted_definition {
-		  $$ = $1;
-		}
-                | explicit_default {
-		  $$ = $1;
-		}
+default_delete : deleted_definition
+                | explicit_default
 		;
 
 /* For C++ deleted definition '= delete' */
@@ -6334,6 +6382,7 @@
 		  $$.val = NewString("delete");
 		  $$.rawval = 0;
 		  $$.type = T_STRING;
+		  $$.unary_arg_type = 0;
 		  $$.qualifier = 0;
 		  $$.refqualifier = 0;
 		  $$.bitfield = 0;
@@ -6349,6 +6398,7 @@
 		  $$.val = NewString("default");
 		  $$.rawval = 0;
 		  $$.type = T_STRING;
+		  $$.unary_arg_type = 0;
 		  $$.qualifier = 0;
 		  $$.refqualifier = 0;
 		  $$.bitfield = 0;
@@ -6361,8 +6411,8 @@
 
 /* Some stuff for handling enums */
 
-ename          :  identifier { $$ = $1; }
-	       |  empty { $$ = (char *) 0;}
+ename          :  identifier
+	       |  %empty { $$ = 0; }
 	       ;
 
 constant_directives : constant_directive
@@ -6371,7 +6421,7 @@
 
 optional_ignored_defines
 		: constant_directives
-		| empty
+		| %empty
 		;
 
 /* Enum lists - any #define macros (constant directives) within the enum list are ignored. Trailing commas accepted. */
@@ -6390,6 +6440,12 @@
 		  set_comment($1, $2);
 		  $$ = $1;
 		}
+		| enumlist_item DOXYGENSTRING {
+		  Setattr($1, "_last", $1);
+		  /* Misplaced doxygen string, attach it to previous parameter, like Doxygen does */
+		  set_comment($1, $2);
+		  $$ = $1;
+		}
 		| enumlist_item COMMA enumlist {
 		  if ($3) {
 		    set_nextSibling($1, $3);
@@ -6400,6 +6456,17 @@
 		  }
 		  $$ = $1;
 		}
+		| enumlist_item DOXYGENPOSTSTRING COMMA enumlist {
+		  if ($4) {
+		    set_nextSibling($1, $4);
+		    Setattr($1,"_last",Getattr($4,"_last"));
+		    Setattr($4,"_last",NULL);
+		  } else {
+		    Setattr($1,"_last",$1);
+		  }
+		  set_comment($1, $2);
+		  $$ = $1;
+		}
 		| enumlist_item COMMA DOXYGENPOSTSTRING enumlist {
 		  if ($4) {
 		    set_nextSibling($1, $4);
@@ -6421,9 +6488,7 @@
 		}
 		;
 
-edecl_with_dox	: edecl {
-		  $$ = $1;
-		}
+edecl_with_dox	: edecl
 		| DOXYGENSTRING edecl {
 		  $$ = $2;
 		  set_comment($2, $1);
@@ -6452,12 +6517,15 @@
 
 etype            : expr {
                    $$ = $1;
+		   /* We get T_USER here for a typedef - unfortunately we can't
+		    * currently resolve typedefs at this stage of parsing. */
 		   if (($$.type != T_INT) && ($$.type != T_UINT) &&
 		       ($$.type != T_LONG) && ($$.type != T_ULONG) &&
 		       ($$.type != T_LONGLONG) && ($$.type != T_ULONGLONG) &&
 		       ($$.type != T_SHORT) && ($$.type != T_USHORT) &&
 		       ($$.type != T_SCHAR) && ($$.type != T_UCHAR) &&
-		       ($$.type != T_CHAR) && ($$.type != T_BOOL)) {
+		       ($$.type != T_CHAR) && ($$.type != T_BOOL) &&
+		       ($$.type != T_UNKNOWN) && ($$.type != T_USER)) {
 		     Swig_error(cparse_file,cparse_line,"Type error. Expecting an integral type\n");
 		   }
                 }
@@ -6465,11 +6533,12 @@
 
 /* Arithmetic expressions.  Used for constants, C++ templates, and other cool stuff. */
 
-expr           : valexpr { $$ = $1; }
+expr           : valexpr
                | type {
 		 Node *n;
 		 $$.val = $1;
-		 $$.type = T_INT;
+		 $$.type = T_UNKNOWN;
+		 $$.unary_arg_type = 0;
 		 /* Check if value is in scope */
 		 n = Swig_symbol_clookup($1,0);
 		 if (n) {
@@ -6478,9 +6547,15 @@
                      String *q = Swig_symbol_qualified(n);
                      if (q) {
                        $$.val = NewStringf("%s::%s", q, Getattr(n,"name"));
+		       $$.type = SwigType_type(Getattr(n, "type"));
                        Delete(q);
                      }
-                   }
+		   } else {
+		     SwigType *type = Getattr(n, "type");
+		     if (type) {
+		       $$.type = SwigType_type(type);
+		     }
+		   }
 		 }
                }
 	       ;
@@ -6490,47 +6565,82 @@
 		 $$.val = NewStringf("%s->%s", $1, $3);
 		 $$.type = 0;
 	       }
+	       | ID ARROW ID LPAREN callparms RPAREN {
+		 $$.val = NewStringf("%s->%s(%s)", $1, $3, $5.val);
+		 $$.type = 0;
+	       }
 	       | exprmem ARROW ID {
 		 $$ = $1;
 		 Printf($$.val, "->%s", $3);
 	       }
-/* This generates a shift-reduce
+	       | exprmem ARROW ID LPAREN callparms RPAREN {
+		 $$ = $1;
+		 Printf($$.val, "->%s(%s)", $3, $5.val);
+	       }
 	       | ID PERIOD ID {
 		 $$.val = NewStringf("%s.%s", $1, $3);
 		 $$.type = 0;
 	       }
-*/
+	       | ID PERIOD ID LPAREN callparms RPAREN {
+		 $$.val = NewStringf("%s.%s(%s)", $1, $3, $5.val);
+		 $$.type = 0;
+	       }
 	       | exprmem PERIOD ID {
 		 $$ = $1;
 		 Printf($$.val, ".%s", $3);
 	       }
+	       | exprmem PERIOD ID LPAREN callparms RPAREN {
+		 $$ = $1;
+		 Printf($$.val, ".%s(%s)", $3, $5.val);
+	       }
 	       ;
 
-valexpr        : exprnum {
-		    $$ = $1;
-               }
-               | exprmem {
-		    $$ = $1;
-               }
+/* Non-compound expression */
+exprsimple     : exprnum
+               | exprmem
                | string {
 		    $$.val = $1;
                     $$.type = T_STRING;
+		    $$.unary_arg_type = 0;
                }
                | SIZEOF LPAREN type parameter_declarator RPAREN {
 		  SwigType_push($3,$4.type);
 		  $$.val = NewStringf("sizeof(%s)",SwigType_str($3,0));
 		  $$.type = T_ULONG;
+		  $$.unary_arg_type = 0;
                }
-               | SIZEOF PERIOD PERIOD PERIOD LPAREN type parameter_declarator RPAREN {
-		  SwigType_push($6,$7.type);
-		  $$.val = NewStringf("sizeof...(%s)",SwigType_str($6,0));
+               | SIZEOF ELLIPSIS LPAREN type parameter_declarator RPAREN {
+		  SwigType_push($4,$5.type);
+		  $$.val = NewStringf("sizeof...(%s)",SwigType_str($4,0));
 		  $$.type = T_ULONG;
+		  $$.unary_arg_type = 0;
                }
-               | exprcompound { $$ = $1; }
+	       /* We don't support all valid expressions here currently - e.g.
+		* sizeof(<unaryop> x) doesn't work - but those are unlikely to
+		* be seen in real code.
+		*
+		* Note: sizeof(x) is not handled here, but instead by the rule
+		* for sizeof(<type>) because it matches that syntactically.
+		*/
+	       | SIZEOF LPAREN exprsimple RPAREN {
+		  $$.val = NewStringf("sizeof(%s)", $3.val);
+		  $$.type = T_ULONG;
+		  $$.unary_arg_type = 0;
+	       }
+	       /* `sizeof expr` without parentheses is valid for an expression,
+		* but not for a type.  This doesn't support `sizeof x` in
+		* addition to the case not supported above.
+		*/
+	       | SIZEOF exprsimple {
+		  $$.val = NewStringf("sizeof(%s)", $2.val);
+		  $$.type = T_ULONG;
+		  $$.unary_arg_type = 0;
+	       }
 	       | wstring {
 		    $$.val = $1;
 		    $$.rawval = NewStringf("L\"%s\"", $$.val);
                     $$.type = T_WSTRING;
+		    $$.unary_arg_type = 0;
 	       }
                | CHARCONST {
 		  $$.val = NewString($1);
@@ -6540,6 +6650,7 @@
 		    $$.rawval = NewString("'\\0'");
 		  }
 		  $$.type = T_CHAR;
+		  $$.unary_arg_type = 0;
 		  $$.bitfield = 0;
 		  $$.throws = 0;
 		  $$.throwf = 0;
@@ -6554,6 +6665,7 @@
 		    $$.rawval = NewString("L'\\0'");
 		  }
 		  $$.type = T_WCHAR;
+		  $$.unary_arg_type = 0;
 		  $$.bitfield = 0;
 		  $$.throws = 0;
 		  $$.throwf = 0;
@@ -6561,6 +6673,11 @@
 		  $$.final = 0;
 	       }
 
+               ;
+
+valexpr        : exprsimple
+	       | exprcompound
+
 /* grouping */
                |  LPAREN expr RPAREN %prec CAST {
 		    $$.val = NewStringf("(%s)",$2.val);
@@ -6573,7 +6690,9 @@
 /* A few common casting operations */
 
                | LPAREN expr RPAREN expr %prec CAST {
-                 $$ = $4;
+		 int cast_type_code = SwigType_type($2.val);
+		 $$ = $4;
+		 $$.unary_arg_type = 0;
 		 if ($4.type != T_STRING) {
 		   switch ($2.type) {
 		     case T_FLOAT:
@@ -6588,10 +6707,28 @@
 		       break;
 		   }
 		 }
-		 $$.type = promote($2.type, $4.type);
+		 /* As well as C-style casts, this grammar rule currently also
+		  * matches a binary operator with a LHS in parentheses for
+		  * binary operators which also have an unary form, e.g.:
+		  *
+		  * (6)*7
+		  * (6)&7
+		  * (6)+7
+		  * (6)-7
+		  */
+		 if (cast_type_code != T_USER && cast_type_code != T_UNKNOWN) {
+		   /* $2 is definitely a type so we know this is a cast. */
+		   $$.type = cast_type_code;
+		 } else if ($4.type == 0 || $4.unary_arg_type == 0) {
+		   /* Not one of the cases above, so we know this is a cast. */
+		   $$.type = cast_type_code;
+		 } else {
+		   $$.type = promote($2.type, $4.unary_arg_type);
+		 }
  	       }
                | LPAREN expr pointer RPAREN expr %prec CAST {
                  $$ = $5;
+		 $$.unary_arg_type = 0;
 		 if ($5.type != T_STRING) {
 		   SwigType_push($2.val,$3);
 		   $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val);
@@ -6599,6 +6736,7 @@
  	       }
                | LPAREN expr AND RPAREN expr %prec CAST {
                  $$ = $5;
+		 $$.unary_arg_type = 0;
 		 if ($5.type != T_STRING) {
 		   SwigType_add_reference($2.val);
 		   $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val);
@@ -6606,6 +6744,7 @@
  	       }
                | LPAREN expr LAND RPAREN expr %prec CAST {
                  $$ = $5;
+		 $$.unary_arg_type = 0;
 		 if ($5.type != T_STRING) {
 		   SwigType_add_rvalue_reference($2.val);
 		   $$.val = NewStringf("(%s) %s", SwigType_str($2.val,0), $5.val);
@@ -6613,6 +6752,7 @@
  	       }
                | LPAREN expr pointer AND RPAREN expr %prec CAST {
                  $$ = $6;
+		 $$.unary_arg_type = 0;
 		 if ($6.type != T_STRING) {
 		   SwigType_push($2.val,$3);
 		   SwigType_add_reference($2.val);
@@ -6621,6 +6761,7 @@
  	       }
                | LPAREN expr pointer LAND RPAREN expr %prec CAST {
                  $$ = $6;
+		 $$.unary_arg_type = 0;
 		 if ($6.type != T_STRING) {
 		   SwigType_push($2.val,$3);
 		   SwigType_add_rvalue_reference($2.val);
@@ -6629,26 +6770,56 @@
  	       }
                | AND expr {
 		 $$ = $2;
-                 $$.val = NewStringf("&%s",$2.val);
-	       }
-               | LAND expr {
-		 $$ = $2;
-                 $$.val = NewStringf("&&%s",$2.val);
+		 $$.val = NewStringf("&%s", $2.val);
+		 $$.rawval = 0;
+		 /* Record the type code for expr so we can properly handle
+		  * cases such as (6)&7 which get parsed using this rule then
+		  * the rule for a C-style cast.
+		  */
+		 $$.unary_arg_type = $2.type;
+		 switch ($$.type) {
+		   case T_CHAR:
+		     $$.type = T_STRING;
+		     break;
+		   case T_WCHAR:
+		     $$.type = T_WSTRING;
+		     break;
+		   default:
+		     $$.type = T_POINTER;
+		 }
 	       }
                | STAR expr {
 		 $$ = $2;
-                 $$.val = NewStringf("*%s",$2.val);
+		 $$.val = NewStringf("*%s", $2.val);
+		 $$.rawval = 0;
+		 /* Record the type code for expr so we can properly handle
+		  * cases such as (6)*7 which get parsed using this rule then
+		  * the rule for a C-style cast.
+		  */
+		 $$.unary_arg_type = $2.type;
+		 switch ($$.type) {
+		   case T_STRING:
+		     $$.type = T_CHAR;
+		     break;
+		   case T_WSTRING:
+		     $$.type = T_WCHAR;
+		     break;
+		   default:
+		     $$.type = T_UNKNOWN;
+		 }
 	       }
-               ;
+	       ;
 
-exprnum        :  NUM_INT { $$ = $1; }
-               |  NUM_FLOAT { $$ = $1; }
-               |  NUM_UNSIGNED { $$ = $1; }
-               |  NUM_LONG { $$ = $1; }
-               |  NUM_ULONG { $$ = $1; }
-               |  NUM_LONGLONG { $$ = $1; }
-               |  NUM_ULONGLONG { $$ = $1; }
-               |  NUM_BOOL { $$ = $1; }
+exprnum        :  NUM_INT
+               |  NUM_DOUBLE
+               |  NUM_FLOAT
+               |  NUM_LONGDOUBLE
+               |  NUM_UNSIGNED
+               |  NUM_LONG
+               |  NUM_ULONG
+               |  NUM_LONGLONG
+               |  NUM_ULONGLONG
+               |  NUM_BOOL
                ;
 
 exprcompound   : expr PLUS expr {
@@ -6707,16 +6878,24 @@
 		 $$.val = NewStringf("%s!=%s",COMPOUND_EXPR_VAL($1),COMPOUND_EXPR_VAL($3));
 		 $$.type = cparse_cplusplus ? T_BOOL : T_INT;
 	       }
-/* Sadly this causes 2 reduce-reduce conflicts with templates.  FIXME resolve these.
-               | expr GREATERTHAN expr {
-		 $$.val = NewStringf("%s > %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
+	       /* Trying to parse `>` in the general case results in conflicts
+		* in the parser, but all user-reported cases are actually inside
+		* parentheses and we can handle that case.
+		*/
+	       | LPAREN expr GREATERTHAN expr RPAREN {
+		 $$.val = NewStringf("(%s > %s)", COMPOUND_EXPR_VAL($2), COMPOUND_EXPR_VAL($4));
 		 $$.type = cparse_cplusplus ? T_BOOL : T_INT;
 	       }
-               | expr LESSTHAN expr {
-		 $$.val = NewStringf("%s < %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
+
+	       /* Similarly for `<` except trying to handle exprcompound on the
+		* left side gives a shift/reduce conflict, so also restrict
+		* handling to non-compound subexpressions there.  Again this
+		* covers all user-reported cases.
+		*/
+               | LPAREN exprsimple LESSTHAN expr RPAREN {
+		 $$.val = NewStringf("(%s < %s)", COMPOUND_EXPR_VAL($2), COMPOUND_EXPR_VAL($4));
 		 $$.type = cparse_cplusplus ? T_BOOL : T_INT;
 	       }
-*/
                | expr GREATERTHANOREQUALTO expr {
 		 $$.val = NewStringf("%s >= %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
 		 $$.type = cparse_cplusplus ? T_BOOL : T_INT;
@@ -6725,6 +6904,20 @@
 		 $$.val = NewStringf("%s <= %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
 		 $$.type = cparse_cplusplus ? T_BOOL : T_INT;
 	       }
+	       | expr LESSEQUALGREATER expr {
+		 $$.val = NewStringf("%s <=> %s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3));
+		 /* `<=>` returns one of `std::strong_ordering`,
+		  * `std::partial_ordering` or `std::weak_ordering`.  The main
+		  * thing to do with the return value in this context is to
+		  * compare it with another ordering of the same type or
+		  * with a literal 0.  We set .type = T_USER here which does
+		  * what we want for the comparison operators, and also means
+		  * that deduce_type() won't deduce a type for this (which is
+		  * better than it deducing the wrong type).
+		  */
+		 $$.type = T_USER;
+		 $$.unary_arg_type = 0;
+	       }
 	       | expr QUESTIONMARK expr COLON expr %prec QUESTIONMARK {
 		 $$.val = NewStringf("%s?%s:%s", COMPOUND_EXPR_VAL($1), COMPOUND_EXPR_VAL($3), COMPOUND_EXPR_VAL($5));
 		 /* This may not be exactly right, but is probably good enough
@@ -6733,23 +6926,33 @@
 	       }
                | MINUS expr %prec UMINUS {
 		 $$.val = NewStringf("-%s",$2.val);
-		 $$.type = $2.type;
+		 $$.type = promote_type($2.type);
+		 /* Record the type code for expr so we can properly handle
+		  * cases such as (6)-7 which get parsed using this rule then
+		  * the rule for a C-style cast.
+		  */
+		 $$.unary_arg_type = $2.type;
 	       }
                | PLUS expr %prec UMINUS {
                  $$.val = NewStringf("+%s",$2.val);
-		 $$.type = $2.type;
+		 $$.type = promote_type($2.type);
+		 /* Record the type code for expr so we can properly handle
+		  * cases such as (6)+7 which get parsed using this rule then
+		  * the rule for a C-style cast.
+		  */
+		 $$.unary_arg_type = $2.type;
 	       }
                | NOT expr {
 		 $$.val = NewStringf("~%s",$2.val);
-		 $$.type = $2.type;
+		 $$.type = promote_type($2.type);
 	       }
                | LNOT expr {
                  $$.val = NewStringf("!%s",COMPOUND_EXPR_VAL($2));
-		 $$.type = T_INT;
+		 $$.type = cparse_cplusplus ? T_BOOL : T_INT;
 	       }
                | type LPAREN {
 		 String *qty;
-                 skip_balanced('(',')');
+		 if (skip_balanced('(',')') < 0) Exit(EXIT_FAILURE);
 		 qty = Swig_symbol_type_qualify($1,0);
 		 if (SwigType_istemplate(qty)) {
 		   String *nstr = SwigType_namestr(qty);
@@ -6758,31 +6961,34 @@
 		 }
 		 $$.val = NewStringf("%s%s",qty,scanner_ccode);
 		 Clear(scanner_ccode);
-		 $$.type = T_INT;
+		 /* Try to deduce the type - this could be a C++ "constructor
+		  * cast" such as `double(4)` or a function call such as
+		  * `some_func()`.  In the latter case we get T_USER, but that
+		  * is wrong so we map it to T_UNKNOWN until we can actually
+		  * deduce the return type of a function call (which is
+		  * complicated because the return type can vary between
+		  * overloaded forms).
+		  */
+		 $$.type = SwigType_type(qty);
+		 if ($$.type == T_USER) $$.type = T_UNKNOWN;
+		 $$.unary_arg_type = 0;
 		 Delete(qty);
                }
                ;
 
-ellipsis      : PERIOD PERIOD PERIOD {
+variadic_opt  : ELLIPSIS {
 	        $$ = NewString("...");
 	      }
-	      ;
-
-variadic      : ellipsis {
-	        $$ = $1;
-	      }
-	      | empty {
+	      | %empty {
 	        $$ = 0;
 	      }
 	      ;
 
-inherit        : raw_inherit {
-		 $$ = $1;
-               }
+inherit        : raw_inherit
                ;
 
 raw_inherit     : COLON { inherit_list = 1; } base_list { $$ = $3; inherit_list = 0; }
-                | empty { $$ = 0; }
+                | %empty { $$ = 0; }
                 ;
 
 base_list      : base_specifier {
@@ -6811,102 +7017,94 @@
                }
                ;
 
-base_specifier : opt_virtual {
-		 $<intvalue>$ = cparse_line;
-	       } idcolon variadic {
+base_specifier : opt_virtual <intvalue>{
+		 $$ = cparse_line;
+	       } idcolon variadic_opt {
 		 $$ = NewHash();
 		 Setfile($$,cparse_file);
-		 Setline($$,$<intvalue>2);
+		 Setline($$,$2);
 		 Setattr($$,"name",$3);
 		 Setfile($3,cparse_file);
-		 Setline($3,$<intvalue>2);
+		 Setline($3,$2);
                  if (last_cpptype && (Strcmp(last_cpptype,"struct") != 0)) {
 		   Setattr($$,"access","private");
 		   Swig_warning(WARN_PARSE_NO_ACCESS, Getfile($$), Getline($$), "No access specifier given for base class '%s' (ignored).\n", SwigType_namestr($3));
                  } else {
 		   Setattr($$,"access","public");
 		 }
-		 if ($4)
-		   SetFlag($$, "variadic");
+		 if ($4) {
+		   SwigType_add_variadic(Getattr($$, "name"));
+		 }
                }
-	       | opt_virtual access_specifier {
-		 $<intvalue>$ = cparse_line;
-	       } opt_virtual idcolon variadic {
+	       | opt_virtual access_specifier <intvalue>{
+		 $$ = cparse_line;
+	       } opt_virtual idcolon variadic_opt {
 		 $$ = NewHash();
 		 Setfile($$,cparse_file);
-		 Setline($$,$<intvalue>3);
+		 Setline($$,$3);
 		 Setattr($$,"name",$5);
 		 Setfile($5,cparse_file);
-		 Setline($5,$<intvalue>3);
+		 Setline($5,$3);
 		 Setattr($$,"access",$2);
 	         if (Strcmp($2,"public") != 0) {
 		   Swig_warning(WARN_PARSE_PRIVATE_INHERIT, Getfile($$), Getline($$), "%s inheritance from base '%s' (ignored).\n", $2, SwigType_namestr($5));
 		 }
-		 if ($6)
-		   SetFlag($$, "variadic");
+		 if ($6) {
+		   SwigType_add_variadic(Getattr($$, "name"));
+		 }
                }
                ;
 
-access_specifier :  PUBLIC { $$ = (char*)"public"; }
-               | PRIVATE { $$ = (char*)"private"; }
-               | PROTECTED { $$ = (char*)"protected"; }
+access_specifier :  PUBLIC { $$ = "public"; }
+               | PRIVATE { $$ = "private"; }
+               | PROTECTED { $$ = "protected"; }
                ;
 
-templcpptype   : CLASS { 
-                   $$ = (char*)"class"; 
+templcpptype   : CLASS variadic_opt {
+                   $$ = NewString("class");
 		   if (!inherit_list) last_cpptype = $$;
+		   if ($2) SwigType_add_variadic($$);
                }
-               | TYPENAME { 
-                   $$ = (char *)"typename"; 
+               | TYPENAME variadic_opt {
+                   $$ = NewString("typename");
 		   if (!inherit_list) last_cpptype = $$;
-               }
-               | CLASS PERIOD PERIOD PERIOD { 
-                   $$ = (char *)"class..."; 
-		   if (!inherit_list) last_cpptype = $$;
-               }
-               | TYPENAME PERIOD PERIOD PERIOD { 
-                   $$ = (char *)"typename..."; 
-		   if (!inherit_list) last_cpptype = $$;
+		   if ($2) SwigType_add_variadic($$);
                }
                ;
 
-cpptype        : templcpptype {
-                 $$ = $1;
-               }
-               | STRUCT { 
-                   $$ = (char*)"struct"; 
+cpptype        : templcpptype
+               | STRUCT {
+                   $$ = NewString("struct");
 		   if (!inherit_list) last_cpptype = $$;
                }
                | UNION {
-                   $$ = (char*)"union"; 
+                   $$ = NewString("union");
 		   if (!inherit_list) last_cpptype = $$;
                }
                ;
 
 classkey       : CLASS {
-                   $$ = (char*)"class";
+                   $$ = NewString("class");
 		   if (!inherit_list) last_cpptype = $$;
                }
                | STRUCT {
-                   $$ = (char*)"struct";
+                   $$ = NewString("struct");
 		   if (!inherit_list) last_cpptype = $$;
                }
                | UNION {
-                   $$ = (char*)"union";
+                   $$ = NewString("union");
 		   if (!inherit_list) last_cpptype = $$;
                }
                ;
 
-classkeyopt    : classkey {
-		   $$ = $1;
-               }
-               | empty {
+classkeyopt    : classkey
+               | %empty {
 		   $$ = 0;
                }
                ;
 
 opt_virtual    : VIRTUAL
-               | empty
+               | %empty
                ;
 
 virt_specifier_seq : OVERRIDE {
@@ -6923,10 +7121,16 @@
 	       }
                ;
 
-virt_specifier_seq_opt : virt_specifier_seq {
-                   $$ = $1;
+virt_specifier_seq_opt : virt_specifier_seq
+               | %empty {
+                   $$ = 0;
                }
-               | empty {
+               ;
+
+class_virt_specifier_opt : FINAL {
+                   $$ = NewString("1");
+               }
+               | %empty {
                    $$ = 0;
                }
                ;
@@ -6989,10 +7193,8 @@
                }
                ;
 
-cpp_const      : qualifiers_exception_specification {
-                    $$ = $1;
-               }
-               | empty { 
+cpp_const      : qualifiers_exception_specification
+               | %empty {
                     $$.throws = 0;
                     $$.throwf = 0;
                     $$.nexcept = 0;
@@ -7014,15 +7216,15 @@
                       Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
                }
                | cpp_const ctor_initializer LBRACE { 
-                    skip_balanced('{','}'); 
+                    if ($1.qualifier)
+                      Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
+                    if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
                     $$.have_parms = 0; 
                     $$.defarg = 0; 
                     $$.throws = $1.throws;
                     $$.throwf = $1.throwf;
                     $$.nexcept = $1.nexcept;
                     $$.final = $1.final;
-                    if ($1.qualifier)
-                      Swig_error(cparse_file, cparse_line, "Constructor cannot have a qualifier.\n");
                }
                | LPAREN parms RPAREN SEMI { 
                     Clear(scanner_ccode); 
@@ -7035,7 +7237,7 @@
 		    $$.final = 0;
                }
                | LPAREN parms RPAREN LBRACE {
-                    skip_balanced('{','}'); 
+                    if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
                     $$.parms = $2; 
                     $$.have_parms = 1; 
                     $$.defarg = 0; 
@@ -7065,17 +7267,17 @@
                ;
 
 ctor_initializer : COLON mem_initializer_list
-               | empty
+               | %empty
                ;
 
 mem_initializer_list : mem_initializer
                | mem_initializer_list COMMA mem_initializer
-               | mem_initializer PERIOD PERIOD PERIOD
-               | mem_initializer_list COMMA mem_initializer PERIOD PERIOD PERIOD
+               | mem_initializer ELLIPSIS
+               | mem_initializer_list COMMA mem_initializer ELLIPSIS
                ;
 
 mem_initializer : idcolon LPAREN {
-		  skip_balanced('(',')');
+		  if (skip_balanced('(',')') < 0) Exit(EXIT_FAILURE);
 		  Clear(scanner_ccode);
 		}
                 /* Uniform initialization in C++11.
@@ -7087,7 +7289,7 @@
                    };
                 */
                 | idcolon LBRACE {
-		  skip_balanced('{','}');
+		  if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
 		  Clear(scanner_ccode);
 		}
                 ;
@@ -7101,24 +7303,23 @@
 		;
 
 /* Identifiers including the C++11 identifiers with special meaning */
-identifier     : ID { $$ = $1; }
+identifier     : ID
 	       | OVERRIDE { $$ = Swig_copy_string("override"); }
 	       | FINAL { $$ = Swig_copy_string("final"); }
 	       ;
 
-idstring       : identifier { $$ = $1; }
+idstring       : identifier
                | default_delete { $$ = Char($1.val); }
                | string { $$ = Char($1); }
                ;
 
-idstringopt    : idstring { $$ = $1; }
-               | empty { $$ = 0; }
+idstringopt    : idstring
+               | %empty { $$ = 0; }
                ;
 
 idcolon        : idtemplate idcolontail { 
-                  $$ = 0;
-		  if (!$$) $$ = NewStringf("%s%s", $1,$2);
-      	          Delete($2);
+		 $$ = NewStringf("%s%s", $1, $2);
+		 Delete($2);
                }
                | NONID DCOLON idtemplatetemplate idcolontail {
 		 $$ = NewStringf("::%s%s",$3,$4);
@@ -7130,7 +7331,7 @@
                | NONID DCOLON idtemplatetemplate {
 		 $$ = NewStringf("::%s",$3);
                }
-               | OPERATOR {
+               | OPERATOR %expect 1 {
                  $$ = NewStringf("%s", $1);
 	       }
                | OPERATOR less_valparms_greater {
@@ -7169,9 +7370,7 @@
 	      }
               ;
 
-idtemplatetemplate : idtemplate {
-		$$ = $1;
-	      }
+idtemplatetemplate : idtemplate
 	      | TEMPLATE identifier less_valparms_greater {
 		$$ = NewStringf("%s%s", $2, $3);
 	      }
@@ -7179,9 +7378,8 @@
 
 /* Identifier, but no templates */
 idcolonnt     : identifier idcolontailnt {
-                  $$ = 0;
-		  if (!$$) $$ = NewStringf("%s%s", $1,$2);
-      	          Delete($2);
+		 $$ = NewStringf("%s%s", $1, $2);
+		 Delete($2);
                }
                | NONID DCOLON identifier idcolontailnt {
 		 $$ = NewStringf("::%s%s",$3,$4);
@@ -7234,16 +7432,12 @@
                | WSTRING { $$ = NewString($1);}
                ;
 
-stringbrace    : string {
-		 $$ = $1;
-               }
+stringbrace    : string
                | LBRACE {
-                  skip_balanced('{','}');
+		  if (skip_balanced('{','}') < 0) Exit(EXIT_FAILURE);
 		  $$ = NewString(scanner_ccode);
                }
-              | HBLOCK {
-		 $$ = $1;
-              }
+              | HBLOCK
                ;
 
 options        : LPAREN kwargs RPAREN {
@@ -7259,7 +7453,7 @@
 		     n = nextSibling(n);
 		  }
                }   
-               | empty { $$ = 0; };
+               | %empty { $$ = 0; };
 
  
 /* Keyword arguments */
@@ -7294,42 +7488,38 @@
                }
                ;
 
-stringnum      : string {
-		 $$ = $1;
-               }
+stringnum      : string
                | exprnum {
                  $$ = Char($1.val);
                }
                ;
 
-empty          :   ;
-
 %%
 
 SwigType *Swig_cparse_type(String *s) {
    String *ns;
-   ns = NewStringf("%s;",s);
+   ns = NewString(s);
    Seek(ns,0,SEEK_SET);
    scanner_file(ns);
    top = 0;
    scanner_next_token(PARSETYPE);
    yyparse();
    /*   Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */
-   return top;
+   return (SwigType *)top;
 }
 
 
 Parm *Swig_cparse_parm(String *s) {
    String *ns;
-   ns = NewStringf("%s;",s);
+   ns = NewString(s);
    Seek(ns,0,SEEK_SET);
    scanner_file(ns);
    top = 0;
    scanner_next_token(PARSEPARM);
    yyparse();
-   /*   Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */
+   /*   Printf(stdout,"parmparse: '%s' ---> '%s'\n", s, top); */
    Delete(ns);
-   return top;
+   return (Parm *)top;
 }
 
 
@@ -7337,9 +7527,9 @@
    String *ns;
    char *cs = Char(s);
    if (cs && cs[0] != '(') {
-     ns = NewStringf("(%s);",s);
+     ns = NewStringf("(%s)",s);
    } else {
-     ns = NewStringf("%s;",s);
+     ns = NewString(s);
    }
    Setfile(ns, Getfile(file_line_node));
    Setline(ns, Getline(file_line_node));
@@ -7348,7 +7538,7 @@
    top = 0;
    scanner_next_token(PARSEPARMS);
    yyparse();
-   /*   Printf(stdout,"typeparse: '%s' ---> '%s'\n", s, top); */
-   return top;
+   /*   Printf(stdout,"parmsparse: '%s' ---> '%s'\n", s, top); */
+   return (ParmList *)top;
 }
 
diff --git a/Source/CParse/templ.c b/Source/CParse/templ.c
index 22d49fa..35ac85c 100644
--- a/Source/CParse/templ.c
+++ b/Source/CParse/templ.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * templ.c
  *
@@ -13,25 +13,35 @@
 
 #include "swig.h"
 #include "cparse.h"
+#include <ctype.h>
 
 static int template_debug = 0;
 
 
 const char *baselists[3];
 
-void SwigType_template_init() {
+void SwigType_template_init(void) {
   baselists[0] = "baselist";
   baselists[1] = "protectedbaselist";
   baselists[2] = "privatebaselist";
 }
 
+void Swig_cparse_debug_templates(int x) {
+  template_debug = x;
+}
+
+/* -----------------------------------------------------------------------------
+ * add_parms()
+ *
+ * Add the value and type of each parameter into patchlist and typelist
+ * (List of String/SwigType) for later template parameter substitutions.
+ * ----------------------------------------------------------------------------- */
 
 static void add_parms(ParmList *p, List *patchlist, List *typelist, int is_pattern) {
   while (p) {
     SwigType *ty = Getattr(p, "type");
     SwigType *val = Getattr(p, "value");
     Append(typelist, ty);
-    Append(typelist, val);
     if (is_pattern) {
       /* Typemap patterns are not simple parameter lists.
        * Output style ("out", "ret" etc) typemap names can be
@@ -44,8 +54,60 @@
   }
 }
 
-void Swig_cparse_debug_templates(int x) {
-  template_debug = x;
+/* -----------------------------------------------------------------------------
+ * expand_variadic_parms()
+ *
+ * Expand variadic parameter in the parameter list stored as attribute in n. For example:
+ *   template <typename... T> struct X : { X(T&... tt); }
+ *   %template(XABC) X<A,B,C>;
+ * inputs for the constructor parameter list will be for attribute = "parms":
+ *   Getattr(n, attribute)   : v.r.T tt
+ *   unexpanded_variadic_parm: v.typename T
+ *   expanded_variadic_parms : A,B,C
+ * results in:
+ *   Getattr(n, attribute)   : r.A,r.B,r.C
+ * that is, template is expanded as: struct XABC : { X(A&,B&,C&); }
+ * Note that there are no parameter names are in the expanded parameter list.
+ * Nothing happens if the parameter list has no variadic parameters.
+ * ----------------------------------------------------------------------------- */
+
+static void expand_variadic_parms(Node *n, const char *attribute, Parm *unexpanded_variadic_parm, ParmList *expanded_variadic_parms) {
+  ParmList *p = Getattr(n, attribute);
+  if (unexpanded_variadic_parm) {
+    Parm *variadic = ParmList_variadic_parm(p);
+    if (variadic) {
+      SwigType *type = Getattr(variadic, "type");
+      String *name = Getattr(variadic, "name");
+      String *unexpanded_name = Getattr(unexpanded_variadic_parm, "name");
+      ParmList *expanded = CopyParmList(expanded_variadic_parms);
+      Parm *ep = expanded;
+      int i = 0;
+      while (ep) {
+	SwigType *newtype = Copy(type);
+	SwigType_del_variadic(newtype);
+	Replaceid(newtype, unexpanded_name, Getattr(ep, "type"));
+	Setattr(ep, "type", newtype);
+	Setattr(ep, "name", name ? NewStringf("%s%d", name, ++i) : 0);
+	ep = nextSibling(ep);
+      }
+      expanded = ParmList_replace_last(p, expanded);
+      Setattr(n, attribute, expanded);
+    }
+  }
+}
+
+/* -----------------------------------------------------------------------------
+ * expand_parms()
+ *
+ * Expand variadic parameters in parameter lists and add parameters to patchlist
+ * and typelist for later template parameter substitutions.
+ * ----------------------------------------------------------------------------- */
+
+static void expand_parms(Node *n, const char *attribute, Parm *unexpanded_variadic_parm, ParmList *expanded_variadic_parms, List *patchlist, List *typelist, int is_pattern) {
+  ParmList *p;
+  expand_variadic_parms(n, attribute, unexpanded_variadic_parm, expanded_variadic_parms);
+  p = Getattr(n, attribute);
+  add_parms(p, patchlist, typelist, is_pattern);
 }
 
 /* -----------------------------------------------------------------------------
@@ -56,7 +118,7 @@
  * template parameters
  * ----------------------------------------------------------------------------- */
 
-static void cparse_template_expand(Node *templnode, Node *n, String *tname, String *rname, String *templateargs, List *patchlist, List *typelist, List *cpatchlist) {
+static void cparse_template_expand(Node *templnode, Node *n, String *tname, String *rname, String *templateargs, List *patchlist, List *typelist, List *cpatchlist, Parm *unexpanded_variadic_parm, ParmList *expanded_variadic_parms) {
   static int expanded = 0;
   String *nodeType;
   if (!n)
@@ -70,7 +132,7 @@
     if (!expanded) {
       expanded = 1;
       set_nodeType(n, Getattr(n, "templatetype"));
-      cparse_template_expand(templnode, n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
+      cparse_template_expand(templnode, n, tname, rname, templateargs, patchlist, typelist, cpatchlist, unexpanded_variadic_parm, expanded_variadic_parms);
       expanded = 0;
       return;
     } else {
@@ -78,7 +140,7 @@
       /* Member templates */
 
       set_nodeType(n, Getattr(n, "templatetype"));
-      cparse_template_expand(templnode, n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
+      cparse_template_expand(templnode, n, tname, rname, templateargs, patchlist, typelist, cpatchlist, unexpanded_variadic_parm, expanded_variadic_parms);
       set_nodeType(n, "template");
       return;
     }
@@ -98,12 +160,13 @@
     Append(cpatchlist, code);
 
     if (Getattr(n, "conversion_operator")) {
+      /* conversion operator "name" and "sym:name" attributes are unusual as they contain c++ types, so treat as code for patching */
       Append(cpatchlist, Getattr(n, "name"));
       if (Getattr(n, "sym:name")) {
 	Append(cpatchlist, Getattr(n, "sym:name"));
       }
     }
-    if (checkAttribute(n, "storage", "friend")) {
+    if (Strstr(Getattr(n, "storage"), "friend")) {
       String *symname = Getattr(n, "sym:name");
       if (symname) {
 	String *stripped_name = SwigType_templateprefix(symname);
@@ -113,8 +176,8 @@
       Append(typelist, Getattr(n, "name"));
     }
 
-    add_parms(Getattr(n, "parms"), cpatchlist, typelist, 0);
-    add_parms(Getattr(n, "throws"), cpatchlist, typelist, 0);
+    expand_parms(n, "parms", unexpanded_variadic_parm, expanded_variadic_parms, cpatchlist, typelist, 0);
+    expand_parms(n, "throws", unexpanded_variadic_parm, expanded_variadic_parms, cpatchlist, typelist, 0);
 
   } else if (Equal(nodeType, "class")) {
     /* Patch base classes */
@@ -127,8 +190,27 @@
 	  int ilen = Len(bases);
 	  for (i = 0; i < ilen; i++) {
 	    String *name = Copy(Getitem(bases, i));
-	    Setitem(bases, i, name);
-	    Append(typelist, name);
+	    if (SwigType_isvariadic(name)) {
+	      Parm *parm = NewParmWithoutFileLineInfo(name, 0);
+	      Node *temp_parm_node = NewHash();
+	      Setattr(temp_parm_node, "variadicbaseparms", parm);
+	      assert(i == ilen - 1);
+	      Delitem(bases, i);
+	      expand_variadic_parms(temp_parm_node, "variadicbaseparms", unexpanded_variadic_parm, expanded_variadic_parms);
+	      {
+		Parm *vp = Getattr(temp_parm_node, "variadicbaseparms");
+		while (vp) {
+		  String *name = Copy(Getattr(vp, "type"));
+		  Append(bases, name);
+		  Append(typelist, name);
+		  vp = nextSibling(vp);
+		}
+	      }
+	      Delete(temp_parm_node);
+	    } else {
+	      Setitem(bases, i, name);
+	      Append(typelist, name);
+	    }
 	  }
 	}
       }
@@ -137,13 +219,57 @@
     {
       Node *cn = firstChild(n);
       while (cn) {
-	cparse_template_expand(templnode, cn, tname, rname, templateargs, patchlist, typelist, cpatchlist);
+	cparse_template_expand(templnode, cn, tname, rname, templateargs, patchlist, typelist, cpatchlist, unexpanded_variadic_parm, expanded_variadic_parms);
 	cn = nextSibling(cn);
       }
     }
   } else if (Equal(nodeType, "constructor")) {
-    String *name = Getattr(n, "name");
     if (!(Getattr(n, "templatetype"))) {
+      String *symname = Getattr(n, "sym:name");
+      String *name;
+      if (symname) {
+	String *stripped_name = SwigType_templateprefix(symname);
+	if (Strstr(tname, stripped_name)) {
+	  Replaceid(symname, stripped_name, tname);
+	}
+	Delete(stripped_name);
+      }
+      name = Getattr(n, "sym:name");
+      if (name) {
+	if (strchr(Char(name), '<')) {
+	  Clear(name);
+	  Append(name, rname);
+	} else {
+	  String *tmp = Copy(name);
+	  Replace(tmp, tname, rname, DOH_REPLACE_ANY);
+	  Clear(name);
+	  Append(name, tmp);
+	  Delete(tmp);
+	}
+      }
+    }
+    Append(cpatchlist, Getattr(n, "code"));
+    Append(typelist, Getattr(n, "decl"));
+    expand_parms(n, "parms", unexpanded_variadic_parm, expanded_variadic_parms, cpatchlist, typelist, 0);
+    expand_parms(n, "throws", unexpanded_variadic_parm, expanded_variadic_parms, cpatchlist, typelist, 0);
+  } else if (Equal(nodeType, "destructor")) {
+    /* We only need to patch the dtor of the template itself, not the destructors of any nested classes, so check that the parent of this node is the root
+     * template node, with the special exception for %extend which adds its methods under an intermediate node. */
+    Node* parent = parentNode(n);
+    if (parent == templnode || (parentNode(parent) == templnode && Equal(nodeType(parent), "extend"))) {
+      String *symname = Getattr(n, "sym:name");
+      if (symname)
+	Replace(symname, tname, rname, DOH_REPLACE_ANY);
+      Append(cpatchlist, Getattr(n, "code"));
+    }
+  } else if (Equal(nodeType, "using")) {
+    String *name = Getattr(n, "name");
+    String *uname = Getattr(n, "uname");
+    if (uname && strchr(Char(uname), '<')) {
+      Append(patchlist, uname);
+    }
+    if (!(Getattr(n, "templatetype"))) {
+      /* Copied from handling "constructor" .. not sure if all this is needed */
       String *symname;
       String *stripped_name = SwigType_templateprefix(name);
       if (Strstr(tname, stripped_name)) {
@@ -160,8 +286,6 @@
       }
       if (strchr(Char(name), '<')) {
 	Append(patchlist, Getattr(n, "name"));
-      } else {
-	Append(name, templateargs);
       }
       name = Getattr(n, "sym:name");
       if (name) {
@@ -176,42 +300,8 @@
 	  Delete(tmp);
 	}
       }
-      /* Setattr(n,"sym:name",name); */
     }
-    Append(cpatchlist, Getattr(n, "code"));
-    Append(typelist, Getattr(n, "decl"));
-    add_parms(Getattr(n, "parms"), cpatchlist, typelist, 0);
-    add_parms(Getattr(n, "throws"), cpatchlist, typelist, 0);
-  } else if (Equal(nodeType, "destructor")) {
-    /* We only need to patch the dtor of the template itself, not the destructors of any nested classes, so check that the parent of this node is the root
-     * template node, with the special exception for %extend which adds its methods under an intermediate node. */
-    Node* parent = parentNode(n);
-    if (parent == templnode || (parentNode(parent) == templnode && Equal(nodeType(parent), "extend"))) {
-      String *name = Getattr(n, "name");
-      if (name) {
-	if (strchr(Char(name), '<'))
-	  Append(patchlist, Getattr(n, "name"));
-	else
-	  Append(name, templateargs);
-      }
-      name = Getattr(n, "sym:name");
-      if (name) {
-	if (strchr(Char(name), '<')) {
-	  String *sn = Copy(tname);
-	  Setattr(n, "sym:name", sn);
-	  Delete(sn);
-	} else {
-	  Replace(name, tname, rname, DOH_REPLACE_ANY);
-	}
-      }
-      /* Setattr(n,"sym:name",name); */
-      Append(cpatchlist, Getattr(n, "code"));
-    }
-  } else if (Equal(nodeType, "using")) {
-    String *uname = Getattr(n, "uname");
-    if (uname && strchr(Char(uname), '<')) {
-      Append(patchlist, uname);
-    }
+
     if (Getattr(n, "namespace")) {
       /* Namespace link.   This is nasty.  Is other namespace defined? */
 
@@ -222,36 +312,141 @@
     Append(cpatchlist, Getattr(n, "code"));
     Append(typelist, Getattr(n, "type"));
     Append(typelist, Getattr(n, "decl"));
-    add_parms(Getattr(n, "parms"), cpatchlist, typelist, 0);
-    add_parms(Getattr(n, "kwargs"), cpatchlist, typelist, 0);
-    add_parms(Getattr(n, "pattern"), cpatchlist, typelist, 1);
-    add_parms(Getattr(n, "throws"), cpatchlist, typelist, 0);
+    expand_parms(n, "parms", unexpanded_variadic_parm, expanded_variadic_parms, cpatchlist, typelist, 0);
+    expand_parms(n, "kwargs", unexpanded_variadic_parm, expanded_variadic_parms, cpatchlist, typelist, 0);
+    expand_parms(n, "pattern", unexpanded_variadic_parm, expanded_variadic_parms, cpatchlist, typelist, 1);
+    expand_parms(n, "throws", unexpanded_variadic_parm, expanded_variadic_parms, cpatchlist, typelist, 0);
     cn = firstChild(n);
     while (cn) {
-      cparse_template_expand(templnode, cn, tname, rname, templateargs, patchlist, typelist, cpatchlist);
+      cparse_template_expand(templnode, cn, tname, rname, templateargs, patchlist, typelist, cpatchlist, unexpanded_variadic_parm, expanded_variadic_parms);
       cn = nextSibling(cn);
     }
   }
 }
 
-static
-String *partial_arg(String *s, String *p) {
-  char *c;
-  char *cp = Char(p);
+/* -----------------------------------------------------------------------------
+ * cparse_fix_function_decl()
+ *
+ * Move the prefix of the "type" attribute (excluding any trailing qualifier)
+ * to the end of the "decl" attribute.
+ * Examples:
+ *   decl="f().", type="p.q(const).char"  => decl="f().p.", type="q(const).char"
+ *   decl="f().p.", type="p.SomeClass"    => decl="f().p.p.", type="SomeClass"
+ *   decl="f().", type="r.q(const).p.int" => decl="f().r.q(const).p.", type="int"
+ * ----------------------------------------------------------------------------- */
+
+static void cparse_fix_function_decl(String *name, SwigType *decl, SwigType *type) {
   String *prefix;
-  String *newarg;
+  int prefixLen;
+  SwigType *last;
 
-  /* Find the prefix on the partial argument */
+  /* The type's prefix is what potentially has to be moved to the end of 'decl' */
+  prefix = SwigType_prefix(type);
 
-  c = strchr(cp, '$');
-  if (!c) {
-    return Copy(s);
+  /* First some parts (qualifier and array) have to be removed from prefix
+     in order to remain in the 'type' attribute. */
+  last = SwigType_last(prefix);
+  while (last) {
+    if (SwigType_isqualifier(last) || SwigType_isarray(last)) {
+      /* Keep this part in the 'type' */
+      Delslice(prefix, Len(prefix) - Len(last), DOH_END);
+      Delete(last);
+      last = SwigType_last(prefix);
+    } else {
+      /* Done with processing prefix */
+      Delete(last);
+      last = 0;
+    }
   }
-  prefix = NewStringWithSize(cp, (int)(c - cp));
-  newarg = Copy(s);
-  Replace(newarg, prefix, "", DOH_REPLACE_ANY | DOH_REPLACE_FIRST);
+
+  /* Transfer prefix from the 'type' to the 'decl' attribute */
+  prefixLen = Len(prefix);
+  if (prefixLen > 0) {
+    Append(decl, prefix);
+    Delslice(type, 0, prefixLen);
+    if (template_debug) {
+      Printf(stdout, "    change function '%s' to type='%s', decl='%s'\n", name, type, decl);
+    }
+  }
+
   Delete(prefix);
-  return newarg;
+}
+
+/* -----------------------------------------------------------------------------
+ * cparse_postprocess_expanded_template()
+ *
+ * This function postprocesses the given node after template expansion.
+ * Currently the only task to perform is fixing function decl and type attributes.
+ * ----------------------------------------------------------------------------- */
+
+static void cparse_postprocess_expanded_template(Node *n) {
+  String *nodeType;
+  if (!n)
+    return;
+  nodeType = nodeType(n);
+  if (Getattr(n, "error"))
+    return;
+
+  if (Equal(nodeType, "cdecl")) {
+    /* A simple C declaration */
+    SwigType *d = Getattr(n, "decl");
+    if (d && SwigType_isfunction(d)) {
+      /* A function node */
+      SwigType *t = Getattr(n, "type");
+      if (t) {
+	String *name = Getattr(n, "name");
+	cparse_fix_function_decl(name, d, t);
+      }
+    }
+  } else {
+    /* Look for any children */
+    Node *cn = firstChild(n);
+    while (cn) {
+      cparse_postprocess_expanded_template(cn);
+      cn = nextSibling(cn);
+    }
+  }
+}
+
+/* -----------------------------------------------------------------------------
+ * partial_arg()
+ *
+ * Return a parameter with type that matches the specialized template argument.
+ * If the input has no partial type, the name is not set in the returned parameter.
+ *
+ * type: an instantiated template parameter type, for example: Vect<(int)>
+ * partialtype: type from specialized template where parameter name has been
+ * replaced by a $ variable, for example: Vect<($1)>
+ *
+ * Returns a parameter of type 'int' and name $1 for the two example parameters above.
+ * ----------------------------------------------------------------------------- */
+
+static Parm *partial_arg(const SwigType *type, const SwigType *partialtype) {
+  SwigType *parmtype;
+  String *parmname = 0;
+  const char *cp = Char(partialtype);
+  const char *c = strchr(cp, '$');
+
+  if (c) {
+    int suffix_length;
+    int prefix_length = (int)(c - cp);
+    int type_length = Len(type);
+    const char *suffix = c;
+    String *prefix = NewStringWithSize(cp, prefix_length);
+    while (++suffix) {
+      if (!isdigit((int)*suffix))
+	break;
+    }
+    parmname = NewStringWithSize(c, (int)(suffix - c)); /* $1, $2 etc */
+    suffix_length = (int)strlen(suffix);
+    assert(Strstr(type, prefix) == Char(type)); /* check that the start of both types match */
+    assert(strcmp(Char(type) + type_length - suffix_length, suffix) == 0); /* check that the end of both types match */
+    parmtype = NewStringWithSize(Char(type) + prefix_length, type_length - suffix_length - prefix_length);
+    Delete(prefix);
+  } else {
+    parmtype = Copy(type);
+  }
+  return NewParmWithoutFileLineInfo(parmtype, parmname);
 }
 
 /* -----------------------------------------------------------------------------
@@ -262,30 +457,29 @@
   List *patchlist, *cpatchlist, *typelist;
   String *templateargs;
   String *tname;
-  String *iname;
+  String *name_with_templateargs = 0;
   String *tbase;
-  patchlist = NewList();
-  cpatchlist = NewList();
-  typelist = NewList();
+  Parm *unexpanded_variadic_parm = 0;
+  ParmList *expanded_variadic_parms = 0;
+  ParmList *templateparms = Getattr(n, "templateparms");
+  ParmList *templateparmsraw = 0;
+  patchlist = NewList();  /* List of String * ("name" and "value" attributes) */
+  cpatchlist = NewList(); /* List of String * (code) */
+  typelist = NewList();   /* List of SwigType * types */
 
-  {
-    String *tmp = NewStringEmpty();
-    if (tparms) {
-      SwigType_add_template(tmp, tparms);
-    }
-    templateargs = Copy(tmp);
-    Delete(tmp);
-  }
+  templateargs = NewStringEmpty();
+  SwigType_add_template(templateargs, tparms);
 
   tname = Copy(Getattr(n, "name"));
   tbase = Swig_scopename_last(tname);
 
-  /* Look for partial specialization matching */
   if (Getattr(n, "partialargs")) {
+    /* Partial specialization */
     Parm *p, *tp;
     ParmList *ptargs = SwigType_function_parms(Getattr(n, "partialargs"), n);
     p = ptargs;
     tp = tparms;
+    /* Adjust templateparms so that the type is expanded, eg typename => int */
     while (p && tp) {
       SwigType *ptype;
       SwigType *tptype;
@@ -293,60 +487,78 @@
       ptype = Getattr(p, "type");
       tptype = Getattr(tp, "type");
       if (ptype && tptype) {
-	partial_type = partial_arg(tptype, ptype);
+	SwigType *ty = Swig_symbol_typedef_reduce(tptype, tscope);
+	Parm *partial_parm = partial_arg(ty, ptype);
+	String *partial_name = Getattr(partial_parm, "name");
+	partial_type = Copy(Getattr(partial_parm, "type"));
 	/*      Printf(stdout,"partial '%s' '%s'  ---> '%s'\n", tptype, ptype, partial_type); */
-	Setattr(tp, "type", partial_type);
+	if (partial_name && strchr(Char(partial_name), '$') == Char(partial_name)) {
+	  int index = atoi(Char(partial_name) + 1) - 1;
+	  Parm *parm;
+	  assert(index >= 0);
+	  parm = ParmList_nth_parm(templateparms, index);
+	  assert(parm);
+	  if (parm) {
+	    Setattr(parm, "type", partial_type);
+	  }
+	}
+	Delete(partial_parm);
 	Delete(partial_type);
+	Delete(ty);
       }
       p = nextSibling(p);
       tp = nextSibling(tp);
     }
-    assert(ParmList_len(ptargs) == ParmList_len(tparms));
     Delete(ptargs);
+  } else {
+    Setattr(n, "templateparmsraw", Getattr(n, "templateparms"));
+    templateparms = CopyParmList(tparms);
+    Setattr(n, "templateparms", templateparms);
   }
 
-  /*
-    Parm *p = tparms;
-    while (p) {
-      Printf(stdout, "tparm: '%s' '%s' '%s'\n", Getattr(p, "name"), Getattr(p, "type"), Getattr(p, "value"));
-      p = nextSibling(p);
-    }
-  */
+  /* TODO: variadic parms for partially specialized templates */
+  templateparmsraw = Getattr(n, "templateparmsraw");
+  unexpanded_variadic_parm = ParmList_variadic_parm(templateparmsraw);
+  if (unexpanded_variadic_parm)
+    expanded_variadic_parms = ParmList_nth_parm(templateparms, ParmList_len(templateparmsraw) - 1);
 
   /*  Printf(stdout,"targs = '%s'\n", templateargs);
      Printf(stdout,"rname = '%s'\n", rname);
      Printf(stdout,"tname = '%s'\n", tname);  */
-  cparse_template_expand(n, n, tname, rname, templateargs, patchlist, typelist, cpatchlist);
+  cparse_template_expand(n, n, tname, rname, templateargs, patchlist, typelist, cpatchlist, unexpanded_variadic_parm, expanded_variadic_parms);
 
   /* Set the name */
   {
     String *name = Getattr(n, "name");
     if (name) {
-      Append(name, templateargs);
+      String *nodeType = nodeType(n);
+      name_with_templateargs = NewStringf("%s%s", name, templateargs);
+      if (!(Equal(nodeType, "constructor") || Equal(nodeType, "destructor"))) {
+	Setattr(n, "name", name_with_templateargs);
+      }
     }
-    iname = name;
   }
 
   /* Patch all of the types */
   {
     Parm *tp = Getattr(n, "templateparms");
-    Parm *p = tparms;
     /*    Printf(stdout,"%s\n", ParmList_str_defaultargs(tp)); */
 
     if (tp) {
       Symtab *tsdecl = Getattr(n, "sym:symtab");
-      while (p && tp) {
+      String *tsname = Getattr(n, "sym:name");
+      while (tp) {
 	String *name, *value, *valuestr, *tmp, *tmpr;
 	int sz, i;
 	String *dvalue = 0;
 	String *qvalue = 0;
 
 	name = Getattr(tp, "name");
-	value = Getattr(p, "value");
+	value = Getattr(tp, "value");
 
 	if (name) {
 	  if (!value)
-	    value = Getattr(p, "type");
+	    value = Getattr(tp, "type");
 	  qvalue = Swig_symbol_typedef_reduce(value, tsdecl);
 	  dvalue = Swig_symbol_type_qualify(qvalue, tsdecl);
 	  if (SwigType_istemplate(dvalue)) {
@@ -357,30 +569,37 @@
 
 	  assert(dvalue);
 	  valuestr = SwigType_str(dvalue, 0);
-	  /* Need to patch default arguments */
-	  {
-	    Parm *rp = nextSibling(p);
-	    while (rp) {
-	      String *rvalue = Getattr(rp, "value");
-	      if (rvalue) {
-		Replace(rvalue, name, dvalue, DOH_REPLACE_ID);
-	      }
-	      rp = nextSibling(rp);
-	    }
-	  }
 	  sz = Len(patchlist);
 	  for (i = 0; i < sz; i++) {
+	    /* Patch String or SwigType with SwigType, eg T => int in Foo<(T)>, or TT => Hello<(int)> in X<(TT)>::meth */
 	    String *s = Getitem(patchlist, i);
 	    Replace(s, name, dvalue, DOH_REPLACE_ID);
 	  }
+
 	  sz = Len(typelist);
 	  for (i = 0; i < sz; i++) {
-	    String *s = Getitem(typelist, i);
-	    /*      Replace(s,name,value, DOH_REPLACE_ID); */
-	    /*      Printf(stdout,"name = '%s', value = '%s', tbase = '%s', iname='%s' s = '%s' --> ", name, dvalue, tbase, iname, s); */
-	    SwigType_typename_replace(s, name, dvalue);
-	    SwigType_typename_replace(s, tbase, iname);
-	    /*      Printf(stdout,"'%s'\n", s); */
+	    SwigType *s = Getitem(typelist, i);
+	    Node *tynode;
+	    String *tyname;
+
+	    SwigType_variadic_replace(s, unexpanded_variadic_parm, expanded_variadic_parms);
+
+	    /*
+	      The approach of 'trivially' replacing template arguments is kind of fragile.
+	      In particular if types with similar name in different namespaces appear.
+	      We will not replace template args if a type/class exists with the same
+	      name which is not a template.
+	    */
+	    tynode = Swig_symbol_clookup(s, 0);
+	    tyname  = tynode ? Getattr(tynode, "sym:name") : 0;
+	    /*
+	    Printf(stdout, "  replacing %s with %s to %s or %s to %s\n", s, name, dvalue, tbase, name_with_templateargs);
+	    Printf(stdout, "    %d %s to %s\n", tp == unexpanded_variadic_parm, name, ParmList_str_defaultargs(expanded_variadic_parms));
+	    */
+	    if (!tyname || !tsname || !Equal(tyname, tsname) || Getattr(tynode, "templatetype")) {
+	      SwigType_typename_replace(s, name, dvalue);
+	      SwigType_typename_replace(s, tbase, name_with_templateargs);
+	    }
 	  }
 
 	  tmp = NewStringf("#%s", name);
@@ -388,7 +607,9 @@
 
 	  sz = Len(cpatchlist);
 	  for (i = 0; i < sz; i++) {
+	    /* Patch String with C++ String type, eg T => int in Foo< T >, or TT => Hello< int > in X< TT >::meth */
 	    String *s = Getitem(cpatchlist, i);
+	    /* Stringising that ought to be done in the preprocessor really, eg #T => "int" */
 	    Replace(s, tmp, tmpr, DOH_REPLACE_ID);
 	    Replace(s, name, valuestr, DOH_REPLACE_ID);
 	  }
@@ -398,10 +619,7 @@
 	  Delete(dvalue);
 	  Delete(qvalue);
 	}
-	p = nextSibling(p);
 	tp = nextSibling(tp);
-	if (!p)
-	  p = tp;
       }
     } else {
       /* No template parameters at all.  This could be a specialization */
@@ -409,10 +627,12 @@
       sz = Len(typelist);
       for (i = 0; i < sz; i++) {
 	String *s = Getitem(typelist, i);
-	SwigType_typename_replace(s, tbase, iname);
+	SwigType_variadic_replace(s, unexpanded_variadic_parm, expanded_variadic_parms);
+	SwigType_typename_replace(s, tbase, name_with_templateargs);
       }
     }
   }
+  cparse_postprocess_expanded_template(n);
 
   /* Patch bases */
   {
@@ -427,6 +647,7 @@
       }
     }
   }
+  Delete(name_with_templateargs);
   Delete(patchlist);
   Delete(cpatchlist);
   Delete(typelist);
@@ -434,70 +655,148 @@
   Delete(tname);
   Delete(templateargs);
 
-  /*  set_nodeType(n,"template"); */
   return 0;
 }
 
 typedef enum { ExactNoMatch = -2, PartiallySpecializedNoMatch = -1, PartiallySpecializedMatch = 1, ExactMatch = 2 } EMatch;
 
 /* -----------------------------------------------------------------------------
+ * is_exact_partial_type()
+ *
+ * Return 1 if parm matches $1, $2, $3 etc exactly without any other prefixes or
+ * suffixes. Return 0 otherwise.
+ * ----------------------------------------------------------------------------- */
+
+static int is_exact_partial_type(const SwigType *type) {
+  const char *c = Char(type);
+  int is_exact = 0;
+  if (*c == '$' && isdigit((int)*(c + 1))) {
+    const char *suffix = c + 1;
+    while (++suffix) {
+      if (!isdigit((int)*suffix))
+	break;
+    }
+    is_exact = (*suffix == 0);
+  }
+  return is_exact;
+}
+
+/* -----------------------------------------------------------------------------
  * does_parm_match()
  *
- * Template argument deduction - check if a template type matches a partially specialized 
+ * Template argument deduction - check if a template type matches a partially specialized
  * template parameter type. Typedef reduce 'partial_parm_type' to see if it matches 'type'.
  *
  * type - template parameter type to match against
- * partial_parm_type - partially specialized template type - a possible match
- * partial_parm_type_base - base type of partial_parm_type
+ * partial_parm_type - specialized template type, for example, r.$1 (partially specialized) or r.int (fully specialized)
  * tscope - template scope
- * specialization_priority - (output) contains a value indicating how good the match is 
+ * specialization_priority - (output) contains a value indicating how good the match is
  *   (higher is better) only set if return is set to PartiallySpecializedMatch or ExactMatch.
  * ----------------------------------------------------------------------------- */
 
-static EMatch does_parm_match(SwigType *type, SwigType *partial_parm_type, const char *partial_parm_type_base, Symtab *tscope, int *specialization_priority) {
+static EMatch does_parm_match(SwigType *type, SwigType *partial_parm_type, Symtab *tscope, int *specialization_priority) {
   static const int EXACT_MATCH_PRIORITY = 99999; /* a number bigger than the length of any conceivable type */
-  int matches;
-  int substitutions;
-  EMatch match;
+  static const int TEMPLATE_MATCH_PRIORITY = 1000; /* a priority added for each nested template, assumes max length of any prefix, such as r.q(const). , is less than this number */
   SwigType *ty = Swig_symbol_typedef_reduce(type, tscope);
-  String *base = SwigType_base(ty);
-  SwigType *t = Copy(partial_parm_type);
-  substitutions = Replaceid(t, partial_parm_type_base, base); /* eg: Replaceid("p.$1", "$1", "int") returns t="p.int" */
-  matches = Equal(ty, t);
+  SwigType *pp_prefix = SwigType_prefix(partial_parm_type);
+  int pp_len = Len(pp_prefix);
+  EMatch match = Strchr(partial_parm_type, '$') == 0 ? ExactNoMatch : PartiallySpecializedNoMatch;
   *specialization_priority = -1;
-  if (substitutions == 1) {
-    /* we have a non-explicit specialized parameter (in partial_parm_type) because a substitution for $1, $2... etc has taken place */
-    SwigType *tt = Copy(partial_parm_type);
-    int len;
-    /*
-       check for match to partial specialization type, for example, all of the following could match the type in the %template:
-       template <typename T> struct XX {};
-       template <typename T> struct XX<T &> {};         // r.$1
-       template <typename T> struct XX<T const&> {};    // r.q(const).$1
-       template <typename T> struct XX<T *const&> {};   // r.q(const).p.$1
-       %template(XXX) XX<int *const&>;                  // r.q(const).p.int
 
-       where type="r.q(const).p.int" will match either of tt="r.", tt="r.q(const)" tt="r.q(const).p"
-    */
-    Replaceid(tt, partial_parm_type_base, ""); /* remove the $1, $2 etc, eg tt="p.$1" => "p." */
-    len = Len(tt);
-    if (Strncmp(tt, ty, len) == 0) {
+  if (Equal(ty, partial_parm_type)) {
+    match = ExactMatch;
+    *specialization_priority = EXACT_MATCH_PRIORITY; /* exact matches always take precedence */
+  } else if (match == PartiallySpecializedNoMatch) {
+    if ((pp_len > 0 && Strncmp(ty, pp_prefix, pp_len) == 0)) {
+      /*
+	 Type starts with pp_prefix, so it is a partial specialization type match, for example,
+	 all of the following could match the type in the %template:
+	   template <typename T> struct XX {};
+	   template <typename T> struct XX<T &> {};         // r.$1
+	   template <typename T> struct XX<T const&> {};    // r.q(const).$1
+	   template <typename T> struct XX<T *const&> {};   // r.q(const).p.$1
+	   %template(XXX) XX<int *const&>;                  // r.q(const).p.int
+	 where type="r.q(const).p.int" will match either of pp_prefix="r.", pp_prefix="r.q(const)." pp_prefix="r.q(const).p."
+      */
       match = PartiallySpecializedMatch;
-      *specialization_priority = len;
+      *specialization_priority = pp_len;
+    } else if (pp_len == 0 && is_exact_partial_type(partial_parm_type)) {
+      /*
+	 Type without a prefix match, as in $1 for int
+	   template <typename T, typename U> struct XX {};
+	   template <typename T, typename U> struct XX<T, U &> {};  // $1,r.$2
+	   %template(XXX) XX<int, double&>;                         // int,r.double
+       */
+      match = PartiallySpecializedMatch;
+      *specialization_priority = pp_len;
     } else {
-      match = PartiallySpecializedNoMatch;
+      /*
+	Check for template types that are templates such as
+	  template<typename V> struct Vect {};
+	  template<typename T> class XX {};
+	  template<class TT> class XX<Vect<TT>> {};
+	  %template(XXVectInt) XX<Vect<int>>;
+	matches type="Vect<(int)>" and partial_parm_type="Vect<($1)>"
+       */
+      if (SwigType_istemplate(partial_parm_type) && SwigType_istemplate(ty)) {
+
+	SwigType *qt = Swig_symbol_typedef_reduce(ty, tscope);
+	String *tsuffix = SwigType_templatesuffix(qt);
+
+	SwigType *pp_qt = Swig_symbol_typedef_reduce(partial_parm_type, tscope);
+	String *pp_tsuffix = SwigType_templatesuffix(pp_qt);
+
+	if (Equal(tsuffix, pp_tsuffix) && Len(tsuffix) == 0) {
+	  String *tprefix = SwigType_templateprefix(qt);
+	  String *qprefix = SwigType_typedef_qualified(tprefix);
+
+	  String *pp_tprefix = SwigType_templateprefix(pp_qt);
+	  String *pp_qprefix = SwigType_typedef_qualified(pp_tprefix);
+
+	  if (Equal(qprefix, pp_qprefix)) {
+	    String *templateargs = SwigType_templateargs(qt);
+	    List *parms = SwigType_parmlist(templateargs);
+	    Iterator pi = First(parms);
+	    Parm *p = pi.item;
+
+	    String *pp_templateargs = SwigType_templateargs(pp_qt);
+	    List *pp_parms = SwigType_parmlist(pp_templateargs);
+	    Iterator pp_pi = First(pp_parms);
+	    Parm *pp = pp_pi.item;
+
+	    if (p && pp) {
+	      /* Implementation is limited to matching single parameter templates only for now */
+	      int priority;
+	      match = does_parm_match(p, pp, tscope, &priority);
+	      if (match <= PartiallySpecializedNoMatch) {
+		*specialization_priority = priority;
+	      } else {
+		*specialization_priority = priority + TEMPLATE_MATCH_PRIORITY;
+	      }
+	    }
+
+	    Delete(pp_parms);
+	    Delete(pp_templateargs);
+	    Delete(parms);
+	    Delete(templateargs);
+	  }
+
+	  Delete(pp_qprefix);
+	  Delete(pp_tprefix);
+	  Delete(qprefix);
+	  Delete(tprefix);
+	}
+
+	Delete(pp_tsuffix);
+	Delete(pp_qt);
+	Delete(tsuffix);
+	Delete(qt);
+      }
     }
-    Delete(tt);
-  } else {
-    match = matches ? ExactMatch : ExactNoMatch;
-    if (matches)
-      *specialization_priority = EXACT_MATCH_PRIORITY; /* exact matches always take precedence */
   }
   /*
   Printf(stdout, "      does_parm_match %2d %5d [%s] [%s]\n", match, *specialization_priority, type, partial_parm_type);
   */
-  Delete(t);
-  Delete(base);
   Delete(ty);
   return match;
 }
@@ -508,7 +807,7 @@
  * Search for a template that matches name with given parameters.
  * ----------------------------------------------------------------------------- */
 
-static Node *template_locate(String *name, Parm *tparms, Symtab *tscope) {
+static Node *template_locate(String *name, Parm *instantiated_parms, String *symname, Symtab *tscope) {
   Node *n = 0;
   String *tname = 0;
   Node *templ;
@@ -522,21 +821,29 @@
   int max_possible_partials = 0;
   int posslen = 0;
 
-  /* Search for primary (unspecialized) template */
-  templ = Swig_symbol_clookup(name, 0);
-
   if (template_debug) {
     tname = Copy(name);
-    SwigType_add_template(tname, tparms);
+    SwigType_add_template(tname, instantiated_parms);
     Printf(stdout, "\n");
-    Swig_diagnostic(cparse_file, cparse_line, "template_debug: Searching for match to: '%s'\n", tname);
+    if (symname)
+      Swig_diagnostic(cparse_file, cparse_line, "Template debug: Searching for match to: '%s' for instantiation of template named '%s'\n", tname, symname);
+    else
+      Swig_diagnostic(cparse_file, cparse_line, "Template debug: Searching for match to: '%s' for instantiation of empty template\n", tname);
     Delete(tname);
     tname = 0;
   }
 
+  /* Search for primary (unspecialized) template */
+  templ = Swig_symbol_clookup(name, 0);
+
   if (templ) {
+    /* TODO: check that this is not a specialization (might be a user error specializing a template before a primary template), but note https://stackoverflow.com/questions/9757642/wrapping-specialised-c-template-class-with-swig */
+    if (template_debug) {
+      Printf(stdout, "    found primary template <%s> '%s'\n", ParmList_str_defaultargs(Getattr(templ, "templateparms")), Getattr(templ, "name"));
+    }
+
     tname = Copy(name);
-    parms = CopyParmList(tparms);
+    parms = CopyParmList(instantiated_parms);
 
     /* All template specializations must be in the primary template's scope, store the symbol table for this scope for specialization lookups */
     primary_scope = Getattr(templ, "sym:symtab");
@@ -545,7 +852,7 @@
     targs = Getattr(templ, "templateparms");
     expandedparms = Swig_symbol_template_defargs(parms, targs, tscope, primary_scope);
 
-    /* reduce the typedef */
+    /* Qualify template parameters */
     p = expandedparms;
     while (p) {
       SwigType *ty = Getattr(p, "type");
@@ -585,11 +892,39 @@
 	}
 	tn = Getattr(n, "template");
 	if (tn) {
-	  if (template_debug) {
-	    Printf(stdout, "    previous instantiation found: '%s'\n", Getattr(n, "name"));
+	  /* Previously wrapped by a template instantiation */
+	  Node *previous_named_instantiation = GetFlag(n, "hidden") ? Getattr(n, "csym:nextSibling") : n; /* "hidden" is set when "sym:name" is a __dummy_ name */
+	  if (!symname) {
+	    /* Quietly ignore empty template instantiations if there is a previous (empty or non-empty) template instantiation */
+	    if (template_debug) {
+	      if (previous_named_instantiation)
+		Printf(stdout, "    previous instantiation with name '%s' found: '%s' - duplicate empty template instantiation ignored\n", Getattr(previous_named_instantiation, "sym:name"), Getattr(n, "name"));
+	      else
+		Printf(stdout, "    previous empty template instantiation found: '%s' - duplicate empty template instantiation ignored\n", Getattr(n, "name"));
+	    }
+	    return 0;
 	  }
+	  /* Accept a second instantiation only if previous template instantiation is empty */
+	  if (previous_named_instantiation) {
+	    String *previous_name = Getattr(previous_named_instantiation, "name");
+	    String *previous_symname = Getattr(previous_named_instantiation, "sym:name");
+	    String *unprocessed_tname = Copy(name);
+	    SwigType_add_template(unprocessed_tname, instantiated_parms);
+
+	    if (template_debug)
+	      Printf(stdout, "    previous instantiation with name '%s' found: '%s' - duplicate instantiation ignored\n", previous_symname, Getattr(n, "name"));
+	    SWIG_WARN_NODE_BEGIN(n);
+	    Swig_warning(WARN_TYPE_REDEFINED, cparse_file, cparse_line, "Duplicate template instantiation of '%s' with name '%s' ignored,\n", SwigType_namestr(unprocessed_tname), symname);
+	    Swig_warning(WARN_TYPE_REDEFINED, Getfile(n), Getline(n), "previous instantiation of '%s' with name '%s'.\n", SwigType_namestr(previous_name), previous_symname);
+	    SWIG_WARN_NODE_END(n);
+
+	    Delete(unprocessed_tname);
+	    return 0;
+	  }
+	  if (template_debug)
+	    Printf(stdout, "    previous empty template instantiation found: '%s' - using as duplicate instantiation overrides empty template instantiation\n", Getattr(n, "name"));
 	  n = tn;
-	  goto success;	  /* Previously wrapped by a template instantiation */
+	  goto success;
 	}
 	Swig_error(cparse_file, cparse_line, "'%s' is not defined as a template. (%s)\n", name, nodeType(n));
 	Delete(tname);
@@ -611,20 +946,18 @@
     /* Rank each template parameter against the desired template parameters then build a matrix of best matches */
     possiblepartials = NewList();
     {
-      char tmp[32];
       List *partials;
 
       partials = Getattr(templ, "partials"); /* note that these partial specializations do not include explicit specializations */
       if (partials) {
 	Iterator pi;
-	int parms_len = ParmList_len(parms);
+	int parms_len = ParmList_len(parms); /* max parameters including defaulted parameters from primary template (ie max parameters) */
 	int *priorities_row;
 	max_possible_partials = Len(partials);
-	priorities_matrix = (int *)malloc(sizeof(int) * max_possible_partials * parms_len); /* slightly wasteful allocation for max possible matches */
+	priorities_matrix = (int *)Malloc(sizeof(int) * max_possible_partials * parms_len); /* slightly wasteful allocation for max possible matches */
 	priorities_row = priorities_matrix;
 	for (pi = First(partials); pi.item; pi = Next(pi)) {
 	  Parm *p = parms;
-	  int all_parameters_match = 1;
 	  int i = 1;
 	  Parm *partialparms = Getattr(pi.item, "partialparms");
 	  Parm *pp = partialparms;
@@ -633,14 +966,14 @@
 	    Printf(stdout, "    checking match: '%s' (partial specialization)\n", templcsymname);
 	  }
 	  if (ParmList_len(partialparms) == parms_len) {
+	    int all_parameters_match = 1;
 	    while (p && pp) {
 	      SwigType *t;
-	      sprintf(tmp, "$%d", i);
 	      t = Getattr(p, "type");
 	      if (!t)
 		t = Getattr(p, "value");
 	      if (t) {
-		EMatch match = does_parm_match(t, Getattr(pp, "type"), tmp, tscope, priorities_row + i - 1);
+		EMatch match = does_parm_match(t, Getattr(pp, "type"), tscope, priorities_row + i - 1);
 		if (match < (int)PartiallySpecializedMatch) {
 		  all_parameters_match = 0;
 		  break;
@@ -684,9 +1017,10 @@
        *   T
        *
        *   An ambiguous example when attempting to match as either specialization could match: %template() X<int *, double *>;
-       *   template<typename T1, typename T2> X class {};  // primary template
-       *   template<typename T1> X<T1, double *> class {}; // specialization (1)
-       *   template<typename T2> X<int *, T2> class {};    // specialization (2)
+       *   template<typename T1, typename T2> class X {};  // primary template
+       *   template<typename T1> class X<T1, double *> {}; // specialization (1)
+       *   template<typename T2> class X<int *, T2> {};    // specialization (2)
+       *
        */
       if (template_debug) {
 	int row, col;
@@ -818,7 +1152,7 @@
     Printf(stdout, "    chosen template:'%s'\n", Getattr(n, "name"));
   }
   Delete(parms);
-  free(priorities_matrix);
+  Free(priorities_matrix);
   return n;
 }
 
@@ -826,53 +1160,263 @@
 /* -----------------------------------------------------------------------------
  * Swig_cparse_template_locate()
  *
- * Search for a template that matches name with given parameters.
- * For templated classes finds the specialized template should there be one.
- * For templated functions finds the unspecialized template even if a specialized
- * template exists.
+ * Search for a template that matches name with given parameters and mark it for instantiation.
+ * For class templates marks the specialized template should there be one.
+ * For function templates marks all the unspecialized templates even if specialized
+ * templates exists.
  * ----------------------------------------------------------------------------- */
 
-Node *Swig_cparse_template_locate(String *name, Parm *tparms, Symtab *tscope) {
-  Node *n = template_locate(name, tparms, tscope);	/* this function does what we want for templated classes */
+Node *Swig_cparse_template_locate(String *name, Parm *instantiated_parms, String *symname, Symtab *tscope) {
+  Node *match = 0;
+  Node *n = template_locate(name, instantiated_parms, symname, tscope); /* this function does what we want for class templates */
 
   if (n) {
     String *nodeType = nodeType(n);
     int isclass = 0;
     assert(Equal(nodeType, "template"));
+    (void)nodeType;
     isclass = (Equal(Getattr(n, "templatetype"), "class"));
-    if (!isclass) {
-      /* If not a templated class we must have a templated function.
+
+    if (isclass) {
+      Node *primary = Getattr(n, "primarytemplate");
+      Parm *tparmsfound = Getattr(primary ? primary : n, "templateparms");
+      int specialized = !tparmsfound; /* fully specialized (an explicit specialization) */
+      int variadic = ParmList_variadic_parm(tparmsfound) != 0;
+      match = n;
+      if (!specialized) {
+	if (!variadic && (ParmList_len(instantiated_parms) > ParmList_len(tparmsfound))) {
+	  Swig_error(cparse_file, cparse_line, "Too many template parameters. Maximum of %d.\n", ParmList_len(tparmsfound));
+	  match = 0;
+	} else if (ParmList_len(instantiated_parms) < ParmList_numrequired(tparmsfound) - (variadic ? 1 : 0)) { /* Variadic parameter is optional */
+	  Swig_error(cparse_file, cparse_line, "Not enough template parameters specified. Minimum of %d required.\n", (ParmList_numrequired(tparmsfound) - (variadic ? 1 : 0)) );
+	  match = 0;
+	}
+      }
+      if (match)
+	SetFlag(n, "instantiate");
+    } else {
+      Node *firstn = 0;
+      /* If not a class template we must have a function template.
          The template found is not necessarily the one we want when dealing with templated
-         functions. We don't want any specialized templated functions as they won't have
+         functions. We don't want any specialized function templates as they won't have
          the default parameters. Let's look for the unspecialized template. Also make sure
          the number of template parameters is correct as it is possible to overload a
-         templated function with different numbers of template parameters. */
+         function template with different numbers of template parameters. */
 
       if (template_debug) {
-	Printf(stdout, "    Not a templated class, seeking most appropriate templated function\n");
+	Printf(stdout, "    Not a class template, seeking all appropriate primary function templates\n");
       }
 
-      n = Swig_symbol_clookup_local(name, 0);
+      firstn = Swig_symbol_clookup_local(name, 0);
+      n = firstn;
+      /* First look for all overloaded functions (non-variadic) template matches.
+       * Looking for all template parameter matches only (not function parameter matches) 
+       * as %template instantiation uses template parameters without any function parameters. */
       while (n) {
-	Parm *tparmsfound = Getattr(n, "templateparms");
-	if (ParmList_len(tparms) == ParmList_len(tparmsfound)) {
-	  /* successful match */
-	  break;
+	if (Strcmp(nodeType(n), "template") == 0) {
+	  Parm *tparmsfound = Getattr(n, "templateparms");
+	  if (!ParmList_variadic_parm(tparmsfound)) {
+	    if (ParmList_len(instantiated_parms) == ParmList_len(tparmsfound)) {
+	      /* successful match */
+	      if (template_debug) {
+		Printf(stdout, "    found: template <%s> '%s' (%s)\n", ParmList_str_defaultargs(Getattr(n, "templateparms")), name, ParmList_str_defaultargs(Getattr(n, "parms")));
+	      }
+	      SetFlag(n, "instantiate");
+	      if (!match)
+		match = n; /* first match */
+	    }
+	  }
 	}
-	/* repeat until we find a match with correct number of templated parameters */
+	/* repeat to find all matches with correct number of templated parameters */
 	n = Getattr(n, "sym:nextSibling");
       }
 
-      if (!n) {
-	Swig_error(cparse_file, cparse_line, "Template '%s' undefined.\n", name);
+      /* Only consider variadic templates if there are no non-variadic template matches */
+      if (!match) {
+	n = firstn;
+	while (n) {
+	  if (Strcmp(nodeType(n), "template") == 0) {
+	    Parm *tparmsfound = Getattr(n, "templateparms");
+	    if (ParmList_variadic_parm(tparmsfound)) {
+	      if (ParmList_len(instantiated_parms) >= ParmList_len(tparmsfound) - 1) {
+		/* successful variadic match */
+		if (template_debug) {
+		  Printf(stdout, "    found: template <%s> '%s' (%s)\n", ParmList_str_defaultargs(Getattr(n, "templateparms")), name, ParmList_str_defaultargs(Getattr(n, "parms")));
+		}
+		SetFlag(n, "instantiate");
+		if (!match)
+		  match = n; /* first match */
+	      }
+	    }
+	  }
+	  /* repeat to find all matches with correct number of templated parameters */
+	  n = Getattr(n, "sym:nextSibling");
+	}
       }
 
-      if ((template_debug) && (n)) {
-	Printf(stdout, "Templated function found: %p\n", n);
-	Swig_print_node(n);
+      if (!match) {
+	Swig_error(cparse_file, cparse_line, "No matching function template '%s' found.\n", name);
       }
     }
   }
 
-  return n;
+  return match;
+}
+
+/* -----------------------------------------------------------------------------
+ * merge_parameters()
+ *
+ * expanded_templateparms are the template parameters passed to %template.
+ * This function adds missing parameter name and type attributes from the chosen
+ * template (templateparms).
+ *
+ * Grab the parameter names from templateparms.
+ * Non-type template parameters have no type information in expanded_templateparms.
+ * Grab them from templateparms.
+ *
+ * Return 1 if there are variadic template parameters, 0 otherwise.
+ * ----------------------------------------------------------------------------- */
+
+static int merge_parameters(ParmList *expanded_templateparms, ParmList *templateparms) {
+  Parm *p = expanded_templateparms;
+  Parm *tp = templateparms;
+  while (p && tp) {
+    Setattr(p, "name", Getattr(tp, "name"));
+    if (!Getattr(p, "type"))
+      Setattr(p, "type", Getattr(tp, "type"));
+    p = nextSibling(p);
+    tp = nextSibling(tp);
+  }
+  return ParmList_variadic_parm(templateparms) ? 1 : 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * use_mark_defaults()
+ *
+ * Mark and use all the template parameters that are expanded from a default value
+ * ----------------------------------------------------------------------------- */
+
+static void use_mark_defaults(ParmList *defaults) {
+  Parm *tp = defaults;
+  while (tp) {
+    Setattr(tp, "default", "1");
+    Setattr(tp, "type", Getattr(tp, "value"));
+    tp = nextSibling(tp);
+  }
+}
+
+/* -----------------------------------------------------------------------------
+ * use_mark_specialized_defaults()
+ *
+ * Modify extra defaulted parameters ready for adding to specialized template parameters list
+ * ----------------------------------------------------------------------------- */
+
+static void use_mark_specialized_defaults(ParmList *defaults) {
+  Parm *tp = defaults;
+  while (tp) {
+    Setattr(tp, "default", "1");
+    Setattr(tp, "type", Getattr(tp, "value"));
+    Delattr(tp, "name");
+    tp = nextSibling(tp);
+  }
+}
+
+/* -----------------------------------------------------------------------------
+ * expand_defaults()
+ *
+ * Replace parameter types in default argument values, example:
+ * input:  int K,int T,class C=Less<(K)>
+ * output: int K,int T,class C=Less<(int)>
+ * ----------------------------------------------------------------------------- */
+
+static void expand_defaults(ParmList *expanded_templateparms) {
+  Parm *tp = expanded_templateparms;
+  while (tp) {
+    Parm *p = expanded_templateparms;
+    String *tv = Getattr(tp, "value");
+    if (!tv)
+      tv = Getattr(tp, "type");
+    while(p) {
+      String *name = Getattr(p, "name");
+      String *value = Getattr(p, "value");
+      if (!value)
+	value = Getattr(p, "type");
+      if (name)
+	Replaceid(tv, name, value);
+      p = nextSibling(p);
+    }
+    tp = nextSibling(tp);
+  }
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_cparse_template_parms_expand()
+ *
+ * instantiated_parms: template parameters passed to %template
+ * primary: primary template node
+ *
+ * Expand the instantiated_parms and return a parameter list with default
+ * arguments filled in where necessary.
+ * ----------------------------------------------------------------------------- */
+
+ParmList *Swig_cparse_template_parms_expand(ParmList *instantiated_parms, Node *primary, Node *templ) {
+  ParmList *expanded_templateparms = CopyParmList(instantiated_parms);
+
+  if (Equal(Getattr(primary, "templatetype"), "class")) {
+    /* Class template */
+    ParmList *templateparms = Getattr(primary, "templateparms");
+    int variadic = merge_parameters(expanded_templateparms, templateparms);
+    /* Add default arguments from primary template */
+    if (!variadic) {
+      ParmList *defaults_start = ParmList_nth_parm(templateparms, ParmList_len(instantiated_parms));
+      if (defaults_start) {
+	ParmList *defaults = CopyParmList(defaults_start);
+	use_mark_defaults(defaults);
+	expanded_templateparms = ParmList_join(expanded_templateparms, defaults);
+	expand_defaults(expanded_templateparms);
+      }
+    }
+  } else {
+    /* Function template */
+    /* TODO: Default template parameters support was only added in C++11 */
+    ParmList *templateparms = Getattr(templ, "templateparms");
+    merge_parameters(expanded_templateparms, templateparms);
+  }
+
+  return expanded_templateparms;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_cparse_template_partialargs_expand()
+ *
+ * partially_specialized_parms: partially specialized template parameters
+ * primary: primary template node
+ * templateparms: primary template parameters (providing the defaults)
+ *
+ * Expand the partially_specialized_parms and return a parameter list with default
+ * arguments filled in where necessary.
+ * ----------------------------------------------------------------------------- */
+
+ParmList *Swig_cparse_template_partialargs_expand(ParmList *partially_specialized_parms, Node *primary, ParmList *templateparms) {
+  ParmList *expanded_templateparms = CopyParmList(partially_specialized_parms);
+
+  if (Equal(Getattr(primary, "templatetype"), "class")) {
+    /* Class template */
+    int variadic = ParmList_variadic_parm(templateparms) ? 1 : 0;
+    /* Add default arguments from primary template */
+    if (!variadic) {
+      ParmList *defaults_start = ParmList_nth_parm(templateparms, ParmList_len(partially_specialized_parms));
+      if (defaults_start) {
+	ParmList *defaults = CopyParmList(defaults_start);
+	use_mark_specialized_defaults(defaults);
+	expanded_templateparms = ParmList_join(expanded_templateparms, defaults);
+	expand_defaults(expanded_templateparms);
+      }
+    }
+  } else {
+    /* Function template */
+    /* TODO: Default template parameters support was only added in C++11 */
+  }
+
+  return expanded_templateparms;
 }
diff --git a/Source/CParse/util.c b/Source/CParse/util.c
index 714bb29..00863c0 100644
--- a/Source/CParse/util.c
+++ b/Source/CParse/util.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * util.c
  *
diff --git a/Source/DOH/README b/Source/DOH/README
index 8be5f65..be90f25 100644
--- a/Source/DOH/README
+++ b/Source/DOH/README
@@ -73,11 +73,17 @@
 Chop(obj)                       Remove trailing whitespace
 
 flags is one of the following:
-     DOH_REPLACE_ANY
-     DOH_REPLACE_NOQUOTE
-     DOH_REPLACE_ID
-     DOH_REPLACE_FIRST
-             
+    DOH_REPLACE_ID
+    DOH_REPLACE_ID_BEGIN
+    DOH_REPLACE_ID_END
+    DOH_REPLACE_NUMBER_END
+
+and can be combined with one or more of the following:
+    DOH_REPLACE_ANY
+    DOH_REPLACE_NOQUOTE
+    DOH_REPLACE_NOCOMMENT
+    DOH_REPLACE_FIRST
+
 Callable Operations
 -------------------
 Call(obj, args)                 Perform a function call with arguments args.
diff --git a/Source/DOH/base.c b/Source/DOH/base.c
index f5e4188..8731a5f 100644
--- a/Source/DOH/base.c
+++ b/Source/DOH/base.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * base.c 
  *
@@ -18,10 +18,6 @@
  * DohDelete()
  * ----------------------------------------------------------------------------- */
 
-#ifndef SWIG_DEBUG_DELETE
-#define SWIG_DEBUG_DELETE 0
-#endif
-
 void DohDelete(DOH *obj) {
   DohBase *b = (DohBase *) obj;
   DohObjInfo *objinfo;
@@ -29,13 +25,8 @@
   if (!obj)
     return;
   if (!DohCheck(b)) {
-#if SWIG_DEBUG_DELETE
-    fputs("DOH: Fatal error. Attempt to delete a non-doh object.\n", stderr);
-    abort();
-#else
-    assert(0);
-#endif
-    return;
+    fputs("Fatal internal error: Attempt to delete a non-DOH object.\n", stderr);
+    Exit(EXIT_FAILURE);
   }
   if (b->flag_intern)
     return;
@@ -64,13 +55,8 @@
   if (!obj)
     return 0;
   if (!DohCheck(b)) {
-#if SWIG_DEBUG_DELETE
-    fputs("DOH: Fatal error. Attempt to copy a non-doh object.\n", stderr);
-    abort();
-#else
-    assert(0);
-#endif
-    return 0;
+    fputs("Fatal internal error: Attempt to copy a non-DOH object.\n", stderr);
+    Exit(EXIT_FAILURE);
   }
   objinfo = b->type;
   if (objinfo->doh_copy) {
@@ -389,6 +375,18 @@
 }
 
 /* -----------------------------------------------------------------------------
+ * DohSortedKeys()
+ * ----------------------------------------------------------------------------- */
+
+DOH *DohSortedKeys(DOH *obj, int (*cmp) (const DOH *, const DOH *)) {
+  DOHList *keys = DohKeys(obj);
+  if (keys) {
+    DohSortList(keys, cmp);
+  }
+  return keys;
+}
+
+/* -----------------------------------------------------------------------------
  * DohGetInt()
  * ----------------------------------------------------------------------------- */
 
diff --git a/Source/DOH/doh.h b/Source/DOH/doh.h
index 7fb64c0..45a1f7f 100644
--- a/Source/DOH/doh.h
+++ b/Source/DOH/doh.h
@@ -4,22 +4,21 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * doh.h
  *
  *     This file describes of the externally visible functions in DOH.
  * ----------------------------------------------------------------------------- */
 
-#ifndef _DOH_H
-#define _DOH_H
+#ifndef SWIG_DOH_H
+#define SWIG_DOH_H
 
-#ifndef MACSWIG
 #include "swigconfig.h"
-#endif
 
-#include <stdio.h>
 #include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
 
 /* Set the namespace prefix for DOH API functions. This can be used to control
    visibility of the functions in libraries */
@@ -53,6 +52,7 @@
 #define DohSetattr         DOH_NAMESPACE(Setattr)
 #define DohDelattr         DOH_NAMESPACE(Delattr)
 #define DohKeys            DOH_NAMESPACE(Keys)
+#define DohSortedKeys      DOH_NAMESPACE(SortedKeys)
 #define DohGetInt          DOH_NAMESPACE(GetInt)
 #define DohGetDouble       DOH_NAMESPACE(GetDouble)
 #define DohGetChar         DOH_NAMESPACE(GetChar)
@@ -122,6 +122,12 @@
 #define DohIterator        DOH_NAMESPACE(Iterator)
 #define DohFirst           DOH_NAMESPACE(First)
 #define DohNext            DOH_NAMESPACE(Next)
+#define DohMalloc          DOH_NAMESPACE(Malloc)
+#define DohRealloc         DOH_NAMESPACE(Realloc)
+#define DohCalloc          DOH_NAMESPACE(Calloc)
+#define DohFree            DOH_NAMESPACE(Free)
+#define DohSetExitHandler  DOH_NAMESPACE(SetExitHandler)
+#define DohExit            DOH_NAMESPACE(Exit)
 #endif
 
 #define DOH_MAJOR_VERSION 0
@@ -163,12 +169,11 @@
 
 /* Memory management */
 
-#ifndef DohMalloc
-#define DohMalloc malloc
-#endif
-#ifndef DohRealloc
-#define DohRealloc realloc
-#endif
+/* Wrappers around malloc(), realloc() and calloc() which never return NULL. */
+extern void *DohMalloc(size_t size);
+extern void *DohRealloc(void *ptr, size_t size);
+extern void *DohCalloc(size_t n, size_t size);
+
 #ifndef DohFree
 #define DohFree free
 #endif
@@ -197,6 +202,7 @@
 extern int DohDelattr(DOH *obj, const DOHString_or_char *name);
 extern int DohCheckattr(DOH *obj, const DOHString_or_char *name, const DOHString_or_char *value);
 extern DOH *DohKeys(DOH *obj);
+extern DOH *DohSortedKeys(DOH *obj, int (*cmp) (const DOH *, const DOH *));
 extern int DohGetInt(DOH *obj, const DOHString_or_char *name);
 extern void DohSetInt(DOH *obj, const DOHString_or_char *name, int);
 extern double DohGetDouble(DOH *obj, const DOHString_or_char *name);
@@ -271,6 +277,24 @@
 extern void DohSetmark(DOH *obj, int x);
 extern int DohGetmark(DOH *obj);
 
+/* Set the function for DohExit() to call instead of exit().
+ *
+ * The registered function can perform clean up, etc.  It should simply
+ * return when done and then exit() will get called.  Bear in mind that
+ * the handler function can be called after malloc() has failed, so it's
+ * a good idea for it to avoid allocating additional memory.
+ *
+ * The registered handler function is unregistered by DohExit() before calling
+ * it to avoid the potential for infinite loops.
+ *
+ * Note: This is sort of like C's atexit(), only for DohExit().  However
+ * only one function can be registered (setting a new function overrides the
+ * previous one) and the registered function is passed the exit status so can
+ * vary its actions based on that.
+ */
+extern void DohSetExitHandler(void (*new_handler)(int));
+extern void DohExit(int status);
+
 /* -----------------------------------------------------------------------------
  * Strings.
  * ----------------------------------------------------------------------------- */
@@ -289,11 +313,12 @@
 
 #define   DOH_REPLACE_ANY         0x01
 #define   DOH_REPLACE_NOQUOTE     0x02
-#define   DOH_REPLACE_ID          0x04
-#define   DOH_REPLACE_FIRST       0x08
-#define   DOH_REPLACE_ID_BEGIN    0x10
-#define   DOH_REPLACE_ID_END      0x20
-#define   DOH_REPLACE_NUMBER_END  0x40
+#define   DOH_REPLACE_NOCOMMENT   0x04
+#define   DOH_REPLACE_ID          0x08
+#define   DOH_REPLACE_FIRST       0x10
+#define   DOH_REPLACE_ID_BEGIN    0x20
+#define   DOH_REPLACE_ID_END      0x40
+#define   DOH_REPLACE_NUMBER_END  0x80
 
 #define Replaceall(s,t,r)  DohReplace(s,t,r,DOH_REPLACE_ANY)
 #define Replaceid(s,t,r)   DohReplace(s,t,r,DOH_REPLACE_ID)
@@ -363,7 +388,7 @@
 #define Push(s,x)          DohInsertitem(s,DOH_BEGIN,x)
 #define Len                DohLen
 #define Data               DohData
-#define Char               (char *) Data
+#define Char(X)            ((char *) Data(X))
 #define Cmp                DohCmp
 #define Equal              DohEqual
 #define Setline            DohSetline
@@ -421,6 +446,7 @@
 #define FileErrorDisplay   DohFileErrorDisplay
 #define NewVoid            DohNewVoid
 #define Keys               DohKeys
+#define SortedKeys         DohSortedKeys
 #define Strcmp             DohStrcmp
 #define Strncmp            DohStrncmp
 #define Strstr             DohStrstr
@@ -439,6 +465,12 @@
 #define Next               DohNext
 #define Iterator           DohIterator
 #define SortList           DohSortList
+#define Malloc             DohMalloc
+#define Realloc            DohRealloc
+#define Calloc             DohCalloc
+#define Free               DohFree
+#define SetExitHandler     DohSetExitHandler
+#define Exit               DohExit
 #endif
 
 #ifdef NIL
@@ -447,5 +479,29 @@
 
 #define NIL  (char *) NULL
 
+/* Defines to allow use of poisoned identifiers.
+ *
+ * For DOH-internal use only!
+ */
+#define doh_internal_calloc calloc
+#define doh_internal_exit exit
+/* doh_internal_free not needed as Free() is a macro defined above. */
+#define doh_internal_malloc malloc
+#define doh_internal_realloc realloc
 
-#endif				/* DOH_H */
+#if defined __GNUC__ && defined DOH_POISON
+/* Use Malloc(), Realloc(), Calloc(), and Free() instead (which will exit with
+ * an error rather than return NULL).
+ */
+# ifndef DOH_NO_POISON_MALLOC_FREE
+/* This works around bison's template checking if malloc and free are defined,
+ * which triggers GCC's poison checks.
+ */
+#  pragma GCC poison malloc free
+# endif
+# pragma GCC poison realloc calloc
+/* Use Exit() instead (which will remove output files on error). */
+# pragma GCC poison abort exit
+#endif
+
+#endif				/* SWIG_DOH_H */
diff --git a/Source/DOH/dohint.h b/Source/DOH/dohint.h
index 87def9d..b637deb 100644
--- a/Source/DOH/dohint.h
+++ b/Source/DOH/dohint.h
@@ -4,15 +4,15 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * dohint.h
  *
  *     This file describes internally managed objects.
  * ----------------------------------------------------------------------------- */
 
-#ifndef _DOHINT_H
-#define _DOHINT_H
+#ifndef SWIG_DOHINT_H
+#define SWIG_DOHINT_H
 
 #include "doh.h"
 
@@ -128,4 +128,4 @@
 extern DOH *DohObjMalloc(DohObjInfo *type, void *data);	/* Allocate a DOH object */
 extern void DohObjFree(DOH *ptr);	/* Free a DOH object     */
 
-#endif				/* DOHINT_H */
+#endif				/* SWIG_DOHINT_H */
diff --git a/Source/DOH/file.c b/Source/DOH/file.c
index 570f84e..4bcf5d5 100644
--- a/Source/DOH/file.c
+++ b/Source/DOH/file.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * file.c
  *
@@ -35,7 +35,7 @@
  * reference count of the underlying DOH objects.
  * ----------------------------------------------------------------------------- */
 
-static DOHList *open_files_list_instance() {
+static DOHList *open_files_list_instance(void) {
   static DOHList *all_open_files = 0;
   if (!all_open_files)
     all_open_files = DohNewList();
@@ -64,6 +64,7 @@
   }
   Delete(sf);
   assert(removed);
+  (void)removed;
 }
 
 /* -----------------------------------------------------------------------------
@@ -72,7 +73,7 @@
  * Close all opened files, to be called on program termination
  * ----------------------------------------------------------------------------- */
 
-void DohCloseAllOpenFiles() {
+void DohCloseAllOpenFiles(void) {
   int i;
   DOHList *all_open_files = open_files_list_instance();
   for (i = 0; i < DohLen(all_open_files); i++) {
@@ -80,6 +81,7 @@
     DOHString *sf = Getitem(all_open_files, i);
     int check = sscanf(Char(sf), "%p", (void **)&f);
     assert(check == 1);
+    (void)check;
     if (f->closeondel) {
       if (f->filep) {
 	check = fclose(f->filep);
@@ -289,10 +291,6 @@
     return 0;
 
   f = (DohFile *) DohMalloc(sizeof(DohFile));
-  if (!f) {
-    fclose(file);
-    return 0;
-  }
   if (newfiles)
     Append(newfiles, filename);
   f->filep = file;
@@ -312,8 +310,6 @@
 DOH *DohNewFileFromFile(FILE *file) {
   DohFile *f;
   f = (DohFile *) DohMalloc(sizeof(DohFile));
-  if (!f)
-    return 0;
   f->filep = file;
   f->fd = 0;
   f->closeondel = 0;
@@ -329,8 +325,6 @@
 DOH *DohNewFileFromFd(int fd) {
   DohFile *f;
   f = (DohFile *) DohMalloc(sizeof(DohFile));
-  if (!f)
-    return 0;
   f->filep = 0;
   f->fd = fd;
   f->closeondel = 0;
diff --git a/Source/DOH/fio.c b/Source/DOH/fio.c
index 7741900..972fb23 100644
--- a/Source/DOH/fio.c
+++ b/Source/DOH/fio.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * fio.c
  *
diff --git a/Source/DOH/hash.c b/Source/DOH/hash.c
index c2bc3dd..1a29b35 100644
--- a/Source/DOH/hash.c
+++ b/Source/DOH/hash.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * hash.c
  *
@@ -130,6 +130,7 @@
  * Hash_clear()
  *
  * Clear all of the entries in the hash table.
+ * File and line numbering info left unmodified.
  * ----------------------------------------------------------------------------- */
 
 static void Hash_clear(DOH *ho) {
@@ -173,10 +174,7 @@
     p = p + 2;
   }
 
-  table = (HashNode **) DohMalloc(newsize * sizeof(HashNode *));
-  for (i = 0; i < newsize; i++) {
-    table[i] = 0;
-  }
+  table = (HashNode **) DohCalloc(newsize, sizeof(HashNode *));
 
   /* Walk down the old set of nodes and re-place */
   h->hashsize = newsize;
diff --git a/Source/DOH/list.c b/Source/DOH/list.c
index 8a96a9a..f2282fe 100644
--- a/Source/DOH/list.c
+++ b/Source/DOH/list.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * list.c
  *
@@ -27,7 +27,6 @@
 static
 void more(List *l) {
   l->items = (void **) DohRealloc(l->items, l->maxitems * 2 * sizeof(void *));
-  assert(l->items);
   l->maxitems *= 2;
 }
 
@@ -74,6 +73,7 @@
  * List_clear()
  *
  * Remove all of the list entries, but keep the list object intact.
+ * File and line numbering info left unmodified.
  * ----------------------------------------------------------------------------- */
 
 static void List_clear(DOH *lo) {
@@ -346,15 +346,10 @@
 #define MAXLISTITEMS 8
 
 DOH *DohNewList(void) {
-  List *l;
-  int i;
-  l = (List *) DohMalloc(sizeof(List));
+  List *l = (List *) DohMalloc(sizeof(List));
   l->nitems = 0;
   l->maxitems = MAXLISTITEMS;
-  l->items = (void **) DohMalloc(l->maxitems * sizeof(void *));
-  for (i = 0; i < MAXLISTITEMS; i++) {
-    l->items[i] = 0;
-  }
+  l->items = (void **) DohCalloc(l->maxitems, sizeof(void *));
   l->file = 0;
   l->line = 0;
   return DohObjMalloc(&DohListType, l);
diff --git a/Source/DOH/memory.c b/Source/DOH/memory.c
index e0e4c68..8b372a6 100644
--- a/Source/DOH/memory.c
+++ b/Source/DOH/memory.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * memory.c
  *
@@ -14,8 +14,11 @@
 
 #include "dohint.h"
 
+#include <stdio.h>
+#include <stdlib.h>
+
 #ifndef DOH_POOL_SIZE
-#define DOH_POOL_SIZE         16384
+#define DOH_POOL_SIZE         4194304
 #endif
 
 /* Checks stale DOH object use - will use a lot more memory as pool memory is not re-used. */
@@ -45,13 +48,10 @@
  * CreatePool() - Create a new memory pool 
  * ---------------------------------------------------------------------- */
 
-static void CreatePool() {
+static void CreatePool(void) {
   Pool *p = 0;
   p = (Pool *) DohMalloc(sizeof(Pool));
-  assert(p);
-  p->ptr = (DohBase *) DohMalloc(sizeof(DohBase) * PoolSize);
-  assert(p->ptr);
-  memset(p->ptr, 0, sizeof(DohBase) * PoolSize);
+  p->ptr = (DohBase *) DohCalloc(PoolSize, sizeof(DohBase));
   p->len = PoolSize;
   p->blen = PoolSize * sizeof(DohBase);
   p->current = 0;
@@ -65,7 +65,7 @@
  * InitPools() - Initialize the memory allocator
  * ---------------------------------------------------------------------- */
 
-static void InitPools() {
+static void InitPools(void) {
   if (pools_initialized)
     return;
   CreatePool();			/* Create initial pool */
@@ -234,3 +234,59 @@
 #endif
 
 }
+
+/* Function to call instead of exit(). */
+static void (*doh_exit_handler)(int) = NULL;
+
+void DohSetExitHandler(void (*new_handler)(int)) {
+  doh_exit_handler = new_handler;
+}
+
+void DohExit(int status) {
+  if (doh_exit_handler) {
+    void (*handler)(int) = doh_exit_handler;
+    /* Unset the handler to avoid infinite loops if it tries to do something
+     * which calls DohExit() (e.g. calling Malloc() and that failing).
+     */
+    doh_exit_handler = NULL;
+    handler(status);
+  }
+  doh_internal_exit(status);
+}
+
+static void allocation_failed(size_t n, size_t size) {
+  /* Report and exit as directly as possible to try to avoid further issues due
+   * to lack of memory. */
+  if (n == 1) {
+#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 199901L
+    fprintf(stderr, "Failed to allocate %zu bytes\n", size);
+#else
+    fprintf(stderr, "Failed to allocate %lu bytes\n", (unsigned long)size);
+#endif
+  } else {
+#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 199901L
+    fprintf(stderr, "Failed to allocate %zu*%zu bytes\n", n, size);
+#else
+    fprintf(stderr, "Failed to allocate %lu*%lu bytes\n", (unsigned long)n, (unsigned long)size);
+#endif
+  }
+  DohExit(EXIT_FAILURE);
+}
+
+void *DohMalloc(size_t size) {
+  void *p = doh_internal_malloc(size);
+  if (!p) allocation_failed(1, size);
+  return p;
+}
+
+void *DohRealloc(void *ptr, size_t size) {
+  void *p = doh_internal_realloc(ptr, size);
+  if (!p) allocation_failed(1, size);
+  return p;
+}
+
+void *DohCalloc(size_t n, size_t size) {
+  void *p = doh_internal_calloc(n, size);
+  if (!p) allocation_failed(n, size);
+  return p;
+}
diff --git a/Source/DOH/string.c b/Source/DOH/string.c
index 6c67285..cdebc3b 100644
--- a/Source/DOH/string.c
+++ b/Source/DOH/string.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * string.c
  *
@@ -180,19 +180,27 @@
   if (s->hashkey >= 0) {
     return s->hashkey;
   } else {
-    char *c = s->str;
+    /* We use the djb2 hash function: https://theartincode.stanis.me/008-djb2/
+     *
+     * One difference is we use initial seed 0.  It seems the usual seed value
+     * is intended to help spread out hash values, which is beneficial if
+     * linear probing is used but DOH Hash uses a chain of buckets instead, and
+     * grouped hash values are probably more cache friendly.  In tests using
+     * 0 seems slightly faster anyway.
+     */
+    const char *c = s->str;
     unsigned int len = s->len > 50 ? 50 : s->len;
     unsigned int h = 0;
     unsigned int mlen = len >> 2;
     unsigned int i = mlen;
     for (; i; --i) {
-      h = (h << 5) + *(c++);
-      h = (h << 5) + *(c++);
-      h = (h << 5) + *(c++);
-      h = (h << 5) + *(c++);
+      h = h + (h << 5) + *(c++);
+      h = h + (h << 5) + *(c++);
+      h = h + (h << 5) + *(c++);
+      h = h + (h << 5) + *(c++);
     }
     for (i = len - (mlen << 2); i; --i) {
-      h = (h << 5) + *(c++);
+      h = h + (h << 5) + *(c++);
     }
     h &= 0x7fffffff;
     s->hashkey = (int)h;
@@ -229,7 +237,6 @@
     if (newlen >= newmaxsize - 1)
       newmaxsize = newlen + 1;
     s->str = (char *) DohRealloc(s->str, newmaxsize);
-    assert(s->str);
     s->maxsize = newmaxsize;
   }
   tc = s->str;
@@ -249,7 +256,9 @@
 
 
 /* -----------------------------------------------------------------------------
- * String_clear() - Clear a string
+ * String_clear() - Clear string contents
+ *
+ * File and line numbering info left unmodified.
  * ----------------------------------------------------------------------------- */
 
 static void String_clear(DOH *so) {
@@ -258,7 +267,6 @@
   s->len = 0;
   *(s->str) = 0;
   s->sp = 0;
-  s->line = 1;
 }
 
 /* -----------------------------------------------------------------------------
@@ -296,7 +304,6 @@
   while (s->maxsize <= s->len + len) {
     int newsize = 2 * s->maxsize;
     s->str = (char *) DohRealloc(s->str, newsize);
-    assert(s->str);
     s->maxsize = newsize;
   }
   memmove(s->str + pos + len, s->str + pos, (s->len - pos));
@@ -424,7 +431,6 @@
   newlen = s->sp + len + 1;
   if (newlen > s->maxsize) {
     s->str = (char *) DohRealloc(s->str, newlen);
-    assert(s->str);
     s->maxsize = newlen;
     s->len = s->sp + len;
   }
@@ -517,7 +523,6 @@
     if (len > (maxsize - 2)) {
       maxsize *= 2;
       tc = (char *) DohRealloc(tc, maxsize);
-      assert(tc);
       s->maxsize = (int) maxsize;
       s->str = tc;
     }
@@ -595,6 +600,13 @@
   }
 }
 
+static char *end_comment(char *s) {
+  char *substring = strstr(s, "*/");
+  if (substring)
+    ++substring;
+  return substring;
+}
+
 static char *match_simple(char *base, char *s, char *token, int tokenlen) {
   (void) base;
   (void) tokenlen;
@@ -607,11 +619,13 @@
     if (!s)
       return 0;
     if ((s > base) && (isalnum((int) *(s - 1)) || (*(s - 1) == '_'))) {
-      s += tokenlen;
+      /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
+      ++s;
       continue;
     }
     if (isalnum((int) *(s + tokenlen)) || (*(s + tokenlen) == '_')) {
-      s += tokenlen;
+      /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
+      ++s;
       continue;
     }
     return s;
@@ -621,12 +635,14 @@
 
 
 static char *match_identifier_begin(char *base, char *s, char *token, int tokenlen) {
+  (void)tokenlen;
   while (s) {
     s = strstr(s, token);
     if (!s)
       return 0;
     if ((s > base) && (isalnum((int) *(s - 1)) || (*(s - 1) == '_'))) {
-      s += tokenlen;
+      /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
+      ++s;
       continue;
     }
     return s;
@@ -641,7 +657,8 @@
     if (!s)
       return 0;
     if (isalnum((int) *(s + tokenlen)) || (*(s + tokenlen) == '_')) {
-      s += tokenlen;
+      /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
+      ++s;
       continue;
     }
     return s;
@@ -656,7 +673,8 @@
     if (!s)
       return 0;
     if (isdigit((int) *(s + tokenlen))) {
-      s += tokenlen;
+      /* We could advance by tokenlen if strstr(s, token) matches can't overlap. */
+      ++s;
       continue;
     }
     return s;
@@ -677,6 +695,7 @@
   int ic;
   int rcount = 0;
   int noquote = 0;
+  int nocomment = 0;
   char *c, *s, *t, *first;
   char *q, *q2;
   char *base;
@@ -698,6 +717,11 @@
   if (flags & DOH_REPLACE_NOQUOTE)
     noquote = 1;
 
+  if (flags & DOH_REPLACE_NOCOMMENT)
+    nocomment = 1;
+
+  assert(!(noquote && nocomment)); /* quote and comment combination not implemented */
+
   /* If we are not replacing inside quotes, we need to do a little extra work */
   if (noquote) {
     q = strpbrk(base, "\"\'");
@@ -723,6 +747,31 @@
     }
   }
 
+  /* If we are not replacing inside comments, we need to do a little extra work */
+  if (nocomment) {
+    q = strstr(base, "/*");
+    if (!q) {
+      nocomment = 0;		/* Well, no comments to worry about. Oh well */
+    } else {
+      while (q && (q < s)) {
+	/* First match was found inside a comment.  Try to find another match */
+	q2 = end_comment(q);
+	if (!q2) {
+	  return 0;
+	}
+	if (q2 > s) {
+	  /* Find next match */
+	  s = (*match) (base, q2 + 1, token, tokenlen);
+	}
+	if (!s)
+	  return 0;		/* Oh well, no matches */
+	q = strstr(q2 + 1, "/*");
+	if (!q)
+	  nocomment = 0;		/* No more comments */
+      }
+    }
+  }
+
   first = s;
   replen = (int)strlen(rep);
 
@@ -768,6 +817,28 @@
 	  }
 	}
       }
+      if (nocomment) {
+	q = strstr(s, "/*");
+	if (!q) {
+	  nocomment = 0;
+	} else {
+	  while (q && (q < c)) {
+	    /* First match was found inside a comment.  Try to find another match */
+	    q2 = end_comment(q);
+	    if (!q2) {
+	      c = 0;
+	      break;
+	    }
+	    if (q2 > c)
+	      c = (*match) (base, q2 + 1, token, tokenlen);
+	    if (!c)
+	      break;
+	    q = strstr(q2 + 1, "/*");
+	    if (!q)
+	      nocomment = 0;	/* No more comments */
+	  }
+	}
+      }
       if (delta) {
 	if (c) {
 	  memmove(t, s, c - s);
@@ -776,7 +847,9 @@
 	  memmove(t, s, (str->str + str->len) - s + 1);
 	}
       } else {
-	t += (c - s);
+	if (c) {
+	  t += (c - s);
+	}
       }
       s = c;
       ic--;
@@ -823,6 +896,29 @@
 	  }
 	}
       }
+      if (nocomment) {
+	q = strstr(s, "/*");
+	if (!q) {
+	  break;
+	} else {
+	  while (q && (q < c)) {
+	    /* First match was found inside a comment.  Try to find another match */
+	    q2 = end_comment(q);
+	    if (!q2) {
+	      c = 0;
+	      break;
+	    }
+	    if (q2 > c) {
+	      c = (*match) (base, q2 + 1, token, tokenlen);
+	      if (!c)
+		break;
+	    }
+	    q = strstr(q2 + 1, "/*");
+	    if (!q)
+	      nocomment = 0;
+	  }
+	}
+      }
       if (c) {
 	rcount++;
 	ic--;
@@ -838,7 +934,6 @@
       newsize *= 2;
 
     ns = (char *) DohMalloc(newsize);
-    assert(ns);
     t = ns;
     s = first;
 
@@ -875,6 +970,29 @@
 	  }
 	}
       }
+      if (nocomment) {
+	q = strstr(s, "/*");
+	if (!q) {
+	  nocomment = 0;
+	} else {
+	  while (q && (q < c)) {
+	    /* First match was found inside a comment.  Try to find another match */
+	    q2 = end_comment(q);
+	    if (!q2) {
+	      c = 0;
+	      break;
+	    }
+	    if (q2 > c) {
+	      c = (*match) (base, q2 + 1, token, tokenlen);
+	      if (!c)
+		break;
+	    }
+	    q = strstr(q2 + 1, "/*");
+	    if (!q)
+	      nocomment = 0;	/* No more comments */
+	  }
+	}
+      }
       if (i < (rcount - 1)) {
 	memcpy(t, s, c - s);
 	t += (c - s);
@@ -1045,7 +1163,7 @@
   str = (String *) DohMalloc(sizeof(String));
   str->hashkey = hashkey;
   str->sp = 0;
-  str->line = 1;
+  str->line = 0;
   str->file = 0;
   max = INIT_MAXSIZE;
   if (s) {
@@ -1075,7 +1193,7 @@
   String *str = (String *) DohMalloc(sizeof(String));
   str->hashkey = 0;
   str->sp = 0;
-  str->line = 1;
+  str->line = 0;
   str->file = 0;
   str->str = (char *) DohMalloc(max);
   str->maxsize = max;
@@ -1101,7 +1219,7 @@
   str = (String *) DohMalloc(sizeof(String));
   str->hashkey = -1;
   str->sp = 0;
-  str->line = 1;
+  str->line = 0;
   str->file = 0;
   max = INIT_MAXSIZE;
   if (s) {
diff --git a/Source/DOH/void.c b/Source/DOH/void.c
index 6111a8c..bbecca2 100644
--- a/Source/DOH/void.c
+++ b/Source/DOH/void.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * void.c
  *
diff --git a/Source/Doxygen/doxycommands.h b/Source/Doxygen/doxycommands.h
index 1f7b5fa..782b6ab 100644
--- a/Source/Doxygen/doxycommands.h
+++ b/Source/Doxygen/doxycommands.h
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * doxycommands.h
  *
@@ -18,11 +18,13 @@
 const char *CMD_HTML_ONLY = "htmlonly";
 // doxy commands are not processed inside this block
 const char *CMD_VERBATIM = "verbatim";
+const char *CMD_CODE = "code";
 const char *CMD_LATEX_1 = "f$";
 const char *CMD_LATEX_2 = "f{";
 const char *CMD_LATEX_3 = "f[";
 const char *CMD_END_HTML_ONLY = "endhtmlonly";
 const char *CMD_END_VERBATIM = "endverbatim";
+const char *CMD_END_CODE = "endcode";
 const char *CMD_END_LATEX_1 = "f$";
 const char *CMD_END_LATEX_2 = "f}";
 const char *CMD_END_LATEX_3 = "f]";
@@ -42,6 +44,8 @@
 const char *simpleCommands[] = {
   // the first line are escaped chars, except \~, which is a language ID command.
   "n", "$", "@", "\\", "&", "~", "<", ">", "#", "%", "\"", ".", "::",
+  // Member groups, which we currently ignore.
+  "{", "}",
   "endcond",
   "callgraph", "callergraph", "showinitializer", "hideinitializer", "internal",
   "nosubgrouping", "public", "publicsection", "private", "privatesection",
diff --git a/Source/Doxygen/doxyentity.cxx b/Source/Doxygen/doxyentity.cxx
index 8b9f657..29bbbe6 100644
--- a/Source/Doxygen/doxyentity.cxx
+++ b/Source/Doxygen/doxyentity.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * doxyentity.cxx
  *
@@ -42,7 +42,7 @@
 
   if (isLeaf) {
     for (int i = 0; i < thisLevel; i++) {
-      cout << "\t";
+      cout << '\t';
     }
 
     cout << "Node Leaf Command: '" << typeOfEntity << "',  ";
@@ -55,7 +55,7 @@
   } else {
 
     for (int i = 0; i < thisLevel; i++) {
-      cout << "\t";
+      cout << '\t';
     }
 
     cout << "Node Command: '" << typeOfEntity << "'" << std::endl;
diff --git a/Source/Doxygen/doxyentity.h b/Source/Doxygen/doxyentity.h
index 93737e6..e475141 100644
--- a/Source/Doxygen/doxyentity.h
+++ b/Source/Doxygen/doxyentity.h
@@ -4,15 +4,15 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * doxyentity.h
  *
  * Part of the Doxygen comment translation module of SWIG.
  * ----------------------------------------------------------------------------- */
 
-#ifndef DOXYGENENTITY_H_
-#define DOXYGENENTITY_H_
+#ifndef SWIG_DOXYENTITY_H
+#define SWIG_DOXYENTITY_H
 
 #include <string>
 #include <list>
diff --git a/Source/Doxygen/doxyparser.cxx b/Source/Doxygen/doxyparser.cxx
index 2e826b2..473769a 100644
--- a/Source/Doxygen/doxyparser.cxx
+++ b/Source/Doxygen/doxyparser.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * doxyparser.cxx
  * ----------------------------------------------------------------------------- */
@@ -34,6 +34,30 @@
 const int TOKENSPERLINE = 8; //change this to change the printing behaviour of the token list
 const std::string END_HTML_TAG_MARK("/");
 
+std::string getBaseCommand(const std::string &cmd) {
+  if (cmd.substr(0,5) == "param")
+    return "param";
+  else if (cmd.substr(0,4) == "code")
+    return "code";
+  else
+    return cmd;
+}
+
+// Find the first position beyond the word command.  Extra logic is
+// used to avoid putting the characters "," and "." in
+// DOXYGEN_WORD_CHARS.
+static size_t getEndOfWordCommand(const std::string &line, size_t pos) {
+  size_t endOfWordPos = line.find_first_not_of(DOXYGEN_WORD_CHARS, pos);
+  if (line.substr(pos, 6) == "param[")
+    // include ",", which can appear in param[in,out]
+    endOfWordPos = line.find_first_not_of(string(DOXYGEN_WORD_CHARS)+ ",", pos);  
+  else if (line.substr(pos, 5) == "code{")
+    // include ".", which can appear in e.g. code{.py}
+    endOfWordPos = line.find_first_not_of(string(DOXYGEN_WORD_CHARS)+ ".", pos);
+  return endOfWordPos;
+}
+
+
 DoxygenParser::DoxygenParser(bool noisy) : noisy(noisy) {
   fillTables();
 }
@@ -118,7 +142,7 @@
 }
 
 DoxygenParser::DoxyCommandEnum DoxygenParser::commandBelongs(const std::string &theCommand) {
-  DoxyCommandsMapIt it = doxygenCommands.find(stringToLower(theCommand));
+  DoxyCommandsMapIt it = doxygenCommands.find(stringToLower(getBaseCommand(theCommand)));
 
   if (it != doxygenCommands.end()) {
     return it->second;
@@ -312,7 +336,7 @@
 
     } else if (endOfParagraph->m_tokenType == COMMAND) {
 
-      if (isSectionIndicator(endOfParagraph->m_tokenString)) {
+      if (isSectionIndicator(getBaseCommand(endOfParagraph->m_tokenString))) {
         return endOfParagraph;
       } else {
         endOfParagraph++;
@@ -666,7 +690,7 @@
   // \f{ ... \f}
   // \f{env}{ ... \f}
   // \f$ ... \f$
-  else if (theCommand == "code" || theCommand == "verbatim"
+  else if (getBaseCommand(theCommand) == "code" || theCommand == "verbatim"
            || theCommand == "dot" || theCommand == "msc" || theCommand == "f[" || theCommand == "f{" || theCommand == "f$") {
     if (!endCommands.size()) {
       // fill in static table of end commands
@@ -683,7 +707,7 @@
     if (it != endCommands.end())
       endCommand = it->second;
     else
-      endCommand = "end" + theCommand;
+      endCommand = "end" + getBaseCommand(theCommand);
 
     std::string content = getStringTilEndCommand(endCommand, tokList);
     aNewList.push_back(DoxygenEntity("plainstd::string", content));
@@ -1057,6 +1081,13 @@
     tokList.push_back(Token(COMMAND, cmd));
     return true;
   } else {
+    if (cmd.empty()) {
+      // This actually indicates a bug in the code in this file, as this
+      // function shouldn't be called at all in this case.
+      printListError(WARN_DOXYGEN_UNKNOWN_COMMAND, "Unexpected empty Doxygen command.");
+      return false;
+    }
+
     // This function is called for the special Doxygen commands, but also for
     // HTML commands (or anything that looks like them, actually) and entities.
     // We don't recognize all of those, so just ignore them and pass them
@@ -1090,7 +1121,7 @@
     size_t endOfWordPos = line.find_first_not_of(DOXYGEN_WORD_CHARS, pos);
     string cmd = line.substr(pos, endOfWordPos - pos);
 
-    if (cmd == CMD_END_HTML_ONLY || cmd == CMD_END_VERBATIM || cmd == CMD_END_LATEX_1 || cmd == CMD_END_LATEX_2 || cmd == CMD_END_LATEX_3) {
+    if (cmd == CMD_END_HTML_ONLY || cmd == CMD_END_VERBATIM || cmd == CMD_END_LATEX_1 || cmd == CMD_END_LATEX_2 || cmd == CMD_END_LATEX_3 || cmd == CMD_END_CODE) {
 
       m_isVerbatimText = false;
       addDoxyCommand(m_tokenList, cmd);
@@ -1154,22 +1185,43 @@
  */
 void DoxygenParser::processWordCommands(size_t &pos, const std::string &line) {
   pos++;
-  size_t endOfWordPos = line.find_first_not_of(DOXYGEN_WORD_CHARS, pos);
+  size_t endOfWordPos = getEndOfWordCommand(line, pos);
 
   string cmd = line.substr(pos, endOfWordPos - pos);
+  if (cmd.empty()) {
+    // This was a bare backslash, just ignore it.
+    return;
+  }
+
   addDoxyCommand(m_tokenList, cmd);
 
-  if (cmd == CMD_HTML_ONLY || cmd == CMD_VERBATIM || cmd == CMD_LATEX_1 || cmd == CMD_LATEX_2 || cmd == CMD_LATEX_3) {
+  // A flag for whether we want to skip leading spaces after the command
+  bool skipLeadingSpace = true;
+
+  if (cmd == CMD_HTML_ONLY || cmd == CMD_VERBATIM || cmd == CMD_LATEX_1 || cmd == CMD_LATEX_2 || cmd == CMD_LATEX_3 || getBaseCommand(cmd) == CMD_CODE) {
 
     m_isVerbatimText = true;
 
-  } else {
+    // Skipping leading space is necessary with inline \code command,
+    // and it won't hurt anything for block \code (TODO: are the other
+    // commands also compatible with skip leading space?  If so, just
+    // do it every time.)
+    if (getBaseCommand(cmd) == CMD_CODE) skipLeadingSpace = true;
+    else skipLeadingSpace = false;
+  } else if (cmd.substr(0,3) == "end") {
+    // If processing an "end" command such as "endlink", don't skip
+    // the space before the next string
+    skipLeadingSpace = false;
+  }
+
+  if (skipLeadingSpace) {
     // skip any possible spaces after command, because some commands have parameters,
     // and spaces between command and parameter must be ignored.
     if (endOfWordPos != string::npos) {
       endOfWordPos = line.find_first_not_of(" \t", endOfWordPos);
     }
   }
+  
   pos = endOfWordPos;
 }
 
@@ -1189,18 +1241,21 @@
   // prepend '<' to distinguish HTML tags from doxygen commands
   if (!cmd.empty() && addDoxyCommand(m_tokenList, '<' + cmd)) {
     // it is a valid HTML command
+    if (pos == string::npos) {
+      pos = line.size();
+    }
     if (line[pos] != '>') {
       // it should be HTML tag with args,
       // for example <A ...>, <IMG ...>, ...
       if (isEndHtmlTag) {
         m_tokenListIt = m_tokenList.end();
-        printListError(WARN_DOXYGEN_HTML_ERROR, "Doxygen HTML error for tag " + cmd + ": Illegal end HTML tag without '>' found.");
+        printListError(WARN_DOXYGEN_HTML_ERROR, "Doxygen HTML error for tag " + cmd + ": Illegal end HTML tag without greater-than ('>') found.");
       }
 
-      endHtmlPos = line.find(">", pos);
+      endHtmlPos = line.find('>', pos);
       if (endHtmlPos == string::npos) {
         m_tokenListIt = m_tokenList.end();
-        printListError(WARN_DOXYGEN_HTML_ERROR, "Doxygen HTML error for tag " + cmd + ": HTML tag without '>' found.");
+        printListError(WARN_DOXYGEN_HTML_ERROR, "Doxygen HTML error for tag " + cmd + ": HTML tag without greater-than ('>') found.");
       }
       // add args of HTML command, like link URL, image URL, ...
       m_tokenList.push_back(Token(PLAINSTRING, line.substr(pos, endHtmlPos - pos)));
@@ -1214,7 +1269,7 @@
       }
     }
 
-    if (pos != string::npos) {
+    if (pos < line.size()) {
       pos++; // skip '>'
     }
   } else {
@@ -1419,7 +1474,7 @@
   int tokNo = 0;
   for (TokenListCIt it = m_tokenList.begin(); it != m_tokenList.end(); it++, tokNo++) {
 
-    cout << it->toString() << " ";
+    cout << it->toString() << ' ';
 
     if ((tokNo % TOKENSPERLINE) == 0) {
       cout << endl;
diff --git a/Source/Doxygen/doxyparser.h b/Source/Doxygen/doxyparser.h
index 96c71d2..a604465 100644
--- a/Source/Doxygen/doxyparser.h
+++ b/Source/Doxygen/doxyparser.h
@@ -4,13 +4,13 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * doxyparser.h
  * ----------------------------------------------------------------------------- */
 
-#ifndef DOXYGENPARSER_H_
-#define DOXYGENPARSER_H_
+#ifndef SWIG_DOXYPARSER_H
+#define SWIG_DOXYPARSER_H
 #include <string>
 #include <list>
 #include <map>
@@ -21,6 +21,11 @@
 
 #include "doxyentity.h"
 
+// Utility function to return the base part of a command that may
+// include options, e.g. param[in] -> param
+std::string getBaseCommand(const std::string &cmd);
+
+
 class DoxygenParser {
 private:
 
@@ -233,7 +238,7 @@
    * Method for Adding a Simple Command
    * Format: @command
    * Plain commands, such as newline etc, they contain no other data
-   *  \n \\ \@ \& \$ \# \< \> \%
+   *  \n \\ \@ \& \$ \# \< \> \% \{ \}
    */
   void addSimpleCommand(const std::string &theCommand, DoxygenEntityList &doxyList);
   /*
diff --git a/Source/Doxygen/doxytranslator.cxx b/Source/Doxygen/doxytranslator.cxx
index fb21de7..a638717 100644
--- a/Source/Doxygen/doxytranslator.cxx
+++ b/Source/Doxygen/doxytranslator.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * doxytranslator.cxx
  *
diff --git a/Source/Doxygen/doxytranslator.h b/Source/Doxygen/doxytranslator.h
index f07b632..f0d3b1b 100644
--- a/Source/Doxygen/doxytranslator.h
+++ b/Source/Doxygen/doxytranslator.h
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * doxytranslator.h
  *
@@ -12,8 +12,8 @@
  * systems.
  * ----------------------------------------------------------------------------- */
 
-#ifndef DOXYGENTRANSLATOR_H_
-#define DOXYGENTRANSLATOR_H_
+#ifndef SWIG_DOXYTRANSLATOR_H
+#define SWIG_DOXYTRANSLATOR_H
 
 #include "swig.h"
 #include "doxyentity.h"
@@ -53,13 +53,13 @@
   virtual ~DoxygenTranslator();
 
   /*
-   * Return the documentation for a given node formated for the correct 
+   * Return the documentation for a given node formatted for the correct 
    * documentation system.
    */
   String *getDocumentation(Node *node, const_String_or_char_ptr indentationString);
 
   /*
-   * Returns truem is the specified node has comment attached.
+   * Returns true if the specified node has comment attached.
    */
   bool hasDocumentation(Node *node);
 
diff --git a/Source/Doxygen/javadoc.cxx b/Source/Doxygen/javadoc.cxx
index 72f84ab..17c7d03 100644
--- a/Source/Doxygen/javadoc.cxx
+++ b/Source/Doxygen/javadoc.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * javadoc.cxx
  * ----------------------------------------------------------------------------- */
@@ -152,7 +152,7 @@
   tagHandlers["f{"] = make_pair(&JavaDocConverter::handleTagVerbatim, "");
 
   tagHandlers["warning"] = make_pair(&JavaDocConverter::handleTagMessage, "Warning: ");
-  // this command just prints it's contents
+  // this command just prints its contents
   // (it is internal command of swig's parser, contains plain text)
   tagHandlers["plainstd::string"] = make_pair(&JavaDocConverter::handlePlainString, "");
   tagHandlers["plainstd::endl"] = make_pair(&JavaDocConverter::handleNewLine, "");
@@ -254,7 +254,7 @@
       i += APPROX_LINE_LENGTH - indent * TAB_SIZE;
     }
 
-    i = unformattedLine.find(" ", i);
+    i = unformattedLine.find(' ', i);
 
     if (i > 0 && i + 1 < unformattedLine.length()) {
       if (!isFirstLine)
@@ -334,7 +334,7 @@
 void JavaDocConverter::translateEntity(DoxygenEntity &tag, std::string &translatedComment) {
 
   std::map<std::string, std::pair<tagHandler, std::string> >::iterator it;
-  it = tagHandlers.find(tag.typeOfEntity);
+  it = tagHandlers.find(getBaseCommand(tag.typeOfEntity));
 
   if (it != tagHandlers.end()) {
     (this->*(it->second.first))(tag, translatedComment, it->second.second);
@@ -463,7 +463,11 @@
   if (it != tag.entityList.end())
     title = it->data;
 
-  translatedComment += "<img src=" + file;
+  translatedComment += "<img src=";
+  if (file.size() >= 2 && file[0] == '"' && file[file.size() - 1] == '"')
+    translatedComment += file;
+  else
+    translatedComment += "\"" + file + "\"";
   if (title.size())
     translatedComment += " alt=" + title;
 
diff --git a/Source/Doxygen/javadoc.h b/Source/Doxygen/javadoc.h
index 6feff52..d2c956c 100644
--- a/Source/Doxygen/javadoc.h
+++ b/Source/Doxygen/javadoc.h
@@ -4,15 +4,15 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * javadoc.h
  *
  * Module to return documentation for nodes formatted for JavaDoc
  * ----------------------------------------------------------------------------- */
 
-#ifndef JAVADOCCONVERTER_H_
-#define JAVADOCCONVERTER_H_
+#ifndef SWIG_JAVADOC_H
+#define SWIG_JAVADOC_H
 
 #include "doxytranslator.h"
 #include <map>
diff --git a/Source/Doxygen/pydoc.cxx b/Source/Doxygen/pydoc.cxx
index eb48993..03986a4 100644
--- a/Source/Doxygen/pydoc.cxx
+++ b/Source/Doxygen/pydoc.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * pydoc.cxx
  *
@@ -174,7 +174,8 @@
     } else {
       if (lastLineWasNonBlank &&
 	  (line.compare(pos, 13, ".. code-block") == 0 ||
-	  line.compare(pos, 7, ".. math") == 0)) {
+	   line.compare(pos, 7, ".. math") == 0 ||
+	   line.compare(pos, 3, ">>>") == 0)) {
 	// Must separate code or math blocks from the previous line
 	result += '\n';
       }
@@ -184,6 +185,21 @@
   return result;
 }
 
+// Helper function to extract the option value from a command,
+// e.g. param[in] -> in
+static std::string getCommandOption(const std::string &command, char openChar, char closeChar) {
+  string option;
+
+  size_t opt_begin, opt_end;
+  opt_begin = command.find(openChar);
+  opt_end = command.find(closeChar);
+  if (opt_begin != string::npos && opt_end != string::npos)
+    option = command.substr(opt_begin+1, opt_end-opt_begin-1);
+
+  return option;
+}
+
+
 /* static */
 PyDocConverter::TagHandlersMap::mapped_type PyDocConverter::make_handler(tagHandler handler) {
   return make_pair(handler, std::string());
@@ -245,7 +261,7 @@
   tagHandlers["date"] = make_handler(&PyDocConverter::handleParagraph);
   tagHandlers["deprecated"] = make_handler(&PyDocConverter::handleParagraph);
   tagHandlers["details"] = make_handler(&PyDocConverter::handleParagraph);
-  tagHandlers["em"] = make_handler(&PyDocConverter::handleParagraph, " ");
+  tagHandlers["em"] = make_handler(&PyDocConverter::handleTagWrap, "*");
   tagHandlers["example"] = make_handler(&PyDocConverter::handleParagraph);
   tagHandlers["exception"] = tagHandlers["throw"] = tagHandlers["throws"] = make_handler(&PyDocConverter::handleTagException);
   tagHandlers["htmlonly"] = make_handler(&PyDocConverter::handleParagraph);
@@ -254,7 +270,7 @@
   tagHandlers["link"] = make_handler(&PyDocConverter::handleParagraph);
   tagHandlers["manonly"] = make_handler(&PyDocConverter::handleParagraph);
   tagHandlers["note"] = make_handler(&PyDocConverter::handleParagraph);
-  tagHandlers["p"] = make_handler(&PyDocConverter::handleParagraph);
+  tagHandlers["p"] = make_handler(&PyDocConverter::handleTagWrap, "``");
   tagHandlers["partofdescription"] = make_handler(&PyDocConverter::handleParagraph);
   tagHandlers["rtfonly"] = make_handler(&PyDocConverter::handleParagraph);
   tagHandlers["remark"] = make_handler(&PyDocConverter::handleParagraph);
@@ -286,7 +302,7 @@
   tagHandlers["ref"] = make_handler(&PyDocConverter::handleTagRef);
   tagHandlers["result"] = tagHandlers["return"] = tagHandlers["returns"] = make_handler(&PyDocConverter::handleTagReturn);
 
-  // this command just prints it's contents
+  // this command just prints its contents
   // (it is internal command of swig's parser, contains plain text)
   tagHandlers["plainstd::string"] = make_handler(&PyDocConverter::handlePlainString);
   tagHandlers["plainstd::endl"] = make_handler(&PyDocConverter::handleNewLine);
@@ -384,7 +400,7 @@
   String *s = Swig_typemap_lookup("doctype", n, lname, 0);
   if (!s) {
     if (String *t = Getattr(n, "type"))
-      s = SwigType_str(t, "");
+      s = SwigType_str(t, NULL);
   }
 
   if (!s)
@@ -418,16 +434,32 @@
   ParmList *plist = CopyParmList(Getattr(currentNode, "parms"));
   for (Parm *p = plist; p; p = nextSibling(p)) {
     String *pname = Getattr(p, "name");
-    if (Char(pname) != param)
-      continue;
-
-    type = getPyDocType(p, pname);
-    break;
+    if (pname && Char(pname) == param) {
+      type = getPyDocType(p, pname);
+      break;
+    }
   }
   Delete(plist);
   return type;
 }
 
+std::string PyDocConverter::getParamValue(std::string param) {
+  std::string value;
+
+  ParmList *plist = CopyParmList(Getattr(currentNode, "parms"));
+  for (Parm *p = plist; p; p = nextSibling(p)) {
+    String *pname = Getattr(p, "name");
+    if (pname && Char(pname) == param) {
+      String *pval = Getattr(p, "value");
+      if (pval)
+	value = Char(pval);
+      break;
+    }
+  }
+  Delete(plist);
+  return value;
+}
+
 std::string PyDocConverter::translateSubtree(DoxygenEntity &doxygenEntity) {
   std::string translatedComment;
 
@@ -456,7 +488,7 @@
 void PyDocConverter::translateEntity(DoxygenEntity &doxyEntity, std::string &translatedComment) {
   // check if we have needed handler and call it
   std::map<std::string, std::pair<tagHandler, std::string> >::iterator it;
-  it = tagHandlers.find(doxyEntity.typeOfEntity);
+  it = tagHandlers.find(getBaseCommand(doxyEntity.typeOfEntity));
   if (it != tagHandlers.end())
     (this->*(it->second.first)) (doxyEntity, translatedComment, it->second.second);
 }
@@ -531,19 +563,29 @@
 
   trimWhitespace(translatedComment);
 
-  // Use the current indent for the code-block line itself.
-  translatedComment += indent.getFirstLineIndent();
-
-  // Go out on a limb and assume that examples in the C or C++ sources use C++.
-  // In the worst case, we'll highlight C code using C++ syntax which is not a
-  // big deal (TODO: handle Doxygen code command language argument).
-  translatedComment += ".. code-block:: c++\n\n";
-
-  // Specify the level of extra indentation that will be used for
-  // subsequent lines within the code block.  Note that the correct
-  // "starting indentation" is already present in the input, so we
-  // only need to add the desired code block indentation.
-  string codeIndent = m_indent;
+  // Check for an option given to the code command (e.g. code{.py}),
+  // and try to set the code-block language accordingly.
+  string option = getCommandOption(tag.typeOfEntity, '{', '}');
+  // Set up the language option to the code-block command, which can
+  // be any language supported by pygments:
+  string codeLanguage;
+  if (option == ".py")
+    // Other possibilities here are "default" or "python3".  In Sphinx
+    // 2.1.2, basic syntax doesn't render quite the same in these as
+    // with "python", which for basic keywords seems to provide
+    // slightly richer formatting.  Another option would be to leave
+    // the language empty, but testing with Sphinx 1.8.5 has produced
+    // an error "1 argument required".
+    codeLanguage = "python";
+  else if (option == ".java")
+    codeLanguage = "java";
+  else if (option == ".c")
+    codeLanguage = "c";
+  else
+    // If there is not a match, or if no option was given, go out on a
+    // limb and assume that the examples in the C or C++ sources use
+    // C++.
+    codeLanguage = "c++";
 
   std::string code;
   handleTagVerbatim(tag, code, arg);
@@ -552,6 +594,27 @@
   // command:
   eraseLeadingNewLine(code);
 
+  // Check for python doctest blocks, and treat them specially:
+  bool isDocTestBlock = false;
+  size_t startPos;
+  // ">>>" would normally appear at the beginning, but doxygen comment
+  // style may have space in front, so skip leading whitespace
+  if ((startPos=code.find_first_not_of(" \t")) != string::npos && code.substr(startPos,3) == ">>>")
+    isDocTestBlock = true;
+
+  string codeIndent;
+  if (! isDocTestBlock) {
+    // Use the current indent for the code-block line itself.
+    translatedComment += indent.getFirstLineIndent();
+    translatedComment += ".. code-block:: " + codeLanguage + "\n\n";
+
+    // Specify the level of extra indentation that will be used for
+    // subsequent lines within the code block.  Note that the correct
+    // "starting indentation" is already present in the input, so we
+    // only need to add the desired code block indentation.
+    codeIndent = m_indent;
+  }
+
   translatedComment += codeIndent;
   for (size_t n = 0; n < code.length(); n++) {
     if (code[n] == '\n') {
@@ -636,8 +699,26 @@
   const std::string &paramName = paramNameEntity.data;
 
   const std::string paramType = getParamType(paramName);
+  const std::string paramValue = getParamValue(paramName);
+
+  // Get command option, e.g. "in", "out", or "in,out"
+  string commandOpt = getCommandOption(tag.typeOfEntity, '[', ']');
+  if (commandOpt == "in,out") commandOpt = "in/out";
+
+  // If provided, append the parameter direction to the type
+  // information via a suffix:
+  std::string suffix;
+  if (commandOpt.size() > 0)
+    suffix = ", " + commandOpt;
+  
+  // If the parameter has a default value, flag it as optional in the
+  // generated type definition.  Particularly helpful when the python
+  // call is generated with *args, **kwargs.
+  if (paramValue.size() > 0)
+    suffix += ", optional";  
+
   if (!paramType.empty()) {
-    translatedComment += ":type " + paramName + ": " + paramType + "\n";
+    translatedComment += ":type " + paramName + ": " + paramType + suffix + "\n";
     translatedComment += indent.getFirstLineIndent();
   }
 
@@ -861,7 +942,7 @@
       for (size_t realOverloadCount = 0; realOverloadCount < allDocumentation.size(); realOverloadCount++) {
         if (realOverloadCount != 0) {
           // separate it from the preceding one.
-          concatDocString << "\n" << indentStr << "|\n\n";
+          concatDocString << '\n' << indentStr << "|\n\n";
         }
 
         oneDoc = allDocumentation[realOverloadCount];
@@ -909,3 +990,4 @@
 
   return NewString(pyDocString.c_str());
 }
+
diff --git a/Source/Doxygen/pydoc.h b/Source/Doxygen/pydoc.h
index df8997d..880ee30 100644
--- a/Source/Doxygen/pydoc.h
+++ b/Source/Doxygen/pydoc.h
@@ -4,15 +4,15 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * pydoc.h
  *
  * Module to return documentation for nodes formatted for PyDoc
  * ----------------------------------------------------------------------------- */
 
-#ifndef PYDOCCONVERTER_H_
-#define PYDOCCONVERTER_H_
+#ifndef SWIG_PYDOC_H
+#define SWIG_PYDOC_H
 
 #include <list>
 #include <string>
@@ -178,6 +178,11 @@
    */
   std::string getParamType(std::string name);
 
+  /*
+   * Simple helper function to retrieve the parameter value
+   */
+  std::string getParamValue(std::string name);
+
 private:
   // temporary thing, should be refactored somehow
   Node *currentNode;
@@ -190,7 +195,7 @@
   typedef std::map<std::string, std::pair<tagHandler, std::string> >TagHandlersMap;
   static TagHandlersMap tagHandlers;
 
-  // this contains the sections tittles, like 'Arguments:' or 'Notes:', that are printed only once
+  // this contains the sections titles, like 'Arguments:' or 'Notes:', that are printed only once
   static std::map<std::string, std::string> sectionTitles;
 
   // Helper functions for fillStaticTables(): make a new tag handler object.
diff --git a/Source/Include/swigconfig.h.in b/Source/Include/swigconfig.h.in
index 192c7d3..12bacec 100644
--- a/Source/Include/swigconfig.h.in
+++ b/Source/Include/swigconfig.h.in
@@ -3,6 +3,18 @@
 /* define if the Boost library is available */
 #undef HAVE_BOOST
 
+/* define if the compiler supports basic C++11 syntax */
+#undef HAVE_CXX11
+
+/* define if the compiler supports basic C++14 syntax */
+#undef HAVE_CXX14
+
+/* define if the compiler supports basic C++17 syntax */
+#undef HAVE_CXX17
+
+/* define if the compiler supports basic C++20 syntax */
+#undef HAVE_CXX20
+
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
@@ -12,18 +24,15 @@
 /* Define to 1 if you have the `dld' library (-ldld). */
 #undef HAVE_LIBDLD
 
-/* Define to 1 if you have the <memory.h> header file. */
-#undef HAVE_MEMORY_H
-
-/* Define if you have PCRE library */
+/* Define if you have PCRE2 library */
 #undef HAVE_PCRE
 
-/* Define if popen is available */
-#undef HAVE_POPEN
-
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
+/* Define to 1 if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
 /* Define to 1 if you have the <stdlib.h> header file. */
 #undef HAVE_STDLIB_H
 
@@ -63,10 +72,9 @@
 /* Define to the version of this package. */
 #undef PACKAGE_VERSION
 
-/* The size of `void *', as computed by sizeof. */
-#undef SIZEOF_VOID_P
-
-/* Define to 1 if you have the ANSI C header files. */
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
+   required in a freestanding environment). This macro is provided for
+   backward compatibility; new code need not use it. */
 #undef STDC_HEADERS
 
 /* Compiler that built SWIG */
diff --git a/Source/Include/swigwarn.h b/Source/Include/swigwarn.h
index a08693a..6edacbd 100644
--- a/Source/Include/swigwarn.h
+++ b/Source/Include/swigwarn.h
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * swigwarn.h
  *
@@ -22,38 +22,38 @@
  * This file is used as the input for generating Lib/swigwarn.swg.
  * ----------------------------------------------------------------------------- */
 
-#ifndef SWIGWARN_H_
-#define SWIGWARN_H_
+#ifndef SWIG_SWIGWARN_H
+#define SWIG_SWIGWARN_H
 
 #define WARN_NONE                     0
 
 /* -- Deprecated features -- */
 
-#define WARN_DEPRECATED_EXTERN        101
-#define WARN_DEPRECATED_VAL           102
-#define WARN_DEPRECATED_OUT           103
-#define WARN_DEPRECATED_DISABLEDOC    104
-#define WARN_DEPRECATED_ENABLEDOC     105
-#define WARN_DEPRECATED_DOCONLY       106
-#define WARN_DEPRECATED_STYLE         107
-#define WARN_DEPRECATED_LOCALSTYLE    108
-#define WARN_DEPRECATED_TITLE         109
-#define WARN_DEPRECATED_SECTION       110
-#define WARN_DEPRECATED_SUBSECTION    111
-#define WARN_DEPRECATED_SUBSUBSECTION 112
-#define WARN_DEPRECATED_ADDMETHODS    113
-#define WARN_DEPRECATED_READONLY      114
-#define WARN_DEPRECATED_READWRITE     115
-#define WARN_DEPRECATED_EXCEPT        116
-#define WARN_DEPRECATED_NEW           117
-#define WARN_DEPRECATED_EXCEPT_TM     118
-#define WARN_DEPRECATED_IGNORE_TM     119
-#define WARN_DEPRECATED_OPTC          120
-#define WARN_DEPRECATED_NAME          121
-#define WARN_DEPRECATED_NOEXTERN      122
-#define WARN_DEPRECATED_NODEFAULT     123
-#define WARN_DEPRECATED_TYPEMAP_LANG  124
-#define WARN_DEPRECATED_INPUT_FILE    125
+/* Unused since 4.2.0: #define WARN_DEPRECATED_EXTERN        101 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_VAL           102 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_OUT           103 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_DISABLEDOC    104 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_ENABLEDOC     105 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_DOCONLY       106 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_STYLE         107 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_LOCALSTYLE    108 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_TITLE         109 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_SECTION       110 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_SUBSECTION    111 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_SUBSUBSECTION 112 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_ADDMETHODS    113 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_READONLY      114 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_READWRITE     115 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_EXCEPT        116 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_NEW           117 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_EXCEPT_TM     118 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_IGNORE_TM     119 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_OPTC          120 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_NAME          121 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_NOEXTERN      122 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_NODEFAULT     123 */
+/* Unused since 4.1.0: #define WARN_DEPRECATED_TYPEMAP_LANG  124 */
+/* Unused since 4.2.0: #define WARN_DEPRECATED_INPUT_FILE    125 */
 #define WARN_DEPRECATED_NESTED_WORKAROUND 126
 
 /* -- Preprocessor -- */
@@ -72,17 +72,17 @@
 #define WARN_PARSE_EXTEND_UNDEF       303
 #define WARN_PARSE_UNSUPPORTED_VALUE  304
 #define WARN_PARSE_BAD_VALUE          305
-#define WARN_PARSE_PRIVATE            306
-#define WARN_PARSE_BAD_DEFAULT        307
+/* Unused since 1.3.32: #define WARN_PARSE_PRIVATE            306 */
+/* Unused since 4.2.0: #define WARN_PARSE_BAD_DEFAULT        307 */
 #define WARN_PARSE_NAMESPACE_ALIAS    308
 #define WARN_PARSE_PRIVATE_INHERIT    309
-#define WARN_PARSE_TEMPLATE_REPEAT    310
-#define WARN_PARSE_TEMPLATE_PARTIAL   311
+/* Unused since 1.3.18: #define WARN_PARSE_TEMPLATE_REPEAT    310 */
+/* Unused since 1.3.18: #define WARN_PARSE_TEMPLATE_PARTIAL   311 */
 #define WARN_PARSE_UNNAMED_NESTED_CLASS 312
 #define WARN_PARSE_UNDEFINED_EXTERN   313
 #define WARN_PARSE_KEYWORD            314
 #define WARN_PARSE_USING_UNDEF        315
-#define WARN_PARSE_MODULE_REPEAT      316
+/* Unused since 1.3.18: #define WARN_PARSE_MODULE_REPEAT      316 */
 #define WARN_PARSE_TEMPLATE_SP_UNDEF  317
 #define WARN_PARSE_TEMPLATE_AMBIG     318
 #define WARN_PARSE_NO_ACCESS          319
@@ -93,11 +93,17 @@
 #define WARN_PARSE_NESTED_TEMPLATE    324
 #define WARN_PARSE_NAMED_NESTED_CLASS 325
 #define WARN_PARSE_EXTEND_NAME        326
+#define WARN_PARSE_EXTERN_TEMPLATE    327
+#define WARN_PARSE_ASSIGNED_VALUE     328
+#define WARN_PARSE_USING_CONSTRUCTOR  329
 
 #define WARN_CPP11_LAMBDA             340
-#define WARN_CPP11_ALIAS_DECLARATION  341  /* redundant now */
-#define WARN_CPP11_ALIAS_TEMPLATE     342  /* redundant now */
-#define WARN_CPP11_VARIADIC_TEMPLATE  343
+/* Unused since 3.0.11: #define WARN_CPP11_ALIAS_DECLARATION  341 */
+/* Unused since 3.0.11: #define WARN_CPP11_ALIAS_TEMPLATE     342 */
+/* Unused since 4.2.0: #define WARN_CPP11_VARIADIC_TEMPLATE  343 */
+#define WARN_CPP11_DECLTYPE           344
+#define WARN_CPP14_AUTO               345
+#define WARN_CPP11_AUTO               346
 
 #define WARN_IGNORE_OPERATOR_NEW        350	/* new */
 #define WARN_IGNORE_OPERATOR_DELETE     351	/* delete */
@@ -146,8 +152,9 @@
 #define WARN_IGNORE_OPERATOR_NEWARR     394	/* new [] */
 #define WARN_IGNORE_OPERATOR_DELARR     395	/* delete [] */
 #define WARN_IGNORE_OPERATOR_REF        396	/* operator *() */
+#define WARN_IGNORE_OPERATOR_LTEQUALGT  397	/* <=> */
 
-/* 394-399 are reserved */
+/* please leave 350-399 free for WARN_IGNORE_OPERATOR_* */
 
 /* -- Type system and typemaps -- */
 
@@ -157,11 +164,12 @@
 #define WARN_TYPE_REDEFINED           404
 #define WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED 405
 
-#define WARN_TYPEMAP_SOURCETARGET     450
+/* Unused since 4.1.0: #define WARN_TYPEMAP_SOURCETARGET     450 */
 #define WARN_TYPEMAP_CHARLEAK         451
-#define WARN_TYPEMAP_SWIGTYPE         452
+/* Unused since 1.3.32: #define WARN_TYPEMAP_SWIGTYPE         452 */
 #define WARN_TYPEMAP_APPLY_UNDEF      453
 #define WARN_TYPEMAP_SWIGTYPELEAK     454
+#define WARN_TYPEMAP_WCHARLEAK        455
 
 #define WARN_TYPEMAP_IN_UNDEF         460
 #define WARN_TYPEMAP_OUT_UNDEF        461
@@ -196,7 +204,7 @@
 #define WARN_LANG_NATIVE_UNIMPL       507
 #define WARN_LANG_DEREF_SHADOW        508
 #define WARN_LANG_OVERLOAD_SHADOW     509
-#define WARN_LANG_FRIEND_IGNORE       510
+#define WARN_LANG_FRIEND_IGNORE       510 /* No longer issued */
 #define WARN_LANG_OVERLOAD_KEYWORD    511
 #define WARN_LANG_OVERLOAD_CONST      512
 #define WARN_LANG_CLASS_UNNAMED       513
@@ -212,6 +220,7 @@
 #define WARN_LANG_EXTEND_DESTRUCTOR   523
 #define WARN_LANG_EXPERIMENTAL        524
 #define WARN_LANG_DIRECTOR_FINAL      525
+#define WARN_LANG_USING_NAME_DIFFERENT 526
 
 /* -- Doxygen comments -- */
 
@@ -223,7 +232,7 @@
 #define WARN_DOXYGEN_UNKNOWN_CHARACTER        565
 #define WARN_DOXYGEN_UNEXPECTED_ITERATOR_VALUE  566
 
-/* -- Reserved (600-799) -- */
+/* -- Reserved (600-699) -- */
 
 /* -- Language module specific warnings (700 - 899) -- */
 
@@ -253,7 +262,12 @@
 
 #define WARN_PYTHON_INDENT_MISMATCH           740
 
-/* please leave 740-759 free for Python */
+/* please leave 740-749 free for Python */
+
+/* Unused since 4.2.0: #define WARN_R_MISSING_RTYPECHECK_TYPEMAP     750 */
+#define WARN_R_TYPEMAP_RTYPECHECK_UNDEF       751
+
+/* please leave 750-759 free for R */
 
 #define WARN_RUBY_WRONG_NAME                  801
 #define WARN_RUBY_MULTIPLE_INHERITANCE        802
@@ -277,6 +291,7 @@
 #define WARN_JAVA_TYPEMAP_DIRECTORIN_NODESC   824
 #define WARN_JAVA_NO_DIRECTORCONNECT_ATTR     825
 #define WARN_JAVA_NSPACE_WITHOUT_PACKAGE      826
+#define WARN_JAVA_TYPEMAP_INTERFACEMODIFIERS_UNDEF 827
 
 /* please leave 810-829 free for Java */
 
@@ -297,26 +312,15 @@
 #define WARN_CSHARP_EXCODE                    844
 #define WARN_CSHARP_CANTHROW                  845
 #define WARN_CSHARP_NO_DIRECTORCONNECT_ATTR   846
+#define WARN_CSHARP_TYPEMAP_INTERFACEMODIFIERS_UNDEF 847
 
 /* please leave 830-849 free for C# */
 
-#define WARN_MODULA3_TYPEMAP_TYPE_UNDEF        850
-#define WARN_MODULA3_TYPEMAP_GETCPTR_UNDEF     851
-#define WARN_MODULA3_TYPEMAP_CLASSMOD_UNDEF    852
-#define WARN_MODULA3_TYPEMAP_PTRCONSTMOD_UNDEF 853
-#define WARN_MODULA3_TYPEMAP_MULTIPLE_RETURN   854
-#define WARN_MODULA3_MULTIPLE_INHERITANCE      855
-#define WARN_MODULA3_TYPECONSTRUCTOR_UNKNOWN   856
-#define WARN_MODULA3_UNKNOWN_PRAGMA            857
-#define WARN_MODULA3_BAD_ENUMERATION           858
-#define WARN_MODULA3_DOUBLE_ID                 859
-#define WARN_MODULA3_BAD_IMPORT                860
-
-/* please leave 850-869 free for Modula 3 */
+/* 850-860 were used by Modula 3 (removed in SWIG 4.1.0) - avoid reusing for now */
 
 #define WARN_PHP_MULTIPLE_INHERITANCE         870
 #define WARN_PHP_UNKNOWN_PRAGMA               871
-#define WARN_PHP_PUBLIC_BASE                  872
+/* Unused since 4.1.0: define WARN_PHP_PUBLIC_BASE                  872 */
 
 /* please leave 870-889 free for PHP */
 
diff --git a/Source/Makefile.am b/Source/Makefile.am
index 5cfb888..94e85e7 100644
--- a/Source/Makefile.am
+++ b/Source/Makefile.am
@@ -6,8 +6,6 @@
 SOURCE_DIR=$(top_srcdir)/Source
 BUILD_SOURCE_DIR=$(top_builddir)/Source
 
-SWIG_CXX_DEFS = @SWILL@
-
 AM_CPPFLAGS =	-I$(BUILD_SOURCE_DIR)/Include	\
 		-I$(BUILD_SOURCE_DIR)/CParse	\
 		-I$(SOURCE_DIR)/Include		\
@@ -18,13 +16,14 @@
 		-I$(SOURCE_DIR)/Swig		\
 		-I$(SOURCE_DIR)/Modules
 
-AM_CXXFLAGS =	$(SWIG_CXX_DEFS)
+AM_CXXFLAGS =
 
-AM_YFLAGS = -d
+AM_YFLAGS = -d -Wall -Werror
 
-BUILT_SOURCES = CParse/parser.h
+
+BUILT_SOURCES = CParse/parser.c CParse/parser.h
 eswig_SOURCES =	CParse/cscanner.c		\
-		CParse/parser.y			\
+		CParse/parser.c			\
 		CParse/templ.c			\
 		CParse/util.c			\
 		DOH/base.c			\
@@ -46,7 +45,6 @@
 		Doxygen/pydoc.cxx		\
 		Doxygen/pydoc.h			\
 		Modules/allocate.cxx		\
-		Modules/browser.cxx		\
 		Modules/contract.cxx		\
 		Modules/csharp.cxx		\
 		Modules/d.cxx			\
@@ -98,10 +96,9 @@
 		Swig/wrapfunc.c
 
 bin_PROGRAMS = eswig
-eswig_LDADD   = @SWIGLIBS@
 
-# Override the link stage to avoid using Libtool
-CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+CParse/parser.c CParse/parser.h: CParse/parser.y
+	$(BISON) $(AM_YFLAGS) $(YFLAGS) --output=CParse/parser.c $(srcdir)/CParse/parser.y
 
 # The executable is copied to the root directory for installation and running the test-suite.
 # This occurs on each invocation of make and is a step towards providing support for multiple
diff --git a/Source/Makefile.in b/Source/Makefile.in
index c82cb4b..9021f3a 100644
--- a/Source/Makefile.in
+++ b/Source/Makefile.in
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.5 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2021 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -96,8 +96,8 @@
 	$(top_srcdir)/Tools/config/ac_define_dir.m4 \
 	$(top_srcdir)/Tools/config/ax_boost_base.m4 \
 	$(top_srcdir)/Tools/config/ax_compare_version.m4 \
-	$(top_srcdir)/Tools/config/ax_cxx_compile_stdcxx_11.m4 \
 	$(top_srcdir)/Tools/config/ax_path_generic.m4 \
+	$(top_srcdir)/Tools/config/m4_ax_cxx_compile_stdcxx.m4 \
 	$(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
 	$(ACLOCAL_M4)
@@ -117,33 +117,32 @@
 	Doxygen/doxyentity.$(OBJEXT) Doxygen/doxyparser.$(OBJEXT) \
 	Doxygen/doxytranslator.$(OBJEXT) Doxygen/javadoc.$(OBJEXT) \
 	Doxygen/pydoc.$(OBJEXT) Modules/allocate.$(OBJEXT) \
-	Modules/browser.$(OBJEXT) Modules/contract.$(OBJEXT) \
-	Modules/csharp.$(OBJEXT) Modules/d.$(OBJEXT) \
-	Modules/directors.$(OBJEXT) Modules/emit.$(OBJEXT) \
-	Modules/go.$(OBJEXT) Modules/guile.$(OBJEXT) \
-	Modules/interface.$(OBJEXT) Modules/java.$(OBJEXT) \
-	Modules/javascript.$(OBJEXT) Modules/lang.$(OBJEXT) \
-	Modules/lua.$(OBJEXT) Modules/main.$(OBJEXT) \
-	Modules/mzscheme.$(OBJEXT) Modules/nested.$(OBJEXT) \
-	Modules/ocaml.$(OBJEXT) Modules/octave.$(OBJEXT) \
-	Modules/overload.$(OBJEXT) Modules/perl5.$(OBJEXT) \
-	Modules/php.$(OBJEXT) Modules/python.$(OBJEXT) \
-	Modules/r.$(OBJEXT) Modules/ruby.$(OBJEXT) \
-	Modules/scilab.$(OBJEXT) Modules/swigmain.$(OBJEXT) \
-	Modules/tcl8.$(OBJEXT) Modules/typepass.$(OBJEXT) \
-	Modules/utils.$(OBJEXT) Modules/xml.$(OBJEXT) \
-	Preprocessor/cpp.$(OBJEXT) Preprocessor/expr.$(OBJEXT) \
-	Swig/cwrap.$(OBJEXT) Swig/deprecate.$(OBJEXT) \
-	Swig/error.$(OBJEXT) Swig/extend.$(OBJEXT) \
-	Swig/fragment.$(OBJEXT) Swig/getopt.$(OBJEXT) \
-	Swig/include.$(OBJEXT) Swig/misc.$(OBJEXT) \
-	Swig/naming.$(OBJEXT) Swig/parms.$(OBJEXT) \
+	Modules/contract.$(OBJEXT) Modules/csharp.$(OBJEXT) \
+	Modules/d.$(OBJEXT) Modules/directors.$(OBJEXT) \
+	Modules/emit.$(OBJEXT) Modules/go.$(OBJEXT) \
+	Modules/guile.$(OBJEXT) Modules/interface.$(OBJEXT) \
+	Modules/java.$(OBJEXT) Modules/javascript.$(OBJEXT) \
+	Modules/lang.$(OBJEXT) Modules/lua.$(OBJEXT) \
+	Modules/main.$(OBJEXT) Modules/mzscheme.$(OBJEXT) \
+	Modules/nested.$(OBJEXT) Modules/ocaml.$(OBJEXT) \
+	Modules/octave.$(OBJEXT) Modules/overload.$(OBJEXT) \
+	Modules/perl5.$(OBJEXT) Modules/php.$(OBJEXT) \
+	Modules/python.$(OBJEXT) Modules/r.$(OBJEXT) \
+	Modules/ruby.$(OBJEXT) Modules/scilab.$(OBJEXT) \
+	Modules/swigmain.$(OBJEXT) Modules/tcl8.$(OBJEXT) \
+	Modules/typepass.$(OBJEXT) Modules/utils.$(OBJEXT) \
+	Modules/xml.$(OBJEXT) Preprocessor/cpp.$(OBJEXT) \
+	Preprocessor/expr.$(OBJEXT) Swig/cwrap.$(OBJEXT) \
+	Swig/deprecate.$(OBJEXT) Swig/error.$(OBJEXT) \
+	Swig/extend.$(OBJEXT) Swig/fragment.$(OBJEXT) \
+	Swig/getopt.$(OBJEXT) Swig/include.$(OBJEXT) \
+	Swig/misc.$(OBJEXT) Swig/naming.$(OBJEXT) Swig/parms.$(OBJEXT) \
 	Swig/scanner.$(OBJEXT) Swig/stype.$(OBJEXT) \
 	Swig/symbol.$(OBJEXT) Swig/tree.$(OBJEXT) \
 	Swig/typemap.$(OBJEXT) Swig/typeobj.$(OBJEXT) \
 	Swig/typesys.$(OBJEXT) Swig/wrapfunc.$(OBJEXT)
 eswig_OBJECTS = $(am_eswig_OBJECTS)
-eswig_DEPENDENCIES =
+eswig_LDADD = $(LDADD)
 AM_V_P = $(am__v_P_@AM_V@)
 am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
 am__v_P_0 = false
@@ -169,32 +168,31 @@
 	Doxygen/$(DEPDIR)/doxyparser.Po \
 	Doxygen/$(DEPDIR)/doxytranslator.Po \
 	Doxygen/$(DEPDIR)/javadoc.Po Doxygen/$(DEPDIR)/pydoc.Po \
-	Modules/$(DEPDIR)/allocate.Po Modules/$(DEPDIR)/browser.Po \
-	Modules/$(DEPDIR)/contract.Po Modules/$(DEPDIR)/csharp.Po \
-	Modules/$(DEPDIR)/d.Po Modules/$(DEPDIR)/directors.Po \
-	Modules/$(DEPDIR)/emit.Po Modules/$(DEPDIR)/go.Po \
-	Modules/$(DEPDIR)/guile.Po Modules/$(DEPDIR)/interface.Po \
-	Modules/$(DEPDIR)/java.Po Modules/$(DEPDIR)/javascript.Po \
-	Modules/$(DEPDIR)/lang.Po Modules/$(DEPDIR)/lua.Po \
-	Modules/$(DEPDIR)/main.Po Modules/$(DEPDIR)/mzscheme.Po \
-	Modules/$(DEPDIR)/nested.Po Modules/$(DEPDIR)/ocaml.Po \
-	Modules/$(DEPDIR)/octave.Po Modules/$(DEPDIR)/overload.Po \
-	Modules/$(DEPDIR)/perl5.Po Modules/$(DEPDIR)/php.Po \
-	Modules/$(DEPDIR)/python.Po Modules/$(DEPDIR)/r.Po \
-	Modules/$(DEPDIR)/ruby.Po Modules/$(DEPDIR)/scilab.Po \
-	Modules/$(DEPDIR)/swigmain.Po Modules/$(DEPDIR)/tcl8.Po \
-	Modules/$(DEPDIR)/typepass.Po Modules/$(DEPDIR)/utils.Po \
-	Modules/$(DEPDIR)/xml.Po Preprocessor/$(DEPDIR)/cpp.Po \
-	Preprocessor/$(DEPDIR)/expr.Po Swig/$(DEPDIR)/cwrap.Po \
-	Swig/$(DEPDIR)/deprecate.Po Swig/$(DEPDIR)/error.Po \
-	Swig/$(DEPDIR)/extend.Po Swig/$(DEPDIR)/fragment.Po \
-	Swig/$(DEPDIR)/getopt.Po Swig/$(DEPDIR)/include.Po \
-	Swig/$(DEPDIR)/misc.Po Swig/$(DEPDIR)/naming.Po \
-	Swig/$(DEPDIR)/parms.Po Swig/$(DEPDIR)/scanner.Po \
-	Swig/$(DEPDIR)/stype.Po Swig/$(DEPDIR)/symbol.Po \
-	Swig/$(DEPDIR)/tree.Po Swig/$(DEPDIR)/typemap.Po \
-	Swig/$(DEPDIR)/typeobj.Po Swig/$(DEPDIR)/typesys.Po \
-	Swig/$(DEPDIR)/wrapfunc.Po
+	Modules/$(DEPDIR)/allocate.Po Modules/$(DEPDIR)/contract.Po \
+	Modules/$(DEPDIR)/csharp.Po Modules/$(DEPDIR)/d.Po \
+	Modules/$(DEPDIR)/directors.Po Modules/$(DEPDIR)/emit.Po \
+	Modules/$(DEPDIR)/go.Po Modules/$(DEPDIR)/guile.Po \
+	Modules/$(DEPDIR)/interface.Po Modules/$(DEPDIR)/java.Po \
+	Modules/$(DEPDIR)/javascript.Po Modules/$(DEPDIR)/lang.Po \
+	Modules/$(DEPDIR)/lua.Po Modules/$(DEPDIR)/main.Po \
+	Modules/$(DEPDIR)/mzscheme.Po Modules/$(DEPDIR)/nested.Po \
+	Modules/$(DEPDIR)/ocaml.Po Modules/$(DEPDIR)/octave.Po \
+	Modules/$(DEPDIR)/overload.Po Modules/$(DEPDIR)/perl5.Po \
+	Modules/$(DEPDIR)/php.Po Modules/$(DEPDIR)/python.Po \
+	Modules/$(DEPDIR)/r.Po Modules/$(DEPDIR)/ruby.Po \
+	Modules/$(DEPDIR)/scilab.Po Modules/$(DEPDIR)/swigmain.Po \
+	Modules/$(DEPDIR)/tcl8.Po Modules/$(DEPDIR)/typepass.Po \
+	Modules/$(DEPDIR)/utils.Po Modules/$(DEPDIR)/xml.Po \
+	Preprocessor/$(DEPDIR)/cpp.Po Preprocessor/$(DEPDIR)/expr.Po \
+	Swig/$(DEPDIR)/cwrap.Po Swig/$(DEPDIR)/deprecate.Po \
+	Swig/$(DEPDIR)/error.Po Swig/$(DEPDIR)/extend.Po \
+	Swig/$(DEPDIR)/fragment.Po Swig/$(DEPDIR)/getopt.Po \
+	Swig/$(DEPDIR)/include.Po Swig/$(DEPDIR)/misc.Po \
+	Swig/$(DEPDIR)/naming.Po Swig/$(DEPDIR)/parms.Po \
+	Swig/$(DEPDIR)/scanner.Po Swig/$(DEPDIR)/stype.Po \
+	Swig/$(DEPDIR)/symbol.Po Swig/$(DEPDIR)/tree.Po \
+	Swig/$(DEPDIR)/typemap.Po Swig/$(DEPDIR)/typeobj.Po \
+	Swig/$(DEPDIR)/typesys.Po Swig/$(DEPDIR)/wrapfunc.Po
 am__mv = mv -f
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
 	$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
@@ -215,18 +213,12 @@
 am__v_CXX_0 = @echo "  CXX     " $@;
 am__v_CXX_1 = 
 CXXLD = $(CXX)
+CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \
+	-o $@
 AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
 am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
 am__v_CXXLD_0 = @echo "  CXXLD   " $@;
 am__v_CXXLD_1 = 
-am__yacc_c2h = sed -e s/cc$$/hh/ -e s/cpp$$/hpp/ -e s/cxx$$/hxx/ \
-		   -e s/c++$$/h++/ -e s/c$$/h/
-YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS)
-AM_V_YACC = $(am__v_YACC_@AM_V@)
-am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@)
-am__v_YACC_0 = @echo "  YACC    " $@;
-am__v_YACC_1 = 
-YLWRAP = $(top_srcdir)/Tools/config/ylwrap
 SOURCES = $(eswig_SOURCES)
 DIST_SOURCES = $(eswig_SOURCES)
 am__can_run_installinfo = \
@@ -251,12 +243,8 @@
   unique=`for i in $$list; do \
     if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
   done | $(am__uniquify_input)`
-ETAGS = etags
-CTAGS = ctags
 am__DIST_COMMON = $(srcdir)/Makefile.in \
-	$(top_srcdir)/Tools/config/depcomp \
-	$(top_srcdir)/Tools/config/ylwrap CParse/parser.c \
-	CParse/parser.h README
+	$(top_srcdir)/Tools/config/depcomp README
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ADB = @ADB@
@@ -268,6 +256,7 @@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
+BISON = @BISON@
 BOOST_CPPFLAGS = @BOOST_CPPFLAGS@
 BOOST_LDFLAGS = @BOOST_LDFLAGS@
 CAMLP4 = @CAMLP4@
@@ -277,6 +266,7 @@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
+CSCOPE = @CSCOPE@
 CSHARPCFLAGS = @CSHARPCFLAGS@
 CSHARPCILINTERPRETER = @CSHARPCILINTERPRETER@
 CSHARPCILINTERPRETER_FLAGS = @CSHARPCILINTERPRETER_FLAGS@
@@ -285,14 +275,13 @@
 CSHARPDYNAMICLINKING = @CSHARPDYNAMICLINKING@
 CSHARPLIBRARYPREFIX = @CSHARPLIBRARYPREFIX@
 CSHARPSO = @CSHARPSO@
+CTAGS = @CTAGS@
 CXX = @CXX@
 CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
 CXXSHARED = @CXXSHARED@
 CYGPATH_W = @CYGPATH_W@
-D1COMPILER = @D1COMPILER@
 D2COMPILER = @D2COMPILER@
-DDEFAULTVERSION = @DDEFAULTVERSION@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 DLIBPREFIX = @DLIBPREFIX@
@@ -301,6 +290,7 @@
 ECHO_T = @ECHO_T@
 EGREP = @EGREP@
 ENABLE_CCACHE = @ENABLE_CCACHE@
+ETAGS = @ETAGS@
 EXEEXT = @EXEEXT@
 EXTRA_CLEAN = @EXTRA_CLEAN@
 GCCGO = @GCCGO@
@@ -320,7 +310,10 @@
 GUILE_CONFIG = @GUILE_CONFIG@
 GUILE_LIBS = @GUILE_LIBS@
 GUILE_SO = @GUILE_SO@
-HAVE_CXX11_COMPILER = @HAVE_CXX11_COMPILER@
+HAVE_CXX11 = @HAVE_CXX11@
+HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX17 = @HAVE_CXX17@
+HAVE_CXX20 = @HAVE_CXX20@
 INSTALL = @INSTALL@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
@@ -337,13 +330,14 @@
 JAVALIBRARYPREFIX = @JAVALIBRARYPREFIX@
 JAVASO = @JAVASO@
 JAVA_CLASSPATH_SEP = @JAVA_CLASSPATH_SEP@
-JAVA_TOOLS_JAR = @JAVA_TOOLS_JAR@
+JAVA_SKIP_DOXYGEN_TEST_CASES = @JAVA_SKIP_DOXYGEN_TEST_CASES@
 JSCENABLED = @JSCENABLED@
 JSCOREDYNAMICLINKING = @JSCOREDYNAMICLINKING@
 JSCOREINC = @JSCOREINC@
 JSCOREVERSION = @JSCOREVERSION@
 JSINTERPRETERCXX = @JSINTERPRETERCXX@
 JSINTERPRETERLINKFLAGS = @JSINTERPRETERLINKFLAGS@
+JSNAPIENABLED = @JSNAPIENABLED@
 JSV8DYNAMICLINKING = @JSV8DYNAMICLINKING@
 JSV8ENABLED = @JSV8ENABLED@
 JSV8INC = @JSV8INC@
@@ -370,6 +364,8 @@
 NDKBUILD = @NDKBUILD@
 NODEGYP = @NODEGYP@
 NODEJS = @NODEJS@
+NODENAPI_DIR = @NODENAPI_DIR@
+NODENPM = @NODENPM@
 OBJEXT = @OBJEXT@
 OCAMLC = @OCAMLC@
 OCAMLDLGEN = @OCAMLDLGEN@
@@ -388,9 +384,12 @@
 PACKAGE_URL = @PACKAGE_URL@
 PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
-PCRE_CFLAGS = @PCRE_CFLAGS@
-PCRE_CONFIG = @PCRE_CONFIG@
-PCRE_LIBS = @PCRE_LIBS@
+PCHINCLUDEARG = @PCHINCLUDEARG@
+PCHINCLUDEEXT = @PCHINCLUDEEXT@
+PCHSUPPORT = @PCHSUPPORT@
+PCRE2_CFLAGS = @PCRE2_CFLAGS@
+PCRE2_CONFIG = @PCRE2_CONFIG@
+PCRE2_LIBS = @PCRE2_LIBS@
 PERL = @PERL@
 PERL5CCCDLFLAGS = @PERL5CCCDLFLAGS@
 PERL5CCDLFLAGS = @PERL5CCDLFLAGS@
@@ -402,10 +401,9 @@
 PHP = @PHP@
 PHPINC = @PHPINC@
 PHP_SO = @PHP_SO@
-PKGCONFIG = @PKGCONFIG@
+PKG_CONFIG = @PKG_CONFIG@
 PLATCFLAGS = @PLATCFLAGS@
 PLATCXXFLAGS = @PLATCXXFLAGS@
-PY2TO3 = @PY2TO3@
 PY3CONFIG = @PY3CONFIG@
 PY3INCLUDE = @PY3INCLUDE@
 PY3LIB = @PY3LIB@
@@ -432,6 +430,7 @@
 SCILAB = @SCILAB@
 SCILABINCLUDE = @SCILABINCLUDE@
 SCILABOPT = @SCILABOPT@
+SCILAB_VERSION = @SCILAB_VERSION@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
@@ -456,22 +455,19 @@
 SKIP_TCL = @SKIP_TCL@
 SO = @SO@
 STRIP = @STRIP@
-SWIGLIBS = @SWIGLIBS@
 SWIG_LIB = @SWIG_LIB@
 SWIG_LIB_INSTALL = @SWIG_LIB_INSTALL@
 SWIG_LIB_PREINST = @SWIG_LIB_PREINST@
 SWIG_LIB_SET = @SWIG_LIB_SET@
-SWILL = @SWILL@
 TCLCXXSHARED = @TCLCXXSHARED@
 TCLDYNAMICLINKING = @TCLDYNAMICLINKING@
 TCLINCLUDE = @TCLINCLUDE@
 TCLLDSHARED = @TCLLDSHARED@
 TCLLIB = @TCLLIB@
+TCLLINK = @TCLLINK@
 TCL_SO = @TCL_SO@
 TRYLINKINGWITHCXX = @TRYLINKINGWITHCXX@
 VERSION = @VERSION@
-YACC = @YACC@
-YFLAGS = @YFLAGS@
 abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
@@ -531,7 +527,6 @@
 AUTOMAKE_OPTIONS = foreign nostdinc subdir-objects 1.7.2
 SOURCE_DIR = $(top_srcdir)/Source
 BUILD_SOURCE_DIR = $(top_builddir)/Source
-SWIG_CXX_DEFS = @SWILL@
 AM_CPPFLAGS = -I$(top_builddir) \
 		-I$(BUILD_SOURCE_DIR)/Include	\
 		-I$(BUILD_SOURCE_DIR)/CParse	\
@@ -543,11 +538,11 @@
 		-I$(SOURCE_DIR)/Swig		\
 		-I$(SOURCE_DIR)/Modules
 
-AM_CXXFLAGS = $(SWIG_CXX_DEFS)
-AM_YFLAGS = -d
-BUILT_SOURCES = CParse/parser.h
+AM_CXXFLAGS = 
+AM_YFLAGS = -d -Wall -Werror
+BUILT_SOURCES = CParse/parser.c CParse/parser.h
 eswig_SOURCES = CParse/cscanner.c		\
-		CParse/parser.y			\
+		CParse/parser.c			\
 		CParse/templ.c			\
 		CParse/util.c			\
 		DOH/base.c			\
@@ -569,7 +564,6 @@
 		Doxygen/pydoc.cxx		\
 		Doxygen/pydoc.h			\
 		Modules/allocate.cxx		\
-		Modules/browser.cxx		\
 		Modules/contract.cxx		\
 		Modules/csharp.cxx		\
 		Modules/d.cxx			\
@@ -620,10 +614,6 @@
 		Swig/typesys.c			\
 		Swig/wrapfunc.c
 
-eswig_LDADD = @SWIGLIBS@
-
-# Override the link stage to avoid using Libtool
-CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
 
 # Beautify the code.
 # Note that this works well on C code, but does some odd joining of lines for C++ code.
@@ -636,7 +626,7 @@
 	$(MAKE) $(AM_MAKEFLAGS) all-am
 
 .SUFFIXES:
-.SUFFIXES: .c .cxx .o .obj .y
+.SUFFIXES: .c .cxx .o .obj
 $(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
 	@for dep in $?; do \
 	  case '$(am__configure_deps)' in \
@@ -716,9 +706,6 @@
 	@: > CParse/$(DEPDIR)/$(am__dirstamp)
 CParse/cscanner.$(OBJEXT): CParse/$(am__dirstamp) \
 	CParse/$(DEPDIR)/$(am__dirstamp)
-CParse/parser.h: CParse/parser.c
-	@if test ! -f $@; then rm -f CParse/parser.c; else :; fi
-	@if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) CParse/parser.c; else :; fi
 CParse/parser.$(OBJEXT): CParse/$(am__dirstamp) \
 	CParse/$(DEPDIR)/$(am__dirstamp)
 CParse/templ.$(OBJEXT): CParse/$(am__dirstamp) \
@@ -765,8 +752,6 @@
 	@: > Modules/$(DEPDIR)/$(am__dirstamp)
 Modules/allocate.$(OBJEXT): Modules/$(am__dirstamp) \
 	Modules/$(DEPDIR)/$(am__dirstamp)
-Modules/browser.$(OBJEXT): Modules/$(am__dirstamp) \
-	Modules/$(DEPDIR)/$(am__dirstamp)
 Modules/contract.$(OBJEXT): Modules/$(am__dirstamp) \
 	Modules/$(DEPDIR)/$(am__dirstamp)
 Modules/csharp.$(OBJEXT): Modules/$(am__dirstamp) \
@@ -912,7 +897,6 @@
 @AMDEP_TRUE@@am__include@ @am__quote@Doxygen/$(DEPDIR)/javadoc.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@Doxygen/$(DEPDIR)/pydoc.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/allocate.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/browser.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/contract.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/csharp.Po@am__quote@ # am--include-marker
 @AMDEP_TRUE@@am__include@ @am__quote@Modules/$(DEPDIR)/d.Po@am__quote@ # am--include-marker
@@ -1001,9 +985,6 @@
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
-.y.c:
-	$(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE)
-
 ID: $(am__tagged_files)
 	$(am__define_uniq_tagged_files); mkid -fID $$unique
 tags: tags-am
@@ -1055,7 +1036,6 @@
 
 distclean-tags:
 	-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
 distdir: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) distdir-am
 
@@ -1099,7 +1079,8 @@
 	done
 install: $(BUILT_SOURCES)
 	$(MAKE) $(AM_MAKEFLAGS) install-am
-install-exec: install-exec-am
+install-exec: $(BUILT_SOURCES)
+	$(MAKE) $(AM_MAKEFLAGS) install-exec-am
 install-data: install-data-am
 uninstall: uninstall-am
 
@@ -1140,8 +1121,6 @@
 maintainer-clean-generic:
 	@echo "This command is intended for maintainers to use"
 	@echo "it deletes files that may require special tools to rebuild."
-	-rm -f CParse/parser.c
-	-rm -f CParse/parser.h
 	-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
 clean: clean-am
 
@@ -1166,7 +1145,6 @@
 	-rm -f Doxygen/$(DEPDIR)/javadoc.Po
 	-rm -f Doxygen/$(DEPDIR)/pydoc.Po
 	-rm -f Modules/$(DEPDIR)/allocate.Po
-	-rm -f Modules/$(DEPDIR)/browser.Po
 	-rm -f Modules/$(DEPDIR)/contract.Po
 	-rm -f Modules/$(DEPDIR)/csharp.Po
 	-rm -f Modules/$(DEPDIR)/d.Po
@@ -1279,7 +1257,6 @@
 	-rm -f Doxygen/$(DEPDIR)/javadoc.Po
 	-rm -f Doxygen/$(DEPDIR)/pydoc.Po
 	-rm -f Modules/$(DEPDIR)/allocate.Po
-	-rm -f Modules/$(DEPDIR)/browser.Po
 	-rm -f Modules/$(DEPDIR)/contract.Po
 	-rm -f Modules/$(DEPDIR)/csharp.Po
 	-rm -f Modules/$(DEPDIR)/d.Po
@@ -1346,7 +1323,7 @@
 
 uninstall-am: uninstall-binPROGRAMS
 
-.MAKE: all check install install-am install-strip
+.MAKE: all check install install-am install-exec install-strip
 
 .PHONY: CTAGS GTAGS TAGS all all-am all-local am--depfiles check \
 	check-am clean clean-binPROGRAMS clean-generic clean-local \
@@ -1365,6 +1342,9 @@
 .PRECIOUS: Makefile
 
 
+CParse/parser.c CParse/parser.h: CParse/parser.y
+	$(BISON) $(AM_YFLAGS) $(YFLAGS) --output=CParse/parser.c $(srcdir)/CParse/parser.y
+
 # The executable is copied to the root directory for installation and running the test-suite.
 # This occurs on each invocation of make and is a step towards providing support for multiple
 # build directories.
diff --git a/Source/Modules/allegrocl.cxx b/Source/Modules/allegrocl.cxx
deleted file mode 100644
index 97af186..0000000
--- a/Source/Modules/allegrocl.cxx
+++ /dev/null
@@ -1,2963 +0,0 @@
-/* ----------------------------------------------------------------------------- 
- * This file is part of SWIG, which is licensed as a whole under version 3 
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
- *
- * allegrocl.cxx
- *
- * ALLEGROCL language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-#include <ctype.h>
-
-// #define ALLEGROCL_DEBUG
-// #define ALLEGROCL_WRAP_DEBUG
-// #define ALLEGROCL_TYPE_DEBUG
-// #define ALLEGROCL_CLASS_DEBUG
-
-static const char *usage = "\
-Allegro CL Options (available with -allegrocl)\n\
-     -identifier-converter <type or funcname> - \n\
-                       Specifies the type of conversion to do on C identifiers to convert\n\
-                       them to symbols. There are two built-in converters: 'null' and\n\
-                       'lispify'. The default is 'null'. If you supply a name other\n\
-                       than one of the built-ins, then a function by that name will be\n\
-                       called to convert identifiers to symbols.\n\
-     -[no]cwrap      - Turn on or turn off generation of an intermediate C file when\n\
-                       creating a C interface. By default this is only done for C++ code.\n\
-     -isolate        - Define all SWIG helper functions in a package unique to this\n\
-                       module. Avoids redefinition warnings when loading multiple\n\
-                       SWIGged modules into the same running Allegro CL image.\n\
-";
-
-static File *f_cl = 0;
-String *f_clhead = NewString("");
-String *f_clwrap = NewString("(swig-in-package ())\n\n");
-static File *f_begin;
-static File *f_runtime;
-static File *f_cxx_header = 0;
-static File *f_cxx_wrapper = 0;
-
-static String *module_name = 0;
-static String *swig_package = 0;
-
-static String *identifier_converter = NewString("identifier-convert-null");
-
-static bool CWrap = true;	// generate wrapper file for C code by default. most correct.
-static bool Generate_Wrapper = false;
-static bool unique_swig_package = false;
-
-static SwigType *fwdref_ffi_type = NewString("__SWIGACL_FwdReference");
-
-static String *current_namespace = NewString("");
-static String *current_package = NewString("");
-static Hash *defined_namespace_packages = NewHash();
-static Node *in_class = 0;
-
-static Node *first_linked_type = 0;
-static Hash *defined_foreign_types = NewHash();
-static Hash *defined_foreign_ltypes = NewHash();
-
-static String *anon_type_name = NewString("anontype");
-static int anon_type_count = 0;
-
-// stub
-String *convert_literal(String *num_param, String *type, bool try_to_split = true);
-
-class ALLEGROCL:public Language {
-public:
-  virtual void main(int argc, char *argv[]);
-  virtual int top(Node *n);
-  virtual int functionWrapper(Node *n);
-  virtual int namespaceDeclaration(Node *n);
-  virtual int constructorHandler(Node *n);
-  virtual int destructorHandler(Node *n);
-  virtual int globalvariableHandler(Node *n);
-  virtual int variableWrapper(Node *n);
-  virtual int constantWrapper(Node *n);
-  virtual int memberfunctionHandler(Node *n);
-  virtual int membervariableHandler(Node *n);
-  virtual int classHandler(Node *n);
-  virtual int emit_one(Node *n);
-  virtual int enumDeclaration(Node *n);
-  virtual int enumvalueDeclaration(Node *n);
-  virtual int typedefHandler(Node *n);
-  virtual int classforwardDeclaration(Node *n);
-  virtual int templateDeclaration(Node *n);
-  virtual int validIdentifier(String *s);
-private:
-  int emit_defun(Node *n, File *f_cl);
-  int emit_dispatch_defun(Node *n);
-  int emit_buffered_defuns(Node *n);
-  int cClassHandler(Node *n);
-  int cppClassHandler(Node *n);
-};
-static ALLEGROCL *allegrocl = 0;
-
-static String *trim(String *str) {
-  char *c = Char(str);
-  while (*c != '\0' && isspace((int) *c))
-    ++c;
-  String *result = NewString(c);
-  Chop(result);
-  return result;
-}
-
-int is_integer(String *s) {
-  char *c = Char(s);
-  if (c[0] == '#' && (c[1] == 'x' || c[1] == 'o'))
-    c += 2;
-
-  while (*c) {
-    if (!isdigit(*c))
-      return 0;
-    c++;
-  }
-  return 1;
-}
-
-String *class_from_class_or_class_ref(String *type) {
-  SwigType *stripped = SwigType_strip_qualifiers(type);
-  if (SwigType_isclass(stripped))
-    return stripped;
-
-  if (SwigType_ispointer(stripped) || SwigType_isreference(stripped)) {
-    // Printf(stderr,"It is a pointer/reference. Is it a class?\n");
-    SwigType_pop(stripped);
-    if (SwigType_isclass(stripped)) {
-      return stripped;
-    }
-  }
-  return 0;
-}
-
-String *lookup_defined_foreign_type(String *k) {
-
-#ifdef ALLEGROCL_TYPE_DEBUG
-  Printf(stderr, "Looking up defined type '%s'.\n  Found: '%s'\n", k, Getattr(defined_foreign_types, k));
-#endif
-
-  return Getattr(defined_foreign_types, k);
-}
-
-String *listify_namespace(String *namespaze) {
-  if (Len(namespaze) == 0)
-    return NewString("()");
-  String *result = NewStringf("(\"%s\")", namespaze);
-  Replaceall(result, "::", "\" \"");
-  return result;
-}
-
-String *namespaced_name(Node *n, String *ns = current_namespace) {
-
-  return NewStringf("%s%s%s", ns, (Len(ns) != 0) ? "::" : "", Getattr(n, "sym:name"));
-}
-
-// "Namespace::Nested::Class2::Baz" -> "Baz"
-static String *strip_namespaces(String *str) {
-  return Swig_scopename_last(str);
-}
-
-void add_linked_type(Node *n) {
-#ifdef ALLEGROCL_CLASS_DEBUG
-  Printf(stderr, "Adding linked node of type: %s(%s) %s(%p)\n\n", nodeType(n), Getattr(n, "storage"), Getattr(n, "name"), n);
-  // Swig_print_node(n);
-#endif
-  if (!first_linked_type) {
-    first_linked_type = n;
-    Setattr(n, "allegrocl:last_linked_type", n);
-  } else {
-    Node *t = Getattr(first_linked_type, "allegrocl:last_linked_type");
-    Setattr(t, "allegrocl:next_linked_type", n);
-    Setattr(first_linked_type, "allegrocl:last_linked_type", n);
-  }
-}
-
-void replace_linked_type(Node *old, Node *new_node) {
-  Node *prev = Getattr(old, "allegrocl:prev_linked_type");
-
-  Setattr(new_node, "allegrocl:next_linked_type", Getattr(old, "allegrocl:next_linked_type"));
-  if (prev)
-    Setattr(prev, "allegrocl:next_linked_type", new_node);
-  Delattr(old, "allegrocl:next_linked_type");
-  Delattr(old, "allegrocl:prev_linked_type");
-
-  // check if we're replacing the first link.
-  if (first_linked_type == old) {
-    first_linked_type = new_node;
-    Setattr(first_linked_type, "allegrocl:last_linked_type", Getattr(old, "allegrocl:last_linked_type"));
-  }
-  // check if we're replacing the last link.
-  if (Getattr(first_linked_type, "allegrocl:last_linked_type") == old)
-    Setattr(first_linked_type, "allegrocl:last_linked_type", new_node);
-}
-
-void insert_linked_type_at(Node *old, Node *new_node, int before = 1) {
-  Node *p = 0;
-
-  if (!first_linked_type) {
-    add_linked_type(new_node);
-    return;
-  }
-
-  if (!before) {
-    Setattr(new_node, "allegrocl:next_linked_type", Getattr(old, "allegrocl:next_linked_type"));
-    Setattr(old, "allegrocl:next_linked_type", new_node);
-    if (Getattr(first_linked_type, "allegrocl:last_linked_type") == old)
-      Setattr(first_linked_type, "allegrocl:last_linked_type", new_node);
-  } else {
-    Node *c = first_linked_type;
-    while (c) {
-      if (c == old) {
-	break;
-      } else {
-	p = c;
-	c = Getattr(c, "allegrocl:next_linked_type");
-      }
-    }
-    if (c == old) {
-      Setattr(new_node, "allegrocl:next_linked_type", c);
-      if (first_linked_type == c) {
-	first_linked_type = new_node;
-	Setattr(first_linked_type, "allegrocl:last_linked_type", Getattr(c, "allegrocl:last_linked_type"));
-	Delattr(c, "allegrocl:last_linked_type");
-      }
-      if (p)
-	Setattr(p, "allegrocl:next_linked_type", new_node);
-    }
-  }
-}
-
-Node *find_linked_type_by_name(String *name) {
-  Node *p = 0;
-  Node *c = first_linked_type;
-
-  // Printf(stderr,"in find_linked_type_by_name '%s'...", name);
-  while (c) {
-    String *key = Getattr(c, "name");
-    if (!Strcmp(key, name)) {
-      break;
-    } else {
-      p = c;
-      c = Getattr(c, "allegrocl:next_linked_type");
-    }
-  }
-  // Printf(stderr,"exit find_linked_type_by_name.\n");
-
-  if (p && c)
-    Setattr(c, "allegrocl:prev_linked_type", p);
-  // Printf(stderr,"find_linked_type_by_name: DONE\n");
-  return c;
-}
-
-Node *get_primary_synonym_of(Node *n) {
-  Node *p = Getattr(n, "allegrocl:synonym-of");
-  Node *prim = n;
-
-  // Printf(stderr, "getting primary synonym of %p\n", n);
-  while (p) {
-    // Printf(stderr, "   found one! %p\n", p);
-    prim = p;
-    p = Getattr(p, "allegrocl:synonym-of");
-  }
-  // Printf(stderr,"get_primary_syn: DONE. returning %s(%p)\n", Getattr(prim,"name"),prim);
-  return prim;
-}
-
-void add_forward_referenced_type(Node *n, int overwrite = 0) {
-  String *k = Getattr(n, "name");
-  String *name = Getattr(n, "sym:name");
-  String *ns = listify_namespace(current_namespace);
-
-  String *val = Getattr(defined_foreign_types, k);
-
-  if (!val || overwrite) {
-#ifdef ALLEGROCL_TYPE_DEBUG
-    Printf(stderr, "Adding forward reference for %s (overwrite=%d)\n", k, overwrite);
-#endif
-    Setattr(defined_foreign_types, Copy(k), NewString("forward-reference"));
-
-    String *mangled_lname_gen = NewStringf("#.(swig-insert-id \"%s\" %s :type :class)", name, ns);
-
-    Setattr(defined_foreign_ltypes, Copy(k), mangled_lname_gen);
-    //    Printf(f_cl, ";; forward reference stub\n"
-    //           "(swig-def-foreign-class \"%s\" (ff:foreign-pointer) (:class ))\n\n"
-    //     , name);
-
-#ifdef ALLEGROCL_CLASS_DEBUG
-    Printf(stderr, "Linking forward reference type = %s(%p)\n", k, n);
-#endif
-    add_linked_type(n);
-  }
-}
-
-void add_defined_foreign_type(Node *n, int overwrite = 0, String *k = 0,
-			      String *name = 0, String *ns = current_namespace) {
-
-  String *val;
-  String *ns_list = listify_namespace(ns);
-  String *templated = n ? Getattr(n, "template") : 0;
-  String *cDeclName = n ? Getattr(n, "name") : 0;
-
-#ifdef ALLEGROCL_CLASS_DEBUG
-  Printf(stderr, "IN A-D-F-T. (n=%p, ow=%d, k=%s, name=%s, ns=%s\n", n, overwrite, k, name, ns);
-  Printf(stderr, "    templated = '%p', classDecl = '%p'\n", templated, cDeclName);
-#endif
-  if (n) {
-    if (!name)
-      name = Getattr(n, "sym:name");
-    if (!name)
-      name = strip_namespaces(Getattr(n, "name"));
-    if (templated) {
-      k = namespaced_name(n);
-    } else {
-      String *kind_of_type = Getattr(n, "kind");
-
-      /*
-         For typedefs of the form:
-
-         typedef struct __xxx { ... } xxx;
-
-	 behavior differs between C mode and C++ mode.
-
-	 C Mode:
-         add_defined_foreign_type will be called once via classHandler
-         to define the type for 'struct __xxx' and add the mapping from
-	 'struct __xxx' -> 'xxx'
-
-	 It will also be called once via typedefHandler to add the
-	 mapping 'xxx' -> 'xxx'
-
-	 C++ Mode:
-	 add_defined_foreign_type will be called once via classHandler
-	 to define the type for 'xxx'. it also adds the mapping from
-	 'xxx' -> 'xxx' and also for 'struct xxx' -> 'xxx'
-
-	 In typedefHandler, we again try to add the mapping from
-	 'xxx' -> 'xxx', which already exists. This second mapping
-	 is ignored.
-
-	 Both modes:
-
-         All references to this typedef'd struct will appear in
-         generated lisp code as an objectd of type 'xxx'. For
-         non-typedef'd structs, the classHand mapping will be
-
-           struct __xxx -> (swig-insert-id "__xxx")
-       */
-      // Swig_print_node(n);
-      String *unnamed = Getattr(n, "unnamed");
-      if (kind_of_type && (!Strcmp(kind_of_type, "struct")
-			   || !Strcmp(kind_of_type, "union")) && cDeclName && !unnamed) {
-	k = NewStringf("%s %s", kind_of_type, cDeclName);
-      } else {
-	if (!Strcmp(nodeType(n), "enum") && unnamed) {
-	  name = NewStringf("%s%d", anon_type_name, anon_type_count++);
-	  k = NewStringf("enum %s", name);
-	  Setattr(n, "allegrocl:name", name);
-
-	} else {
-	  k = k ? k : Getattr(n, "name");
-	}
-      }
-    }
-    // Swig_print_node(n);
-  }
-
-  String *tname = SwigType_istemplate_templateprefix(name);
-  if (tname) {
-    String *temp = strip_namespaces(tname);
-    name = NewStringf("%s%s%s", temp, SwigType_templateargs(name), SwigType_templatesuffix(name));
-    Delete(temp);
-    Delete(tname);
-  }
-
-  val = lookup_defined_foreign_type(k);
-
-  int is_fwd_ref = 0;
-  if (val)
-    is_fwd_ref = !Strcmp(val, "forward-reference");
-
-  if (!val || overwrite || is_fwd_ref) {
-#ifdef ALLEGROCL_CLASS_DEBUG
-    Printf(stderr, "Adding defined type '%s' = '%s' '%s' (overwrite=%d, in-class=%d)\n", k, ns, name, overwrite, in_class);
-#endif
-    String *mangled_name_gen = NewStringf("#.(swig-insert-id \"%s\" %s :type :type)", name, ns_list);
-    String *mangled_lname_gen = NewStringf("#.(swig-insert-id \"%s\" %s :type :class)", name, ns_list);
-
-    Setattr(defined_foreign_types, Copy(k), Copy(mangled_name_gen));
-    Setattr(defined_foreign_ltypes, Copy(k), Copy(mangled_lname_gen));
-
-    if (CPlusPlus) {
-      bool cpp_struct = Strstr(k, "struct ") ? true : false;
-      bool cpp_union = Strstr(k, "union ") ? true : false;
-
-      String *cpp_type = 0;
-      if (cpp_struct) {
-	cpp_type = Copy(k);
-	Replaceall(cpp_type, "struct ", "");
-      } else if (cpp_union) {
-	cpp_type = Copy(k);
-	Replaceall(cpp_type, "union ", "");
-      }
-
-      if (cpp_struct || cpp_union) {
-#ifdef ALLEGROCL_CLASS_DEBUG
-	Printf(stderr, " Also adding defined type '%s' = '%s' '%s' (overwrite=%d)\n", cpp_type, ns, name, overwrite);
-#endif
-	Setattr(defined_foreign_types, Copy(cpp_type), Copy(mangled_name_gen));
-	Setattr(defined_foreign_ltypes, Copy(cpp_type), Copy(mangled_lname_gen));
-      }
-    }
-#ifdef ALLEGROCL_CLASS_DEBUG
-    Printf(stderr, "looking to add %s/%s(%p) to linked_type_list...\n", k, name, n);
-#endif
-    if (is_fwd_ref) {
-      // Printf(stderr,"*** 1\n");
-      if (n)
-	add_linked_type(n);
-    } else {
-      // Printf(stderr,"*** 1-a\n");
-      if (SwigType_istemplate(k)) {
-	SwigType *resolved = SwigType_typedef_resolve_all(k);
-	// Printf(stderr,"*** 1-b\n");
-	Node *match = find_linked_type_by_name(resolved);
-	Node *new_node = 0;
-	// Printf(stderr, "*** temp-1\n");
-	if (n) {
-	  new_node = n;
-	} else {
-#ifdef ALLEGROCL_CLASS_DEBUG
-	  Printf(stderr, "Creating a new templateInst:\n");
-	  Printf(stderr, "       name = %s\n", resolved);
-	  Printf(stderr, "   sym:name = %s\n", name);
-	  Printf(stderr, "  real-name = %s\n", k);
-	  Printf(stderr, "       type = %s\n", resolved);
-	  Printf(stderr, "         ns = %s\n\n", ns);
-#endif
-	  new_node = NewHash();
-	  Setattr(new_node, "nodeType", "templateInst");
-	  Setattr(new_node, "name", Copy(resolved));
-	  Setattr(new_node, "sym:name", Copy(name));
-	  Setattr(new_node, "real-name", Copy(k));
-	  Setattr(new_node, "type", Copy(resolved));
-	  Setattr(new_node, "allegrocl:namespace", ns);
-	  Setattr(new_node, "allegrocl:package", ns);
-	}
-
-	if (!match) {
-	  if (!Strcmp(nodeType(new_node), "templateInst") && in_class) {
-	    /* this is an implicit template instantiation found while
-	       walking a class. need to insert this into the
-	       linked_type list before the current class definition */
-#ifdef ALLEGROCL_CLASS_DEBUG
-	    Printf(stderr, "trying to insert a templateInst before a class\n");
-#endif
-	    insert_linked_type_at(in_class, new_node);
-#ifdef ALLEGROCL_CLASS_DEBUG
-	    Printf(stderr, "DID IT!\n");
-#endif
-	  } else {
-	    // Printf(stderr,"*** 3\n");
-	    add_linked_type(new_node);
-	  }
-	  Setattr(new_node, "allegrocl:synonym:is-primary", "1");
-	} else {
-	  // a synonym type was found (held in variable 'match')
-	  // Printf(stderr, "setting primary synonym of %p to %p\n", new_node, match);
-	  if (new_node == match)
-	    Printf(stderr, "Hey-4 * - '%s' is a synonym of itself!\n", Getattr(new_node, "name"));
-	  Setattr(new_node, "allegrocl:synonym-of", match);
-	  // Printf(stderr,"*** 4\n");
-	  add_linked_type(new_node);
-	}
-      } else {
-	Node *match;
-
-	if (!Strcmp(nodeType(n), "cdecl") && !Strcmp(Getattr(n, "storage"), "typedef")) {
-	  SwigType *type = SwigType_strip_qualifiers(Getattr(n, "type"));
-#ifdef ALLEGROCL_CLASS_DEBUG
-	  Printf(stderr, "Examining typedef '%s' for class references. (%d)\n", type, SwigType_isclass(type));
-#endif
-	  if (SwigType_isclass(type)) {
-#ifdef ALLEGROCL_CLASS_DEBUG
-	    Printf(stderr, "Found typedef of a class '%s'\n", type);
-#endif
-	    /* 
-	       For the following parsed expression:
-
-	       typedef struct __xxx { ... } xxx;
-
-	       if n is of kind "class" (defining the class 'struct __xxx'
-	       then we add n to the linked type list.
-
-	       if n is "cdecl" node of storage "typedef" (to note
-	       that xxx is equivalent to 'struct __xxx' then we don't
-	       want to add this node to the linked type list.
-	     */
-	    String *defined_type = lookup_defined_foreign_type(type);
-	    String *defined_key_type = lookup_defined_foreign_type(k);
-
-	    if ((Strstr(type, "struct ") || Strstr(type, "union "))
-		&& defined_type && !Strcmp(defined_type, defined_key_type)) {
-	      // mark as a synonym but don't add to linked_type list
-	      // Printf(stderr,"*** 4.8\n");
-	      Setattr(n, "allegrocl:synonym", "1");
-	    } else {
-	      SwigType *lookup_type = SwigType_istemplate(type) ? SwigType_typedef_resolve_all(type) : Copy(type);
-	      match = find_linked_type_by_name(lookup_type);
-	      if (match) {
-		Setattr(n, "allegrocl:synonym", "1");
-		Setattr(n, "allegrocl:synonym-of", match);
-		Setattr(n, "real-name", Copy(lookup_type));
-
-		// Printf(stderr, "*** pre-5: found match of '%s'(%p)\n", Getattr(match,"name"),match);
-		// if(n == match) Printf(stderr, "Hey-5 *** setting synonym of %p to %p\n", n, match);
-		// Printf(stderr,"*** 5\n");
-		add_linked_type(n);
-	      } else {
-#ifdef ALLEGROCL_CLASS_DEBUG
-		Printf(stderr, "Creating classfoward node for struct stub in typedef.\n");
-#endif
-		Node *new_node = NewHash();
-		String *symname = Copy(type);
-		Replaceall(symname, "struct ", "");
-		Setattr(new_node, "nodeType", "classforward");
-		Setattr(new_node, "name", Copy(type));
-		Setattr(new_node, "sym:name", symname);
-		Setattr(new_node, "allegrocl:namespace", ns);
-		Setattr(new_node, "allegrocl:package", ns);
-
-		String *mangled_new_name = NewStringf("#.(swig-insert-id \"%s\" %s)", symname, ns_list);
-		String *mangled_new_lname = NewStringf("#.(swig-insert-id \"%s\" %s :type :class)", symname, ns_list);
-		Setattr(defined_foreign_types, Copy(symname), Copy(mangled_new_name));
-		Setattr(defined_foreign_ltypes, Copy(symname), Copy(mangled_new_lname));
-
-		// Printf(stderr,"Weird! Can't find the type!\n");
-		add_forward_referenced_type(new_node);
-		add_linked_type(new_node);
-
-		Setattr(n, "allegrocl:synonym", "1");
-		Setattr(n, "allegrocl:synonym-of", new_node);
-
-		add_linked_type(n);
-	      }
-	      Delete(lookup_type);
-	    }
-	  } else {
-	    // check if it's a pointer or reference to a class.
-	    // Printf(stderr,"Checking if '%s' is a p. or r. to a class\n", type);
-	    String *class_ref = class_from_class_or_class_ref(type);
-	    if (class_ref) {
-	      match = find_linked_type_by_name(class_ref);
-	      Setattr(n, "allegrocl:synonym", "1");
-	      Setattr(n, "allegrocl:synonym-of", match);
-	      add_linked_type(n);
-	    }
-	  }
-	  Delete(type);
-	  // synonym types have already been added.
-	  // Printf(stderr,"*** 10\n");
-	  if (!Getattr(n, "allegrocl:synonym"))
-	    add_linked_type(n);
-	} else if (Getattr(n, "template")) {
-	  // Printf(stderr, "this is a class template node(%s)\n", nodeType(n));
-	  String *resolved = SwigType_typedef_resolve_all(Getattr(n, "name"));
-
-#ifdef ALLEGROCL_CLASS_DEBUG
-	  Printf(stderr, "   looking up %s for linked type match with %s...\n", Getattr(n, "sym:name"), resolved);
-#endif
-	  match = find_linked_type_by_name(resolved);
-	  if (!match) {
-#ifdef ALLEGROCL_CLASS_DEBUG
-	    Printf(stderr, "found no implicit instantiation of %%template node %s(%p)\n", Getattr(n, "name"), n);
-#endif
-	    add_linked_type(n);
-	  } else {
-	    Node *primary = get_primary_synonym_of(match);
-
-	    Setattr(n, "allegrocl:synonym:is-primary", "1");
-	    Delattr(primary, "allegrocl:synonym:is-primary");
-	    if (n == match)
-	      Printf(stderr, "Hey-7 * setting synonym of %p to %p\n (match = %p)", primary, n, match);
-	    Setattr(primary, "allegrocl:synonym-of", n);
-	    // Printf(stderr,"*** 7\n");
-	    add_linked_type(n);
-	  }
-	} else {
-#ifdef ALLEGROCL_CLASS_DEBUG
-	  Printf(stderr, "linking type '%s'(%p)\n", k, n);
-#endif
-	  // Printf(stderr,"*** 8\n");
-	  add_linked_type(n);
-	}
-      }
-    }
-    Delete(mangled_name_gen);
-    Delete(mangled_lname_gen);
-  } else {
-    if (!CPlusPlus || Strcmp(Getattr(n,"kind"),"typedef")) {
-       Swig_warning(WARN_TYPE_REDEFINED, Getfile(n), Getline(n),
-		    "Attempting to store a foreign type that exists: %s (%s)\n",
-		    k, val);
-    } 
-  }
-
-  Delete(ns_list);
-
-#ifdef ALLEGROCL_CLASS_DEBUG
-  Printf(stderr, "OUT A-D-F-T\n");
-#endif
-}
-
-void note_implicit_template_instantiation(SwigType *t) {
-  // the namespace of the implicit instantiation is not necessarily
-  // current_namespace. Attempt to cull this from the type.
-#ifdef ALLEGROCL_CLASS_DEBUG
-  Printf(stderr, "culling namespace of '%s' from '%s'\n", t, SwigType_templateprefix(t));
-#endif
-  SwigType *type = Copy(t);
-  SwigType *tok = SwigType_pop(type);
-  String *implicit_ns = SwigType_istemplate(tok) ? Swig_scopename_prefix(SwigType_templateprefix(tok)) : 0;
-  add_defined_foreign_type(0, 0, t, t, implicit_ns ? implicit_ns : current_namespace);
-
-  Delete(type);
-}
-
-String *get_ffi_type(Node *n, SwigType *ty, const_String_or_char_ptr name) {
-  /* lookup defined foreign type.
-     if it exists, it will return a form suitable for placing
-     into lisp code to generate the def-foreign-type name */
-
-#ifdef ALLEGROCL_TYPE_DEBUG
-  Printf(stderr, "inside g_f_t: looking up '%s' '%s'\n", ty, name);
-#endif
-
-  String *found_type = lookup_defined_foreign_type(ty);
-
-  if (found_type) {
-#ifdef ALLEGROCL_TYPE_DEBUG
-    Printf(stderr, "found_type '%s'\n", found_type);
-#endif
-    return (Strcmp(found_type, "forward-reference") ? Copy(found_type) : get_ffi_type(n, fwdref_ffi_type, ""));
-  } else {
-    Node *node = NewHash();
-    Setattr(node, "type", ty);
-    Setfile(node, Getfile(n));
-    Setline(node, Getline(n));
-    const String *tm = Swig_typemap_lookup("ffitype", node, name, 0);
-    Delete(node);
-
-    if (tm) {
-#ifdef ALLEGROCL_TYPE_DEBUG
-      Printf(stderr, "g-f-t: found ffitype typemap '%s'\n", tm);
-#endif
-      return NewString(tm);
-    }
-
-    if (SwigType_istemplate(ty)) {
-      note_implicit_template_instantiation(ty);
-      return Copy(lookup_defined_foreign_type(ty));
-    }
-  }
-  return 0;
-}
-
-String *lookup_defined_foreign_ltype(String *l) {
-
-#ifdef ALLEGROCL_TYPE_DEBUG
-  Printf(stderr, "Looking up defined ltype '%s'.\n  Found: '%s'\n", l, Getattr(defined_foreign_ltypes, l));
-#endif
-  return Getattr(defined_foreign_ltypes, l);
-}
-
-/* walk type and return string containing lisp version.
-   recursive. */
-String *internal_compose_foreign_type(Node *n, SwigType *ty) {
-
-  SwigType *tok;
-  String *ffiType = NewString("");
-
-  // for a function type, need to walk the parm list.
-  while (Len(ty) != 0) {
-    tok = SwigType_pop(ty);
-
-    if (SwigType_isfunction(tok)) {
-      // Generate Function wrapper
-      Printf(ffiType, "(:function ");
-      // walk parm list
-      List *pl = SwigType_parmlist(tok);
-
-      Printf(ffiType, "(");	// start parm list
-      for (Iterator i = First(pl); i.item; i = Next(i)) {
-	SwigType *f_arg = SwigType_strip_qualifiers(i.item);
-	Printf(ffiType, "%s ", internal_compose_foreign_type(n, f_arg));
-	Delete(f_arg);
-      }
-      Printf(ffiType, ")");	// end parm list.
-
-      // do function return type.
-      Printf(ffiType, " %s)", internal_compose_foreign_type(n, ty));
-      break;
-    } else if (SwigType_ispointer(tok) || SwigType_isreference(tok)) {
-      Printf(ffiType, "(* %s)", internal_compose_foreign_type(n, ty));
-    } else if (SwigType_isarray(tok)) {
-      Printf(ffiType, "(:array %s", internal_compose_foreign_type(n, ty));
-      String *atype = NewString("int");
-      String *dim = convert_literal(SwigType_array_getdim(tok, 0), atype);
-      Delete(atype);
-      if (is_integer(dim)) {
-	Printf(ffiType, " %s)", dim);
-      } else {
-	Printf(ffiType, " #| %s |#)", SwigType_array_getdim(tok, 0));
-      }
-    } else if (SwigType_ismemberpointer(tok)) {
-      // temp
-      Printf(ffiType, "(* %s)", internal_compose_foreign_type(n, ty));
-    } else {
-      String *res = get_ffi_type(n, tok, "");
-      if (res) {
-	Printf(ffiType, "%s", res);
-      } else {
-	SwigType *resolved_type = SwigType_typedef_resolve_all(tok);
-	if (Cmp(resolved_type, tok) != 0) {
-	  res = get_ffi_type(n, resolved_type, "");
-	  if (res) {
-	  } else {
-	    res = internal_compose_foreign_type(n, resolved_type);
-	  }
-	  if (res)
-	    Printf(ffiType, "%s", res);
-	}
-
-	if (!res) {
-	  String *is_struct = 0;
-	  String *tok_remove_text = 0;
-	  String *tok_name = Copy(tok);
-	  String *tok_key = SwigType_str(tok,0);
-	  if ((is_struct = Strstr(tok_key, "struct ")) || Strstr(tok_key, "union ")) {
-	    tok_remove_text = NewString(is_struct ? "struct " : "union ");
-	  }
-
-	  /* be more permissive of opaque types. This is the swig way.
-	     compiles will notice if these types are ultimately not
-	     present. */
-
-	  if(tok_remove_text) {
-	    Replaceall(tok_name,tok_remove_text,"");
-	  }
-	  tok_name = strip_namespaces(tok_name);
-	  Delete(tok_remove_text);
-	  // Swig_warning(WARN_TYPE_UNDEFINED_CLASS, Getfile(tok), Getline(tok), "Unable to find definition of '%s', assuming forward reference.\n", tok);
-
-#ifdef ALLEGROCL_TYPE_DEBUG
-	  Printf(stderr, "i-c-f-t: adding forward reference for unknown type '%s'. mapping: %s -> %s\n", tok, tok_key, tok_name);
-#endif
-	  Node *nn = NewHash();
-	  Setattr(nn,"nodeType","classforward");
-	  Setattr(nn,"kind","class");
-	  Setattr(nn,"sym:name",tok_name);
-	  Setattr(nn,"name",tok_key);
-	  Setattr(nn,"allegrocl:package",current_namespace);
-
-	  add_forward_referenced_type(nn, 0);
-	  // tok_name is dangling here, unused. ouch. why?
-	  Printf(ffiType, "%s", get_ffi_type(n, tok, ""), tok_name);
-	}
-      }
-    }
-  }
-  return ffiType;
-}
-
-String *compose_foreign_type(Node *n, SwigType *ty, String * /*id*/ = 0) {
-
-#ifdef ALLEGROCL_TYPE_DEBUG
-  Printf(stderr, "compose_foreign_type: ENTER (%s)...\n ", ty);
-  // Printf(stderr, "compose_foreign_type: ENTER (%s)(%s)...\n ", ty, (id ? id : 0));
-  /* String *id_ref = SwigType_str(ty, id);
-  Printf(stderr, "looking up typemap for %s, found '%s'(%p)\n",
-	 id_ref, lookup_res ? Getattr(lookup_res, "code") : 0, lookup_res);
-  if (lookup_res) Swig_print_node(lookup_res);
-  */
-#endif
-
-  /* should we allow named lookups in the typemap here? YES! */
-  /* unnamed lookups should be found in get_ffi_type, called
-     by internal_compose_foreign_type(), below. */
-
-  /* I'm reverting to 'no' for the question above. I can no longer
-     remember why I needed it. If a user needed it, I'll find out
-     as soon as they upgrade. Sigh. -mutandiz 9/16/2008. */
-
-/*
-  if(id && lookup_res) {
-#ifdef ALLEGROCL_TYPE_DEBUG
-    Printf(stderr, "compose_foreign_type: EXIT-1 (%s)\n ", Getattr(lookup_res, "code"));
-#endif
-    return NewString(Getattr(lookup_res, "code"));
-  }
-*/
-
-  SwigType *temp = SwigType_strip_qualifiers(ty);
-  String *res = internal_compose_foreign_type(n, temp);
-  Delete(temp);
-
-#ifdef ALLEGROCL_TYPE_DEBUG
-  Printf(stderr, "compose_foreign_type: EXIT (%s)\n ", res);
-#endif
-
-  return res;
-}
-
-void update_package_if_needed(Node *n, File *f = f_clwrap) {
-#ifdef ALLEGROCL_DEBUG
-  Printf(stderr, "update_package: ENTER... \n");
-  Printf(stderr, "  current_package = '%s'\n", current_package);
-  Printf(stderr, "     node_package = '%s'\n", Getattr(n, "allegrocl:package"));
-  Printf(stderr, "   node(%p) = '%s'\n", n, Getattr(n, "name"));
-#endif
-  String *node_package = Getattr(n, "allegrocl:package");
-  if (Strcmp(current_package, node_package)) {
-    String *lispy_package = listify_namespace(node_package);
-
-    Delete(current_package);
-    current_package = Copy(node_package);
-    Printf(f, "\n(swig-in-package %s)\n", lispy_package);
-    Delete(lispy_package);
-  }
-#ifdef ALLEGROCL_DEBUG
-  Printf(stderr, "update_package: EXIT.\n");
-#endif
-}
-
-static String *mangle_name(Node *n, char const *prefix = "ACL", String *ns = current_namespace) {
-  String *suffix = Getattr(n, "sym:overname");
-  String *pre_mangled_name = NewStringf("%s_%s__%s%s", prefix, ns, Getattr(n, "sym:name"), suffix);
-  String *mangled_name = Swig_name_mangle(pre_mangled_name);
-  Delete(pre_mangled_name);
-  return mangled_name;
-}
-
-/* utilities */
-
-/* remove a pointer from ffitype. non-destructive. 
-   (* :char) ==> :char
-   (* (:array :int 30)) ==> (:array :int 30) */
-String *dereference_ffitype(String *ffitype) {
-   char *start;
-   char *temp = Char(ffitype);
-   String *reduced_type = 0;
-
-   if(temp && temp[0] == '(' && temp[1] == '*') {
-      temp += 2;
-
-      // walk past start of pointer references
-      while(*temp == ' ') temp++;
-      start = temp;
-      // temp = Char(reduced_type);
-      reduced_type = NewString(start);
-      temp = Char(reduced_type);
-      // walk to end of string. remove closing paren
-      while(*temp != '\0') temp++;
-      *(--temp) = '\0';
-   }
-
-   return reduced_type ? reduced_type : Copy(ffitype);
-}
-
-/* returns new string w/ parens stripped */
-String *strip_parens(String *string) {
-  string = Copy(string);
-  Replaceall(string, "(", "");
-  Replaceall(string, ")", "");
-  return string;
-}
-
-int ALLEGROCL::validIdentifier(String *s) {
-#ifdef ALLEGROCL_DEBUG
-	Printf(stderr, "validIdentifier %s\n", s);
-#endif
-
-  char *c = Char(s);
-
-  bool got_dot = false;
-  bool only_dots = true;
-
-  /* Check that s is a valid common lisp symbol. There's a lot of leeway here.
-     A common lisp symbol is essentially any token that's not a number and
-     does not consist of only dots. 
-
-     We are expressly not allowing spaces in identifiers here, but spaces
-     could be added via the identifier converter. */
-  while (*c) {
-    if (*c == '.') {
-      got_dot = true;
-    } else {
-      only_dots = false;
-    }
-    if (!isgraph(*c))
-      return 0;
-    c++;
-  }
-
-  return (got_dot && only_dots) ? 0 : 1;
-}
-
-String *infix_to_prefix(String *val, char split_op, const String *op, String *type) {
-  List *ored = Split(val, split_op, -1);
-
-  // some float hackery
-  if (((split_op == '+') || (split_op == '-')) && Len(ored) == 2 &&
-      (SwigType_type(type) == T_FLOAT || SwigType_type(type) == T_DOUBLE || SwigType_type(type) == T_LONGDOUBLE)) {
-    // check that we're not splitting a float
-    String *possible_result = convert_literal(val, type, false);
-    if (possible_result)
-      return possible_result;
-
-  }
-  // try parsing the split results. if any part fails, kick out.
-  bool part_failed = false;
-  if (Len(ored) > 1) {
-    String *result = NewStringf("(%s", op);
-    for (Iterator i = First(ored); i.item; i = Next(i)) {
-      String *converted = convert_literal(i.item, type);
-      if (converted) {
-	Printf(result, " %s", converted);
-	Delete(converted);
-      } else {
-	part_failed = true;
-	break;
-      }
-    }
-    Printf(result, ")");
-    Delete(ored);
-    return part_failed ? 0 : result;
-  }
-  Delete(ored);
-  return 0;
-}
-
-/* To be called by code generating the lisp interface
-   Will return a containing the literal based on type.
-   Will return null if there are problems.
-
-   try_to_split defaults to true (see stub above).
- */
-String *convert_literal(String *literal, String *type, bool try_to_split) {
-  String *num_param = Copy(literal);
-  String *trimmed = trim(num_param);
-  String *num = strip_parens(trimmed), *res = 0;
-  char *s = Char(num);
-
-  String *ns = listify_namespace(current_namespace);
-
-  // very basic parsing of infix expressions.
-  if (try_to_split && SwigType_type(type) != T_STRING) {
-    if ((res = infix_to_prefix(num, '|', "logior", type)))
-      return res;
-    if ((res = infix_to_prefix(num, '&', "logand", type)))
-      return res;
-    if ((res = infix_to_prefix(num, '^', "logxor", type)))
-      return res;
-    if ((res = infix_to_prefix(num, '*', "*", type)))
-      return res;
-    if ((res = infix_to_prefix(num, '/', "/", type)))
-      return res;
-    if ((res = infix_to_prefix(num, '+', "+", type)))
-      return res;
-    if ((res = infix_to_prefix(num, '-', "-", type)))
-      return res;
-    // if ((res = infix_to_prefix(num, '~', "lognot", type))) return res;
-    //  if( (res = infix_to_prefix(num, '<<', "ash", type)) ) return res;  
-  }
-
-  // unary complement...
-  if (s[0] == '~' && Len(num) >= 2) {
-    String *id = NewString(++s);
-    String *id_conv = convert_literal(id, type, false);
-    Delete(id);
-    if (id_conv) 
-      return NewStringf("(lognot %s)", id_conv);
-    s--;
-  }
-
-  if (SwigType_type(type) == T_FLOAT || SwigType_type(type) == T_DOUBLE || SwigType_type(type) == T_LONGDOUBLE) {
-    // Use CL syntax for float literals 
-    String *oldnum = Copy(num);
-
-    // careful. may be a float identifier or float constant.
-    char *num_start = Char(num);
-    char *num_end = num_start + strlen(num_start) - 1;
-
-    bool is_literal = isdigit(*num_start) || (*num_start == '.');
-
-    String *lisp_exp = 0;
-    if (is_literal) {
-      if (*num_end == 'f' || *num_end == 'F') {
-	lisp_exp = NewString("f");
-      } else {
-	lisp_exp = NewString("d");
-      }
-
-      if (*num_end == 'l' || *num_end == 'L' || *num_end == 'f' || *num_end == 'F') {
-	*num_end = '\0';
-	num_end--;
-      }
-
-      int exponents = Replaceall(num, "e", lisp_exp) + Replaceall(num, "E", lisp_exp);
-
-      if (!exponents)
-	Printf(num, "%s0", lisp_exp);
-
-      if (exponents > 1 || (exponents + Replaceall(num, ".", ".") == 0)) {
-	// Printf(stderr, "Can't parse '%s' as type '%s'.\n", oldnum, type);
-	Delete(num);
-	num = 0;
-      }
-      Delete(lisp_exp);
-    } else {
-      String *id = NewStringf("#.(swig-insert-id \"%s\" %s :type :constant)",
-			      num, ns);
-      Delete(num);
-      num = id;
-    }
-
-    Delete(oldnum);
-    Delete(trimmed);
-    Delete(ns);
-    return num;
-  } else if (SwigType_type(type) == T_CHAR) {
-    /* Use CL syntax for character literals */
-    Delete(num);
-    Delete(trimmed);
-    return NewStringf("#\\%s", num_param);
-  } else if (SwigType_type(type) == T_STRING) {
-    /* Use CL syntax for string literals */
-    Delete(num);
-    Delete(trimmed);
-    return NewStringf("\"%s\"", num_param);
-  } else if (Len(num) >= 1 && (isdigit(s[0]) || s[0] == '+' || s[0] == '-')) {
-    /* use CL syntax for numbers */
-    String *oldnum = Copy(num);
-    int usuffixes = Replaceall(num, "u", "") + Replaceall(num, "U", "");
-    int lsuffixes = Replaceall(num, "l", "") + Replaceall(num, "L", "");
-    if (usuffixes > 1 || lsuffixes > 1) {
-      Printf(stderr, "Weird!! number %s looks invalid.\n", oldnum);
-      SWIG_exit(EXIT_FAILURE);
-    }
-    s = Char(num);
-    if (s[0] == '0' && Len(num) >= 2) {
-      /*octal or hex */
-      res = NewStringf("#%c%s", tolower(s[1]) == 'x' ? 'x' : 'o', s + 2);
-      Delete(num);
-    } else {
-      res = num;
-    }
-    Delete(oldnum);
-    Delete(trimmed);
-    return res;
-  } else if (allegrocl->validIdentifier(num)) {
-    /* convert C/C++ identifiers to CL symbols */
-    res = NewStringf("#.(swig-insert-id \"%s\" %s :type :constant)", num, ns);
-    Delete(num);
-    Delete(trimmed);
-    Delete(ns);
-    return res;
-  } else {
-    Delete(trimmed);
-    return num;
-  }
-}
-
-
-void emit_stub_class(Node *n) {
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_stub_class: ENTER... '%s'(%p)\n", Getattr(n, "sym:name"), n);
-  Swig_print_node(n);
-#endif
-
-
-  String *name = Getattr(n, "sym:name");
-
-  if (Getattr(n, "allegrocl:synonym:already-been-stubbed"))
-    return;
-
-  String *tname = SwigType_istemplate_templateprefix(name);
-  if (tname) {
-    String *temp = strip_namespaces(tname);
-    name = NewStringf("%s%s%s", temp, SwigType_templateargs(name), SwigType_templatesuffix(name));
-    Delete(temp);
-    Delete(tname);
-  } else {
-    name = strip_namespaces(name);
-  }
-
-  // Printf(f_clhead, ";; from emit-stub-class\n");
-  update_package_if_needed(n, f_clhead);
-  Printf(f_clhead, ";; class template stub.\n");
-  Printf(f_clhead, "(swig-def-foreign-stub \"%s\")\n", name);
-
-  Setattr(n, "allegrocl:synonym:already-been-stubbed", "1");
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_stub_class: EXIT\n");
-#endif
-}
-
-void emit_synonym(Node *synonym) {
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_synonym: ENTER... \n");
-#endif
-
-  // Printf(stderr,"in emit_synonym for %s(%p)\n", Getattr(synonym,"name"),synonym);
-  int is_tempInst = !Strcmp(nodeType(synonym), "templateInst");
-  String *synonym_type;
-
-  Node *of = get_primary_synonym_of(synonym);
-
-  if (is_tempInst) {
-    // Printf(stderr, "*** using real-name '%s'\n", Getattr(synonym,"real-name"));
-    synonym_type = Getattr(synonym, "real-name");
-  } else {
-    // Printf(stderr, "*** using name '%s'\n", Getattr(synonym,"name"));
-    synonym_type = Getattr(synonym, "name");
-  }
-
-  String *synonym_ns = listify_namespace(Getattr(synonym, "allegrocl:namespace"));
-  String *syn_ltype, *syn_type, *of_ltype;
-  // String *of_cdeclname = Getattr(of,"allegrocl:classDeclarationName");
-  String *of_ns = Getattr(of, "allegrocl:namespace");
-  String *of_ns_list = listify_namespace(of_ns);
-  // String *of_name = of_cdeclname ? NewStringf("struct %s", Getattr(of,"name")) : NewStringf("%s::%s", of_ns, Getattr(of,"sym:name"));
-  // String *of_name = NewStringf("%s::%s", of_ns, Getattr(of,"sym:name"));
-  String *of_name = namespaced_name(of, of_ns);
-
-  if (CPlusPlus && !Strcmp(nodeType(synonym), "cdecl")) {
-    String *real_name = Getattr(synonym, "real-name");
-    if (!real_name)
-      real_name = NewString("Unknown"); // TODO: fix
-    syn_ltype = NewStringf("#.(swig-insert-id \"%s\" %s :type :class)", strip_namespaces(real_name), synonym_ns);
-    syn_type = NewStringf("#.(swig-insert-id \"%s\" %s :type :type)", strip_namespaces(real_name), synonym_ns);
-  } else {
-    syn_ltype = lookup_defined_foreign_ltype(synonym_type);
-    syn_type = lookup_defined_foreign_type(synonym_type);
-  }
-
-  of_ltype = lookup_defined_foreign_ltype(of_name);
-
-  // Printf(stderr,";; from emit-synonym syn='%s' of_ltype='%s'\n", syn_ltype, of_ltype);
-  if( of_ltype )
-      Printf(f_clhead, "(swig-def-synonym-type %s\n   %s\n   %s)\n", syn_ltype, of_ltype, syn_type);
-
-  Delete(synonym_ns);
-  Delete(of_ns_list);
-  Delete(of_name);
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_synonym: EXIT\n");
-#endif
-}
-
-void emit_full_class(Node *n) {
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_full_class: ENTER... \n");
-#endif
-
-  String *name = Getattr(n, "sym:name");
-  String *kind = Getattr(n, "kind");
-
-  // Printf(stderr,"in emit_full_class: '%s'(%p).", Getattr(n,"name"),n);
-  if (Getattr(n, "allegrocl:synonym-of")) {
-    // Printf(stderr,"but it's a synonym of something.\n");
-    update_package_if_needed(n, f_clhead);
-    emit_synonym(n);
-    return;
-  }
-  // collect superclasses
-  String *bases = Getattr(n, "bases");
-  String *supers = NewString("(");
-  if (bases) {
-    int first = 1;
-    for (Iterator i = First(bases); i.item; i = Next(i)) {
-      if (!first)
-	Printf(supers, " ");
-      String *s = lookup_defined_foreign_ltype(Getattr(i.item, "name"));
-      // String *name = Getattr(i.item,"name");
-      if (s) {
-	Printf(supers, "%s", s);
-      } else {
-#ifdef ALLEGROCL_TYPE_DEBUG
-	Printf(stderr, "emit_templ_inst: did not find ltype for base class %s (%s)", Getattr(i.item, "name"), Getattr(n, "allegrocl:namespace"));
-#endif
-      }
-    }
-  } else {
-    Printf(supers, "ff:foreign-pointer");
-  }
-
-  // check for "feature:aclmixins" and add those as well.
-  Printf(supers, " %s)", Getattr(n,"feature:aclmixins"));
-
-  // Walk children to generate type definition.
-  String *slotdefs = NewString("   ");
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "  walking children...\n");
-#endif
-
-  Node *c;
-  for (c = firstChild(n); c; c = nextSibling(c)) {
-    String *storage_type = Getattr(c, "storage");
-    if ((!Strcmp(nodeType(c), "cdecl") && (!storage_type || Strcmp(storage_type, "typedef")))) {
-      String *access = Getattr(c, "access");
-
-      // hack. why would decl have a value of "variableHandler" and now "0"?
-      String *childDecl = Getattr(c, "decl");
-      // Printf(stderr,"childDecl = '%s' (%s)\n", childDecl, Getattr(c,"view"));
-      if (!childDecl || !Strcmp(childDecl, "0"))
-	childDecl = NewString("");
-
-      SwigType *childType;
-      String *cname;
-
-      // don't include types for private slots (yet). spr33959.
-      if(access && Strcmp(access,"public")) {
-	      childType = NewStringf("int");
-	      cname = NewString("nil");
-      } else {
-	      childType = NewStringf("%s%s", childDecl, Getattr(c, "type"));
-	      cname = Copy(Getattr(c, "name"));
-      }
-
-      if (!SwigType_isfunction(childType)) {
-	// Printf(slotdefs, ";;; member functions don't appear as slots.\n ");
-	// Printf(slotdefs, ";; ");
-	String *ns = listify_namespace(Getattr(n, "allegrocl:package"));
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-	Printf(stderr, "slot name = '%s' ns = '%s' class-of '%s' and type = '%s'\n", cname, ns, name, childType);
-#endif
-	Printf(slotdefs, "(#.(swig-insert-id \"%s\" %s :type :slot :class \"%s\") %s)", cname, ns, name, compose_foreign_type(n, childType));
-	Delete(ns);
-	if (access && Strcmp(access, "public"))
-	  Printf(slotdefs, " ;; %s member", access);
-
-	Printf(slotdefs, "\n   ");
-      }
-      Delete(childType);
-      Delete(cname);
-    }
-  }
-
-  String *ns_list = listify_namespace(Getattr(n, "allegrocl:namespace"));
-  update_package_if_needed(n, f_clhead);
-  Printf(f_clhead, "(swig-def-foreign-class \"%s\"\n %s\n  (:%s\n%s))\n\n", name, supers, kind, slotdefs);
-
-  Delete(supers);
-  Delete(ns_list);
-
-  Setattr(n, "allegrocl:synonym:already-been-stubbed", "1");
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_full_class: EXIT\n");
-#endif
-
-}
-
-void emit_class(Node *n) {
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_class: ENTER... '%s'(%p)\n", Getattr(n, "sym:name"), n);
-#endif
-
-  int is_tempInst = !Strcmp(nodeType(n), "templateInst");
-
-  String *ns_list = listify_namespace(Getattr(n, "allegrocl:namespace"));
-  String *name = Getattr(n, is_tempInst ? "real-name" : "name");
-
-  String *tname = SwigType_istemplate_templateprefix(name);
-  if (tname) {
-    String *temp = strip_namespaces(tname);
-    name = NewStringf("%s%s%s", temp, SwigType_templateargs(name), SwigType_templatesuffix(name));
-    Delete(temp);
-    Delete(tname);
-  } else {
-    name = strip_namespaces(name);
-  }
-
-  if (Getattr(n, "allegrocl:synonym:is-primary")) {
-    // Printf(stderr,"  is primary... ");
-    if (is_tempInst) {
-      emit_stub_class(n);
-    } else {
-      emit_full_class(n);
-    }
-  } else {
-    // Node *primary = Getattr(n,"allegrocl:synonym-of");
-    Node *primary = get_primary_synonym_of(n);
-    if (primary && (primary != n)) {
-      // Printf(stderr,"  emitting synonym... ");
-      emit_stub_class(primary);
-      update_package_if_needed(n, f_clhead);
-      emit_synonym(n);
-    } else {
-      emit_full_class(n);
-    }
-  }
-  // Printf(stderr,"DONE\n");
-  Delete(name);
-  Delete(ns_list);
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_class: EXIT\n");
-#endif
-}
-
-void emit_typedef(Node *n) {
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_typedef: ENTER... \n");
-#endif
-
-  String *name;
-  String *sym_name = Getattr(n, "sym:name");
-  String *type = NewStringf("%s%s", Getattr(n, "decl"), Getattr(n, "type"));
-  String *lisp_type = compose_foreign_type(n, type);
-  Delete(type);
-  Node *in_class = Getattr(n, "allegrocl:typedef:in-class");
-
-  // Printf(stderr,"in emit_typedef: '%s'(%p).",Getattr(n,"name"),n);
-  if (Getattr(n, "allegrocl:synonym-of")) {
-    // Printf(stderr," but it's a synonym of something.\n");
-    emit_synonym(n);
-    return;
-  }
-
-  if (in_class) {
-    String *class_name = Getattr(in_class, "name");
-    String *tname = SwigType_istemplate_templateprefix(class_name);
-    if (tname) {
-      String *temp = strip_namespaces(tname);
-      class_name = NewStringf("%s%s%s", temp, SwigType_templateargs(class_name), SwigType_templatesuffix(class_name));
-      Delete(temp);
-      Delete(tname);
-    }
-
-    name = NewStringf("%s__%s", class_name, sym_name);
-    Setattr(n, "allegrocl:in-class", in_class);
-  } else {
-    name = sym_name ? Copy(sym_name) : Copy(Getattr(n, "name"));
-  }
-
-  // leave these in for now. might want to change these to def-foreign-class at some point.
-//  Printf(f_clhead, ";; %s\n", SwigType_typedef_resolve_all(lisp_type));
-  Printf(f_clhead, "(swig-def-foreign-type \"%s\"\n  %s)\n", name, lisp_type);
-
-  Delete(name);
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_typedef: EXIT\n");
-#endif
-}
-
-void emit_enum_type_no_wrap(Node *n) {
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_enum_type_no_wrap: ENTER... \n");
-#endif
-
-  String *unnamed = Getattr(n, "unnamed");
-  String *name;
-  //  SwigType *enumtype;
-
-  name = unnamed ? Getattr(n, "allegrocl:name") : Getattr(n, "sym:name");
-  SwigType *tmp = NewStringf("enum %s", unnamed ? unnamed : name);
-
-  Node *node = NewHash();
-  Setattr(node, "type", tmp);
-  Setfile(node, Getfile(n));
-  Setline(node, Getline(n));
-  const String *enumtype = Swig_typemap_lookup("ffitype", node, "", 0);
-  Delete(node);
-
-  Delete(tmp);
-
-  if (name) {
-    String *ns = listify_namespace(current_namespace);
-
-    Printf(f_clhead, "(swig-def-foreign-type \"%s\" %s)\n", name, enumtype);
-    Delete(ns);
-
-    // walk children.
-    Node *c;
-    for (c = firstChild(n); c; c = nextSibling(c)) {
-      if (!Getattr(c, "error")) {
-	String *val = Getattr(c, "enumvalue");
-	if (!val)
-	  val = Getattr(c, "enumvalueex");
-	String *converted_val = convert_literal(val, Getattr(c, "type"));
-	String *valname = Getattr(c, "sym:name");
-
-	if (converted_val) {
-	  Printf(f_clhead, "(swig-defconstant \"%s\" %s)\n", valname, converted_val);
-	  Delete(converted_val);
-	} else {
-	  Swig_warning(WARN_LANG_DISCARD_CONST, Getfile(n), Getline(n), "Unable to parse enum value '%s'. Setting to NIL\n", val);
-	  Printf(f_clhead, "(swig-defconstant \"%s\" nil #| %s |#)\n", valname, val);
-	}
-      }
-    }
-  }
-  Printf(f_clhead, "\n");
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_enum_type_no_wrap: EXIT\n");
-#endif
-
-}
-
-void emit_enum_type(Node *n) {
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_enum_type: ENTER... \n");
-#endif
-
-  if (!Generate_Wrapper) {
-    emit_enum_type_no_wrap(n);
-    return;
-  }
-
-  String *unnamed = Getattr(n, "unnamed");
-  String *name;
-  // SwigType *enumtype;
-
-  name = unnamed ? Getattr(n, "allegrocl:name") : Getattr(n, "sym:name");
-  SwigType *tmp = NewStringf("enum %s", unnamed ? unnamed : name);
-
-  Node *node = NewHash();
-  Setattr(node, "type", tmp);
-  Setfile(node, Getfile(n));
-  Setline(node, Getline(n));
-  const String *enumtype = Swig_typemap_lookup("ffitype", node, "", 0);
-  Delete(node);
-
-  Delete(tmp);
-
-  if (name) {
-    String *ns = listify_namespace(current_namespace);
-
-    Printf(f_clhead, "(swig-def-foreign-type \"%s\" %s)\n", name, enumtype);
-    Delete(ns);
-
-    // walk children.
-    Node *c;
-    for(c = firstChild(n); c; c=nextSibling(c)) {
-      String *mangled_name = mangle_name(c, "ACL_ENUM", Getattr(c,"allegrocl:package"));
-      Printf(f_clhead, "(swig-defvar \"%s\" \"%s\" :type :constant :ftype :signed-long)\n", Getattr(c, "sym:name"), mangled_name);
-      Delete(mangled_name);
-    }
-  }
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_enum_type: EXIT\n");
-#endif
-
-}
-
-void emit_default_linked_type(Node *n) {
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_default_linked_type: ENTER... \n");
-#endif
-
-  // catchall for non class types.
-  if (!Strcmp(nodeType(n), "classforward")) {
-    Printf(f_clhead, ";; forward referenced stub.\n");
-    Printf(f_clhead, "(swig-def-foreign-class \"%s\" (ff:foreign-pointer) (:class ))\n\n", Getattr(n, "sym:name"));
-  } else if (!Strcmp(nodeType(n), "enum")) {
-    emit_enum_type(n);
-  } else {
-    Printf(stderr, "Don't know how to emit node type '%s' named '%s'\n", nodeType(n), Getattr(n, "name"));
-  }
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_default_linked_type: EXIT\n");
-#endif
-
-}
-
-void dump_linked_types(File *f) {
-  Node *n = first_linked_type;
-  int i = 0;
-  while (n) {
-    Printf(f, "%d: (%p) node '%s' name '%s'\n", i++, n, nodeType(n), Getattr(n, "sym:name"));
-
-    Node *t = Getattr(n, "allegrocl:synonym-of");
-    if (t)
-      Printf(f, "     synonym-of %s(%p)\n", Getattr(t, "name"), t);
-    n = Getattr(n, "allegrocl:next_linked_type");
-  }
-}
-
-void emit_linked_types() {
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_linked_types: ENTER... ");
-#endif
-
-  Node *n = first_linked_type;
-
-  while (n) {
-    String *node_type = nodeType(n);
-
-    // Printf(stderr,"emitting node %s(%p) of type %s.", Getattr(n,"name"),n, nodeType(n));
-    if (!Strcmp(node_type, "class") || !Strcmp(node_type, "templateInst")) {
-      // may need to emit a stub, so it will update the package itself.
-      // Printf(stderr," Passing to emit_class.");
-      emit_class(n);
-    } else if (!Strcmp(nodeType(n), "cdecl")) {
-      // Printf(stderr," Passing to emit_typedef.");
-      update_package_if_needed(n, f_clhead);
-      emit_typedef(n);
-    } else {
-      // Printf(stderr," Passing to default_emitter.");
-      update_package_if_needed(n, f_clhead);
-      emit_default_linked_type(n);
-    }
-
-    n = Getattr(n, "allegrocl:next_linked_type");
-    // Printf(stderr,"returned.\n");
-  }
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_linked_types: EXIT\n");
-#endif
-}
-
-extern "C" Language *swig_allegrocl(void) {
-  return (allegrocl = new ALLEGROCL());
-}
-
-void ALLEGROCL::main(int argc, char *argv[]) {
-  int i;
-
-  Preprocessor_define("SWIGALLEGROCL 1", 0);
-  SWIG_library_directory("allegrocl");
-  SWIG_config_file("allegrocl.swg");
-
-  for (i = 1; i < argc; i++) {
-    if (!strcmp(argv[i], "-identifier-converter")) {
-      char *conv = argv[i + 1];
-
-      if (!conv)
-	Swig_arg_error();
-
-      Swig_mark_arg(i);
-      Swig_mark_arg(i + 1);
-      i++;
-
-      /* check for built-ins */
-      if (!strcmp(conv, "lispify")) {
-	Delete(identifier_converter);
-	identifier_converter = NewString("identifier-convert-lispify");
-      } else if (!strcmp(conv, "null")) {
-	Delete(identifier_converter);
-	identifier_converter = NewString("identifier-convert-null");
-      } else {
-	/* Must be user defined */
-	Delete(identifier_converter);
-	identifier_converter = NewString(conv);
-      }
-    } else if (!strcmp(argv[i], "-cwrap")) {
-      CWrap = true;
-      Swig_mark_arg(i);
-    } else if (!strcmp(argv[i], "-nocwrap")) {
-      CWrap = false;
-      Swig_mark_arg(i);
-    } else if (!strcmp(argv[i], "-isolate")) {
-      unique_swig_package = true;
-      Swig_mark_arg(i);
-    }
-
-    if (!strcmp(argv[i], "-help")) {
-      Printf(stdout, "%s\n", usage);
-    }
-
-  }
-
-  allow_overloading();
-}
-
-int ALLEGROCL::top(Node *n) {
-  module_name = Getattr(n, "name");
-  String *cxx_filename = Getattr(n, "outfile");
-  String *cl_filename = NewString("");
-
-  swig_package = unique_swig_package ? NewStringf("swig.%s", module_name) : NewString("swig");
-
-  Printf(cl_filename, "%s%s.cl", SWIG_output_directory(), module_name);
-
-  f_cl = NewFile(cl_filename, "w", SWIG_output_files());
-  if (!f_cl) {
-    Printf(stderr, "Unable to open %s for writing\n", cl_filename);
-    SWIG_exit(EXIT_FAILURE);
-  }
-
-  Generate_Wrapper = CPlusPlus || CWrap;
-
-  if (Generate_Wrapper) {
-    f_begin = NewFile(cxx_filename, "w", SWIG_output_files());
-    if (!f_begin) {
-      Delete(f_cl);
-      Printf(stderr, "Unable to open %s for writing\n", cxx_filename);
-      SWIG_exit(EXIT_FAILURE);
-    }
-  } else
-    f_begin = NewString("");
-
-  f_runtime = NewString("");
-  f_cxx_header = f_runtime;
-  f_cxx_wrapper = NewString("");
-
-  Swig_register_filebyname("header", f_cxx_header);
-  Swig_register_filebyname("wrapper", f_cxx_wrapper);
-  Swig_register_filebyname("begin", f_begin);
-  Swig_register_filebyname("runtime", f_runtime);
-  Swig_register_filebyname("lisp", f_clwrap);
-  Swig_register_filebyname("lisphead", f_cl);
-
-  Swig_banner(f_begin);
-
-  Printf(f_runtime, "\n\n#ifndef SWIGALLEGROCL\n#define SWIGALLEGROCL\n#endif\n\n");
-
-  Swig_banner_target_lang(f_cl, ";;");
-
-  Printf(f_cl, "\n"
-	 "(defpackage :%s\n"
-	 "  (:use :common-lisp :ff :excl)\n"
-	 "  (:export #:*swig-identifier-converter* #:*swig-module-name*\n"
-	 "           #:*void* #:*swig-export-list*))\n"
-	 "(in-package :%s)\n\n"
-	 "(eval-when (:compile-toplevel :load-toplevel :execute)\n"
-	 "  (defparameter *swig-identifier-converter* '%s)\n"
-	 "  (defparameter *swig-module-name* :%s))\n\n", swig_package, swig_package, identifier_converter, module_name);
-  Printf(f_cl, "(defpackage :%s\n" "  (:use :common-lisp :%s :ff :excl))\n\n", module_name, swig_package);
-
-  Printf(f_clhead, "(in-package :%s)\n", module_name);
-
-  Language::top(n);
-
-#ifdef ALLEGROCL_TYPE_DEBUG
-  dump_linked_types(stderr);
-#endif
-  emit_linked_types();
-
-  Printf(f_clwrap, "\n(cl::in-package :%s)\n", swig_package);
-  Printf(f_clwrap, "\n(macrolet ((swig-do-export ()\n");
-  Printf(f_clwrap, "                 `(dolist (s ',*swig-export-list*)\n");
-  Printf(f_clwrap, "                    (apply #'export s))))\n");
-  Printf(f_clwrap, "   (swig-do-export))\n");
-  Printf(f_clwrap, "\n(setq *swig-export-list* nil)\n");
-
-  Printf(f_cl, "%s\n", f_clhead);
-  Printf(f_cl, "%s\n", f_clwrap);
-
-  Delete(f_cl);
-  Delete(f_clhead);
-  Delete(f_clwrap);
-
-  Dump(f_runtime, f_begin);
-  Printf(f_begin, "%s\n", f_cxx_wrapper);
-
-  Delete(f_runtime);
-  Delete(f_begin);
-  Delete(f_cxx_wrapper);
-
-  // Swig_print_tree(n);
-
-  return SWIG_OK;
-}
-
-int any_varargs(ParmList *pl) {
-  Parm *p;
-
-  for (p = pl; p; p = nextSibling(p)) {
-    if (SwigType_isvarargs(Getattr(p, "type")))
-      return 1;
-  }
-
-  return 0;
-}
-
-String *get_lisp_type(Node *n, SwigType *ty, const_String_or_char_ptr name) {
-  Node *node = NewHash();
-  Setattr(node, "type", ty);
-  Setattr(node, "name", name);
-  Setfile(node, Getfile(n));
-  Setline(node, Getline(n));
-  const String *tm = Swig_typemap_lookup("lisptype", node, "", 0);
-  Delete(node);
-
-  return tm ? NewString(tm) : NewString("");
-}
-
-Node *parent_node_skipping_extends(Node *n) {
-  Node *result = n;
-  do {
-    result = parentNode(result);
-  }
-  while (Cmp("extend", nodeType(result)) == 0);
-  return result;
-}
-
-/* -----------------------------------------------------------------------------
- * emit_num_lin_arguments()
- *
- * Calculate the total number of arguments.   This function is safe for use
- * with multi-argument typemaps which may change the number of arguments in
- * strange ways.
- * ----------------------------------------------------------------------------- */
-
-int emit_num_lin_arguments(ParmList *parms) {
-  Parm *p = parms;
-  int nargs = 0;
-
-  while (p) {
-    // Printf(stderr,"enla: '%s' lin='%p' numinputs='%s'\n", Getattr(p,"name"), Getattr(p,"tmap:lin"), Getattr(p,"tmap:lin:numinputs"));
-    if (Getattr(p, "tmap:lin")) {
-      nargs += GetInt(p, "tmap:lin:numinputs");
-      p = Getattr(p, "tmap:lin:next");
-    } else {
-      p = nextSibling(p);
-    }
-  }
-
-  /* DB 04/02/2003: Not sure this is necessary with tmap:in:numinputs */
-  /*
-     if (parms && (p = Getattr(parms,"emit:varargs"))) {
-     if (!nextSibling(p)) {
-     nargs--;
-     }
-     }
-   */
-  return nargs;
-}
-
-String *id_converter_type(SwigType const *type) {
-  SwigType *t = Copy(type);
-  String *result = 0;
-
-  if (SwigType_ispointer(t)) {
-    SwigType_pop(t);
-    String *pointee = id_converter_type(t);
-    result = NewStringf("(:* %s)", pointee);
-    Delete(pointee);
-  } else if (SwigType_ismemberpointer(t)) {
-    String *klass = SwigType_parm(t);
-    SwigType_pop(t);
-    String *member = id_converter_type(t);
-    result = NewStringf("(:member \"%s\" %s)", klass, member);
-    Delete(klass);
-    Delete(member);
-  } else if (SwigType_isreference(t)) {
-    SwigType_pop(t);
-    String *referencee = id_converter_type(t);
-    result = NewStringf("(:& %s)", referencee);
-    Delete(referencee);
-  } else if (SwigType_isarray(t)) {
-    String *size = SwigType_parm(t);
-    SwigType_pop(t);
-    String *element_type = id_converter_type(t);
-    result = NewStringf("(:array %s \"%s\")", element_type, size);
-    Delete(size);
-    Delete(element_type);
-  } else if (SwigType_isfunction(t)) {
-    result = NewString("(:function (");
-    String *parmlist_str = SwigType_parm(t);
-    List *parms = SwigType_parmlist(parmlist_str);
-
-    for (Iterator i = First(parms); i.item;) {
-      String *parm = id_converter_type((SwigType *) i.item);
-      Printf(result, "%s", parm);
-      i = Next(i);
-      if (i.item)
-	Printf(result, " ");
-      Delete(parm);
-    }
-    SwigType_pop(t);
-    String *ret = id_converter_type(t);
-    Printf(result, ") %s)", ret);
-
-    Delete(parmlist_str);
-    Delete(parms);
-    Delete(ret);
-  } else if (SwigType_isqualifier(t)) {
-    result = NewString("(:qualified (");
-    String *qualifiers_str = Copy(SwigType_parm(t));	// ?!
-    // Replaceall below SEGVs if we don't put the Copy here...
-    SwigType_pop(t);
-    String *qualifiee = id_converter_type(t);
-
-    Replaceall(qualifiers_str, " ", " :");
-    if (Len(qualifiers_str) > 0)
-      Printf(result, ":");
-    Printf(result, "%s) %s)", qualifiers_str, qualifiee);
-
-    Delete(qualifiers_str);
-    Delete(qualifiee);
-  } else if (SwigType_istemplate(t)) {
-    result = NewStringf("(:template \"%s\")", t);
-  } else {			/* if (SwigType_issimple(t)) */
-
-    if (Strstr(Char(t), "::")) {
-      result = listify_namespace(t);
-    } else {
-      result = NewStringf("\"%s\"", t);
-    }
-  }
-
-  Delete(t);
-  return result;
-}
-
-static ParmList *parmlist_with_names(ParmList *pl) {
-  ParmList *pl2 = CopyParmList(pl);
-  for (Parm *p = pl, *p2 = pl2; p2; p = nextSibling(p), p2 = nextSibling(p2)) {
-    if (!Getattr(p2, "name"))
-      Setattr(p2, "name", Getattr(p2, "lname"));
-    Setattr(p2, "name", strip_namespaces(Getattr(p2, "name")));
-    Setattr(p2, "tmap:ctype", Getattr(p, "tmap:ctype"));
-
-    String *temp = Getattr(p, "tmap:lin");
-    if (temp) {
-      Setattr(p2, "tmap:lin", temp);
-      Setattr(p2, "tmap:lin:next", Getattr(p, "tmap:lin:next"));
-    }
-  }
-  return pl2;
-}
-
-static String *parmlist_str_id_converter(ParmList *pl) {
-  String *result = NewString("");
-  for (Parm *p = pl; p;) {
-    String *lispy_type = id_converter_type(Getattr(p, "type"));
-    Printf(result, "(\"%s\" %s)", Getattr(p, "name"), lispy_type);
-    Delete(lispy_type);
-    if ((p = nextSibling(p)))
-      Printf(result, " ");
-  }
-  return result;
-}
-
-String *collect_others_args(Node *overload) {
-  String *overloaded_from = Getattr(overload, "sym:overloaded");
-  String *others_args = NewString("");
-  int first_overload = 1;
-
-  for (Node *overload2 = overloaded_from; overload2; overload2 = Getattr(overload2, "sym:nextSibling")) {
-    if (overload2 == overload || GetInt(overload2, "overload:ignore"))
-      continue;
-
-    ParmList *opl = parmlist_with_names(Getattr(overload2, "wrap:parms"));
-    String *args = parmlist_str_id_converter(opl);
-    if (!first_overload)
-      Printf(others_args, "\n                           ");
-    Printf(others_args, "(%s)", args);
-    Delete(args);
-    Delete(opl);
-    first_overload = 0;
-  }
-  return others_args;
-}
-
-struct IDargs {
-  String *name;
-  String *type;
-  String *klass;
-  String *arity;
-
-  IDargs():name(0), type(0), klass(0), arity(0) {
-  }
-
-  String *full_quoted_str() {
-    String *result = no_others_quoted_str();
-    if (arity)
-      Printf(result, " :arity %s", arity);
-    return result;
-  }
-
-  String *no_others_quoted_str() {
-    String *result = NewString("");
-    Printf(result, "\"%s\" :type :%s", name, type);
-    if (klass)
-      Printf(result, " :class \"%s\"", klass);
-    return result;
-  }
-
-  String *noname_str(bool include_class = true) {
-    String *result = NewString("");
-    Printf(result, " :type :%s", type);
-    if (klass && include_class)
-      Printf(result, " :class \"%s\"", klass);
-    if (arity)
-      Printf(result, " :arity %s", arity);
-    return result;
-  }
-
-  String *noname_no_others_str(bool include_class = true) {
-    String *result = NewString("");
-    Printf(result, " :type :%s", type);
-    if (klass && include_class)
-      Printf(result, " :class \"%s\"", klass);
-    return result;
-  }
-};
-IDargs *id_converter_arguments(Node *n) {
-  IDargs *result = (IDargs *) GetVoid(n, "allegrocl:id-converter-args");
-  if (!result)
-    result = new IDargs;
-
-  // Base name
-  if (!result->name) {
-    result->name = Getattr(n, "allegrocl:old-sym:name");
-    if (!result->name)
-      result->name = Getattr(n, "sym:name");
-    result->name = Copy(result->name);
-  }
-  // :type
-  if (result->type)
-    Delete(result->type);
-  if (!Getattr(n, "allegrocl:kind"))
-    Setattr(n, "allegrocl:kind", "function");
-  if (Strstr(Getattr(n, "name"), "operator "))
-    Replaceall(Getattr(n, "allegrocl:kind"), "function", "operator");
-  if (Strstr(Getattr(n, "allegrocl:kind"), "variable")) {
-    int name_end = Len(Getattr(n, "sym:name")) - 4;
-    char *str = Char(Getattr(n, "sym:name"));
-    String *get_set = NewString(str + name_end + 1);
-    result->type = Copy(Getattr(n, "allegrocl:kind"));
-    Replaceall(result->type, "variable", "");
-    Printf(result->type, "%ster", get_set);
-    Delete(get_set);
-  } else {
-    result->type = Copy(Getattr(n, "allegrocl:kind"));
-  }
-
-  // :class
-  if (Strstr(result->type, "member ")) {
-    Replaceall(result->type, "member ", "");
-    if (!result->klass) {
-      result->klass = Copy(Getattr(parent_node_skipping_extends(n), "sym:name"));
-    }
-  }
-  // :arity
-  if (Getattr(n, "sym:overloaded")) {
-    if (result->arity)
-      Delete(result->arity);
-    result->arity = NewStringf("%d",
-			       // emit_num_arguments(Getattr(n, "wrap:parms")));
-			       emit_num_lin_arguments(Getattr(n, "wrap:parms")));
-    // Printf(stderr, "got arity of '%s' node '%s' '%p'\n", result->arity, Getattr(n,"name"), Getattr(n,"wrap:parms"));
-  }
-
-  SetVoid(n, "allegrocl:id-converter-args", result);
-  return result;
-}
-
-int ALLEGROCL::emit_buffered_defuns(Node *n) {
-
-  Node *overloaded_from = Getattr(n, "sym:overloaded");
-
-  String *wrap;
-
-  if (!overloaded_from) {
-    wrap = Getattr(n, "allegrocl:lisp-wrap");
-
-    Printf(f_clwrap, "%s\n", wrap);
-    Delattr(n, "allegrocl:lisp-wrap");
-    Delete(wrap);
-  } else {
-    for (Node *overload = overloaded_from; overload; overload = Getattr(overload, "sym:nextSibling")) {
-      String *others_args = collect_others_args(overload);
-      wrap = Getattr(overload, "allegrocl:lisp-wrap");
-
-      Replaceall(wrap, "@@OTHERS-ARGS-GO-HERE@@", others_args);
-//        IDargs* id_args = id_converter_arguments(overload);
-//        Replaceall(id_args->others_args, "@@OTHERS-ARGS-GO-HERE@@", others_args);
-
-      if (!GetInt(overload, "overload:ignore"))
-	Printf(f_clwrap, "%s", wrap);
-
-      Delattr(overload, "allegrocl:lisp-wrap");
-      Delete(wrap);
-    }
-  }
-  return SWIG_OK;
-}
-
-String *dispatching_type(Node *n, Parm *p) {
-  String *result = 0;
-
-  String *parsed = Getattr(p, "type");	//Swig_cparse_type(Getattr(p,"tmap:ctype"));
-  String *cl_t = SwigType_typedef_resolve_all(parsed);
-
-  Node *node = NewHash();
-  Setattr(node, "type", parsed);
-  Setfile(node, Getfile(n));
-  Setline(node, Getline(n));
-  const String *tm = Swig_typemap_lookup("lispclass", node, Getattr(p, "name"), 0);
-  Delete(node);
-
-  if (tm) {
-    result = Copy(tm);
-  } else {
-    String *lookup_type = class_from_class_or_class_ref(parsed);
-    if (lookup_type)
-      result = lookup_defined_foreign_ltype(lookup_type);
-  }
-
-  //  if (!result && SwigType_ispointer(cl_t)) {
-  //    SwigType_pop(cl_t);
-  //    result = lookup_defined_foreign_ltype(cl_t);
-  //  }
-
-  if (!result)
-    result = NewStringf("ff:foreign-pointer");
-
-  // Delete(parsed);
-  Delete(cl_t);
-  return result;
-}
-
-int ALLEGROCL::emit_dispatch_defun(Node *n) {
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_dispatch_defun: ENTER... ");
-#endif
-  List *overloads = Swig_overload_rank(n, true);
-
-  // Printf(stderr,"\ndispatch node=%p\n\n", n);
-  // Swig_print_node(n);
-
-  Node *overloaded_from = Getattr(n,"sym:overloaded");
-  bool include_class = Getattr(overloaded_from, "allegrocl:dispatcher:include-class") ? true : false;
-  String *id_args = id_converter_arguments(n)->noname_no_others_str(include_class);
-  Printf(f_clwrap, "(swig-dispatcher (\"%s\" %s :arities (", Getattr(overloaded_from, "allegrocl:dispatcher:name"), id_args);
-
-  Delattr(overloaded_from, "allegrocl:dispatcher:include-class");
-  Delattr(overloaded_from, "allegrocl:dispatcher:name");
-
-  int last_arity = -1;
-  for (Iterator i = First(overloads); i.item; i = Next(i)) {
-    int arity = emit_num_lin_arguments(Getattr(i.item, "wrap:parms"));
-    if (arity == last_arity)
-      continue;
-
-    Printf(f_clwrap, "%s%d", last_arity == -1 ? "" : " ", arity);
-
-    last_arity = arity;
-  }
-  Printf(f_clwrap, ")))\n");
-
-  Delete(id_args);
-  Delete(overloads);
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_dispatch_defun: EXIT\n");
-#endif
-
-  return SWIG_OK;
-}
-
-int ALLEGROCL::emit_defun(Node *n, File *fcl) {
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_defun: ENTER... ");
-#endif
-
-  // avoid name conflicts between smart pointer wrappers and the wrappers for the
-  // actual class.
-  bool smartmemberwrapper = (!Cmp(Getattr(n, "view"), "memberfunctionHandler") &&
-			     Getattr(n,"allocate:smartpointeraccess"));
-
-#ifdef ALLEGROCL_DEBUG
-  int auto_generated = Cmp(Getattr(n, "view"), "globalfunctionHandler");
-  Printf(stderr, "%s%sfunction %s%s%s\n", auto_generated ? "> " : "", Getattr(n, "sym:overloaded")
-	 ? "overloaded " : "", current_namespace, (current_namespace) > 0 ? "::" : "", Getattr(n, "sym:name"));
-  Printf(stderr, "  (view: %s)\n", Getattr(n, "view"));
-  Swig_print_node(n);
-#endif
-
-
-  String *funcname = Getattr(n, "allegrocl:old-sym:name");
-  if (smartmemberwrapper || !funcname)
-    funcname = Getattr(n, "sym:name");
-
-  String *mangled_name = Getattr(n, "wrap:name");
-  ParmList *pl = parmlist_with_names(Getattr(n, "wrap:parms"));
-
-  // attach typemap info.
-  Wrapper *wrap = NewWrapper();
-  Swig_typemap_attach_parms("lin", pl, wrap);
-  // Swig_typemap_attach_parms("ffitype", pl, wrap);
-  Swig_typemap_lookup("lout", n, Swig_cresult_name(), 0);
-
-  SwigType *result_type = Swig_cparse_type(Getattr(n, "tmap:ctype"));
-  // prime the pump, with support for OUTPUT, INOUT typemaps.
-  Printf(wrap->code,
-	 "(cl::let ((ACL_ffresult %s:*void*)\n        ACL_result)\n  $body\n  (cl::if (cl::eq ACL_ffresult %s:*void*)\n    (cl::values-list ACL_result)\n   (cl::values-list (cl::cons ACL_ffresult ACL_result))))",
-	 swig_package, swig_package);
-
-  Parm *p;
-  int largnum = 0, argnum = 0, first = 1;
-  // int varargs=0;
-  if (Generate_Wrapper) {
-    String *extra_parms = id_converter_arguments(n)->noname_str(smartmemberwrapper ? false : true);
-    Node *overloaded_from = Getattr(n,"sym:overloaded");
-    if (overloaded_from) {
-      if(!GetFlag(overloaded_from,"allegrocl:dispatcher:name")) {
-        Setattr(overloaded_from,"allegrocl:dispatcher:name",funcname);
-	Setattr(overloaded_from,"allegrocl:dispatcher:include-class", smartmemberwrapper ? 0 : "1");
-	// Printf(stderr, "   set a:d:name='%s', a:d:i-c='%s'\n", Getattr(n,"allegrocl:dispatcher:name"), Getattr(n,"allegrocl:dispatcher:include-class"));
-      }
-      Printf(fcl, "(swig-defmethod (\"%s\" \"%s\"%s)\n", funcname, mangled_name, extra_parms);
-    } else
-      Printf(fcl, "(swig-defun (\"%s\" \"%s\"%s)\n", funcname, mangled_name, extra_parms);
-    Delete(extra_parms);
-  }
-  // Just C
-  else {
-    Printf(fcl, "(swig-defun (\"%s\" \"%s\")\n", funcname, Generate_Wrapper ? mangled_name : funcname);
-  }
-
-  //////////////////////////////////////
-  // Lisp foreign call parameter list //
-  //////////////////////////////////////
-  Printf(fcl, "  (");
-
-  /* Special cases */
-
-  if (ParmList_len(pl) == 0) {
-    Printf(fcl, ":void");
-/*  } else if (any_varargs(pl)) {
-    Printf(fcl, "#| varargs |#");
-    varargs=1; */
-  } else {
-    String *largs = NewString("");
-
-    for (p = pl; p; p = nextSibling(p), argnum++, largnum++) {
-      // SwigType *argtype=Getattr(p, "type");
-      SwigType *argtype = Swig_cparse_type(Getattr(p, "tmap:ctype"));
-      SwigType *parmtype = Getattr(p,"type");
-
-      if (!first) {
-	Printf(fcl, "\n   ");
-      }
-
-      /* by default, skip varargs */
-      if (!SwigType_isvarargs(parmtype)) {
-	String *argname = NewStringf("PARM%d_%s", largnum, Getattr(p, "name"));
-
-	// Printf(stderr,"%s\n", Getattr(p,"tmap:lin"));
-	String *ffitype = compose_foreign_type(n, argtype, Getattr(p,"name"));
-	String *deref_ffitype = dereference_ffitype(ffitype);
-	String *lisptype = get_lisp_type(n, parmtype, Getattr(p, "name"));
-
-#ifdef ALLEGROCL_DEBUG
-	Printf(stderr, "lisptype of '%s' '%s' = '%s'\n", parmtype,
-	       Getattr(p, "name"), lisptype);
-#endif
-
-	// while we're walking the parameters, generating LIN
-	// wrapper code...
-	Setattr(p, "lname", NewStringf("SWIG_arg%d", largnum));
-
-	String *parm_code = Getattr(p, "tmap:lin");
-	if (parm_code) {
-	  String *lname = Getattr(p, "lname");
-
-	  Printf(largs, " %s", lname);
-	  Replaceall(parm_code, "$in_fftype", ffitype); // must come before $in
-	  Replaceall(parm_code, "$in", argname);
-	  Replaceall(parm_code, "$out", lname);
-	  Replaceall(parm_code, "$*in_fftype", deref_ffitype);
-	  Replaceall(wrap->code, "$body", parm_code);
-	}
-
-	String *dispatchtype = Getattr(n, "sym:overloaded") ? dispatching_type(n, p) : NewString("");
-
-	// if this parameter has been removed from the C/++ wrapper
-	// it shouldn't be in the lisp wrapper either.
-	if (!checkAttribute(p, "tmap:in:numinputs", "0")) {
-	  Printf(fcl, "(%s %s %s %s %s)",
-		 // parms in the ff wrapper, but not in the lisp wrapper.
-		 (checkAttribute(p, "tmap:lin:numinputs", "0") ? ":p-" : ":p+"), argname, dispatchtype, ffitype, lisptype);
-
-	  first = 0;
-	}
-
-	Delete(argname);
-	Delete(ffitype);
-	Delete(deref_ffitype);
-	Delete(lisptype);
-      }
-    }
-
-    Printf(wrap->locals, "%s", largs);
-  }
-
-  String *lout = Getattr(n, "tmap:lout");
-  Replaceall(lout, "$owner", GetFlag(n, "feature:new") ? "t" : "nil");
-
-  Replaceall(wrap->code, "$body", lout);
-  // $lclass handling.
-  String *lclass = (String *) 0;
-  SwigType *parsed = Swig_cparse_type(Getattr(n, "tmap:ctype"));
-  //  SwigType *cl_t = SwigType_typedef_resolve_all(parsed);
-  SwigType *cl_t = class_from_class_or_class_ref(parsed);
-  String *out_ffitype = compose_foreign_type(n, parsed);
-  String *deref_out_ffitype;
-  String *out_temp = Copy(parsed);
-
-  if (SwigType_ispointer(out_temp)) {
-    SwigType_pop(out_temp);
-    deref_out_ffitype = compose_foreign_type(n, out_temp);
-  } else {
-    deref_out_ffitype = Copy(out_ffitype);
-  }
-
-  Delete(out_temp);
-
-  Delete(parsed);
-
-  if (cl_t) {
-    lclass = lookup_defined_foreign_ltype(cl_t);
-  }
-
-  int ff_foreign_ptr = 0;
-  if (!lclass) {
-    ff_foreign_ptr = 1;
-    lclass = NewStringf("ff:foreign-pointer");
-  }
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "for output wrapping %s: type=%s, ctype=%s\n", Getattr(n, "name"),
-	 Getattr(n, "type"), Swig_cparse_type(Getattr(n, "tmap:ctype")));
-#endif
-
-  if (lclass)
-    Replaceall(wrap->code, "$lclass", lclass);
-  if (out_ffitype)
-    Replaceall(wrap->code, "$out_fftype", out_ffitype);
-  if (deref_out_ffitype)
-    Replaceall(wrap->code, "$*out_fftype", deref_out_ffitype);
-
-  Replaceall(wrap->code, "$body", NewStringf("(swig-ff-call%s)", wrap->locals));
-  String *ldestructor = Copy(lclass);
-  if (ff_foreign_ptr)
-    Replaceall(ldestructor, ldestructor, "cl::identity");
-  else
-    Replaceall(ldestructor, ":type :class", ":type :destructor");
-  Replaceall(wrap->code, "$ldestructor", ldestructor);
-  Delete(ldestructor);
-
-  Printf(fcl, ")\n");		/* finish arg list */
-
-  /////////////////////////////////////////////////////
-  // Lisp foreign call return type and optimizations //
-  /////////////////////////////////////////////////////
-  Printf(fcl, "  (:returning (%s %s)", compose_foreign_type(n, result_type), get_lisp_type(n, Getattr(n, "type"), Swig_cresult_name()));
-
-  for (Iterator option = First(n); option.item; option = Next(option)) {
-    if (Strncmp("feature:ffargs:", option.key, 15))
-      continue;
-    String *option_val = option.item;
-    String *option_name = NewString(Char(option.key) + 14);
-    Replaceall(option_name, "_", "-");
-
-    // TODO: varargs vs call-direct ?
-    Printf(fcl, "\n   %s %s", option_name, option_val);
-
-    Delete(option_name);
-  }
-
-  Printf(fcl, ")\n  %s)\n\n", wrap->code);
-  // Wrapper_print(wrap, stderr);
-
-  Delete(result_type);
-  Delete(mangled_name);
-  Delete(pl);
-  DelWrapper(wrap);
-
-#ifdef ALLEGROCL_WRAP_DEBUG
-  Printf(stderr, "emit_defun: EXIT\n");
-#endif
-
-  return SWIG_OK;
-}
-
-int ALLEGROCL::functionWrapper(Node *n) {
-#ifdef ALLEGROCL_DEBUG
-	Printf(stderr, "functionWrapper %s\n", Getattr(n,"name"));
-#endif
-
-
-  ParmList *parms = CopyParmList(Getattr(n, "parms"));
-  Wrapper *f = NewWrapper();
-  SwigType *t = Getattr(n, "type");
-  String *name = Getattr(n, "name");
-
-  String *raw_return_type = Swig_typemap_lookup("ctype", n, "", 0);
-  SwigType *return_type = Swig_cparse_type(raw_return_type);
-  SwigType *resolved = SwigType_typedef_resolve_all(return_type);
-  int is_void_return = (Cmp(resolved, "void") == 0);
-
-  Delete(resolved);
-
-  if (!is_void_return) {
-     String *lresult_init =
-	     NewStringf("= (%s)0",
-			SwigType_str(SwigType_strip_qualifiers(return_type),0));
-     Wrapper_add_localv(f, "lresult",
-			SwigType_lstr(SwigType_ltype(return_type), "lresult"),
-			lresult_init, NIL);
-     Delete(lresult_init);
-  }
-  // Emit all of the local variables for holding arguments.
-  emit_parameter_variables(parms, f);
-
-  // Attach the standard typemaps 
-  Swig_typemap_attach_parms("ctype", parms, f);
-  Swig_typemap_attach_parms("lin", parms, f);
-  emit_attach_parmmaps(parms, f);
-
-  String *mangled = mangle_name(n);
-  Node *overloaded = Getattr(n, "sym:overloaded");
-
-  // Parameter overloading
-  Setattr(n, "wrap:parms", parms);
-  Setattr(n, "wrap:name", mangled);
-
-  if (overloaded) {
-    // emit warnings when overloading is impossible on the lisp side.
-    // basically Swig_overload_check(n), but with script_lang_wrapping
-    // set to true.
-    Delete(Swig_overload_rank(n, true));
-    if (Getattr(n, "overload:ignore")) {
-      // if we're the last overload, make sure to force the emit
-      // of the rest of the overloads before we leave.
-      // Printf(stderr, "ignored overload %s(%p)\n", name, Getattr(n, "sym:nextSibling"));
-      if (!Getattr(n, "sym:nextSibling")) {
-	update_package_if_needed(n);
-	emit_buffered_defuns(n);
-	emit_dispatch_defun(n);
-      }
-      DelWrapper(f);
-      return SWIG_OK;
-    }
-  }
-  // Get number of required and total arguments 
-  int num_arguments = emit_num_arguments(parms);
-  int gencomma = 0;
-
-#ifdef ALLEGROCL_DEBUG
-  Printf(stderr, "Walking parameters for %s '%s'\n", Getattr(n, "allegrocl:kind"), name);
-#endif
-  // Now walk the function parameter list and generate code to get arguments
-  String *name_and_parms = NewStringf("%s (", mangled);
-  int i;
-  Parm *p;
-  for (i = 0, p = parms; i < num_arguments; i++) {
-
-#ifdef ALLEGROCL_DEBUG
-	  String *temp1 = Getattr(p,"tmap:in");
-	  String *temp2 = Getattr(p,"tmap:in:numinputs");
-	  Printf(stderr,"  parm %d: %s, tmap:in='%s', tmap:in:numinputs='%s'\n", i, Getattr(p,"name"), temp1 ? temp1 : "", temp2 ? temp2 : "");
-#endif
-
-    while (p && checkAttribute(p, "tmap:in:numinputs", "0")) {
-      p = Getattr(p, "tmap:in:next");
-    }
-
-    if (!p)
-      break;
-
-    SwigType *c_parm_type = Swig_cparse_type(Getattr(p, "tmap:ctype"));
-    String *arg = NewStringf("l%s", Getattr(p, "lname"));
-
-    // Emit parameter declaration
-    if (gencomma)
-      Printf(name_and_parms, ", ");
-    String *parm_decl = SwigType_str(c_parm_type, arg);
-    Printf(name_and_parms, "%s", parm_decl);
-#ifdef ALLEGROCL_DEBUG
-    Printf(stderr, "  param: %s\n", parm_decl);
-#endif
-    Delete(parm_decl);
-    gencomma = 1;
-
-    // Emit parameter conversion code
-    String *parm_code = Getattr(p, "tmap:in");
-    //if (!parm_code) {
-    //  Swig_warning(...);
-    //  p = nextSibling(p);
-    /*} else */  {
-      // canThrow(n, "in", p);
-      Replaceall(parm_code, "$input", arg);
-      Setattr(p, "emit:input", arg);
-      Printf(f->code, "%s\n", parm_code);
-      p = Getattr(p, "tmap:in:next");
-    }
-
-    Delete(arg);
-  }
-  Printf(name_and_parms, ")");
-
-#ifdef ALLEGROCL_DEBUG
-  Printf(stderr, "   arity = %d(%d)\n", emit_num_lin_arguments(parms), emit_num_lin_arguments(Getattr(n,"wrap:parms")));
-#endif
-
-  // Emit the function definition
-  String *signature = SwigType_str(return_type, name_and_parms);
-  Printf(f->def, "EXPORT %s {", signature);
-  if (CPlusPlus)
-    Printf(f->code, "  try {\n");
-
-  String *actioncode = emit_action(n);
-
-  String *tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode);
-  if (!is_void_return) {
-    if (tm) { 
-      Replaceall(tm, "$result", "lresult");
-      Printf(f->code, "%s\n", tm);
-      Printf(f->code, "    return lresult;\n");
-      Delete(tm);
-    } else {
-      Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number,
-		   "Unable to use return type %s in function %s.\n",
-		   SwigType_str(t, 0), name);
-    }
-  }
-
-  /* See if there is any return cleanup code */
-  if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
-    Replaceall(tm, "$source", Swig_cresult_name());
-    Printf(f->code, "%s\n", tm);
-    Delete(tm);
-  }
-
-  emit_return_variable(n, t, f);
-
-  if (CPlusPlus) {
-    Printf(f->code, "  } catch (...) {\n");
-    if (!is_void_return)
-      Printf(f->code, "    return (%s)0;\n",
-	     SwigType_str(SwigType_strip_qualifiers(return_type),0));
-    Printf(f->code, "  }\n");
-  }
-  Printf(f->code, "}\n");
-
-  /* print this when in C mode? make this a command-line arg? */
-  if (Generate_Wrapper)
-    Wrapper_print(f, f_cxx_wrapper);
-
-  String *f_buffer = NewString("");
-
-  emit_defun(n, f_buffer);
-  Setattr(n, "allegrocl:lisp-wrap", f_buffer);
-
-  if (!overloaded || !Getattr(n, "sym:nextSibling")) {
-    update_package_if_needed(n);
-    emit_buffered_defuns(n);
-    // this is the last overload.
-    if (overloaded) {
-      emit_dispatch_defun(n);
-    }
-  }
-
-  DelWrapper(f);
-
-  return SWIG_OK;
-}
-
-int ALLEGROCL::namespaceDeclaration(Node *n) {
-#ifdef ALLEGROCL_DEBUG
-  Printf(stderr, "namespaceDecl: '%s'(%p) (fc=%p)\n", Getattr(n, "sym:name"), n, firstChild(n));
-#endif
-
-  /* don't wrap a namespace with no contents. package bloat.
-     also, test-suite/namespace_class.i claims an unnamed namespace
-     is 'private' and should not be wrapped. Complying...
-  */
-  if (Getattr(n,"unnamed") || !firstChild(n))
-    return SWIG_OK;
-
-  String *name = Getattr(n, "sym:name");
-
-  String *old_namespace = current_namespace;
-  if (Cmp(current_namespace, "") == 0)
-    current_namespace = NewStringf("%s", name);
-  else
-    current_namespace = NewStringf("%s::%s", current_namespace, name);
-
-  if (!GetInt(defined_namespace_packages, current_namespace)) {
-    SetInt(defined_namespace_packages, current_namespace, 1);
-    String *lispy_namespace = listify_namespace(current_namespace);
-    Printf(f_clhead, "(swig-defpackage %s)\n", lispy_namespace);
-    Delete(lispy_namespace);
-  }
-
-  emit_children(n);
-
-  Delete(current_namespace);
-  current_namespace = old_namespace;
-  return SWIG_OK;
-}
-
-int ALLEGROCL::constructorHandler(Node *n) {
-#ifdef ALLEGROCL_DEBUG
-  Printf(stderr, "constructorHandler %s\n", Getattr(n, "name"));
-#endif
-  // Swig_print_node(n);
-  Setattr(n, "allegrocl:kind", "constructor");
-  Setattr(n, "allegrocl:old-sym:name", Getattr(n, "sym:name"));
-
-  // Let SWIG generate a global forwarding function.
-  return Language::constructorHandler(n);
-}
-
-int ALLEGROCL::destructorHandler(Node *n) {
-#ifdef ALLEGROCL_DEBUG
-  Printf(stderr, "destructorHandler %s\n", Getattr(n, "name"));
-#endif
-
-  Setattr(n, "allegrocl:kind", "destructor");
-  Setattr(n, "allegrocl:old-sym:name", Getattr(n, "sym:name"));
-
-  // Let SWIG generate a global forwarding function.
-  return Language::destructorHandler(n);
-}
-
-int ALLEGROCL::constantWrapper(Node *n) {
-#ifdef ALLEGROCL_DEBUG
-  Printf(stderr, "constantWrapper %s\n", Getattr(n, "name"));
-#endif
-
-  if (Generate_Wrapper) {
-    // Setattr(n,"wrap:name",mangle_name(n, "ACLPP"));
-    String *const_type = Getattr(n, "type");
-
-    String *const_val = 0;
-    String *raw_const = Getattr(n, "value");
-
-    if (SwigType_type(const_type) == T_STRING) {
-      const_val = NewStringf("\"%s\"", raw_const);
-    } else if (SwigType_type(const_type) == T_CHAR) {
-      const_val = NewStringf("'%s'", raw_const);
-    } else {
-      const_val = Copy(raw_const);
-    }
-
-    SwigType_add_qualifier(const_type, "const");
-
-    String *ppcname = NewStringf("ACLppc_%s", Getattr(n, "sym:name"));
-    // Printf(f_runtime, "static const %s = %s;\n", SwigType_lstr(const_type, ppcname), const_val);
-    Printf(f_runtime, "static %s = %s;\n", SwigType_lstr(const_type, ppcname), const_val);
-
-    Setattr(n, "name", ppcname);
-    SetFlag(n, "feature:immutable");
-
-    Delete(const_val);
-    return variableWrapper(n);
-  }
-
-  String *type = Getattr(n, "type");
-  String *value = Getattr(n, "value");
-  String *converted_value = convert_literal(value, type);
-  String *name = Getattr(n, "sym:name");
-
-  Setattr(n, "allegrocl:kind", "constant");
-  Setattr(n, "allegrocl:old-sym:name", Getattr(n, "sym:name"));
-
-#if 0
-  Printf(stdout, "constant %s is of type %s. value: %s\n", name, type, converted_value);
-#endif
-
-  if (converted_value) {
-    Printf(f_clwrap, "(swig-defconstant \"%s\" %s)\n", name, converted_value);
-  } else {
-    Swig_warning(WARN_LANG_DISCARD_CONST, Getfile(n), Getline(n), "Unable to parse constant value '%s'. Setting to NIL\n", value);
-    Printf(f_clwrap, "(swig-defconstant \"%s\" nil #| %s |#)\n", name, value);
-  }
-
-  Delete(converted_value);
-
-  return SWIG_OK;
-}
-
-int ALLEGROCL::globalvariableHandler(Node *n) {
-#ifdef ALLEGROCL_DEBUG
-  Printf(stderr, "globalvariableHandler %s\n", Getattr(n, "name"));
-#endif
-
-  if (Generate_Wrapper)
-    return Language::globalvariableHandler(n);
-
-  // String *name = Getattr(n, "name");
-  SwigType *type = Getattr(n, "type");
-  SwigType *rtype = SwigType_typedef_resolve_all(type);
-
-  if (SwigType_isclass(rtype)) {
-    SwigType_add_pointer(type);
-    SwigType_add_pointer(rtype);
-  }
-
-  Printf(f_clwrap, "(swig-defvar \"%s\" \"%s\" :type %s)\n",
-	 Getattr(n, "sym:name"), Getattr(n, "sym:name"), ((SwigType_isconst(type)) ? ":constant" : ":variable"));
-
-  return SWIG_OK;
-}
-
-int ALLEGROCL::variableWrapper(Node *n) {
-#ifdef ALLEGROCL_DEBUG
-  Printf(stderr, "variableWrapper %s\n", Getattr(n, "name"));
-#endif
-  Setattr(n, "allegrocl:kind", "variable");
-  Setattr(n, "allegrocl:old-sym:name", Getattr(n, "sym:name"));
-
-  // Let SWIG generate a get/set function pair.
-  if (Generate_Wrapper)
-    return Language::variableWrapper(n);
-
-  String *name = Getattr(n, "name");
-  SwigType *type = Getattr(n, "type");
-  SwigType *ctype;
-  SwigType *rtype = SwigType_typedef_resolve_all(type);
-
-  String *mangled_name = mangle_name(n);
-
-  int pointer_added = 0;
-
-  if (SwigType_isclass(rtype)) {
-    SwigType_add_pointer(type);
-    SwigType_add_pointer(rtype);
-    pointer_added = 1;
-  }
-
-  ctype = SwigType_str(type, 0);
-
-  // EXPORT <SwigType_str> <mangled_name>;
-  // <SwigType_str> <mangled_name> = <name>;
-  Printf(f_runtime, "EXPORT %s %s;\n%s %s = %s%s;\n", ctype, mangled_name, ctype, mangled_name, (pointer_added ? "&" : ""), name);
-
-  Printf(f_cl, "(swig-defvar \"%s\" :type %s)\n", mangled_name, ((SwigType_isconst(type)) ? ":constant" : ":variable"));
-
-  Printf(stderr,"***\n");
-  Delete(mangled_name);
-
-#ifdef ALLEGROCL_DEBUG
-  Printf(stderr, "DONE variable %s\n", Getattr(n, "name"));
-#endif
-
-  return SWIG_OK;
-}
-
-int ALLEGROCL::memberfunctionHandler(Node *n) {
-#ifdef ALLEGROCL_DEBUG
-  Printf(stderr, "memberfunctionHandler %s::%s\n", Getattr(parent_node_skipping_extends(n), "name"), Getattr(n, "name"));
-  Swig_print_node(n);
-#endif
-  Setattr(n, "allegrocl:kind", "member function");
-  Setattr(n, "allegrocl:old-sym:name", Getattr(n, "sym:name"));
-
-  // Let SWIG generate a global forwarding function.
-  return Language::memberfunctionHandler(n);
-}
-
-int ALLEGROCL::membervariableHandler(Node *n) {
-#ifdef ALLEGROCL_DEBUG
-  Printf(stderr, "membervariableHandler %s::%s\n", Getattr(parent_node_skipping_extends(n), "name"), Getattr(n, "name"));
-#endif
-  Setattr(n, "allegrocl:kind", "member variable");
-  Setattr(n, "allegrocl:old-sym:name", Getattr(n, "sym:name"));
-
-  // Let SWIG generate a get/set function pair.
-  return Language::membervariableHandler(n);
-}
-
-int ALLEGROCL::typedefHandler(Node *n) {
-#ifdef ALLEGROCL_TYPE_DEBUG
-  Printf(stderr, "In typedefHandler\n");
-#endif
-
-  SwigType *typedef_type = Getattr(n,"type");
-  // has the side-effect of noting any implicit
-  // template instantiations in type.
-  String *ff_type = compose_foreign_type(n, typedef_type);
-
-  String *sym_name = Getattr(n, "sym:name");
-
-  String *name;
-  String *type_ref;
-
-  if (in_class) {
-#ifdef ALLEGROCL_TYPE_DEBUG
-    Printf(stderr, "  typedef in class '%s'(%p)\n", Getattr(in_class, "sym:name"), in_class);
-#endif
-    Setattr(n, "allegrocl:typedef:in-class", in_class);
-
-    String *class_name = Getattr(in_class, "name");
-    name = NewStringf("%s__%s", class_name, sym_name);
-    type_ref = NewStringf("%s::%s", class_name, sym_name);
-    Setattr(n, "allegrocl:in-class", in_class);
-  } else {
-    name = Copy(sym_name);
-    type_ref = Copy(Getattr(n, "name"));
-  }
-
-  Setattr(n, "allegrocl:namespace", current_namespace);
-
-  String *lookup = lookup_defined_foreign_type(typedef_type);
-
-#ifdef ALLEGROCL_TYPE_DEBUG
-  Printf(stderr, "** lookup='%s'(%p), typedef_type='%s', strcmp = '%d' strstr = '%d'\n", lookup, lookup, typedef_type, Strcmp(typedef_type,"void"), Strstr(ff_type,"__SWIGACL_FwdReference"));
-#endif
-
-  if(lookup || (!lookup && Strcmp(typedef_type,"void")) ||
-     (!lookup && Strstr(ff_type,"__SWIGACL_FwdReference"))) {
-	  add_defined_foreign_type(n, 0, type_ref, name);
-  } else {
-     add_forward_referenced_type(n);
-  }
-
-#ifdef ALLEGROCL_TYPE_DEBUG
-  Printf(stderr, "Out typedefHandler\n");
-#endif
-
-  Delete(ff_type);
-
-  return SWIG_OK;
-}
-
-// forward referenced classes are added specially to defined_foreign_types
-int ALLEGROCL::classforwardDeclaration(Node *n) {
-#ifdef ALLEGROCL_DEBUG
-  Printf(stderr, "classforwardDeclaration %s\n", Getattr(n, "name"));
-#endif
-
-  add_forward_referenced_type(n);
-  return SWIG_OK;
-}
-
-int ALLEGROCL::classHandler(Node *n) {
-#ifdef ALLEGROCL_DEBUG
-  Printf(stderr, "classHandler %s::%s\n", current_namespace, Getattr(n, "sym:name"));
-#endif
-
-  int result;
-
-  if (Generate_Wrapper)
-    result = cppClassHandler(n);
-  else
-    result = cClassHandler(n);
-
-  return result;
-}
-
-int ALLEGROCL::cClassHandler(Node *n) {
-#ifdef ALLEGROCL_TYPE_DEBUG
-  Printf(stderr, "In cClassHandler\n");
-#endif
-  /* Add this structure to the known lisp types */
-  // Printf(stderr, "Adding %s foreign type\n", name);
-  String *ns = listify_namespace(current_namespace);
-
-  add_defined_foreign_type(n);
-
-  Delete(ns);
-
-#ifdef ALLEGROCL_TYPE_DEBUG
-  Printf(stderr, "Out cClassHandler\n");
-#endif
-
-  return SWIG_OK;
-}
-
-int ALLEGROCL::cppClassHandler(Node *n) {
-#ifdef ALLEGROCL_DEBUG
-  Printf(stderr, "cppClassHandler %s\n", Getattr(n, "name"));
-#endif
-
-  // String *name=Getattr(n, "sym:name");
-  // String *kind = Getattr(n,"kind");
-
-  /* Template instantiation.
-     Careful. 
-     SWIG does not create instantiations of templated classes whenever
-     it sees a templated class reference (say, as a return type, or
-     in a parameter list).
-
-     The %template directive results in a templated class instantiation
-     that will actually be seen by <LANG> :: classHandler().
-
-     In this case, we don't want to error if the type already exists;
-     the point is to force the creation of wrappers for the templated
-     class.
-   */
-  String *templated = Getattr(n, "template");
-  String *t_name;
-  // String *ns = listify_namespace(current_namespace);
-
-  if (templated) {
-    t_name = namespaced_name(n);
-  } else {
-    t_name = Getattr(n, "name");
-  }
-
-  Setattr(n, "allegrocl:namespace", current_namespace);
-
-  /* Add this structure to the known lisp types.
-     Class may contain references to the type currently being
-     defined */
-  if (!templated || !lookup_defined_foreign_type(t_name)) {
-#ifdef ALLEGROCL_CLASS_DEBUG
-    Printf(stderr, "Adding %s foreign type\n", Getattr(n, "sym:name"));
-#endif
-    add_defined_foreign_type(n);
-  } else {
-#ifdef ALLEGROCL_CLASS_DEBUG
-    Printf(stderr, "cppClassHand: type %s already exists. Assuming %%template instantiation for wrapping purposes.\n", Getattr(n, "sym:name"));
-#endif
-    add_defined_foreign_type(n, 1);
-  }
-
-  // Generate slot accessors, constructor, and destructor.
-  Node *prev_class = in_class;
-  in_class = n;
-
-  Node *c;
-  // walk all member variables.
-#ifdef ALLEGROCL_CLASS_DEBUG
-  Printf(stderr, "   MANUALLY walking class members... \n");
-#endif
-  for (c = firstChild(n); c; c = nextSibling(c)) {
-    // ping the types of all children--even protected and private
-    // so their types can be added to the linked_type_list.
-    SwigType *childType = NewStringf("%s%s", Getattr(c, "decl"),
-				     Getattr(c, "type"));
-#ifdef ALLEGROCL_CLASS_DEBUG
-    Printf(stderr, "looking at child '%p' of type '%s' '%d'\n", c, childType, SwigType_isfunction(childType));
-    // Swig_print_node(c);
-#endif
-    if (!SwigType_isfunction(childType))
-      Delete(compose_foreign_type(n, childType));
-
-    Delete(childType);
-  }
-#ifdef ALLEGROCL_CLASS_DEBUG
-  Printf(stderr, "   MANUAL walk DONE.\n");
-#endif
-
-  // this will walk all necessary methods.
-#ifdef ALLEGROCL_CLASS_DEBUG
-  Printf(stderr, "   LANGUAGE walk of children...\n");
-#endif
-  Language::classHandler(n);
-#ifdef ALLEGROCL_CLASS_DEBUG
-  Printf(stderr, "   LANGUAGE walk DONE\n");
-#endif
-  in_class = prev_class;
-
-  return SWIG_OK;
-}
-
-int ALLEGROCL::emit_one(Node *n) {
-  // When the current package does not correspond with the current
-  // namespace we need to generate an IN-PACKAGE form, unless the
-  // current node is another namespace node.
-  if (Cmp(nodeType(n), "namespace") != 0 && Cmp(current_package, current_namespace) != 0) {
-    String *lispy_namespace = listify_namespace(current_namespace);
-    Printf(f_clwrap, "(swig-in-package %s)\n", lispy_namespace);
-    Delete(lispy_namespace);
-    Delete(current_package);
-    current_package = NewStringf("%s", current_namespace);
-  }
-
-  Setattr(n, "allegrocl:package", current_package);
-
-  return Language::emit_one(n);
-}
-
-int ALLEGROCL::enumDeclaration(Node *n) {
-#ifdef ALLEGROCL_DEBUG
-  Printf(stderr, "enumDeclaration %s\n", Getattr(n, "name"));
-#endif
-
-  if (getCurrentClass() && (cplus_mode != PUBLIC))
-    return SWIG_NOWRAP;
-
-  if (Getattr(n, "sym:name")) {
-    add_defined_foreign_type(n);
-  }
-  Node *c;
-  for (c = firstChild(n); c; c = nextSibling(c)) {
-    ALLEGROCL::enumvalueDeclaration(c);
-    // since we walk our own children, we need to add
-    // the current package ourselves.
-    Setattr(c, "allegrocl:package", current_package);
-  }
-  return SWIG_OK;
-}
-
-
-int ALLEGROCL::enumvalueDeclaration(Node *n) {
-#ifdef ALLEGROCL_DEBUG
-  Printf(stderr, "enumvalueDeclaration %s\n", Getattr(n, "name"));
-#endif
-  /* print this when in C mode? make this a command-line arg? */
-  if (Generate_Wrapper) {
-	  SwigType *enum_type = Copy(Getattr(n,"type"));
-	  String *mangled_name =
-		  mangle_name(n, "ACL_ENUM",
-			      in_class ? Getattr(in_class,"name") :
-			      current_namespace);
-	  
-	  SwigType_add_qualifier(enum_type,"const");
-
-	  String *enum_decl = SwigType_str(enum_type, mangled_name);
-	  Printf(f_cxx_wrapper, "EXPORT %s;\n", enum_decl);
-	  Printf(f_cxx_wrapper, "%s = %s;\n", enum_decl, Getattr(n, "value"));
-
-    Delete(mangled_name);
-    Delete(enum_type);
-    Delete(enum_decl);
-  }
-  return SWIG_OK;
-}
-
-int ALLEGROCL::templateDeclaration(Node *n) {
-#ifdef ALLEGROCL_DEBUG
-  Printf(stderr, "templateDeclaration %s\n", Getattr(n, "name"));
-#endif
-
-  String *type = Getattr(n, "templatetype");
-
-  // Printf(stderr, "tempDecl: %s %s\n", Getattr(n,"name"),
-  //        type);
-  // Swig_print_node(n);
-
-  if (!Strcmp(type, "cdecl")) {
-    SwigType *ty = NewStringf("%s%s", Getattr(n, "decl"),
-			      Getattr(n, "type"));
-    Delete(ty);
-  }
-
-  Delete(type);
-
-  return SWIG_OK;
-}
-
diff --git a/Source/Modules/allocate.cxx b/Source/Modules/allocate.cxx
index 23683c3..a53be07 100644
--- a/Source/Modules/allocate.cxx
+++ b/Source/Modules/allocate.cxx
@@ -4,15 +4,26 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * allocate.cxx
  *
- * This module tries to figure out which classes and structures support
+ * This module also has two main purposes modifying the parse tree.
+ *
+ * First, it is responsible for adding in using declarations from base class
+ * members into the parse tree.
+ *
+ * Second, after each class declaration, it analyses if the class/struct supports
  * default constructors and destructors in C++.   There are several rules that
  * define this behavior including pure abstract methods, private sections,
  * and non-default constructors in base classes.  See the ARM or
  * Doc/Manual/SWIGPlus.html for details.
+ *
+ * Once the analysis is complete, the non-explicit/implied default constructors
+ * and destructors are added to the parse tree. Implied copy constructors are
+ * added too if requested via the copyctor feature. Detection of implied
+ * assignment operators is also handled as assigment is required in the generated
+ * code for variable setters.
  * ----------------------------------------------------------------------------- */
 
 #include "swigmod.h"
@@ -30,7 +41,7 @@
 
 extern "C" {
   static String *search_decl = 0;	/* Declarator being searched */
-  static int check_implemented(Node *n) {
+  static Node *check_implemented(Node *n) {
     String *decl;
     if (!n)
        return 0;
@@ -44,7 +55,7 @@
 	    if (!GetFlag(n, "abstract")) {
 	      Delete(decl1);
 	      Delete(decl2);
-	      return 1;
+	      return n;
 	    }
 	  }
 	  Delete(decl1);
@@ -197,7 +208,7 @@
 	      // Found a polymorphic method.
 	      // Mark the polymorphic method, in case the virtual keyword was not used.
 	      Setattr(n, "storage", "virtual");
-	      if (!Getattr(b, "feature:interface")) { // interface implementation neither hides nor overrides
+	      if (!GetFlag(b, "feature:interface")) { // interface implementation neither hides nor overrides
 		if (both_have_public_access || both_have_protected_access) {
 		  if (!is_non_public_base(inclass, b))
 		    Setattr(n, "override", base);	// Note C# definition of override, ie access must be the same
@@ -396,7 +407,7 @@
 	if (!GetFlag(c, "feature:ignore")) {
 	  String *storage = Getattr(c, "storage");
 	  if (!((Cmp(storage, "typedef") == 0))
-	      && !((Cmp(storage, "friend") == 0))) {
+	      && !Strstr(storage, "friend")) {
 	    String *name = Getattr(c, "name");
 	    String *symname = Getattr(c, "sym:name");
 	    Node *e = Swig_symbol_clookup_local(name, 0);
@@ -526,6 +537,172 @@
     }
   }
 
+/* -----------------------------------------------------------------------------
+ * clone_member_for_using_declaration()
+ *
+ * Create a new member (constructor or method) by copying it from member c, ready
+ * for adding as a child to the using declaration node n.
+ * ----------------------------------------------------------------------------- */
+
+  Node *clone_member_for_using_declaration(Node *c, Node *n) {
+    Node *parent = parentNode(n);
+    String *decl = Getattr(c, "decl");
+    String *symname = Getattr(n, "sym:name");
+    int match = 0;
+
+    Node *over = Getattr(n, "sym:overloaded");
+    while (over) {
+      String *odecl = Getattr(over, "decl");
+      if (Cmp(decl, odecl) == 0) {
+	match = 1;
+	break;
+      }
+      over = Getattr(over, "sym:nextSibling");
+    }
+
+    if (match) {
+      /* Don't generate a method if the method is overridden in this class,
+       * for example don't generate another m(bool) should there be a Base::m(bool) :
+       * struct Derived : Base {
+       *   void m(bool);
+       *   using Base::m;
+       * };
+       */
+      return 0;
+    }
+
+    Node *nn = copyNode(c);
+    Setfile(nn, Getfile(n));
+    Setline(nn, Getline(n));
+    if (!Getattr(nn, "sym:name"))
+      Setattr(nn, "sym:name", symname);
+    Symtab *st = Getattr(n, "sym:symtab");
+    assert(st);
+    Setattr(nn, "sym:symtab", st);
+    // The real parent is the "using" declaration node, but subsequent code generally handles
+    // and expects a class member to point to the parent class node
+    Setattr(nn, "parentNode", parent);
+
+    if (Equal(nodeType(c), "constructor")) {
+      Setattr(nn, "name", Getattr(n, "name"));
+      Setattr(nn, "sym:name", Getattr(n, "sym:name"));
+      // Note that the added constructor's access is the same as that of
+      // the base class' constructor not of the using declaration.
+      // It has already been set correctly and should not be changed.
+    } else {
+      // Access might be different from the method in the base class
+      Delattr(nn, "access");
+      Setattr(nn, "access", Getattr(n, "access"));
+    }
+
+    if (!GetFlag(nn, "feature:ignore")) {
+      ParmList *parms = CopyParmList(Getattr(c, "parms"));
+      int is_pointer = SwigType_ispointer_return(Getattr(nn, "decl"));
+      int is_void = checkAttribute(nn, "type", "void") && !is_pointer;
+      Setattr(nn, "parms", parms);
+      Delete(parms);
+      if (Getattr(n, "feature:extend")) {
+	String *ucode = is_void ? NewStringf("{ self->%s(", Getattr(n, "uname")) : NewStringf("{ return self->%s(", Getattr(n, "uname"));
+
+	for (ParmList *p = parms; p;) {
+	  Append(ucode, Getattr(p, "name"));
+	  p = nextSibling(p);
+	  if (p)
+	    Append(ucode, ",");
+	}
+	Append(ucode, "); }");
+	Setattr(nn, "code", ucode);
+	Delete(ucode);
+      }
+      ParmList *throw_parm_list = Getattr(c, "throws");
+      if (throw_parm_list)
+	Setattr(nn, "throws", CopyParmList(throw_parm_list));
+    } else {
+      Delete(nn);
+      nn = 0;
+    }
+    return nn;
+  }
+
+/* -----------------------------------------------------------------------------
+ * add_member_for_using_declaration()
+ *
+ * Add a new member (constructor or method) by copying it from member c.
+ * Add it into the linked list of members under the using declaration n (ccount,
+ * unodes and last_unodes are used for this).
+ * ----------------------------------------------------------------------------- */
+
+  void add_member_for_using_declaration(Node *c, Node *n, int &ccount, Node *&unodes, Node *&last_unodes) {
+    if (!(Swig_storage_isstatic(c)
+	  || checkAttribute(c, "storage", "typedef")
+	  || Strstr(Getattr(c, "storage"), "friend")
+	  || (Getattr(c, "feature:extend") && !Getattr(c, "code"))
+	  || GetFlag(c, "feature:ignore"))) {
+
+      String *symname = Getattr(n, "sym:name");
+      String *csymname = Getattr(c, "sym:name");
+      Node *parent = parentNode(n);
+      bool using_inherited_constructor_symname_okay = Equal(nodeType(c), "constructor") && Equal(symname, Getattr(parent, "sym:name"));
+      if (!csymname || Equal(csymname, symname) || using_inherited_constructor_symname_okay) {
+	Node *nn = clone_member_for_using_declaration(c, n);
+	if (nn) {
+	  ccount++;
+	  if (!last_unodes) {
+	    last_unodes = nn;
+	    unodes = nn;
+	  } else {
+	    Setattr(nn, "previousSibling", last_unodes);
+	    Setattr(last_unodes, "nextSibling", nn);
+	    Setattr(nn, "sym:previousSibling", last_unodes);
+	    Setattr(last_unodes, "sym:nextSibling", nn);
+	    Setattr(nn, "sym:overloaded", unodes);
+	    Setattr(unodes, "sym:overloaded", unodes);
+	    last_unodes = nn;
+	  }
+	}
+      } else {
+	Swig_warning(WARN_LANG_USING_NAME_DIFFERENT, Getfile(n), Getline(n), "Using declaration %s, with name '%s', is not actually using\n", SwigType_namestr(Getattr(n, "uname")), symname);
+	Swig_warning(WARN_LANG_USING_NAME_DIFFERENT, Getfile(c), Getline(c), "the method from %s, with name '%s', as the names are different.\n", Swig_name_decl(c), csymname);
+      }
+    }
+  }
+
+  bool is_assignable_type(const SwigType *type) {
+    bool assignable = true;
+    if (SwigType_type(type) == T_USER) {
+      Node *cn = Swig_symbol_clookup(type, 0);
+      if (cn) {
+	if ((Strcmp(nodeType(cn), "class") == 0)) {
+	  if (Getattr(cn, "allocate:noassign")) {
+	    assignable = false;
+	  }
+	}
+      }
+    } else if (SwigType_isarray(type)) {
+      SwigType *array_type = SwigType_array_type(type);
+      assignable = is_assignable_type(array_type);
+    }
+    return assignable;
+  }
+
+  bool is_assignable(Node *n, bool &is_reference, bool &is_const) {
+    SwigType *ty = Copy(Getattr(n, "type"));
+    SwigType_push(ty, Getattr(n, "decl"));
+    SwigType *ftd = SwigType_typedef_resolve_all(ty);
+    SwigType *td = SwigType_strip_qualifiers(ftd);
+
+    bool assignable = is_assignable_type(td);
+    is_reference = SwigType_isreference(td) || SwigType_isrvalue_reference(td);
+    is_const = !SwigType_ismutable(ftd);
+    if (GetFlag(n, "hasconsttype"))
+      is_const = true;
+
+    Delete(ty);
+    Delete(ftd);
+    Delete(td);
+    return assignable;
+  }
+
 public:
 Allocate():
   inclass(NULL), extendmode(0) {
@@ -572,8 +749,10 @@
       Setattr(n, "allocate:default_destructor", "1");
     }
 
-    if (Getattr(n, "allocate:visit"))
+    if (Getattr(n, "allocate:visit")) {
+      Swig_symbol_setscope(symtab);
       return SWIG_OK;
+    }
     Setattr(n, "allocate:visit", "1");
 
     /* Always visit base classes first */
@@ -625,58 +804,85 @@
 	Delattr(n, "allocate:default_constructor");
       }
       if (!Getattr(n, "allocate:default_constructor")) {
-	/* Check base classes */
-	List *bases = Getattr(n, "allbases");
-	int allows_default = 1;
+	// No default constructor if either the default constructor or copy constructor is declared as deleted
+	if (!GetFlag(n, "allocate:deleted_default_constructor") && !GetFlag(n, "allocate:deleted_copy_constructor")) {
+	  /* Check base classes */
+	  List *bases = Getattr(n, "allbases");
+	  int allows_default = 1;
 
-	for (int i = 0; i < Len(bases); i++) {
-	  Node *n = Getitem(bases, i);
-	  /* If base class does not allow default constructor, we don't allow it either */
-	  if (!Getattr(n, "allocate:default_constructor") && (!Getattr(n, "allocate:default_base_constructor"))) {
-	    allows_default = 0;
+	  for (int i = 0; i < Len(bases); i++) {
+	    Node *n = Getitem(bases, i);
+	    /* If base class does not allow default constructor, we don't allow it either */
+	    if (!Getattr(n, "allocate:default_constructor") && (!Getattr(n, "allocate:default_base_constructor"))) {
+	      allows_default = 0;
+	    }
+	    /* not constructible if base destructor is deleted */
+	    if (Getattr(n, "allocate:deleted_default_destructor")) {
+	      allows_default = 0;
+	    }
 	  }
-	}
-	if (allows_default) {
-	  Setattr(n, "allocate:default_constructor", "1");
+	  if (allows_default) {
+	    Setattr(n, "allocate:default_constructor", "1");
+	  }
 	}
       }
     }
+
     if (!Getattr(n, "allocate:has_copy_constructor")) {
       if (Getattr(n, "abstracts")) {
 	Delattr(n, "allocate:copy_constructor");
+	Delattr(n, "allocate:copy_constructor_non_const");
       }
       if (!Getattr(n, "allocate:copy_constructor")) {
-	/* Check base classes */
-	List *bases = Getattr(n, "allbases");
-	int allows_copy = 1;
+	// No copy constructor if the copy constructor is declared as deleted
+	if (!GetFlag(n, "allocate:deleted_copy_constructor")) {
+	  /* Check base classes */
+	  List *bases = Getattr(n, "allbases");
+	  int allows_copy = 1;
+	  int must_be_copy_non_const = 0;
 
-	for (int i = 0; i < Len(bases); i++) {
-	  Node *n = Getitem(bases, i);
-	  /* If base class does not allow copy constructor, we don't allow it either */
-	  if (!Getattr(n, "allocate:copy_constructor") && (!Getattr(n, "allocate:copy_base_constructor"))) {
-	    allows_copy = 0;
+	  for (int i = 0; i < Len(bases); i++) {
+	    Node *n = Getitem(bases, i);
+	    /* If base class does not allow copy constructor, we don't allow it either */
+	    if (!Getattr(n, "allocate:copy_constructor") && (!Getattr(n, "allocate:copy_base_constructor"))) {
+	      allows_copy = 0;
+	    }
+	    /* not constructible if base destructor is deleted */
+	    if (Getattr(n, "allocate:deleted_default_destructor")) {
+	      allows_copy = 0;
+	    }
+	    if (Getattr(n, "allocate:copy_constructor_non_const") || (Getattr(n, "allocate:copy_base_constructor_non_const"))) {
+	      must_be_copy_non_const = 1;
+	    }
 	  }
-	}
-	if (allows_copy) {
-	  Setattr(n, "allocate:copy_constructor", "1");
+	  if (allows_copy) {
+	    Setattr(n, "allocate:copy_constructor", "1");
+	  }
+	  if (must_be_copy_non_const) {
+	    Setattr(n, "allocate:copy_constructor_non_const", "1");
+	  }
 	}
       }
     }
 
     if (!Getattr(n, "allocate:has_destructor")) {
       /* No destructor was defined */
-      List *bases = Getattr(n, "allbases");
-      int allows_destruct = 1;
+      /* No destructor if the destructor is declared as deleted */
+      if (!GetFlag(n, "allocate:deleted_default_destructor")) {
+	/* Check base classes */
+	List *bases = Getattr(n, "allbases");
+	int allows_destruct = 1;
 
-      for (int i = 0; i < Len(bases); i++) {
-	Node *n = Getitem(bases, i);
-	/* If base class does not allow default destructor, we don't allow it either */
-	if (!Getattr(n, "allocate:default_destructor") && (!Getattr(n, "allocate:default_base_destructor"))) {
-	  allows_destruct = 0;
+	for (int i = 0; i < Len(bases); i++) {
+	  Node *n = Getitem(bases, i);
+	  /* If base class does not allow default destructor, we don't allow it either */
+	  if (!Getattr(n, "allocate:default_destructor") && (!Getattr(n, "allocate:default_base_destructor"))) {
+	    allows_destruct = 0;
+	  }
 	}
-      }
-      if (allows_destruct) {
-	Setattr(n, "allocate:default_destructor", "1");
+	if (allows_destruct) {
+	  Setattr(n, "allocate:default_destructor", "1");
+	}
       }
     }
 
@@ -688,10 +894,14 @@
       for (int i = 0; i < Len(bases); i++) {
 	Node *n = Getitem(bases, i);
 	/* If base class does not allow assignment, we don't allow it either */
-	if (Getattr(n, "allocate:has_assign")) {
-	  allows_assign = !Getattr(n, "allocate:noassign");
+	if (Getattr(n, "allocate:noassign")) {
+	  allows_assign = 0;
 	}
       }
+      /* If any member variables are non assignable, this class is also non assignable by default */
+      if (GetFlag(n, "allocate:has_nonassignable")) {
+	allows_assign = 0;
+      }
       if (!allows_assign) {
 	Setattr(n, "allocate:noassign", "1");
       }
@@ -736,30 +946,206 @@
     /* Only care about default behavior.  Remove temporary values */
     Setattr(n, "allocate:visit", "1");
     Swig_symbol_setscope(symtab);
+
+    /* Now we can add the additional implied constructors and destructors to the parse tree */
+    if (!ImportMode && !GetFlag(n, "feature:ignore")) {
+      int dir = 0;
+      if (Swig_directors_enabled()) {
+	int ndir = GetFlag(n, "feature:director");
+	int nndir = GetFlag(n, "feature:nodirector");
+	/* 'nodirector' has precedence over 'director' */
+	dir = (ndir || nndir) ? (ndir && !nndir) : 0;
+      }
+      int abstract = !dir && abstractClassTest(n);
+      int odefault = !GetFlag(n, "feature:nodefault");
+
+      /* default constructor */
+      if (!abstract && !GetFlag(n, "feature:nodefaultctor") && odefault) {
+	if (!Getattr(n, "allocate:has_constructor") && Getattr(n, "allocate:default_constructor")) {
+	  addDefaultConstructor(n);
+	}
+      }
+      /* copy constructor */
+      if (CPlusPlus && !abstract && GetFlag(n, "feature:copyctor")) {
+	if (!Getattr(n, "allocate:has_copy_constructor") && Getattr(n, "allocate:copy_constructor")) {
+	  addCopyConstructor(n);
+	}
+      }
+      /* default destructor */
+      if (!GetFlag(n, "feature:nodefaultdtor") && odefault) {
+	if (!Getattr(n, "allocate:has_destructor") && Getattr(n, "allocate:default_destructor")) {
+	  addDestructor(n);
+	}
+      }
+    }
+
     return SWIG_OK;
   }
 
   virtual int accessDeclaration(Node *n) {
-    String *kind = Getattr(n, "kind");
-    if (Cmp(kind, "public") == 0) {
-      cplus_mode = PUBLIC;
-    } else if (Cmp(kind, "private") == 0) {
-      cplus_mode = PRIVATE;
-    } else if (Cmp(kind, "protected") == 0) {
-      cplus_mode = PROTECTED;
-    }
+    cplus_mode = accessModeFromString(Getattr(n, "kind"));
     return SWIG_OK;
   }
 
   virtual int usingDeclaration(Node *n) {
 
-    Node *c = 0;
-    for (c = firstChild(n); c; c = nextSibling(c)) {
-      if (Strcmp(nodeType(c), "cdecl") == 0) {
-	process_exceptions(c);
+    if (!Getattr(n, "namespace")) {
+      Node *ns;
+      /* using id */
+      Symtab *stab = Getattr(n, "sym:symtab");
+      if (stab) {
+	String *uname = Getattr(n, "uname");
+	ns = Swig_symbol_clookup(uname, stab);
+	if (!ns && SwigType_istemplate(uname)) {
+	  String *tmp = Swig_symbol_template_deftype(uname, 0);
+	  if (!Equal(tmp, uname)) {
+	    ns = Swig_symbol_clookup(tmp, stab);
+	  }
+	  Delete(tmp);
+	}
+      } else {
+	ns = 0;
+      }
+      if (!ns) {
+	if (is_public(n)) {
+	  Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(n), Getline(n), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(n, "uname")));
+	}
+      } else if (Equal(nodeType(ns), "constructor") && !GetFlag(n, "usingctor")) {
+	Swig_warning(WARN_PARSE_USING_CONSTRUCTOR, Getfile(n), Getline(n), "Using declaration '%s' for inheriting constructors uses base '%s' which is not an immediate base of '%s'.\n", SwigType_namestr(Getattr(n, "uname")), SwigType_namestr(Getattr(ns, "name")), SwigType_namestr(Getattr(parentNode(n), "name")));
+      } else {
+	if (inclass && !GetFlag(n, "feature:ignore") && Getattr(n, "sym:name")) {
+	  {
+	    String *ntype = nodeType(ns);
+	    if (Equal(ntype, "cdecl") || Equal(ntype, "constructor") || Equal(ntype, "template") || Equal(ntype, "using")) {
+	      /* Add a new class member to the parse tree (copy it from the base class member pointed to by the using declaration in node n) */
+	      Node *c = ns;
+	      Node *unodes = 0, *last_unodes = 0;
+	      int ccount = 0;
 
-	if (inclass)
-	  class_member_is_defined_in_bases(c, inclass);
+	      while (c) {
+		String *cnodetype = nodeType(c);
+		if (Equal(cnodetype, "cdecl")) {
+		  add_member_for_using_declaration(c, n, ccount, unodes, last_unodes);
+		} else if (Equal(cnodetype, "constructor")) {
+		  add_member_for_using_declaration(c, n, ccount, unodes, last_unodes);
+		} else if (Equal(cnodetype, "template")) {
+		  // A templated member (in a non-template class or in a template class that where the member has a separate template declaration)
+		  // Find the template instantiations in the using declaration (base class)
+		  for (Node *member = ns; member; member = nextSibling(member)) {
+		    /* Constructors have already been handled, only add member functions
+		     * This adds an implicit template instantiation and is a bit unusual as SWIG requires explicit %template for other template instantiations.
+		     * However, of note, is that there is no valid C++ syntax for a template instantiation to introduce a name via a using declaration...
+		     *
+		     *   struct Base { template <typename T> void template_method(T, T) {} };
+		     *   struct Derived : Base { using Base::template_method; };
+		     *   %template()   Base::template_method<int>;              // SWIG template instantiation
+		     *   template void Base::template_method<int>(int, int);    // C++ template instantiation
+		     *   template void Derived::template_method<int>(int, int); // Not valid C++
+		    */
+		    if (Getattr(member, "template") == ns && checkAttribute(ns, "templatetype", "cdecl")) {
+		      if (!GetFlag(member, "feature:ignore") && !Getattr(member, "error")) {
+			add_member_for_using_declaration(member, n, ccount, unodes, last_unodes);
+		      }
+		    }
+		  }
+		} else if (Equal(cnodetype, "using")) {
+		  for (Node *member = firstChild(c); member; member = nextSibling(member)) {
+		    add_member_for_using_declaration(member, n, ccount, unodes, last_unodes);
+		  }
+		}
+		c = Getattr(c, "csym:nextSibling");
+	      }
+	      if (unodes) {
+		set_firstChild(n, unodes);
+		if (ccount > 1) {
+		  if (!Getattr(n, "sym:overloaded")) {
+		    Setattr(n, "sym:overloaded", n);
+		    Setattr(n, "sym:overname", "_SWIG_0");
+		  }
+		}
+	      }
+
+	      /* Hack the parse tree symbol table for overloaded methods. Replace the "using" node with the
+	       * list of overloaded methods we have just added in as child nodes to the "using" node.
+	       * The node will still exist, it is just the symbol table linked list of overloaded methods
+	       * which is hacked. */
+	      if (Getattr(n, "sym:overloaded")) {
+		int cnt = 0;
+		Node *ps = Getattr(n, "sym:previousSibling");
+		Node *ns = Getattr(n, "sym:nextSibling");
+		Node *fc = firstChild(n);
+		Node *firstoverloaded = Getattr(n, "sym:overloaded");
+#ifdef DEBUG_OVERLOADED
+		show_overloaded(firstoverloaded);
+#endif
+
+		if (firstoverloaded == n) {
+		  // This 'using' node we are cutting out was the first node in the overloaded list. 
+		  // Change the first node in the list
+		  Delattr(firstoverloaded, "sym:overloaded");
+		  firstoverloaded = fc ? fc : ns;
+
+		  // Correct all the sibling overloaded methods (before adding in new methods)
+		  Node *nnn = ns;
+		  while (nnn) {
+		    Setattr(nnn, "sym:overloaded", firstoverloaded);
+		    nnn = Getattr(nnn, "sym:nextSibling");
+		  }
+		}
+
+		if (!fc) {
+		  // Remove from overloaded list ('using' node does not actually end up adding in any methods)
+		  if (ps) {
+		    Setattr(ps, "sym:nextSibling", ns);
+		  }
+		  if (ns) {
+		    Setattr(ns, "sym:previousSibling", ps);
+		  }
+		} else {
+		  // The 'using' node results in methods being added in - slot in these methods here
+		  Node *pp = fc;
+		  while (pp) {
+		    Node *ppn = Getattr(pp, "sym:nextSibling");
+		    Setattr(pp, "sym:overloaded", firstoverloaded);
+		    Setattr(pp, "sym:overname", NewStringf("%s_%d", Getattr(n, "sym:overname"), cnt++));
+		    if (ppn)
+		      pp = ppn;
+		    else
+		      break;
+		  }
+		  if (ps) {
+		    Setattr(ps, "sym:nextSibling", fc);
+		    Setattr(fc, "sym:previousSibling", ps);
+		  }
+		  if (ns) {
+		    Setattr(ns, "sym:previousSibling", pp);
+		    Setattr(pp, "sym:nextSibling", ns);
+		  }
+		}
+		Delattr(n, "sym:previousSibling");
+		Delattr(n, "sym:nextSibling");
+		Delattr(n, "sym:overloaded");
+		Delattr(n, "sym:overname");
+		clean_overloaded(firstoverloaded);
+#ifdef DEBUG_OVERLOADED
+		show_overloaded(firstoverloaded);
+#endif
+	      }
+	    }
+	  }
+	}
+      }
+
+      Node *c = 0;
+      for (c = firstChild(n); c; c = nextSibling(c)) {
+	if (Equal(nodeType(c), "cdecl")) {
+	  process_exceptions(c);
+
+	  if (inclass)
+	    class_member_is_defined_in_bases(c, inclass);
+	} else if (Equal(nodeType(c), "constructor")) {
+	  constructorDeclaration(c);
+	}
       }
     }
 
@@ -777,10 +1163,25 @@
       /* Check to see if this is a static member or not.  If so, we add an attribute
          cplus:staticbase that saves the current class */
 
-      if (Swig_storage_isstatic(n)) {
+      int is_static = Swig_storage_isstatic(n);
+      if (is_static) {
 	Setattr(n, "cplus:staticbase", inclass);
       }
 
+      if (Cmp(Getattr(n, "kind"), "variable") == 0) {
+        /* Check member variable to determine whether assignment is valid */
+	bool is_reference;
+	bool is_const;
+	bool assignable = is_assignable(n, is_reference, is_const);
+	if (!assignable || is_const) {
+	  SetFlag(n, "feature:immutable");
+	}
+	if (!is_static) {
+	  if (!assignable || is_reference || is_const)
+	    SetFlag(inclass, "allocate:has_nonassignable"); // The class has a variable that cannot be assigned to
+	}
+      }
+
       String *name = Getattr(n, "name");
       if (cplus_mode != PUBLIC) {
 	if (Strcmp(name, "operator =") == 0) {
@@ -854,6 +1255,24 @@
 	  }
 	}
       }
+    } else {
+      if (Cmp(Getattr(n, "kind"), "variable") == 0) {
+	bool is_reference;
+	bool is_const;
+	bool assignable = is_assignable(n, is_reference, is_const);
+	if (!assignable || is_const) {
+	  SetFlag(n, "feature:immutable");
+	}
+      }
+    }
+    return SWIG_OK;
+  }
+
+  virtual int templateDeclaration(Node *n) {
+    String *ttype = Getattr(n, "templatetype");
+    if (Equal(ttype, "constructor")) {
+      // Templated constructors need to be taken account of even if not instantiated with %template
+      constructorDeclaration(n);
     }
     return SWIG_OK;
   }
@@ -861,34 +1280,43 @@
   virtual int constructorDeclaration(Node *n) {
     if (!inclass)
       return SWIG_OK;
-    Parm *parms = Getattr(n, "parms");
 
+    Parm *parms = Getattr(n, "parms");
+    bool deleted_constructor = (GetFlag(n, "deleted"));
+    bool default_constructor = !ParmList_numrequired(parms);
+    AccessMode access_mode = accessModeFromString(Getattr(n, "access"));
     process_exceptions(n);
-    if (!extendmode) {
-      if (!ParmList_numrequired(parms)) {
-	/* Class does define a default constructor */
-	/* However, we had better see where it is defined */
-	if (cplus_mode == PUBLIC) {
-	  Setattr(inclass, "allocate:default_constructor", "1");
-	} else if (cplus_mode == PROTECTED) {
-	  Setattr(inclass, "allocate:default_base_constructor", "1");
+
+    if (!deleted_constructor) {
+      if (!extendmode) {
+	if (default_constructor) {
+	  /* Class does define a default constructor */
+	  /* However, we had better see where it is defined */
+	  if (access_mode == PUBLIC) {
+	    Setattr(inclass, "allocate:default_constructor", "1");
+	  } else if (access_mode == PROTECTED) {
+	    Setattr(inclass, "allocate:default_base_constructor", "1");
+	  }
 	}
-      }
-      /* Class defines some kind of constructor. May or may not be public */
-      Setattr(inclass, "allocate:has_constructor", "1");
-      if (cplus_mode == PUBLIC) {
+	/* Class defines some kind of constructor. May or may not be public */
+	Setattr(inclass, "allocate:has_constructor", "1");
+	if (access_mode == PUBLIC) {
+	  Setattr(inclass, "allocate:public_constructor", "1");
+	}
+      } else {
+	Setattr(inclass, "allocate:has_constructor", "1");
 	Setattr(inclass, "allocate:public_constructor", "1");
       }
     } else {
-      Setattr(inclass, "allocate:has_constructor", "1");
-      Setattr(inclass, "allocate:public_constructor", "1");
+      if (default_constructor && !extendmode)
+	SetFlag(inclass, "allocate:deleted_default_constructor");
     }
 
-
     /* See if this is a copy constructor */
     if (parms && (ParmList_numrequired(parms) == 1)) {
       /* Look for a few cases. X(const X &), X(X &), X(X *) */
       int copy_constructor = 0;
+      int copy_constructor_non_const = 0;
       SwigType *type = Getattr(inclass, "name");
       String *tn = NewStringf("r.q(const).%s", type);
       String *cc = SwigType_typedef_resolve_all(tn);
@@ -908,6 +1336,7 @@
 	cc = NewStringf("r.%s", Getattr(inclass, "name"));
 	if (Strcmp(cc, Getattr(parms, "type")) == 0) {
 	  copy_constructor = 1;
+	  copy_constructor_non_const = 1;
 	} else {
 	  Delete(cc);
 	  cc = NewStringf("p.%s", Getattr(inclass, "name"));
@@ -923,12 +1352,26 @@
       Delete(tn);
 
       if (copy_constructor) {
-	Setattr(n, "copy_constructor", "1");
-	Setattr(inclass, "allocate:has_copy_constructor", "1");
-	if (cplus_mode == PUBLIC) {
-	  Setattr(inclass, "allocate:copy_constructor", "1");
-	} else if (cplus_mode == PROTECTED) {
-	  Setattr(inclass, "allocate:copy_base_constructor", "1");
+	if (!deleted_constructor) {
+	  Setattr(n, "copy_constructor", "1");
+	  Setattr(inclass, "allocate:has_copy_constructor", "1");
+	  if (access_mode == PUBLIC) {
+	    Setattr(inclass, "allocate:copy_constructor", "1");
+	  } else if (access_mode == PROTECTED) {
+	    Setattr(inclass, "allocate:copy_base_constructor", "1");
+	  }
+	  if (copy_constructor_non_const) {
+	    Setattr(n, "copy_constructor_non_const", "1");
+	    Setattr(inclass, "allocate:has_copy_constructor_non_const", "1");
+	    if (access_mode == PUBLIC) {
+	      Setattr(inclass, "allocate:copy_constructor_non_const", "1");
+	    } else if (access_mode == PROTECTED) {
+	      Setattr(inclass, "allocate:copy_base_constructor_non_const", "1");
+	    }
+	  }
+	} else {
+	  if (!extendmode)
+	    SetFlag(inclass, "allocate:deleted_copy_constructor");
 	}
       }
     }
@@ -939,21 +1382,199 @@
     (void) n;
     if (!inclass)
       return SWIG_OK;
-    if (!extendmode) {
-      Setattr(inclass, "allocate:has_destructor", "1");
-      if (cplus_mode == PUBLIC) {
+
+    if (!GetFlag(n, "deleted")) {
+      if (!extendmode) {
+	Setattr(inclass, "allocate:has_destructor", "1");
+	if (cplus_mode == PUBLIC) {
+	  Setattr(inclass, "allocate:default_destructor", "1");
+	} else if (cplus_mode == PROTECTED) {
+	  Setattr(inclass, "allocate:default_base_destructor", "1");
+	} else if (cplus_mode == PRIVATE) {
+	  Setattr(inclass, "allocate:private_destructor", "1");
+	}
+      } else {
+	Setattr(inclass, "allocate:has_destructor", "1");
 	Setattr(inclass, "allocate:default_destructor", "1");
-      } else if (cplus_mode == PROTECTED) {
-	Setattr(inclass, "allocate:default_base_destructor", "1");
-      } else if (cplus_mode == PRIVATE) {
-	Setattr(inclass, "allocate:private_destructor", "1");
       }
     } else {
-      Setattr(inclass, "allocate:has_destructor", "1");
-      Setattr(inclass, "allocate:default_destructor", "1");
+      if (!extendmode)
+	SetFlag(inclass, "allocate:deleted_default_destructor");
     }
+
     return SWIG_OK;
   }
+
+static void addCopyConstructor(Node *n) {
+  Node *cn = NewHash();
+  set_nodeType(cn, "constructor");
+  Setattr(cn, "access", "public");
+  Setfile(cn, Getfile(n));
+  Setline(cn, Getline(n));
+
+  int copy_constructor_non_const = GetFlag(n, "allocate:copy_constructor_non_const");
+  String *cname = Getattr(n, "name");
+  SwigType *type = Copy(cname);
+  String *lastname = Swig_scopename_last(cname);
+  String *name = SwigType_templateprefix(lastname);
+  String *cc = NewStringf(copy_constructor_non_const ? "r.%s" : "r.q(const).%s", type);
+  String *decl = NewStringf("f(%s).", cc);
+  String *oldname = Getattr(n, "sym:name");
+
+  if (Getattr(n, "allocate:has_constructor")) {
+    // to work properly with '%rename Class', we must look
+    // for any other constructor in the class, which has not been
+    // renamed, and use its name as oldname.
+    Node *c;
+    for (c = firstChild(n); c; c = nextSibling(c)) {
+      if (Equal(nodeType(c), "constructor")) {
+	String *csname = Getattr(c, "sym:name");
+	String *clast = Swig_scopename_last(Getattr(c, "name"));
+	if (Equal(csname, clast)) {
+	  oldname = csname;
+	  Delete(clast);
+	  break;
+	}
+	Delete(clast);
+      }
+    }
+  }
+
+  String *symname = Swig_name_make(cn, cname, name, decl, oldname);
+  if (Strcmp(symname, "$ignore") != 0) {
+    Parm *p = NewParm(cc, "other", n);
+
+    Setattr(cn, "name", name);
+    Setattr(cn, "sym:name", symname);
+    SetFlag(cn, "feature:new");
+    Setattr(cn, "decl", decl);
+    Setattr(cn, "ismember", "1");
+    Setattr(cn, "parentNode", n);
+    Setattr(cn, "parms", p);
+    Setattr(cn, "copy_constructor", "1");
+
+    Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
+    Node *on = Swig_symbol_add(symname, cn);
+    Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn);
+    Swig_symbol_setscope(oldscope);
+
+    if (on == cn) {
+      Node *access = NewHash();
+      set_nodeType(access, "access");
+      Setattr(access, "kind", "public");
+      appendChild(n, access);
+      appendChild(n, cn);
+      Setattr(n, "has_copy_constructor", "1");
+      Setattr(n, "copy_constructor_decl", decl);
+      Setattr(n, "allocate:copy_constructor", "1");
+      Delete(access);
+    }
+  }
+  Delete(cn);
+  Delete(lastname);
+  Delete(name);
+  Delete(decl);
+  Delete(symname);
+}
+
+static void addDefaultConstructor(Node *n) {
+  Node *cn = NewHash();
+  set_nodeType(cn, "constructor");
+  Setattr(cn, "access", "public");
+  Setfile(cn, Getfile(n));
+  Setline(cn, Getline(n));
+
+  String *cname = Getattr(n, "name");
+  String *lastname = Swig_scopename_last(cname);
+  String *name = SwigType_templateprefix(lastname);
+  String *decl = NewString("f().");
+  String *oldname = Getattr(n, "sym:name");
+  String *symname = Swig_name_make(cn, cname, name, decl, oldname);
+
+  if (Strcmp(symname, "$ignore") != 0) {
+    Setattr(cn, "name", name);
+    Setattr(cn, "sym:name", symname);
+    SetFlag(cn, "feature:new");
+    Setattr(cn, "decl", decl);
+    Setattr(cn, "ismember", "1");
+    Setattr(cn, "parentNode", n);
+    Setattr(cn, "default_constructor", "1");
+
+    Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
+    Node *on = Swig_symbol_add(symname, cn);
+    Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn);
+    Swig_symbol_setscope(oldscope);
+
+    if (on == cn) {
+      Node *access = NewHash();
+      set_nodeType(access, "access");
+      Setattr(access, "kind", "public");
+      appendChild(n, access);
+      appendChild(n, cn);
+      Setattr(n, "has_default_constructor", "1");
+      Setattr(n, "allocate:default_constructor", "1");
+      Delete(access);
+    }
+  }
+  Delete(cn);
+  Delete(lastname);
+  Delete(name);
+  Delete(decl);
+  Delete(symname);
+}
+
+static void addDestructor(Node *n) {
+  Node *cn = NewHash();
+  set_nodeType(cn, "destructor");
+  Setattr(cn, "access", "public");
+  Setfile(cn, Getfile(n));
+  Setline(cn, Getline(n));
+
+  String *cname = Getattr(n, "name");
+  String *lastname = Swig_scopename_last(cname);
+  String *name = SwigType_templateprefix(lastname);
+  Insert(name, 0, "~");
+  String *decl = NewString("f().");
+  String *symname = Swig_name_make(cn, cname, name, decl, 0);
+  if (Strcmp(symname, "$ignore") != 0) {
+    String *possible_nonstandard_symname = NewStringf("~%s", Getattr(n, "sym:name"));
+
+    Setattr(cn, "name", name);
+    Setattr(cn, "sym:name", symname);
+    Setattr(cn, "decl", "f().");
+    Setattr(cn, "ismember", "1");
+    Setattr(cn, "parentNode", n);
+
+    Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
+    Node *nonstandard_destructor = Equal(possible_nonstandard_symname, symname) ? 0 : Swig_symbol_clookup(possible_nonstandard_symname, 0);
+    Node *on = Swig_symbol_add(symname, cn);
+    Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn);
+    Swig_symbol_setscope(oldscope);
+
+    if (on == cn) {
+      // SWIG accepts a non-standard named destructor in %extend that uses a typedef for the destructor name
+      // For example: typedef struct X {} XX; %extend X { ~XX() {...} }
+      // Don't add another destructor if a nonstandard one has been declared
+      if (!nonstandard_destructor) {
+	Node *access = NewHash();
+	set_nodeType(access, "access");
+	Setattr(access, "kind", "public");
+	appendChild(n, access);
+	appendChild(n, cn);
+	Setattr(n, "has_destructor", "1");
+	Setattr(n, "allocate:has_destructor", "1");
+	Delete(access);
+      }
+    }
+    Delete(possible_nonstandard_symname);
+  }
+  Delete(cn);
+  Delete(lastname);
+  Delete(name);
+  Delete(decl);
+  Delete(symname);
+}
+
 };
 
 void Swig_default_allocators(Node *n) {
diff --git a/Source/Modules/browser.cxx b/Source/Modules/browser.cxx
deleted file mode 100644
index 217b40a..0000000
--- a/Source/Modules/browser.cxx
+++ /dev/null
@@ -1,421 +0,0 @@
-/* ----------------------------------------------------------------------------- 
- * This file is part of SWIG, which is licensed as a whole under version 3 
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
- *
- * browser.cxx
- *
- * A web-base parse tree browser using SWILL.   This is an optional
- * feature that's normally disabled.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-
-#ifdef SWIG_SWILL
-extern "C" {
-#include "swill.h"
-} static FILE *out = 0;
-static Node *view_top = 0;
-
-class Browser:public Dispatcher {
-  void show_checkbox(Node *t, Node *n) {
-    int v = 0;
-    if (Getmeta(n, "visible")) {
-      v = 1;
-    }
-    if (v) {
-      Printf(out, "<a name=\"n%p\"></a>[<a href=\"hide.html?node=%p&hn=%p#n%p\">-</a>] ", n, t, n, n);
-    } else {
-      Printf(out, "<a name=\"n%p\"></a>[<a href=\"show.html?node=%p&hn=%p#n%p\">+</a>] ", n, t, n, n);
-    }
-  }
-  void show_attributes(Node *obj) {
-    if (!Getmeta(obj, "visible"))
-      return;
-    String *os = NewString("");
-    String *k;
-    Iterator ki;
-    ki = First(obj);
-    while (ki.key) {
-      k = ki.key;
-      if ((Cmp(k, "nodeType") == 0) || (Cmp(k, "firstChild") == 0) || (Cmp(k, "lastChild") == 0) ||
-	  (Cmp(k, "parentNode") == 0) || (Cmp(k, "nextSibling") == 0) || (Cmp(k, "previousSibling") == 0) || (*(Char(k)) == '$')) {
-	/* Do nothing */
-      } else if (Cmp(k, "parms") == 0) {
-	String *o = NewString("");
-	Printf(o, "%s", ParmList_protostr(Getattr(obj, k)));
-	Replaceall(o, "&", "&amp;");
-	Replaceall(o, "<", "&lt;");
-	Replaceall(o, ">", "&gt;");
-	Printf(os, "<a href=\"data.html?n=%p\">?</a> %-12s - %s\n", Getattr(obj, k), k, o);
-	Delete(o);
-      } else {
-	DOH *o;
-	char *trunc = "";
-	if (DohIsString(Getattr(obj, k))) {
-	  o = Str(Getattr(obj, k));
-	  if (Len(o) > 70) {
-	    trunc = "...";
-	  }
-	  Replaceall(o, "&", "&amp;");
-	  Replaceall(o, "<", "&lt;");
-	  Printf(os, "<a href=\"data.html?n=%p\">?</a> %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj, k), k, o, trunc);
-	  Delete(o);
-	} else {
-	  Printf(os, "<a href=\"data.html?n=%p\">?</a> %-12s - %p\n", Getattr(obj, k), k, Getattr(obj, k));
-	}
-      }
-      ki = Next(ki);
-    }
-    Printf(out, "<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(os));
-    Delete(os);
-  }
-
-public:
-  virtual int emit_one(Node *n) {
-    char *tag = Char(nodeType(n));
-    char *file = Char(Getfile(n));
-    int line = Getline(n);
-    char *name = GetChar(n, "name");
-
-    show_checkbox(view_top, n);
-    Printf(out, "<b><a href=\"index.html?node=%p\">%s</a></b>", n, tag);
-    if (name) {
-      Printf(out, " (%s)", name);
-    }
-    Printf(out, ".  %s:%d\n", file, line);
-    Printf(out, "<br>");
-    Dispatcher::emit_one(n);
-    return SWIG_OK;
-  }
-  virtual int emit_children(Node *n) {
-    if (Getmeta(n, "visible")) {
-      Printf(out, "<blockquote>\n");
-      Dispatcher::emit_children(n);
-      Printf(out, "</blockquote>\n");
-    }
-    return SWIG_OK;
-  }
-  virtual int defaultHandler(Node *n) {
-    show_attributes(n);
-    return SWIG_OK;
-  }
-  virtual int top(Node *n) {
-    show_attributes(n);
-    emit_children(n);
-    return SWIG_OK;
-  }
-  virtual int includeDirective(Node *n) {
-    show_attributes(n);
-    emit_children(n);
-    return SWIG_OK;
-  }
-  virtual int importDirective(Node *n) {
-    show_attributes(n);
-    emit_children(n);
-    return SWIG_OK;
-  }
-
-  virtual int extendDirective(Node *n) {
-    show_attributes(n);
-    emit_children(n);
-    return SWIG_OK;
-  }
-  virtual int classDeclaration(Node *n) {
-    show_attributes(n);
-    emit_children(n);
-    return SWIG_OK;
-  }
-
-  virtual int templateDeclaration(Node *n) {
-    show_attributes(n);
-    emit_children(n);
-    return SWIG_OK;
-  }
-
-  virtual int lambdaDeclaration(Node *n) {
-    show_attributes(n);
-    emit_children(n);
-    return SWIG_OK;
-  }
-
-  virtual int enumDeclaration(Node *n) {
-    show_attributes(n);
-    emit_children(n);
-    return SWIG_OK;
-  }
-  virtual int typemapDirective(Node *n) {
-    show_attributes(n);
-    emit_children(n);
-    return SWIG_OK;
-  }
-  virtual int namespaceDeclaration(Node *n) {
-    show_attributes(n);
-    emit_children(n);
-    return SWIG_OK;
-  }
-  virtual int usingDeclaration(Node *n) {
-    show_attributes(n);
-    emit_children(n);
-    return SWIG_OK;
-  }
-
-};
-
-static int browser_exit = 0;
-static Node *tree_top = 0;
-static Browser *browse = 0;
-
-/* ----------------------------------------------------------------------
- * exit_handler()      - Force the browser to exit
- * ---------------------------------------------------------------------- */
-
-void exit_handler(FILE *f) {
-  browser_exit = 1;
-  Printf(f, "Terminated.\n");
-}
-
-/* ----------------------------------------------------------------------
- * node_handler()      - Generate information about a specific node
- * ---------------------------------------------------------------------- */
-
-static void display(FILE *f, Node *n) {
-  /* Print standard HTML header */
-
-  Printf(f, "<HTML><HEAD><TITLE>SWIG-%s</TITLE></HEAD><BODY BGCOLOR=\"#ffffff\">\n", Swig_package_version());
-  Printf(f, "<b>SWIG-%s</b><br>\n", Swig_package_version());
-  Printf(f, "[ <a href=\"exit.html\">Exit</a> ]");
-  Printf(f, " [ <a href=\"index.html?node=%p\">Top</a> ]", tree_top);
-  if (n != tree_top) {
-    Printf(f, " [ <a href=\"index.html?node=%p\">Up</a> ]", parentNode(n));
-  }
-  Printf(f, " [ <a href=\"symbol.html\">Symbols</a> ]");
-  Printf(f, "<br><hr><p>\n");
-
-  out = f;
-
-  browse->emit_one(n);
-
-  /* Print standard footer */
-  Printf(f, "<br><hr></BODY></HTML>\n");
-
-}
-
-void node_handler(FILE *f) {
-  Node *n = 0;
-  if (!swill_getargs("p(node)", &n)) {
-    n = tree_top;
-  }
-  view_top = n;
-  display(f, n);
-}
-
-
-/* ----------------------------------------------------------------------
- * hide_handler()      - Hide a node 
- * ---------------------------------------------------------------------- */
-
-void hide_handler(FILE *f) {
-  Node *n = 0;
-  if (!swill_getargs("p(hn)", &n)) {
-    n = 0;
-  }
-  if (n) {
-    Delmeta(n, "visible");
-  }
-  node_handler(f);
-}
-
-void show_handler(FILE *f) {
-  Node *n = 0;
-  if (!swill_getargs("p(hn)", &n)) {
-    n = 0;
-  }
-  if (n) {
-    Setmeta(n, "visible", "1");
-  }
-  node_handler(f);
-}
-
-void raw_data(FILE *out, Node *obj) {
-  if (!obj)
-    return;
-  if (DohIsMapping(obj)) {
-    String *k;
-    Iterator ki;
-    String *os = NewString("");
-    Printf(os, "Hash {\n");
-    ki = First(obj);
-    while (ki.key) {
-      k = ki.key;
-      DOH *o;
-      const char *trunc = "";
-      if (DohIsString(Getattr(obj, k))) {
-	o = Str(Getattr(obj, k));
-	if (Len(o) > 70) {
-	  trunc = "...";
-	}
-	Replaceall(o, "<", "&lt;");
-	Printf(os, "    <a href=\"data.html?n=%p\">?</a> %-12s - \"%(escape)-0.70s%s\"\n", Getattr(obj, k), k, o, trunc);
-	Delete(o);
-      } else {
-	Printf(os, "    <a href=\"data.html?n=%p\">?</a> %-12s - %p\n", Getattr(obj, k), k, Getattr(obj, k));
-      }
-      ki = Next(ki);
-    }
-    Printf(os, "}\n");
-    Printf(out, "<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(os));
-    Delete(os);
-  } else if (DohIsString(obj)) {
-    String *o = Str(obj);
-    Replaceall(o, "<", "&lt;");
-    Printf(out, "<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(o));
-    Delete(o);
-  } else if (DohIsSequence(obj)) {
-    int i;
-    String *os = NewString("");
-    Printf(os, "List [\n");
-    for (i = 0; i < Len(obj); i++) {
-      DOH *o = Getitem(obj, i);
-      const char *trunc = "";
-      if (DohIsString(o)) {
-	String *s = Str(o);
-	if (Len(s) > 70) {
-	  trunc = "...";
-	}
-	Replaceall(o, "<", "&lt;");
-	Printf(os, "    <a href=\"data.html?n=%p\">?</a> [%d] - \"%(escape)-0.70s%s\"\n", o, i, s, trunc);
-	Delete(s);
-      } else {
-	Printf(os, "    <a href=\"data.html?n=%p\">?</a> [%d] - %p\n", o, i, o);
-      }
-    }
-    Printf(os, "\n]\n");
-    Printf(out, "<FONT color=\"#660000\"><pre>\n%s</pre></FONT>\n", Char(os));
-    Delete(os);
-  }
-}
-
-void data_handler(FILE *f) {
-  DOH *n = 0;
-  if (!swill_getargs("p(n)", &n)) {
-    n = 0;
-  }
-  Printf(f, "<HTML><HEAD><TITLE>SWIG-%s</TITLE></HEAD><BODY BGCOLOR=\"#ffffff\">\n", Swig_package_version());
-  Printf(f, "<b>SWIG-%s</b><br>\n", Swig_package_version());
-  Printf(f, "[ <a href=\"exit.html\">Exit</a> ]");
-  Printf(f, " [ <a href=\"index.html?node=%p\">Top</a> ]", tree_top);
-  Printf(f, "<br><hr><p>\n");
-  if (n) {
-    raw_data(f, n);
-  }
-  /* Print standard footer */
-  Printf(f, "<br><hr></BODY></HTML>\n");
-}
-
-void symbol_handler(FILE *f) {
-  Symtab *sym;
-  char *name = 0;
-
-  Printf(f, "<HTML><HEAD><TITLE>SWIG-%s</TITLE></HEAD><BODY BGCOLOR=\"#ffffff\">\n", Swig_package_version());
-  Printf(f, "<b>SWIG-%s</b><br>\n", Swig_package_version());
-  Printf(f, "[ <a href=\"exit.html\">Exit</a> ]");
-  Printf(f, " [ <a href=\"index.html?node=%p\">Top</a> ]", tree_top);
-  Printf(f, " [ <a href=\"symbol.html\">Symbols</a> ]");
-  Printf(f, "<br><hr><p>\n");
-
-  if (!swill_getargs("p(sym)|s(name)", &sym, &name)) {
-    sym = Swig_symbol_getscope("");
-    name = 0;
-  }
-  if (!sym) {
-    Printf(f, "No symbol table specified!\n");
-    return;
-  }
-  {
-    String *q = Swig_symbol_qualifiedscopename(sym);
-    if (!Len(q)) {
-      Printf(f, "<b>Symbol table: :: (global)</b><br>\n");
-    } else {
-      Printf(f, "<b>Symbol table: %s</b><br>\n", q);
-    }
-    Delete(q);
-  }
-
-  fprintf(f, "<p><form action=\"symbol.html\" method=GET>\n");
-  fprintf(f, "Symbol lookup: <input type=text name=name size=40></input><br>\n");
-  fprintf(f, "<input type=hidden name=sym value=\"%p\">\n", sym);
-  fprintf(f, "Submit : <input type=submit></input>\n");
-  fprintf(f, "</form>");
-
-  if (name) {
-    Node *n = Swig_symbol_clookup(name, sym);
-    Printf(f, "Symbol '%s':\n", name);
-    Printf(f, "<blockquote>\n");
-    if (!n) {
-      Printf(f, "Not defined!\n");
-    } else {
-      raw_data(f, n);
-    }
-    Printf(f, "</blockquote>\n");
-  }
-
-  Printf(f, "<p><b>Nested scopes</b><br>\n");
-  Printf(f, "<blockquote><pre>\n");
-  {
-    Hash *h;
-    h = firstChild(sym);
-    while (h) {
-      Printf(f, "<a href=\"symbol.html?sym=%p\">%s</a>\n", h, Getattr(h, "name"));
-      h = nextSibling(h);
-    }
-  }
-  Printf(f, "</pre></blockquote>\n");
-
-  Printf(f, "<p><b>Symbol table contents</b></br>\n");
-  raw_data(f, Getattr(sym, "symtab"));
-  Printf(f, "<br><hr></BODY></HTML>\n");
-
-}
-#endif
-
-void Swig_browser(Node *top, int port) {
-#ifdef SWIG_SWILL
-  int sport;
-  browser_exit = 0;
-
-  /* Initialize the server */
-  sport = swill_init(port);
-  if (sport < 0) {
-    Printf(stderr, "Couldn't open socket on port %d. Sorry.\n", port);
-    return;
-  }
-  browse = new Browser();
-  Setmeta(top, "visible", "1");
-  tree_top = top;
-
-  Printf(stderr, "SWIG: Tree browser listening on port %d\n", sport);
-
-  swill_handle("exit.html", exit_handler, 0);
-  swill_handle("index.html", node_handler, 0);
-  swill_handle("hide.html", hide_handler, 0);
-  swill_handle("show.html", show_handler, 0);
-  swill_handle("data.html", data_handler, 0);
-  swill_handle("symbol.html", symbol_handler, 0);
-  swill_netscape("index.html");
-
-  while (!browser_exit) {
-    swill_serve();
-  }
-  Printf(stderr, "Browser terminated.\n");
-  swill_close();
-  delete browse;
-  return;
-#else
-  (void) top;
-  (void) port;
-#endif
-}
diff --git a/Source/Modules/cffi.cxx b/Source/Modules/cffi.cxx
deleted file mode 100644
index bf33388..0000000
--- a/Source/Modules/cffi.cxx
+++ /dev/null
@@ -1,1186 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3 
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
- *
- * cffi.cxx
- *
- * cffi language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "cparse.h"
-#include <ctype.h>
-
-//#define CFFI_DEBUG
-//#define CFFI_WRAP_DEBUG
-
-static const char *usage = "\
-CFFI Options (available with -cffi)\n\
-     -generate-typedef - Use defctype to generate shortcuts according to the\n\
-                         typedefs in the input.\n\
-     -[no]cwrap        - Turn on or turn off generation of an intermediate C\n\
-                         file when creating a C interface. By default this is\n\
-                         only done for C++ code.\n\
-     -[no]swig-lisp    - Turn on or off generation of code for helper lisp\n\
-                         macro, functions, etc. which SWIG uses while\n\
-                         generating wrappers. These macros, functions may still\n\
-                         be used by generated wrapper code.\n\
-";
-
-class CFFI:public Language {
-public:
-  String *f_cl;
-  String *f_clhead;
-  String *f_clwrap;
-  bool CWrap;     // generate wrapper file for C code?  
-  File *f_begin;
-  File *f_runtime;
-  File *f_cxx_header;
-  File *f_cxx_wrapper;
-  File *f_clos;
-
-  String *module;
-  virtual void main(int argc, char *argv[]);
-  virtual int top(Node *n);
-  virtual int functionWrapper(Node *n);
-  virtual int variableWrapper(Node *n);
-  virtual int constantWrapper(Node *n);
-  //  virtual int classDeclaration(Node *n);
-  virtual int enumDeclaration(Node *n);
-  virtual int typedefHandler(Node *n);
-
-  //c++ specific code
-  virtual int constructorHandler(Node *n);
-  virtual int destructorHandler(Node *n);
-  virtual int memberfunctionHandler(Node *n);
-  virtual int membervariableHandler(Node *n);
-  virtual int classHandler(Node *n);
-
-private:
-  static void checkConstraints(ParmList *parms, Wrapper *f);
-  static void argout(ParmList *parms, Wrapper *f);
-  static String *freearg(ParmList *parms);
-  static void cleanupFunction(Node *n, Wrapper *f, ParmList *parms);
-
-  void emit_defun(Node *n, String *name);
-  void emit_defmethod(Node *n);
-  void emit_initialize_instance(Node *n);
-  void emit_getter(Node *n);
-  void emit_setter(Node *n);
-  void emit_class(Node *n);
-  void emit_struct_union(Node *n, bool un);
-  void emit_export(Node *n, String *name);
-  void emit_inline(Node *n, String *name);
-  String *lispy_name(char *name);
-  String *lispify_name(Node *n, String *ty, const char *flag, bool kw = false);
-  String *convert_literal(String *num_param, String *type, bool try_to_split = true);
-  String *infix_to_prefix(String *val, char split_op, const String *op, String *type);
-  String *strip_parens(String *string);
-  String *trim(String *string);
-  int generate_typedef_flag;
-  bool no_swig_lisp;
-};
-
-void CFFI::main(int argc, char *argv[]) {
-  int i;
-
-  Preprocessor_define("SWIGCFFI 1", 0);
-  SWIG_library_directory("cffi");
-  SWIG_config_file("cffi.swg");
-  generate_typedef_flag = 0;
-  no_swig_lisp = false;
-  CWrap = false;
-  for (i = 1; i < argc; i++) {
-    if (!Strcmp(argv[i], "-help")) {
-      Printf(stdout, "%s\n", usage);
-    } else if (!strcmp(argv[i], "-cwrap")) {
-      CWrap = true;
-      Swig_mark_arg(i);
-    } else if ((Strcmp(argv[i], "-generate-typedef") == 0)) {
-      generate_typedef_flag = 1;
-      Swig_mark_arg(i);
-    } else if (!strcmp(argv[i], "-nocwrap")) {
-      CWrap = false;
-      Swig_mark_arg(i);
-    } else if (!strcmp(argv[i], "-swig-lisp")) {
-      no_swig_lisp = false;
-      Swig_mark_arg(i);
-    } else if (!strcmp(argv[i], "-noswig-lisp")) {
-      no_swig_lisp = true;
-      Swig_mark_arg(i);
-    }
-
-  }
-  f_clhead = NewString("");
-  f_clwrap = NewString("");
-  f_cl = NewString("");
-
-  allow_overloading();
-}
-
-int CFFI::top(Node *n) {
-  File *f_null = NewString("");
-  module = Getattr(n, "name");
-
-  String *cxx_filename = Getattr(n, "outfile");
-  String *lisp_filename = NewString("");
-
-  Printf(lisp_filename, "%s%s.lisp", SWIG_output_directory(), module);
-
-  File *f_lisp = NewFile(lisp_filename, "w", SWIG_output_files());
-  if (!f_lisp) {
-    FileErrorDisplay(lisp_filename);
-    SWIG_exit(EXIT_FAILURE);
-  }
-
-  if (CPlusPlus || CWrap) {
-    f_begin = NewFile(cxx_filename, "w", SWIG_output_files());
-    if (!f_begin) {
-      Delete(f_lisp);
-      Printf(stderr, "Unable to open %s for writing\n", cxx_filename);
-      SWIG_exit(EXIT_FAILURE);
-    }
-
-    String *clos_filename = NewString("");
-    Printf(clos_filename, "%s%s-clos.lisp", SWIG_output_directory(), module);
-    f_clos = NewFile(clos_filename, "w", SWIG_output_files());
-    if (!f_clos) {
-      Delete(f_lisp);
-      Printf(stderr, "Unable to open %s for writing\n", cxx_filename);
-      SWIG_exit(EXIT_FAILURE);
-    }
-  } else {
-    f_begin = NewString("");
-    f_clos = NewString("");
-  }
-
-  f_runtime = NewString("");
-  f_cxx_header = f_runtime;
-  f_cxx_wrapper = NewString("");
-
-  Swig_register_filebyname("header", f_cxx_header);
-  Swig_register_filebyname("wrapper", f_cxx_wrapper);
-  Swig_register_filebyname("begin", f_begin);
-  Swig_register_filebyname("runtime", f_runtime);
-  Swig_register_filebyname("lisphead", f_clhead);
-  if (!no_swig_lisp)
-    Swig_register_filebyname("swiglisp", f_cl);
-  else
-    Swig_register_filebyname("swiglisp", f_null);
-
-  Swig_banner(f_begin);
-
-  Printf(f_runtime, "\n\n#ifndef SWIGCFFI\n#define SWIGCFFI\n#endif\n\n");
-
-  Swig_banner_target_lang(f_lisp, ";;;");
-
-  Language::top(n);
-  Printf(f_lisp, "%s\n", f_clhead);
-  Printf(f_lisp, "%s\n", f_cl);
-  Printf(f_lisp, "%s\n", f_clwrap);
-
-  Delete(f_lisp);
-  Delete(f_cl);
-  Delete(f_clhead);
-  Delete(f_clwrap);
-  Dump(f_runtime, f_begin);
-  Delete(f_runtime);
-  Delete(f_begin);
-  Delete(f_cxx_wrapper);
-  Delete(f_null);
-
-  return SWIG_OK;
-}
-
-int CFFI::classHandler(Node *n) {
-#ifdef CFFI_DEBUG
-  Printf(stderr, "class %s::%s\n", "some namespace",  //current_namespace,
-   Getattr(n, "sym:name"));
-#endif
-  String *name = Getattr(n, "sym:name");
-  String *kind = Getattr(n, "kind");
-
-  // maybe just remove this check and get rid of the else clause below.
-  if (Strcmp(kind, "struct") == 0) {
-    emit_struct_union(n, false);
-    return SWIG_OK;
-  } else if (Strcmp(kind, "union") == 0) {
-    emit_struct_union(n, true);
-    return SWIG_OK;
-  } else if (Strcmp(kind, "class") == 0) {
-    emit_class(n);
-    Language::classHandler(n);
-  } else {
-    Printf(stderr, "Don't know how to deal with %s kind of class yet.\n", kind);
-    Printf(stderr, " (name: %s)\n", name);
-    SWIG_exit(EXIT_FAILURE);
-    return SWIG_OK;
-  }
-
-  return SWIG_OK;
-}
-
-int CFFI::constructorHandler(Node *n) {
-#ifdef CFFI_DEBUG
-  Printf(stderr, "constructor %s\n", Getattr(n, "name"));
-  Printf(stderr, "constructor %s\n and %s and %s", Getattr(n, "kind"), Getattr(n, "sym:name"), Getattr(n, "allegrocl:old-sym:name"));
-#endif
-  Setattr(n, "cffi:constructorfunction", "1");
-  // Let SWIG generate a global forwarding function.
-  return Language::constructorHandler(n);
-}
-
-int CFFI::destructorHandler(Node *n) {
-#ifdef CFFI_DEBUG
-  Printf(stderr, "destructor %s\n", Getattr(n, "name"));
-#endif
-
-  // Let SWIG generate a global forwarding function.
-  return Language::destructorHandler(n);
-}
-
-void CFFI::emit_defmethod(Node *n) {
-  String *args_placeholder = NewStringf("");
-  String *args_call = NewStringf("");
-
-  ParmList *pl = Getattr(n, "parms");
-  int argnum = 0;
-  Node *parent = getCurrentClass();
-  bool first = 0;
-  
-  for (Parm *p = pl; p; p = nextSibling(p), argnum++) {
-    String *argname = Getattr(p, "name");
-    String *ffitype = Swig_typemap_lookup("lispclass", p, "", 0);
-
-    int tempargname = 0;
-
-    if(!first)
-      first = true;
-    else
-      Printf(args_placeholder, " ");
-      
-    if (!argname) {
-      argname = NewStringf("arg%d", argnum);
-      tempargname = 1;
-    } else if (Strcmp(argname, "t") == 0 || Strcmp(argname, "T") == 0) {
-      argname = NewStringf("t-arg%d", argnum);
-      tempargname = 1;
-    }
-    if (Len(ffitype) > 0)
-      Printf(args_placeholder, "(%s %s)", argname, ffitype);
-    else
-      Printf(args_placeholder, "%s", argname);
-
-    if (ffitype && Strcmp(ffitype, lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'classname")) == 0)
-      Printf(args_call, " (ff-pointer %s)", argname);
-    else
-      Printf(args_call, " %s", argname);
-
-    Delete(ffitype);
-
-    if (tempargname)
-      Delete(argname);
-  }
-
-  String *method_name = Getattr(n, "name");
-  int x = Replace(method_name, "operator ", "", DOH_REPLACE_FIRST); //  
-
-  if (x == 1)
-    Printf(f_clos, "(cl:shadow \"%s\")\n", method_name);
-
-  Printf(f_clos, "(cl:defmethod %s (%s)\n  (%s%s))\n\n",
-         lispify_name(n, lispy_name(Char(method_name)), "'method"), args_placeholder,
-         lispify_name(n, Getattr(n, "sym:name"), "'function"), args_call);
-
-}
-
-void CFFI::emit_initialize_instance(Node *n) {
-  String *args_placeholder = NewStringf("");
-  String *args_call = NewStringf("");
-
-  ParmList *pl = Getattr(n, "parms");
-  int argnum = 0;
-  Node *parent = getCurrentClass();
-
-  for (Parm *p = pl; p; p = nextSibling(p), argnum++) {
-    String *argname = Getattr(p, "name");
-    String *ffitype = Swig_typemap_lookup("lispclass", p, "", 0);
-
-    int tempargname = 0;
-    if (!argname) {
-      argname = NewStringf("arg%d", argnum);
-      tempargname = 1;
-    } else if (Strcmp(argname, "t") == 0 || Strcmp(argname, "T") == 0) {
-      argname = NewStringf("t-arg%d", argnum);
-      tempargname = 1;
-    }
-    if (Len(ffitype) > 0)
-      Printf(args_placeholder, " (%s %s)", argname, ffitype);
-    else
-      Printf(args_placeholder, " %s", argname);
-
-    if (ffitype && Strcmp(ffitype, lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'classname")) == 0)
-      Printf(args_call, " (ff-pointer %s)", argname);
-    else
-      Printf(args_call, " %s", argname);
-
-    Delete(ffitype);
-
-    if (tempargname)
-      Delete(argname);
-  }
-
-  Printf(f_clos, "(cl:defmethod initialize-instance :after ((obj %s) &key%s)\n  (setf (slot-value obj 'ff-pointer) (%s%s)))\n\n",
-         lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'class"), args_placeholder,
-         lispify_name(n, Getattr(n, "sym:name"), "'function"), args_call);
-
-}
-
-void CFFI::emit_setter(Node *n) {
-  Node *parent = getCurrentClass();
-  Printf(f_clos, "(cl:defmethod (cl:setf %s) (arg0 (obj %s))\n  (%s (ff-pointer obj) arg0))\n\n",
-         lispify_name(n, Getattr(n, "name"), "'method"),
-         lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'class"), lispify_name(n, Getattr(n, "sym:name"), "'function"));
-}
-
-
-void CFFI::emit_getter(Node *n) {
-  Node *parent = getCurrentClass();
-  Printf(f_clos, "(cl:defmethod %s ((obj %s))\n  (%s (ff-pointer obj)))\n\n",
-         lispify_name(n, Getattr(n, "name"), "'method"),
-         lispify_name(parent, lispy_name(Char(Getattr(parent, "sym:name"))), "'class"), lispify_name(n, Getattr(n, "sym:name"), "'function"));
-}
-
-int CFFI::memberfunctionHandler(Node *n) {
-  // Let SWIG generate a global forwarding function.
-  Setattr(n, "cffi:memberfunction", "1");
-  return Language::memberfunctionHandler(n);
-}
-
-int CFFI::membervariableHandler(Node *n) {
-  // Let SWIG generate a get/set function pair.
-  Setattr(n, "cffi:membervariable", "1");
-  return Language::membervariableHandler(n);
-}
-
-
-void CFFI::checkConstraints(ParmList *parms, Wrapper *f) {
-  Parm *p = parms;
-  while (p) {
-    String *tm = Getattr(p, "tmap:check");
-    if (!tm) {
-      p = nextSibling(p);
-    } else {
-      tm = Copy(tm);
-      Replaceall(tm, "$input", Getattr(p, "emit:input"));
-      Printv(f->code, tm, "\n\n", NULL);
-      Delete(tm);
-      p = Getattr(p, "tmap:check:next");
-    }
-  }
-}
-
-void CFFI::argout(ParmList *parms, Wrapper *f) {
-  Parm *p = parms;
-  while (p) {
-    String *tm = Getattr(p, "tmap:argout");
-    if (!tm) {
-      p = nextSibling(p);
-    } else {
-      tm = Copy(tm);
-      Replaceall(tm, "$result", Swig_cresult_name());
-      Replaceall(tm, "$input", Getattr(p, "emit:input"));
-      Printv(f->code, tm, "\n", NULL);
-      Delete(tm);
-      p = Getattr(p, "tmap:argout:next");
-    }
-  }
-}
-
-String *CFFI::freearg(ParmList *parms) {
-  String *ret = NewString("");
-  Parm *p = parms;
-  while (p) {
-    String *tm = Getattr(p, "tmap:freearg");
-    if (!tm) {
-      p = nextSibling(p);
-    } else {
-      tm = Copy(tm);
-      Replaceall(tm, "$input", Getattr(p, "emit:input"));
-      Printv(ret, tm, "\n", NULL);
-      Delete(tm);
-      p = Getattr(p, "tmap:freearg:next");
-    }
-  }
-  return ret;
-}
-
-void CFFI::cleanupFunction(Node *n, Wrapper *f, ParmList *parms) {
-  String *cleanup = freearg(parms);
-  Printv(f->code, cleanup, NULL);
-
-  if (GetFlag(n, "feature:new")) {
-    String *tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0);
-    if (tm) {
-      Replaceall(tm, "$source", Swig_cresult_name());
-      Printv(f->code, tm, "\n", NULL);
-      Delete(tm);
-    }
-  }
-
-  Replaceall(f->code, "$cleanup", cleanup);
-  Delete(cleanup);
-
-  Replaceall(f->code, "$symname", Getattr(n, "sym:name"));
-}
-
-int CFFI::functionWrapper(Node *n) {
-
-  ParmList *parms = Getattr(n, "parms");
-  String *iname = Getattr(n, "sym:name");
-  Wrapper *f = NewWrapper();
-
-  String *raw_return_type = Swig_typemap_lookup("ctype", n, "", 0);
-  SwigType *return_type = Swig_cparse_type(raw_return_type);
-  SwigType *resolved = SwigType_typedef_resolve_all(return_type);
-  int is_void_return = (Cmp(resolved, "void") == 0);
-  Delete(resolved);
-
-  if (!is_void_return) {
-    String *lresult_init = NewStringf("lresult = (%s)0", raw_return_type);
-    Wrapper_add_localv(f, "lresult", raw_return_type, lresult_init, NIL);
-    Delete(lresult_init);
-  }
-
-  String *overname = 0;
-  if (Getattr(n, "sym:overloaded")) {
-    overname = Getattr(n, "sym:overname");
-  } else {
-    if (!addSymbol(iname, n)) {
-      DelWrapper(f);
-      return SWIG_ERROR;
-    }
-  }
-
-  String *wname = Swig_name_wrapper(iname);
-  if (overname) {
-    Append(wname, overname);
-  }
-  Setattr(n, "wrap:name", wname);
-
-  // Emit all of the local variables for holding arguments.
-  emit_parameter_variables(parms, f);
-
-  // Attach the standard typemaps 
-  Swig_typemap_attach_parms("ctype", parms, f);
-  emit_attach_parmmaps(parms, f);
-
-  int num_arguments = emit_num_arguments(parms);
-  String *name_and_parms = NewStringf("%s (", wname);
-  int i;
-  Parm *p;
-  int gencomma = 0;
-
-#ifdef CFFI_DEBUG
-  Printf(stderr, "function  -  %s - %d\n", Getattr(n, "name"), num_arguments);
-#endif
-
-  for (i = 0, p = parms; i < num_arguments; i++) {
-
-    while (checkAttribute(p, "tmap:in:numinputs", "0")) {
-      p = Getattr(p, "tmap:in:next");
-    }
-
-    SwigType *c_parm_type = Swig_cparse_type(Getattr(p, "tmap:ctype"));
-    String *arg = NewStringf("l%s", Getattr(p, "lname"));
-
-    // Emit parameter declaration
-    if (gencomma)
-      Printf(name_and_parms, ", ");
-    String *parm_decl = SwigType_str(c_parm_type, arg);
-    Printf(name_and_parms, "%s", parm_decl);
-#ifdef CFFI_DEBUG
-    Printf(stderr, "  param: %s\n", parm_decl);
-#endif
-    Delete(parm_decl);
-    gencomma = 1;
-
-    // Emit parameter conversion code
-    String *parm_code = Getattr(p, "tmap:in");
-    {
-      Replaceall(parm_code, "$input", arg);
-      Setattr(p, "emit:input", arg);
-      Printf(f->code, "%s\n", parm_code);
-      p = Getattr(p, "tmap:in:next");
-    }
-
-    Delete(arg);
-  }
-  Printf(name_and_parms, ")");
-
-  // Emit the function definition
-  String *signature = SwigType_str(return_type, name_and_parms);
-  Printf(f->def, "EXPORT %s {", signature);
-
-  checkConstraints(parms, f);
-
-  Printf(f->code, "  try {\n");
-
-  String *actioncode = emit_action(n);
-
-  String *result_convert = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode);
-  if (result_convert) {
-    Replaceall(result_convert, "$result", "lresult");
-    Printf(f->code, "%s\n", result_convert);
-  }
-  Delete(result_convert);
-
-  argout(parms, f);
-
-  cleanupFunction(n, f, parms);
-
-  /* See if there is any return cleanup code */
-  String *tm = 0;
-  if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
-    Replaceall(tm, "$source", Swig_cresult_name());
-    Printf(f->code, "%s\n", tm);
-    Delete(tm);
-  }
-
-  if (!is_void_return) {
-    Printf(f->code, "    return lresult;\n");
-  }
-
-  emit_return_variable(n, Getattr(n, "type"), f);
-
-  Printf(f->code, "  } catch (...) {\n");
-  if (!is_void_return)
-    Printf(f->code, "    return (%s)0;\n", raw_return_type);
-  Printf(f->code, "  }\n");
-  Printf(f->code, "}\n");
-
-  if (CPlusPlus)
-    Wrapper_print(f, f_runtime);
-
-  if (CPlusPlus) {
-    emit_defun(n, wname);
-    if (Getattr(n, "cffi:memberfunction"))
-      emit_defmethod(n);
-    else if (Getattr(n, "cffi:membervariable")) {
-      if (Getattr(n, "memberget"))
-        emit_getter(n);
-      else if (Getattr(n, "memberset"))
-        emit_setter(n);
-    }
-    else if (Getattr(n, "cffi:constructorfunction")) {
-      emit_initialize_instance(n);
-    }
-  } else
-    emit_defun(n, iname);
-
-  //   if (!overloaded || !Getattr(n, "sym:nextSibling")) {
-  //     update_package_if_needed(n);
-  //     emit_buffered_defuns(n);
-  //     // this is the last overload.
-  //     if (overloaded) {
-  //       emit_dispatch_defun(n);
-  //     }
-  //   }
-
-  Delete(wname);
-  DelWrapper(f);
-
-  return SWIG_OK;
-}
-
-
-void CFFI::emit_defun(Node *n, String *name) {
-  String *func_name = Getattr(n, "sym:name");
-
-  ParmList *pl = Getattr(n, "parms");
-
-  int argnum = 0;
-
-  func_name = lispify_name(n, func_name, "'function");
-
-  emit_inline(n, func_name);
-
-  Printf(f_cl, "\n(cffi:defcfun (\"%s\" %s)", name, func_name);
-  String *ffitype = Swig_typemap_lookup("cout", n, ":pointer", 0);
-
-  Printf(f_cl, " %s", ffitype);
-  Delete(ffitype);
-
-  for (Parm *p = pl; p; p = nextSibling(p), argnum++) {
-
-    if (SwigType_isvarargs(Getattr(p, "type"))) {
-      Printf(f_cl, "\n  %s", NewString("&rest"));
-      continue;
-    }
-
-    String *argname = Getattr(p, "name");
-
-    ffitype = Swig_typemap_lookup("cin", p, "", 0);
-
-    int tempargname = 0;
-    if (!argname) {
-
-      argname = NewStringf("arg%d", argnum);
-      tempargname = 1;
-    } else if (Strcmp(argname, "t") == 0 || Strcmp(argname, "T") == 0) {
-      argname = NewStringf("t_arg%d", argnum);
-      tempargname = 1;
-    }
-
-    Printf(f_cl, "\n  (%s %s)", argname, ffitype);
-
-    Delete(ffitype);
-
-    if (tempargname)
-      Delete(argname);
-  }
-  Printf(f_cl, ")\n");    /* finish arg list */
-
-  emit_export(n, func_name);
-}
-
-
-int CFFI::constantWrapper(Node *n) {
-  String *type = Getattr(n, "type");
-  String *converted_value;
-  if (SwigType_type(type) == T_STRING) {
-    converted_value = NewString(Getattr(n, "rawval"));
-  } else {
-    converted_value = convert_literal(Getattr(n, "value"), type);
-  }
-
-  String *name = lispify_name(n, Getattr(n, "sym:name"), "'constant");
-
-  if (Strcmp(name, "t") == 0 || Strcmp(name, "T") == 0)
-    name = NewStringf("t_var");
-
-  Printf(f_cl, "\n(cl:defconstant %s %s)\n", name, converted_value);
-  Delete(converted_value);
-
-  emit_export(n, name);
-  return SWIG_OK;
-}
-
-int CFFI::variableWrapper(Node *n) {
-  String *var_name = Getattr(n, "sym:name");
-  String *lisp_type = Swig_typemap_lookup("cin", n, "", 0);
-  String *lisp_name = lispify_name(n, var_name, "'variable");
-
-  if (Strcmp(lisp_name, "t") == 0 || Strcmp(lisp_name, "T") == 0)
-    lisp_name = NewStringf("t_var");
-
-  Printf(f_cl, "\n(cffi:defcvar (\"%s\" %s)\n %s)\n", var_name, lisp_name, lisp_type);
-
-  Delete(lisp_type);
-
-  emit_export(n, lisp_name);
-  return SWIG_OK;
-}
-
-int CFFI::typedefHandler(Node *n) {
-  if (generate_typedef_flag && strncmp(Char(Getattr(n, "type")), "enum", 4)) {
-    String *lisp_name = lispify_name(n, Getattr(n, "name"), "'typename");
-    Printf(f_cl, "\n(cffi:defctype %s %s)\n", lisp_name, Swig_typemap_lookup("cin", n, "", 0));
-    emit_export(n, lisp_name);
-  }
-  return Language::typedefHandler(n);
-}
-
-int CFFI::enumDeclaration(Node *n) {
-  if (getCurrentClass() && (cplus_mode != PUBLIC))
-    return SWIG_NOWRAP;
-
-  String *name = Getattr(n, "sym:name");
-  bool slot_name_keywords;
-  String *lisp_name = 0;
-  if (name && Len(name) != 0) {
-    lisp_name = lispify_name(n, name, "'enumname");
-    if (GetFlag(n, "feature:bitfield")) {
-      Printf(f_cl, "\n(cffi:defbitfield %s", lisp_name);
-    } else {
-      Printf(f_cl, "\n(cffi:defcenum %s", lisp_name);
-    }
-    slot_name_keywords = true;
-
-    //Registering the enum name to the cin and cout typemaps
-    Parm *pattern = NewParm(name, NULL, n);
-    Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL);
-    Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL);
-    Delete(pattern);
-    //Registering with the kind, i.e., enum
-    pattern = NewParm(NewStringf("enum %s", name), NULL, n);
-    Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL);
-    Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL);
-    Delete(pattern);
-
-  } else {
-    Printf(f_cl, "\n(defanonenum %s", name);
-    slot_name_keywords = false;
-  }
-
-  for (Node *c = firstChild(n); c; c = nextSibling(c)) {
-
-    String *slot_name = lispify_name(c, Getattr(c, "name"), "'enumvalue", slot_name_keywords);
-    String *value = Getattr(c, "enumvalue");
-
-    if (!value || GetFlag(n, "feature:bitfield:ignore_values"))
-      Printf(f_cl, "\n\t%s", slot_name);
-    else {
-      String *type = Getattr(c, "type");
-      String *converted_value = convert_literal(value, type);
-      Printf(f_cl, "\n\t(%s #.%s)", slot_name, converted_value);
-      Delete(converted_value);
-    }
-    Delete(value);
-  }
-
-  Printf(f_cl, ")\n");
-
-  // No need to export keywords
-  if (lisp_name && Len(lisp_name) != 0) {
-    emit_export(n, lisp_name);
-  } else {
-    for (Node *c = firstChild(n); c; c = nextSibling(c))
-      emit_export(c, lispify_name(c, Getattr(c, "name"), "'enumvalue"));
-  }
-
-  return SWIG_OK;
-}
-void CFFI::emit_class(Node *n) {
-
-#ifdef CFFI_WRAP_DEBUG
-  Printf(stderr, "emit_class: ENTER... '%s'(%p)\n", Getattr(n, "sym:name"), n);
-#endif
-
-  String *name = Getattr(n, "sym:name");
-  String *lisp_name = lispify_name(n, lispy_name(Char(name)), "'classname");
-
-  String *bases = Getattr(n, "bases");
-  String *supers = NewString("(");
-  if (bases) {
-    int first = 1;
-    for (Iterator i = First(bases); i.item; i = Next(i)) {
-      if (!first)
-  Printf(supers, " ");
-      String *s = Getattr(i.item, "name");
-      Printf(supers, "%s", lispify_name(i.item, lispy_name(Char(s)), "'classname"));
-    }
-  } else {
-    // Printf(supers,"ff:foreign-pointer");
-  }
-
-  Printf(supers, ")");
-  Printf(f_clos, "\n(cl:defclass %s%s", lisp_name, supers);
-  Printf(f_clos, "\n  ((ff-pointer :reader ff-pointer)))\n\n");
-
-  Parm *pattern = NewParm(Getattr(n, "name"), NULL, n);
-
-  Swig_typemap_register("lispclass", pattern, lisp_name, NULL, NULL);
-  SwigType_add_pointer(Getattr(pattern, "type"));
-  Swig_typemap_register("lispclass", pattern, lisp_name, NULL, NULL);
-  SwigType_add_qualifier(Getattr(pattern, "type"), "const");
-  Swig_typemap_register("lispclass", pattern, lisp_name, NULL, NULL);
-  SwigType_del_pointer(Getattr(pattern, "type"));
-  SwigType_add_reference(Getattr(pattern, "type"));
-  Swig_typemap_register("lispclass", pattern, lisp_name, NULL, NULL);
-
-#ifdef CFFI_WRAP_DEBUG
-  Printf(stderr, "  pattern %s  name %s .. ... %s .\n", pattern, lisp_name);
-#endif
-
-  Delete(pattern);
-
-  // Walk children to generate type definition.
-  String *slotdefs = NewString("   ");
-
-#ifdef CFFI_WRAP_DEBUG
-  Printf(stderr, "  walking children...\n");
-#endif
-
-  Node *c;
-  for (c = firstChild(n); c; c = nextSibling(c)) {
-    String *storage_type = Getattr(c, "storage");
-    if ((!Strcmp(nodeType(c), "cdecl") && (!storage_type || Strcmp(storage_type, "typedef")))) {
-      String *access = Getattr(c, "access");
-
-      // hack. why would decl have a value of "variableHandler" and now "0"?
-      String *childDecl = Getattr(c, "decl");
-      // Printf(stderr,"childDecl = '%s' (%s)\n", childDecl, Getattr(c,"view"));
-      if (!Strcmp(childDecl, "0"))
-  childDecl = NewString("");
-
-      SwigType *childType = NewStringf("%s%s", childDecl,
-               Getattr(c, "type"));
-      String *cname = (access && Strcmp(access, "public")) ? NewString("nil") : Copy(Getattr(c, "name"));
-
-      if (!SwigType_isfunction(childType)) {
-  // Printf(slotdefs, ";;; member functions don't appear as slots.\n ");
-  // Printf(slotdefs, ";; ");
-  //        String *ns = listify_namespace(Getattr(n, "cffi:package"));
-  String *ns = NewString("");
-#ifdef CFFI_WRAP_DEBUG
-  Printf(stderr, "slot name = '%s' ns = '%s' class-of '%s' and type = '%s'\n", cname, ns, name, childType);
-#endif
-  Printf(slotdefs, "(#.(swig-insert-id \"%s\" %s :type :slot :class \"%s\") %s)", cname, ns, name, childType);  //compose_foreign_type(childType)
-  Delete(ns);
-  if (access && Strcmp(access, "public"))
-    Printf(slotdefs, " ;; %s member", access);
-
-  Printf(slotdefs, "\n   ");
-      }
-      Delete(childType);
-      Delete(cname);
-    }
-  }
-
-
-  //   String *ns_list = listify_namespace(Getattr(n,"cffi:namespace"));
-  //   update_package_if_needed(n,f_clhead);
-  //   Printf(f_clos, 
-  //          "(swig-def-foreign-class \"%s\"\n %s\n  (:%s\n%s))\n\n", 
-  //          name, supers, kind, slotdefs);
-
-  Delete(supers);
-  //  Delete(ns_list);
-
-  //  Parm *pattern = NewParm(name, NULL, n);
-  // Swig_typemap_register("cin",pattern,lisp_name,NULL,NULL);  
-  //Swig_typemap_register("cout",pattern,lisp_name,NULL,NULL);
-  //Delete(pattern);
-
-#ifdef CFFI_WRAP_DEBUG
-  Printf(stderr, "emit_class: EXIT\n");
-#endif
-}
-
-// Includes structs
-void CFFI::emit_struct_union(Node *n, bool un = false) {
-#ifdef CFFI_DEBUG
-  Printf(stderr, "struct/union %s\n", Getattr(n, "name"));
-  Printf(stderr, "struct/union %s\n and %s", Getattr(n, "kind"), Getattr(n, "sym:name"));
-#endif
-
-  String *name = Getattr(n, "sym:name");
-  String *kind = Getattr(n, "kind");
-
-  if (Strcmp(kind, "struct") != 0 && Strcmp(kind, "union") != 0) {
-    Printf(stderr, "Don't know how to deal with %s kind of class yet.\n", kind);
-    Printf(stderr, " (name: %s)\n", name);
-    SWIG_exit(EXIT_FAILURE);
-  }
-  String *lisp_name = lispify_name(n, name, "'classname");
-
-  //Register the struct/union name to the cin and cout typemaps
-
-  Parm *pattern = NewParm(name, NULL, n);
-  Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL);
-  Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL);
-  Delete(pattern);
-  //Registering with the kind, i.e., struct or union
-  pattern = NewParm(NewStringf("%s %s", kind, name), NULL, n);
-  Swig_typemap_register("cin", pattern, lisp_name, NULL, NULL);
-  Swig_typemap_register("cout", pattern, lisp_name, NULL, NULL);
-  Delete(pattern);
-
-  if (un) {
-    Printf(f_cl, "\n(cffi:defcunion %s", lisp_name);
-  } else
-    Printf(f_cl, "\n(cffi:defcstruct %s", lisp_name);
-
-
-  for (Node *c = firstChild(n); c; c = nextSibling(c)) {
-#ifdef CFFI_DEBUG
-    Printf(stderr, "struct/union %s\n", Getattr(c, "name"));
-    Printf(stderr, "struct/union %s and %s \n", Getattr(c, "kind"), Getattr(c, "sym:name"));
-#endif
-
-    if (Strcmp(nodeType(c), "cdecl")) {
-      //C declaration ignore
-      //        Printf(stderr, "Structure %s has a slot that we can't deal with.\n",
-      //               name);
-      //        Printf(stderr, "nodeType: %s, name: %s, type: %s\n", 
-      //               nodeType(c),
-      //               Getattr(c, "name"),
-      //               Getattr(c, "type"));
-      //       SWIG_exit(EXIT_FAILURE);
-    } else {
-      SwigType *childType = NewStringf("%s%s", Getattr(c, "decl"), Getattr(c, "type"));
-
-      Node *node = NewHash();
-      Setattr(node, "type", childType);
-      Setfile(node, Getfile(n));
-      Setline(node, Getline(n));
-      const String *tm = Swig_typemap_lookup("cin", node, "", 0);
-
-      String *typespec = tm ? NewString(tm) : NewString("");
-
-      String *slot_name = lispify_name(c, Getattr(c, "sym:name"), "'slotname");
-      if (slot_name && (Strcmp(slot_name, "t") == 0 || Strcmp(slot_name, "T") == 0))
-	slot_name = NewStringf("t_var");
-
-      if (SwigType_isarray(childType) && SwigType_array_ndim(childType) == 1) {
-          String *dim = SwigType_array_getdim(childType, 0);
-          Printf(f_cl, "\n\t(%s %s :count %s)", slot_name, typespec, dim);
-          Delete(dim);
-      } else
-          Printf(f_cl, "\n\t(%s %s)", slot_name, typespec);
-
-      Delete(node);
-      Delete(childType);
-      Delete(typespec);
-    }
-  }
-
-  Printf(f_cl, ")\n");
-
-  emit_export(n, lisp_name);
-  for (Node *child = firstChild(n); child; child = nextSibling(child)) {
-    if (!Strcmp(nodeType(child), "cdecl")) {
-      emit_export(child, lispify_name(child, Getattr(child, "sym:name"), "'slotname"));
-    }
-  }
-
-  /* Add this structure to the known lisp types */
-  //Printf(stdout, "Adding %s foreign type\n", name);
-  //  add_defined_foreign_type(name);
-
-}
-
-void CFFI::emit_export(Node *n, String *name) {
-  if (GetInt(n, "feature:export")) {
-    String* package = Getattr(n, "feature:export:package");
-    Printf(f_cl, "\n(cl:export '%s%s%s)\n", name, package ? " " : "",
-                                                  package ? package : "");
-  }
-}
-
-void CFFI::emit_inline(Node *n, String *name) {
-  if (GetInt(n, "feature:inline"))
-    Printf(f_cl, "\n(cl:declaim (cl:inline %s))\n", name);
-}
-
-String *CFFI::lispify_name(Node *n, String *ty, const char *flag, bool kw) {
-  String *intern_func = Getattr(n, "feature:intern_function");
-  if (intern_func) {
-    if (Strcmp(intern_func, "1") == 0)
-      intern_func = NewStringf("swig-lispify");
-    return NewStringf("#.(%s \"%s\" %s%s)", intern_func, ty, flag, kw ? " :keyword" : "");
-  } else if (kw)
-    return NewStringf(":%s", ty);
-  else
-    return ty;
-}
-
-/* utilities */
-/* returns new string w/ parens stripped */
-String *CFFI::strip_parens(String *string) {
-  char *s = Char(string), *p;
-  int len = Len(string);
-  String *res;
-
-  if (len == 0 || s[0] != '(' || s[len - 1] != ')') {
-    return NewString(string);
-  }
-
-  p = (char *) malloc(len - 2 + 1);
-  if (!p) {
-    Printf(stderr, "Malloc failed\n");
-    SWIG_exit(EXIT_FAILURE);
-  }
-
-  strncpy(p, s + 1, len - 1);
-  p[len - 2] = 0;   /* null terminate */
-
-  res = NewString(p);
-  free(p);
-
-  return res;
-}
-
-String *CFFI::trim(String *str) {
-  char *c = Char(str);
-  while (*c != '\0' && isspace((int) *c))
-    ++c;
-  String *result = NewString(c);
-  Chop(result);
-  return result;
-}
-
-String *CFFI::infix_to_prefix(String *val, char split_op, const String *op, String *type) {
-  List *ored = Split(val, split_op, -1);
-
-  // some float hackery
-  //i don't understand it, if you do then please explain
-  //   if ( ((split_op == '+') || (split_op == '-')) && Len(ored) == 2 &&
-  //        (SwigType_type(type) == T_FLOAT || SwigType_type(type) == T_DOUBLE ||
-  //    SwigType_type(type) == T_LONGDOUBLE) ) {
-  //     // check that we're not splitting a float
-  //     String *possible_result = convert_literal(val, type, false);
-  //     if (possible_result) return possible_result;
-
-  //   }
-
-  // try parsing the split results. if any part fails, kick out.
-  bool part_failed = false;
-  if (Len(ored) > 1) {
-    String *result = NewStringf("(%s", op);
-    for (Iterator i = First(ored); i.item; i = Next(i)) {
-      String *converted = convert_literal(i.item, type);
-      if (converted) {
-  Printf(result, " %s", converted);
-  Delete(converted);
-      } else {
-  part_failed = true;
-  break;
-      }
-    }
-    Printf(result, ")");
-    Delete(ored);
-    return part_failed ? 0 : result;
-  } else {
-    Delete(ored);
-  }
-  return 0;
-}
-
-/* To be called by code generating the lisp interface
-   Will return a String containing the literal based on type.
-   Will return null if there are problems.
-
-   try_to_split defaults to true (see stub above).
-*/
-String *CFFI::convert_literal(String *literal, String *type, bool try_to_split) {
-  String *num_param = Copy(literal);
-  String *trimmed = trim(num_param);
-  String *num = strip_parens(trimmed), *res = 0;
-  Delete(trimmed);
-  char *s = Char(num);
-
-  // very basic parsing of infix expressions.
-  if (try_to_split) {
-    if ((res = infix_to_prefix(num, '|', "cl:logior", type)))
-      return res;
-    if ((res = infix_to_prefix(num, '&', "cl:logand", type)))
-      return res;
-    if ((res = infix_to_prefix(num, '^', "cl:logxor", type)))
-      return res;
-    if ((res = infix_to_prefix(num, '*', "cl:*", type)))
-      return res;
-    if ((res = infix_to_prefix(num, '/', "cl:/", type)))
-      return res;
-    if ((res = infix_to_prefix(num, '+', "cl:+", type)))
-      return res;
-    if ((res = infix_to_prefix(num, '-', "cl:-", type)))
-      return res;
-  }
-
-  if (SwigType_type(type) == T_FLOAT || SwigType_type(type) == T_DOUBLE || SwigType_type(type) == T_LONGDOUBLE) {
-    // Use CL syntax for float literals 
-
-    // careful. may be a float identifier or float constant.
-    char *num_start = Char(num);
-    char *num_end = num_start + strlen(num_start) - 1;
-
-    bool is_literal = isdigit(*num_start) || (*num_start == '.') || (*num_start == '+') || (*num_start == '-');
-
-    String *lisp_exp = 0;
-    if (is_literal) {
-      if (*num_end == 'f' || *num_end == 'F') {
-        lisp_exp = NewString("f");
-      } else {
-        lisp_exp = NewString("d");
-      }
-
-      if (*num_end == 'l' || *num_end == 'L' || *num_end == 'f' || *num_end == 'F') {
-        *num_end = '\0';
-        num_end--;
-      }
-
-      int exponents = Replaceall(num, "e", lisp_exp) + Replaceall(num, "E", lisp_exp);
-
-      if (!exponents)
-        Printf(num, "%s0", lisp_exp);
-
-      if (exponents > 1 || (exponents + Replaceall(num, ".", ".") == 0)) {
-        Delete(num);
-        num = 0;
-      }
-    }
-    return num;
-  } else if (SwigType_type(type) == T_CHAR) {
-    /* Use CL syntax for character literals */
-    String* result = NewStringf("#\\%s", s);
-    Delete(num);
-    return result;
-  } else if (SwigType_type(type) == T_STRING) {
-    /* Use CL syntax for string literals */
-    String* result = NewStringf("\"%s\"", num_param);
-    Delete(num);
-    return result;
-  } else if (SwigType_type(type) == T_INT || SwigType_type(type) == T_UINT) {
-    // Printf(stderr, "Is a T_INT or T_UINT %s, before replaceall\n", s);
-    const char *num_start = Char(num);
-    bool is_literal = isdigit(*num_start) || (*num_start == '.') || (*num_start == '+') || (*num_start == '-');
-    if (is_literal) {
-      Replaceall(num, "u", "");
-      Replaceall(num, "U", "");
-      Replaceall(num, "l", "");
-      Replaceall(num, "L", "");
-    }
-
-    int i, j;
-    if (sscanf(s, "%d >> %d", &i, &j) == 2) {
-      String* result = NewStringf("(cl:ash %d -%d)", i, j);
-      Delete(num);
-      return result;
-    } else if (sscanf(s, "%d << %d", &i, &j) == 2) {
-      String* result = NewStringf("(cl:ash %d %d)", i, j);
-      Delete(num);
-      return result;
-    }
-  }
-
-  if (Len(num) >= 2 && s[0] == '0') { /* octal or hex */
-    if (s[1] == 'x'){
-      Replace(num,"0","#",DOH_REPLACE_FIRST);
-    }
-    else{
-      Replace(num,"0","#o",DOH_REPLACE_FIRST);
-    }
-  }
-  return num;
-}
-
-//less flexible as it does the conversion in C, the lispify name does the conversion in lisp
-String *CFFI::lispy_name(char *name) {
-  bool helper = false;
-  String *new_name = NewString("");
-  for (unsigned int i = 0; i < strlen(name); i++) {
-    if (name[i] == '_' || name[i] == '-') {
-      Printf(new_name, "%c", '-');
-      helper = false;
-    } else if (name[i] >= 'A' && name[i] <= 'Z') {
-      if (helper)
-  Printf(new_name, "%c", '-');
-      Printf(new_name, "%c", ('a' + (name[i] - 'A')));
-      helper = false;
-    } else {
-      helper = true;
-      Printf(new_name, "%c", name[i]);
-    }
-  }
-  return new_name;
-}
-
-extern "C" Language *swig_cffi(void) {
-  return new CFFI();
-}
diff --git a/Source/Modules/chicken.cxx b/Source/Modules/chicken.cxx
deleted file mode 100644
index 76b6455..0000000
--- a/Source/Modules/chicken.cxx
+++ /dev/null
@@ -1,1535 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3 
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
- *
- * chicken.cxx
- *
- * CHICKEN language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-
-#include <ctype.h>
-
-static const char *usage = "\
-\
-CHICKEN Options (available with -chicken)\n\
-     -closprefix <prefix>   - Prepend <prefix> to all clos identifiers\n\
-     -noclosuses            - Do not (declare (uses ...)) in scheme file\n\
-     -nocollection          - Do not register pointers with chicken garbage\n\
-                              collector and export destructors\n\
-     -nounit                - Do not (declare (unit ...)) in scheme file\n\
-     -proxy                 - Export TinyCLOS class definitions\n\
-     -unhideprimitive       - Unhide the primitive: symbols\n\
-     -useclassprefix        - Prepend the class name to all clos identifiers\n\
-\n";
-
-static char *module = 0;
-static const char *chicken_path = "chicken";
-static int num_methods = 0;
-
-static File *f_begin = 0;
-static File *f_runtime = 0;
-static File *f_header = 0;
-static File *f_wrappers = 0;
-static File *f_init = 0;
-static String *chickentext = 0;
-static String *closprefix = 0;
-static String *swigtype_ptr = 0;
-
-
-static String *f_sym_size = 0;
-
-/* some options */
-static int declare_unit = 1;
-static int no_collection = 0;
-static int clos_uses = 1;
-
-/* C++ Support + Clos Classes */
-static int clos = 0;
-static String *c_class_name = 0;
-static String *class_name = 0;
-static String *short_class_name = 0;
-
-static int in_class = 0;
-static int have_constructor = 0;
-static bool exporting_destructor = false;
-static bool exporting_constructor = false;
-static String *constructor_name = 0;
-static String *member_name = 0;
-
-/* sections of the .scm code */
-static String *scm_const_defs = 0;
-static String *clos_class_defines = 0;
-static String *clos_methods = 0;
-
-/* Some clos options */
-static int useclassprefix = 0;
-static String *clossymnameprefix = 0;
-static int hide_primitive = 1;
-static Hash *primitive_names = 0;
-
-/* Used for overloading constructors */
-static int has_constructor_args = 0;
-static List *constructor_arg_types = 0;
-static String *constructor_dispatch = 0;
-
-static Hash *overload_parameter_lists = 0;
-
-class CHICKEN:public Language {
-public:
-
-  virtual void main(int argc, char *argv[]);
-  virtual int top(Node *n);
-  virtual int functionWrapper(Node *n);
-  virtual int variableWrapper(Node *n);
-  virtual int constantWrapper(Node *n);
-  virtual int classHandler(Node *n);
-  virtual int memberfunctionHandler(Node *n);
-  virtual int membervariableHandler(Node *n);
-  virtual int constructorHandler(Node *n);
-  virtual int destructorHandler(Node *n);
-  virtual int validIdentifier(String *s);
-  virtual int staticmembervariableHandler(Node *n);
-  virtual int staticmemberfunctionHandler(Node *n);
-  virtual int importDirective(Node *n);
-
-protected:
-  void addMethod(String *scheme_name, String *function);
-  /* Return true iff T is a pointer type */
-  int isPointer(SwigType *t);
-  void dispatchFunction(Node *n);
-
-  String *chickenNameMapping(String *, const_String_or_char_ptr );
-  String *chickenPrimitiveName(String *);
-
-  String *runtimeCode();
-  String *defaultExternalRuntimeFilename();
-  String *buildClosFunctionCall(List *types, const_String_or_char_ptr closname, const_String_or_char_ptr funcname);
-};
-
-/* -----------------------------------------------------------------------
- * swig_chicken()    - Instantiate module
- * ----------------------------------------------------------------------- */
-
-static Language *new_swig_chicken() {
-  return new CHICKEN();
-}
-
-extern "C" {
-  Language *swig_chicken(void) {
-    return new_swig_chicken();
-  }
-}
-
-void CHICKEN::main(int argc, char *argv[]) {
-  int i;
-
-  SWIG_library_directory(chicken_path);
-
-  // Look for certain command line options
-  for (i = 1; i < argc; i++) {
-    if (argv[i]) {
-      if (strcmp(argv[i], "-help") == 0) {
-	fputs(usage, stdout);
-	SWIG_exit(0);
-      } else if (strcmp(argv[i], "-proxy") == 0) {
-	clos = 1;
-	Swig_mark_arg(i);
-      } else if (strcmp(argv[i], "-closprefix") == 0) {
-	if (argv[i + 1]) {
-	  clossymnameprefix = NewString(argv[i + 1]);
-	  Swig_mark_arg(i);
-	  Swig_mark_arg(i + 1);
-	  i++;
-	} else {
-	  Swig_arg_error();
-	}
-      } else if (strcmp(argv[i], "-useclassprefix") == 0) {
-	useclassprefix = 1;
-	Swig_mark_arg(i);
-      } else if (strcmp(argv[i], "-unhideprimitive") == 0) {
-	hide_primitive = 0;
-	Swig_mark_arg(i);
-      } else if (strcmp(argv[i], "-nounit") == 0) {
-	declare_unit = 0;
-	Swig_mark_arg(i);
-      } else if (strcmp(argv[i], "-noclosuses") == 0) {
-	clos_uses = 0;
-	Swig_mark_arg(i);
-      } else if (strcmp(argv[i], "-nocollection") == 0) {
-	no_collection = 1;
-	Swig_mark_arg(i);
-      }
-    }
-  }
-
-  if (!clos)
-    hide_primitive = 0;
-
-  // Add a symbol for this module
-  Preprocessor_define("SWIGCHICKEN 1", 0);
-
-  // Set name of typemaps
-
-  SWIG_typemap_lang("chicken");
-
-  // Read in default typemaps */
-  SWIG_config_file("chicken.swg");
-  allow_overloading();
-}
-
-int CHICKEN::top(Node *n) {
-  String *chicken_filename = NewString("");
-  File *f_scm;
-  String *scmmodule;
-
-  /* Initialize all of the output files */
-  String *outfile = Getattr(n, "outfile");
-
-  f_begin = NewFile(outfile, "w", SWIG_output_files());
-  if (!f_begin) {
-    FileErrorDisplay(outfile);
-    SWIG_exit(EXIT_FAILURE);
-  }
-  f_runtime = NewString("");
-  f_init = NewString("");
-  f_header = NewString("");
-  f_wrappers = NewString("");
-  chickentext = NewString("");
-  closprefix = NewString("");
-  f_sym_size = NewString("");
-  primitive_names = NewHash();
-  overload_parameter_lists = NewHash();
-
-  /* Register file targets with the SWIG file handler */
-  Swig_register_filebyname("header", f_header);
-  Swig_register_filebyname("wrapper", f_wrappers);
-  Swig_register_filebyname("begin", f_begin);
-  Swig_register_filebyname("runtime", f_runtime);
-  Swig_register_filebyname("init", f_init);
-
-  Swig_register_filebyname("chicken", chickentext);
-  Swig_register_filebyname("closprefix", closprefix);
-
-  clos_class_defines = NewString("");
-  clos_methods = NewString("");
-  scm_const_defs = NewString("");
-
-  Swig_banner(f_begin);
-
-  Printf(f_runtime, "\n\n#ifndef SWIGCHICKEN\n#define SWIGCHICKEN\n#endif\n\n");
-
-  if (no_collection)
-    Printf(f_runtime, "#define SWIG_CHICKEN_NO_COLLECTION 1\n");
-
-  Printf(f_runtime, "\n");
-
-  /* Set module name */
-  module = Swig_copy_string(Char(Getattr(n, "name")));
-  scmmodule = NewString(module);
-  Replaceall(scmmodule, "_", "-");
-
-  Printf(f_header, "#define SWIG_init swig_%s_init\n", module);
-  Printf(f_header, "#define SWIG_name \"%s\"\n", scmmodule);
-
-  Printf(f_wrappers, "#ifdef __cplusplus\n");
-  Printf(f_wrappers, "extern \"C\" {\n");
-  Printf(f_wrappers, "#endif\n\n");
-
-  Language::top(n);
-
-  SwigType_emit_type_table(f_runtime, f_wrappers);
-
-  Printf(f_wrappers, "#ifdef __cplusplus\n");
-  Printf(f_wrappers, "}\n");
-  Printf(f_wrappers, "#endif\n");
-
-  Printf(f_init, "C_kontinue (continuation, ret);\n");
-  Printf(f_init, "}\n\n");
-
-  Printf(f_init, "#ifdef __cplusplus\n");
-  Printf(f_init, "}\n");
-  Printf(f_init, "#endif\n");
-
-  Printf(chicken_filename, "%s%s.scm", SWIG_output_directory(), module);
-  if ((f_scm = NewFile(chicken_filename, "w", SWIG_output_files())) == 0) {
-    FileErrorDisplay(chicken_filename);
-    SWIG_exit(EXIT_FAILURE);
-  }
-
-  Swig_banner_target_lang(f_scm, ";;");
-  Printf(f_scm, "\n");
-
-  if (declare_unit)
-    Printv(f_scm, "(declare (unit ", scmmodule, "))\n\n", NIL);
-  Printv(f_scm, "(declare \n",
-	 tab4, "(hide swig-init swig-init-return)\n",
-	 tab4, "(foreign-declare \"C_extern void swig_", module, "_init(C_word,C_word,C_word) C_noret;\"))\n", NIL);
-  Printv(f_scm, "(define swig-init (##core#primitive \"swig_", module, "_init\"))\n", NIL);
-  Printv(f_scm, "(define swig-init-return (swig-init))\n\n", NIL);
-
-  if (clos) {
-    //Printf (f_scm, "(declare (uses tinyclos))\n");
-    //New chicken versions have tinyclos as an egg
-    Printf(f_scm, "(require-extension tinyclos)\n");
-    Replaceall(closprefix, "$module", scmmodule);
-    Printf(f_scm, "%s\n", closprefix);
-    Printf(f_scm, "%s\n", clos_class_defines);
-    Printf(f_scm, "%s\n", clos_methods);
-  } else {
-    Printf(f_scm, "%s\n", scm_const_defs);
-  }
-
-  Printf(f_scm, "%s\n", chickentext);
-
-  Delete(f_scm);
-
-  char buftmp[20];
-  sprintf(buftmp, "%d", num_methods);
-  Replaceall(f_init, "$nummethods", buftmp);
-  Replaceall(f_init, "$symsize", f_sym_size);
-
-  if (hide_primitive)
-    Replaceall(f_init, "$veclength", buftmp);
-  else
-    Replaceall(f_init, "$veclength", "0");
-
-  Delete(chicken_filename);
-  Delete(chickentext);
-  Delete(closprefix);
-  Delete(overload_parameter_lists);
-
-  Delete(clos_class_defines);
-  Delete(clos_methods);
-  Delete(scm_const_defs);
-
-  /* Close all of the files */
-  Delete(primitive_names);
-  Delete(scmmodule);
-  Dump(f_runtime, f_begin);
-  Dump(f_header, f_begin);
-  Dump(f_wrappers, f_begin);
-  Wrapper_pretty_print(f_init, f_begin);
-  Delete(f_header);
-  Delete(f_wrappers);
-  Delete(f_sym_size);
-  Delete(f_init);
-  Delete(f_runtime);
-  Delete(f_begin);
-  return SWIG_OK;
-}
-
-int CHICKEN::functionWrapper(Node *n) {
-
-  String *name = Getattr(n, "name");
-  String *iname = Getattr(n, "sym:name");
-  SwigType *d = Getattr(n, "type");
-  ParmList *l = Getattr(n, "parms");
-
-  Parm *p;
-  int i;
-  String *wname;
-  Wrapper *f;
-  String *mangle = NewString("");
-  String *get_pointers;
-  String *cleanup;
-  String *argout;
-  String *tm;
-  String *overname = 0;
-  String *declfunc = 0;
-  String *scmname;
-  bool any_specialized_arg = false;
-  List *function_arg_types = NewList();
-
-  int num_required;
-  int num_arguments;
-  int have_argout;
-
-  Printf(mangle, "\"%s\"", SwigType_manglestr(d));
-
-  if (Getattr(n, "sym:overloaded")) {
-    overname = Getattr(n, "sym:overname");
-  } else {
-    if (!addSymbol(iname, n))
-      return SWIG_ERROR;
-  }
-
-  f = NewWrapper();
-  wname = NewString("");
-  get_pointers = NewString("");
-  cleanup = NewString("");
-  argout = NewString("");
-  declfunc = NewString("");
-  scmname = NewString(iname);
-  Replaceall(scmname, "_", "-");
-
-  /* Local vars */
-  Wrapper_add_local(f, "resultobj", "C_word resultobj");
-
-  /* Write code to extract function parameters. */
-  emit_parameter_variables(l, f);
-
-  /* Attach the standard typemaps */
-  emit_attach_parmmaps(l, f);
-  Setattr(n, "wrap:parms", l);
-
-  /* Get number of required and total arguments */
-  num_arguments = emit_num_arguments(l);
-  num_required = emit_num_required(l);
-
-  Append(wname, Swig_name_wrapper(iname));
-  if (overname) {
-    Append(wname, overname);
-  }
-  // Check for interrupts
-  Printv(f->code, "C_trace(\"", scmname, "\");\n", NIL);
-
-  Printv(f->def, "static ", "void ", wname, " (C_word argc, C_word closure, C_word continuation", NIL);
-  Printv(declfunc, "void ", wname, "(C_word,C_word,C_word", NIL);
-
-  /* Generate code for argument marshalling */
-  for (i = 0, p = l; i < num_arguments; i++) {
-
-    while (checkAttribute(p, "tmap:in:numinputs", "0")) {
-      p = Getattr(p, "tmap:in:next");
-    }
-
-    SwigType *pt = Getattr(p, "type");
-    String *ln = Getattr(p, "lname");
-
-    Printf(f->def, ", C_word scm%d", i + 1);
-    Printf(declfunc, ",C_word");
-
-    /* Look for an input typemap */
-    if ((tm = Getattr(p, "tmap:in"))) {
-      String *parse = Getattr(p, "tmap:in:parse");
-      if (!parse) {
-        String *source = NewStringf("scm%d", i + 1);
-	Replaceall(tm, "$source", source);
-	Replaceall(tm, "$target", ln);
-	Replaceall(tm, "$input", source);
-	Setattr(p, "emit:input", source);	/* Save the location of
-						   the object */
-
-	if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
-	  Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
-	} else {
-	  Replaceall(tm, "$disown", "0");
-	}
-
-	if (i >= num_required)
-	  Printf(get_pointers, "if (argc-2>%i && (%s)) {\n", i, source);
-	Printv(get_pointers, tm, "\n", NIL);
-	if (i >= num_required)
-	  Printv(get_pointers, "}\n", NIL);
-
-	if (clos) {
-	  if (i < num_required) {
-	    if (strcmp("void", Char(pt)) != 0) {
-	      Node *class_node = 0;
-	      String *clos_code = Getattr(p, "tmap:in:closcode");
-	      class_node = classLookup(pt);
-	      if (clos_code && class_node) {
-		String *class_name = NewStringf("<%s>", Getattr(class_node, "sym:name"));
-		Replaceall(class_name, "_", "-");
-		Append(function_arg_types, class_name);
-		Append(function_arg_types, Copy(clos_code));
-		any_specialized_arg = true;
-		Delete(class_name);
-	      } else {
-		Append(function_arg_types, "<top>");
-		Append(function_arg_types, "$input");
-	      }
-	    }
-	  }
-	}
-        Delete(source);
-      }
-
-      p = Getattr(p, "tmap:in:next");
-      continue;
-    } else {
-      Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
-      break;
-    }
-  }
-
-  /* finish argument marshalling */
-
-  Printf(f->def, ") {");
-  Printf(declfunc, ")");
-
-  if (num_required != num_arguments) {
-    Append(function_arg_types, "^^##optional$$");
-  }
-
-  /* First check the number of arguments is correct */
-  if (num_arguments != num_required)
-    Printf(f->code, "if (argc-2<%i || argc-2>%i) C_bad_argc(argc,%i);\n", num_required, num_arguments, num_required + 2);
-  else
-    Printf(f->code, "if (argc!=%i) C_bad_argc(argc,%i);\n", num_arguments + 2, num_arguments + 2);
-
-  /* Now piece together the first part of the wrapper function */
-  Printv(f->code, get_pointers, NIL);
-
-  /* Insert constraint checking code */
-  for (p = l; p;) {
-    if ((tm = Getattr(p, "tmap:check"))) {
-      Replaceall(tm, "$target", Getattr(p, "lname"));
-      Printv(f->code, tm, "\n", NIL);
-      p = Getattr(p, "tmap:check:next");
-    } else {
-      p = nextSibling(p);
-    }
-  }
-
-  /* Insert cleanup code */
-  for (p = l; p;) {
-    if ((tm = Getattr(p, "tmap:freearg"))) {
-      Replaceall(tm, "$source", Getattr(p, "lname"));
-      Printv(cleanup, tm, "\n", NIL);
-      p = Getattr(p, "tmap:freearg:next");
-    } else {
-      p = nextSibling(p);
-    }
-  }
-
-  /* Insert argument output code */
-  have_argout = 0;
-  for (p = l; p;) {
-    if ((tm = Getattr(p, "tmap:argout"))) {
-
-      if (!have_argout) {
-	have_argout = 1;
-	// Print initial argument output code
-	Printf(argout, "SWIG_Chicken_SetupArgout\n");
-      }
-
-      Replaceall(tm, "$source", Getattr(p, "lname"));
-      Replaceall(tm, "$target", "resultobj");
-      Replaceall(tm, "$arg", Getattr(p, "emit:input"));
-      Replaceall(tm, "$input", Getattr(p, "emit:input"));
-      Printf(argout, "%s", tm);
-      p = Getattr(p, "tmap:argout:next");
-    } else {
-      p = nextSibling(p);
-    }
-  }
-
-  Setattr(n, "wrap:name", wname);
-
-  /* Emit the function call */
-  String *actioncode = emit_action(n);
-
-  /* Return the function value */
-  if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
-    Replaceall(tm, "$source", Swig_cresult_name());
-    Replaceall(tm, "$target", "resultobj");
-    Replaceall(tm, "$result", "resultobj");
-    if (GetFlag(n, "feature:new")) {
-      Replaceall(tm, "$owner", "1");
-    } else {
-      Replaceall(tm, "$owner", "0");
-    }
-
-    Printf(f->code, "%s", tm);
-
-    if (have_argout)
-      Printf(f->code, "\nSWIG_APPEND_VALUE(resultobj);\n");
-
-  } else {
-    Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
-  }
-  emit_return_variable(n, d, f);
-
-  /* Insert the argument output code */
-  Printv(f->code, argout, NIL);
-
-  /* Output cleanup code */
-  Printv(f->code, cleanup, NIL);
-
-  /* Look to see if there is any newfree cleanup code */
-  if (GetFlag(n, "feature:new")) {
-    if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
-      Replaceall(tm, "$source", Swig_cresult_name());
-      Printf(f->code, "%s\n", tm);
-    }
-  }
-
-  /* See if there is any return cleanup code */
-  if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
-    Replaceall(tm, "$source", Swig_cresult_name());
-    Printf(f->code, "%s\n", tm);
-  }
-
-
-  if (have_argout) {
-    Printf(f->code, "C_kontinue(continuation,C_SCHEME_END_OF_LIST);\n");
-  } else {
-    if (exporting_constructor && clos && hide_primitive) {
-      /* Don't return a proxy, the wrapped CLOS class is the proxy */
-      Printf(f->code, "C_kontinue(continuation,resultobj);\n");
-    } else {
-      // make the continuation the proxy creation function, if one exists
-      Printv(f->code, "{\n",
-	     "C_word func;\n",
-	     "SWIG_Chicken_FindCreateProxy(func, resultobj)\n",
-	     "if (C_swig_is_closurep(func))\n",
-	     "  ((C_proc4)(void *)C_block_item(func, 0))(4,func,continuation,resultobj,C_SCHEME_FALSE);\n",
-	     "else\n", "  C_kontinue(continuation, resultobj);\n", "}\n", NIL);
-    }
-  }
-
-  /* Error handling code */
-#ifdef USE_FAIL
-  Printf(f->code, "fail:\n");
-  Printv(f->code, cleanup, NIL);
-  Printf(f->code, "swig_panic (\"failure in " "'$symname' SWIG function wrapper\");\n");
-#endif
-  Printf(f->code, "}\n");
-
-  /* Substitute the cleanup code */
-  Replaceall(f->code, "$cleanup", cleanup);
-
-  /* Substitute the function name */
-  Replaceall(f->code, "$symname", iname);
-  Replaceall(f->code, "$result", "resultobj");
-
-  /* Dump the function out */
-  Printv(f_wrappers, "static ", declfunc, " C_noret;\n", NIL);
-  Wrapper_print(f, f_wrappers);
-
-  /* Now register the function with the interpreter.   */
-  if (!Getattr(n, "sym:overloaded")) {
-    if (exporting_destructor && !no_collection) {
-      Printf(f_init, "((swig_chicken_clientdata *)(SWIGTYPE%s->clientdata))->destroy = (swig_chicken_destructor) %s;\n", swigtype_ptr, wname);
-    } else {
-      addMethod(scmname, wname);
-    }
-
-    /* Only export if we are not in a class, or if in a class memberfunction */
-    if (!in_class || member_name) {
-      String *method_def;
-      String *clos_name;
-      if (in_class)
-	clos_name = NewString(member_name);
-      else
-	clos_name = chickenNameMapping(scmname, "");
-
-      if (!any_specialized_arg) {
-	method_def = NewString("");
-	Printv(method_def, "(define ", clos_name, " ", chickenPrimitiveName(scmname), ")", NIL);
-      } else {
-	method_def = buildClosFunctionCall(function_arg_types, clos_name, chickenPrimitiveName(scmname));
-      }
-      Printv(clos_methods, method_def, "\n", NIL);
-      Delete(clos_name);
-      Delete(method_def);
-    }
-
-    if (have_constructor && !has_constructor_args && any_specialized_arg) {
-      has_constructor_args = 1;
-      constructor_arg_types = Copy(function_arg_types);
-    }
-  } else {
-    /* add function_arg_types to overload hash */
-    List *flist = Getattr(overload_parameter_lists, scmname);
-    if (!flist) {
-      flist = NewList();
-      Setattr(overload_parameter_lists, scmname, flist);
-    }
-
-    Append(flist, Copy(function_arg_types));
-
-    if (!Getattr(n, "sym:nextSibling")) {
-      dispatchFunction(n);
-    }
-  }
-
-
-  Delete(wname);
-  Delete(get_pointers);
-  Delete(cleanup);
-  Delete(declfunc);
-  Delete(mangle);
-  Delete(function_arg_types);
-  DelWrapper(f);
-  return SWIG_OK;
-}
-
-int CHICKEN::variableWrapper(Node *n) {
-  char *name = GetChar(n, "name");
-  char *iname = GetChar(n, "sym:name");
-  SwigType *t = Getattr(n, "type");
-  ParmList *l = Getattr(n, "parms");
-
-  String *wname = NewString("");
-  String *mangle = NewString("");
-  String *tm;
-  String *tm2 = NewString("");
-  String *argnum = NewString("0");
-  String *arg = NewString("argv[0]");
-  Wrapper *f;
-  String *overname = 0;
-  String *scmname;
-
-  scmname = NewString(iname);
-  Replaceall(scmname, "_", "-");
-
-  Printf(mangle, "\"%s\"", SwigType_manglestr(t));
-
-  if (Getattr(n, "sym:overloaded")) {
-    overname = Getattr(n, "sym:overname");
-  } else {
-    if (!addSymbol(iname, n))
-      return SWIG_ERROR;
-  }
-
-  f = NewWrapper();
-
-  /* Attach the standard typemaps */
-  emit_attach_parmmaps(l, f);
-  Setattr(n, "wrap:parms", l);
-
-  // evaluation function names
-  Append(wname, Swig_name_wrapper(iname));
-  if (overname) {
-    Append(wname, overname);
-  }
-  Setattr(n, "wrap:name", wname);
-
-  // Check for interrupts
-  Printv(f->code, "C_trace(\"", scmname, "\");\n", NIL);
-
-  if (1 || (SwigType_type(t) != T_USER) || (isPointer(t))) {
-
-    Printv(f->def, "static ", "void ", wname, "(C_word, C_word, C_word, C_word) C_noret;\n", NIL);
-    Printv(f->def, "static " "void ", wname, "(C_word argc, C_word closure, " "C_word continuation, C_word value) {\n", NIL);
-
-    Wrapper_add_local(f, "resultobj", "C_word resultobj");
-
-    Printf(f->code, "if (argc!=2 && argc!=3) C_bad_argc(argc,2);\n");
-
-    /* Check for a setting of the variable value */
-    if (!GetFlag(n, "feature:immutable")) {
-      Printf(f->code, "if (argc > 2) {\n");
-      if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
-	Replaceall(tm, "$source", "value");
-	Replaceall(tm, "$target", name);
-	Replaceall(tm, "$input", "value");
-	/* Printv(f->code, tm, "\n",NIL); */
-	emit_action_code(n, f->code, tm);
-      } else {
-	Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
-      }
-      Printf(f->code, "}\n");
-    }
-
-    String *varname;
-    if (SwigType_istemplate((char *) name)) {
-      varname = SwigType_namestr((char *) name);
-    } else {
-      varname = name;
-    }
-
-    // Now return the value of the variable - regardless
-    // of evaluating or setting.
-    if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
-      Replaceall(tm, "$source", varname);
-      Replaceall(tm, "$varname", varname);
-      Replaceall(tm, "$target", "resultobj");
-      Replaceall(tm, "$result", "resultobj");
-      /* Printf(f->code, "%s\n", tm); */
-      emit_action_code(n, f->code, tm);
-    } else {
-      Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
-    }
-
-    Printv(f->code, "{\n",
-	   "C_word func;\n",
-	   "SWIG_Chicken_FindCreateProxy(func, resultobj)\n",
-	   "if (C_swig_is_closurep(func))\n",
-	   "  ((C_proc4)(void *)C_block_item(func, 0))(4,func,continuation,resultobj,C_SCHEME_FALSE);\n",
-	   "else\n", "  C_kontinue(continuation, resultobj);\n", "}\n", NIL);
-
-    /* Error handling code */
-#ifdef USE_FAIL
-    Printf(f->code, "fail:\n");
-    Printf(f->code, "swig_panic (\"failure in " "'%s' SWIG wrapper\");\n", proc_name);
-#endif
-    Printf(f->code, "}\n");
-
-    Wrapper_print(f, f_wrappers);
-
-    /* Now register the variable with the interpreter.   */
-    addMethod(scmname, wname);
-
-    if (!in_class || member_name) {
-      String *clos_name;
-      if (in_class)
-	clos_name = NewString(member_name);
-      else
-	clos_name = chickenNameMapping(scmname, "");
-
-      Node *class_node = classLookup(t);
-      String *clos_code = Getattr(n, "tmap:varin:closcode");
-      if (class_node && clos_code && !GetFlag(n, "feature:immutable")) {
-	Replaceall(clos_code, "$input", "(car lst)");
-	Printv(clos_methods, "(define (", clos_name, " . lst) (if (null? lst) (", chickenPrimitiveName(scmname), ") (",
-	       chickenPrimitiveName(scmname), " ", clos_code, ")))\n", NIL);
-      } else {
-	/* Simply re-export the procedure */
-	if (GetFlag(n, "feature:immutable") && GetFlag(n, "feature:constasvar")) {
-	  Printv(clos_methods, "(define ", clos_name, " (", chickenPrimitiveName(scmname), "))\n", NIL);
-	  Printv(scm_const_defs, "(set! ", scmname, " (", scmname, "))\n", NIL);
-	} else {
-	  Printv(clos_methods, "(define ", clos_name, " ", chickenPrimitiveName(scmname), ")\n", NIL);
-	}
-      }
-      Delete(clos_name);
-    }
-  } else {
-    Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, "Unsupported variable type %s (ignored).\n", SwigType_str(t, 0));
-  }
-
-  Delete(wname);
-  Delete(argnum);
-  Delete(arg);
-  Delete(tm2);
-  Delete(mangle);
-  DelWrapper(f);
-  return SWIG_OK;
-}
-
-/* ------------------------------------------------------------
- * constantWrapper()
- * ------------------------------------------------------------ */
-
-int CHICKEN::constantWrapper(Node *n) {
-
-  char *name = GetChar(n, "name");
-  char *iname = GetChar(n, "sym:name");
-  SwigType *t = Getattr(n, "type");
-  ParmList *l = Getattr(n, "parms");
-  String *value = Getattr(n, "value");
-
-  String *proc_name = NewString("");
-  String *wname = NewString("");
-  String *mangle = NewString("");
-  String *tm;
-  String *tm2 = NewString("");
-  String *source = NewString("");
-  String *argnum = NewString("0");
-  String *arg = NewString("argv[0]");
-  Wrapper *f;
-  String *overname = 0;
-  String *scmname;
-  String *rvalue;
-  SwigType *nctype;
-
-  scmname = NewString(iname);
-  Replaceall(scmname, "_", "-");
-
-  Printf(source, "swig_const_%s", iname);
-  Replaceall(source, "::", "__");
-
-  Printf(mangle, "\"%s\"", SwigType_manglestr(t));
-
-  if (Getattr(n, "sym:overloaded")) {
-    overname = Getattr(n, "sym:overname");
-  } else {
-    if (!addSymbol(iname, n))
-      return SWIG_ERROR;
-  }
-
-  Append(wname, Swig_name_wrapper(iname));
-  if (overname) {
-    Append(wname, overname);
-  }
-
-  nctype = NewString(t);
-  if (SwigType_isconst(nctype)) {
-    Delete(SwigType_pop(nctype));
-  }
-
-  bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0);
-  if (SwigType_type(nctype) == T_STRING) {
-    rvalue = NewStringf("\"%s\"", value);
-  } else if (SwigType_type(nctype) == T_CHAR && !is_enum_item) {
-    rvalue = NewStringf("\'%s\'", value);
-  } else {
-    rvalue = NewString(value);
-  }
-
-  /* Special hook for member pointer */
-  if (SwigType_type(t) == T_MPOINTER) {
-    Printf(f_header, "static %s = %s;\n", SwigType_str(t, source), rvalue);
-  } else {
-    if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
-      Replaceall(tm, "$source", rvalue);
-      Replaceall(tm, "$target", source);
-      Replaceall(tm, "$result", source);
-      Replaceall(tm, "$value", rvalue);
-      Printf(f_header, "%s\n", tm);
-    } else {
-      Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value.\n");
-      return SWIG_NOWRAP;
-    }
-  }
-
-  f = NewWrapper();
-
-  /* Attach the standard typemaps */
-  emit_attach_parmmaps(l, f);
-  Setattr(n, "wrap:parms", l);
-
-  // evaluation function names
-
-  // Check for interrupts
-  Printv(f->code, "C_trace(\"", scmname, "\");\n", NIL);
-
-  if (1 || (SwigType_type(t) != T_USER) || (isPointer(t))) {
-
-    Setattr(n, "wrap:name", wname);
-    Printv(f->def, "static ", "void ", wname, "(C_word, C_word, C_word) C_noret;\n", NIL);
-
-    Printv(f->def, "static ", "void ", wname, "(C_word argc, C_word closure, " "C_word continuation) {\n", NIL);
-
-    Wrapper_add_local(f, "resultobj", "C_word resultobj");
-
-    Printf(f->code, "if (argc!=2) C_bad_argc(argc,2);\n");
-
-    // Return the value of the variable
-    if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
-
-      Replaceall(tm, "$source", source);
-      Replaceall(tm, "$varname", source);
-      Replaceall(tm, "$target", "resultobj");
-      Replaceall(tm, "$result", "resultobj");
-      /* Printf(f->code, "%s\n", tm); */
-      emit_action_code(n, f->code, tm);
-    } else {
-      Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
-    }
-
-    Printv(f->code, "{\n",
-	   "C_word func;\n",
-	   "SWIG_Chicken_FindCreateProxy(func, resultobj)\n",
-	   "if (C_swig_is_closurep(func))\n",
-	   "  ((C_proc4)(void *)C_block_item(func, 0))(4,func,continuation,resultobj,C_SCHEME_FALSE);\n",
-	   "else\n", "  C_kontinue(continuation, resultobj);\n", "}\n", NIL);
-
-    /* Error handling code */
-#ifdef USE_FAIL
-    Printf(f->code, "fail:\n");
-    Printf(f->code, "swig_panic (\"failure in " "'%s' SWIG wrapper\");\n", proc_name);
-#endif
-    Printf(f->code, "}\n");
-
-    Wrapper_print(f, f_wrappers);
-
-    /* Now register the variable with the interpreter.   */
-    addMethod(scmname, wname);
-
-    if (!in_class || member_name) {
-      String *clos_name;
-      if (in_class)
-	clos_name = NewString(member_name);
-      else
-	clos_name = chickenNameMapping(scmname, "");
-      if (GetFlag(n, "feature:constasvar")) {
-	Printv(clos_methods, "(define ", clos_name, " (", chickenPrimitiveName(scmname), "))\n", NIL);
-	Printv(scm_const_defs, "(set! ", scmname, " (", scmname, "))\n", NIL);
-      } else {
-	Printv(clos_methods, "(define ", clos_name, " ", chickenPrimitiveName(scmname), ")\n", NIL);
-      }
-      Delete(clos_name);
-    }
-
-  } else {
-    Swig_warning(WARN_TYPEMAP_VAR_UNDEF, input_file, line_number, "Unsupported variable type %s (ignored).\n", SwigType_str(t, 0));
-  }
-
-  Delete(wname);
-  Delete(nctype);
-  Delete(proc_name);
-  Delete(argnum);
-  Delete(arg);
-  Delete(tm2);
-  Delete(mangle);
-  Delete(source);
-  Delete(rvalue);
-  DelWrapper(f);
-  return SWIG_OK;
-}
-
-int CHICKEN::classHandler(Node *n) {
-  /* Create new strings for building up a wrapper function */
-  have_constructor = 0;
-  constructor_dispatch = 0;
-  constructor_name = 0;
-
-  c_class_name = NewString(Getattr(n, "sym:name"));
-  class_name = NewString("");
-  short_class_name = NewString("");
-  Printv(class_name, "<", c_class_name, ">", NIL);
-  Printv(short_class_name, c_class_name, NIL);
-  Replaceall(class_name, "_", "-");
-  Replaceall(short_class_name, "_", "-");
-
-  if (!addSymbol(class_name, n))
-    return SWIG_ERROR;
-
-  /* Handle inheritance */
-  String *base_class = NewString("");
-  List *baselist = Getattr(n, "bases");
-  if (baselist && Len(baselist)) {
-    Iterator base = First(baselist);
-    while (base.item) {
-      if (!Getattr(base.item, "feature:ignore"))
-	Printv(base_class, "<", Getattr(base.item, "sym:name"), "> ", NIL);
-      base = Next(base);
-    }
-  }
-
-  Replaceall(base_class, "_", "-");
-
-  String *scmmod = NewString(module);
-  Replaceall(scmmod, "_", "-");
-
-  Printv(clos_class_defines, "(define ", class_name, "\n", "  (make <swig-metaclass-", scmmod, "> 'name \"", short_class_name, "\"\n", NIL);
-  Delete(scmmod);
-
-  if (Len(base_class)) {
-    Printv(clos_class_defines, "    'direct-supers (list ", base_class, ")\n", NIL);
-  } else {
-    Printv(clos_class_defines, "    'direct-supers (list <object>)\n", NIL);
-  }
-
-  Printf(clos_class_defines, "    'direct-slots (list 'swig-this\n");
-
-  String *mangled_classname = Swig_name_mangle(Getattr(n, "sym:name"));
-
-  SwigType *ct = NewStringf("p.%s", Getattr(n, "name"));
-  swigtype_ptr = SwigType_manglestr(ct);
-
-  Printf(f_runtime, "static swig_chicken_clientdata _swig_chicken_clientdata%s = { 0 };\n", mangled_classname);
-  Printv(f_init, "SWIG_TypeClientData(SWIGTYPE", swigtype_ptr, ", (void *) &_swig_chicken_clientdata", mangled_classname, ");\n", NIL);
-  SwigType_remember(ct);
-
-  /* Emit all of the members */
-
-  in_class = 1;
-  Language::classHandler(n);
-  in_class = 0;
-
-  Printf(clos_class_defines, ")))\n\n");
-
-  if (have_constructor) {
-    Printv(clos_methods, "(define-method (initialize (obj ", class_name, ") initargs)\n", "  (swig-initialize obj initargs ", NIL);
-    if (constructor_arg_types) {
-      String *initfunc_name = NewStringf("%s@@SWIG@initmethod", class_name);
-      String *func_call = buildClosFunctionCall(constructor_arg_types, initfunc_name, chickenPrimitiveName(constructor_name));
-      Printf(clos_methods, "%s)\n)\n", initfunc_name);
-      Printf(clos_methods, "(declare (hide %s))\n", initfunc_name);
-      Printf(clos_methods, "%s\n", func_call);
-      Delete(func_call);
-      Delete(initfunc_name);
-      Delete(constructor_arg_types);
-      constructor_arg_types = 0;
-    } else if (constructor_dispatch) {
-      Printf(clos_methods, "%s)\n)\n", constructor_dispatch);
-      Delete(constructor_dispatch);
-      constructor_dispatch = 0;
-    } else {
-      Printf(clos_methods, "%s)\n)\n", chickenPrimitiveName(constructor_name));
-    }
-    Delete(constructor_name);
-    constructor_name = 0;
-  } else {
-    Printv(clos_methods, "(define-method (initialize (obj ", class_name, ") initargs)\n", "  (swig-initialize obj initargs (lambda x #f)))\n", NIL);
-  }
-
-  /* export class initialization function */
-  if (clos) {
-    String *funcname = NewString(mangled_classname);
-    Printf(funcname, "_swig_chicken_setclosclass");
-    String *closfuncname = NewString(funcname);
-    Replaceall(closfuncname, "_", "-");
-
-    Printv(f_wrappers, "static void ", funcname, "(C_word,C_word,C_word,C_word) C_noret;\n",
-	   "static void ", funcname, "(C_word argc, C_word closure, C_word continuation, C_word cl) {\n",
-	   "  C_trace(\"", funcname, "\");\n",
-	   "  if (argc!=3) C_bad_argc(argc,3);\n",
-	   "  swig_chicken_clientdata *cdata = (swig_chicken_clientdata *) SWIGTYPE", swigtype_ptr, "->clientdata;\n",
-	   "  cdata->gc_proxy_create = CHICKEN_new_gc_root();\n",
-	   "  CHICKEN_gc_root_set(cdata->gc_proxy_create, cl);\n", "  C_kontinue(continuation, C_SCHEME_UNDEFINED);\n", "}\n", NIL);
-    addMethod(closfuncname, funcname);
-
-    Printv(clos_methods, "(", chickenPrimitiveName(closfuncname), " (lambda (x lst) (if lst ",
-	   "(cons (make ", class_name, " 'swig-this x) lst) ", "(make ", class_name, " 'swig-this x))))\n\n", NIL);
-    Delete(closfuncname);
-    Delete(funcname);
-  }
-
-  Delete(mangled_classname);
-  Delete(swigtype_ptr);
-  swigtype_ptr = 0;
-
-  Delete(class_name);
-  Delete(short_class_name);
-  Delete(c_class_name);
-  class_name = 0;
-  short_class_name = 0;
-  c_class_name = 0;
-
-  return SWIG_OK;
-}
-
-int CHICKEN::memberfunctionHandler(Node *n) {
-  String *iname = Getattr(n, "sym:name");
-  String *proc = NewString(iname);
-  Replaceall(proc, "_", "-");
-
-  member_name = chickenNameMapping(proc, short_class_name);
-  Language::memberfunctionHandler(n);
-  Delete(member_name);
-  member_name = NULL;
-  Delete(proc);
-
-  return SWIG_OK;
-}
-
-int CHICKEN::staticmemberfunctionHandler(Node *n) {
-  String *iname = Getattr(n, "sym:name");
-  String *proc = NewString(iname);
-  Replaceall(proc, "_", "-");
-
-  member_name = NewStringf("%s-%s", short_class_name, proc);
-  Language::staticmemberfunctionHandler(n);
-  Delete(member_name);
-  member_name = NULL;
-  Delete(proc);
-
-  return SWIG_OK;
-}
-
-int CHICKEN::membervariableHandler(Node *n) {
-  String *iname = Getattr(n, "sym:name");
-  //String *pb = SwigType_typedef_resolve_all(SwigType_base(Getattr(n, "type")));
-
-  Language::membervariableHandler(n);
-
-  String *proc = NewString(iname);
-  Replaceall(proc, "_", "-");
-
-  //Node *class_node = Swig_symbol_clookup(pb, Getattr(n, "sym:symtab"));
-  Node *class_node = classLookup(Getattr(n, "type"));
-
-  //String *getfunc = NewStringf("%s-%s-get", short_class_name, proc);
-  //String *setfunc = NewStringf("%s-%s-set", short_class_name, proc);
-  String *getfunc = Swig_name_get(NSPACE_TODO, Swig_name_member(NSPACE_TODO, c_class_name, iname));
-  Replaceall(getfunc, "_", "-");
-  String *setfunc = Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, c_class_name, iname));
-  Replaceall(setfunc, "_", "-");
-
-  Printv(clos_class_defines, "        (list '", proc, " ':swig-virtual ':swig-get ", chickenPrimitiveName(getfunc), NIL);
-
-  if (!GetFlag(n, "feature:immutable")) {
-    if (class_node) {
-      Printv(clos_class_defines, " ':swig-set (lambda (x y) (", chickenPrimitiveName(setfunc), " x (slot-ref y 'swig-this))))\n", NIL);
-    } else {
-      Printv(clos_class_defines, " ':swig-set ", chickenPrimitiveName(setfunc), ")\n", NIL);
-    }
-  } else {
-    Printf(clos_class_defines, ")\n");
-  }
-
-  Delete(proc);
-  Delete(setfunc);
-  Delete(getfunc);
-  return SWIG_OK;
-}
-
-int CHICKEN::staticmembervariableHandler(Node *n) {
-  String *iname = Getattr(n, "sym:name");
-  String *proc = NewString(iname);
-  Replaceall(proc, "_", "-");
-
-  member_name = NewStringf("%s-%s", short_class_name, proc);
-  Language::staticmembervariableHandler(n);
-  Delete(member_name);
-  member_name = NULL;
-  Delete(proc);
-
-  return SWIG_OK;
-}
-
-int CHICKEN::constructorHandler(Node *n) {
-  have_constructor = 1;
-  has_constructor_args = 0;
-
-
-  exporting_constructor = true;
-  Language::constructorHandler(n);
-  exporting_constructor = false;
-
-  has_constructor_args = 1;
-
-  String *iname = Getattr(n, "sym:name");
-  constructor_name = Swig_name_construct(NSPACE_TODO, iname);
-  Replaceall(constructor_name, "_", "-");
-  return SWIG_OK;
-}
-
-int CHICKEN::destructorHandler(Node *n) {
-
-  if (no_collection)
-    member_name = NewStringf("delete-%s", short_class_name);
-
-  exporting_destructor = true;
-  Language::destructorHandler(n);
-  exporting_destructor = false;
-
-  if (no_collection) {
-    Delete(member_name);
-    member_name = NULL;
-  }
-
-  return SWIG_OK;
-}
-
-int CHICKEN::importDirective(Node *n) {
-  String *modname = Getattr(n, "module");
-  if (modname && clos_uses) {
-
-    // Find the module node for this imported module.  It should be the
-    // first child but search just in case.
-    Node *mod = firstChild(n);
-    while (mod && Strcmp(nodeType(mod), "module") != 0)
-      mod = nextSibling(mod);
-
-    if (mod) {
-      String *name = Getattr(mod, "name");
-      if (name) {
-	Printf(closprefix, "(declare (uses %s))\n", name);
-      }
-    }
-  }
-
-  return Language::importDirective(n);
-}
-
-String *CHICKEN::buildClosFunctionCall(List *types, const_String_or_char_ptr closname, const_String_or_char_ptr funcname) {
-  String *method_signature = NewString("");
-  String *func_args = NewString("");
-  String *func_call = NewString("");
-
-  Iterator arg_type;
-  int arg_count = 0;
-  int optional_arguments = 0;
-
-  for (arg_type = First(types); arg_type.item; arg_type = Next(arg_type)) {
-    if (Strcmp(arg_type.item, "^^##optional$$") == 0) {
-      optional_arguments = 1;
-    } else {
-      Printf(method_signature, " (arg%i %s)", arg_count, arg_type.item);
-      arg_type = Next(arg_type);
-      if (!arg_type.item)
-	break;
-
-      String *arg = NewStringf("arg%i", arg_count);
-      String *access_arg = Copy(arg_type.item);
-
-      Replaceall(access_arg, "$input", arg);
-      Printf(func_args, " %s", access_arg);
-
-      Delete(arg);
-      Delete(access_arg);
-    }
-    arg_count++;
-  }
-
-  if (optional_arguments) {
-    Printf(func_call, "(define-method (%s %s . args) (apply %s %s args))", closname, method_signature, funcname, func_args);
-  } else {
-    Printf(func_call, "(define-method (%s %s) (%s %s))", closname, method_signature, funcname, func_args);
-  }
-
-  Delete(method_signature);
-  Delete(func_args);
-
-  return func_call;
-}
-
-extern "C" {
-
-  /* compares based on non-primitive names */
-  static int compareTypeListsHelper(const DOH *a, const DOH *b, int opt_equal) {
-    List *la = (List *) a;
-    List *lb = (List *) b;
-
-    Iterator ia = First(la);
-    Iterator ib = First(lb);
-
-    while (ia.item && ib.item) {
-      int ret = Strcmp(ia.item, ib.item);
-      if (ret)
-	return ret;
-      ia = Next(Next(ia));
-      ib = Next(Next(ib));
-    } if (opt_equal && ia.item && Strcmp(ia.item, "^^##optional$$") == 0)
-      return 0;
-    if (ia.item)
-      return -1;
-    if (opt_equal && ib.item && Strcmp(ib.item, "^^##optional$$") == 0)
-      return 0;
-    if (ib.item)
-      return 1;
-
-    return 0;
-  }
-
-  static int compareTypeLists(const DOH *a, const DOH *b) {
-    return compareTypeListsHelper(a, b, 0);
-  }
-}
-
-void CHICKEN::dispatchFunction(Node *n) {
-  /* Last node in overloaded chain */
-
-  int maxargs;
-  String *tmp = NewString("");
-  String *dispatch = Swig_overload_dispatch(n, "%s (2+$numargs,closure," "continuation$commaargs);", &maxargs);
-
-  /* Generate a dispatch wrapper for all overloaded functions */
-
-  Wrapper *f = NewWrapper();
-  String *iname = Getattr(n, "sym:name");
-  String *wname = NewString("");
-  String *scmname = NewString(iname);
-  Replaceall(scmname, "_", "-");
-
-  Append(wname, Swig_name_wrapper(iname));
-
-  Printv(f->def, "static void real_", wname, "(C_word, C_word, C_word, C_word) C_noret;\n", NIL);
-
-  Printv(f->def, "static void real_", wname, "(C_word oldargc, C_word closure, C_word continuation, C_word args) {", NIL);
-
-  Wrapper_add_local(f, "argc", "int argc");
-  Printf(tmp, "C_word argv[%d]", maxargs + 1);
-  Wrapper_add_local(f, "argv", tmp);
-  Wrapper_add_local(f, "ii", "int ii");
-  Wrapper_add_local(f, "t", "C_word t = args");
-  Printf(f->code, "if (!C_swig_is_list (args)) {\n");
-  Printf(f->code, "  swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE, " "\"Argument #1 must be a list of overloaded arguments\");\n");
-  Printf(f->code, "}\n");
-  Printf(f->code, "argc = C_unfix (C_i_length (args));\n");
-  Printf(f->code, "for (ii = 0; (ii < argc) && (ii < %d); ii++, t = C_block_item (t, 1)) {\n", maxargs);
-  Printf(f->code, "argv[ii] = C_block_item (t, 0);\n");
-  Printf(f->code, "}\n");
-
-  Printv(f->code, dispatch, "\n", NIL);
-  Printf(f->code, "swig_barf (SWIG_BARF1_BAD_ARGUMENT_TYPE," "\"No matching function for overloaded '%s'\");\n", iname);
-  Printv(f->code, "}\n", NIL);
-  Wrapper_print(f, f_wrappers);
-  addMethod(scmname, wname);
-
-  DelWrapper(f);
-  f = NewWrapper();
-
-  /* varargs */
-  Printv(f->def, "void ", wname, "(C_word, C_word, C_word, ...) C_noret;\n", NIL);
-  Printv(f->def, "void ", wname, "(C_word c, C_word t0, C_word t1, ...) {", NIL);
-  Printv(f->code,
-	 "C_word t2;\n",
-	 "va_list v;\n",
-	 "C_word *a, c2 = c;\n",
-	 "C_save_rest (t1, c2, 2);\n", "a = C_alloc((c-2)*3);\n", "t2 = C_restore_rest (a, C_rest_count (0));\n", "real_", wname, " (3, t0, t1, t2);\n", NIL);
-  Printv(f->code, "}\n", NIL);
-  Wrapper_print(f, f_wrappers);
-
-  /* Now deal with overloaded function when exporting clos */
-  if (clos) {
-    List *flist = Getattr(overload_parameter_lists, scmname);
-    if (flist) {
-      Delattr(overload_parameter_lists, scmname);
-
-      SortList(flist, compareTypeLists);
-
-      String *clos_name;
-      if (have_constructor && !has_constructor_args) {
-	has_constructor_args = 1;
-	constructor_dispatch = NewStringf("%s@SWIG@new@dispatch", short_class_name);
-	clos_name = Copy(constructor_dispatch);
-	Printf(clos_methods, "(declare (hide %s))\n", clos_name);
-      } else if (in_class)
-	clos_name = NewString(member_name);
-      else
-	clos_name = chickenNameMapping(scmname, "");
-
-      Iterator f;
-      List *prev = 0;
-      int all_primitive = 1;
-
-      /* first check for duplicates and an empty call */
-      String *newlist = NewList();
-      for (f = First(flist); f.item; f = Next(f)) {
-	/* check if cur is a duplicate of prev */
-	if (prev && compareTypeListsHelper(f.item, prev, 1) == 0) {
-	  Delete(f.item);
-	} else {
-	  Append(newlist, f.item);
-	  prev = f.item;
-	  Iterator j;
-	  for (j = First(f.item); j.item; j = Next(j)) {
-	    if (Strcmp(j.item, "^^##optional$$") != 0 && Strcmp(j.item, "<top>") != 0)
-	      all_primitive = 0;
-	  }
-	}
-      }
-      Delete(flist);
-      flist = newlist;
-
-      if (all_primitive) {
-	Printf(clos_methods, "(define %s %s)\n", clos_name, chickenPrimitiveName(scmname));
-      } else {
-	for (f = First(flist); f.item; f = Next(f)) {
-	  /* now export clos code for argument */
-	  String *func_call = buildClosFunctionCall(f.item, clos_name, chickenPrimitiveName(scmname));
-	  Printf(clos_methods, "%s\n", func_call);
-	  Delete(f.item);
-	  Delete(func_call);
-	}
-      }
-
-      Delete(clos_name);
-      Delete(flist);
-    }
-  }
-
-  DelWrapper(f);
-  Delete(dispatch);
-  Delete(tmp);
-  Delete(wname);
-}
-
-int CHICKEN::isPointer(SwigType *t) {
-  return SwigType_ispointer(SwigType_typedef_resolve_all(t));
-}
-
-void CHICKEN::addMethod(String *scheme_name, String *function) {
-  String *sym = NewString("");
-  if (clos) {
-    Append(sym, "primitive:");
-  }
-  Append(sym, scheme_name);
-
-  /* add symbol to Chicken internal symbol table */
-  if (hide_primitive) {
-    Printv(f_init, "{\n",
-	   "  C_word *p0 = a;\n", "  *(a++)=C_CLOSURE_TYPE|1;\n", "  *(a++)=(C_word)", function, ";\n", "  C_mutate(return_vec++, (C_word)p0);\n", "}\n", NIL);
-  } else {
-    Printf(f_sym_size, "+C_SIZEOF_INTERNED_SYMBOL(%d)", Len(sym));
-    Printf(f_init, "sym = C_intern (&a, %d, \"%s\");\n", Len(sym), sym);
-    Printv(f_init, "C_mutate ((C_word*)sym+1, (*a=C_CLOSURE_TYPE|1, a[1]=(C_word)", function, ", tmp=(C_word)a, a+=2, tmp));\n", NIL);
-  }
-
-  if (hide_primitive) {
-    Setattr(primitive_names, scheme_name, NewStringf("(vector-ref swig-init-return %i)", num_methods));
-  } else {
-    Setattr(primitive_names, scheme_name, Copy(sym));
-  }
-
-  num_methods++;
-
-  Delete(sym);
-}
-
-String *CHICKEN::chickenPrimitiveName(String *name) {
-  String *value = Getattr(primitive_names, name);
-  if (value)
-    return value;
-  else {
-    Swig_error(input_file, line_number, "Internal Error: attempting to reference non-existent primitive name %s\n", name);
-    return NewString("#f");
-  }
-}
-
-int CHICKEN::validIdentifier(String *s) {
-  char *c = Char(s);
-  /* Check whether we have an R5RS identifier. */
-  /* <identifier> --> <initial> <subsequent>* | <peculiar identifier> */
-  /* <initial> --> <letter> | <special initial> */
-  if (!(isalpha(*c) || (*c == '!') || (*c == '$') || (*c == '%')
-	|| (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
-	|| (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
-	|| (*c == '^') || (*c == '_') || (*c == '~'))) {
-    /* <peculiar identifier> --> + | - | ... */
-    if ((strcmp(c, "+") == 0)
-	|| strcmp(c, "-") == 0 || strcmp(c, "...") == 0)
-      return 1;
-    else
-      return 0;
-  }
-  /* <subsequent> --> <initial> | <digit> | <special subsequent> */
-  while (*c) {
-    if (!(isalnum(*c) || (*c == '!') || (*c == '$') || (*c == '%')
-	  || (*c == '&') || (*c == '*') || (*c == '/') || (*c == ':')
-	  || (*c == '<') || (*c == '=') || (*c == '>') || (*c == '?')
-	  || (*c == '^') || (*c == '_') || (*c == '~') || (*c == '+')
-	  || (*c == '-') || (*c == '.') || (*c == '@')))
-      return 0;
-    c++;
-  }
-  return 1;
-}
-
-  /* ------------------------------------------------------------
-   * closNameMapping()
-   * Maps the identifier from C++ to the CLOS based on command 
-   * line parameters and such.
-   * If class_name = "" that means the mapping is for a function or
-   * variable not attached to any class.
-   * ------------------------------------------------------------ */
-String *CHICKEN::chickenNameMapping(String *name, const_String_or_char_ptr class_name) {
-  String *n = NewString("");
-
-  if (Strcmp(class_name, "") == 0) {
-    // not part of a class, so no class name to prefix
-    if (clossymnameprefix) {
-      Printf(n, "%s%s", clossymnameprefix, name);
-    } else {
-      Printf(n, "%s", name);
-    }
-  } else {
-    if (useclassprefix) {
-      Printf(n, "%s-%s", class_name, name);
-    } else {
-      if (clossymnameprefix) {
-	Printf(n, "%s%s", clossymnameprefix, name);
-      } else {
-	Printf(n, "%s", name);
-      }
-    }
-  }
-  return n;
-}
-
-String *CHICKEN::runtimeCode() {
-  String *s = Swig_include_sys("chickenrun.swg");
-  if (!s) {
-    Printf(stderr, "*** Unable to open 'chickenrun.swg'\n");
-    s = NewString("");
-  }
-  return s;
-}
-
-String *CHICKEN::defaultExternalRuntimeFilename() {
-  return NewString("swigchickenrun.h");
-}
diff --git a/Source/Modules/clisp.cxx b/Source/Modules/clisp.cxx
deleted file mode 100644
index d7f1971..0000000
--- a/Source/Modules/clisp.cxx
+++ /dev/null
@@ -1,515 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3 
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
- *
- * clisp.cxx
- *
- * clisp language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-
-static const char *usage = "\
-CLISP Options (available with -clisp)\n\
-     -extern-all       - Create clisp definitions for all the functions and\n\
-                         global variables otherwise only definitions for\n\
-                         externed functions and variables are created.\n\
-     -generate-typedef - Use def-c-type to generate shortcuts according to the\n\
-                         typedefs in the input.\n\
-";
-
-class CLISP:public Language {
-public:
-  File *f_cl;
-  String *module;
-  virtual void main(int argc, char *argv[]);
-  virtual int top(Node *n);
-  virtual int functionWrapper(Node *n);
-  virtual int variableWrapper(Node *n);
-  virtual int constantWrapper(Node *n);
-  virtual int classDeclaration(Node *n);
-  virtual int enumDeclaration(Node *n);
-  virtual int typedefHandler(Node *n);
-  List *entries;
-private:
-  String *get_ffi_type(Node *n, SwigType *ty);
-  String *convert_literal(String *num_param, String *type);
-  String *strip_parens(String *string);
-  int extern_all_flag;
-  int generate_typedef_flag;
-  int is_function;
-};
-
-void CLISP::main(int argc, char *argv[]) {
-  int i;
-
-  Preprocessor_define("SWIGCLISP 1", 0);
-  SWIG_library_directory("clisp");
-  SWIG_config_file("clisp.swg");
-  generate_typedef_flag = 0;
-  extern_all_flag = 0;
-
-  for (i = 1; i < argc; i++) {
-    if (!strcmp(argv[i], "-help")) {
-      Printf(stdout, "%s\n", usage);
-    } else if ((Strcmp(argv[i], "-extern-all") == 0)) {
-      extern_all_flag = 1;
-      Swig_mark_arg(i);
-    } else if ((Strcmp(argv[i], "-generate-typedef") == 0)) {
-      generate_typedef_flag = 1;
-      Swig_mark_arg(i);
-    }
-  }
-}
-
-int CLISP::top(Node *n) {
-
-  File *f_null = NewString("");
-  module = Getattr(n, "name");
-  String *output_filename;
-  entries = NewList();
-
-  /* Get the output file name */
-  String *outfile = Getattr(n, "outfile");
-
-  if (!outfile) {
-    Printf(stderr, "Unable to determine outfile\n");
-    SWIG_exit(EXIT_FAILURE);
-  }
-
-  output_filename = NewStringf("%s%s.lisp", SWIG_output_directory(), module);
-
-  f_cl = NewFile(output_filename, "w+", SWIG_output_files());
-  if (!f_cl) {
-    FileErrorDisplay(output_filename);
-    SWIG_exit(EXIT_FAILURE);
-  }
-
-  Swig_register_filebyname("header", f_null);
-  Swig_register_filebyname("begin", f_null);
-  Swig_register_filebyname("runtime", f_null);
-  Swig_register_filebyname("wrapper", f_null);
-
-  String *header = NewString("");
-
-  Swig_banner_target_lang(header, ";;");
-
-  Printf(header, "\n(defpackage :%s\n  (:use :common-lisp :ffi)", module);
-
-  Language::top(n);
-
-  Iterator i;
-
-  long len = Len(entries);
-  if (len > 0) {
-    Printf(header, "\n  (:export");
-  }
-  //else nothing to export
-
-  for (i = First(entries); i.item; i = Next(i)) {
-    Printf(header, "\n\t:%s", i.item);
-  }
-
-  if (len > 0) {
-    Printf(header, ")");
-  }
-
-  Printf(header, ")\n");
-  Printf(header, "\n(in-package :%s)\n", module);
-  Printf(header, "\n(default-foreign-language :stdc)\n");
-
-  len = Tell(f_cl);
-
-  Printf(f_cl, "%s", header);
-
-  long end = Tell(f_cl);
-
-  for (len--; len >= 0; len--) {
-    end--;
-    (void)Seek(f_cl, len, SEEK_SET);
-    int ch = Getc(f_cl);
-    (void)Seek(f_cl, end, SEEK_SET);
-    Putc(ch, f_cl);
-  }
-
-  Seek(f_cl, 0, SEEK_SET);
-  Write(f_cl, Char(header), Len(header));
-
-  Delete(f_cl);
-
-  return SWIG_OK;
-}
-
-
-int CLISP::functionWrapper(Node *n) {
-  is_function = 1;
-  String *storage = Getattr(n, "storage");
-  if (!extern_all_flag && (!storage || (!Swig_storage_isextern(n) && !Swig_storage_isexternc(n))))
-    return SWIG_OK;
-
-  String *func_name = Getattr(n, "sym:name");
-
-  ParmList *pl = Getattr(n, "parms");
-
-  int argnum = 0, first = 1;
-
-  Printf(f_cl, "\n(ffi:def-call-out %s\n\t(:name \"%s\")\n", func_name, func_name);
-
-  Append(entries, func_name);
-
-  if (ParmList_len(pl) != 0) {
-    Printf(f_cl, "\t(:arguments ");
-  }
-  for (Parm *p = pl; p; p = nextSibling(p), argnum++) {
-
-    String *argname = Getattr(p, "name");
-    //    SwigType *argtype;
-
-    String *ffitype = get_ffi_type(n, Getattr(p, "type"));
-
-    int tempargname = 0;
-
-    if (!argname) {
-      argname = NewStringf("arg%d", argnum);
-      tempargname = 1;
-    }
-
-    if (!first) {
-      Printf(f_cl, "\n\t\t");
-    }
-    Printf(f_cl, "(%s %s)", argname, ffitype);
-    first = 0;
-
-    Delete(ffitype);
-
-    if (tempargname)
-      Delete(argname);
-  }
-  if (ParmList_len(pl) != 0) {
-    Printf(f_cl, ")\n");	/* finish arg list */
-  }
-  String *ffitype = get_ffi_type(n, Getattr(n, "type"));
-  if (Strcmp(ffitype, "NIL")) {	//when return type is not nil
-    Printf(f_cl, "\t(:return-type %s)\n", ffitype);
-  }
-  Printf(f_cl, "\t(:library +library-name+))\n");
-
-  return SWIG_OK;
-}
-
-
-int CLISP::constantWrapper(Node *n) {
-  is_function = 0;
-  String *type = Getattr(n, "type");
-  String *converted_value = convert_literal(Getattr(n, "value"), type);
-  String *name = Getattr(n, "sym:name");
-
-  Printf(f_cl, "\n(defconstant %s %s)\n", name, converted_value);
-  Append(entries, name);
-  Delete(converted_value);
-
-  return SWIG_OK;
-}
-
-int CLISP::variableWrapper(Node *n) {
-  is_function = 0;
-  String *storage = Getattr(n, "storage");
-
-  if (!extern_all_flag && (!storage || (!Swig_storage_isextern(n) && !Swig_storage_isexternc(n))))
-    return SWIG_OK;
-
-  String *var_name = Getattr(n, "sym:name");
-  String *lisp_type = get_ffi_type(n, Getattr(n, "type"));
-  Printf(f_cl, "\n(ffi:def-c-var %s\n (:name \"%s\")\n (:type %s)\n", var_name, var_name, lisp_type);
-  Printf(f_cl, "\t(:library +library-name+))\n");
-  Append(entries, var_name);
-
-  Delete(lisp_type);
-  return SWIG_OK;
-}
-
-int CLISP::typedefHandler(Node *n) {
-  if (generate_typedef_flag) {
-    is_function = 0;
-    Printf(f_cl, "\n(ffi:def-c-type %s %s)\n", Getattr(n, "name"), get_ffi_type(n, Getattr(n, "type")));
-  }
-
-  return Language::typedefHandler(n);
-}
-
-int CLISP::enumDeclaration(Node *n) {
-  if (getCurrentClass() && (cplus_mode != PUBLIC))
-    return SWIG_NOWRAP;
-
-  is_function = 0;
-  String *name = Getattr(n, "sym:name");
-
-  Printf(f_cl, "\n(ffi:def-c-enum %s ", name);
-
-  for (Node *c = firstChild(n); c; c = nextSibling(c)) {
-
-    String *slot_name = Getattr(c, "name");
-    String *value = Getattr(c, "enumvalue");
-
-    Printf(f_cl, "(%s %s)", slot_name, value);
-
-    Append(entries, slot_name);
-
-    Delete(value);
-  }
-
-  Printf(f_cl, ")\n");
-  return SWIG_OK;
-}
-
-
-// Includes structs
-int CLISP::classDeclaration(Node *n) {
-  is_function = 0;
-  String *name = Getattr(n, "sym:name");
-  String *kind = Getattr(n, "kind");
-
-  if (Strcmp(kind, "struct")) {
-    Printf(stderr, "Don't know how to deal with %s kind of class yet.\n", kind);
-    Printf(stderr, " (name: %s)\n", name);
-    SWIG_exit(EXIT_FAILURE);
-  }
-
-
-  Printf(f_cl, "\n(ffi:def-c-struct %s", name);
-
-  Append(entries, NewStringf("make-%s", name));
-
-  for (Node *c = firstChild(n); c; c = nextSibling(c)) {
-
-    if (Strcmp(nodeType(c), "cdecl")) {
-      Printf(stderr, "Structure %s has a slot that we can't deal with.\n", name);
-      Printf(stderr, "nodeType: %s, name: %s, type: %s\n", nodeType(c), Getattr(c, "name"), Getattr(c, "type"));
-      SWIG_exit(EXIT_FAILURE);
-    }
-
-    String *temp = Copy(Getattr(c, "decl"));
-    if (temp) {
-      Append(temp, Getattr(c, "type"));	//appending type to the end, otherwise wrong type
-      String *lisp_type = get_ffi_type(n, temp);
-      Delete(temp);
-
-      String *slot_name = Getattr(c, "sym:name");
-      Printf(f_cl, "\n\t(%s %s)", slot_name, lisp_type);
-
-      Append(entries, NewStringf("%s-%s", name, slot_name));
-
-      Delete(lisp_type);
-    }
-  }
-
-  Printf(f_cl, ")\n");
-
-  /* Add this structure to the known lisp types */
-  //Printf(stdout, "Adding %s foreign type\n", name);
-  //  add_defined_foreign_type(name);
-
-  return SWIG_OK;
-}
-
-/* utilities */
-/* returns new string w/ parens stripped */
-String *CLISP::strip_parens(String *string) {
-  char *s = Char(string), *p;
-  int len = Len(string);
-  String *res;
-
-  if (len == 0 || s[0] != '(' || s[len - 1] != ')') {
-    return NewString(string);
-  }
-
-  p = (char *) malloc(len - 2 + 1);
-  if (!p) {
-    Printf(stderr, "Malloc failed\n");
-    SWIG_exit(EXIT_FAILURE);
-  }
-
-  strncpy(p, s + 1, len - 1);
-  p[len - 2] = 0;		/* null terminate */
-
-  res = NewString(p);
-  free(p);
-
-  return res;
-}
-
-String *CLISP::convert_literal(String *num_param, String *type) {
-  String *num = strip_parens(num_param), *res;
-  char *s = Char(num);
-
-  /* Make sure doubles use 'd' instead of 'e' */
-  if (!Strcmp(type, "double")) {
-    String *updated = Copy(num);
-    if (Replace(updated, "e", "d", DOH_REPLACE_ANY) > 1) {
-      Printf(stderr, "Weird!! number %s looks invalid.\n", num);
-      SWIG_exit(EXIT_FAILURE);
-    }
-    Delete(num);
-    return updated;
-  }
-
-  if (SwigType_type(type) == T_CHAR) {
-    /* Use CL syntax for character literals */
-    return NewStringf("#\\%s", num_param);
-  } else if (SwigType_type(type) == T_STRING) {
-    /* Use CL syntax for string literals */
-    return NewStringf("\"%s\"", num_param);
-  }
-
-  if (Len(num) < 2 || s[0] != '0') {
-    return num;
-  }
-
-  /* octal or hex */
-
-  res = NewStringf("#%c%s", s[1] == 'x' ? 'x' : 'o', s + 2);
-  Delete(num);
-
-  return res;
-}
-
-String *CLISP::get_ffi_type(Node *n, SwigType *ty) {
-  Node *node = NewHash();
-  Setattr(node, "type", ty);
-  Setfile(node, Getfile(n));
-  Setline(node, Getline(n));
-  const String *tm = Swig_typemap_lookup("in", node, "", 0);
-  Delete(node);
-
-  if (tm) {
-    return NewString(tm);
-  } else if (SwigType_ispointer(ty)) {
-    SwigType *cp = Copy(ty);
-    SwigType_del_pointer(cp);
-    String *inner_type = get_ffi_type(n, cp);
-
-    if (SwigType_isfunction(cp)) {
-      return inner_type;
-    }
-
-    SwigType *base = SwigType_base(ty);
-    String *base_name = SwigType_str(base, 0);
-
-    String *str;
-    if (!Strcmp(base_name, "int") || !Strcmp(base_name, "float") || !Strcmp(base_name, "short")
-	|| !Strcmp(base_name, "double") || !Strcmp(base_name, "long") || !Strcmp(base_name, "char")) {
-
-      str = NewStringf("(ffi:c-ptr %s)", inner_type);
-    } else {
-      str = NewStringf("(ffi:c-pointer %s)", inner_type);
-    }
-    Delete(base_name);
-    Delete(base);
-    Delete(cp);
-    Delete(inner_type);
-    return str;
-  } else if (SwigType_isarray(ty)) {
-    SwigType *cp = Copy(ty);
-    String *array_dim = SwigType_array_getdim(ty, 0);
-
-    if (!Strcmp(array_dim, "")) {	//dimension less array convert to pointer
-      Delete(array_dim);
-      SwigType_del_array(cp);
-      SwigType_add_pointer(cp);
-      String *str = get_ffi_type(n, cp);
-      Delete(cp);
-      return str;
-    } else {
-      SwigType_pop_arrays(cp);
-      String *inner_type = get_ffi_type(n, cp);
-      Delete(cp);
-
-      int ndim = SwigType_array_ndim(ty);
-      String *dimension;
-      if (ndim == 1) {
-	dimension = array_dim;
-      } else {
-	dimension = array_dim;
-	for (int i = 1; i < ndim; i++) {
-	  array_dim = SwigType_array_getdim(ty, i);
-	  Append(dimension, " ");
-	  Append(dimension, array_dim);
-	  Delete(array_dim);
-	}
-	String *temp = dimension;
-	dimension = NewStringf("(%s)", dimension);
-	Delete(temp);
-      }
-      String *str;
-      if (is_function)
-	str = NewStringf("(ffi:c-ptr (ffi:c-array %s %s))", inner_type, dimension);
-      else
-	str = NewStringf("(ffi:c-array %s %s)", inner_type, dimension);
-
-      Delete(inner_type);
-      Delete(dimension);
-      return str;
-    }
-  } else if (SwigType_isfunction(ty)) {
-    SwigType *cp = Copy(ty);
-    SwigType *fn = SwigType_pop_function(cp);
-    String *args = NewString("");
-    ParmList *pl = SwigType_function_parms(fn, n);
-    if (ParmList_len(pl) != 0) {
-      Printf(args, "(:arguments ");
-    }
-    int argnum = 0, first = 1;
-    for (Parm *p = pl; p; p = nextSibling(p), argnum++) {
-      String *argname = Getattr(p, "name");
-      SwigType *argtype = Getattr(p, "type");
-      String *ffitype = get_ffi_type(n, argtype);
-
-      int tempargname = 0;
-
-      if (!argname) {
-	argname = NewStringf("arg%d", argnum);
-	tempargname = 1;
-      }
-      if (!first) {
-	Printf(args, "\n\t\t");
-      }
-      Printf(args, "(%s %s)", argname, ffitype);
-      first = 0;
-      Delete(ffitype);
-      if (tempargname)
-	Delete(argname);
-    }
-    if (ParmList_len(pl) != 0) {
-      Printf(args, ")\n");	/* finish arg list */
-    }
-    String *ffitype = get_ffi_type(n, cp);
-    String *str = NewStringf("(ffi:c-function %s \t\t\t\t(:return-type %s))", args, ffitype);
-    Delete(fn);
-    Delete(args);
-    Delete(cp);
-    Delete(ffitype);
-    return str;
-  }
-  String *str = SwigType_str(ty, 0);
-  if (str) {
-    char *st = Strstr(str, "struct");
-    if (st) {
-      st += 7;
-      return NewString(st);
-    }
-    char *cl = Strstr(str, "class");
-    if (cl) {
-      cl += 6;
-      return NewString(cl);
-    }
-  }
-  return str;
-}
-
-extern "C" Language *swig_clisp(void) {
-  return new CLISP();
-}
diff --git a/Source/Modules/contract.cxx b/Source/Modules/contract.cxx
index 7e0eaf9..dfc85eb 100644
--- a/Source/Modules/contract.cxx
+++ b/Source/Modules/contract.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * contract.cxx
  *
diff --git a/Source/Modules/csharp.cxx b/Source/Modules/csharp.cxx
index 17100b3..b0103f3 100644
--- a/Source/Modules/csharp.cxx
+++ b/Source/Modules/csharp.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * csharp.cxx
  *
@@ -12,8 +12,8 @@
  * ----------------------------------------------------------------------------- */
 
 #include "swigmod.h"
-#include <limits.h>		// for INT_MAX
 #include "cparse.h"
+#include <limits.h>		// for INT_MAX
 #include <ctype.h>
 
 /* Hash type used for upcalls from C/C++ */
@@ -59,6 +59,7 @@
   String *variable_name;	//Name of a variable being wrapped
   String *proxy_class_constants_code;
   String *module_class_constants_code;
+  String *common_begin_code;
   String *enum_code;
   String *dllimport;		// DllImport attribute name
   String *namespce;		// Optional namespace name
@@ -134,6 +135,7 @@
       variable_name(NULL),
       proxy_class_constants_code(NULL),
       module_class_constants_code(NULL),
+      common_begin_code(NULL),
       enum_code(NULL),
       dllimport(NULL),
       namespce(NULL),
@@ -166,7 +168,7 @@
     /* for now, multiple inheritance in directors is disabled, this
        should be easy to implement though */
     director_multiple_inheritance = 0;
-    director_language = 1;
+    directorLanguage();
   }
 
   /* -----------------------------------------------------------------------------
@@ -288,7 +290,8 @@
   virtual int top(Node *n) {
 
     // Get any options set in the module directive
-    Node *optionsnode = Getattr(Getattr(n, "module"), "options");
+    Node *module = Getattr(n, "module");
+    Node *optionsnode = Getattr(module, "options");
 
     if (optionsnode) {
       if (Getattr(optionsnode, "imclassname"))
@@ -308,6 +311,9 @@
 	allow_dirprot();
       }
       allow_allprotected(GetFlag(optionsnode, "allprotected"));
+      common_begin_code = Getattr(optionsnode, "csbegin");
+      if (common_begin_code)
+	Printf(common_begin_code, "\n");
     }
 
     /* Initialize all of the output files */
@@ -316,24 +322,24 @@
 
     if (!outfile) {
       Printf(stderr, "Unable to determine outfile\n");
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
 
     f_begin = NewFile(outfile, "w", SWIG_output_files());
     if (!f_begin) {
       FileErrorDisplay(outfile);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       if (!outfile_h) {
         Printf(stderr, "Unable to determine outfile_h\n");
-        SWIG_exit(EXIT_FAILURE);
+        Exit(EXIT_FAILURE);
       }
       f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
       if (!f_runtime_h) {
 	FileErrorDisplay(outfile_h);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
     }
 
@@ -369,9 +375,9 @@
     }
 
     // module class and intermediary classes are always created
-    if (!addSymbol(imclass_name, n))
+    if (!addSymbol(imclass_name, module))
       return SWIG_ERROR;
-    if (!addSymbol(module_class_name, n))
+    if (!addSymbol(module_class_name, module))
       return SWIG_ERROR;
 
     imclass_class_code = NewString("");
@@ -399,9 +405,9 @@
 
     Swig_banner(f_begin);
 
-    Printf(f_runtime, "\n\n#ifndef SWIGCSHARP\n#define SWIGCSHARP\n#endif\n\n");
+    Swig_obligatory_macros(f_runtime, "CSHARP");
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Printf(f_runtime, "#define SWIG_DIRECTORS\n");
 
       /* Emit initial director header and director code: */
@@ -444,7 +450,7 @@
     /* Emit code */
     Language::top(n);
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       // Insert director runtime into the f_runtime file (make it occur before %header section)
       Swig_insert_file("director_common.swg", f_runtime);
       Swig_insert_file("director.swg", f_runtime);
@@ -608,7 +614,7 @@
     Dump(f_runtime, f_begin);
     Dump(f_header, f_begin);
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Dump(f_directors, f_begin);
       Dump(f_directors_h, f_runtime_h);
 
@@ -649,6 +655,7 @@
     Printf(f, "//\n");
     Swig_banner_target_lang(f, "//");
     Printf(f, "//------------------------------------------------------------------------------\n\n");
+    Printv(f, common_begin_code, NIL);
   }
 
   /* -----------------------------------------------------------------------------
@@ -670,7 +677,7 @@
 	f_single_out = NewFile(filen, "w", SWIG_output_files());
 	if (!f_single_out) {
 	  FileErrorDisplay(filen);
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	}
 	Append(filenames_list, Copy(filen));
 	Delete(filen);
@@ -684,7 +691,7 @@
       File *f = NewFile(filen, "w", SWIG_output_files());
       if (!f) {
 	FileErrorDisplay(filen);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       Append(filenames_list, Copy(filen));
       Delete(filen);
@@ -901,8 +908,6 @@
       // Get typemap for this argument
       if ((tm = Getattr(p, "tmap:in"))) {
 	canThrow(n, "in", p);
-	Replaceall(tm, "$source", arg);	/* deprecated */
-	Replaceall(tm, "$target", ln);	/* deprecated */
 	Replaceall(tm, "$arg", arg);	/* deprecated? */
 	Replaceall(tm, "$input", arg);
 	Setattr(p, "emit:input", arg);
@@ -921,7 +926,6 @@
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:check"))) {
 	canThrow(n, "check", p);
-	Replaceall(tm, "$target", Getattr(p, "lname"));	/* deprecated */
 	Replaceall(tm, "$arg", Getattr(p, "emit:input"));	/* deprecated? */
 	Replaceall(tm, "$input", Getattr(p, "emit:input"));
 	Printv(f->code, tm, "\n", NIL);
@@ -935,7 +939,6 @@
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:freearg"))) {
 	canThrow(n, "freearg", p);
-	Replaceall(tm, "$source", Getattr(p, "emit:input"));	/* deprecated */
 	Replaceall(tm, "$arg", Getattr(p, "emit:input"));	/* deprecated? */
 	Replaceall(tm, "$input", Getattr(p, "emit:input"));
 	Printv(cleanup, tm, "\n", NIL);
@@ -949,8 +952,6 @@
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:argout"))) {
 	canThrow(n, "argout", p);
-	Replaceall(tm, "$source", Getattr(p, "emit:input"));	/* deprecated */
-	Replaceall(tm, "$target", Getattr(p, "lname"));	/* deprecated */
 	Replaceall(tm, "$arg", Getattr(p, "emit:input"));	/* deprecated? */
 	Replaceall(tm, "$result", "jresult");
 	Replaceall(tm, "$input", Getattr(p, "emit:input"));
@@ -982,8 +983,6 @@
       /* Return value if necessary  */
       if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
 	canThrow(n, "out", n);
-	Replaceall(tm, "$source", Swig_cresult_name());	/* deprecated */
-	Replaceall(tm, "$target", "jresult");	/* deprecated */
 	Replaceall(tm, "$result", "jresult");
 
         if (GetFlag(n, "feature:new"))
@@ -1011,7 +1010,6 @@
     if (GetFlag(n, "feature:new")) {
       if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
 	canThrow(n, "newfree", n);
-	Replaceall(tm, "$source", Swig_cresult_name());	/* deprecated */
 	Printf(f->code, "%s\n", tm);
       }
     }
@@ -1020,7 +1018,6 @@
     if (!native_function_flag) {
       if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
 	canThrow(n, "ret", n);
-	Replaceall(tm, "$source", Swig_cresult_name());	/* deprecated */
 	Printf(f->code, "%s\n", tm);
       }
     }
@@ -1180,6 +1177,58 @@
 	return SWIG_NOWRAP;
 
       String *nspace = Getattr(n, "sym:nspace"); // NSpace/getNSpace() only works during Language::enumDeclaration call
+      enum_code = NewString("");
+      String *symname = Getattr(n, "sym:name");
+      String *constants_code = (proxy_flag && is_wrapping_class())? proxy_class_constants_code : module_class_constants_code;
+      EnumFeature enum_feature = decodeEnumFeature(n);
+      String *typemap_lookup_type = Getattr(n, "name");
+
+      if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
+	// Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper C# enum
+
+	String *scope = getCurrentScopeName(nspace);
+	if (!addSymbol(symname, n, scope))
+	  return SWIG_ERROR;
+
+	// Enum base (underlying enum type)
+	Node *attributes = NewHash();
+	const String *pure_baseclass = typemapLookup(n, "csbase", typemap_lookup_type, WARN_NONE, attributes);
+	bool purebase_replace = GetFlag(attributes, "tmap:csbase:replace") ? true : false;
+	Delete(attributes);
+
+	const String *baseclass = NULL;
+	if (!purebase_replace) {
+	  String *underlying_enum_type = Getattr(n, "enumbase");
+	  if (underlying_enum_type) {
+	    baseclass = typemapLookup(n, "cstype", underlying_enum_type, WARN_CSHARP_TYPEMAP_CSWTYPE_UNDEF);
+	  }
+	}
+
+	const String *wanted_base = baseclass ? baseclass : pure_baseclass;
+
+	if (purebase_replace) {
+	  wanted_base = pure_baseclass;
+	} else if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) {
+	  Swig_warning(WARN_CSHARP_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
+		       "Warning for %s, enum base %s ignored. Multiple enum bases is not supported in C# enums. "
+		       "Perhaps you need the 'replace' attribute in the csbase typemap?\n", typemap_lookup_type, pure_baseclass);
+	}
+
+	// Class attributes
+	const String *csattributes = typemapLookup(n, "csattributes", typemap_lookup_type, WARN_NONE);
+	if (csattributes && *Char(csattributes))
+	  Printf(enum_code, "%s\n", csattributes);
+
+	// Emit the enum
+	Printv(enum_code, typemapLookup(n, "csclassmodifiers", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF),	// Class modifiers (enum modifiers really)
+	       " ", symname, *Char(wanted_base) ? " : " : "", wanted_base, " {\n", NIL);
+	Delete(scope);
+      } else {
+	// Wrap C++ enum with integers - just indicate start of enum with a comment, no comment for anonymous enums of any sort
+	if (symname && !Getattr(n, "unnamedinstance"))
+	  Printf(constants_code, "  // %s \n", symname);
+      }
+
       if (proxy_flag && !is_wrapping_class()) {
 	// Global enums / enums in a namespace
 	assert(!full_imclass_name);
@@ -1195,42 +1244,14 @@
 	}
       }
 
-      enum_code = NewString("");
-      String *symname = Getattr(n, "sym:name");
-      String *constants_code = (proxy_flag && is_wrapping_class())? proxy_class_constants_code : module_class_constants_code;
-      EnumFeature enum_feature = decodeEnumFeature(n);
-      String *typemap_lookup_type = Getattr(n, "name");
-
-      if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
-	// Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper C# enum
-
-	String *scope = getCurrentScopeName(nspace);
-	if (!addSymbol(symname, n, scope))
-	  return SWIG_ERROR;
-
-	// Pure C# baseclass and interfaces
-	const String *pure_baseclass = typemapLookup(n, "csbase", typemap_lookup_type, WARN_NONE);
-	const String *pure_interfaces = typemapLookup(n, "csinterfaces", typemap_lookup_type, WARN_NONE);
-
-	// Class attributes
-	const String *csattributes = typemapLookup(n, "csattributes", typemap_lookup_type, WARN_NONE);
-	if (csattributes && *Char(csattributes))
-	  Printf(enum_code, "%s\n", csattributes);
-
-	// Emit the enum
-	Printv(enum_code, typemapLookup(n, "csclassmodifiers", typemap_lookup_type, WARN_CSHARP_TYPEMAP_CLASSMOD_UNDEF),	// Class modifiers (enum modifiers really)
-	       " ", symname, (*Char(pure_baseclass) || *Char(pure_interfaces)) ? " : " : "", pure_baseclass, ((*Char(pure_baseclass)) && *Char(pure_interfaces)) ?	// Interfaces
-	       ", " : "", pure_interfaces, " {\n", NIL);
-	Delete(scope);
-      } else {
-	// Wrap C++ enum with integers - just indicate start of enum with a comment, no comment for anonymous enums of any sort
-	if (symname && !Getattr(n, "unnamedinstance"))
-	  Printf(constants_code, "  // %s \n", symname);
-      }
-
       // Emit each enum item
       Language::enumDeclaration(n);
 
+      if (proxy_flag && !is_wrapping_class()) {
+	Delete(full_imclass_name);
+	full_imclass_name = 0;
+      }
+
       if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
 	// Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper C# enum
 	// Finish the enum declaration
@@ -1282,11 +1303,6 @@
 
       Delete(enum_code);
       enum_code = NULL;
-
-      if (proxy_flag && !is_wrapping_class()) {
-	Delete(full_imclass_name);
-	full_imclass_name = 0;
-      }
     }
     return SWIG_OK;
   }
@@ -1709,12 +1725,12 @@
    * addInterfaceNameAndUpcasts()
    * ----------------------------------------------------------------------------- */
 
-  void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, String *c_classname) {
-    List *keys = Keys(base_list);
-    for (Iterator it = First(keys); it.item; it = Next(it)) {
-      Node *base = Getattr(base_list, it.item);
-      String *c_baseclass = SwigType_namestr(Getattr(base, "name"));
+  void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, List *base_list, SwigType *c_classname) {
+    for (Iterator it = First(base_list); it.item; it = Next(it)) {
+      Node *base = it.item;
+      SwigType *c_baseclassname = Getattr(base, "name");
       String *interface_name = Getattr(base, "interface:name");
+      SwigType *bsmart = Getattr(base, "smart");
       if (Len(interface_list))
 	Append(interface_list, ", ");
       Append(interface_list, interface_name);
@@ -1733,14 +1749,12 @@
       Replaceall(cptr_method_name, "$interfacename", interface_name);
 
       String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), cptr_method_name);
-      upcastsCode(smart, upcast_method_name, c_classname, c_baseclass);
+      upcastsCode(smart, bsmart, upcast_method_name, c_classname, c_baseclassname);
 
       Delete(upcast_method_name);
       Delete(cptr_method_name);
       Delete(interface_code);
-      Delete(c_baseclass);
     }
-    Delete(keys);
   }
 
   /* -----------------------------------------------------------------------------
@@ -1749,7 +1763,7 @@
    * Add code for C++ casting to base class
    * ----------------------------------------------------------------------------- */
 
-  void upcastsCode(SwigType *smart, String *upcast_method_name, String *c_classname, String *c_baseclass) {
+  void upcastsCode(SwigType *smart, SwigType *bsmart, String *upcast_method_name, SwigType *c_classname, SwigType *c_baseclassname) {
     String *wname = Swig_name_wrapper(upcast_method_name);
 
     Printv(imclass_cppcasts_code, "\n  [global::System.Runtime.InteropServices.DllImport(\"", dllimport, "\", EntryPoint=\"", wname, "\")]\n", NIL);
@@ -1758,27 +1772,31 @@
     Replaceall(imclass_cppcasts_code, "$csclassname", proxy_class_name);
 
     if (smart) {
-      SwigType *bsmart = Copy(smart);
-      SwigType *rclassname = SwigType_typedef_resolve_all(c_classname);
-      SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass);
-      Replaceall(bsmart, rclassname, rbaseclass);
-      Delete(rclassname);
-      Delete(rbaseclass);
-      String *smartnamestr = SwigType_namestr(smart);
-      String *bsmartnamestr = SwigType_namestr(bsmart);
-      Printv(upcasts_code,
-	  "SWIGEXPORT ", bsmartnamestr, " * SWIGSTDCALL ", wname, "(", smartnamestr, " *jarg1) {\n",
-	  "    return jarg1 ? new ", bsmartnamestr, "(*jarg1) : 0;\n"
-	  "}\n", "\n", NIL);
-      Delete(bsmartnamestr);
-      Delete(smartnamestr);
-      Delete(bsmart);
+      if (bsmart) {
+	String *smartnamestr = SwigType_namestr(smart);
+	String *bsmartnamestr = SwigType_namestr(bsmart);
+
+	Printv(upcasts_code,
+	    "SWIGEXPORT ", bsmartnamestr, " * SWIGSTDCALL ", wname, "(", smartnamestr, " *jarg1) {\n",
+	    "    return jarg1 ? new ", bsmartnamestr, "(*jarg1) : 0;\n"
+	    "}\n", "\n", NIL);
+
+	Delete(bsmartnamestr);
+	Delete(smartnamestr);
+      }
     } else {
+      String *classname = SwigType_namestr(c_classname);
+      String *baseclassname = SwigType_namestr(c_baseclassname);
+
       Printv(upcasts_code,
-	  "SWIGEXPORT ", c_baseclass, " * SWIGSTDCALL ", wname, "(", c_classname, " *jarg1) {\n",
-	  "    return (", c_baseclass, " *)jarg1;\n"
+	  "SWIGEXPORT ", baseclassname, " * SWIGSTDCALL ", wname, "(", classname, " *jarg1) {\n",
+	  "    return (", baseclassname, " *)jarg1;\n"
 	  "}\n", "\n", NIL);
+
+      Delete(baseclassname);
+      Delete(classname);
     }
+
     Delete(wname);
   }
 
@@ -1787,16 +1805,16 @@
    * ----------------------------------------------------------------------------- */
 
   void emitProxyClassDefAndCPPCasts(Node *n) {
-    String *c_classname = SwigType_namestr(Getattr(n, "name"));
-    String *c_baseclass = NULL;
+    SwigType *c_classname = Getattr(n, "name");
+    SwigType *c_baseclassname = NULL;
     String *baseclass = NULL;
-    String *c_baseclassname = NULL;
     String *interface_list = NewStringEmpty();
     String *interface_upcasts = NewStringEmpty();
     SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
     bool feature_director = Swig_directorclass(n) ? true : false;
     bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested");
-    SwigType *smart = Swig_cparse_smartptr(n);
+    SwigType *smart = Getattr(n, "smart");
+    SwigType *bsmart = 0;
 
     // Inheritance from pure C# classes
     Node *attributes = NewHash();
@@ -1811,13 +1829,15 @@
       if (baselist) {
 	Iterator base = First(baselist);
 	while (base.item) {
-	  if (!(GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface"))) {
-	    String *baseclassname = Getattr(base.item, "name");
+	  if (!(GetFlag(base.item, "feature:ignore") || GetFlag(base.item, "feature:interface"))) {
+	    SwigType *baseclassname = Getattr(base.item, "name");
 	    if (!c_baseclassname) {
-	      c_baseclassname = baseclassname;
-	      baseclass = Copy(getProxyName(baseclassname));
-	      if (baseclass)
-		c_baseclass = SwigType_namestr(baseclassname);
+	      String *name = getProxyName(baseclassname);
+	      if (name) {
+		c_baseclassname = baseclassname;
+		baseclass = name;
+		bsmart = Getattr(base.item, "smart");
+	      }
 	    } else {
 	      /* Warn about multiple inheritance for additional base class(es) */
 	      String *proxyclassname = Getattr(n, "classtypeobj");
@@ -1829,11 +1849,11 @@
 	}
       }
     }
-    Hash *interface_bases = Getattr(n, "interface:bases");
+    List *interface_bases = Getattr(n, "interface:bases");
     if (interface_bases)
       addInterfaceNameAndUpcasts(smart, interface_list, interface_upcasts, interface_bases, c_classname);
 
-    bool derived = baseclass && getProxyName(c_baseclassname);
+    bool derived = baseclass != 0;
     if (derived && purebase_notderived)
       pure_baseclass = empty_string;
     const String *wanted_base = baseclass ? baseclass : pure_baseclass;
@@ -1841,7 +1861,6 @@
     if (purebase_replace) {
       wanted_base = pure_baseclass;
       derived = false;
-      Delete(baseclass);
       baseclass = NULL;
       if (purebase_notderived)
         Swig_error(Getfile(n), Getline(n), "The csbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type);
@@ -1969,9 +1988,32 @@
 	// Only emit if there is at least one director method
 	Printf(proxy_class_code, "\n");
 	Printf(proxy_class_code, "  private bool SwigDerivedClassHasMethod(string methodName, global::System.Type[] methodTypes) {\n");
-	Printf(proxy_class_code,
-	       "    global::System.Reflection.MethodInfo methodInfo = this.GetType().GetMethod(methodName, global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance, null, methodTypes, null);\n");
-	Printf(proxy_class_code, "    bool hasDerivedMethod = methodInfo.DeclaringType.IsSubclassOf(typeof(%s));\n", proxy_class_name);
+	Printf(proxy_class_code, "    global::System.Reflection.MethodInfo[] methodInfos = this.GetType().GetMethods(\n");
+	Printf(proxy_class_code, "        global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance);\n");
+	Printf(proxy_class_code, "    foreach (global::System.Reflection.MethodInfo methodInfo in methodInfos) {\n");
+	Printf(proxy_class_code, "      if (methodInfo.DeclaringType == null)\n");
+	Printf(proxy_class_code, "        continue;\n\n");
+	Printf(proxy_class_code, "      if (methodInfo.Name != methodName)\n");
+	Printf(proxy_class_code, "        continue;\n\n");
+	Printf(proxy_class_code, "      var parameters = methodInfo.GetParameters();\n");
+	Printf(proxy_class_code, "      if (parameters.Length != methodTypes.Length)\n");
+	Printf(proxy_class_code, "        continue;\n\n");
+	Printf(proxy_class_code, "      bool parametersMatch = true;\n");
+	Printf(proxy_class_code, "      for (var i = 0; i < parameters.Length; i++) {\n");
+	Printf(proxy_class_code, "        if (parameters[i].ParameterType != methodTypes[i]) {\n");
+	Printf(proxy_class_code, "          parametersMatch = false;\n");
+	Printf(proxy_class_code, "          break;\n");
+	Printf(proxy_class_code, "        }\n");
+	Printf(proxy_class_code, "      }\n\n");
+	Printf(proxy_class_code, "      if (!parametersMatch)\n");
+	Printf(proxy_class_code, "        continue;\n\n");
+	Printf(proxy_class_code, "      if (methodInfo.IsVirtual && (methodInfo.DeclaringType.IsSubclassOf(typeof(%s))) &&\n", proxy_class_name);
+	Printf(proxy_class_code, "        methodInfo.DeclaringType != methodInfo.GetBaseDefinition().DeclaringType) {\n");
+	Printf(proxy_class_code, "        return true;\n");
+	Printf(proxy_class_code, "      }\n");
+	Printf(proxy_class_code, "    }\n\n");
+	Printf(proxy_class_code, "    return false;\n");
+
 	/* Could add this code to cover corner case where the GetMethod() returns a method which allows type
 	 * promotion, eg it will return foo(double), if looking for foo(int).
 	 if (hasDerivedMethod) {
@@ -1991,7 +2033,7 @@
 	 }
 	 }
 	 */
-	Printf(proxy_class_code, "    return hasDerivedMethod;\n");
+	//Printf(proxy_class_code, "    return hasDerivedMethod;\n");
 	Printf(proxy_class_code, "  }\n");
       }
 
@@ -2032,12 +2074,9 @@
 
     if (derived) {
       String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast");
-      upcastsCode(smart, upcast_method_name, c_classname, c_baseclass);
+      upcastsCode(smart, bsmart, upcast_method_name, c_classname, c_baseclassname);
       Delete(upcast_method_name);
     }
-
-    Delete(smart);
-    Delete(baseclass);
   }
 
   /* ----------------------------------------------------------------------
@@ -2046,11 +2085,12 @@
 
   void emitInterfaceDeclaration(Node *n, String *interface_name, File *f_interface) {
     Printv(f_interface, typemapLookup(n, "csimports", Getattr(n, "classtypeobj"), WARN_NONE), "\n", NIL);
-    Printf(f_interface, "public interface %s", interface_name);
+    Printv(f_interface, typemapLookup(n, "csinterfacemodifiers", Getattr(n, "classtypeobj"), WARN_CSHARP_TYPEMAP_INTERFACEMODIFIERS_UNDEF), NIL);
+    Printf(f_interface, " %s", interface_name);
     if (List *baselist = Getattr(n, "bases")) {
       String *bases = 0;
       for (Iterator base = First(baselist); base.item; base = Next(base)) {
-	if (GetFlag(base.item, "feature:ignore") || !Getattr(base.item, "feature:interface"))
+	if (GetFlag(base.item, "feature:ignore") || !GetFlag(base.item, "feature:interface"))
 	  continue; // TODO: warn about skipped non-interface bases
 	String *base_iname = Getattr(base.item, "interface:name");
 	if (!bases)
@@ -2101,7 +2141,7 @@
 
     if (proxy_flag) {
       proxy_class_name = NewString(Getattr(n, "sym:name"));
-      String *interface_name = Getattr(n, "feature:interface") ? Getattr(n, "interface:name") : 0;
+      String *interface_name = GetFlag(n, "feature:interface") ? Getattr(n, "interface:name") : 0;
       if (Node *outer = Getattr(n, "nested:outer")) {
 	String *outerClassesPrefix = Copy(Getattr(outer, "sym:name"));
 	for (outer = Getattr(outer, "nested:outer"); outer != 0; outer = Getattr(outer, "nested:outer")) {
@@ -2127,12 +2167,12 @@
 	full_imclass_name = NewStringf("%s", imclass_name);
 	if (Cmp(proxy_class_name, imclass_name) == 0) {
 	  Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name);
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	}
 
 	if (Cmp(proxy_class_name, module_class_name) == 0) {
 	  Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name);
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	}
       } else {
 	if (namespce) {
@@ -2157,7 +2197,7 @@
       destructor_call = NewString("");
       proxy_class_constants_code = NewString("");
 
-      if (Getattr(n, "feature:interface")) {
+      if (GetFlag(n, "feature:interface")) {
 	interface_class_code = NewString("");
 	String *output_directory = outputDirectory(nspace);
 	f_interface = getOutputFile(output_directory, interface_name);
@@ -2260,6 +2300,31 @@
     return SWIG_OK;
   }
 
+  void printArgumentDeclaration(Node *n, Parm *p, String *param_type, String *arg, String *code)
+  {
+    String *specifiedoverridekey = NewString("feature:cs:defaultargs:");
+    Append(specifiedoverridekey, arg);
+    String *specifiedoverridevalue = Getattr(n, specifiedoverridekey);
+    if (specifiedoverridevalue) {
+      Printf(code, "%s %s=%s", param_type, arg, specifiedoverridevalue);
+    } else {
+      String *cppvalue = NULL;
+      //if they've not specified defaultargs, then fall back to
+      //the normal default handling of specifying one overload per possible
+      //set of arguments.  If they have, then use the default argument from
+      //c++ as a literal csharp expression.
+      if (Getattr(n, "feature:cs:defaultargs"))
+        cppvalue = Getattr(p, "value");
+      if (cppvalue)
+        Printf(code, "%s %s=%s", param_type, arg, cppvalue);
+      else
+        Printf(code, "%s %s", param_type, arg);
+    }
+    Delete(specifiedoverridekey);
+  }
+
+
+
   /* ----------------------------------------------------------------------
    * memberfunctionHandler()
    * ---------------------------------------------------------------------- */
@@ -2328,7 +2393,7 @@
     String *pre_code = NewString("");
     String *post_code = NewString("");
     String *terminator_code = NewString("");
-    bool is_interface = Getattr(parentNode(n), "feature:interface") != 0 
+    bool is_interface = GetFlag(parentNode(n), "feature:interface") && !checkAttribute(n, "kind", "variable")
       && !static_flag && Getattr(n, "interface:owner") == 0;
 
     if (!proxy_flag)
@@ -2338,6 +2403,9 @@
     if (Getattr(n, "overload:ignore"))
       return;
 
+    if (Getattr(n, "feature:cs:defaultargs") && Getattr(n, "defaultargs"))
+      return;
+
     // Don't generate proxy method for additional explicitcall method used in directors
     if (GetFlag(n, "explicitcall"))
       return;
@@ -2422,7 +2490,6 @@
       Printf(imcall, "swigCPtr");
 
     emit_mark_varargs(l);
-
     int gencomma = !static_flag;
 
     /* Output each parameter */
@@ -2501,9 +2568,9 @@
 	    Printf(interface_class_code, ", ");
 	}
 	gencomma = 2;
-	Printf(function_code, "%s %s", param_type, arg);
+        printArgumentDeclaration(n, p, param_type, arg, function_code);
 	if (is_interface)
-	  Printf(interface_class_code, "%s %s", param_type, arg);
+            printArgumentDeclaration(n, p, param_type, arg, interface_class_code);
 
 	Delete(arg);
 	Delete(param_type);
@@ -2558,8 +2625,8 @@
 	Replaceall(imcall, "$imfuncname", intermediary_function_name);
 	String *excode = NewString("");
 	Node *directorNode = Getattr(n, "directorNode");
-	if (directorNode) {
-	  UpcallData *udata = Getattr(directorNode, "upcalldata");
+	UpcallData *udata = directorNode ? Getattr(directorNode, "upcalldata") : 0;
+	if (udata) {
 	  String *methid = Getattr(udata, "class_methodidx");
 
 	  if (!Cmp(return_type, "void"))
@@ -2577,6 +2644,7 @@
       } else {
 	Replaceall(imcall, "$imfuncname", intermediary_function_name);
       }
+      Replaceall(tm, "$imfuncname", intermediary_function_name);
       Replaceall(tm, "$imcall", imcall);
     } else {
       Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0));
@@ -2608,6 +2676,8 @@
 	const String *methodmods = Getattr(n, "feature:cs:methodmodifiers");
 	if (!methodmods)
 	  methodmods = (is_public(n) ? public_string : protected_string);
+
+	// Start property declaration
 	Printf(proxy_class_code, "  %s %s%s %s {", methodmods, static_flag ? "static " : "", variable_type, variable_name);
       }
       generate_property_declaration_flag = false;
@@ -2620,6 +2690,7 @@
 	if ((tm = Swig_typemap_lookup("csvarin", variable_parm, "", 0))) {
 	  substituteClassname(cvariable_type, tm);
 	  Replaceall(tm, "$csinput", "value");
+          Replaceall(tm, "$imfuncname", intermediary_function_name);
 	  Replaceall(tm, "$imcall", imcall);
 	  excodeSubstitute(n, tm, "csvarin", variable_parm);
 	  Printf(proxy_class_code, "%s", tm);
@@ -2634,6 +2705,7 @@
 	  else
 	    Replaceall(tm, "$owner", "false");
 	  substituteClassname(t, tm);
+          Replaceall(tm, "$imfuncname", intermediary_function_name);
 	  Replaceall(tm, "$imcall", imcall);
 	  excodeSubstitute(n, tm, "csvarout", n);
 	  Printf(proxy_class_code, "%s", tm);
@@ -2680,6 +2752,9 @@
     if (Getattr(n, "overload:ignore"))
       return SWIG_OK;
 
+    if (Getattr(n, "feature:cs:defaultargs") && Getattr(n, "defaultargs"))
+      return SWIG_OK;
+
     if (proxy_flag) {
       String *overloaded_name = getOverloadedName(n);
       String *mangled_overname = Swig_name_construct(getNSpace(), overloaded_name);
@@ -2788,7 +2863,7 @@
 	  Printf(helper_code, ", ");
 	  Printf(helper_args, ", ");
         }
-	Printf(function_code, "%s %s", param_type, arg);
+        printArgumentDeclaration(n, p, param_type, arg, function_code);
 	Printf(helper_code, "%s %s", param_type, arg);
 	Printf(helper_args, "%s", cshin ? cshin : arg);
 	++gencomma;
@@ -2908,6 +2983,7 @@
     variable_wrapper_flag = false;
     generate_property_declaration_flag = false;
 
+    // End property declaration
     Printf(proxy_class_code, "\n  }\n\n");
 
     return SWIG_OK;
@@ -2919,8 +2995,6 @@
 
   virtual int staticmembervariableHandler(Node *n) {
 
-    bool static_const_member_flag = (Getattr(n, "value") == 0);
-
     generate_property_declaration_flag = true;
     variable_name = Getattr(n, "sym:name");
     wrapping_member_flag = true;
@@ -2930,8 +3004,10 @@
     static_flag = false;
     generate_property_declaration_flag = false;
 
-    if (static_const_member_flag)
+    if (!GetFlag(n, "wrappedasconstant")) {
+      // End property declaration
       Printf(proxy_class_code, "\n  }\n\n");
+    }
 
     return SWIG_OK;
   }
@@ -2957,7 +3033,7 @@
     /* A C# HandleRef is used for all classes in the SWIG intermediary class.
      * The intermediary class methods are thus mangled when overloaded to give
      * a unique name. */
-    String *overloaded_name = NewStringf("%s", Getattr(n, "sym:name"));
+    String *overloaded_name = Copy(Getattr(n, "sym:name"));
 
     if (Getattr(n, "sym:overloaded")) {
       Printv(overloaded_name, Getattr(n, "sym:overname"), NIL);
@@ -2988,6 +3064,9 @@
     String *post_code = NewString("");
     String *terminator_code = NewString("");
 
+    if (Getattr(n, "feature:cs:defaultargs") && Getattr(n, "defaultargs"))
+      return;
+
     if (l) {
       if (SwigType_type(Getattr(l, "type")) == T_VOID) {
 	l = nextSibling(l);
@@ -3107,7 +3186,7 @@
       if (gencomma >= 2)
 	Printf(function_code, ", ");
       gencomma = 2;
-      Printf(function_code, "%s %s", param_type, arg);
+      printArgumentDeclaration(n, p, param_type, arg, function_code);
 
       p = Getattr(p, "tmap:in:next");
       Delete(arg);
@@ -3146,6 +3225,7 @@
       else
 	Replaceall(tm, "$owner", "false");
       substituteClassname(t, tm);
+      Replaceall(tm, "$imfuncname", overloaded_name);
       Replaceall(tm, "$imcall", imcall);
     } else {
       Swig_warning(WARN_CSHARP_TYPEMAP_CSOUT_UNDEF, input_file, line_number, "No csout typemap defined for %s\n", SwigType_str(t, 0));
@@ -3184,6 +3264,7 @@
 	if ((tm = Getattr(p, "tmap:csvarin"))) {
 	  substituteClassname(pt, tm);
 	  Replaceall(tm, "$csinput", "value");
+	  Replaceall(tm, "$imfuncname", overloaded_name);
 	  Replaceall(tm, "$imcall", imcall);
 	  excodeSubstitute(n, tm, "csvarin", p);
 	  Printf(module_class_code, "%s", tm);
@@ -3198,6 +3279,7 @@
 	  else
 	    Replaceall(tm, "$owner", "false");
 	  substituteClassname(t, tm);
+	  Replaceall(tm, "$imfuncname", overloaded_name);
 	  Replaceall(tm, "$imcall", imcall);
 	  excodeSubstitute(n, tm, "csvarout", n);
 	  Printf(module_class_code, "%s", tm);
@@ -3665,7 +3747,7 @@
       if (newdir_error) {
 	Printf(stderr, "%s\n", newdir_error);
 	Delete(newdir_error);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       Printv(output_directory, nspace_subdirectory, SWIG_FILE_DELIMITER, 0);
       Delete(nspace_subdirectory);
@@ -3729,7 +3811,8 @@
     String *qualified_classname = Copy(sym_name);
     String *nspace = getNSpace();
     String *dirClassName = directorClassName(n);
-    String *smartptr = Getattr(n, "feature:smartptr");
+    SwigType *smart = Getattr(n, "smart");
+    String *smartptr = smart ? SwigType_namestr(smart) : 0;
     if (!GetFlag(n, "feature:flatnested")) {
       for (Node *outer_class = Getattr(n, "nested:outer"); outer_class; outer_class = Getattr(outer_class, "nested:outer")) {
 
@@ -3798,7 +3881,7 @@
     String *name = Getattr(n, "name");
     String *symname = Getattr(n, "sym:name");
     SwigType *returntype = Getattr(n, "type");
-    String *overloaded_name = getOverloadedName(n);
+    String *overloaded_name = 0;
     String *storage = Getattr(n, "storage");
     String *value = Getattr(n, "value");
     String *decl = Getattr(n, "decl");
@@ -3820,7 +3903,6 @@
     String *qualified_name = NewStringf("%s::%s", dirclassname, name);
     SwigType *c_ret_type = NULL;
     String *jupcall_args = NewString("");
-    String *imclass_dmethod;
     String *callback_typedef_parms = NewString("");
     String *delegate_parms = NewString("");
     String *proxy_method_types = NewString("");
@@ -3834,7 +3916,8 @@
     // we're consistent with the sym:overload name in functionWrapper. (?? when
     // does the overloaded method name get set?)
 
-    imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name));
+    if (!ignored_method)
+      overloaded_name = getOverloadedName(n);
 
     qualified_return = SwigType_rcaststr(returntype, "c_result");
 
@@ -3887,28 +3970,28 @@
       }
     }
 
-    /* Create the intermediate class wrapper */
-    tm = Swig_typemap_lookup("imtype", n, "", 0);
-    if (tm) {
-      String *imtypeout = Getattr(n, "tmap:imtype:out");	// the type in the imtype typemap's out attribute overrides the type in the typemap
-      if (imtypeout)
-	tm = imtypeout;
-      const String *im_directoroutattributes = Getattr(n, "tmap:imtype:directoroutattributes");
-      if (im_directoroutattributes) {
-	Printf(callback_def, "  %s\n", im_directoroutattributes);
-	if (!ignored_method)
-	  Printf(director_delegate_definitions, "  %s\n", im_directoroutattributes);
-      }
+    if (!ignored_method) {
+      /* Create the intermediate class wrapper */
+      tm = Swig_typemap_lookup("imtype", n, "", 0);
+      if (tm) {
+	String *imtypeout = Getattr(n, "tmap:imtype:out");	// the type in the imtype typemap's out attribute overrides the type in the typemap
+	if (imtypeout)
+	  tm = imtypeout;
+	const String *im_directoroutattributes = Getattr(n, "tmap:imtype:directoroutattributes");
+	if (im_directoroutattributes) {
+	  Printf(callback_def, "  %s\n", im_directoroutattributes);
+	  if (!ignored_method)
+	    Printf(director_delegate_definitions, "  %s\n", im_directoroutattributes);
+	}
 
-      Printf(callback_def, "  private %s SwigDirectorMethod%s(", tm, overloaded_name);
-      if (!ignored_method) {
+	Printf(callback_def, "  private %s SwigDirectorMethod%s(", tm, overloaded_name);
 	const String *csdirectordelegatemodifiers = Getattr(n, "feature:csdirectordelegatemodifiers");
 	String *modifiers = (csdirectordelegatemodifiers ? NewStringf("%s%s", csdirectordelegatemodifiers, Len(csdirectordelegatemodifiers) > 0 ? " " : "") : NewStringf("public "));
 	Printf(director_delegate_definitions, "  %sdelegate %s", modifiers, tm);
 	Delete(modifiers);
+      } else {
+	Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(returntype, 0));
       }
-    } else {
-      Swig_warning(WARN_CSHARP_TYPEMAP_CSTYPE_UNDEF, input_file, line_number, "No imtype typemap defined for %s\n", SwigType_str(returntype, 0));
     }
 
     if ((c_ret_type = Swig_typemap_lookup("ctype", n, "", 0))) {
@@ -4064,11 +4147,10 @@
 	      /* Get the C# parameter type */
 	      if ((tm = Getattr(p, "tmap:cstype"))) {
 		substituteClassname(pt, tm);
-		if (Strncmp(tm, "ref ", 4) == 0) {
-		  Replace(tm, "ref ", "", DOH_REPLACE_FIRST);
+		int flags = DOH_REPLACE_FIRST | DOH_REPLACE_ID_BEGIN | DOH_REPLACE_NOCOMMENT;
+		if (Replace(tm, "ref ", "", flags) || Replace(tm, "ref\t", "", flags)) {
 		  Printf(proxy_method_types, "typeof(%s).MakeByRefType()", tm);
-		} else if (Strncmp(tm, "out ", 4) == 0) {
-		  Replace(tm, "out ", "", DOH_REPLACE_FIRST);
+		} else if (Replace(tm, "out ", "", flags) || Replace(tm, "out\t", "", flags)) {
 		  Printf(proxy_method_types, "typeof(%s).MakeByRefType()", tm);
 		} else {
 		  Printf(proxy_method_types, "typeof(%s)", tm);
@@ -4267,6 +4349,8 @@
 
     if (!ignored_method) {
       /* Emit the actual upcall through */
+      String *member_name = Swig_name_member(getNSpace(), getClassPrefix(), overloaded_name);
+      String *imclass_dmethod = NewStringf("SwigDirector_%s", member_name);
       UpcallData *udata = addUpcallMethod(imclass_dmethod, symname, decl, overloaded_name);
       String *methid = Getattr(udata, "class_methodidx");
       Setattr(n, "upcalldata", udata);
@@ -4282,6 +4366,9 @@
       Printf(director_delegate_instances, "  private SwigDelegate%s_%s swigDelegate%s;\n", classname, methid, methid);
       Printf(director_method_types, "  private static global::System.Type[] swigMethodTypes%s = new global::System.Type[] { %s };\n", methid, proxy_method_types);
       Printf(director_connect_parms, "SwigDirector%s%s delegate%s", classname, methid, methid);
+
+      Delete(imclass_dmethod);
+      Delete(member_name);
     }
 
     Delete(pre_code);
diff --git a/Source/Modules/d.cxx b/Source/Modules/d.cxx
index 5e82dfd..b86f14a 100644
--- a/Source/Modules/d.cxx
+++ b/Source/Modules/d.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * d.cxx
  *
@@ -22,6 +22,7 @@
   static const char *usage;
   const String *empty_string;
   const String *public_string;
+  const String *private_string;
   const String *protected_string;
 
   /*
@@ -44,9 +45,6 @@
   // written to their own files.
   bool split_proxy_dmodule;
 
-  // The major D version targeted (currently 1 or 2).
-  unsigned short d_version;
-
   /*
    * State variables which indicate what is being wrapped at the moment.
    * This is probably not the most elegant way of handling state, but it has
@@ -177,6 +175,9 @@
   // The full code for the current proxy class, including the epilogue.
   String* proxy_class_code;
 
+  // Code generated at the begin of every D file
+  String *common_begin_code;
+
   // Contains a D call to the function wrapping C++ the destructor of the
   // current class (if there is a public C++ destructor).
   String *destructor_call;
@@ -221,6 +222,7 @@
    * --------------------------------------------------------------------------- */
    D():empty_string(NewString("")),
       public_string(NewString("public")),
+      private_string(NewString("private")),
       protected_string(NewString("protected")),
       f_begin(NULL),
       f_runtime(NULL),
@@ -232,7 +234,6 @@
       f_directors_h(NULL),
       filenames_list(NULL),
       split_proxy_dmodule(false),
-      d_version(1),
       native_function_flag(false),
       static_flag(false),
       variable_wrapper_flag(false),
@@ -263,6 +264,7 @@
       proxy_class_body_code(NULL),
       proxy_class_epilogue_code(NULL),
       proxy_class_code(NULL),
+      common_begin_code(NULL),
       destructor_call(NULL),
       director_dcallbacks_code(NULL),
       wrapper_loader_code(NULL),
@@ -278,7 +280,7 @@
     // For now, multiple inheritance with directors is not possible. It should be
     // easy to implement though.
     director_multiple_inheritance = 0;
-    director_language = 1;
+    directorLanguage();
 
     // Not used:
     Delete(none_comparison);
@@ -295,8 +297,8 @@
     for (int i = 1; i < argc; i++) {
       if (argv[i]) {
 	if ((strcmp(argv[i], "-d2") == 0)) {
+	  /* Keep for backward compatible only */
       	  Swig_mark_arg(i);
-      	  d_version = 2;
       	} else if (strcmp(argv[i], "-wrapperlibrary") == 0) {
 	  if (argv[i + 1]) {
 	    wrap_library_name = NewString("");
@@ -331,9 +333,7 @@
 
     // Also make the target D version available as preprocessor symbol for
     // use in our library files.
-    String *version_define = NewStringf("SWIG_D_VERSION %u", d_version);
-    Preprocessor_define(version_define, 0);
-    Delete(version_define);
+    Preprocessor_define("SWIG_D_VERSION 2", 0);
 
     // Add typemap definitions
     SWIG_typemap_lang("d");
@@ -347,7 +347,8 @@
    * --------------------------------------------------------------------------- */
   virtual int top(Node *n) {
     // Get any options set in the module directive
-    Node *optionsnode = Getattr(Getattr(n, "module"), "options");
+    Node *module = Getattr(n, "module");
+    Node *optionsnode = Getattr(module, "options");
 
     if (optionsnode) {
       if (Getattr(optionsnode, "imdmodulename")) {
@@ -370,6 +371,10 @@
       }
 
       allow_allprotected(GetFlag(optionsnode, "allprotected"));
+
+      common_begin_code = Getattr(optionsnode, "dbegin");
+      if (common_begin_code)
+	Printf(common_begin_code, "\n");
     }
 
     /* Initialize all of the output files */
@@ -378,24 +383,24 @@
 
     if (!outfile) {
       Printf(stderr, "Unable to determine outfile\n");
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
 
     f_begin = NewFile(outfile, "w", SWIG_output_files());
     if (!f_begin) {
       FileErrorDisplay(outfile);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       if (!outfile_h) {
 	Printf(stderr, "Unable to determine outfile_h\n");
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
       if (!f_runtime_h) {
 	FileErrorDisplay(outfile_h);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
     }
 
@@ -472,9 +477,9 @@
 
     Swig_banner(f_begin);
 
-    Printf(f_runtime, "\n\n#ifndef SWIGD\n#define SWIGD\n#endif\n\n");
+    Swig_obligatory_macros(f_runtime, "D");
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Printf(f_runtime, "#define SWIG_DIRECTORS\n");
 
       /* Emit initial director header and director code: */
@@ -505,7 +510,7 @@
     // Emit all the wrapper code.
     Language::top(n);
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       // Insert director runtime into the f_runtime file (before %header section).
       Swig_insert_file("director_common.swg", f_runtime);
       Swig_insert_file("director.swg", f_runtime);
@@ -518,7 +523,7 @@
       File *im_d_file = NewFile(filen, "w", SWIG_output_files());
       if (!im_d_file) {
 	FileErrorDisplay(filen);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       Append(filenames_list, Copy(filen));
       Delete(filen);
@@ -549,7 +554,7 @@
       File *proxy_d_file = NewFile(filen, "w", SWIG_output_files());
       if (!proxy_d_file) {
 	FileErrorDisplay(filen);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       Append(filenames_list, Copy(filen));
       Delete(filen);
@@ -583,7 +588,7 @@
       File *file = NewFile(filename, "w", SWIG_output_files());
       if (!file) {
 	FileErrorDisplay(filename);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       Delete(filename);
 
@@ -687,7 +692,7 @@
     Dump(f_runtime, f_begin);
     Dump(f_header, f_begin);
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Dump(f_directors, f_begin);
       Dump(f_directors_h, f_runtime_h);
 
@@ -804,8 +809,33 @@
 
     // Emit the enum declaration.
     if (typemap_lookup_type) {
+
+      // Enum base (underlying enum type)
+      Node *attributes = NewHash();
+      const String *pure_baseclass = lookupCodeTypemap(n, "dbase", typemap_lookup_type, WARN_NONE, attributes);
+      bool purebase_replace = GetFlag(attributes, "tmap:dbase:replace") ? true : false;
+      Delete(attributes);
+
+      const String *baseclass = NULL;
+      if (!purebase_replace) {
+	String *underlying_enum_type = Getattr(n, "enumbase");
+	if (underlying_enum_type) {
+	  baseclass = lookupCodeTypemap(n, "dtype", underlying_enum_type, WARN_D_TYPEMAP_DTYPE_UNDEF);
+	}
+      }
+
+      const String *wanted_base = baseclass ? baseclass : pure_baseclass;
+
+      if (purebase_replace) {
+	wanted_base = pure_baseclass;
+      } else if (Len(pure_baseclass) > 0 && Len(baseclass) > 0) {
+	Swig_warning(WARN_D_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
+		     "Warning for %s, enum base %s ignored. Multiple enum bases is not supported in D enums. "
+		     "Perhaps you need the 'replace' attribute in the dbase typemap?\n", typemap_lookup_type, pure_baseclass);
+      }
+
       const String *enummodifiers = lookupCodeTypemap(n, "dclassmodifiers", typemap_lookup_type, WARN_D_TYPEMAP_CLASSMOD_UNDEF);
-      Printv(proxy_enum_code, "\n", enummodifiers, " ", symname, " {\n", NIL);
+      Printv(proxy_enum_code, "\n", enummodifiers, " ", symname, *Char(wanted_base) ? " : " : "", wanted_base, " {\n", NIL);
     } else {
       // Handle anonymous enums.
       Printv(proxy_enum_code, "\nenum {\n", NIL);
@@ -863,7 +893,7 @@
 	File *class_file = NewFile(filename, "w", SWIG_output_files());
 	if (!class_file) {
 	  FileErrorDisplay(filename);
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	}
 	Append(filenames_list, Copy(filename));
 	Delete(filename);
@@ -1335,7 +1365,7 @@
       Delete(output_directory);
       if (!class_file) {
 	FileErrorDisplay(filename);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       Append(filenames_list, Copy(filename));
       Delete(filename);
@@ -1349,7 +1379,6 @@
       Printf(class_file, "\nstatic import %s;\n", im_dmodule_fq_name);
     }
 
-    Clear(proxy_class_imports);
     Clear(proxy_class_enums_code);
     Clear(proxy_class_body_code);
     Clear(proxy_class_epilogue_code);
@@ -1361,6 +1390,8 @@
     // to the proxy_class_* variables.
     Language::classHandler(n);
 
+    // This function write super methods in proxy_class_body_code
+    writeDirectorSuperFunctions(n);
 
     writeProxyClassAndUpcasts(n);
     writeDirectorConnectWrapper(n);
@@ -1384,6 +1415,7 @@
       Printv(proxyCodeBuffer(getNSpace()), proxy_class_code, NIL);
     }
 
+    Clear(proxy_class_imports);
     Delete(proxy_class_qname);
     proxy_class_qname = NULL;
     Delete(proxy_class_name);
@@ -1447,20 +1479,11 @@
     Swig_typemap_attach_parms("dtype", l, NULL);
 
     // Get D return type.
-    String *return_type = NewString("");
-    String *tm;
-    if ((tm = lookupDTypemap(n, "dtype"))) {
-      String *dtypeout = Getattr(n, "tmap:dtype:out");
-      if (dtypeout) {
-	// The type in the out attribute of the typemap overrides the type
-	// in the dtype typemap.
-	tm = dtypeout;
-	replaceClassname(tm, t);
-      }
-      Printf(return_type, "%s", tm);
-    } else {
+    String *return_type = getOutDtype(n);
+    if (!return_type) {
       Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number,
 	"No dtype typemap defined for %s\n", SwigType_str(t, 0));
+      return_type = NewString("");
     }
 
     const String *itemname = wrapping_member_flag ? variable_name : symname;
@@ -1472,14 +1495,7 @@
       attributes = Copy(is_public(n) ? public_string : protected_string);
     }
 
-    if (d_version == 1) {
-      if (static_flag) {
-	Printv(attributes, " static", NIL);
-      }
-      Printf(constants_code, "\n%s const %s %s = ", attributes, return_type, itemname);
-    } else {
-      Printf(constants_code, "\n%s enum %s %s = ", attributes, return_type, itemname);
-    }
+    Printf(constants_code, "\n%s enum %s %s = ", attributes, return_type, itemname);
     Delete(attributes);
 
     // Retrieve the override value set via %dconstvalue, if any.
@@ -1537,7 +1553,6 @@
     String *im_return_type = NewString("");
     String *cleanup = NewString("");
     String *outarg = NewString("");
-    String *body = NewString("");
     int num_arguments = 0;
     bool is_void_return;
     String *overloaded_name = getOverloadedName(n);
@@ -1844,7 +1859,6 @@
     Delete(im_return_type);
     Delete(cleanup);
     Delete(outarg);
-    Delete(body);
     Delete(overloaded_name);
     DelWrapper(f);
     return SWIG_OK;
@@ -1943,7 +1957,7 @@
     String *name = Getattr(n, "name");
     String *symname = Getattr(n, "sym:name");
     SwigType *returntype = Getattr(n, "type");
-    String *overloaded_name = getOverloadedName(n);
+    String *overloaded_name = 0;
     String *storage = Getattr(n, "storage");
     String *value = Getattr(n, "value");
     String *decl = Getattr(n, "decl");
@@ -1962,7 +1976,6 @@
     String *qualified_name = NewStringf("%s::%s", dirclassname, name);
     SwigType *c_ret_type = NULL;
     String *dcallback_call_args = NewString("");
-    String *imclass_dmethod;
     String *callback_typedef_parms = NewString("");
     String *delegate_parms = NewString("");
     String *proxy_method_param_list = NewString("");
@@ -1977,7 +1990,8 @@
     // we're consistent with the sym:overload name in functionWrapper. (?? when
     // does the overloaded method name get set?)
 
-    imclass_dmethod = NewStringf("SwigDirector_%s", Swig_name_member(getNSpace(), classname, overloaded_name));
+    if (!ignored_method)
+      overloaded_name = getOverloadedName(n);
 
     qualified_return = SwigType_rcaststr(returntype, "c_result");
 
@@ -2121,11 +2135,22 @@
 	  // in the typemap itself.
 	  c_param_type = ctypeout;
 	}
+	// ctype default assignment
+	const String *ctypedef = Getattr(p, "tmap:ctype:default");
+	String *ctypeassign;
+	if (ctypedef) {
+	  ctypeassign = Copy(ctypedef);
+	} else if (SwigType_ispointer(pt) || SwigType_isreference(pt)) {
+	  ctypeassign = NewString("= 0");
+	} else {
+	  ctypeassign = NewString("");
+	}
 
 	/* Add to local variables */
 	Printf(c_decl, "%s %s", c_param_type, arg);
 	if (!ignored_method)
-	  Wrapper_add_localv(w, arg, c_decl, (!(SwigType_ispointer(pt) || SwigType_isreference(pt)) ? "" : "= 0"), NIL);
+	  Wrapper_add_localv(w, arg, c_decl, ctypeassign, NIL);
+	Delete(ctypeassign);
 
 	/* Add input marshalling code */
 	if ((tm = Getattr(p, "tmap:directorin"))) {
@@ -2366,23 +2391,16 @@
       // We cannot directly use n here because its »type« attribute does not
       // the full return type any longer after Language::functionHandler has
       // returned.
-      String *dp_return_type = lookupDTypemap(n, "dtype");
-      if (dp_return_type) {
-	String *dtypeout = Getattr(n, "tmap:dtype:out");
-	if (dtypeout) {
-	  // The type in the dtype typemap's out attribute overrides the type
-	  // in the typemap itself.
-	  dp_return_type = dtypeout;
-  	replaceClassname(dp_return_type, returntype);
-	}
-      } else {
+      String *dp_return_type = getOutDtype(n);
+      if (!dp_return_type) {
 	Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number,
 	  "No dtype typemap defined for %s\n", SwigType_str(returntype, 0));
 	dp_return_type = NewString("");
       }
 
+      String *member_name = Swig_name_member(getNSpace(), classname, overloaded_name);
+      String *imclass_dmethod = NewStringf("SwigDirector_%s", member_name);
       UpcallData *udata = addUpcallMethod(imclass_dmethod, symname, decl, overloaded_name, dp_return_type, proxy_method_param_list);
-      Delete(dp_return_type);
 
       // Write the global callback function pointer on the C code.
       String *methid = Getattr(udata, "class_methodidx");
@@ -2396,6 +2414,10 @@
       String *dirClassName = directorClassName(parent);
       Printf(proxy_callback_type, "%s_Callback%s", dirClassName, methid);
       Printf(im_dmodule_code, "alias extern(C) %s function(void*%s) %s;\n", proxy_callback_return_type, delegate_parms, proxy_callback_type);
+
+      Delete(imclass_dmethod);
+      Delete(member_name);
+      Delete(dp_return_type);
       Delete(proxy_callback_type);
       Delete(dirClassName);
     }
@@ -2636,7 +2658,7 @@
    *  - "proxyfuncname": The name of the D proxy function.
    *  - "imfuncname": The corresponding function in the intermediary D module.
    * --------------------------------------------------------------------------- */
-  void writeProxyClassFunction(Node *n) {
+  void writeProxyClassFunction(Node *n, bool super = false) {
     SwigType *t = Getattr(n, "type");
     ParmList *l = Getattr(n, "parms");
     String *intermediary_function_name = Getattr(n, "imfuncname");
@@ -2645,7 +2667,6 @@
     Parm *p;
     int i;
     String *imcall = NewString("");
-    String *return_type = NewString("");
     String *function_code = NewString("");
     bool setter_flag = false;
     String *pre_code = NewString("");
@@ -2675,18 +2696,11 @@
     Swig_typemap_attach_parms("din", l, NULL);
 
     // Get return types.
-    if ((tm = lookupDTypemap(n, "dtype"))) {
-      String *dtypeout = Getattr(n, "tmap:dtype:out");
-      if (dtypeout) {
-	// The type in the dtype typemap's out attribute overrides the type in
-	// the typemap.
-	tm = dtypeout;
-        replaceClassname(tm, t);
-      }
-      Printf(return_type, "%s", tm);
-    } else {
+    String *return_type = getOutDtype(n);
+    if (!return_type) {
       Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number,
 	"No dtype typemap defined for %s\n", SwigType_str(t, 0));
+      return_type = NewString("");
     }
 
     if (wrapping_member_flag) {
@@ -2699,44 +2713,18 @@
       }
     }
 
-    // Write function modifiers.
-    {
-      String *modifiers;
+    // We move the modifiers after the parameter list
+    // as we need the D parametes to catch D override of functions
+    String *param_function_code = NewString("");
 
-      const String *mods_override = Getattr(n, "feature:d:methodmodifiers");
-      if (mods_override) {
-	modifiers = Copy(mods_override);
-      } else {
-	modifiers = Copy(is_public(n) ? public_string : protected_string);
-
-	if (Getattr(n, "override")) {
-	  Printf(modifiers, " override");
-	}
+    if (super) {
+      Printf(imcall, "super.$funcname(");
+    } else {
+      // Write the wrapper function call up to the parameter list.
+      Printv(imcall, im_dmodule_fq_name, ".$imfuncname(", NIL);
+      if (!static_flag) {
+	Printf(imcall, "cast(void*)swigCPtr");
       }
-
-      if (is_smart_pointer()) {
-	// Smart pointer classes do not mirror the inheritance hierarchy of the
-	// underlying pointer type, so no override required.
-	Replaceall(modifiers, "override", "");
-      }
-
-      Chop(modifiers);
-
-      if (static_flag) {
-	Printf(modifiers, " static");
-      }
-
-      Printf(function_code, "%s ", modifiers);
-      Delete(modifiers);
-    }
-
-    // Complete the function declaration up to the parameter list.
-    Printf(function_code, "%s %s(", return_type, proxy_function_name);
-
-    // Write the wrapper function call up to the parameter list.
-    Printv(imcall, im_dmodule_fq_name, ".$imfuncname(", NIL);
-    if (!static_flag) {
-      Printf(imcall, "cast(void*)swigCPtr");
     }
 
     String *proxy_param_types = NewString("");
@@ -2744,16 +2732,18 @@
     // Write the parameter list for the proxy function declaration and the
     // wrapper function call.
     emit_mark_varargs(l);
-    int gencomma = !static_flag;
+    int gencomma = !static_flag && !super;
     for (i = 0, p = l; p; i++) {
       // Ignored varargs.
       if (checkAttribute(p, "varargs:ignore", "1")) {
+	Setattr(p, "d:type", NewString(""));
 	p = nextSibling(p);
 	continue;
       }
 
       // Ignored parameters.
       if (checkAttribute(p, "tmap:in:numinputs", "0")) {
+	Setattr(p, "d:type", NewString(""));
 	p = Getattr(p, "tmap:in:next");
 	continue;
       }
@@ -2809,17 +2799,26 @@
 	  if ((tm = lookupDTypemap(p, "dtype"))) {
 	    const String *inattributes = Getattr(p, "tmap:dtype:inattributes");
 	    Printf(proxy_type, "%s%s", inattributes ? inattributes : empty_string, tm);
+	    {
+	      int ln = Len(package);
+	      /* If proxy_type uses the package name, it must be larger */
+	      if (Len(proxy_type) > ln && Strncmp(package, proxy_type, ln) == 0) {
+		Setattr(p, "d:type", NewString(Char(proxy_type) + ln));
+	      } else {
+		Setattr(p, "d:type", Copy(proxy_type));
+	      }
+	    }
 	  } else {
 	    Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number,
 	      "No dtype typemap defined for %s\n", SwigType_str(pt, 0));
 	  }
 
 	  if (gencomma >= 2) {
-	    Printf(function_code, ", ");
+	    Printf(param_function_code, ", ");
 	    Printf(proxy_param_types, ", ");
 	  }
 	  gencomma = 2;
-	  Printf(function_code, "%s %s", proxy_type, param_name);
+	  Printf(param_function_code, "%s %s", proxy_type, param_name);
 	  Append(proxy_param_types, proxy_type);
 
 	  Delete(proxy_type);
@@ -2830,10 +2829,42 @@
       p = Getattr(p, "tmap:in:next");
     }
 
+    // Complete the function declaration up to the parameter list.
+    // Write function modifiers.
+    {
+      const String *mods_override = Getattr(n, "feature:d:methodmodifiers");
+      bool isPrivate = false;
+      if (mods_override) {
+	isPrivate = Strcmp(mods_override, private_string) == 0;
+      } else {
+	mods_override = is_public(n) ? public_string : protected_string;
+      }
+      String *modifiers = Copy(mods_override);
+      Setattr(n, "dmodify", Copy(mods_override));
+
+      /* private function are never override */
+      if (super || (!isPrivate && isDOverride(n, l))) {
+	Printf(modifiers, " override");
+      }
+
+      Chop(modifiers);
+
+      if (static_flag) {
+	Printf(modifiers, " static");
+      }
+
+      Printf(function_code, "%s ", modifiers);
+      Delete(modifiers);
+    }
+    Printf(function_code, "%s %s(", return_type, proxy_function_name);
+
+    // Add Body the parameter list part after the modifiers
+    Append(function_code, param_function_code);
+
     Printf(imcall, ")");
     Printf(function_code, ") ");
 
-    if (d_version > 1 && wrapping_member_flag) {
+    if (wrapping_member_flag) {
       Printf(function_code, "@property ");
     }
 
@@ -2841,67 +2872,82 @@
       Printf(function_code, "const ");
     }
 
-    // Lookup the code used to convert the wrapper return value to the proxy
-    // function return type.
-    if ((tm = lookupDTypemap(n, "dout"))) {
-      replaceExcode(n, tm, "dout", n);
-      bool is_pre_code = Len(pre_code) > 0;
-      bool is_post_code = Len(post_code) > 0;
-      bool is_terminator_code = Len(terminator_code) > 0;
-      if (is_pre_code || is_post_code || is_terminator_code) {
-	if (is_post_code) {
-	  Insert(tm, 0, "\n  try ");
-	  Printv(tm, " finally {\n", post_code, "\n  }", NIL);
-	} else {
-	  Insert(tm, 0, "\n  ");
-	}
-	if (is_pre_code) {
-	  Insert(tm, 0, pre_code);
-	  Insert(tm, 0, "\n");
-	}
-	if (is_terminator_code) {
-	  Printv(tm, "\n", terminator_code, NIL);
-	}
-	Insert(tm, 0, "{");
-	Printv(tm, "}", NIL);
-      }
-      if (GetFlag(n, "feature:new"))
-	Replaceall(tm, "$owner", "true");
-      else
-	Replaceall(tm, "$owner", "false");
-      replaceClassname(tm, t);
-
-      // For director methods: generate code to selectively make a normal
-      // polymorphic call or an explicit method call. Needed to prevent infinite
-      // recursion when calling director methods.
-      Node *explicit_n = Getattr(n, "explicitcallnode");
-      if (explicit_n && Swig_directorclass(getCurrentClass())) {
-	String *ex_overloaded_name = getOverloadedName(explicit_n);
-	String *ex_intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, ex_overloaded_name);
-
-	String *ex_imcall = Copy(imcall);
-	Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name);
-	Replaceall(imcall, "$imfuncname", intermediary_function_name);
-
-	String *excode = NewString("");
-	if (!Cmp(return_type, "void"))
-	  Printf(excode, "if (swigIsMethodOverridden!(%s delegate(%s), %s function(%s), %s)()) %s; else %s",
-	    return_type, proxy_param_types, return_type, proxy_param_types, proxy_function_name, ex_imcall, imcall);
-	else
-	  Printf(excode, "((swigIsMethodOverridden!(%s delegate(%s), %s function(%s), %s)()) ? %s : %s)",
-	    return_type, proxy_param_types, return_type, proxy_param_types, proxy_function_name, ex_imcall, imcall);
-
-	Clear(imcall);
-	Printv(imcall, excode, NIL);
-	Delete(ex_overloaded_name);
-	Delete(excode);
+    if (super) {
+      Replaceall(imcall, "$funcname", proxy_function_name);
+      if (!Cmp(return_type, "void")) {
+	tm = NewString("{\n  $imcall;\n}");
       } else {
-	Replaceall(imcall, "$imfuncname", intermediary_function_name);
+	tm = NewString("{\n  return $imcall;\n}");
       }
       Replaceall(tm, "$imcall", imcall);
     } else {
-      Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number,
-	"No dout typemap defined for %s\n", SwigType_str(t, 0));
+      // Lookup the code used to convert the wrapper return value to the proxy
+      // function return type.
+      if ((tm = lookupDTypemap(n, "dout"))) {
+	replaceExcode(n, tm, "dout", n);
+	bool is_pre_code = Len(pre_code) > 0;
+	bool is_post_code = Len(post_code) > 0;
+	bool is_terminator_code = Len(terminator_code) > 0;
+	if (is_pre_code || is_post_code || is_terminator_code) {
+	  if (is_post_code) {
+	    Insert(tm, 0, "\n  try ");
+	    Printv(tm, " finally {\n", post_code, "\n  }", NIL);
+	  } else {
+	    Insert(tm, 0, "\n  ");
+	  }
+	  if (is_pre_code) {
+	    Insert(tm, 0, pre_code);
+	    Insert(tm, 0, "\n");
+	  }
+	  if (is_terminator_code) {
+	    Printv(tm, "\n", terminator_code, NIL);
+	  }
+	  Insert(tm, 0, "{");
+	  Printv(tm, "}", NIL);
+	}
+	if (GetFlag(n, "feature:new"))
+	  Replaceall(tm, "$owner", "true");
+	else
+	  Replaceall(tm, "$owner", "false");
+	replaceClassname(tm, t);
+
+	// For director methods: generate code to selectively make a normal
+	// polymorphic call or an explicit method call. Needed to prevent infinite
+	// recursion when calling director methods.
+	Node *explicit_n = Getattr(n, "explicitcallnode");
+	if (explicit_n && Swig_directorclass(getCurrentClass())) {
+	  String *ex_overloaded_name = getOverloadedName(explicit_n);
+	  String *ex_intermediary_function_name = Swig_name_member(getNSpace(), proxy_class_name, ex_overloaded_name);
+
+	  String *ex_imcall = Copy(imcall);
+	  Replaceall(ex_imcall, "$imfuncname", ex_intermediary_function_name);
+	  Replaceall(imcall, "$imfuncname", intermediary_function_name);
+
+	  String *override_use_const = NewString("");
+	  if (wrapMemberFunctionAsDConst(n)) {
+	    Printf(override_use_const, "Const");
+	  }
+	  String *excode = NewString("");
+	  if (!Cmp(return_type, "void"))
+	    Printf(excode, "if (swigIsMethodOverridden%s!(%s delegate(%s), %s function(%s), %s)()) %s; else %s",
+	     override_use_const, return_type, proxy_param_types, return_type, proxy_param_types, proxy_function_name, ex_imcall, imcall);
+	  else
+	    Printf(excode, "((swigIsMethodOverridden%s!(%s delegate(%s), %s function(%s), %s)()) ? %s : %s)",
+	     override_use_const, return_type, proxy_param_types, return_type, proxy_param_types, proxy_function_name, ex_imcall, imcall);
+
+	  Clear(imcall);
+	  Printv(imcall, excode, NIL);
+	  Delete(ex_overloaded_name);
+	  Delete(excode);
+	} else {
+	  Replaceall(imcall, "$imfuncname", intermediary_function_name);
+	}
+	Replaceall(tm, "$imfuncname", intermediary_function_name);
+	Replaceall(tm, "$imcall", imcall);
+      } else {
+	Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number,
+	  "No dout typemap defined for %s\n", SwigType_str(t, 0));
+      }
     }
 
     Delete(proxy_param_types);
@@ -2914,6 +2960,7 @@
     // Write function code buffer to the class code.
     Printv(proxy_class_body_code, "\n", function_code, "\n", NIL);
 
+    Delete(tm);
     Delete(pre_code);
     Delete(post_code);
     Delete(terminator_code);
@@ -2932,7 +2979,6 @@
     Parm *p;
     int i;
     String *imcall = NewString("");
-    String *return_type = NewString("");
     String *function_code = NewString("");
     int num_arguments = 0;
     String *overloaded_name = getOverloadedName(n);
@@ -2953,18 +2999,11 @@
     Swig_typemap_attach_parms("din", l, NULL);
 
     /* Get return types */
-    if ((tm = lookupDTypemap(n, "dtype"))) {
-      String *dtypeout = Getattr(n, "tmap:dtype:out");
-      if (dtypeout) {
-	// The type in the dtype typemap's out attribute overrides the type in
-	// the typemap.
-	tm = dtypeout;
-	replaceClassname(tm, t);
-      }
-      Printf(return_type, "%s", tm);
-    } else {
+    String *return_type = getOutDtype(n);
+    if (!return_type) {
       Swig_warning(WARN_D_TYPEMAP_DTYPE_UNDEF, input_file, line_number,
 	"No dtype typemap defined for %s\n", SwigType_str(t, 0));
+      return_type = NewString("");
     }
 
     /* Change function name for global variables */
@@ -3067,7 +3106,7 @@
     Printf(imcall, ")");
     Printf(function_code, ") ");
 
-    if (global_variable_flag && (d_version > 1)) {
+    if (global_variable_flag) {
       Printf(function_code, "@property ");
     }
 
@@ -3100,6 +3139,7 @@
       else
 	Replaceall(tm, "$owner", "false");
       replaceClassname(tm, t);
+      Replaceall(tm, "$imfuncname", overloaded_name);
       Replaceall(tm, "$imcall", imcall);
     } else {
       Swig_warning(WARN_D_TYPEMAP_DOUT_UNDEF, input_file, line_number,
@@ -3140,11 +3180,11 @@
      * Handle inheriting from D and C++ classes.
      */
 
-    String *c_classname = SwigType_namestr(Getattr(n, "name"));
-    String *c_baseclass = NULL;
-    Node *basenode = NULL;
-    String *basename = NULL;
+    String *c_classname = Getattr(n, "name");
     String *c_baseclassname = NULL;
+    Node *basenode = NULL;
+    String *baseclass = NULL;
+    SwigType *bsmart = 0;
 
     // Inheritance from pure D classes.
     Node *attributes = NewHash();
@@ -3161,13 +3201,15 @@
 	Iterator base = First(baselist);
 	while (base.item) {
 	  if (!GetFlag(base.item, "feature:ignore")) {
-	    String *baseclassname = Getattr(base.item, "name");
+	    SwigType *baseclassname = Getattr(base.item, "name");
 	    if (!c_baseclassname) {
 	      basenode = base.item;
-	      c_baseclassname = baseclassname;
-	      basename = createProxyName(c_baseclassname);
-	      if (basename)
-		c_baseclass = SwigType_namestr(baseclassname);
+	      String *name = createProxyName(baseclassname);
+	      if (name) {
+		c_baseclassname = baseclassname;
+		baseclass = name;
+		bsmart = Getattr(base.item, "smart");
+	      }
 	    } else {
 	      /* Warn about multiple inheritance for additional base class(es) */
 	      String *proxyclassname = Getattr(n, "classtypeobj");
@@ -3180,25 +3222,24 @@
       }
     }
 
-    bool derived = (basename != NULL);
+    bool derived = baseclass != NULL;
 
     if (derived && purebase_notderived) {
       pure_baseclass = empty_string;
     }
-    const String *wanted_base = basename ? basename : pure_baseclass;
+    const String *wanted_base = baseclass ? baseclass : pure_baseclass;
 
     if (purebase_replace) {
       wanted_base = pure_baseclass;
       derived = false;
       basenode = NULL;
-      Delete(basename);
-      basename = NULL;
+      baseclass = NULL;
       if (purebase_notderived) {
 	Swig_error(Getfile(n), Getline(n),
 	  "The dbase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n",
 	  typemap_lookup_type);
       }
-    } else if (basename && Len(pure_baseclass) > 0) {
+    } else if (baseclass && Len(pure_baseclass) > 0) {
       Swig_warning(WARN_D_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
 	"Warning for %s, base class %s ignored. Multiple inheritance is not supported in D. "
 	"Perhaps you need one of the 'replace' or 'notderived' attributes in the dbase typemap?\n", typemap_lookup_type, pure_baseclass);
@@ -3206,7 +3247,7 @@
 
     // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy)
     if (derived) {
-      writeClassUpcast(n, proxy_class_name, c_classname, c_baseclass);
+      writeClassUpcast(n, bsmart, proxy_class_name, c_classname, c_baseclassname);
     }
 
     /*
@@ -3354,8 +3395,7 @@
     // Write the class body and the curly bracket closing the class definition
     // to the proxy module.
     indentCode(body);
-    Replaceall(body, "$dbaseclass", basename);
-    Delete(basename);
+    Replaceall(body, "$dbaseclass", baseclass);
 
     Printv(proxy_class_code, body, "\n}\n", NIL);
     Delete(body);
@@ -3368,48 +3408,48 @@
   /* ---------------------------------------------------------------------------
    * D::writeClassUpcast()
    * --------------------------------------------------------------------------- */
-  void writeClassUpcast(Node *n, const String* d_class_name, String* c_class_name, String* c_base_name) {
+  void writeClassUpcast(Node *n, SwigType *bsmart, const String *d_class_name, SwigType *c_classname, SwigType *c_baseclassname) {
 
-    SwigType *smart = Swig_cparse_smartptr(n);
+    SwigType *smart = Getattr(n, "smart");
     String *upcast_name = Swig_name_member(getNSpace(), d_class_name, (smart != 0 ? "SmartPtrUpcast" : "Upcast"));
     String *upcast_wrapper_name = Swig_name_wrapper(upcast_name);
 
-    writeImDModuleFunction(upcast_name, "void*", "(void* objectRef)",
-      upcast_wrapper_name);
+    writeImDModuleFunction(upcast_name, "void*", "(void* objectRef)", upcast_wrapper_name);
+
+    String *classname = SwigType_namestr(c_classname);
+    String *baseclassname = SwigType_namestr(c_baseclassname);
 
     if (smart) {
-      SwigType *bsmart = Copy(smart);
-      SwigType *rclassname = SwigType_typedef_resolve_all(c_class_name);
-      SwigType *rbaseclass = SwigType_typedef_resolve_all(c_base_name);
-      Replaceall(bsmart, rclassname, rbaseclass);
-      Delete(rclassname);
-      Delete(rbaseclass);
-      String *smartnamestr = SwigType_namestr(smart);
-      String *bsmartnamestr = SwigType_namestr(bsmart);
-      Printv(upcasts_code,
-	"SWIGEXPORT ", bsmartnamestr, " * ", upcast_wrapper_name,
-	  "(", smartnamestr, " *objectRef) {\n",
-	"    return objectRef ? new ", bsmartnamestr, "(*objectRef) : 0;\n"
-	"}\n",
-	"\n", NIL);
-      Delete(bsmartnamestr);
-      Delete(smartnamestr);
-      Delete(bsmart);
+      if (bsmart) {
+	String *smartnamestr = SwigType_namestr(smart);
+	String *bsmartnamestr = SwigType_namestr(bsmart);
+
+	Printv(upcasts_code,
+	  "SWIGEXPORT ", bsmartnamestr, " * ", upcast_wrapper_name,
+	    "(", smartnamestr, " *objectRef) {\n",
+	  "    return objectRef ? new ", bsmartnamestr, "(*objectRef) : 0;\n"
+	  "}\n",
+	  "\n", NIL);
+
+	Delete(bsmartnamestr);
+	Delete(smartnamestr);
+      }
     } else {
       Printv(upcasts_code,
-	"SWIGEXPORT ", c_base_name, " * ", upcast_wrapper_name,
-	  "(", c_base_name, " *objectRef) {\n",
-	"    return (", c_base_name, " *)objectRef;\n"
+	"SWIGEXPORT ", baseclassname, " * ", upcast_wrapper_name,
+	  "(", classname, " *objectRef) {\n",
+	"    return (", baseclassname, " *)objectRef;\n"
 	"}\n",
 	"\n", NIL);
     }
 
-    Replaceall(upcasts_code, "$cclass", c_class_name);
-    Replaceall(upcasts_code, "$cbaseclass", c_base_name);
+    Replaceall(upcasts_code, "$cclass", classname);
+    Replaceall(upcasts_code, "$cbaseclass", baseclassname);
 
-    Delete(upcast_name);
+    Delete(baseclassname);
+    Delete(classname);
     Delete(upcast_wrapper_name);
-    Delete(smart);
+    Delete(upcast_name);
   }
 
   /* ---------------------------------------------------------------------------
@@ -3430,7 +3470,7 @@
       class_file = NewFile(filename, "w", SWIG_output_files());
       if (!class_file) {
 	FileErrorDisplay(filename);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       Append(filenames_list, Copy(filename));
       Delete(filename);
@@ -3533,7 +3573,11 @@
     // Only emit it if the proxy class has at least one method.
     if (first_class_dmethod < curr_class_dmethod) {
       Printf(proxy_class_body_code, "\n");
-      Printf(proxy_class_body_code, "private bool swigIsMethodOverridden(DelegateType, FunctionType, alias fn)() %s{\n", (d_version > 1) ? "const " : "");
+      Printf(proxy_class_body_code, "private bool swigIsMethodOverridden(DelegateType, FunctionType, alias fn)() {\n");
+      Printf(proxy_class_body_code, "  DelegateType dg = &fn;\n");
+      Printf(proxy_class_body_code, "  return dg.funcptr != SwigNonVirtualAddressOf!(FunctionType, fn);\n");
+      Printf(proxy_class_body_code, "}\n");
+      Printf(proxy_class_body_code, "private bool swigIsMethodOverriddenConst(DelegateType, FunctionType, alias fn)() inout {\n");
       Printf(proxy_class_body_code, "  DelegateType dg = &fn;\n");
       Printf(proxy_class_body_code, "  return dg.funcptr != SwigNonVirtualAddressOf!(FunctionType, fn);\n");
       Printf(proxy_class_body_code, "}\n");
@@ -3558,6 +3602,38 @@
   }
 
   /* ---------------------------------------------------------------------------
+   * D::writeDirectorSuperFunctions()
+   *
+   * Writes super methods for protected methods in virtual table
+   * which are not implemented in class.
+   * So the director connect function can call them.
+   * As function outside the class, can call module protected methods
+   *  but not protected of clases outside this module!
+   * --------------------------------------------------------------------------- */
+  // TODO WORK
+  void writeDirectorSuperFunctions(Node *n) {
+    if (!Swig_directorclass(n))
+      return;
+
+    Node *vtable = Getattr(n, "vtable");
+    int len = Len(vtable);
+    for (int i = 0; i < len; i++) {
+      Node *item = Getitem(vtable, i);
+      if (GetFlag(item, "director")) {
+	Node *method = Getattr(item, "methodNode");
+	Node *p = parentNode(method);
+	if (p && p != n && is_protected(method)) {
+	  const String *nodeType = nodeType(method);
+	  if (Strcmp(nodeType, "cdecl") == 0) {
+	    Setattr(method, "proxyfuncname", Getattr(method, "sym:name"));
+	    writeProxyClassFunction(method, true);
+	  }
+	}
+      }
+    }
+  }
+
+  /* ---------------------------------------------------------------------------
    * D::writeDirectorConnectWrapper()
    *
    * Writes the director connect function and the corresponding declaration to
@@ -3752,7 +3828,7 @@
 	Swig_error(input_file, line_number,
 	  "Class name cannot be equal to intermediary D module name: %s\n",
 	  class_name);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
 
       String *nspace = getNSpace();
@@ -3765,7 +3841,7 @@
 	    Swig_error(input_file, line_number,
 	      "Class name cannot be the same as the root package it is in: %s\n",
 	      class_name);
-	    SWIG_exit(EXIT_FAILURE);
+	    Exit(EXIT_FAILURE);
 	  }
 	  Delete(dotless_package);
 	} else {
@@ -3774,7 +3850,7 @@
 	    Swig_error(input_file, line_number,
 	      "Class name cannot be the same as the outermost namespace it is in: %s\n",
 	      class_name);
-	    SWIG_exit(EXIT_FAILURE);
+	    Exit(EXIT_FAILURE);
 	  }
 	  Delete(outer);
 	}
@@ -3786,7 +3862,7 @@
 	  Swig_error(input_file, line_number,
 	    "Class name cannot be the same as the innermost namespace it is in: %s\n",
 	    class_name);
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	}
 	Delete(inner);
       } else {
@@ -3794,7 +3870,7 @@
 	  Swig_error(input_file, line_number,
 	    "Class name cannot be equal to proxy D module name: %s\n",
 	    class_name);
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	}
       }
     }
@@ -4280,6 +4356,7 @@
    * D::getOverloadedName()
    * --------------------------------------------------------------------------- */
   String *getOverloadedName(Node *n) const {
+
     // A void* parameter is used for all wrapped classes in the wrapper code.
     // Thus, the wrapper function names for overloaded functions are postfixed
     // with a counter string to make them unique.
@@ -4348,7 +4425,6 @@
    * wrapped as D »const« or not.
    * --------------------------------------------------------------------------- */
   bool wrapMemberFunctionAsDConst(Node *n) const {
-    if (d_version == 1) return false;
     if (static_flag) return false; // Never emit »const« for static member functions.
     return GetFlag(n, "memberget") || SwigType_isconst(Getattr(n, "decl"));
   }
@@ -4422,6 +4498,159 @@
   }
 
   /* ---------------------------------------------------------------------------
+   * D::checkClassBaseOver()
+   *
+   * Search a class for a method that can override the current method.
+   * --------------------------------------------------------------------------- */
+  bool checkClassBaseOver(Node *b, const String *name, ParmList *l, const int llen, const String *bname = NULL)
+  {
+    if (bname == NULL) {
+      bname = Getattr(b, "name");
+    }
+    for(Node *e = firstChild(b); e; e = nextSibling(e)) {
+      /* We look for D only fuctions! */
+      const String *ename = Getattr(e, "name");
+      const String *etype = nodeType(e);
+      if (Strcmp(etype, "extend") == 0) {
+	/* extend of class do not have a name attribute,
+	 * it is the same class. */
+	if (checkClassBaseOver(e, name, l, llen, bname)) {
+	  return true;
+	}
+      } else if (Strcmp(etype, "cdecl") == 0 || Strcmp(etype, "using") == 0) {
+	/* 'using' is marked in markDOverride() same as 'cdecl' */
+	if (Strcmp(name, ename) == 0) {
+	  if (GetFlag(e, "d:override_property")) {
+	    return true;
+	  }
+	  /* Do we need a full compare of ParmList? How about in typemaps? */
+	  ParmList *el = Getattr(e, "d:override_parms");
+	  const int ellen = ParmList_len(el);
+	  if (GetFlag(e, "d:can_override") && ellen == llen) {
+	    bool eq = true;
+	    String *detd = NewString("");
+	    if (llen > 0) {
+	      for(ParmList *le = el, *ln = l; eq && le && ln; le = nextSibling(le), ln = nextSibling(ln)) {
+		const String *ntd = Getattr(ln, "d:type");
+		const String *etd = Getattr(le, "d:type");
+		Printf(detd, "%s.%s", etd, etd);
+		/* Parameter types are equal, or the type is 'class.class' */
+		eq = etd && ntd && (Strcmp(ntd, etd) == 0 || Strcmp(ntd, detd) == 0);
+	      }
+	    }
+	    Delete(detd);
+	    if (eq) {
+	      return true;
+	    }
+	  }
+	}
+      }
+    }
+    return false;
+  }
+
+  /* ---------------------------------------------------------------------------
+   * D::checkBaseOver()
+   *
+   * Traverse all base classes and look for a method the current method override.
+   * --------------------------------------------------------------------------- */
+  bool checkBaseOver(Node *c, const String *name, ParmList *l, const int llen)
+  {
+    // * Member template functions?
+    if (!c) {
+      return false;
+    }
+    List *bases = Getattr(c, "bases");
+    if (!bases) {
+      return false;
+    }
+    for (int i = 0; i < Len(bases); i++) {
+      Node *b = Getitem(bases, i);
+      if (checkClassBaseOver(b, name, l, llen)) {
+	return true;
+      }
+      if (checkBaseOver(b, name, l, llen)) {
+	return true;
+      }
+    }
+    return false;
+  }
+
+  /* ---------------------------------------------------------------------------
+   * D::markDOverride()
+   *
+   * Mark current method for methods in derived classes.
+   * --------------------------------------------------------------------------- */
+  void markDOverride(Node *n, const String *name, ParmList *l, Node *p, const String *pname, const String *ptype) {
+     if (!pname && Strcmp(ptype, "extend") == 0) {
+       Node *pp = parentNode(p);
+       if (pp) {
+	 pname = Getattr(pp, "name");
+       }
+     }
+    for(Node *e = firstChild(p); e; e = nextSibling(e)) {
+      /* Am I in my class? */
+      if (n == e) {
+	SetFlag(n, "d:can_override");
+	if (wrapping_member_flag) {
+	  SetFlag(n, "d:override_property");
+	} else {
+	  Setattr(n, "d:override_parms", CopyParmList(l));
+	}
+	return;
+      }
+    }
+    /*
+     * I am a 'using' method.
+     * Our method is using a method definition from a different class.
+     * We need to mark the original 'using' method in our class,
+     * as this node is not accessibale in derived classes.
+     */
+    for(Node *e = firstChild(p); e; e = nextSibling(e)) {
+      const String *ename = Getattr(e, "name");
+      const String *ntype = nodeType(e);
+      if (ename && Strcmp(ename, name) == 0 && ntype && Strcmp(ntype, "using") == 0) {
+	SetFlag(e, "d:can_override");
+	Setattr(e, "d:override_parms", CopyParmList(l));
+	return;
+      }
+    }
+  }
+
+  /* ---------------------------------------------------------------------------
+   * D::isDOverride()
+   *
+   * Override should be used for override D existing method.
+   * Class D methods, non static and non private.
+   * Check if current method override,
+   * anf mark it for derived classes use.
+   * --------------------------------------------------------------------------- */
+  bool isDOverride(Node *n, ParmList *l) {
+    if (is_smart_pointer()) {
+      /* Smart pointer classes do not mirror the inheritance hierarchy of the
+       * underlying pointer type, so no override required. */
+      return false;
+    }
+    if (static_flag) { /* Static are never override */
+      return false;
+    }
+    Node *p = parentNode(n);
+    if (!p) {
+      return false;
+    }
+    const String *name = Getattr(n, "name");
+    const int llen = ParmList_len(l);
+    const String *ptype = nodeType(p);
+    const String *pname = Getattr(p, "name");
+    markDOverride(n, name, l, p, pname, ptype);
+    if (Strcmp(ptype, "extend") == 0) {
+      /* The 'bases' are in the class we extend */
+      p = parentNode(p);
+    }
+    return checkBaseOver(p, name, l, llen);
+  }
+
+  /* ---------------------------------------------------------------------------
    * D::overridingOverloadCount()
    *
    * Given a member function node, this function counts how many of the
@@ -4477,6 +4706,27 @@
     Printf(f, "/* ----------------------------------------------------------------------------\n");
     Swig_banner_target_lang(f, " *");
     Printf(f, " * ----------------------------------------------------------------------------- */\n\n");
+    Printv(f, common_begin_code, NIL);
+  }
+
+  /* ---------------------------------------------------------------------------
+   * D::getOutDtype()
+   *
+   * Returns the return (out) D type and check the Dtype out typemap.
+   * --------------------------------------------------------------------------- */
+  String *getOutDtype(Node *n) {
+    String *result = lookupDTypemap(n, "dtype");
+    if (result) {
+      String *dtypeout = Copy(Getattr(n, "tmap:dtype:out"));
+      if (dtypeout) {
+	/* The type in the out attribute of the typemap overrides the type
+	 * in the dtype typemap. */
+	Delete(result);
+	result = dtypeout;
+	replaceClassname(result, Getattr(n, "type"));
+      }
+    }
+    return result;
   }
 
   /* ---------------------------------------------------------------------------
@@ -4494,7 +4744,7 @@
       if (newdir_error) {
 	Printf(stderr, "%s\n", newdir_error);
 	Delete(newdir_error);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       Printv(output_directory, nspace_subdirectory, SWIG_FILE_DELIMITER, 0);
       Delete(nspace_subdirectory);
@@ -4553,7 +4803,7 @@
     char *tmp = Char(nspace);
     char *c = tmp;
     char *co = 0;
-    if (!strstr(c, "."))
+    if (!strchr(c, '.'))
       return 0;
 
     co = c + Len(nspace);
@@ -4580,7 +4830,7 @@
     if (!nspace) return NULL;
     char *c = Char(nspace);
     char *cc = c;
-    if (!strstr(c, "."))
+    if (!strchr(c, '.'))
       return NewString(nspace);
 
     while (*c) {
@@ -4603,7 +4853,7 @@
     char *tmp = Char(nspace);
     char *c = tmp;
     char *cc = c;
-    if (!strstr(c, "."))
+    if (!strchr(c, '.'))
       return NULL;
 
     while (*c) {
@@ -4635,7 +4885,7 @@
  * ----------------------------------------------------------------------------- */
 const char *D::usage = "\
 D Options (available with -d)\n\
-     -d2                  - Generate code for D2/Phobos (default: D1/Tango)\n\
+     -d2                  - Generate code for D2/Phobos (The default, left for backward compatibility)\n\
      -package <pkg>       - Write generated D modules into package <pkg>\n\
      -splitproxy          - Write each D type to a dedicated file instead of\n\
                             generating a single proxy D module.\n\
diff --git a/Source/Modules/directors.cxx b/Source/Modules/directors.cxx
index a91d5fd..14e2e84 100644
--- a/Source/Modules/directors.cxx
+++ b/Source/Modules/directors.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * directors.cxx
  *
@@ -97,7 +97,6 @@
 
 String *Swig_method_call(const_String_or_char_ptr name, ParmList *parms) {
   String *func;
-  int i = 0;
   int comma = 0;
   Parm *p = parms;
   SwigType *pt;
@@ -115,7 +114,6 @@
       pname = Getattr(p, "name");
       Printf(func, "%s", pname);
       comma = 1;
-      i++;
     }
     p = nextSibling(p);
   }
@@ -160,7 +158,7 @@
     SwigType *rettype_stripped = SwigType_strip_qualifiers(rettype);
     String *rtype = SwigType_str(rettype, 0);
     Append(result, rtype);
-    if (SwigType_issimple(rettype_stripped) && return_base_type)
+    if ((SwigType_issimple(rettype_stripped) && return_base_type) || SwigType_isqualifier(rettype))
       Append(result, " ");
     Delete(rtype);
     Delete(rettype_stripped);
@@ -175,10 +173,6 @@
   if (qualifiers)
     Printv(result, " ", qualifiers, NIL);
 
-  // Reformat result to how it has been historically
-  Replaceall(result, ",", ", ");
-  Replaceall(result, "=", " = ");
-
   Delete(args_string);
   Delete(popped_decl);
   Delete(qualifiers);
@@ -239,3 +233,38 @@
   }
 }
 
+/* -----------------------------------------------------------------------------
+ * Swig_director_can_unwrap()
+ *
+ * Determine whether a function's return type can be returned as an existing
+ * target language object instead of creating a new target language object.
+ * Must be a director class and only for return by pointer or reference only
+ * (not by value or by pointer to pointer etc).
+ * ----------------------------------------------------------------------------- */
+
+bool Swig_director_can_unwrap(Node *n) {
+
+  // FIXME: this will not try to unwrap directors returned as non-director
+  //        base class pointers!
+
+  bool unwrap = false;
+
+  String *type = Getattr(n, "type");
+  SwigType *t = SwigType_typedef_resolve_all(type);
+  SwigType *t1 = SwigType_strip_qualifiers(t);
+  SwigType *prefix = SwigType_prefix(t1);
+
+  if (Strcmp(prefix, "p.") == 0 || Strcmp(prefix, "r.") == 0) {
+    Node *parent = Swig_methodclass(n);
+    Node *module = Getattr(parent, "module");
+    Node *target = Swig_directormap(module, t1);
+    if (target)
+      unwrap = true;
+  }
+
+  Delete(prefix);
+  Delete(t1);
+  Delete(t);
+
+  return unwrap;
+}
diff --git a/Source/Modules/emit.cxx b/Source/Modules/emit.cxx
index 7a4c2dc..7039196 100644
--- a/Source/Modules/emit.cxx
+++ b/Source/Modules/emit.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * emit.cxx
  *
@@ -64,8 +64,6 @@
   Swig_cargs(f, l);
 
   /* Attach typemaps to parameters */
-  /*  Swig_typemap_attach_parms("ignore",l,f); */
-
   Swig_typemap_attach_parms("default", l, f);
   Swig_typemap_attach_parms("arginit", l, f);
 
@@ -74,7 +72,6 @@
   while (p) {
     tm = Getattr(p, "tmap:arginit");
     if (tm) {
-      Replace(tm, "$target", Getattr(p, "lname"), DOH_REPLACE_ANY);
       Printv(f->code, tm, "\n", NIL);
       p = Getattr(p, "tmap:arginit:next");
     } else {
@@ -87,7 +84,6 @@
   while (p) {
     tm = Getattr(p, "tmap:default");
     if (tm) {
-      Replace(tm, "$target", Getattr(p, "lname"), DOH_REPLACE_ANY);
       Printv(f->code, tm, "\n", NIL);
       p = Getattr(p, "tmap:default:next");
     } else {
@@ -110,20 +106,14 @@
   Swig_typemap_attach_parms("freearg", l, f);
 
   {
-    /* This is compatibility code to deal with the deprecated "ignore" typemap */
+    /* Handle in typemaps with numinputs=0. */
     Parm *p = l;
-    Parm *np;
     while (p) {
       String *tm = Getattr(p, "tmap:in");
-      if (tm && checkAttribute(p, "tmap:in:numinputs", "0")) {
-	Replaceall(tm, "$target", Getattr(p, "lname"));
-	Printv(f->code, tm, "\n", NIL);
-	np = Getattr(p, "tmap:in:next");
-	while (p && (p != np)) {
-	  /*	  Setattr(p,"ignore","1");    Deprecate */
-	  p = nextSibling(p);
+      if (tm) {
+	if (checkAttribute(p, "tmap:in:numinputs", "0")) {
+	  Printv(f->code, tm, "\n", NIL);
 	}
-      } else if (tm) {
 	p = Getattr(p, "tmap:in:next");
       } else {
 	p = nextSibling(p);
@@ -140,14 +130,6 @@
     while (p) {
       npin = Getattr(p, "tmap:in:next");
 
-      /*
-         if (Getattr(p,"tmap:ignore")) {
-         npin = Getattr(p,"tmap:ignore:next");
-         } else if (Getattr(p,"tmap:in")) {
-         npin = Getattr(p,"tmap:in:next");
-         }
-       */
-
       if (Getattr(p, "tmap:freearg")) {
 	npfreearg = Getattr(p, "tmap:freearg:next");
 	if (npin != npfreearg) {
@@ -414,7 +396,7 @@
   if (tm)
     tm = Copy(tm);
   if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
-    if (Strstr(tm, "$")) {
+    if (Strchr(tm, '$')) {
       Swig_replace_special_variables(n, parentNode(n), tm);
       Replaceall(tm, "$function", eaction); // deprecated
       Replaceall(tm, "$action", eaction);
@@ -534,13 +516,6 @@
     }
   }
 
-  /* Look for except typemap (Deprecated) */
-  tm = Swig_typemap_lookup("except", n, Swig_cresult_name(), 0);
-  if (tm) {
-    Setattr(n, "feature:except", tm);
-    tm = 0;
-  }
-
   /* emit the except feature code */
   emit_action_code(n, actioncode, eaction);
 
diff --git a/Source/Modules/go.cxx b/Source/Modules/go.cxx
index 0163f71..bbc9808 100644
--- a/Source/Modules/go.cxx
+++ b/Source/Modules/go.cxx
@@ -1,6 +1,10 @@
 /* -----------------------------------------------------------------------------
- * See the LICENSE file for information on copyright, usage and redistribution
- * of SWIG, and the README file for authors - http://www.swig.org/release.html.
+ * This file is part of SWIG, which is licensed as a whole under version 3
+ * (or any later version) of the GNU General Public License. Some additional
+ * terms also apply to certain portions of SWIG. The full details of the SWIG
+ * license and copyrights can be found in the LICENSE and COPYRIGHT files
+ * included with the SWIG source code as distributed by the SWIG developers
+ * and at https://www.swig.org/legal.html.
  *
  * go.cxx
  *
@@ -115,8 +119,6 @@
   String *package;
   // SWIG module name.
   String *module;
-  // Flag for generating cgo input files.
-  bool cgo_flag;
   // Flag for generating gccgo output.
   bool gccgo_flag;
   // Prefix to use with gccgo.
@@ -137,7 +139,6 @@
   /* Output files */
   File *f_c_begin;
   File *f_go_begin;
-  File *f_gc_begin;
 
   /* Output fragments */
   File *f_c_runtime;
@@ -151,9 +152,6 @@
   File *f_go_header;
   File *f_go_wrappers;
   File *f_go_directors;
-  File *f_gc_runtime;
-  File *f_gc_header;
-  File *f_gc_wrappers;
   File *f_cgo_comment;
   File *f_cgo_comment_typedefs;
 
@@ -201,7 +199,6 @@
 public:
   GO():package(NULL),
      module(NULL),
-     cgo_flag(true),
      gccgo_flag(false),
      go_prefix(NULL),
      prefix_option(NULL),
@@ -212,7 +209,6 @@
      intgo_type_size(0),
      f_c_begin(NULL),
      f_go_begin(NULL),
-     f_gc_begin(NULL),
      f_c_runtime(NULL),
      f_c_header(NULL),
      f_c_wrappers(NULL),
@@ -224,9 +220,6 @@
      f_go_header(NULL),
      f_go_wrappers(NULL),
      f_go_directors(NULL),
-     f_gc_runtime(NULL),
-     f_gc_header(NULL),
-     f_gc_wrappers(NULL),
      f_cgo_comment(NULL),
      f_cgo_comment_typedefs(NULL),
      saw_import(false),
@@ -244,7 +237,7 @@
      go_imports(NULL),
      unique_id(NULL) {
     director_multiple_inheritance = 1;
-    director_language = 1;
+    directorLanguage();
     director_prot_ctor_code = NewString("_swig_gopanic(\"accessing abstract class or protected constructor\");");
   }
 
@@ -255,7 +248,7 @@
   virtual void main(int argc, char *argv[]) {
 
     SWIG_library_directory("go");
-    bool display_help = false;
+    bool saw_nocgo_flag = false;
 
     // Process command line options.
     for (int i = 1; i < argc; i++) {
@@ -271,10 +264,9 @@
 	  }
 	} else if (strcmp(argv[i], "-cgo") == 0) {
 	  Swig_mark_arg(i);
-	  cgo_flag = true;
 	} else if (strcmp(argv[i], "-no-cgo") == 0) {
 	  Swig_mark_arg(i);
-	  cgo_flag = false;
+	  saw_nocgo_flag = true;
 	} else if (strcmp(argv[i], "-gccgo") == 0) {
 	  Swig_mark_arg(i);
 	  gccgo_flag = true;
@@ -340,12 +332,16 @@
 	    Swig_arg_error();
 	  }
 	} else if (strcmp(argv[i], "-help") == 0) {
-	  display_help = true;
 	  Printf(stdout, "%s\n", usage);
 	}
       }
     }
 
+    if (saw_nocgo_flag) {
+      Printf(stderr, "SWIG -go: -no-cgo option is no longer supported\n");
+      Exit(EXIT_FAILURE);
+    }
+
     if (gccgo_flag && !pkgpath_option && !prefix_option) {
       prefix_option = NewString("go");
     }
@@ -353,22 +349,10 @@
     // Add preprocessor symbol to parser.
     Preprocessor_define("SWIGGO 1", 0);
 
-    if (cgo_flag) {
-      Preprocessor_define("SWIGGO_CGO 1", 0);
-    }
-
     if (gccgo_flag) {
       Preprocessor_define("SWIGGO_GCCGO 1", 0);
     }
 
-    // This test may be removed in the future, when we can assume that
-    // everybody has upgraded to Go 1.1.  The code below is prepared
-    // for this test to simply be taken out.
-    if (intgo_type_size == 0 && !display_help) {
-      Printf(stderr, "SWIG -go: -intgosize option required but not specified\n");
-      SWIG_exit(EXIT_FAILURE);
-    }
-
     if (intgo_type_size == 32) {
       Preprocessor_define("SWIGGO_INTGO_SIZE 32", 0);
     } else if (intgo_type_size == 64) {
@@ -387,7 +371,7 @@
   /* ---------------------------------------------------------------------
    * top()
    *
-   * For 6g/8g, we are going to create the following files:
+   * For gc, we are going to create the following files:
    *
    * 1) A .c or .cxx file compiled with gcc.  This file will contain
    *    function wrappers.  Each wrapper will take a pointer to a
@@ -458,18 +442,12 @@
     String *go_filename = NewString("");
     Printf(go_filename, "%s%s.go", SWIG_output_directory(), module);
 
-    String *gc_filename = NULL;
-    if (!gccgo_flag) {
-      gc_filename = NewString("");
-      Printf(gc_filename, "%s%s_gc.c", SWIG_output_directory(), module);
-    }
-
     // Generate a unique ID based on a hash of the SWIG input.
     swig_uint64 hash = {0, 0};
     FILE *swig_input = Swig_open(swig_filename);
     if (swig_input == NULL) {
       FileErrorDisplay(swig_filename);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
     String *swig_input_content = Swig_read_file(swig_input);
     siphash(&hash, Char(swig_input_content), Len(swig_input_content));
@@ -483,33 +461,25 @@
     f_c_begin = NewFile(c_filename, "w", SWIG_output_files());
     if (!f_c_begin) {
       FileErrorDisplay(c_filename);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       if (!c_filename_h) {
 	Printf(stderr, "Unable to determine outfile_h\n");
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       f_c_directors_h = NewFile(c_filename_h, "w", SWIG_output_files());
       if (!f_c_directors_h) {
 	FileErrorDisplay(c_filename_h);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
     }
 
     f_go_begin = NewFile(go_filename, "w", SWIG_output_files());
     if (!f_go_begin) {
       FileErrorDisplay(go_filename);
-      SWIG_exit(EXIT_FAILURE);
-    }
-
-    if (!gccgo_flag && !cgo_flag) {
-      f_gc_begin = NewFile(gc_filename, "w", SWIG_output_files());
-      if (!f_gc_begin) {
-	FileErrorDisplay(gc_filename);
-	SWIG_exit(EXIT_FAILURE);
-      }
+      Exit(EXIT_FAILURE);
     }
 
     f_c_runtime = NewString("");
@@ -522,15 +492,8 @@
     f_go_header = NewString("");
     f_go_wrappers = NewString("");
     f_go_directors = NewString("");
-    if (!gccgo_flag && !cgo_flag) {
-      f_gc_runtime = NewString("");
-      f_gc_header = NewString("");
-      f_gc_wrappers = NewString("");
-    }
-    if (cgo_flag) {
-      f_cgo_comment = NewString("");
-      f_cgo_comment_typedefs = NewString("");
-    }
+    f_cgo_comment = NewString("");
+    f_cgo_comment_typedefs = NewString("");
 
     Swig_register_filebyname("begin", f_c_begin);
     Swig_register_filebyname("runtime", f_c_runtime);
@@ -545,18 +508,13 @@
     Swig_register_filebyname("go_header", f_go_header);
     Swig_register_filebyname("go_wrapper", f_go_wrappers);
     Swig_register_filebyname("go_director", f_go_directors);
-    if (!gccgo_flag && !cgo_flag) {
-      Swig_register_filebyname("gc_begin", f_gc_begin);
-      Swig_register_filebyname("gc_runtime", f_gc_runtime);
-      Swig_register_filebyname("gc_header", f_gc_header);
-      Swig_register_filebyname("gc_wrapper", f_gc_wrappers);
-    }
-    if (cgo_flag) {
-      Swig_register_filebyname("cgo_comment", f_cgo_comment);
-      Swig_register_filebyname("cgo_comment_typedefs", f_cgo_comment_typedefs);
-    }
+    Swig_register_filebyname("cgo_comment", f_cgo_comment);
+    Swig_register_filebyname("cgo_comment_typedefs", f_cgo_comment_typedefs);
 
     Swig_banner(f_c_begin);
+
+    Swig_obligatory_macros(f_c_runtime, "GO");
+
     if (CPlusPlus) {
       Printf(f_c_begin, "\n// source: %s\n\n", swig_filename);
     } else {
@@ -564,11 +522,12 @@
     }
 
     Printf(f_c_runtime, "#define SWIGMODULE %s\n", module);
+
     if (gccgo_flag) {
       Printf(f_c_runtime, "#define SWIGGO_PREFIX %s\n", go_prefix);
     }
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Printf(f_c_runtime, "#define SWIG_DIRECTORS\n");
 
       Swig_banner(f_c_directors_h);
@@ -587,34 +546,18 @@
     Swig_banner(f_go_begin);
     Printf(f_go_begin, "\n// source: %s\n", swig_filename);
 
-    if (!gccgo_flag && !cgo_flag && soname) {
-      Swig_banner(f_gc_begin);
-      Printf(f_gc_begin, "\n/* source: %s */\n\n", swig_filename);
-      Printf(f_gc_begin, "\n/* This file should be compiled with 6c/8c.  */\n");
-      Printf(f_gc_begin, "#pragma dynimport _ _ \"%s\"\n", soname);
-    }
+    Printv(f_cgo_comment_typedefs, "/*\n", NULL);
 
-    if (cgo_flag) {
-      Printv(f_cgo_comment_typedefs, "/*\n", NULL);
-
-      // The cgo program defines the intgo type after our function
-      // definitions, but we want those definitions to be able to use
-      // intgo also.
-      Printv(f_cgo_comment_typedefs, "#define intgo swig_intgo\n", NULL);
-      Printv(f_cgo_comment_typedefs, "typedef void *swig_voidp;\n", NULL);
-    }
+    // The cgo program defines the intgo type after our function
+    // definitions, but we want those definitions to be able to use
+    // intgo also.
+    Printv(f_cgo_comment_typedefs, "#define intgo swig_intgo\n", NULL);
+    Printv(f_cgo_comment_typedefs, "typedef void *swig_voidp;\n", NULL);
 
     // Output module initialization code.
 
     Printf(f_go_begin, "\npackage %s\n\n", getModuleName(package));
 
-    if (gccgo_flag && !cgo_flag) {
-      Printf(f_go_runtime, "func SwigCgocall()\n");
-      Printf(f_go_runtime, "func SwigCgocallDone()\n");
-      Printf(f_go_runtime, "func SwigCgocallBack()\n");
-      Printf(f_go_runtime, "func SwigCgocallBackDone()\n\n");
-    }
-
     // All the C++ wrappers should be extern "C".
 
     Printv(f_c_wrappers, "#ifdef __cplusplus\n", "extern \"C\" {\n", "#endif\n\n", NULL);
@@ -630,7 +573,7 @@
 
     Language::top(n);
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       // Insert director runtime into the f_runtime file (make it occur before %header section)
       Swig_insert_file("director_common.swg", f_c_runtime);
       Swig_insert_file("director.swg", f_c_runtime);
@@ -673,7 +616,7 @@
 
     Dump(f_c_header, f_c_runtime);
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Printf(f_c_directors_h, "#endif\n");
       Delete(f_c_directors_h);
       f_c_directors_h = NULL;
@@ -686,34 +629,52 @@
     // End the extern "C".
     Printv(f_c_wrappers, "#ifdef __cplusplus\n", "}\n", "#endif\n\n", NULL);
 
-    if (cgo_flag) {
-      // End the cgo comment.
-      Printv(f_cgo_comment, "#undef intgo\n", NULL);
-      Printv(f_cgo_comment, "*/\n", NULL);
-      Printv(f_cgo_comment, "import \"C\"\n", NULL);
-      Printv(f_cgo_comment, "\n", NULL);
+    // End the cgo comment.
+    Printv(f_cgo_comment, "#undef intgo\n", NULL);
+    Printv(f_cgo_comment, "*/\n", NULL);
+    Printv(f_cgo_comment, "import \"C\"\n", NULL);
+    Printv(f_cgo_comment, "\n", NULL);
+
+    bool need_panic = false;
+    if (Strstr(f_c_runtime, "SWIG_contract_assert(") != 0 || Strstr(f_c_wrappers, "SWIG_contract_assert(") != 0) {
+      Printv(f_c_begin, "\n#define SWIG_contract_assert(expr, msg) if (!(expr)) { _swig_gopanic(msg); } else\n\n", NULL);
+      need_panic = true;
+    }
+
+    if (!gccgo_flag && (need_panic || Strstr(f_c_runtime, "_swig_gopanic") != 0 || Strstr(f_c_wrappers, "_swig_gopanic") != 0)) {
+      Printv(f_go_header, "//export cgo_panic_", unique_id, "\n", NULL);
+      Printv(f_go_header, "func cgo_panic_", unique_id, "(p *byte) {\n", NULL);
+      Printv(f_go_header, "\ts := (*[1024]byte)(unsafe.Pointer(p))[:]\n", NULL);
+      Printv(f_go_header, "\tfor i, b := range s {\n", NULL);
+      Printv(f_go_header, "\t\tif b == 0 {\n", NULL);
+      Printv(f_go_header, "\t\t\tpanic(string(s[:i]))\n", NULL);
+      Printv(f_go_header, "\t\t}\n", NULL);
+      Printv(f_go_header, "\t}\n", NULL);
+      Printv(f_go_header, "\tpanic(string(s))\n", NULL);
+      Printv(f_go_header, "}\n\n", NULL);
+
+      Printv(f_c_begin, "\nextern\n", NULL);
+      Printv(f_c_begin, "#ifdef __cplusplus\n", NULL);
+      Printv(f_c_begin, "  \"C\"\n", NULL);
+      Printv(f_c_begin, "#endif\n", NULL);
+      Printv(f_c_begin, "  void cgo_panic_", unique_id, "(const char*);\n", NULL);
+      Printv(f_c_begin, "static void _swig_gopanic(const char *p) {\n", NULL);
+      Printv(f_c_begin, "  cgo_panic_", unique_id, "(p);\n", NULL);
+      Printv(f_c_begin, "}\n\n", NULL);
     }
 
     Dump(f_c_runtime, f_c_begin);
     Dump(f_c_wrappers, f_c_begin);
     Dump(f_c_init, f_c_begin);
-    if (cgo_flag) {
-      Dump(f_cgo_comment_typedefs, f_go_begin);
-      Dump(f_cgo_comment, f_go_begin);
-    }
+    Dump(f_cgo_comment_typedefs, f_go_begin);
+    Dump(f_cgo_comment, f_go_begin);
     Dump(f_go_imports, f_go_begin);
     Dump(f_go_header, f_go_begin);
     Dump(f_go_runtime, f_go_begin);
     Dump(f_go_wrappers, f_go_begin);
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Dump(f_go_directors, f_go_begin);
     }
-    if (!gccgo_flag && !cgo_flag) {
-      Dump(f_gc_header, f_gc_begin);
-      Dump(f_gc_runtime, f_gc_begin);
-      Dump(f_gc_wrappers, f_gc_begin);
-    }
-
     Delete(f_c_runtime);
     Delete(f_c_header);
     Delete(f_c_wrappers);
@@ -723,21 +684,10 @@
     Delete(f_go_header);
     Delete(f_go_wrappers);
     Delete(f_go_directors);
-    if (!gccgo_flag && !cgo_flag) {
-      Delete(f_gc_runtime);
-      Delete(f_gc_header);
-      Delete(f_gc_wrappers);
-    }
-    if (cgo_flag) {
-      Delete(f_cgo_comment);
-      Delete(f_cgo_comment_typedefs);
-    }
-
+    Delete(f_cgo_comment);
+    Delete(f_cgo_comment_typedefs);
     Delete(f_c_begin);
     Delete(f_go_begin);
-    if (!gccgo_flag && !cgo_flag) {
-      Delete(f_gc_begin);
-    }
 
     return SWIG_OK;
   }
@@ -810,13 +760,6 @@
       return SWIG_OK;
     }
 
-    // Don't emit constructors for abstract director classes.  They
-    // will never succeed anyhow.
-    if (Swig_methodclass(n) && Swig_directorclass(n)
-	&& Strcmp(Char(Getattr(n, "wrap:action")), director_prot_ctor_code) == 0) {
-      return SWIG_OK;
-    }
-
     String *name = Getattr(n, "sym:name");
     String *nodetype = Getattr(n, "nodeType");
     bool is_static = is_static_member_function || isStatic(n);
@@ -890,7 +833,9 @@
 	SwigType *type = Copy(getClassType());
 	SwigType_add_pointer(type);
 	String *cres = Swig_cresult(type, Swig_cresult_name(), call);
-	Setattr(n, "wrap:action", cres);
+	if (!Equal(Getattr(n, "wrap:action"), director_prot_ctor_code)) {
+	  Setattr(n, "wrap:action", cres);
+	}
       }
     } else if (Cmp(nodetype, "destructor") == 0) {
       // No need to emit protected destructors.
@@ -952,7 +897,7 @@
     ParmList *parms = Getattr(n, "parms");
     Setattr(n, "wrap:parms", parms);
 
-    int r = makeWrappers(n, name, go_name, overname, wname, NULL, parms, result, is_static);
+    int r = makeWrappers(n, go_name, overname, wname, NULL, parms, result, is_static);
     if (r != SWIG_OK) {
       return r;
     }
@@ -1010,7 +955,6 @@
    *
    * Write out the various function wrappers.
    * n: The function we are emitting.
-   * name: The function name.
    * go_name: The name of the function in Go.
    * overname: The overload string for overloaded function.
    * wname: The SWIG wrapped name--the name of the C function.
@@ -1021,38 +965,15 @@
    * is_static: Whether this is a static method or member.
    * ---------------------------------------------------------------------- */
 
-  int makeWrappers(Node *n, String *name, String *go_name, String *overname, String *wname, List *base, ParmList *parms, SwigType *result, bool is_static) {
+  int makeWrappers(Node *n, String *go_name, String *overname, String *wname, List *base, ParmList *parms, SwigType *result, bool is_static) {
 
     assert(result);
 
     int ret = SWIG_OK;
 
-    if (cgo_flag) {
-      int r = makeCgoWrappers(n, go_name, overname, wname, base, parms, result, is_static);
-      if (r != SWIG_OK) {
-	ret = r;
-      }
-    } else {
-      int r = goFunctionWrapper(n, name, go_name, overname, wname, base, parms, result, is_static);
-      if (r != SWIG_OK) {
-	ret = r;
-      }
-
-      if (!gccgo_flag) {
-	r = gcFunctionWrapper(wname);
-	if (r != SWIG_OK) {
-	  ret = r;
-	}
-	r = gccFunctionWrapper(n, base, wname, parms, result);
-	if (r != SWIG_OK) {
-	  ret = r;
-	}
-      } else {
-	r = gccgoFunctionWrapper(n, base, wname, parms, result);
-	if (r != SWIG_OK) {
-	  ret = r;
-	}
-      }
+    int r = makeCgoWrappers(n, go_name, overname, wname, base, parms, result, is_static);
+    if (r != SWIG_OK) {
+      ret = r;
     }
 
     if (class_methods) {
@@ -1334,9 +1255,15 @@
 
       String *goin = goGetattr(p, "tmap:goin");
       if (goin == NULL) {
-	Printv(f_go_wrappers, "\t", ivar, " := ", ln, NULL);
+	Printv(f_go_wrappers, "\t", ivar, " := ", NULL);
+	bool need_close = false;
 	if ((i == 0 && info->is_destructor) || ((i > 0 || !info->receiver || info->base || info->is_constructor) && goTypeIsInterface(p, pt))) {
-	  Printv(f_go_wrappers, ".Swigcptr()", NULL);
+	  Printv(f_go_wrappers, "getSwigcptr(", NULL);
+	  need_close = true;
+	}
+	Printv(f_go_wrappers, ln, NULL);
+	if (need_close) {
+	  Printv(f_go_wrappers, ")", NULL);
 	}
 	Printv(f_go_wrappers, "\n", NULL);
 	Setattr(p, "emit:goinput", ln);
@@ -1529,7 +1456,7 @@
       p = getParm(p);
 
       SwigType *pt = Copy(Getattr(p, "type"));
-      if (SwigType_isarray(pt)) {
+      if (SwigType_isarray(pt) && Getattr(p, "tmap:gotype") == NULL) {
 	SwigType_del_array(pt);
 	SwigType_add_pointer(pt);
       }
@@ -1619,415 +1546,6 @@
   }
 
   /* ----------------------------------------------------------------------
-   * goFunctionWrapper()
-   *
-   * Write out a function wrapper in Go.  When not implementing a
-   * method, the actual code is all in C; here we just declare the C
-   * function.  When implementing a method, we have to call the C
-   * function, because it will have a different name.  If base is not
-   * NULL, then we are being called to forward a virtual method to a
-   * base class.
-   * ---------------------------------------------------------------------- */
-
-  int goFunctionWrapper(Node *n, String *name, String *go_name, String *overname, String *wname, List *base, ParmList *parms, SwigType *result, bool is_static) {
-    Wrapper *dummy = initGoTypemaps(parms);
-
-    int parm_count = emit_num_arguments(parms);
-    int required_count = emit_num_required(parms);
-
-    String *receiver = class_receiver;
-    if (receiver && is_static) {
-      receiver = NULL;
-    }
-
-    String *nodetype = Getattr(n, "nodeType");
-    bool is_constructor = Cmp(nodetype, "constructor") == 0;
-    bool is_destructor = Cmp(nodetype, "destructor") == 0;
-    if (is_constructor || is_destructor) {
-      assert(class_receiver);
-      assert(!base);
-      receiver = NULL;
-    }
-
-    Swig_save("cgoGoWrapper", n, "type", "tmap:goout", NULL);
-    Setattr(n, "type", result);
-
-    String *goout = goTypemapLookup("goout", n, "swig_r");
-
-    Swig_restore(n);
-
-    bool add_to_interface = (interfaces && !is_constructor && !is_destructor && !is_static && !overname && checkFunctionVisibility(n, NULL));
-
-    bool needs_wrapper = (gccgo_flag || receiver || is_constructor || is_destructor || parm_count > required_count);
-
-    bool has_goout = false;
-    if (goout) {
-      has_goout = true;
-    }
-
-    // See whether any of the function parameters are represented by
-    // interface values.  When calling the C++ code, we need to convert
-    // back to a uintptr.
-    Parm *p = parms;
-    for (int i = 0; i < parm_count; ++i) {
-      p = getParm(p);
-      String *ty = Getattr(p, "type");
-      if (goGetattr(p, "tmap:goargout")) {
-	has_goout = true;
-	needs_wrapper = true;
-      } else if (goTypeIsInterface(p, ty) || goGetattr(p, "tmap:goin")) {
-	needs_wrapper = true;
-      }
-
-      if (paramNeedsEscape(p)) {
-	needs_wrapper = true;
-      }
-
-      p = nextParm(p);
-    }
-    if (goTypeIsInterface(n, result) || goout != NULL) {
-      needs_wrapper = true;
-    }
-
-    if (!gccgo_flag) {
-      Printv(f_go_wrappers, "var ", wname, " unsafe.Pointer\n\n", NULL);
-    }
-
-    // If this is a method, first declare the C function we will call.
-    // If we do not need a wrapper, then we will only be writing a
-    // declaration.
-    String *wrapper_name = NULL;
-    if (needs_wrapper) {
-      wrapper_name = buildGoWrapperName(name, overname);
-
-      if (gccgo_flag) {
-	Printv(f_go_wrappers, "//extern ", go_prefix, "_", wname, "\n", NULL);
-      }
-
-      bool arg = false;
-      Printv(f_go_wrappers, "func ", wrapper_name, "(", NULL);
-      if (parm_count > required_count) {
-	Printv(f_go_wrappers, argName(&arg), " int", NULL);
-      }
-      Parm *p = getParm(parms);
-      int i = 0;
-      if (is_destructor) {
-	if (parm_count > required_count) {
-	  Printv(f_go_wrappers, ", ", NULL);
-	}
-	Printv(f_go_wrappers, argName(&arg), " uintptr", NULL);
-	++i;
-	p = nextParm(p);
-      } else if (receiver && (base || !is_constructor)) {
-	if (parm_count > required_count) {
-	  Printv(f_go_wrappers, ", ", NULL);
-	}
-	Printv(f_go_wrappers, argName(&arg), " ", receiver, NULL);
-	if (!base) {
-	  ++i;
-	  p = nextParm(p);
-	}
-      }
-      for (; i < parm_count; ++i) {
-	p = getParm(p);
-	if (i > 0 || (base && receiver) || parm_count > required_count) {
-	  Printv(f_go_wrappers, ", ", NULL);
-	}
-	String *tm = goWrapperType(p, Getattr(p, "type"), false);
-	Printv(f_go_wrappers, argName(&arg), " ", tm, NULL);
-	Delete(tm);
-	p = nextParm(p);
-      }
-      Printv(f_go_wrappers, ")", NULL);
-      if (is_constructor) {
-	Printv(f_go_wrappers, " (", argName(&arg), " ", class_receiver, ")", NULL);
-      } else {
-	if (SwigType_type(result) != T_VOID) {
-	  String *tm = goWrapperType(n, result, true);
-	  Printv(f_go_wrappers, " (", argName(&arg), " ", tm, ")", NULL);
-	  Delete(tm);
-	}
-      }
-
-      if (!gccgo_flag) {
-	Printv(f_go_wrappers, " {\n", NULL);
-	if (arg) {
-	  Printv(f_go_wrappers, "\t_swig_p := uintptr(unsafe.Pointer(&base))\n", NULL);
-	} else {
-	  Printv(f_go_wrappers, "\tvar _swig_p uintptr\n", NULL);
-	}
-	Printv(f_go_wrappers, "\t_cgo_runtime_cgocall(", wname, ", _swig_p)\n", NULL);
-	Printv(f_go_wrappers, "\treturn\n", NULL);
-	Printv(f_go_wrappers, "}", NULL);
-      }
-
-      Printv(f_go_wrappers, "\n\n", NULL);
-    }
-
-    // Start defining the Go function.
-
-    if (!needs_wrapper && gccgo_flag) {
-      Printv(f_go_wrappers, "//extern ", go_prefix, "_", wname, "\n", NULL);
-    }
-
-    Printv(f_go_wrappers, "func ", NULL);
-
-    p = parms;
-    int pi = 0;
-
-    // Add the receiver if this is a method.
-    String *first = NULL;
-    if (receiver) {
-      Printv(f_go_wrappers, "(", NULL);
-      if (base && receiver) {
-	Printv(f_go_wrappers, "_swig_base", NULL);
-	if (first == NULL) {
-	  first = NewString("_swig_base");
-	}
-      } else {
-	Printv(f_go_wrappers, Getattr(p, "lname"), NULL);
-	if (first == NULL) {
-	  first = Copy(Getattr(p, "lname"));
-	}
-	p = nextParm(p);
-	++pi;
-      }
-      Printv(f_go_wrappers, " ", receiver, ") ", NULL);
-    }
-
-    Printv(f_go_wrappers, go_name, NULL);
-    if (overname) {
-      Printv(f_go_wrappers, overname, NULL);
-    }
-    Printv(f_go_wrappers, "(", NULL);
-
-    // If we are doing methods, add this function to the interface.
-    if (add_to_interface) {
-      Printv(interfaces, "\t", go_name, "(", NULL);
-    }
-
-    // Write out the parameters to both the function definition and
-    // the interface.
-
-    String *parm_print = NewString("");
-
-    for (; pi < parm_count; ++pi) {
-      p = getParm(p);
-      if (pi == 0 && is_destructor) {
-	String *cl = exportedName(class_name);
-	Printv(parm_print, Getattr(p, "lname"), " ", cl, NULL);
-	if (first == NULL) {
-	  first = Copy(Getattr(p, "lname"));
-	}
-	Delete(cl);
-      } else {
-	if (pi > (receiver && !base ? 1 : 0)) {
-	  Printv(parm_print, ", ", NULL);
-	}
-	if (pi >= required_count) {
-	  Printv(parm_print, "_swig_args ...interface{}", NULL);
-	  if (first == NULL) {
-	    first = NewString("_swig_args");
-	  }
-	  break;
-	}
-	Printv(parm_print, Getattr(p, "lname"), " ", NULL);
-	if (first == NULL) {
-	  first = Copy(Getattr(p, "lname"));
-	}
-	String *tm = goType(p, Getattr(p, "type"));
-	Printv(parm_print, tm, NULL);
-	Delete(tm);
-      }
-      p = nextParm(p);
-    }
-
-    Printv(parm_print, ")", NULL);
-
-    // Write out the result type.
-    if (is_constructor) {
-      String *cl = exportedName(class_name);
-      Printv(parm_print, " (_swig_ret ", cl, ")", NULL);
-      if (first == NULL) {
-	first = NewString("_swig_ret");
-      }
-      Delete(cl);
-    } else {
-      if (SwigType_type(result) != T_VOID) {
-	String *tm = goType(n, result);
-	Printv(parm_print, " (_swig_ret ", tm, ")", NULL);
-	if (first == NULL) {
-	  first = NewString("_swig_ret");
-	}
-	Delete(tm);
-      }
-    }
-
-    Printv(f_go_wrappers, parm_print, NULL);
-    if (add_to_interface) {
-      Printv(interfaces, parm_print, "\n", NULL);
-    }
-
-    // If this is a wrapper, we need to actually call the C function.
-    if (needs_wrapper) {
-      Printv(f_go_wrappers, " {\n", NULL);
-
-      if (parm_count > required_count) {
-	Parm *p = parms;
-	int i;
-	for (i = 0; i < required_count; ++i) {
-	  p = getParm(p);
-	  p = nextParm(p);
-	}
-	for (; i < parm_count; ++i) {
-	  p = getParm(p);
-	  String *tm = goType(p, Getattr(p, "type"));
-	  Printv(f_go_wrappers, "\tvar ", Getattr(p, "lname"), " ", tm, "\n", NULL);
-	  Printf(f_go_wrappers, "\tif len(_swig_args) > %d {\n", i - required_count);
-	  Printf(f_go_wrappers, "\t\t%s = _swig_args[%d].(%s)\n", Getattr(p, "lname"), i - required_count, tm);
-	  Printv(f_go_wrappers, "\t}\n", NULL);
-	  Delete(tm);
-	  p = nextParm(p);
-	}
-      }
-
-      String *call = NewString("");
-
-      bool need_return_var = SwigType_type(result) != T_VOID && ((gccgo_flag && is_constructor) || has_goout);
-      if (need_return_var) {
-	Printv(f_go_wrappers, "\tvar swig_r ", NULL);
-	if (is_constructor) {
-	  String *cl = exportedName(class_name);
-	  Printv(f_go_wrappers, cl, NULL);
-	  Delete(cl);
-	} else {
-	  Printv(f_go_wrappers, goImType(n, result), NULL);
-	}
-	Printv(f_go_wrappers, "\n", NULL);
-      }
-
-      if (gccgo_flag) {
-	if (has_goout || is_constructor) {
-	  Printv(call, "\tfunc() {\n", NULL);
-	}
-	Printv(call, "\tdefer SwigCgocallDone()\n", NULL);
-	Printv(call, "\tSwigCgocall()\n", NULL);
-      }
-
-      Printv(call, "\t", NULL);
-      if (SwigType_type(result) != T_VOID) {
-	if (need_return_var) {
-	  Printv(call, "swig_r = ", NULL);
-	} else {
-	  Printv(call, "return ", NULL);
-	}
-      }
-
-      Printv(call, wrapper_name, "(", NULL);
-
-      if (parm_count > required_count) {
-	Printv(call, "len(_swig_args)", NULL);
-      }
-
-      if (base && receiver) {
-	if (parm_count > required_count) {
-	  Printv(call, ", ", NULL);
-	}
-	Printv(call, "_swig_base", NULL);
-      }
-
-      Parm *p = parms;
-      for (int i = 0; i < parm_count; ++i) {
-	p = getParm(p);
-	if (i > 0 || (base && receiver)
-	    || parm_count > required_count) {
-	  Printv(call, ", ", NULL);
-	}
-
-	SwigType *pt = Getattr(p, "type");
-	String *ln = Getattr(p, "lname");
-
-	String *goin = goGetattr(p, "tmap:goin");
-	if (goin == NULL) {
-	  Printv(call, ln, NULL);
-	  if ((i == 0 && is_destructor) || ((i > 0 || !receiver || base || is_constructor) && goTypeIsInterface(p, pt))) {
-	    Printv(call, ".Swigcptr()", NULL);
-	  }
-	  Setattr(p, "emit:goinput", ln);
-	} else {
-	  String *ivar = NewString("");
-	  Printf(ivar, "_swig_i_%d", i);
-	  String *itm = goImType(p, pt);
-	  Printv(f_go_wrappers, "\tvar ", ivar, " ", itm, "\n", NULL);
-	  goin = Copy(goin);
-	  Replaceall(goin, "$input", ln);
-	  Replaceall(goin, "$result", ivar);
-	  Printv(f_go_wrappers, goin, "\n", NULL);
-	  Delete(goin);
-	  Printv(call, ivar, NULL);
-	  Setattr(p, "emit:goinput", ivar);
-	}
-
-	// If the parameter has an argout or freearg typemap, make
-	// sure that it escapes.
-	if (paramNeedsEscape(p)) {
-	  Printv(f_go_wrappers, "\tif Swig_escape_always_false {\n", NULL);
-	  Printv(f_go_wrappers, "\t\tSwig_escape_val = ", Getattr(p, "emit:goinput"), "\n", NULL);
-	  Printv(f_go_wrappers, "\t}\n", NULL);
-	}
-
-	p = nextParm(p);
-      }
-      Printv(call, ")\n", NULL);
-
-      if (gccgo_flag && (has_goout || is_constructor)) {
-	Printv(call, "\t}()\n", NULL);
-      }
-
-      Printv(f_go_wrappers, call, NULL);
-      Delete(call);
-
-      goargout(parms);
-
-      if (need_return_var) {
-	if (goout == NULL) {
-	  Printv(f_go_wrappers, "\treturn swig_r\n", NULL);
-	} else {
-	  String *tm = goType(n, result);
-	  Printv(f_go_wrappers, "\tvar swig_r_1 ", tm, "\n", NULL);
-	  Replaceall(goout, "$input", "swig_r");
-	  Replaceall(goout, "$result", "swig_r_1");
-	  Printv(f_go_wrappers, goout, "\n", NULL);
-	  Printv(f_go_wrappers, "\treturn swig_r_1\n", NULL);
-	}
-      }
-
-      Printv(f_go_wrappers, "}\n", NULL);
-    } else if (!gccgo_flag) {
-      // We don't need a wrapper.  If we're using gccgo, the function
-      // declaration is all we need--it has a //extern comment to
-      // GCC-compiled wrapper.  If we're not using gccgo, we need to
-      // call the GCC-compiled wrapper here.
-      Printv(f_go_wrappers, " {\n", NULL);
-      if (first == NULL) {
-	Printv(f_go_wrappers, "\tvar _swig_p uintptr\n", NULL);
-      } else {
-	Printv(f_go_wrappers, "\t_swig_p := uintptr(unsafe.Pointer(&", first, "))\n", NULL);
-      }
-      Printv(f_go_wrappers, "\t_cgo_runtime_cgocall(", wname, ", _swig_p)\n", NULL);
-      Printv(f_go_wrappers, "\treturn\n", NULL);
-      Printv(f_go_wrappers, "}", NULL);
-    }
-
-    Printv(f_go_wrappers, "\n", NULL);
-
-    Delete(wrapper_name);
-    DelWrapper(dummy);
-
-    return SWIG_OK;
-  }
-
-  /* ----------------------------------------------------------------------
    * initGoTypemaps()
    *
    * Initialize the typenames for a Go wrapper, returning a dummy
@@ -2055,362 +1573,6 @@
     return dummy;
   }
 
-  /* ----------------------------------------------------------------------
-   * argName()
-   *
-   * A helper for goFunctionWrapper to output the first argument name
-   * as "base" and all others as "_".
-   * ---------------------------------------------------------------------- */
-
-  const char *argName(bool *arg) {
-    if (*arg) {
-      return "_";
-    }
-    *arg = true;
-    return "base";
-  }
-
-  /* ----------------------------------------------------------------------
-   * paramNeedsEscape()
-   *
-   * A helper for goFunctionWrapper that returns whether a parameter
-   * needs to explicitly escape.  This is true if the parameter has a
-   * non-empty argout or freearg typemap, because in those cases the
-   * Go argument might be or contain a pointer.  We need to ensure
-   * that that pointer does not point into the stack, which means that
-   * it needs to escape.
-   * ---------------------------------------------------------------------- */
-  bool paramNeedsEscape(Parm *p) {
-    String *argout = Getattr(p, "tmap:argout");
-    String *freearg = Getattr(p, "tmap:freearg");
-    if ((!argout || Len(argout) == 0) && (!freearg || Len(freearg) == 0)) {
-      return false;
-    }
-    // If a C++ type is represented as an interface type in Go, then
-    // we don't care whether it escapes, because we know that the
-    // pointer is a C++ pointer.
-    if (goTypeIsInterface(p, Getattr(p, "type"))) {
-      return false;
-    }
-    return true;
-  }
-
-  /* ----------------------------------------------------------------------
-   * gcFunctionWrapper()
-   *
-   * This is used for 6g/8g, not for gccgo.  Write out the function
-   * redirector that will be compiled with 6c/8c.  This used to write
-   * out a real function wrapper, but that has moved into Go code.
-   * ---------------------------------------------------------------------- */
-
-  int gcFunctionWrapper(String *wname) {
-    Wrapper *f = NewWrapper();
-
-    Printv(f->def, "#pragma dynimport ", wname, " ", wname, " \"\"\n", NULL);
-    Printv(f->def, "#pragma cgo_import_static ", wname, "\n", NULL);
-    Printv(f->def, "extern void ", wname, "(void*);\n", NULL);
-    // Declare this as a uintptr, since it is not a pointer into the
-    // Go heap.
-    // \xc2\xb7 is UTF-8 for U+00B7 which is Unicode 'Middle Dot'
-    Printv(f->def, "uintptr \xc2\xb7", wname, " = (uintptr)", wname, ";\n", NULL);
-
-    Wrapper_print(f, f_gc_wrappers);
-
-    DelWrapper(f);
-
-    return SWIG_OK;
-  }
-
-  /* ----------------------------------------------------------------------
-   * gccFunctionWrapper()
-   *
-   * This is used for 6g/8g, not for gccgo.  Write out the function
-   * wrapper which will be compiled with gcc.  If the base parameter
-   * is not NULL, this is calls the base class method rather than
-   * executing the SWIG wrapper code.
-   * ---------------------------------------------------------------------- */
-
-  int gccFunctionWrapper(Node *n, List *base, String *wname, ParmList *parms, SwigType *result) {
-    Wrapper *f = NewWrapper();
-
-    Swig_save("gccFunctionWrapper", n, "parms", NULL);
-
-    Parm *base_parm = NULL;
-    if (base && !isStatic(n)) {
-      SwigType *base_type = Copy(getClassType());
-      SwigType_add_pointer(base_type);
-      base_parm = NewParm(base_type, NewString("arg1"), n);
-      set_nextSibling(base_parm, parms);
-      parms = base_parm;
-    }
-
-    emit_parameter_variables(parms, f);
-    emit_attach_parmmaps(parms, f);
-    int parm_count = emit_num_arguments(parms);
-    int required_count = emit_num_required(parms);
-    bool needs_swigargs = false;
-
-    emit_return_variable(n, result, f);
-
-    // Start the function definition.
-
-    Printv(f->def, "void\n", wname, "(void *swig_v)\n", "{\n", NULL);
-
-    // The single function parameter is a pointer to the real argument
-    // values.  Define the structure that it points to.
-
-    String *swigargs = NewString("\tstruct swigargs {\n");
-
-    if (parm_count > required_count) {
-      needs_swigargs = true;
-      Printv(swigargs, "\t\tintgo _swig_optargc;\n", NULL);
-    }
-
-    Parm *p = parms;
-    for (int i = 0; i < parm_count; ++i) {
-      p = getParm(p);
-
-      String *ln = Getattr(p, "lname");
-      SwigType *pt = Getattr(p, "type");
-      String *ct = gcCTypeForGoValue(p, pt, ln);
-      Printv(swigargs, "\t\t\t", ct, ";\n", NULL);
-      needs_swigargs = true;
-      Delete(ct);
-
-      String *gn = NewStringf("_swig_go_%d", i);
-      ct = gcCTypeForGoValue(p, pt, gn);
-      Setattr(p, "emit:input", gn);
-      Wrapper_add_local(f, gn, ct);
-      Delete(ct);
-
-      p = nextParm(p);
-    }
-    if (SwigType_type(result) != T_VOID) {
-      Printv(swigargs, "\t\tlong : 0;\n", NULL);
-      String *ln = NewString(Swig_cresult_name());
-      String *ct = gcCTypeForGoValue(n, result, ln);
-      Delete(ln);
-      Printv(swigargs, "\t\t", ct, ";\n", NULL);
-      needs_swigargs = true;
-      Delete(ct);
-
-      ln = NewString("_swig_go_result");
-      ct = gcCTypeForGoValue(n, result, ln);
-      Wrapper_add_local(f, "_swig_go_result", ct);
-      Delete(ct);
-      Delete(ln);
-    }
-    Printv(swigargs, "\t} SWIGSTRUCTPACKED *swig_a = (struct swigargs *) swig_v;\n", NULL);
-
-    // Copy the input arguments out of the structure into the Go local
-    // variables.
-    p = parms;
-    for (int i = 0; i < parm_count; ++i) {
-      p = getParm(p);
-      String *ln = Getattr(p, "lname");
-      String *gn = Getattr(p, "emit:input");
-      Printv(f->code, "\t", gn, " = swig_a->", ln, ";\n", NULL);
-      p = nextParm(p);
-    }
-
-    // Apply the in typemaps.
-    p = parms;
-    for (int i = 0; i < parm_count; ++i) {
-      p = getParm(p);
-      String *tm = Getattr(p, "tmap:in");
-      if (!tm) {
-	Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument\n", SwigType_str(Getattr(p, "type"), 0));
-      } else {
-	tm = Copy(tm);
-	String *gn = Getattr(p, "emit:input");
-	Replaceall(tm, "$input", gn);
-	if (i < required_count) {
-	  Printv(f->code, "\t", tm, "\n", NULL);
-	} else {
-	  Printf(f->code, "\tif (swig_a->_swig_optargc > %d) {\n", i - required_count);
-	  Printv(f->code, "\t\t", tm, "\n", NULL);
-	  Printv(f->code, "\t}\n", NULL);
-	}
-	Delete(tm);
-      }
-      p = nextParm(p);
-    }
-
-    Printv(f->code, "\n", NULL);
-
-    // Do the real work of the function.
-
-    checkConstraints(parms, f);
-
-    emitGoAction(n, base, parms, result, f);
-
-    argout(parms, f);
-
-    cleanupFunction(n, f, parms);
-
-    if (needs_swigargs)
-    {
-      Printv(f->locals, swigargs, NULL);
-    }
-
-    Printv(f->code, "}\n", NULL);
-
-    Wrapper_print(f, f_c_wrappers);
-
-    Swig_restore(n);
-
-    Delete(swigargs);
-    DelWrapper(f);
-    Delete(base_parm);
-
-    return SWIG_OK;
-  }
-
-  /* ----------------------------------------------------------------------
-   * gccgoFunctionWrapper()
-   *
-   * This is used for gccgo, not 6g/8g.  Write out the function
-   * wrapper which will be compiled with gcc.  If the base parameter
-   * is not NULL, this is calls the base class method rather than
-   * executing the SWIG wrapper code.
-   * ---------------------------------------------------------------------- */
-
-  int gccgoFunctionWrapper(Node *n, List *base, String *wname, ParmList *parms, SwigType *result) {
-    Wrapper *f = NewWrapper();
-
-    Swig_save("gccgoFunctionWrapper", n, "parms", NULL);
-
-    Parm *base_parm = NULL;
-    if (base && !isStatic(n)) {
-      SwigType *base_type = Copy(getClassType());
-      SwigType_add_pointer(base_type);
-      base_parm = NewParm(base_type, NewString("arg1"), n);
-      set_nextSibling(base_parm, parms);
-      parms = base_parm;
-    }
-
-    emit_parameter_variables(parms, f);
-    emit_attach_parmmaps(parms, f);
-    int parm_count = emit_num_arguments(parms);
-    int required_count = emit_num_required(parms);
-
-    emit_return_variable(n, result, f);
-
-    // Start the function definition.
-
-    String *fnname = NewString("");
-    Printv(fnname, "go_", wname, "(", NULL);
-
-    if (parm_count > required_count) {
-      Printv(fnname, "intgo _swig_optargc", NULL);
-    }
-
-    Parm *p = parms;
-    for (int i = 0; i < parm_count; ++i) {
-      p = getParm(p);
-      SwigType *pt = Copy(Getattr(p, "type"));
-      if (SwigType_isarray(pt)) {
-	SwigType_del_array(pt);
-	SwigType_add_pointer(pt);
-      }
-      String *pn = NewString("g");
-      Append(pn, Getattr(p, "lname"));
-      String *ct = gccgoCTypeForGoValue(p, pt, pn);
-      if (i > 0 || parm_count > required_count) {
-	Printv(fnname, ", ", NULL);
-      }
-      Printv(fnname, ct, NULL);
-      Delete(ct);
-      Delete(pn);
-      Delete(pt);
-      p = nextParm(p);
-    }
-
-    Printv(fnname, ")", NULL);
-
-    String *fndef = NewString("");
-    if (SwigType_type(result) == T_VOID) {
-      Printv(fndef, "void ", fnname, NULL);
-    } else {
-      String *ct = gccgoCTypeForGoValue(n, result, fnname);
-      Printv(fndef, ct, NULL);
-      Delete(ct);
-    }
-
-    Printv(f->def, fndef, " __asm__(\"", go_prefix, "_", wname, "\");\n", NULL);
-
-    Printv(f->def, fndef, " {\n", NULL);
-
-    Delete(fnname);
-    Delete(fndef);
-
-    if (SwigType_type(result) != T_VOID) {
-      String *ln = NewString("_swig_go_result");
-      String *ct = gccgoCTypeForGoValue(n, result, ln);
-      Wrapper_add_local(f, "_swig_go_result", ct);
-      Delete(ct);
-      Delete(ln);
-    }
-
-    // Copy the parameters into the variables which hold their values,
-    // applying appropriate transformations.
-
-    p = parms;
-    for (int i = 0; i < parm_count; ++i) {
-      p = getParm(p);
-
-      String *tm = Getattr(p, "tmap:in");
-      if (!tm) {
-	Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number,
-		     "Unable to use type %s as a function argument\n", SwigType_str(Getattr(p, "type"), 0));
-      } else {
-	String *ln = Getattr(p, "lname");
-	String *pn = NewString("g");
-	Append(pn, ln);
-	tm = Copy(tm);
-	Replaceall(tm, "$input", pn);
-	Setattr(p, "emit:input", pn);
-	if (i < required_count) {
-	  Printv(f->code, "  ", tm, "\n", NULL);
-	} else {
-	  Printf(f->code, "  if (_swig_optargc > %d) {\n", i - required_count);
-	  Printv(f->code, "    ", tm, "\n", NULL);
-	  Printv(f->code, "  }\n", NULL);
-	}
-	Delete(tm);
-      }
-
-      p = nextParm(p);
-    }
-
-    Printv(f->code, "\n", NULL);
-
-    // Do the real work of the function.
-
-    checkConstraints(parms, f);
-
-    emitGoAction(n, base, parms, result, f);
-
-    argout(parms, f);
-
-    cleanupFunction(n, f, parms);
-
-    if (SwigType_type(result) != T_VOID) {
-      Printv(f->code, "  return _swig_go_result;\n", NULL);
-    }
-
-    Printv(f->code, "}\n", NULL);
-
-    Wrapper_print(f, f_c_wrappers);
-
-    Swig_restore(n);
-
-    DelWrapper(f);
-    Delete(base_parm);
-
-    return SWIG_OK;
-  }
-
   /* -----------------------------------------------------------------------
    * checkConstraints()
    *
@@ -2442,10 +1604,6 @@
    * ----------------------------------------------------------------------- */
 
   void emitGoAction(Node *n, List *base, ParmList *parms, SwigType *result, Wrapper *f) {
-    if (!gccgo_flag && !cgo_flag && SwigType_type(result) != T_VOID) {
-      Wrapper_add_local(f, "swig_stktop", "char *swig_stktop");
-      Printv(f->code, "\tswig_stktop = _swig_topofstack();\n", NULL);
-    }
     String *actioncode;
     if (!base || isStatic(n)) {
       Swig_director_emit_dynamic_cast(n, f);
@@ -2455,9 +1613,6 @@
       actioncode = NewString("");
 
       String *current = NewString("");
-      if (!gccgo_flag && !cgo_flag) {
-	Printv(current, "swig_a->", NULL);
-      }
       Printv(current, Getattr(parms, "lname"), NULL);
 
       int vc = 0;
@@ -2493,14 +1648,6 @@
       Delete(tm);
     }
 
-    if (!gccgo_flag && !cgo_flag && SwigType_type(result) != T_VOID) {
-      // If the function called back into the Go code, the stack might
-      // have been copied.  We need to adjust swig_a accordingly here.
-      // This is what cgo does.
-      Printv(f->code, "\tswig_a = (struct swigargs*)((char*)swig_a + (_swig_topofstack() - swig_stktop));\n", NULL);
-      Printv(f->code, "\tswig_a->", Swig_cresult_name(), " = ", "_swig_go_result;\n", NULL);
-    }
-
     Swig_restore(n);
   }
 
@@ -2553,26 +1700,23 @@
       }
     }
 
-    // When using cgo, if we need to memcpy a parameter to pass it to
-    // the C code, the compiler may think that the parameter is not
-    // live during the function call.  If the garbage collector runs
-    // while the C/C++ function is running, the parameter may be
-    // freed.  Force the compiler to see the parameter as live across
-    // the C/C++ function.
-    if (cgo_flag) {
-      int parm_count = emit_num_arguments(parms);
-      p = parms;
-      for (int i = 0; i < parm_count; ++i) {
-	p = getParm(p);
-	bool c_struct_type;
-	Delete(cgoTypeForGoValue(p, Getattr(p, "type"), &c_struct_type));
-	if (c_struct_type) {
-	  Printv(f_go_wrappers, "\tif Swig_escape_always_false {\n", NULL);
-	  Printv(f_go_wrappers, "\t\tSwig_escape_val = ", Getattr(p, "emit:goinput"), "\n", NULL);
-	  Printv(f_go_wrappers, "\t}\n", NULL);
-	}
-	p = nextParm(p);
+    // If we need to memcpy a parameter to pass it to the C code, the
+    // compiler may think that the parameter is not live during the
+    // function call.  If the garbage collector runs while the C/C++
+    // function is running, the parameter may be freed.  Force the
+    // compiler to see the parameter as live across the C/C++ function.
+    int parm_count = emit_num_arguments(parms);
+    p = parms;
+    for (int i = 0; i < parm_count; ++i) {
+      p = getParm(p);
+      bool c_struct_type;
+      Delete(cgoTypeForGoValue(p, Getattr(p, "type"), &c_struct_type));
+      if (c_struct_type) {
+	Printv(f_go_wrappers, "\tif Swig_escape_always_false {\n", NULL);
+	Printv(f_go_wrappers, "\t\tSwig_escape_val = ", Getattr(p, "emit:goinput"), "\n", NULL);
+	Printv(f_go_wrappers, "\t}\n", NULL);
       }
+      p = nextParm(p);
     }
   }
 
@@ -2615,7 +1759,6 @@
     if (GetFlag(n, "feature:new")) {
       String *tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0);
       if (tm) {
-	Replaceall(tm, "$source", Swig_cresult_name());
 	Printv(f->code, tm, "\n", NULL);
 	Delete(tm);
       }
@@ -2627,7 +1770,6 @@
     /* See if there is any return cleanup code */
     String *tm;
     if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
-      Replaceall(tm, "$source", Swig_cresult_name());
       Printf(f->code, "%s\n", tm);
       Delete(tm);
     }
@@ -2895,7 +2037,7 @@
     Append(wname, unique_id);
     Setattr(n, "wrap:name", wname);
 
-    int r = makeWrappers(n, sname, go_name, NULL, wname, NULL, NULL, type, true);
+    int r = makeWrappers(n, go_name, NULL, wname, NULL, NULL, type, true);
 
     if (r != SWIG_OK) {
       return r;
@@ -3065,76 +2207,9 @@
     }
 
     for (Node *ni = Getattr(base, "firstChild"); ni; ni = nextSibling(ni)) {
-
-      if (GetFlag(ni, "feature:ignore")) {
-	continue;
-      }
-
-      if (!is_public(ni)) {
-	continue;
-      }
-
-      String *type = Getattr(ni, "nodeType");
-      if (Strcmp(type, "constructor") == 0 || Strcmp(type, "destructor") == 0 || Strcmp(type, "enum") == 0 || Strcmp(type, "using") == 0 || Strcmp(type, "classforward") == 0 || Strcmp(type, "template") == 0) {
-	continue;
-      }
-      String *storage = Getattr(ni, "storage");
-      if (storage && (Strcmp(storage, "typedef") == 0 || Strcmp(storage, "friend") == 0)) {
-	continue;
-      }
-
-      String *mname = Getattr(ni, "sym:name");
-      if (!mname) {
-	continue;
-      }
-
-      String *lname = Getattr(ni, "name");
-      if (Getattr(class_methods, lname)) {
-	continue;
-      }
-      if (Getattr(local, lname)) {
-	continue;
-      }
-      Setattr(local, lname, NewString(""));
-
-      String *ty = NewString(Getattr(ni, "type"));
-      SwigType_push(ty, Getattr(ni, "decl"));
-      String *fullty = SwigType_typedef_resolve_all(ty);
-      bool is_function = SwigType_isfunction(fullty) ? true : false;
-      Delete(ty);
-      Delete(fullty);
-
-      if (is_function) {
-	int r = goBaseMethod(n, bases, ni);
-	if (r != SWIG_OK) {
-	  return r;
-	}
-
-	if (Getattr(ni, "sym:overloaded")) {
-	  for (Node *on = Getattr(ni, "sym:nextSibling"); on; on = Getattr(on, "sym:nextSibling")) {
-	    r = goBaseMethod(n, bases, on);
-	    if (r != SWIG_OK) {
-	      return r;
-	    }
-	  }
-
-	  String *receiver = class_receiver;
-	  bool is_static = isStatic(ni);
-	  if (is_static) {
-	    receiver = NULL;
-	  }
-	  String *go_name = buildGoName(Getattr(ni, "sym:name"), is_static, false);
-	  r = makeDispatchFunction(ni, go_name, receiver, is_static, NULL, false);
-	  Delete(go_name);
-	  if (r != SWIG_OK) {
-	    return r;
-	  }
-	}
-      } else {
-	int r = goBaseVariable(n, bases, ni);
-	if (r != SWIG_OK) {
-	  return r;
-	}
+      int r = goBaseEntry(n, bases, local, ni);
+      if (r != SWIG_OK) {
+	return r;
       }
     }
 
@@ -3155,6 +2230,105 @@
   }
 
   /* ------------------------------------------------------------
+   * goBaseEntry()
+   *
+   * Implement one entry defined in a parent class for a child class.
+   * n is the child class.
+   * ------------------------------------------------------------ */
+
+  int goBaseEntry(Node* n, List* bases, Hash *local, Node* entry) {
+    if (GetFlag(entry, "feature:ignore")) {
+      return SWIG_OK;
+    }
+
+    if (!is_public(entry)) {
+      return SWIG_OK;
+    }
+
+    String *type = Getattr(entry, "nodeType");
+    if (Strcmp(type, "constructor") == 0 || Strcmp(type, "destructor") == 0 || Strcmp(type, "enum") == 0 || Strcmp(type, "using") == 0 || Strcmp(type, "classforward") == 0 || Strcmp(type, "template") == 0) {
+      return SWIG_OK;
+    }
+
+    if (Strcmp(type, "extend") == 0) {
+      for (Node* extend = firstChild(entry); extend; extend = nextSibling(extend)) {
+	if (isStatic(extend)) {
+	  // If we don't do this, the extend_default test case fails.
+	  continue;
+	}
+
+	int r = goBaseEntry(n, bases, local, extend);
+	if (r != SWIG_OK) {
+	  return r;
+	}
+      }
+      return SWIG_OK;
+    }
+
+    String *storage = Getattr(entry, "storage");
+    if (storage && (Strcmp(storage, "typedef") == 0 || Strstr(storage, "friend"))) {
+      return SWIG_OK;
+    }
+
+    String *mname = Getattr(entry, "sym:name");
+    if (!mname) {
+      return SWIG_OK;
+    }
+
+    String *lname = Getattr(entry, "name");
+    if (Getattr(class_methods, lname)) {
+      return SWIG_OK;
+    }
+    if (Getattr(local, lname)) {
+      return SWIG_OK;
+    }
+    Setattr(local, lname, NewString(""));
+
+    String *ty = NewString(Getattr(entry, "type"));
+    SwigType_push(ty, Getattr(entry, "decl"));
+    String *fullty = SwigType_typedef_resolve_all(ty);
+    bool is_function = SwigType_isfunction(fullty) ? true : false;
+    Delete(ty);
+    Delete(fullty);
+
+    if (is_function) {
+      int r = goBaseMethod(n, bases, entry);
+      if (r != SWIG_OK) {
+	return r;
+      }
+
+      if (Getattr(entry, "sym:overloaded")) {
+	for (Node *on = Getattr(entry, "sym:nextSibling"); on; on = Getattr(on, "sym:nextSibling")) {
+	  r = goBaseMethod(n, bases, on);
+	  if (r != SWIG_OK) {
+	    return r;
+	  }
+	}
+
+	String *receiver = class_receiver;
+	bool is_static = isStatic(entry);
+	if (is_static) {
+	  receiver = NULL;
+	}
+	String *go_name = buildGoName(Getattr(entry, "sym:name"), is_static, false);
+	r = makeDispatchFunction(entry, go_name, receiver, is_static, NULL, false);
+	Delete(go_name);
+	if (r != SWIG_OK) {
+	    return r;
+	}
+      }
+    } else {
+      int r = goBaseVariable(n, bases, entry);
+      if (r != SWIG_OK) {
+	return r;
+      }
+    }
+
+    return SWIG_OK;
+  }
+
+
+  /* ------------------------------------------------------------
    * goBaseMethod()
    *
    * Implement a method defined in a parent class for a child class.
@@ -3208,7 +2382,13 @@
       }
     }
 
-    int r = makeWrappers(method, name, go_name, overname, wname, bases, Getattr(method, "parms"), result, is_static);
+    // A method added by %extend in a base class may have void parms.
+    ParmList* parms = Getattr(method, "parms");
+    if (parms != NULL && SwigType_type(Getattr(parms, "type")) == T_VOID) {
+      parms = NULL;
+    }
+
+    int r = makeWrappers(method, go_name, overname, wname, bases, parms, result, is_static);
 
     Swig_restore(method);
 
@@ -3263,7 +2443,7 @@
 
     String *mname = Swig_name_member(getNSpace(), Getattr(var_class, "sym:name"), var_name);
 
-    if (is_assignable(var)) {
+    if (!is_immutable(var)) {
       for (Iterator ki = First(var); ki.key; ki = Next(ki)) {
 	if (Strncmp(ki.key, "tmap:", 5) == 0) {
 	  Delattr(var, ki.key);
@@ -3283,7 +2463,7 @@
       Append(wname, unique_id);
       ParmList *parms = NewParm(vt, var_name, var);
       String *result = NewString("void");
-      int r = makeWrappers(var, mname_set, go_name, NULL, wname, bases, parms, result, false);
+      int r = makeWrappers(var, go_name, NULL, wname, bases, parms, result, false);
       if (r != SWIG_OK) {
 	return r;
       }
@@ -3312,7 +2492,7 @@
     String *wname = Swig_name_wrapper(mname_get);
     Append(wname, unique_id);
 
-    int r = makeWrappers(var, mname_get, go_name, NULL, wname, bases, NULL, vt, false);
+    int r = makeWrappers(var, go_name, NULL, wname, bases, NULL, vt, false);
     if (r != SWIG_OK) {
       return r;
     }
@@ -3363,7 +2543,7 @@
       Printv(interfaces, "\tSwigIs", go_base_name, "()\n", NULL);
 
       Printv(f_go_wrappers, "func (p ", go_type_name, ") SwigGet", go_base_name, "() ", go_base_type, " {\n", NULL);
-      Printv(f_go_wrappers, "\treturn ", go_base_type_name, "(p.Swigcptr())\n", NULL);
+      Printv(f_go_wrappers, "\treturn ", go_base_type_name, "(getSwigcptr(p))\n", NULL);
       Printv(f_go_wrappers, "}\n\n", NULL);
 
       Printv(interfaces, "\tSwigGet", go_base_name, "() ", go_base_type, "\n", NULL);
@@ -3428,8 +2608,7 @@
       SwigType *result = Copy(Getattr(b.item, "classtypeobj"));
       SwigType_add_pointer(result);
 
-      int r = makeWrappers(n, name, go_name, NULL, wname, NULL, parm, result,
-			   false);
+      int r = makeWrappers(n, go_name, NULL, wname, NULL, parm, result, false);
       if (r != SWIG_OK) {
 	return r;
       }
@@ -3566,7 +2745,7 @@
     Printv(f_go_wrappers, "}\n\n", NULL);
 
     Printv(f_go_wrappers, "func (p *", director_struct_name, ") Swigcptr() uintptr {\n", NULL);
-    Printv(f_go_wrappers, "\treturn p.", go_type_name, ".Swigcptr()\n", NULL);
+    Printv(f_go_wrappers, "\treturn getSwigcptr(p.", go_type_name, ")\n", NULL);
     Printv(f_go_wrappers, "}\n\n", NULL);
 
     Printv(f_go_wrappers, "func (p *", director_struct_name, ") SwigIs", go_name, "() {\n", NULL);
@@ -3677,50 +2856,17 @@
     }
 
     if (!is_ignored) {
-      if (cgo_flag) {
-	Printv(f_cgo_comment, "extern uintptr_t ", wname, "(int", NULL);
+      Printv(f_cgo_comment, "extern uintptr_t ", wname, "(int", NULL);
 
-	p = parms;
-	for (int i = 0; i < parm_count; ++i) {
-	  p = getParm(p);
-	  bool c_struct_type;
-	  String *ct = cgoTypeForGoValue(p, Getattr(p, "type"), &c_struct_type);
-	  Printv(f_cgo_comment, ", ", ct, " ", Getattr(p, "lname"), NULL);
-	  p = nextParm(p);
-	}
-	Printv(f_cgo_comment, ");\n", NULL);
-      } else {
-	// Declare the C++ wrapper.
-
-	if (!gccgo_flag) {
-	  Printv(f_go_wrappers, "var ", wname, " unsafe.Pointer\n\n", NULL);
-	} else {
-	  Printv(f_go_wrappers, "//extern ", go_prefix, "_", wname, "\n", NULL);
-	}
-
-	Printv(f_go_wrappers, "func ", fn_with_over_name, "(_swig_director int", NULL);
-
-	p = parms;
-	for (int i = 0; i < parm_count; ++i) {
-	  p = getParm(p);
-	  String *tm = goWrapperType(p, Getattr(p, "type"), false);
-	  Printv(f_go_wrappers, ", _ ", tm, NULL);
-	  Delete(tm);
-	  p = nextParm(p);
-	}
-
-	Printv(f_go_wrappers, ") (_swig_ret ", go_type_name, ")", NULL);
-
-	if (!gccgo_flag) {
-	  Printv(f_go_wrappers, " {\n", NULL);
-	  Printv(f_go_wrappers, "\t_swig_p := uintptr(unsafe.Pointer(&_swig_director))\n", NULL);
-	  Printv(f_go_wrappers, "\t_cgo_runtime_cgocall(", wname, ", _swig_p)\n", NULL);
-	  Printv(f_go_wrappers, "\treturn\n", NULL);
-	  Printv(f_go_wrappers, "}", NULL);
-	}
-
-	Printv(f_go_wrappers, "\n\n", NULL);
+      p = parms;
+      for (int i = 0; i < parm_count; ++i) {
+	p = getParm(p);
+	bool c_struct_type;
+	String *ct = cgoTypeForGoValue(p, Getattr(p, "type"), &c_struct_type);
+	Printv(f_cgo_comment, ", ", ct, " ", Getattr(p, "lname"), NULL);
+	p = nextParm(p);
       }
+      Printv(f_cgo_comment, ");\n", NULL);
 
       // Write out the Go function that calls the wrapper.
 
@@ -3740,19 +2886,10 @@
 
       Printv(f_go_wrappers, "\tp := &", director_struct_name, "{0, v}\n", NULL);
 
-      if (gccgo_flag && !cgo_flag) {
-	Printv(f_go_wrappers, "\tdefer SwigCgocallDone()\n", NULL);
-	Printv(f_go_wrappers, "\tSwigCgocall()\n", NULL);
-      }
-
       String *call = NewString("");
 
       Printv(call, "\tp.", class_receiver, " = ", NULL);
-      if (cgo_flag) {
-	Printv(call, go_type_name, "(C.", wname, "(C.int(swigDirectorAdd(p))", NULL);
-      } else {
-	Printv(call, fn_with_over_name, "(swigDirectorAdd(p)", NULL);
-      }
+      Printv(call, go_type_name, "(C.", wname, "(C.int(swigDirectorAdd(p))", NULL);
 
       p = parms;
       for (int i = 0; i < parm_count; ++i) {
@@ -3766,9 +2903,15 @@
 
 	String *goin = goGetattr(p, "tmap:goin");
 	if (goin == NULL) {
-	  Printv(f_go_wrappers, "\t", ivar, " := ", ln, NULL);
+	  Printv(f_go_wrappers, "\t", ivar, " := ", NULL);
+	  bool need_close = false;
 	  if (goTypeIsInterface(p, pt)) {
-	    Printv(f_go_wrappers, ".Swigcptr()", NULL);
+	    Printv(f_go_wrappers, "getSwigcptr(", NULL);
+	    need_close = true;
+	  }
+	  Printv(f_go_wrappers, ln, NULL);
+	  if (need_close) {
+	    Printv(f_go_wrappers, ")", NULL);
 	  }
 	  Printv(f_go_wrappers, "\n", NULL);
 	} else {
@@ -3783,25 +2926,19 @@
 
 	Setattr(p, "emit:goinput", ivar);
 
-	if (cgo_flag) {
-	  bool c_struct_type;
-	  String *ct = cgoTypeForGoValue(p, pt, &c_struct_type);
-	  if (c_struct_type) {
-	    Printv(call, "*(*C.", ct, ")(unsafe.Pointer(&", ivar, "))", NULL);
-	  } else {
-	    Printv(call, "C.", ct, "(", ivar, ")", NULL);
-	  }
-	  Delete(ct);
+	bool c_struct_type;
+	String *ct = cgoTypeForGoValue(p, pt, &c_struct_type);
+	if (c_struct_type) {
+	  Printv(call, "*(*C.", ct, ")(unsafe.Pointer(&", ivar, "))", NULL);
 	} else {
-	  Printv(call, ivar, NULL);
+	  Printv(call, "C.", ct, "(", ivar, ")", NULL);
 	}
+	Delete(ct);
+
 	p = nextParm(p);
       }
 
-      Printv(call, ")", NULL);
-      if (cgo_flag) {
-	Printv(call, ")", NULL);
-      }
+      Printv(call, "))", NULL);
 
       Printv(f_go_wrappers, call, "\n", NULL);
 
@@ -3839,39 +2976,23 @@
       Printv(action, ");", NULL);
       Setattr(n, "wrap:action", action);
 
-      if (cgo_flag) {
-	cgoWrapperInfo info;
+      cgoWrapperInfo info;
 
-	info.n = n;
-	info.go_name = func_name;
-	info.overname = overname;
-	info.wname = wname;
-	info.base = NULL;
-	info.parms = first_parm;
-	info.result = result;
-	info.is_static = false;
-	info.receiver = NULL;
-	info.is_constructor = true;
-	info.is_destructor = false;
+      info.n = n;
+      info.go_name = func_name;
+      info.overname = overname;
+      info.wname = wname;
+      info.base = NULL;
+      info.parms = first_parm;
+      info.result = result;
+      info.is_static = false;
+      info.receiver = NULL;
+      info.is_constructor = true;
+      info.is_destructor = false;
 
-	int r = cgoGccWrapper(&info);
-	if (r != SWIG_OK) {
-	  return r;
-	}
-      } else if (!gccgo_flag) {
-	int r = gcFunctionWrapper(wname);
-	if (r != SWIG_OK) {
-	  return r;
-	}
-	r = gccFunctionWrapper(n, NULL, wname, first_parm, result);
-	if (r != SWIG_OK) {
-	  return r;
-	}
-      } else {
-	int r = gccgoFunctionWrapper(n, NULL, wname, first_parm, result);
-	if (r != SWIG_OK) {
-	  return r;
-	}
+      int r = cgoGccWrapper(&info);
+      if (r != SWIG_OK) {
+	return r;
       }
 
       Swig_restore(n);
@@ -3960,7 +3081,7 @@
       Setattr(n, "wrap:parms", parms);
 
       String *result = NewString("void");
-      int r = makeWrappers(n, fnname, fnname, NULL, wname, NULL, parms, result, isStatic(n));
+      int r = makeWrappers(n, fnname, NULL, wname, NULL, parms, result, isStatic(n));
       if (r != SWIG_OK) {
 	return r;
       }
@@ -4025,65 +3146,9 @@
    * makeDirectorDestructorWrapper
    *
    * Emit the function wrapper for the destructor of a director class.
-   * This writes director_sig to f_c_directors and leaves the function
-   * unfinished.
    * ------------------------------------------------------------ */
 
   void makeDirectorDestructorWrapper(String *go_name, String *director_struct_name, String *director_sig) {
-    if (cgo_flag) {
-      makeCgoDirectorDestructorWrapper(go_name, director_struct_name, director_sig);
-      return;
-    }
-
-    Printv(f_go_wrappers, "func ", go_name, "(c int) {\n", NULL);
-    if (gccgo_flag) {
-      Printv(f_go_wrappers, "\tSwigCgocallBack()\n", NULL);
-      Printv(f_go_wrappers, "\tdefer SwigCgocallBackDone()\n", NULL);
-    }
-    Printv(f_go_wrappers, "\tswigDirectorLookup(c).(*", director_struct_name, ").", class_receiver, " = 0\n", NULL);
-    Printv(f_go_wrappers, "\tswigDirectorDelete(c)\n", NULL);
-    Printv(f_go_wrappers, "}\n\n", NULL);
-
-    String *wname = NewString("_swiggo_wrap_DeleteDirector_");
-    Append(wname, class_name);
-
-    if (!gccgo_flag) {
-      Printv(f_c_directors, "extern \"C\" void ", wname, "(void*, int);\n", NULL);
-    } else {
-      Printv(f_c_directors, "extern \"C\" void ", wname, "(intgo) __asm__(\"", go_prefix, ".", go_name, "\");\n", NULL);
-    }
-
-    Printv(f_c_directors, director_sig, NULL);
-
-    if (!gccgo_flag) {
-      Printv(f_c_directors, "  struct { intgo p; } SWIGSTRUCTPACKED a;\n", NULL);
-      Printv(f_c_directors, "  a.p = go_val;\n", NULL);
-      Printv(f_c_directors, "  crosscall2(", wname, ", &a, (int) sizeof a);\n", NULL);
-
-      Printv(f_gc_wrappers, "#pragma dynexport ", wname, " ", wname, "\n", NULL);
-      Printv(f_gc_wrappers, "#pragma cgo_export_static ", wname, " ", wname, "\n", NULL);
-      Printv(f_gc_wrappers, "#pragma textflag 7\n", NULL);
-      Printv(f_gc_wrappers, "extern void \xc2\xb7", go_name, "();\n", NULL);
-      Printv(f_gc_wrappers, "void\n", NULL);
-      Printv(f_gc_wrappers, wname, "(void *a, int32 n)\n", NULL);
-      Printv(f_gc_wrappers, "{\n", NULL);
-      Printv(f_gc_wrappers, "\truntime\xc2\xb7" "cgocallback(\xc2\xb7", go_name, ", a, n);\n", NULL);
-      Printv(f_gc_wrappers, "}\n\n", NULL);
-    } else {
-      Printv(f_c_directors, "  ", wname, "(go_val);\n", NULL);
-    }
-
-    Delete(wname);
-  }
-
-  /* ------------------------------------------------------------
-   * makeCgoDirectorDestructorWrapper
-   *
-   * When using cgo, emit the function wrapper for the destructor of a
-   * director class.
-   * ------------------------------------------------------------ */
-
-  void makeCgoDirectorDestructorWrapper(String *go_name, String *director_struct_name, String *director_sig) {
     String *wname = Copy(go_name);
     Append(wname, unique_id);
 
@@ -4115,6 +3180,7 @@
     String *name = Getattr(n, "sym:name");
     if (!name) {
       assert(is_ignored);
+      (void)is_ignored;
       name = Getattr(n, "name");
     }
 
@@ -4252,9 +3318,7 @@
     if (overname) {
       Append(callback_name, overname);
     }
-    if (cgo_flag) {
-      Append(callback_name, unique_id);
-    }
+    Append(callback_name, unique_id);
 
     String *upcall_name = Copy(director_struct_name);
     Append(upcall_name, "_upcall_");
@@ -4315,68 +3379,28 @@
       Printv(f_go_wrappers, "}\n\n", NULL);
 
       if (!GetFlag(n, "abstract")) {
-	if (cgo_flag) {
-	  Printv(f_cgo_comment, "extern ", NULL);
+	Printv(f_cgo_comment, "extern ", NULL);
 
-	  if (SwigType_type(result) == T_VOID) {
-	    Printv(f_cgo_comment, "void", NULL);
-	  } else {
-	    bool c_struct_type;
-	    String *ret_type = cgoTypeForGoValue(n, result, &c_struct_type);
-	    Printv(f_cgo_comment, ret_type, NULL);
-	    Delete(ret_type);
-	  }
-
-	  Printv(f_cgo_comment, " ", upcall_wname, "(uintptr_t", NULL);
-
-	  p = parms;
-	  for (int i = 0; i < parm_count; ++i) {
-	    p = getParm(p);
-	    bool c_struct_type;
-	    String *ct = cgoTypeForGoValue(p, Getattr(p, "type"), &c_struct_type);
-	    Printv(f_cgo_comment, ", ", ct, " ", Getattr(p, "lname"), NULL);
-	    p = nextParm(p);
-	  }
-	  Printv(f_cgo_comment, ");\n", NULL);
+	if (SwigType_type(result) == T_VOID) {
+	  Printv(f_cgo_comment, "void", NULL);
 	} else {
-	  // Declare the upcall function, which calls the method on
-	  // the parent class.
-
-	  if (!gccgo_flag) {
-	    Printv(f_go_wrappers, "var ", upcall_wname, " unsafe.Pointer\n\n", NULL);
-	  } else {
-	    Printv(f_go_wrappers, "//extern ", go_prefix, "_", upcall_wname, "\n", NULL);
-	  }
-
-	  Printv(f_go_wrappers, "func ", upcall_gc_name, "(_swig_ptr ", go_type_name, NULL);
-
-	  p = parms;
-	  for (int i = 0; i < parm_count; ++i) {
-	    p = getParm(p);
-	    String *tm = goWrapperType(p, Getattr(p, "type"), false);
-	    Printv(f_go_wrappers, ", _ ", tm, NULL);
-	    Delete(tm);
-	    p = nextParm(p);
-	  }
-
-	  Printv(f_go_wrappers, ")", NULL);
-
-	  if (SwigType_type(result) != T_VOID) {
-	    String *tm = goWrapperType(n, result, true);
-	    Printv(f_go_wrappers, " (_swig_ret ", tm, ")", NULL);
-	    Delete(tm);
-	  }
-
-	  if (!gccgo_flag) {
-	    Printv(f_go_wrappers, " {\n", NULL);
-	    Printv(f_go_wrappers, "\t_swig_p := uintptr(unsafe.Pointer(&_swig_ptr))\n", NULL);
-	    Printv(f_go_wrappers, "\t_cgo_runtime_cgocall(", upcall_wname, ", _swig_p)\n", NULL);
-	    Printv(f_go_wrappers, "\treturn\n", NULL);
-	    Printv(f_go_wrappers, "}", NULL);
-	  }
-
-	  Printv(f_go_wrappers, "\n\n", NULL);
+	  bool c_struct_type;
+	  String *ret_type = cgoTypeForGoValue(n, result, &c_struct_type);
+	  Printv(f_cgo_comment, ret_type, NULL);
+	  Delete(ret_type);
 	}
+
+	Printv(f_cgo_comment, " ", upcall_wname, "(uintptr_t", NULL);
+
+	p = parms;
+	for (int i = 0; i < parm_count; ++i) {
+	  p = getParm(p);
+	  bool c_struct_type;
+	  String *ct = cgoTypeForGoValue(p, Getattr(p, "type"), &c_struct_type);
+	  Printv(f_cgo_comment, ", ", ct, " ", Getattr(p, "lname"), NULL);
+	  p = nextParm(p);
+	}
+	Printv(f_cgo_comment, ");\n", NULL);
       }
 
       // Define the method on the director class in Go.
@@ -4435,73 +3459,36 @@
 	String *ret_type = NULL;
 	bool memcpy_ret = false;
 	String *wt = NULL;
-	bool has_goout = false;
 	String *goout = NULL;
 	if (SwigType_type(result) != T_VOID) {
 	  ret_type = goImType(n, result);
 	  Printv(f_go_wrappers, "\tvar swig_r ", ret_type, "\n", NULL);
 	  goout = goTypemapLookup("goout", n, "swig_r");
-	  if (goout) {
-	    has_goout = true;
-	  }
 
-	  if (cgo_flag) {
-	    bool c_struct_type;
-	    Delete(cgoTypeForGoValue(n, result, &c_struct_type));
-	    if (c_struct_type) {
-	      memcpy_ret = true;
-	    }
+	  bool c_struct_type;
+	  Delete(cgoTypeForGoValue(n, result, &c_struct_type));
+	  if (c_struct_type) {
+	    memcpy_ret = true;
 	  }
 	}
 
-	p = parms;
-	for (int i = 0; i < parm_count; ++i) {
-	  p = getParm(p);
-	  if (goGetattr(p, "tmap:goargout")) {
-	    has_goout = true;
-	  }
-	  p = nextParm(p);
-	}
-
 	String *call = NewString("");
 
-	if (gccgo_flag && !cgo_flag) {
-	  if (has_goout) {
-	    Printv(call, "\tfunc() {\n", NULL);
-	  }
-	  Printv(call, "\tdefer SwigCgocallDone()\n", NULL);
-	  Printv(call, "\tSwigCgocall()\n", NULL);
-	}
-
 	Printv(call, "\t", NULL);
 	if (SwigType_type(result) != T_VOID) {
 	  if (memcpy_ret) {
 	    Printv(call, "swig_r_p := ", NULL);
 	  } else {
-	    Printv(call, "swig_r = ", NULL);
-	    if (cgo_flag) {
-	      Printv(call, "(", ret_type, ")(", NULL);
-	    }
+	    Printv(call, "swig_r = (", ret_type, ")(", NULL);
 	  }
-	  if (cgo_flag && goTypeIsInterface(n, result)) {
+	  if (goTypeIsInterface(n, result)) {
 	    wt = goWrapperType(n, result, true);
 	    Printv(call, "(", wt, ")(", NULL);
 	  }
 	}
 
-	if (cgo_flag) {
-	  Printv(call, "C.", upcall_wname, NULL);
-	} else {
-	  Printv(call, upcall_gc_name, NULL);
-	}
-	Printv(call, "(", NULL);
-	if (cgo_flag) {
-	  Printv(call, "C.uintptr_t(", NULL);
-	}
-	Printv(call, "swig_p.", go_type_name, NULL);
-	if (cgo_flag) {
-	  Printv(call, ")", NULL);
-	}
+	Printv(call, "C.", upcall_wname, "(C.uintptr_t(swig_p.",
+	       go_type_name, ")", NULL);
 
 	p = parms;
 	for (int i = 0; i < parm_count; ++i) {
@@ -4517,9 +3504,15 @@
 	  // the goin typemap.
 	  String *goin = goGetattr(p, "tmap:goin");
 	  if (goin == NULL) {
-	    Printv(f_go_wrappers, "\t", ivar, " := ", ln, NULL);
+	    Printv(f_go_wrappers, "\t", ivar, " := ", NULL);
+	    bool need_close = false;
 	    if (goTypeIsInterface(p, pt)) {
-	      Printv(f_go_wrappers, ".Swigcptr()", NULL);
+	      Printv(f_go_wrappers, "getSwigcptr(", NULL);
+	      need_close = true;
+	    }
+	    Printv(f_go_wrappers, ln, NULL);
+	    if (need_close) {
+	      Printv(f_go_wrappers, ")", NULL);
 	    }
 	    Printv(f_go_wrappers, "\n", NULL);
 	  } else {
@@ -4528,22 +3521,18 @@
 	    goin = Copy(goin);
 	    Replaceall(goin, "$input", ln);
 	    Replaceall(goin, "$result", ivar);
-	    Printv(f_go_wrappers, goin, NULL);
+	    Printv(f_go_wrappers, goin, "\n", NULL);
 	    Delete(goin);
 	  }
 
 	  Setattr(p, "emit:goinput", ivar);
 
-	  if (cgo_flag) {
-	    bool c_struct_type;
-	    String *ct = cgoTypeForGoValue(p, pt, &c_struct_type);
-	    if (c_struct_type) {
-	      Printv(call, "*(*C.", ct, ")(unsafe.Pointer(&", ivar, "))", NULL);
-	    } else {
-	      Printv(call, "C.", ct, "(", ivar, ")", NULL);
-	    }
+	  bool c_struct_type;
+	  String *ct = cgoTypeForGoValue(p, pt, &c_struct_type);
+	  if (c_struct_type) {
+	    Printv(call, "*(*C.", ct, ")(unsafe.Pointer(&", ivar, "))", NULL);
 	  } else {
-	    Printv(call, ivar, NULL);
+	    Printv(call, "C.", ct, "(", ivar, ")", NULL);
 	  }
 
 	  p = nextParm(p);
@@ -4551,19 +3540,13 @@
 
 	Printv(call, ")", NULL);
 
-	if (gccgo_flag && !cgo_flag && has_goout) {
-	  Printv(call, "\n\t}()", NULL);
+	if (wt) {
+	  // Close the type conversion to the wrapper type.
+	  Printv(call, ")", NULL);
 	}
-
-	if (cgo_flag) {
-	  if (wt) {
-	    // Close the type conversion to the wrapper type.
-	    Printv(call, ")", NULL);
-	  }
-	  if (SwigType_type(result) != T_VOID && !memcpy_ret) {
-	    // Close the type conversion of the return value.
-	    Printv(call, ")", NULL);
-	  }
+	if (SwigType_type(result) != T_VOID && !memcpy_ret) {
+	  // Close the type conversion of the return value.
+	  Printv(call, ")", NULL);
 	}
 
 	Printv(call, "\n", NULL);
@@ -4600,11 +3583,162 @@
 
       Printv(f_go_wrappers, "}\n\n", NULL);
 
-      // Define a method in the C++ director class that the C++ upcall
-      // function can call.  This permits an upcall to a protected
-      // method.
-
       if (!GetFlag(n, "abstract")) {
+	// Define a function that uses the Go director type that other
+	// methods in the Go type can call to get parent methods.
+
+	Printv(f_go_wrappers, "func Director", cn, go_with_over_name, "(swig_p ", cn, NULL);
+
+	p = parms;
+	for (int i = 0; i < parm_count; ++i) {
+	  p = getParm(p);
+	  Printv(f_go_wrappers, ", ", Getattr(p, "lname"), " ", NULL);
+	  String *tm = goType(p, Getattr(p, "type"));
+	  Printv(f_go_wrappers, tm, NULL);
+	  Delete(tm);
+	  p = nextParm(p);
+	}
+
+	Printv(f_go_wrappers, ")", NULL);
+
+	if (SwigType_type(result) != T_VOID) {
+	  String *tm = goType(n, result);
+	  Printv(f_go_wrappers, " ", tm, NULL);
+	  Delete(tm);
+	}
+
+	Printv(f_go_wrappers, " {\n", NULL);
+
+	String *ret_type = NULL;
+	bool memcpy_ret = false;
+	String *wt = NULL;
+	String *goout = NULL;
+	if (SwigType_type(result) != T_VOID) {
+	  ret_type = goImType(n, result);
+	  Printv(f_go_wrappers, "\tvar swig_r ", ret_type, "\n", NULL);
+	  goout = goTypemapLookup("goout", n, "swig_r");
+
+	  bool c_struct_type;
+	  Delete(cgoTypeForGoValue(n, result, &c_struct_type));
+	  if (c_struct_type) {
+	    memcpy_ret = true;
+	  }
+	}
+
+	String *call = NewString("");
+
+	Printv(call, "\t", NULL);
+	if (SwigType_type(result) != T_VOID) {
+	  if (memcpy_ret) {
+	    Printv(call, "swig_r_p := ", NULL);
+	  } else {
+	    Printv(call, "swig_r = (", ret_type, ")(", NULL);
+	  }
+	  if (goTypeIsInterface(n, result)) {
+	    wt = goWrapperType(n, result, true);
+	    Printv(call, "(", wt, ")(", NULL);
+	  }
+	}
+
+	Printv(call, "C.", upcall_wname, "(C.uintptr_t(swig_p.(*",
+	       director_struct_name, ").", go_type_name, ")", NULL);
+
+	p = parms;
+	for (int i = 0; i < parm_count; ++i) {
+	  Printv(call, ", ", NULL);
+	  p = getParm(p);
+	  SwigType *pt = Getattr(p, "type");
+
+	  String *ivar = NewStringf("_swig_i_%d", i);
+
+	  String *ln = Copy(Getattr(p, "lname"));
+
+	  String *goin = goGetattr(p, "tmap:goin");
+	  if (goin == NULL) {
+	    Printv(f_go_wrappers, "\t", ivar, " := ", NULL);
+	    bool need_close = false;
+	    if (goTypeIsInterface(p, pt)) {
+	      Printv(f_go_wrappers, "getSwigcptr(", NULL);
+	      need_close = true;
+	    }
+	    Printv(f_go_wrappers, ln, NULL);
+	    if (need_close) {
+	      Printv(f_go_wrappers, ")", NULL);
+	    }
+	    Printv(f_go_wrappers, "\n", NULL);
+	  } else {
+	    String *itm = goImType(p, pt);
+	    Printv(f_go_wrappers, "\tvar ", ivar, " ", itm, "\n", NULL);
+	    goin = Copy(goin);
+	    Replaceall(goin, "$input", ln);
+	    Replaceall(goin, "$result", ivar);
+	    Printv(f_go_wrappers, goin, "\n", NULL);
+	    Delete(goin);
+	  }
+
+	  Setattr(p, "emit:goinput", ivar);
+
+	  bool c_struct_type;
+	  String *ct = cgoTypeForGoValue(p, pt, &c_struct_type);
+	  if (c_struct_type) {
+	    Printv(call, "*(*C.", ct, ")(unsafe.Pointer(&", ivar, "))", NULL);
+	  } else {
+	    Printv(call, "C.", ct, "(", ivar, ")", NULL);
+	  }
+
+	  Delete(ln);
+
+	  p = nextParm(p);
+	}
+
+	Printv(call, ")", NULL);
+
+	if (wt) {
+	  // Close the type conversion to the wrapper type.
+	  Printv(call, ")", NULL);
+	}
+	if (SwigType_type(result) != T_VOID && !memcpy_ret) {
+	  // Close the type conversion of the return value.
+	  Printv(call, ")", NULL);
+	}
+
+	Printv(call, "\n", NULL);
+
+	Printv(f_go_wrappers, call, NULL);
+	Delete(call);
+
+	if (memcpy_ret) {
+	  Printv(f_go_wrappers, "\tswig_r = *(*", ret_type, ")(unsafe.Pointer(&swig_r_p))\n", NULL);
+	}
+
+	goargout(parms);
+
+	if (SwigType_type(result) != T_VOID) {
+	  if (goout == NULL) {
+	    Printv(f_go_wrappers, "\treturn swig_r\n", NULL);
+	  } else {
+	    String *tm = goType(n, result);
+	    Printv(f_go_wrappers, "\tvar swig_r_1 ", tm, "\n", NULL);
+	    Replaceall(goout, "$input", "swig_r");
+	    Replaceall(goout, "$result", "swig_r_1");
+	    Printv(f_go_wrappers, goout, "\n", NULL);
+	    Printv(f_go_wrappers, "\treturn swig_r_1\n", NULL);
+	  }
+	}
+
+	Printv(f_go_wrappers, "}\n\n", NULL);
+
+	if (ret_type) {
+	  Delete(ret_type);
+	}
+	if (wt) {
+	  Delete(wt);
+	}
+
+	// Define a method in the C++ director class that the C++
+	// upcall function can call.  This permits an upcall to a
+	// protected method.
+
 	String *upcall_method_name = NewString("_swig_upcall_");
 	Append(upcall_method_name, name);
 	if (overname) {
@@ -4677,41 +3811,23 @@
 	Printv(action, ");", NULL);
 	Setattr(n, "wrap:action", action);
 
-	if (cgo_flag) {
-	  cgoWrapperInfo info;
+	cgoWrapperInfo info;
 
-	  info.n = n;
-	  info.go_name = go_name;
-	  info.overname = overname;
-	  info.wname = upcall_wname;
-	  info.base = NULL;
-	  info.parms = first_parm;
-	  info.result = result;
-	  info.is_static = is_static;
-	  info.receiver = NULL;
-	  info.is_constructor = false;
-	  info.is_destructor = false;
+	info.n = n;
+	info.go_name = go_name;
+	info.overname = overname;
+	info.wname = upcall_wname;
+	info.base = NULL;
+	info.parms = first_parm;
+	info.result = result;
+	info.is_static = is_static;
+	info.receiver = NULL;
+	info.is_constructor = false;
+	info.is_destructor = false;
 
-	  int r = cgoGccWrapper(&info);
-	  if (r != SWIG_OK) {
-	    return r;
-	  }
-	} else if (!gccgo_flag) {
-	  // Write the upcall wrapper function.  This is compiled by gc
-	  // and calls the C++ function.
-	  int r = gcFunctionWrapper(upcall_wname);
-	  if (r != SWIG_OK) {
-	    return r;
-	  }
-	  r = gccFunctionWrapper(n, NULL, upcall_wname, first_parm, result);
-	  if (r != SWIG_OK) {
-	    return r;
-	  }
-	} else {
-	  int r = gccgoFunctionWrapper(n, NULL, upcall_wname, first_parm, result);
-	  if (r != SWIG_OK) {
-	    return r;
-	  }
+	int r = cgoGccWrapper(&info);
+	if (r != SWIG_OK) {
+	  return r;
 	}
 
 	Delete(first_type);
@@ -4721,195 +3837,13 @@
 
 	Swig_restore(n);
 	Delete(upcall_method_name);
-
-	// Define a function that uses the Go director type that other
-	// methods in the Go type can call to get parent methods.
-
-	Printv(f_go_wrappers, "func Director", cn, go_with_over_name, "(p ", cn, NULL);
-
-	p = parms;
-	for (int i = 0; i < parm_count; ++i) {
-	  p = getParm(p);
-	  Printv(f_go_wrappers, ", ", Getattr(p, "lname"), " ", NULL);
-	  String *tm = goType(p, Getattr(p, "type"));
-	  Printv(f_go_wrappers, tm, NULL);
-	  Delete(tm);
-	  p = nextParm(p);
-	}
-
-	Printv(f_go_wrappers, ")", NULL);
-
-	if (SwigType_type(result) != T_VOID) {
-	  String *tm = goType(n, result);
-	  Printv(f_go_wrappers, " ", tm, NULL);
-	  Delete(tm);
-	}
-
-	Printv(f_go_wrappers, " {\n", NULL);
-
-	String *ret_type = NULL;
-	bool memcpy_ret = false;
-	String *wt = NULL;
-	String *goout = NULL;
-	if (SwigType_type(result) != T_VOID) {
-	  ret_type = goImType(n, result);
-	  Printv(f_go_wrappers, "\tvar swig_r ", ret_type, "\n", NULL);
-	  goout = goTypemapLookup("goout", n, "swig_r");
-
-	  if (cgo_flag) {
-	    bool c_struct_type;
-	    Delete(cgoTypeForGoValue(n, result, &c_struct_type));
-	    if (c_struct_type) {
-	      memcpy_ret = true;
-	    }
-	  }
-	}
-
-	String *call = NewString("");
-
-	if (gccgo_flag && !cgo_flag) {
-	  if (goout != NULL) {
-	    Printv(call, "\tfunc() {\n", NULL);
-	  }
-	  Printv(call, "\tdefer SwigCgocallDone()\n", NULL);
-	  Printv(call, "\tSwigCgocall()\n", NULL);
-	}
-
-	Printv(call, "\t", NULL);
-	if (SwigType_type(result) != T_VOID) {
-	  if (memcpy_ret) {
-	    Printv(call, "swig_r_p := ", NULL);
-	  } else {
-	    Printv(call, "swig_r = ", NULL);
-	    if (cgo_flag) {
-	      Printv(call, "(", ret_type, ")(", NULL);
-	    }
-	  }
-	  if (cgo_flag && goTypeIsInterface(n, result)) {
-	    wt = goWrapperType(n, result, true);
-	    Printv(call, "(", wt, ")(", NULL);
-	  }
-	}
-
-	if (cgo_flag) {
-	  Printv(call, "C.", upcall_wname, NULL);
-	} else {
-	  Printv(call, upcall_gc_name, NULL);
-	}
-	Printv(call, "(", NULL);
-	if (cgo_flag) {
-	  Printv(call, "C.uintptr_t(", NULL);
-	}
-	Printv(call, "p.(*", director_struct_name, ").", go_type_name, NULL);
-	if (cgo_flag) {
-	  Printv(call, ")", NULL);
-	}
-
-	p = parms;
-	for (int i = 0; i < parm_count; ++i) {
-	  Printv(call, ", ", NULL);
-	  p = getParm(p);
-	  SwigType *pt = Getattr(p, "type");
-
-	  String *ivar = NewStringf("_swig_i_%d", i);
-
-	  String *ln = Copy(Getattr(p, "lname"));
-
-	  String *goin = goGetattr(p, "tmap:goin");
-	  if (goin == NULL) {
-	    Printv(f_go_wrappers, "\t", ivar, " := ", ln, NULL);
-	    if (goTypeIsInterface(p, pt)) {
-	      Printv(f_go_wrappers, ".Swigcptr()", NULL);
-	    }
-	    Printv(f_go_wrappers, "\n", NULL);
-	  } else {
-	    String *itm = goImType(p, pt);
-	    Printv(f_go_wrappers, "\tvar ", ivar, " ", itm, "\n", NULL);
-	    goin = Copy(goin);
-	    Replaceall(goin, "$input", ln);
-	    Replaceall(goin, "$result", ivar);
-	    Printv(f_go_wrappers, goin, NULL);
-	    Delete(goin);
-	  }
-
-	  Setattr(p, "emit:goinput", ivar);
-
-	  if (cgo_flag) {
-	    bool c_struct_type;
-	    String *ct = cgoTypeForGoValue(p, pt, &c_struct_type);
-	    if (c_struct_type) {
-	      Printv(call, "*(*C.", ct, ")(unsafe.Pointer(&", ivar, "))", NULL);
-	    } else {
-	      Printv(call, "C.", ct, "(", ivar, ")", NULL);
-	    }
-	  } else {
-	    Printv(call, ivar, NULL);
-	  }
-
-	  Delete(ln);
-
-	  p = nextParm(p);
-	}
-
-	Printv(call, ")", NULL);
-
-	if (gccgo_flag && !cgo_flag && goout != NULL) {
-	  Printv(call, "\n\t}()", NULL);
-	}
-
-	if (cgo_flag) {
-	  if (wt) {
-	    // Close the type conversion to the wrapper type.
-	    Printv(call, ")", NULL);
-	  }
-	  if (SwigType_type(result) != T_VOID && !memcpy_ret) {
-	    // Close the type conversion of the return value.
-	    Printv(call, ")", NULL);
-	  }
-	}
-
-	Printv(call, "\n", NULL);
-
-	Printv(f_go_wrappers, call, NULL);
-	Delete(call);
-
-	if (memcpy_ret) {
-	  Printv(f_go_wrappers, "\tswig_r = *(*", ret_type, ")(unsafe.Pointer(&swig_r_p))\n", NULL);
-	}
-
-	goargout(parms);
-
-	if (SwigType_type(result) != T_VOID) {
-	  if (goout == NULL) {
-	    Printv(f_go_wrappers, "\treturn swig_r\n", NULL);
-	  } else {
-	    String *tm = goType(n, result);
-	    Printv(f_go_wrappers, "\tvar swig_r_1 ", tm, "\n", NULL);
-	    Replaceall(goout, "$input", "swig_r");
-	    Replaceall(goout, "$result", "swig_r_1");
-	    Printv(f_go_wrappers, goout, "\n", NULL);
-	    Printv(f_go_wrappers, "\treturn swig_r_1\n", NULL);
-	  }
-	}
-
-	Printv(f_go_wrappers, "}\n\n", NULL);
-
-	if (ret_type) {
-	  Delete(ret_type);
-	}
-	if (wt) {
-	  Delete(wt);
-	}
       }
 
       // The Go function which invokes the method.  This is called by
       // the C++ method on the director class.
 
-      if (cgo_flag) {
-	Printv(f_go_wrappers, "//export ", callback_name, "\n", NULL);
-      }
-
-      Printv(f_go_wrappers, "func ", callback_name, "(swig_c int", NULL);
+      Printv(f_go_wrappers, "//export ", callback_name, "\n",
+	     "func ", callback_name, "(swig_c int", NULL);
 
       p = parms;
       for (int i = 0; i < parm_count; ++i) {
@@ -4951,7 +3885,7 @@
 	if (SwigType_type(result) != T_VOID) {
 	  Printv(call, "swig_r = ", NULL);
 	  if (result_is_interface) {
-	    Printv(call, result_wrapper, "(", NULL);
+	    Printv(call, result_wrapper, "(getSwigcptr(", NULL);
 	  }
 	}
 	Printv(call, "swig_p.", go_with_over_name, "(", NULL);
@@ -5011,27 +3945,15 @@
 	Printv(call, ")", NULL);
 
 	if (result_is_interface) {
-	  Printv(call, ".Swigcptr())", NULL);
+	  Printv(call, "))", NULL);
 	}
 	Printv(call, "\n", NULL);
 
-	if (gccgo_flag && !cgo_flag) {
-	  if (goout != NULL) {
-	    Printv(f_go_wrappers, "\tfunc() {\n", NULL);
-	  }
-	  Printv(f_go_wrappers, "\tSwigCgocallBack()\n", NULL);
-	  Printv(f_go_wrappers, "\tdefer SwigCgocallBackDone()\n", NULL);
-	}
-
 	Printv(f_go_wrappers, "\tswig_p := swigDirectorLookup(swig_c).(*", director_struct_name, ")\n", NULL);
 	Printv(f_go_wrappers, goincode, NULL);
 	Printv(f_go_wrappers, call, NULL);
 	Delete(call);
 
-	if (gccgo_flag && !cgo_flag && goout != NULL) {
-	  Printv(f_go_wrappers, "\t}()\n", NULL);
-	}
-
 	if (SwigType_type(result) != T_VOID) {
 	  if (goout == NULL) {
 	    Printv(f_go_wrappers, "\treturn swig_r\n", NULL);
@@ -5133,241 +4055,6 @@
    * Emit the function wrapper for a director method.
    * ------------------------------------------------------------ */
   void makeDirectorMethodWrapper(Node *n, Wrapper *w, String *callback_name) {
-    if (cgo_flag) {
-      makeCgoDirectorMethodWrapper(n, w, callback_name);
-      return;
-    }
-
-    ParmList *parms = Getattr(n, "wrap:parms");
-    SwigType *result = Getattr(n, "type");
-
-    String *callback_wname = Swig_name_wrapper(callback_name);
-    Append(callback_wname, unique_id);
-
-    if (!gccgo_flag) {
-      Printv(f_c_directors, "extern \"C\" void ", callback_wname, "(void*, int);\n", NULL);
-    } else {
-      Printv(f_c_directors, "extern \"C\" ", NULL);
-
-      String *fnname = NewString("");
-      Printv(fnname, callback_wname, "(int", NULL);
-
-      Parm *p = parms;
-      while (p) {
-	while (checkAttribute(p, "tmap:directorin:numinputs", "0")) {
-	  p = Getattr(p, "tmap:directorin:next");
-	}
-	String *cg = gccgoCTypeForGoValue(p, Getattr(p, "type"),
-					  Getattr(p, "lname"));
-	Printv(fnname, ", ", cg, NULL);
-	Delete(cg);
-	p = Getattr(p, "tmap:directorin:next");
-      }
-
-      Printv(fnname, ")", NULL);
-
-      if (SwigType_type(result) == T_VOID) {
-	Printv(f_c_directors, "void ", fnname, NULL);
-      } else {
-	String *tm = gccgoCTypeForGoValue(n, result, fnname);
-	Printv(f_c_directors, tm, NULL);
-	Delete(tm);
-      }
-
-      Delete(fnname);
-
-      Printv(f_c_directors, " __asm__(\"", go_prefix, ".", callback_name, "\");\n", NULL);
-    }
-
-    if (!gccgo_flag) {
-      Printv(w->code, "  struct {\n", NULL);
-      Printv(w->code, "    intgo go_val;\n", NULL);
-
-      Parm *p = parms;
-      while (p) {
-	while (checkAttribute(p, "tmap:directorin:numinputs", "0")) {
-	  p = Getattr(p, "tmap:directorin:next");
-	}
-	String *ln = Getattr(p, "lname");
-	String *cg = gcCTypeForGoValue(p, Getattr(p, "type"), ln);
-	Printv(w->code, "      ", cg, ";\n", NULL);
-	Delete(cg);
-	p = Getattr(p, "tmap:directorin:next");
-      }
-      if (SwigType_type(result) != T_VOID) {
-	Printv(w->code, "    long : 0;\n", NULL);
-	String *rname = NewString(Swig_cresult_name());
-	String *cg = gcCTypeForGoValue(n, result, rname);
-	Printv(w->code, "    ", cg, ";\n", NULL);
-	Delete(cg);
-	Delete(rname);
-      }
-
-      Printv(w->code, "  } SWIGSTRUCTPACKED swig_a;\n", NULL);
-      Printv(w->code, "  swig_a.go_val = go_val;\n", NULL);
-
-      p = parms;
-      while (p) {
-	while (checkAttribute(p, "tmap:directorin:numinputs", "0")) {
-	  p = Getattr(p, "tmap:directorin:next");
-	}
-	String *tm = Getattr(p, "tmap:directorin");
-	if (!tm) {
-	  Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file,
-		       line_number, "Unable to use type %s as director method argument\n", SwigType_str(Getattr(p, "type"), 0));
-	} else {
-	  tm = Copy(tm);
-	  String *ln = Getattr(p, "lname");
-	  String *input = NewString("");
-	  Printv(input, "swig_a.", ln, NULL);
-	  Setattr(p, "emit:directorinput", input);
-	  Replaceall(tm, "$input", input);
-	  Replaceall(tm, "$owner", "0");
-	  Delete(input);
-	  Printv(w->code, "\t", tm, "\n", NULL);
-	  Delete(tm);
-	}
-	p = Getattr(p, "tmap:directorin:next");
-      }
-
-      Printv(w->code, "  crosscall2(", callback_wname, ", &swig_a, (int) sizeof swig_a);\n", NULL);
-
-      /* Marshal outputs */
-      for (p = parms; p;) {
-	String *tm;
-	if ((tm = Getattr(p, "tmap:directorargout"))) {
-	  tm = Copy(tm);
-	  Replaceall(tm, "$result", "jresult");
-	  Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
-	  Printv(w->code, tm, "\n", NIL);
-	  Delete(tm);
-	  p = Getattr(p, "tmap:directorargout:next");
-	} else {
-	  p = nextSibling(p);
-	}
-      }
-
-      if (SwigType_type(result) != T_VOID) {
-	String *result_str = NewString("c_result");
-	String *tm = Swig_typemap_lookup("directorout", n, result_str, NULL);
-	if (!tm) {
-	  Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
-		       "Unable to use type %s as director method result\n", SwigType_str(result, 0));
-	} else {
-	  static const String *swig_a_result = NewStringf("swig_a.%s", Swig_cresult_name());
-	  Replaceall(tm, "$input", swig_a_result);
-	  Replaceall(tm, "$result", "c_result");
-	  Printv(w->code, "  ", tm, "\n", NULL);
-	  String *retstr = SwigType_rcaststr(result, "c_result");
-	  Printv(w->code, "  return ", retstr, ";\n", NULL);
-	  Delete(retstr);
-	  Delete(tm);
-	}
-	Delete(result_str);
-      }
-
-      // The C wrapper code which calls the Go function.
-      Printv(f_gc_wrappers, "#pragma dynexport ", callback_wname, " ", callback_wname, "\n", NULL);
-      Printv(f_gc_wrappers, "#pragma cgo_export_static ", callback_wname, " ", callback_wname, "\n", NULL);
-      Printv(f_gc_wrappers, "#pragma textflag 7\n", NULL);
-      Printv(f_gc_wrappers, "extern void \xc2\xb7", callback_name, "();\n", NULL);
-      Printv(f_gc_wrappers, "void\n", NULL);
-      Printv(f_gc_wrappers, callback_wname, "(void *a, int32 n)\n", NULL);
-      Printv(f_gc_wrappers, "{\n", NULL);
-      Printv(f_gc_wrappers, "\truntime\xc2\xb7" "cgocallback(\xc2\xb7", callback_name, ", a, n);\n", NULL);
-      Printv(f_gc_wrappers, "}\n\n", NULL);
-    } else {
-      if (SwigType_type(result) != T_VOID) {
-	String *r = NewString(Swig_cresult_name());
-	String *tm = gccgoCTypeForGoValue(n, result, r);
-	Wrapper_add_local(w, r, tm);
-	Delete(tm);
-	Delete(r);
-      }
-
-      String *args = NewString("");
-
-      Parm *p = parms;
-      while (p) {
-	while (checkAttribute(p, "tmap:directorin:numinputs", "0")) {
-	  p = Getattr(p, "tmap:directorin:next");
-	}
-
-	String *pn = NewString("g");
-	Append(pn, Getattr(p, "lname"));
-	Setattr(p, "emit:directorinput", pn);
-
-	String *tm = gccgoCTypeForGoValue(n, Getattr(p, "type"), pn);
-	Wrapper_add_local(w, pn, tm);
-	Delete(tm);
-
-	tm = Getattr(p, "tmap:directorin");
-	if (!tm) {
-	  Swig_warning(WARN_TYPEMAP_DIRECTORIN_UNDEF, input_file,
-		       line_number, "Unable to use type %s as director method argument\n", SwigType_str(Getattr(p, "type"), 0));
-	} else {
-	  tm = Copy(tm);
-	  Replaceall(tm, "$input", pn);
-	  Replaceall(tm, "$owner", 0);
-	  Printv(w->code, "  ", tm, "\n", NULL);
-	  Delete(tm);
-
-	  Printv(args, ", ", pn, NULL);
-	}
-
-	p = Getattr(p, "tmap:directorin:next");
-      }
-
-      Printv(w->code, "  ", NULL);
-      if (SwigType_type(result) != T_VOID) {
-	Printv(w->code, Swig_cresult_name(), " = ", NULL);
-      }
-      Printv(w->code, callback_wname, "(go_val", args, ");\n", NULL);
-
-      /* Marshal outputs */
-      for (p = parms; p;) {
-	String *tm;
-	if ((tm = Getattr(p, "tmap:directorargout"))) {
-	  tm = Copy(tm);
-	  Replaceall(tm, "$result", "jresult");
-	  Replaceall(tm, "$input", Getattr(p, "emit:directorinput"));
-	  Printv(w->code, tm, "\n", NIL);
-	  Delete(tm);
-	  p = Getattr(p, "tmap:directorargout:next");
-	} else {
-	  p = nextSibling(p);
-	}
-      }
-
-      if (SwigType_type(result) != T_VOID) {
-	String *result_str = NewString("c_result");
-	String *tm = Swig_typemap_lookup("directorout", n, result_str, NULL);
-	if (!tm) {
-	  Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
-		       "Unable to use type %s as director method result\n", SwigType_str(result, 0));
-	} else {
-	  Replaceall(tm, "$input", Swig_cresult_name());
-	  Replaceall(tm, "$result", "c_result");
-	  Printv(w->code, "  ", tm, "\n", NULL);
-	  String *retstr = SwigType_rcaststr(result, "c_result");
-	  Printv(w->code, "  return ", retstr, ";\n", NULL);
-	  Delete(retstr);
-	  Delete(tm);
-	}
-	Delete(result_str);
-      }
-    }
-
-    Delete(callback_wname);
-  }
-
-  /* ------------------------------------------------------------
-   * makeDirectorMethodWrapper
-   *
-   * Emit the function wrapper for a director method for cgo.
-   * ------------------------------------------------------------ */
-
-  void makeCgoDirectorMethodWrapper(Node *n, Wrapper *w, String *callback_name) {
     ParmList *parms = Getattr(n, "wrap:parms");
     SwigType *result = Getattr(n, "type");
 
@@ -5964,8 +4651,8 @@
    * 'X'.
    * ---------------------------------------------------------------------- */
 
-  String *exportedName(String *name) {
-    String *copy = Copy(name);
+  String *exportedName(SwigType *name) {
+    SwigType *copy = Copy(name);
     char c = *Char(copy);
     if (islower(c)) {
       char l[2];
@@ -5985,7 +4672,7 @@
       u[2] = '\0';
       Replace(copy, l, u, DOH_REPLACE_FIRST);
     }
-    String *ret = Swig_name_mangle(copy);
+    String *ret = Swig_name_mangle_type(copy);
     Delete(copy);
     return ret;
   }
@@ -6033,7 +4720,7 @@
     Append(nw, c3);
     Delete(c2);
     Delete(c3);
-    String *ret = Swig_name_mangle(nw);
+    String *ret = Swig_name_mangle_string(nw);
     Delete(nw);
     return ret;
   }
@@ -6050,7 +4737,7 @@
   String *buildGoWrapperName(String *name, String *overname) {
     String *s1 = NewString("_swig_wrap_");
     Append(s1, name);
-    String *s2 = Swig_name_mangle(s1);
+    String *s2 = Swig_name_mangle_string(s1);
     Delete(s1);
     if (overname) {
       Append(s2, overname);
@@ -6085,6 +4772,7 @@
     }
     bool r = addSymbol(name, n, scope) ? true : false;
     assert(r);
+    (void)r;
     return true;
   }
 
@@ -6452,7 +5140,7 @@
     }
 
     String *t = Copy(type);
-    if (SwigType_isarray(t)) {
+    if (SwigType_isarray(t) && Getattr(n, "tmap:gotype") == NULL) {
       SwigType_del_array(t);
       SwigType_add_pointer(t);
     }
@@ -6593,10 +5281,14 @@
       }
     }
 
-    if (Getattr(undefined_types, ty) && !Getattr(defined_types, ty)) {
+    String* go_type = goType(n, ty);
+
+    if (Getattr(undefined_types, ty) && !Getattr(defined_types, go_type)) {
+      Delete(go_type);
       return goWrapperType(n, type, true);
     }
 
+    Delete(go_type);
     return goType(n, type);
   }
 
@@ -6647,7 +5339,7 @@
    * gcCTypeForGoValue()
    *
    * Given a type, return the C/C++ type which will be used to catch
-   * the value in Go.  This is the 6g/8g version.
+   * the value in Go.  This is the gc version.
    * ---------------------------------------------------------------------- */
 
   String *gcCTypeForGoValue(Node *n, SwigType *type, String *name) {
@@ -6656,7 +5348,19 @@
 
     String *tail = NewString("");
     SwigType *t = SwigType_typedef_resolve_all(type);
-    if (!SwigType_isreference(t)) {
+    bool is_const_ref = false;
+    if (SwigType_isreference(t)) {
+      SwigType* tt = Copy(t);
+      SwigType_del_reference(tt);
+      if (SwigType_isqualifier(tt)) {
+	String* q = SwigType_parm(tt);
+	if (Strcmp(q, "const") == 0) {
+	  is_const_ref = true;
+	}
+      }
+      Delete(tt);
+    }
+    if (!is_const_ref) {
       while (Strncmp(gt, "*", 1) == 0) {
 	Replace(gt, "*", "", DOH_REPLACE_FIRST);
 	Printv(tail, "*", NULL);
@@ -6800,17 +5504,6 @@
   }
 
   /* ----------------------------------------------------------------------
-   * gccgoCTypeForGoValue()
-   *
-   * Given a type, return the C/C++ type which will be used to catch
-   * the value in Go.  This is the gccgo version.
-   * ---------------------------------------------------------------------- */
-
-  String *gccgoCTypeForGoValue(Node *n, SwigType *type, String *name) {
-    return gcCTypeForGoValue(n, type, name);
-  }
-
-  /* ----------------------------------------------------------------------
    * goTypeIsInterface
    *
    * Return whether this C++ type is represented as an interface type
@@ -6858,11 +5551,11 @@
       return NewString("int");
     }
 
-    String *type = Getattr(n, "enumtype");
+    SwigType *type = Getattr(n, "enumtype");
     assert(type);
     char *p = Char(type);
     int len = Len(type);
-    String *s = NewString("");
+    SwigType *s = NewString("");
     bool capitalize = true;
     for (int i = 0; i < len; ++i, ++p) {
       if (*p == ':') {
@@ -6878,7 +5571,7 @@
       }
     }
 
-    ret = Swig_name_mangle(s);
+    ret = Swig_name_mangle_type(s);
     Delete(s);
     return ret;
   }
@@ -6922,7 +5615,7 @@
 
   bool isStatic(Node *n) {
     String *storage = Getattr(n, "storage");
-    return (storage && (Swig_storage_isstatic(n) || Strcmp(storage, "friend") == 0) && (!SmartPointer || !Getattr(n, "allocate:smartpointeraccess")));
+    return (storage && (Swig_storage_isstatic(n) || Strstr(storage, "friend")) && (!SmartPointer || !Getattr(n, "allocate:smartpointeraccess")));
   }
 
   /* ----------------------------------------------------------------------
@@ -6933,7 +5626,7 @@
 
   bool isFriend(Node *n) {
     String *storage = Getattr(n, "storage");
-    return storage && Strcmp(storage, "friend") == 0;
+    return storage && Strstr(storage, "friend");
   }
 
   /* ----------------------------------------------------------------------
diff --git a/Source/Modules/guile.cxx b/Source/Modules/guile.cxx
index 461c69e..bb23019 100644
--- a/Source/Modules/guile.cxx
+++ b/Source/Modules/guile.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * guile.cxx
  *
@@ -12,7 +12,6 @@
  * ----------------------------------------------------------------------------- */
 
 #include "swigmod.h"
-
 #include <ctype.h>
 
 // Note string broken in half for compilers that can't handle long strings
@@ -28,9 +27,7 @@
                                Use `module' for native Guile module linking\n\
                                (requires Guile >= 1.5.0).  Use `passive' for\n\
                                passive linking (no C-level module-handling code),\n\
-                               `ltdlmod' for Guile's old dynamic module\n\
-                               convention (Guile <= 1.4), or `hobbit' for hobbit\n\
-                               modules.\n\
+                               or `hobbit' for hobbit modules.\n\
      -onlysetters            - Don't emit traditional getter and setter\n\
                                procedures for structure slots,\n\
                                only emit procedures-with-setters.\n\
@@ -62,7 +59,6 @@
   GUILE_LSTYLE_SIMPLE,		// call `SWIG_init()'
   GUILE_LSTYLE_PASSIVE,		// passive linking (no module code)
   GUILE_LSTYLE_MODULE,		// native guile module linking (Guile >= 1.4.1)
-  GUILE_LSTYLE_LTDLMOD_1_4,	// old (Guile <= 1.4) dynamic module convention
   GUILE_LSTYLE_HOBBIT		// use (hobbit4d link)
 } linkage = GUILE_LSTYLE_SIMPLE;
 
@@ -109,8 +105,8 @@
 static String *memberfunction_name = 0;
 
 extern "C" {
-  static int has_classname(Node *class_node) {
-    return Getattr(class_node, "guile:goopsclassname") ? 1 : 0;
+  static Node *has_classname(Node *class_node) {
+    return Getattr(class_node, "guile:goopsclassname") ? class_node : 0;
   }
 }
 
@@ -132,7 +128,7 @@
       if (argv[i]) {
 	if (strcmp(argv[i], "-help") == 0) {
 	  fputs(usage, stdout);
-	  SWIG_exit(EXIT_SUCCESS);
+	  Exit(EXIT_SUCCESS);
 	} else if (strcmp(argv[i], "-prefix") == 0) {
 	  if (argv[i + 1]) {
 	    prefix = NewString(argv[i + 1]);
@@ -153,9 +149,7 @@
 	  }
 	} else if (strcmp(argv[i], "-Linkage") == 0 || strcmp(argv[i], "-linkage") == 0) {
 	  if (argv[i + 1]) {
-	    if (0 == strcmp(argv[i + 1], "ltdlmod"))
-	      linkage = GUILE_LSTYLE_LTDLMOD_1_4;
-	    else if (0 == strcmp(argv[i + 1], "hobbit"))
+	    if (0 == strcmp(argv[i + 1], "hobbit"))
 	      linkage = GUILE_LSTYLE_HOBBIT;
 	    else if (0 == strcmp(argv[i + 1], "simple"))
 	      linkage = GUILE_LSTYLE_SIMPLE;
@@ -176,7 +170,7 @@
 	    procdoc = NewFile(argv[i + 1], "w", SWIG_output_files());
 	    if (!procdoc) {
 	      FileErrorDisplay(argv[i + 1]);
-	      SWIG_exit(EXIT_FAILURE);
+	      Exit(EXIT_FAILURE);
 	    }
 	    Swig_mark_arg(i);
 	    Swig_mark_arg(i + 1);
@@ -212,12 +206,6 @@
 	} else if ((strcmp(argv[i], "-shadow") == 0) || ((strcmp(argv[i], "-proxy") == 0))) {
 	  goops = true;
 	  Swig_mark_arg(i);
-	} else if (strcmp(argv[i], "-gh") == 0) {
-	  Printf(stderr, "Deprecated command line option: -gh. Wrappers are always generated for the SCM interface. See documentation for more information regarding the deprecated GH interface.\n");
-	  Swig_mark_arg(i);
-	} else if (strcmp(argv[i], "-scm") == 0) {
-	  Printf(stderr, "Deprecated command line option: -scm. Wrappers are always generated for the SCM interface. See documentation for more information regarding the deprecated GH interface.\n");
-	  Swig_mark_arg(i);
 	} else if (strcmp(argv[i], "-primsuffix") == 0) {
 	  if (argv[i + 1]) {
 	    primsuffix = NewString(argv[i + 1]);
@@ -255,7 +243,7 @@
     if (goops) {
       if (linkage != GUILE_LSTYLE_PASSIVE && linkage != GUILE_LSTYLE_MODULE) {
 	Printf(stderr, "guile: GOOPS support requires passive or module linkage\n");
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
     }
 
@@ -298,7 +286,7 @@
     f_begin = NewFile(outfile, "w", SWIG_output_files());
     if (!f_begin) {
       FileErrorDisplay(outfile);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
     f_runtime = NewString("");
     f_init = NewString("");
@@ -322,7 +310,7 @@
 
     Swig_banner(f_begin);
 
-    Printf(f_runtime, "\n\n#ifndef SWIGGUILE\n#define SWIGGUILE\n#endif\n\n");
+    Swig_obligatory_macros(f_runtime, "GUILE");
 
     /* Write out directives and declarations */
 
@@ -421,21 +409,6 @@
       Printf(f_init, "  return SCM_UNSPECIFIED;\n");
       Printf(f_init, "}\n");
       break;
-    case GUILE_LSTYLE_LTDLMOD_1_4:
-      Printf(f_init, "\n/* Linkage: ltdlmod */\n");
-      Replaceall(module_func, "/", "_");
-      Insert(module_func, 0, "scm_init_");
-      Append(module_func, "_module");
-      Printf(f_init, "SCM\n%s (void)\n{\n", module_func);
-      {
-	String *mod = NewString(module_name);
-	Replaceall(mod, "/", " ");
-	Printf(f_init, "    scm_register_module_xxx (\"%s\", (void *) SWIG_init);\n", mod);
-	Printf(f_init, "    return SCM_UNSPECIFIED;\n");
-	Delete(mod);
-      }
-      Printf(f_init, "}\n");
-      break;
     case GUILE_LSTYLE_MODULE:
       Printf(f_init, "\n/* Linkage: module */\n");
       Replaceall(module_func, "/", "_");
@@ -476,7 +449,8 @@
       Printf(f_init, "}\n");
       break;
     default:
-      abort();			// for now
+      fputs("Fatal internal error: Invalid Guile linkage setting.\n", stderr);
+      Exit(EXIT_FAILURE);
     }
 
     if (scmstub) {
@@ -495,7 +469,7 @@
       File *scmstubfile = NewFile(fname, "w", SWIG_output_files());
       if (!scmstubfile) {
 	FileErrorDisplay(fname);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       Delete(fname);
 
@@ -526,7 +500,7 @@
       File *goopsfile = NewFile(fname, "w", SWIG_output_files());
       if (!goopsfile) {
 	FileErrorDisplay(fname);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       Delete(fname);
       Swig_banner_target_lang(goopsfile, ";;;");
@@ -719,7 +693,6 @@
 	sprintf(source, "argv[%d]", i);
       else
 	sprintf(source, "s_%d", i);
-      String *target = Getattr(p, "lname");
 
       if (!args_passed_as_array) {
 	if (i != 0)
@@ -730,8 +703,6 @@
 	Printf(f->code, "    if (%s != SCM_UNDEFINED) {\n", source);
       }
       if ((tm = Getattr(p, "tmap:in"))) {
-	Replaceall(tm, "$source", source);
-	Replaceall(tm, "$target", target);
 	Replaceall(tm, "$input", source);
 	Setattr(p, "emit:input", source);
 	Printv(f->code, tm, "\n", NIL);
@@ -761,8 +732,7 @@
 	if (goops) {
 	  if (i < numreq) {
 	    if (strcmp("void", Char(pt)) != 0) {
-	      Node *class_node = Swig_symbol_clookup_check(pb, Getattr(n, "sym:symtab"),
-							   has_classname);
+	      Node *class_node = Swig_symbol_clookup_check(pb, Getattr(n, "sym:symtab"), has_classname);
 	      String *goopsclassname = !class_node ? NULL : Getattr(class_node, "guile:goopsclassname");
 	      /* do input conversion */
 	      if (goopsclassname) {
@@ -794,7 +764,6 @@
     /* Insert constraint checking code */
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:check"))) {
-	Replaceall(tm, "$target", Getattr(p, "lname"));
 	Printv(f->code, tm, "\n", NIL);
 	p = Getattr(p, "tmap:check:next");
       } else {
@@ -807,8 +776,6 @@
     String *returns_argout = NewString("");
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:argout"))) {
-	Replaceall(tm, "$source", Getattr(p, "lname"));
-	Replaceall(tm, "$target", Getattr(p, "lname"));
 	Replaceall(tm, "$arg", Getattr(p, "emit:input"));
 	Replaceall(tm, "$input", Getattr(p, "emit:input"));
 	Printv(outarg, tm, "\n", NIL);
@@ -828,7 +795,6 @@
     /* Insert cleanup code */
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:freearg"))) {
-	Replaceall(tm, "$target", Getattr(p, "lname"));
 	Replaceall(tm, "$input", Getattr(p, "emit:input"));
 	Printv(cleanup, tm, "\n", NIL);
 	p = Getattr(p, "tmap:freearg:next");
@@ -859,8 +825,6 @@
     // Now have return value, figure out what to do with it.
     if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
       Replaceall(tm, "$result", "gswig_result");
-      Replaceall(tm, "$target", "gswig_result");
-      Replaceall(tm, "$source", Swig_cresult_name());
       if (GetFlag(n, "feature:new"))
 	Replaceall(tm, "$owner", "1");
       else
@@ -898,13 +862,11 @@
 
     if (GetFlag(n, "feature:new")) {
       if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
-	Replaceall(tm, "$source", Swig_cresult_name());
 	Printv(f->code, tm, "\n", NIL);
       }
     }
     // Free any memory allocated by the function being wrapped..
     if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
-      Replaceall(tm, "$source", Swig_cresult_name());
       Printv(f->code, tm, "\n", NIL);
     }
     // Wrap things up (in a manner of speaking)
@@ -924,8 +886,12 @@
 
     if (!Getattr(n, "sym:overloaded")) {
       if (numargs > 10) {
+	/* "The total number of these arguments should match the actual number
+	 * of arguments to fcn, but may not exceed 10" says:
+	 * https://www.gnu.org/software/guile/manual/html_node/Primitive-Procedures.html
+	 * We handle this case by passing all the arguments as "rest".
+	 */
 	int i;
-	/* gh_new_procedure would complain: too many args */
 	/* Build a wrapper wrapper */
 	Printv(f_wrappers, "static SCM\n", wname, "_rest (SCM rest)\n", NIL);
 	Printv(f_wrappers, "{\n", NIL);
@@ -958,20 +924,16 @@
 
 	if (!is_setter) {
 	  /* Strip off "-get" */
-	  char *pws_name = (char *) malloc(sizeof(char) * (len - 3));
-	  strncpy(pws_name, pc, len - 3);
-	  pws_name[len - 4] = 0;
 	  if (struct_member == 2) {
 	    /* There was a setter, so create a procedure with setter */
 	    Printf(f_init, "scm_c_define");
-	    Printf(f_init, "(\"%s\", " "scm_make_procedure_with_setter(getter, setter));\n", pws_name);
+	    Printf(f_init, "(\"%.*s\", " "scm_make_procedure_with_setter(getter, setter));\n", pc, len - 4);
 	  } else {
 	    /* There was no setter, so make an alias to the getter */
 	    Printf(f_init, "scm_c_define");
-	    Printf(f_init, "(\"%s\", getter);\n", pws_name);
+	    Printf(f_init, "(\"%.*s\", getter);\n", pc, len - 4);
 	  }
-	  Printf(exported_symbols, "\"%s\", ", pws_name);
-	  free(pws_name);
+	  Printf(exported_symbols, "\"%.*s\", ", pc, len - 4);
 	}
       } else {
 	/* Register the function */
@@ -1127,6 +1089,8 @@
     Replaceall(proc_name, "_", "-");
     Setattr(n, "wrap:name", proc_name);
 
+    int assignable = !is_immutable(n);
+
     if (1 || (SwigType_type(t) != T_USER) || (is_a_pointer(t))) {
 
       Printf(f->def, "static SCM\n%s(SCM s_0)\n{\n", var_name);
@@ -1137,13 +1101,11 @@
 
       Wrapper_add_local(f, "gswig_result", "SCM gswig_result");
 
-      if (!GetFlag(n, "feature:immutable")) {
+      if (assignable) {
 	/* Check for a setting of the variable value */
 	Printf(f->code, "if (s_0 != SCM_UNDEFINED) {\n");
 	if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
-	  Replaceall(tm, "$source", "s_0");
 	  Replaceall(tm, "$input", "s_0");
-	  Replaceall(tm, "$target", name);
 	  /* Printv(f->code,tm,"\n",NIL); */
 	  emit_action_code(n, f->code, tm);
 	} else {
@@ -1155,8 +1117,6 @@
       // of evaluating or setting)
 
       if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
-	Replaceall(tm, "$source", name);
-	Replaceall(tm, "$target", "gswig_result");
 	Replaceall(tm, "$result", "gswig_result");
 	/* Printv(f->code,tm,"\n",NIL); */
 	emit_action_code(n, f->code, tm);
@@ -1171,7 +1131,7 @@
 
       // Now add symbol to the Guile interpreter
 
-      if (!emit_setters || GetFlag(n, "feature:immutable")) {
+      if (!emit_setters || !assignable) {
 	/* Read-only variables become a simple procedure returning the
 	   value; read-write variables become a simple procedure with
 	   an optional argument. */
@@ -1180,7 +1140,7 @@
 	  /* need to export this function as a variable instead of a procedure */
 	  if (scmstub) {
 	    /* export the function in the wrapper, and (set!) it in scmstub */
-	    Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, %d, 0, (swig_guile_proc) %s);\n", proc_name, !GetFlag(n, "feature:immutable"), var_name);
+	    Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, %d, 0, (swig_guile_proc) %s);\n", proc_name, assignable, var_name);
 	    Printf(scmtext, "(set! %s (%s))\n", proc_name, proc_name);
 	  } else {
 	    /* export the variable directly */
@@ -1189,7 +1149,7 @@
 
 	} else {
 	  /* Export the function as normal */
-	  Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, %d, 0, (swig_guile_proc) %s);\n", proc_name, !GetFlag(n, "feature:immutable"), var_name);
+	  Printf(f_init, "scm_c_define_gsubr(\"%s\", 0, %d, 0, (swig_guile_proc) %s);\n", proc_name, assignable, var_name);
 	}
 
       } else {
@@ -1209,7 +1169,7 @@
 	  Printv(primitive_name, "primitive:", NIL);
 	Printv(primitive_name, proc_name, NIL);
 	/* Simply re-export the procedure */
-	if ((!emit_setters || GetFlag(n, "feature:immutable"))
+	if ((!emit_setters || !assignable)
 	    && GetFlag(n, "feature:constasvar")) {
 	  Printv(goopscode, "(define ", goops_name, " (", primitive_name, "))\n", NIL);
 	} else {
@@ -1227,7 +1187,7 @@
 	String *signature2 = NULL;
 	String *doc = NewString("");
 
-	if (GetFlag(n, "feature:immutable")) {
+	if (!assignable) {
 	  Printv(signature, proc_name, NIL);
 	  if (GetFlag(n, "feature:constasvar")) {
 	    Printv(doc, "Is constant ", NIL);
@@ -1334,9 +1294,7 @@
     // See if there's a typemap
 
     if ((tm = Swig_typemap_lookup("constant", n, name, 0))) {
-      Replaceall(tm, "$source", value);
       Replaceall(tm, "$value", value);
-      Replaceall(tm, "$target", name);
       Printv(f_header, tm, "\n", NIL);
     } else {
       // Create variable and assign it a value
@@ -1417,7 +1375,7 @@
     SwigType *ct = NewStringf("p.%s", Getattr(n, "name"));
     swigtype_ptr = SwigType_manglestr(ct);
 
-    String *mangled_classname = Swig_name_mangle(Getattr(n, "sym:name"));
+    String *mangled_classname = Swig_name_mangle_string(Getattr(n, "sym:name"));
     /* Export clientdata structure */
     Printf(f_runtime, "static swig_guile_clientdata _swig_guile_clientdata%s = { NULL, SCM_EOL };\n", mangled_classname);
 
diff --git a/Source/Modules/interface.cxx b/Source/Modules/interface.cxx
index fee6cd7..83a5e5f 100644
--- a/Source/Modules/interface.cxx
+++ b/Source/Modules/interface.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * interface.cxx
  *
@@ -15,6 +15,7 @@
  * ----------------------------------------------------------------------------- */
 
 #include "swigmod.h"
+#include "cparse.h"
 
 static bool interface_feature_enabled = false;
 
@@ -28,25 +29,31 @@
 
 static List *collect_interface_methods(Node *n) {
   List *methods = NewList();
-  if (Hash *bases = Getattr(n, "interface:bases")) {
-    List *keys = Keys(bases);
-    for (Iterator base = First(keys); base.item; base = Next(base)) {
-      Node *cls = Getattr(bases, base.item);
+  if (List *bases = Getattr(n, "interface:bases")) {
+    for (Iterator base = First(bases); base.item; base = Next(base)) {
+      Node *cls = base.item;
       if (cls == n)
 	continue;
       for (Node *child = firstChild(cls); child; child = nextSibling(child)) {
 	if (Cmp(nodeType(child), "cdecl") == 0) {
 	  if (GetFlag(child, "feature:ignore") || Getattr(child, "interface:owner"))
 	    continue; // skip methods propagated to bases
-	  Node *m = Copy(child);
-	  set_nextSibling(m, NIL);
-	  set_previousSibling(m, NIL);
-	  Setattr(m, "interface:owner", cls);
-	  Append(methods, m);
+	  if (!checkAttribute(child, "kind", "function"))
+	    continue;
+	  if (checkAttribute(child, "storage", "static"))
+	    continue; // accept virtual methods, non-virtual methods too... mmm??. Warn that the interface class has something that is not a virtual method?
+	  Node *nn = copyNode(child);
+	  Setattr(nn, "interface:owner", cls);
+	  ParmList *parms = CopyParmList(Getattr(child, "parms"));
+	  Setattr(nn, "parms", parms);
+	  Delete(parms);
+	  ParmList *throw_parm_list = Getattr(child, "throws");
+	  if (throw_parm_list)
+	    Setattr(nn, "throws", CopyParmList(throw_parm_list));
+	  Append(methods, nn);
 	}
       }
     }
-    Delete(keys);
   }
   return methods;
 }
@@ -55,17 +62,17 @@
  * collect_interface_bases
  * ----------------------------------------------------------------------------- */
 
-static void collect_interface_bases(Hash *bases, Node *n) {
-  if (Getattr(n, "feature:interface")) {
+static void collect_interface_bases(List *bases, Node *n) {
+  if (GetFlag(n, "feature:interface")) {
     String *name = Getattr(n, "interface:name");
     if (!Getattr(bases, name))
-      Setattr(bases, name, n);
+      Append(bases, n);
   }
 
   if (List *baselist = Getattr(n, "bases")) {
     for (Iterator base = First(baselist); base.item; base = Next(base)) {
       if (!GetFlag(base.item, "feature:ignore")) {
-	if (Getattr(base.item, "feature:interface"))
+	if (GetFlag(base.item, "feature:interface"))
 	  collect_interface_bases(bases, base.item);
       }
     }
@@ -83,21 +90,21 @@
  * ----------------------------------------------------------------------------- */
 
 static void collect_interface_base_classes(Node *n) {
-  if (Getattr(n, "feature:interface")) {
+  if (GetFlag(n, "feature:interface")) {
     // check all bases are also interfaces
     if (List *baselist = Getattr(n, "bases")) {
       for (Iterator base = First(baselist); base.item; base = Next(base)) {
 	if (!GetFlag(base.item, "feature:ignore")) {
-	  if (!Getattr(base.item, "feature:interface")) {
+	  if (!GetFlag(base.item, "feature:interface")) {
 	    Swig_error(Getfile(n), Getline(n), "Base class '%s' of '%s' is not similarly marked as an interface.\n", SwigType_namestr(Getattr(base.item, "name")), SwigType_namestr(Getattr(n, "name")));
-	    SWIG_exit(EXIT_FAILURE);
+	    Exit(EXIT_FAILURE);
 	  }
 	}
       }
     }
   }
 
-  Hash *interface_bases = NewHash();
+  List *interface_bases = NewList();
   collect_interface_bases(interface_bases, n);
   if (Len(interface_bases) == 0)
     Delete(interface_bases);
@@ -110,11 +117,11 @@
  * ----------------------------------------------------------------------------- */
 
 static void process_interface_name(Node *n) {
-  if (Getattr(n, "feature:interface")) {
+  if (GetFlag(n, "feature:interface")) {
     String *interface_name = Getattr(n, "feature:interface:name");
     if (!Len(interface_name)) {
       Swig_error(Getfile(n), Getline(n), "The interface feature for '%s' is missing the name attribute.\n", SwigType_namestr(Getattr(n, "name")));
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
     if (Strchr(interface_name, '%')) {
       String *name = NewStringf(interface_name, Getattr(n, "sym:name"));
@@ -139,7 +146,7 @@
     process_interface_name(n);
     collect_interface_base_classes(n);
     List *methods = collect_interface_methods(n);
-    bool is_interface = Getattr(n, "feature:interface") != 0;
+    bool is_interface = GetFlag(n, "feature:interface") ? true : false;
     for (Iterator mi = First(methods); mi.item; mi = Next(mi)) {
       if (!is_interface && GetFlag(mi.item, "abstract"))
 	continue;
@@ -164,8 +171,26 @@
       }
       Delete(this_decl_resolved);
       if (!identically_overloaded_method) {
-	// TODO: Fix if the method is overloaded with different arguments / has default args
-	appendChild(n, mi.item);
+	// Add method copied from base class to this derived class
+	Node *cn = mi.item;
+	Delattr(cn, "sym:overname");
+	String *prefix = Getattr(n, "name");
+	String *name = Getattr(cn, "name");
+	String *decl = Getattr(cn, "decl");
+	String *oldname = Getattr(cn, "sym:name");
+
+	String *symname = Swig_name_make(cn, prefix, name, decl, oldname);
+	if (Strcmp(symname, "$ignore") != 0) {
+	  Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
+	  Node *on = Swig_symbol_add(symname, cn);
+	  (void)on;
+	  assert(on == cn);
+
+	  // Features from the copied base class method are already present, now add in features specific to the added method in the derived class
+	  Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn);
+	  Swig_symbol_setscope(oldscope);
+	  appendChild(n, cn);
+	}
       } else {
 	Delete(mi.item);
       }
diff --git a/Source/Modules/java.cxx b/Source/Modules/java.cxx
index fcc8381..c115cae 100644
--- a/Source/Modules/java.cxx
+++ b/Source/Modules/java.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * java.cxx
  *
@@ -12,8 +12,8 @@
  * ----------------------------------------------------------------------------- */
 
 #include "swigmod.h"
-#include <limits.h>		// for INT_MAX
 #include "cparse.h"
+#include <limits.h>		// for INT_MAX
 #include <ctype.h>
 #include "javadoc.h"
 
@@ -64,6 +64,7 @@
   String *variable_name;	//Name of a variable being wrapped
   String *proxy_class_constants_code;
   String *module_class_constants_code;
+  String *common_begin_code;
   String *enum_code;
   String *package;		// Optional package name
   String *jnipackage;		// Package name used in the JNI code
@@ -139,6 +140,7 @@
       variable_name(NULL),
       proxy_class_constants_code(NULL),
       module_class_constants_code(NULL),
+      common_begin_code(NULL),
       enum_code(NULL),
       package(NULL),
       jnipackage(NULL),
@@ -167,7 +169,7 @@
     /* for now, multiple inheritance in directors is disabled, this
        should be easy to implement though */
     director_multiple_inheritance = 0;
-    director_language = 1;
+    directorLanguage();
   }
   
   ~JAVA() {
@@ -196,7 +198,7 @@
       String *name = Getattr(n, "name") ? Getattr(n, "name") : NewString("<unnamed>");
       Swig_warning(WARN_JAVA_NSPACE_WITHOUT_PACKAGE, Getfile(n), Getline(n),
 	  "The nspace feature is used on '%s' without -package. "
-	  "The generated code may not compile as Java does not support types declared in a named package accessing types declared in an unnamed package.\n", name);
+	  "The generated code may not compile as Java does not support types declared in a named package accessing types declared in an unnamed package.\n", SwigType_namestr(name));
     }
   }
 
@@ -284,10 +286,6 @@
 	  } else {
 	    Swig_arg_error();
 	  }
-	} else if ((strcmp(argv[i], "-shadow") == 0) || ((strcmp(argv[i], "-proxy") == 0))) {
-	  Printf(stderr, "Deprecated command line option: %s. Proxy classes are now generated by default.\n", argv[i]);
-	  Swig_mark_arg(i);
-	  proxy_flag = true;
 	} else if ((strcmp(argv[i], "-doxygen") == 0)) {
 	  Swig_mark_arg(i);
 	  doxygen = true;
@@ -307,15 +305,6 @@
 	} else if (strcmp(argv[i], "-oldvarnames") == 0) {
 	  Swig_mark_arg(i);
 	  old_variable_names = true;
-	} else if (strcmp(argv[i], "-jnic") == 0) {
-	  Swig_mark_arg(i);
-	  Printf(stderr, "Deprecated command line option: -jnic. C JNI calling convention now used when -c++ not specified.\n");
-	} else if (strcmp(argv[i], "-nofinalize") == 0) {
-	  Swig_mark_arg(i);
-	  Printf(stderr, "Deprecated command line option: -nofinalize. Use the new javafinalize typemap instead.\n");
-	} else if (strcmp(argv[i], "-jnicpp") == 0) {
-	  Swig_mark_arg(i);
-	  Printf(stderr, "Deprecated command line option: -jnicpp. C++ JNI calling convention now used when -c++ specified.\n");
 	} else if (strcmp(argv[i], "-help") == 0) {
 	  Printf(stdout, "%s\n", usage);
 	}
@@ -343,7 +332,8 @@
   virtual int top(Node *n) {
 
     // Get any options set in the module directive
-    Node *optionsnode = Getattr(Getattr(n, "module"), "options");
+    Node *module = Getattr(n, "module");
+    Node *optionsnode = Getattr(module, "options");
 
     if (optionsnode) {
       if (Getattr(optionsnode, "jniclassname"))
@@ -363,6 +353,9 @@
 	allow_dirprot();
       }
       allow_allprotected(GetFlag(optionsnode, "allprotected"));
+      common_begin_code = Getattr(optionsnode, "javabegin");
+      if (common_begin_code)
+	Printf(common_begin_code, "\n");
     }
 
     /* Initialize all of the output files */
@@ -371,24 +364,24 @@
 
     if (!outfile) {
       Printf(stderr, "Unable to determine outfile\n");
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
 
     f_begin = NewFile(outfile, "w", SWIG_output_files());
     if (!f_begin) {
       FileErrorDisplay(outfile);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       if (!outfile_h) {
         Printf(stderr, "Unable to determine outfile_h\n");
-        SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
       if (!f_runtime_h) {
 	FileErrorDisplay(outfile_h);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
     }
 
@@ -425,9 +418,9 @@
     constants_interface_name = NewStringf("%sConstants", module_class_name);
 
     // module class and intermediary classes are always created
-    if (!addSymbol(imclass_name, n))
+    if (!addSymbol(imclass_name, module))
       return SWIG_ERROR;
-    if (!addSymbol(module_class_name, n))
+    if (!addSymbol(module_class_name, module))
       return SWIG_ERROR;
 
     imclass_class_code = NewString("");
@@ -456,9 +449,9 @@
 
     Swig_banner(f_begin);
 
-    Printf(f_runtime, "\n\n#ifndef SWIGJAVA\n#define SWIGJAVA\n#endif\n\n");
+    Swig_obligatory_macros(f_runtime, "JAVA");
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Printf(f_runtime, "#define SWIG_DIRECTORS\n");
 
       /* Emit initial director header and director code: */
@@ -510,7 +503,7 @@
     /* Emit code */
     Language::top(n);
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       // Insert director runtime into the f_runtime file (make it occur before %header section)
       Swig_insert_file("director_common.swg", f_runtime);
       Swig_insert_file("director.swg", f_runtime);
@@ -521,7 +514,7 @@
       File *f_im = NewFile(filen, "w", SWIG_output_files());
       if (!f_im) {
 	FileErrorDisplay(filen);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       Append(filenames_list, Copy(filen));
       Delete(filen);
@@ -576,7 +569,7 @@
       File *f_module = NewFile(filen, "w", SWIG_output_files());
       if (!f_module) {
 	FileErrorDisplay(filen);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       Append(filenames_list, Copy(filen));
       Delete(filen);
@@ -635,7 +628,7 @@
       File *f_module = NewFile(filen, "w", SWIG_output_files());
       if (!f_module) {
 	FileErrorDisplay(filen);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       Append(filenames_list, Copy(filen));
       Delete(filen);
@@ -752,7 +745,7 @@
     /* Close all of the files */
     Dump(f_header, f_runtime);
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Dump(f_directors, f_runtime);
       Dump(f_directors_h, f_runtime_h);
 
@@ -786,6 +779,7 @@
     Printf(f, "/* ----------------------------------------------------------------------------\n");
     Swig_banner_target_lang(f, " *");
     Printf(f, " * ----------------------------------------------------------------------------- */\n\n");
+    Printv(f, common_begin_code, NIL);
   }
 
   /*-----------------------------------------------------------------------
@@ -1001,8 +995,6 @@
       // Get typemap for this argument
       if ((tm = Getattr(p, "tmap:in"))) {
 	addThrows(n, "tmap:in", p);
-	Replaceall(tm, "$source", arg);	/* deprecated */
-	Replaceall(tm, "$target", ln);	/* deprecated */
 	Replaceall(tm, "$arg", arg);	/* deprecated? */
 	Replaceall(tm, "$input", arg);
 	Setattr(p, "emit:input", arg);
@@ -1027,7 +1019,6 @@
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:check"))) {
 	addThrows(n, "tmap:check", p);
-	Replaceall(tm, "$target", Getattr(p, "lname"));	/* deprecated */
 	Replaceall(tm, "$arg", Getattr(p, "emit:input"));	/* deprecated? */
 	Replaceall(tm, "$input", Getattr(p, "emit:input"));
 	Printv(f->code, tm, "\n", NIL);
@@ -1041,7 +1032,6 @@
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:freearg"))) {
 	addThrows(n, "tmap:freearg", p);
-	Replaceall(tm, "$source", Getattr(p, "emit:input"));	/* deprecated */
 	Replaceall(tm, "$arg", Getattr(p, "emit:input"));	/* deprecated? */
 	Replaceall(tm, "$input", Getattr(p, "emit:input"));
 	Printv(cleanup, tm, "\n", NIL);
@@ -1055,8 +1045,6 @@
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:argout"))) {
 	addThrows(n, "tmap:argout", p);
-	Replaceall(tm, "$source", Getattr(p, "emit:input"));	/* deprecated */
-	Replaceall(tm, "$target", Getattr(p, "lname"));	/* deprecated */
 	Replaceall(tm, "$arg", Getattr(p, "emit:input"));	/* deprecated? */
 	Replaceall(tm, "$result", "jresult");
 	Replaceall(tm, "$input", Getattr(p, "emit:input"));
@@ -1090,8 +1078,6 @@
       /* Return value if necessary  */
       if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
 	addThrows(n, "tmap:out", n);
-	Replaceall(tm, "$source", Swig_cresult_name());	/* deprecated */
-	Replaceall(tm, "$target", "jresult");	/* deprecated */
 	Replaceall(tm, "$result", "jresult");
 
         if (GetFlag(n, "feature:new"))
@@ -1118,7 +1104,6 @@
     if (GetFlag(n, "feature:new")) {
       if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
 	addThrows(n, "tmap:newfree", n);
-	Replaceall(tm, "$source", Swig_cresult_name());	/* deprecated */
 	Printf(f->code, "%s\n", tm);
       }
     }
@@ -1127,7 +1112,6 @@
     if (!native_function_flag) {
       if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
 	addThrows(n, "tmap:ret", n);
-	Replaceall(tm, "$source", Swig_cresult_name());	/* deprecated */
 	Printf(f->code, "%s\n", tm);
       }
     }
@@ -1262,11 +1246,6 @@
 	return SWIG_NOWRAP;
 
       String *nspace = Getattr(n, "sym:nspace"); // NSpace/getNSpace() only works during Language::enumDeclaration call
-      if (proxy_flag && !is_wrapping_class()) {
-	// Global enums / enums in a namespace
-	assert(!full_imclass_name);
-	constructIntermediateClassName(n);
-      }
 
       enum_code = NewString("");
       String *symname = Getattr(n, "sym:name");
@@ -1317,9 +1296,20 @@
 	}
       }
 
+      if (proxy_flag && !is_wrapping_class()) {
+	// Global enums / enums in a namespace
+	assert(!full_imclass_name);
+	constructIntermediateClassName(n);
+      }
+
       // Emit each enum item
       Language::enumDeclaration(n);
 
+      if (proxy_flag && !is_wrapping_class()) {
+	Delete(full_imclass_name);
+	full_imclass_name = 0;
+      }
+
       if ((enum_feature != SimpleEnum) && symname && typemap_lookup_type) {
 	// Wrap (non-anonymous) C/C++ enum within a typesafe, typeunsafe or proper Java enum
 	// Finish the enum declaration
@@ -1342,10 +1332,7 @@
 	  // Add extra indentation
 	  Replaceall(enum_code, "\n", "\n  ");
 	  Replaceall(enum_code, "  \n", "\n");
-	  if (GetFlag(getCurrentClass(), "feature:interface"))
-	    Printv(interface_class_code, "  ", enum_code, "\n\n", NIL);
-	  else
-	    Printv(proxy_class_constants_code, "  ", enum_code, "\n\n", NIL);
+	  Printv(proxy_class_constants_code, "  ", enum_code, "\n\n", NIL);
 	} else {
 	  // Global enums are defined in their own file
 	  String *output_directory = outputDirectory(nspace);
@@ -1353,7 +1340,7 @@
 	  File *f_enum = NewFile(filen, "w", SWIG_output_files());
 	  if (!f_enum) {
 	    FileErrorDisplay(filen);
-	    SWIG_exit(EXIT_FAILURE);
+	    Exit(EXIT_FAILURE);
 	  }
 	  Append(filenames_list, Copy(filen));
 	  Delete(filen);
@@ -1389,11 +1376,6 @@
 
       Delete(enum_code);
       enum_code = NULL;
-
-      if (proxy_flag && !is_wrapping_class()) {
-	Delete(full_imclass_name);
-	full_imclass_name = 0;
-      }
     }
     return SWIG_OK;
   }
@@ -1774,36 +1756,6 @@
 	} else if (Strcmp(code, "moduleinterfaces") == 0) {
 	  Delete(module_interfaces);
 	  module_interfaces = Copy(strvalue);
-	} else if (Strcmp(code, "moduleimport") == 0) {
-	  Swig_error(input_file, line_number, "Deprecated pragma. Please use the moduleimports pragma.\n");
-	} else if (Strcmp(code, "moduleinterface") == 0) {
-	  Swig_error(input_file, line_number, "Deprecated pragma. Please use the moduleinterfaces pragma.\n");
-	} else if (Strcmp(code, "modulemethodmodifiers") == 0) {
-	  Swig_error(input_file, line_number, "Deprecated pragma. Please use %%javamethodmodifiers.\n");
-	} else if (Strcmp(code, "allshadowimport") == 0) {
-	  Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaimports).\n");
-	} else if (Strcmp(code, "allshadowcode") == 0) {
-	  Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javacode).\n");
-	} else if (Strcmp(code, "allshadowbase") == 0) {
-	  Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javabase).\n");
-	} else if (Strcmp(code, "allshadowinterface") == 0) {
-	  Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javainterfaces).\n");
-	} else if (Strcmp(code, "allshadowclassmodifiers") == 0) {
-	  Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaclassmodifiers).\n");
-	} else if (proxy_flag) {
-	  if (Strcmp(code, "shadowcode") == 0) {
-	    Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javacode).\n");
-	  } else if (Strcmp(code, "shadowimport") == 0) {
-	    Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaimports).\n");
-	  } else if (Strcmp(code, "shadowbase") == 0) {
-	    Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javabase).\n");
-	  } else if (Strcmp(code, "shadowinterface") == 0) {
-	    Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javainterfaces).\n");
-	  } else if (Strcmp(code, "shadowclassmodifiers") == 0) {
-	    Swig_error(input_file, line_number, "Deprecated pragma. Please use %%typemap(javaclassmodifiers).\n");
-	  } else {
-	    Swig_error(input_file, line_number, "Unrecognized pragma.\n");
-	  }
 	} else {
 	  Swig_error(input_file, line_number, "Unrecognized pragma.\n");
 	}
@@ -1853,12 +1805,12 @@
    * addInterfaceNameAndUpcasts()
    * ----------------------------------------------------------------------------- */
 
-  void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, Hash *base_list, String *c_classname) {
-    List *keys = Keys(base_list);
-    for (Iterator it = First(keys); it.item; it = Next(it)) {
-      Node *base = Getattr(base_list, it.item);
-      String *c_baseclass = SwigType_namestr(Getattr(base, "name"));
+  void addInterfaceNameAndUpcasts(SwigType *smart, String *interface_list, String *interface_upcasts, List *base_list, SwigType *c_classname) {
+    for (Iterator it = First(base_list); it.item; it = Next(it)) {
+      Node *base = it.item;
+      SwigType *c_baseclassname = Getattr(base, "name");
       String *interface_name = Getattr(base, "interface:name");
+      SwigType *bsmart = Getattr(base, "smart");
       if (Len(interface_list))
 	Append(interface_list, ", ");
       Append(interface_list, interface_name);
@@ -1877,13 +1829,12 @@
       Replaceall(cptr_method_name, "$interfacename", interface_name);
 
       String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), cptr_method_name);
-      upcastsCode(smart, upcast_method_name, c_classname, c_baseclass);
+      upcastsCode(smart, bsmart, upcast_method_name, c_classname, c_baseclassname);
+
       Delete(upcast_method_name);
       Delete(cptr_method_name);
       Delete(interface_code);
-      Delete(c_baseclass);
     }
-    Delete(keys);
   }
 
   /* -----------------------------------------------------------------------------
@@ -1892,42 +1843,48 @@
    * Add code for C++ casting to base class
    * ----------------------------------------------------------------------------- */
 
-  void upcastsCode(SwigType *smart, String *upcast_method_name, String *c_classname, String *c_baseclass) {
+  void upcastsCode(SwigType *smart, SwigType *bsmart, String *upcast_method_name, SwigType *c_classname, SwigType *c_baseclassname) {
     String *jniname = makeValidJniName(upcast_method_name);
     String *wname = Swig_name_wrapper(jniname);
+
     Printf(imclass_cppcasts_code, "  public final static native long %s(long jarg1);\n", upcast_method_name);
+
     if (smart) {
-      SwigType *bsmart = Copy(smart);
-      SwigType *rclassname = SwigType_typedef_resolve_all(c_classname);
-      SwigType *rbaseclass = SwigType_typedef_resolve_all(c_baseclass);
-      Replaceall(bsmart, rclassname, rbaseclass);
-      Delete(rclassname);
-      Delete(rbaseclass);
-      String *smartnamestr = SwigType_namestr(smart);
-      String *bsmartnamestr = SwigType_namestr(bsmart);
-      Printv(upcasts_code,
-	  "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n",
-	  "    jlong baseptr = 0;\n"
-	  "    ", smartnamestr, " *argp1;\n"
-	  "    (void)jenv;\n"
-	  "    (void)jcls;\n"
-	  "    argp1 = *(", smartnamestr, " **)&jarg1;\n"
-	  "    *(", bsmartnamestr, " **)&baseptr = argp1 ? new ", bsmartnamestr, "(*argp1) : 0;\n"
-	  "    return baseptr;\n"
-	  "}\n", "\n", NIL);
-      Delete(bsmartnamestr);
-      Delete(smartnamestr);
-      Delete(bsmart);
+      if (bsmart) {
+	String *smartnamestr = SwigType_namestr(smart);
+	String *bsmartnamestr = SwigType_namestr(bsmart);
+
+	Printv(upcasts_code,
+	    "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n",
+	    "    jlong baseptr = 0;\n"
+	    "    ", smartnamestr, " *argp1;\n"
+	    "    (void)jenv;\n"
+	    "    (void)jcls;\n"
+	    "    argp1 = *(", smartnamestr, " **)&jarg1;\n"
+	    "    *(", bsmartnamestr, " **)&baseptr = argp1 ? new ", bsmartnamestr, "(*argp1) : 0;\n"
+	    "    return baseptr;\n"
+	    "}\n", "\n", NIL);
+
+	Delete(bsmartnamestr);
+	Delete(smartnamestr);
+      }
     } else {
+      String *classname = SwigType_namestr(c_classname);
+      String *baseclassname = SwigType_namestr(c_baseclassname);
+
       Printv(upcasts_code,
 	  "SWIGEXPORT jlong JNICALL ", wname, "(JNIEnv *jenv, jclass jcls, jlong jarg1) {\n",
 	  "    jlong baseptr = 0;\n"
 	  "    (void)jenv;\n"
 	  "    (void)jcls;\n"
-	  "    *(", c_baseclass, " **)&baseptr = *(", c_classname, " **)&jarg1;\n"
+	  "    *(", baseclassname, " **)&baseptr = *(", classname, " **)&jarg1;\n"
 	  "    return baseptr;\n"
 	  "}\n", "\n", NIL);
+
+      Delete(baseclassname);
+      Delete(classname);
     }
+
     Delete(wname);
     Delete(jniname);
   }
@@ -1937,16 +1894,16 @@
    * ----------------------------------------------------------------------------- */
 
   void emitProxyClassDefAndCPPCasts(Node *n) {
-    String *c_classname = SwigType_namestr(Getattr(n, "name"));
-    String *c_baseclass = NULL;
+    SwigType *c_classname = Getattr(n, "name");
+    SwigType *c_baseclassname = NULL;
     String *baseclass = NULL;
-    String *c_baseclassname = NULL;
     String *interface_list = NewStringEmpty();
     String *interface_upcasts = NewStringEmpty();
     SwigType *typemap_lookup_type = Getattr(n, "classtypeobj");
     bool feature_director = Swig_directorclass(n) ? true : false;
     bool has_outerclass = Getattr(n, "nested:outer") != 0 && !GetFlag(n, "feature:flatnested");
-    SwigType *smart = Swig_cparse_smartptr(n);
+    SwigType *smart = Getattr(n, "smart");
+    SwigType *bsmart = 0;
 
     // Inheritance from pure Java classes
     Node *attributes = NewHash();
@@ -1961,13 +1918,15 @@
       if (baselist) {
 	Iterator base = First(baselist);
 	while (base.item) {
-	  if (!(GetFlag(base.item, "feature:ignore") || Getattr(base.item, "feature:interface"))) {
-	    String *baseclassname = Getattr(base.item, "name");
+	  if (!(GetFlag(base.item, "feature:ignore") || GetFlag(base.item, "feature:interface"))) {
+	    SwigType *baseclassname = Getattr(base.item, "name");
 	    if (!c_baseclassname) {
-	      c_baseclassname = baseclassname;
-	      baseclass = Copy(getProxyName(baseclassname));
-	      if (baseclass)
-		c_baseclass = SwigType_namestr(baseclassname);
+	      String *name = getProxyName(baseclassname);
+	      if (name) {
+		c_baseclassname = baseclassname;
+		baseclass = name;
+		bsmart = Getattr(base.item, "smart");
+	      }
 	    } else {
 	      /* Warn about multiple inheritance for additional base class(es) */
 	      String *proxyclassname = Getattr(n, "classtypeobj");
@@ -1980,11 +1939,11 @@
       }
     }
 
-    Hash *interface_bases = Getattr(n, "interface:bases");
+    List *interface_bases = Getattr(n, "interface:bases");
     if (interface_bases)
       addInterfaceNameAndUpcasts(smart, interface_list, interface_upcasts, interface_bases, c_classname);
 
-    bool derived = baseclass && getProxyName(c_baseclassname);
+    bool derived = baseclass != 0;
     if (derived && purebase_notderived)
       pure_baseclass = empty_string;
     const String *wanted_base = baseclass ? baseclass : pure_baseclass;
@@ -1992,7 +1951,6 @@
     if (purebase_replace) {
       wanted_base = pure_baseclass;
       derived = false;
-      Delete(baseclass);
       baseclass = NULL;
       if (purebase_notderived)
         Swig_error(Getfile(n), Getline(n), "The javabase typemap for proxy %s must contain just one of the 'replace' or 'notderived' attributes.\n", typemap_lookup_type);
@@ -2115,12 +2073,9 @@
 
     if (derived) {
       String *upcast_method_name = Swig_name_member(getNSpace(), getClassPrefix(), smart != 0 ? "SWIGSmartPtrUpcast" : "SWIGUpcast");
-      upcastsCode(smart, upcast_method_name, c_classname, c_baseclass);
+      upcastsCode(smart, bsmart, upcast_method_name, c_classname, c_baseclassname);
       Delete(upcast_method_name);
     }
-
-    Delete(smart);
-    Delete(baseclass);
   }
 
   /* ----------------------------------------------------------------------
@@ -2138,11 +2093,12 @@
     }
 
     Printv(f_interface, typemapLookup(n, "javaimports", Getattr(n, "classtypeobj"), WARN_NONE), "\n", NIL);
-    Printf(f_interface, "public interface %s", interface_name);
+    Printv(f_interface, typemapLookup(n, "javainterfacemodifiers", Getattr(n, "classtypeobj"), WARN_JAVA_TYPEMAP_INTERFACEMODIFIERS_UNDEF), NIL);
+    Printf(f_interface, " %s", interface_name);
     if (List *baselist = Getattr(n, "bases")) {
       String *bases = 0;
       for (Iterator base = First(baselist); base.item; base = Next(base)) {
-	if (GetFlag(base.item, "feature:ignore") || !Getattr(base.item, "feature:interface"))
+	if (GetFlag(base.item, "feature:ignore") || !GetFlag(base.item, "feature:interface"))
 	  continue; // TODO: warn about skipped non-interface bases
 	String *base_iname = Getattr(base.item, "interface:name");
 	if (!bases)
@@ -2217,12 +2173,12 @@
 
 	if (Cmp(proxy_class_name, imclass_name) == 0) {
 	  Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name);
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	}
 
 	if (Cmp(proxy_class_name, module_class_name) == 0) {
 	  Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name);
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	}
       } else {
 	if (outerClassesPrefix) {
@@ -2238,7 +2194,7 @@
 	}
       }
 
-      String *interface_name = Getattr(n, "feature:interface") ? Getattr(n, "interface:name") : 0;
+      String *interface_name = GetFlag(n, "feature:interface") ? Getattr(n, "interface:name") : 0;
       if (outerClassesPrefix) {
 	String *fnspace = nspace ? NewStringf("%s.%s", nspace, outerClassesPrefix) : outerClassesPrefix;
 	if (!addSymbol(proxy_class_name, n, fnspace))
@@ -2262,7 +2218,7 @@
 	f_proxy = NewFile(filen, "w", SWIG_output_files());
 	if (!f_proxy) {
 	  FileErrorDisplay(filen);
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	}
 	Append(filenames_list, Copy(filen));
 	Delete(filen);
@@ -2289,14 +2245,14 @@
       destructor_throws_clause = NewString("");
       proxy_class_constants_code = NewString("");
 
-      if (Getattr(n, "feature:interface")) {
+      if (GetFlag(n, "feature:interface")) {
         interface_class_code = NewString("");
 	String *output_directory = outputDirectory(nspace);
 	String *filen = NewStringf("%s%s.java", output_directory, interface_name);
 	f_interface = NewFile(filen, "w", SWIG_output_files());
 	if (!f_interface) {
 	  FileErrorDisplay(filen);
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	}
 	Append(filenames_list, filen); // file name ownership goes to the list
 	emitBanner(f_interface);
@@ -2464,7 +2420,7 @@
     bool setter_flag = false;
     String *pre_code = NewString("");
     String *post_code = NewString("");
-    bool is_interface = Getattr(parentNode(n), "feature:interface") != 0 
+    bool is_interface = GetFlag(parentNode(n), "feature:interface") && !checkAttribute(n, "kind", "variable")
       && !static_flag && Getattr(n, "interface:owner") == 0;
 
     if (!proxy_flag)
@@ -2696,6 +2652,7 @@
 	Replaceall(imcall, "$imfuncname", intermediary_function_name);
       }
 
+      Replaceall(tm, "$imfuncname", intermediary_function_name);
       Replaceall(tm, "$jnicall", imcall);
     } else {
       Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, "No javaout typemap defined for %s\n", SwigType_str(t, 0));
@@ -2997,7 +2954,7 @@
      * a Java long is used for all classes in the SWIG intermediary class.
      * The intermediary class methods are thus mangled when overloaded to give
      * a unique name. */
-    String *overloaded_name = NewStringf("%s", Getattr(n, "sym:name"));
+    String *overloaded_name = Copy(Getattr(n, "sym:name"));
 
     if (Getattr(n, "sym:overloaded")) {
       Printv(overloaded_name, Getattr(n, "sym:overname"), NIL);
@@ -3181,6 +3138,7 @@
       else
 	Replaceall(tm, "$owner", "false");
       substituteClassname(t, tm);
+      Replaceall(tm, "$imfuncname", overloaded_name);
       Replaceall(tm, "$jnicall", imcall);
     } else {
       Swig_warning(WARN_JAVA_TYPEMAP_JAVAOUT_UNDEF, input_file, line_number, "No javaout typemap defined for %s\n", SwigType_str(t, 0));
@@ -3499,7 +3457,7 @@
     File *f_swigtype = NewFile(filen, "w", SWIG_output_files());
     if (!f_swigtype) {
       FileErrorDisplay(filen);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
     Append(filenames_list, Copy(filen));
     Delete(filen);
@@ -3714,7 +3672,7 @@
       if (newdir_error) {
 	Printf(stderr, "%s\n", newdir_error);
 	Delete(newdir_error);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       Printv(output_directory, nspace_subdirectory, SWIG_FILE_DELIMITER, 0);
       Delete(nspace_subdirectory);
@@ -3835,7 +3793,8 @@
     String *norm_name = SwigType_namestr(Getattr(n, "name"));
     String *swig_director_connect = Swig_name_member(getNSpace(), getClassPrefix(), "director_connect");
     String *swig_director_connect_jni = makeValidJniName(swig_director_connect);
-    String *smartptr = Getattr(n, "feature:smartptr");
+    SwigType *smart = Getattr(n, "smart");
+    String *smartptr = smart ? SwigType_namestr(smart) : 0;
     String *dirClassName = directorClassName(n);
     Wrapper *code_wrap;
 
@@ -3881,7 +3840,7 @@
 	   "SWIGEXPORT void JNICALL Java_%s%s_%s(JNIEnv *jenv, jclass jcls, jobject jself, jlong objarg, jboolean jtake_or_release) {\n",
 	   jnipackage, jni_imclass_name, changeown_jnimethod_name);
 
-    if (Len(smartptr)) {
+    if (smartptr) {
         Printf(code_wrap->code, "  %s *obj = *((%s **)&objarg);\n", smartptr, smartptr);
         Printf(code_wrap->code, "  // Keep a local instance of the smart pointer around while we are using the raw pointer\n");
         Printf(code_wrap->code, "  // Avoids using smart pointer specific API.\n");
@@ -4011,7 +3970,7 @@
     String *name = Getattr(n, "name");
     String *symname = Getattr(n, "sym:name");
     SwigType *returntype = Getattr(n, "type");
-    String *overloaded_name = getOverloadedName(n);
+    String *overloaded_name = 0;
     String *storage = Getattr(n, "storage");
     String *value = Getattr(n, "value");
     String *decl = Getattr(n, "decl");
@@ -4034,7 +3993,7 @@
     String *classret_desc = NewString("");
     SwigType *c_ret_type = NULL;
     String *jupcall_args = NewString("swigjobj");
-    String *imclass_dmethod;
+    String *imclass_dmethod = 0;
     String *callback_def = NewString("");
     String *callback_code = NewString("");
     String *imcall_args = NewString("");
@@ -4047,7 +4006,11 @@
     // we're consistent with the sym:overload name in functionWrapper. (?? when
     // does the overloaded method name get set?)
 
-    imclass_dmethod = NewStringf("%s", Swig_name_member(getNSpace(), dirclassname, overloaded_name));
+    if (!ignored_method) {
+      overloaded_name = getOverloadedName(n);
+      imclass_dmethod = Swig_name_member(getNSpace(), dirclassname, overloaded_name);
+    }
+
 
     qualified_return = SwigType_rcaststr(returntype, "c_result");
 
@@ -4100,12 +4063,14 @@
       }
     }
 
-    /* Create the intermediate class wrapper */
-    tm = Swig_typemap_lookup("jtype", n, "", 0);
-    if (tm) {
-      Printf(callback_def, "  public static %s %s(%s jself", tm, imclass_dmethod, qualified_classname);
-    } else {
-      Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(returntype, 0));
+    if (!ignored_method) {
+      /* Create the intermediate class wrapper */
+      tm = Swig_typemap_lookup("jtype", n, "", 0);
+      if (tm) {
+	Printf(callback_def, "  public static %s %s(%s jself", tm, imclass_dmethod, qualified_classname);
+      } else {
+	Swig_warning(WARN_JAVA_TYPEMAP_JTYPE_UNDEF, input_file, line_number, "No jtype typemap defined for %s\n", SwigType_str(returntype, 0));
+      }
     }
 
     String *cdesc = NULL;
@@ -4828,34 +4793,27 @@
     // .'s to delimit namespaces, so we need to replace those with /'s
     Replace(internal_classname, NSPACE_SEPARATOR, "/", DOH_REPLACE_ANY);
 
-    Wrapper_add_localv(w, "baseclass", "static jclass baseclass", "= 0", NIL);
     Printf(w->def, "void %s::swig_connect_director(JNIEnv *jenv, jobject jself, jclass jcls, bool swig_mem_own, bool weak_global) {", director_classname);
 
+    Printf(w->def, "static jclass baseclass = swig_new_global_ref(jenv, \"%s\");\n", internal_classname);
+    Printf(w->def, "if (!baseclass) return;\n");
+
     if (first_class_dmethod != curr_class_dmethod) {
-      Printf(w->def, "static struct {\n");
-      Printf(w->def, "const char *mname;\n");
-      Printf(w->def, "const char *mdesc;\n");
-      Printf(w->def, "jmethodID base_methid;\n");
-      Printf(w->def, "} methods[] = {\n");
+      Printf(w->def, "static SwigDirectorMethod methods[] = {\n");
 
       for (int i = first_class_dmethod; i < curr_class_dmethod; ++i) {
 	UpcallData *udata = Getitem(dmethods_seq, i);
 
-	Printf(w->def, "{ \"%s\", \"%s\", NULL }", Getattr(udata, "method"), Getattr(udata, "fdesc"));
+	Printf(w->def, "SwigDirectorMethod(jenv, baseclass, \"%s\", \"%s\")", Getattr(udata, "method"), Getattr(udata, "fdesc"));
 	if (i != curr_class_dmethod - 1)
 	  Putc(',', w->def);
 	Putc('\n', w->def);
       }
 
-      Printf(w->def, "};\n");
+      Printf(w->def, "};");
     }
 
     Printf(w->code, "if (swig_set_self(jenv, jself, swig_mem_own, weak_global)) {\n");
-    Printf(w->code, "if (!baseclass) {\n");
-    Printf(w->code, "baseclass = jenv->FindClass(\"%s\");\n", internal_classname);
-    Printf(w->code, "if (!baseclass) return;\n");
-    Printf(w->code, "baseclass = (jclass) jenv->NewGlobalRef(baseclass);\n");
-    Printf(w->code, "}\n");
 
     int n_methods = curr_class_dmethod - first_class_dmethod;
 
@@ -4870,12 +4828,8 @@
 
       /* Emit the code to look up the class's methods, initialize the override array */
 
-      Printf(w->code, "bool derived = (jenv->IsSameObject(baseclass, jcls) ? false : true);\n");
-      Printf(w->code, "for (int i = 0; i < %d; ++i) {\n", n_methods);
-      Printf(w->code, "  if (!methods[i].base_methid) {\n");
-      Printf(w->code, "    methods[i].base_methid = jenv->GetMethodID(baseclass, methods[i].mname, methods[i].mdesc);\n");
-      Printf(w->code, "    if (!methods[i].base_methid) return;\n");
-      Printf(w->code, "  }\n");
+      Printf(w->code, "  bool derived = (jenv->IsSameObject(baseclass, jcls) ? false : true);\n");
+      Printf(w->code, "  for (int i = 0; i < %d; ++i) {\n", n_methods);
       // Generally, derived classes have a mix of overridden and
       // non-overridden methods and it is worth making a GetMethodID
       // check during initialization to determine if each method is
@@ -4895,8 +4849,8 @@
       } else {
         Printf(w->code, "  swig_override[i] = false;\n");
         Printf(w->code, "  if (derived) {\n");
-        Printf(w->code, "    jmethodID methid = jenv->GetMethodID(jcls, methods[i].mname, methods[i].mdesc);\n");
-        Printf(w->code, "    swig_override[i] = (methid != methods[i].base_methid);\n");
+        Printf(w->code, "    jmethodID methid = jenv->GetMethodID(jcls, methods[i].name, methods[i].desc);\n");
+        Printf(w->code, "    swig_override[i] = methods[i].methid && (methid != methods[i].methid);\n");
         Printf(w->code, "    jenv->ExceptionClear();\n");
         Printf(w->code, "  }\n");
       }
diff --git a/Source/Modules/javascript.cxx b/Source/Modules/javascript.cxx
index 31576bd..8fe394f 100644
--- a/Source/Modules/javascript.cxx
+++ b/Source/Modules/javascript.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * javascript.cxx
  *
@@ -24,12 +24,14 @@
 // keywords used for state variables
 #define NAME "name"
 #define NAME_MANGLED "name_mangled"
+#define INDEX "idx"
 #define TYPE "type"
 #define TYPE_MANGLED "type_mangled"
 #define WRAPPER_NAME "wrapper"
 #define IS_IMMUTABLE "is_immutable"
 #define IS_STATIC "is_static"
 #define IS_ABSTRACT "is_abstract"
+#define IS_WRAPPED "is_wrapped"
 #define GETTER "getter"
 #define SETTER "setter"
 #define PARENT "parent"
@@ -39,6 +41,7 @@
 #define CTOR_DISPATCHERS "ctor_dispatchers"
 #define DTOR "dtor"
 #define ARGCOUNT "wrap:argc"
+#define ARGREQUIRED "wrap:argmin"
 #define HAS_TEMPLATES "has_templates"
 #define FORCE_CPP "force_cpp"
 #define RESET true
@@ -125,7 +128,8 @@
    enum JSEngine {
      JavascriptCore,
      V8,
-     NodeJS
+     NodeJS,
+     NAPI
    };
 
    JSEmitter(JSEngine engine);
@@ -166,7 +170,7 @@
    */
   virtual int exitClass(Node *) {
     return SWIG_OK;
-  };
+  }
 
   /**
    * Invoked at the beginning of the variableHandler.
@@ -178,7 +182,7 @@
    */
   virtual int exitVariable(Node *) {
     return SWIG_OK;
-  };
+  }
 
   /**
    * Invoked at the beginning of the functionHandler.
@@ -190,7 +194,7 @@
    */
   virtual int exitFunction(Node *) {
     return SWIG_OK;
-  };
+  }
 
   /**
    * Invoked by functionWrapper callback after call to Language::functionWrapper.
@@ -225,6 +229,13 @@
 protected:
 
   /**
+   * Helper function for detecting if the constructor Node does not use a name that matches
+   * the expected name for a constructor. Occurs when %rename is used for just a constructor
+   * or %template instantiates a templated constructor with a different name to the class.
+   */
+  bool isRenamedConstructor(Node *n);
+
+  /**
    * Generates code for a constructor function.
    */
   virtual int emitCtor(Node *n);
@@ -255,6 +266,8 @@
 
   virtual String *emitInputTypemap(Node *n, Parm *params, Wrapper *wrapper, String *arg);
 
+  virtual String *emitCheckTypemap(Node *n, Parm *params, Wrapper *wrapper, String *arg);
+
   virtual void marshalOutput(Node *n, ParmList *params, Wrapper *wrapper, String *actioncode, const String *cresult = 0, bool emitReturnVariable = true);
 
   virtual void emitCleanupCode(Node *n, Wrapper *wrapper, ParmList *params);
@@ -264,14 +277,21 @@
    */
   Node *getBaseClass(Node *n);
 
-  Parm *skipIgnoredArgs(Parm *p);
-
   virtual int createNamespace(String *scope);
 
   virtual Hash *createNamespaceEntry(const char *name, const char *parent, const char *parent_mangled);
 
   virtual int emitNamespaces() = 0;
 
+  virtual const char *getFunctionTemplate(bool);
+
+  virtual const char *getFunctionDispatcherTemplate(bool);
+
+  virtual const char *getOverloadedFunctionTemplate(bool);
+
+  virtual const char *getSetterTemplate(bool);
+
+  virtual const char *getGetterTemplate(bool);
 
 protected:
 
@@ -293,6 +313,7 @@
 JSEmitter *swig_javascript_create_JSCEmitter();
 JSEmitter *swig_javascript_create_V8Emitter();
 JSEmitter *swig_javascript_create_NodeJSEmitter();
+JSEmitter *swig_javascript_create_NAPIEmitter();
 
 /**********************************************************************
  * JAVASCRIPT: SWIG module implementation
@@ -512,14 +533,14 @@
   return SWIG_OK;
 }
 
-static const char *usage = (char *) "\
+static const char *usage = (char *)"\
 Javascript Options (available with -javascript)\n\
      -jsc                   - creates a JavascriptCore extension \n\
      -v8                    - creates a v8 extension \n\
      -node                  - creates a node.js extension \n\
+     -napi                  - creates a NAPI extension \n\
      -debug-codetemplates   - generates information about the origin of code templates\n";
 
-
 /* ---------------------------------------------------------------------
  * main()
  *
@@ -535,26 +556,33 @@
   for (int i = 1; i < argc; i++) {
     if (argv[i]) {
       if (strcmp(argv[i], "-v8") == 0) {
-      	if (engine != -1) {
+	if (engine != -1) {
 	  Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE);
-	  SWIG_exit(-1);
-      	}
+	  Exit(EXIT_FAILURE);
+	}
 	Swig_mark_arg(i);
 	engine = JSEmitter::V8;
       } else if (strcmp(argv[i], "-jsc") == 0) {
-      	if (engine != -1) {
+	if (engine != -1) {
 	  Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE);
-	  SWIG_exit(-1);
-      	}
+	  Exit(EXIT_FAILURE);
+	}
 	Swig_mark_arg(i);
 	engine = JSEmitter::JavascriptCore;
       } else if (strcmp(argv[i], "-node") == 0) {
-      	if (engine != -1) {
+	if (engine != -1) {
 	  Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE);
-	  SWIG_exit(-1);
-      	}
+	  Exit(EXIT_FAILURE);
+	}
 	Swig_mark_arg(i);
 	engine = JSEmitter::NodeJS;
+      } else if (strcmp(argv[i], "-napi") == 0) {
+	if (engine != -1) {
+	  Printf(stderr, ERR_MSG_ONLY_ONE_ENGINE_PLEASE);
+	  Exit(EXIT_FAILURE);
+	}
+	Swig_mark_arg(i);
+	engine = JSEmitter::NAPI;
       } else if (strcmp(argv[i], "-debug-codetemplates") == 0) {
 	Swig_mark_arg(i);
 	js_template_enable_debug = true;
@@ -566,6 +594,7 @@
   }
 
   switch (engine) {
+  case JSEmitter::NodeJS:
   case JSEmitter::V8:
     {
       emitter = swig_javascript_create_V8Emitter();
@@ -575,6 +604,9 @@
       if (!cparse_cplusplus) {
 	Swig_cparse_cplusplusout(1);
       }
+      if (engine == JSEmitter::NodeJS) {
+	Preprocessor_define("BUILDING_NODE_EXTENSION 1", 0);
+      }
       break;
     }
   case JSEmitter::JavascriptCore:
@@ -584,18 +616,21 @@
       SWIG_library_directory("javascript/jsc");
       break;
     }
-  case JSEmitter::NodeJS:
+  case JSEmitter::NAPI:
     {
-      emitter = swig_javascript_create_V8Emitter();
-      Preprocessor_define("SWIG_JAVASCRIPT_V8 1", 0);
+      emitter = swig_javascript_create_NAPIEmitter();
+      Preprocessor_define("SWIG_JAVASCRIPT_NAPI 1", 0);
+      SWIG_library_directory("javascript/napi");
       Preprocessor_define("BUILDING_NODE_EXTENSION 1", 0);
-      SWIG_library_directory("javascript/v8");
+      if (!cparse_cplusplus) {
+	Swig_cparse_cplusplusout(1);
+      }
       break;
     }
   default:
     {
-      Printf(stderr, "SWIG Javascript: Unknown engine. Please specify one of '-jsc', '-v8' or '-node'.\n");
-      SWIG_exit(-1);
+      Printf(stderr, "SWIG Javascript: Unknown engine. Please specify one of '-jsc', '-v8', '-node' or '-napi'.\n");
+      Exit(EXIT_FAILURE);
       break;
     }
   }
@@ -666,7 +701,7 @@
 
   if (!templ) {
     Printf(stderr, "Could not find template %s\n.", name);
-    SWIG_exit(EXIT_FAILURE);
+    Exit(EXIT_FAILURE);
   }
 
   Template t(templ, name);
@@ -693,17 +728,6 @@
   return SWIG_OK;
 }
 
-/* ---------------------------------------------------------------------
- * skipIgnoredArgs()
- * --------------------------------------------------------------------- */
-
-Parm *JSEmitter::skipIgnoredArgs(Parm *p) {
-  while (checkAttribute(p, "tmap:in:numinputs", "0")) {
-    p = Getattr(p, "tmap:in:next");
-  }
-  return p;
-}
-
 /* -----------------------------------------------------------------------------
  * JSEmitter::getBaseClass() :  the node of the base class or NULL
  *
@@ -727,7 +751,7 @@
  /* -----------------------------------------------------------------------------
   * JSEmitter::emitWrapperFunction() :  dispatches emitter functions.
   *
-  * This allows to have small sized, dedicated emitting functions.
+  * This allows having small sized, dedicated emitting functions.
   * All state dependent branching is done here.
   * ----------------------------------------------------------------------------- */
 
@@ -760,13 +784,10 @@
 	ret = emitSetter(n, is_member, is_static);
       } else if (is_getter) {
 	ret = emitGetter(n, is_member, is_static);
-      } else {
-	Swig_print_node(n);
       }
 
     } else {
       Printf(stderr, "Warning: unsupported wrapper function type\n");
-      Swig_print_node(n);
       ret = SWIG_ERROR;
     }
   } else {
@@ -778,7 +799,6 @@
       ret = emitDtor(n);
     } else {
       Printf(stderr, "Warning: unsupported wrapper function type");
-      Swig_print_node(n);
       ret = SWIG_ERROR;
     }
   }
@@ -852,7 +872,7 @@
     SetFlag(state.variable(), IS_STATIC);
   }
 
-  if (!Language::instance()->is_assignable(n)) {
+  if (Language::instance()->is_immutable(n)) {
     SetFlag(state.variable(), IS_IMMUTABLE);
   }
   // FIXME: test "arrays_global" does not compile with that as it is not allowed to assign to char[]
@@ -863,8 +883,44 @@
   return SWIG_OK;
 }
 
+const char *JSEmitter::getFunctionTemplate(bool) {
+  return "js_function";
+}
+
+const char *JSEmitter::getFunctionDispatcherTemplate(bool) {
+  return "js_function_dispatcher";
+}
+
+const char *JSEmitter::getOverloadedFunctionTemplate(bool) {
+  return "js_overloaded_function";
+}
+
+const char *JSEmitter::getGetterTemplate(bool) {
+  return "js_getter";
+}
+
+const char *JSEmitter::getSetterTemplate(bool) {
+  return "js_setter";
+}
+
+bool JSEmitter::isRenamedConstructor(Node *n) {
+  Node *cls = parentNode(n);
+  if (!Equal(nodeType(cls), "class")) {
+    cls = parentNode(cls);
+    assert(Equal(nodeType(cls), "class"));
+  }
+
+  return !Equal(Getattr(n, "constructorHandler:sym:name"), Getattr(cls, "sym:name"));
+}
+
 int JSEmitter::emitCtor(Node *n) {
 
+  // Constructor renaming does not work in JavaScript.
+  // This allows us to slip past the unit tests which are broken for all JavaScript backends.
+  // TODO: fix by correcting the bad constructor name - this is the approach used in the Java module.
+  if (isRenamedConstructor(n))
+    return SWIG_ERROR;
+
   Wrapper *wrapper = NewWrapper();
 
   bool is_overloaded = GetFlag(n, "sym:overloaded") != 0;
@@ -884,10 +940,6 @@
   ParmList *params = Getattr(n, "parms");
   emit_parameter_variables(params, wrapper);
   emit_attach_parmmaps(params, wrapper);
-  // HACK: in test-case `ignore_parameter` emit_attach_parmmaps generated an extra line of applied typemaps.
-  // Deleting wrapper->code here, to reset, and as it seemed to have no side effect elsewhere
-  Delete(wrapper->code);
-  wrapper->code = NewString("");
 
   Printf(wrapper->locals, "%sresult;", SwigType_str(Getattr(n, "type"), 0));
 
@@ -897,16 +949,20 @@
 
   emitCleanupCode(n, wrapper, params);
 
-  t_ctor.replace("$jswrapper", wrap_name)
+  t_ctor.replace("$jsmangledname", state.clazz(NAME_MANGLED))
+      .replace("$jswrapper", wrap_name)
       .replace("$jsmangledtype", state.clazz(TYPE_MANGLED))
       .replace("$jslocals", wrapper->locals)
       .replace("$jscode", wrapper->code)
       .replace("$jsargcount", Getattr(n, ARGCOUNT))
+      .replace("$jsparent", state.clazz(PARENT_MANGLED))
+      .replace("$jsargrequired", Getattr(n, ARGREQUIRED))
       .pretty_print(f_wrappers);
 
   Template t_ctor_case(getTemplate("js_ctor_dispatch_case"));
   t_ctor_case.replace("$jswrapper", wrap_name)
-      .replace("$jsargcount", Getattr(n, ARGCOUNT));
+      .replace("$jsargcount", Getattr(n, ARGCOUNT))
+      .replace("$jsargrequired", Getattr(n, ARGREQUIRED));
   Append(state.clazz(CTOR_DISPATCHERS), t_ctor_case.str());
 
   DelWrapper(wrapper);
@@ -917,8 +973,10 @@
       String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name"));
       Template t_mainctor(getTemplate("js_ctor_dispatcher"));
       t_mainctor.replace("$jswrapper", wrap_name)
+	  .replace("$jsmangledtype", state.clazz(TYPE_MANGLED))
 	  .replace("$jsmangledname", state.clazz(NAME_MANGLED))
 	  .replace("$jsdispatchcases", state.clazz(CTOR_DISPATCHERS))
+	  .replace("$jsparent", state.clazz(PARENT_MANGLED))
 	  .pretty_print(f_wrappers);
       state.clazz(CTOR, wrap_name);
     }
@@ -936,7 +994,7 @@
   SwigType *type = state.clazz(TYPE);
   String *p_classtype = SwigType_add_pointer(state.clazz(TYPE));
   String *ctype = SwigType_lstr(p_classtype, "");
-  String *free = NewString("");
+  String *jsfree = NewString("");
 
   // (Taken from JSCore implementation.)
   /* The if (Extend) block was taken from the Ruby implementation.
@@ -979,9 +1037,9 @@
   // TODO: generate dtors more similar to other wrappers
   // EW: I think this is wrong. delete should only be used when new was used to create. If malloc was used, free needs to be used.
   if (SwigType_isarray(type)) {
-    Printf(free, "delete [] (%s)", ctype);
+    Printf(jsfree, "delete [] (%s)", ctype);
   } else {
-    Printf(free, "delete (%s)", ctype);
+    Printf(jsfree, "delete (%s)", ctype);
   }
 
   String *destructor_action = Getattr(n, "wrap:action");
@@ -994,7 +1052,7 @@
      {
      SWIG_PRV_DATA* t = (SWIG_PRV_DATA*)JSObjectGetPrivate(thisObject);
      if(t && t->swigCMemOwn) free ((${type}*)t->swigCObject);
-     if(t) free(t);
+     free(t);
      }
      %}
 
@@ -1007,7 +1065,7 @@
      ${type}* arg1 = (${type}*)t->swigCObject;
      ${destructor_action}
      }
-     if(t) free(t);
+     free(t);
 
      Based on what I saw in the Lua and Ruby modules, I use Getattr(n, "wrap:action")
      to decide if the user has a preferred destructor action.
@@ -1031,7 +1089,7 @@
     state.clazz(DTOR, wrap_name);
     t_dtor.replace("${classname_mangled}", state.clazz(NAME_MANGLED))
 	.replace("$jswrapper", wrap_name)
-	.replace("$jsfree", free)
+	.replace("$jsfree", jsfree)
 	.replace("$jstype", ctype);
 
     t_dtor.replace("${destructor_action}", destructor_action);
@@ -1041,21 +1099,21 @@
     state.clazz(DTOR, wrap_name);
     t_dtor.replace("$jsmangledname", state.clazz(NAME_MANGLED))
 	.replace("$jswrapper", wrap_name)
-	.replace("$jsfree", free)
+	.replace("$jsfree", jsfree)
 	.replace("$jstype", ctype)
 	.pretty_print(f_wrappers);
   }
 
   Delete(p_classtype);
   Delete(ctype);
-  Delete(free);
+  Delete(jsfree);
 
   return SWIG_OK;
 }
 
 int JSEmitter::emitGetter(Node *n, bool is_member, bool is_static) {
   Wrapper *wrapper = NewWrapper();
-  Template t_getter(getTemplate("js_getter"));
+  Template t_getter(getTemplate(getGetterTemplate(is_member)));
 
   // prepare wrapper name
   String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name"));
@@ -1074,7 +1132,8 @@
 
   emitCleanupCode(n, wrapper, params);
 
-  t_getter.replace("$jswrapper", wrap_name)
+  t_getter.replace("$jsmangledname", state.clazz(NAME_MANGLED))
+      .replace("$jswrapper", wrap_name)
       .replace("$jslocals", wrapper->locals)
       .replace("$jscode", wrapper->code)
       .pretty_print(f_wrappers);
@@ -1093,7 +1152,7 @@
 
   Wrapper *wrapper = NewWrapper();
 
-  Template t_setter(getTemplate("js_setter"));
+  Template t_setter(getTemplate(getSetterTemplate(is_member)));
 
   // prepare wrapper name
   String *wrap_name = Swig_name_wrapper(Getattr(n, "sym:name"));
@@ -1112,7 +1171,8 @@
 
   emitCleanupCode(n, wrapper, params);
 
-  t_setter.replace("$jswrapper", wrap_name)
+  t_setter.replace("$jsmangledname", state.clazz(NAME_MANGLED))
+      .replace("$jswrapper", wrap_name)
       .replace("$jslocals", wrapper->locals)
       .replace("$jscode", wrapper->code)
       .pretty_print(f_wrappers);
@@ -1137,18 +1197,18 @@
 
   Wrapper *wrapper = NewWrapper();
   SwigType *type = Getattr(n, "type");
-  String *name = Getattr(n, "name");
   String *iname = Getattr(n, "sym:name");
-  String *wname = Swig_name_wrapper(name);
+  String *wname = Swig_name_get(Getattr(current_namespace, NAME_MANGLED), iname);
   String *rawval = Getattr(n, "rawval");
   String *value = rawval ? rawval : Getattr(n, "value");
 
-  // HACK: forcing usage of cppvalue for v8 (which turned out to fix typdef_struct.i, et. al)
+  // HACK: forcing usage of cppvalue for v8 (which turned out to fix typedef_struct.i, et. al)
   if (State::IsSet(state.globals(FORCE_CPP)) && Getattr(n, "cppvalue") != NULL) {
     value = Getattr(n, "cppvalue");
   }
 
-  Template t_getter(getTemplate("js_getter"));
+  bool is_member = GetFlag(n, "ismember");
+  Template t_getter(getTemplate(getGetterTemplate(is_member)));
 
   // call the variable methods as a constants are
   // registered in same way
@@ -1171,13 +1231,19 @@
 
   marshalOutput(n, 0, wrapper, NewString(""), value, false);
 
-  t_getter.replace("$jswrapper", wname)
+  t_getter.replace("$jsmangledname", state.clazz(NAME_MANGLED))
+      .replace("$jswrapper", wname)
       .replace("$jslocals", wrapper->locals)
       .replace("$jscode", wrapper->code)
       .pretty_print(f_wrappers);
 
   exitVariable(n);
 
+  // This is the counterpart to the "constant" test in
+  // exitVariable, it prevents double setting of
+  // symbols that are both constants and variables
+  SetFlag(n, "constant");
+
   DelWrapper(wrapper);
 
   return SWIG_OK;
@@ -1185,7 +1251,7 @@
 
 int JSEmitter::emitFunction(Node *n, bool is_member, bool is_static) {
   Wrapper *wrapper = NewWrapper();
-  Template t_function(getTemplate("js_function"));
+  Template t_function(getTemplate(getFunctionTemplate(is_member)));
 
   bool is_overloaded = GetFlag(n, "sym:overloaded") != 0;
 
@@ -1193,7 +1259,7 @@
   String *iname = Getattr(n, "sym:name");
   String *wrap_name = Swig_name_wrapper(iname);
   if (is_overloaded) {
-    t_function = getTemplate("js_overloaded_function");
+    t_function = getTemplate(getOverloadedFunctionTemplate(is_member));
     Append(wrap_name, Getattr(n, "sym:overname"));
   }
   Setattr(n, "wrap:name", wrap_name);
@@ -1204,30 +1270,26 @@
   emit_parameter_variables(params, wrapper);
   emit_attach_parmmaps(params, wrapper);
 
-  // HACK: in test-case `ignore_parameter` emit_attach_parmmaps generates an extra line of applied typemap.
-  // Deleting wrapper->code here fixes the problem, and seems to have no side effect elsewhere
-  Delete(wrapper->code);
-  wrapper->code = NewString("");
-
   marshalInputArgs(n, params, wrapper, Function, is_member, is_static);
   String *action = emit_action(n);
   marshalOutput(n, params, wrapper, action);
   emitCleanupCode(n, wrapper, params);
   Replaceall(wrapper->code, "$symname", iname);
 
-  t_function.replace("$jswrapper", wrap_name)
+  t_function.replace("$jsmangledname", state.clazz(NAME_MANGLED))
+      .replace("$jswrapper", wrap_name)
       .replace("$jslocals", wrapper->locals)
       .replace("$jscode", wrapper->code)
       .replace("$jsargcount", Getattr(n, ARGCOUNT))
+      .replace("$jsargrequired", Getattr(n, ARGREQUIRED))
       .pretty_print(f_wrappers);
 
-
   DelWrapper(wrapper);
 
   return SWIG_OK;
 }
 
-int JSEmitter::emitFunctionDispatcher(Node *n, bool /*is_member */ ) {
+int JSEmitter::emitFunctionDispatcher(Node *n, bool is_member) {
   Wrapper *wrapper = NewWrapper();
 
   // Generate call list, go to first node
@@ -1243,19 +1305,20 @@
       // handle function overloading
       Template t_dispatch_case = getTemplate("js_function_dispatch_case");
       t_dispatch_case.replace("$jswrapper", siblname)
-	  .replace("$jsargcount", Getattr(sibl, ARGCOUNT));
+	  .replace("$jsargcount", Getattr(sibl, ARGCOUNT))
+	  .replace("$jsargrequired", Getattr(sibl, ARGREQUIRED));
 
       Append(wrapper->code, t_dispatch_case.str());
     }
 
   } while ((sibl = Getattr(sibl, "sym:nextSibling")));
 
-  Template t_function(getTemplate("js_function_dispatcher"));
+  Template t_function(getTemplate(getFunctionDispatcherTemplate(is_member)));
 
   // Note: this dispatcher function gets called after the last overloaded function has been created.
   // At this time, n.wrap:name contains the name of the last wrapper function.
   // To get a valid function name for the dispatcher function we take the last wrapper name and
-  // substract the extension "sym:overname",
+  // subtract the extension "sym:overname",
   String *wrap_name = NewString(Getattr(n, "wrap:name"));
   String *overname = Getattr(n, "sym:overname");
 
@@ -1268,7 +1331,7 @@
 
   String *new_string = NewStringf("%s_%s", class_name, wrap_name);
   String *final_wrap_name = Swig_name_wrapper(new_string);
-     
+
   Setattr(n, "wrap:name", final_wrap_name);
   state.function(WRAPPER_NAME, final_wrap_name);
 
@@ -1279,6 +1342,7 @@
 
   // call this here, to replace all variables
   t_function.replace("$jswrapper", final_wrap_name)
+      .replace("$jsmangledname", state.clazz(NAME_MANGLED))
       .replace("$jsname", state.function(NAME))
       .pretty_print(f_wrappers);
 
@@ -1289,9 +1353,39 @@
 }
 
 String *JSEmitter::emitInputTypemap(Node *n, Parm *p, Wrapper *wrapper, String *arg) {
+  String *code = NewString("");
   // Get input typemap for current param
   String *tm = Getattr(p, "tmap:in");
+  String *tm_def = Getattr(p, "tmap:default");
   SwigType *type = Getattr(p, "type");
+  int argmin = -1;
+  int argidx = -1;
+  bool is_optional = false;
+
+  if (Getattr(n, ARGREQUIRED)) {
+    argmin = GetInt(n, ARGREQUIRED);
+  }
+  if (Getattr(p, INDEX)) {
+    argidx = GetInt(p, INDEX);
+  }
+
+  if (tm_def != NULL) {
+    is_optional = true;
+  }
+  if (argmin >= 0 && argidx >= 0 && argidx >= argmin) {
+    is_optional = true;
+  }
+  if (is_optional && Getattr(p, INDEX) == NULL) {
+    Printf(stderr, "Argument %s in %s cannot be a default argument\n", Getattr(p, NAME), state.function(NAME));
+    return SWIG_ERROR;
+  }
+
+  if (is_optional) {
+    Template t_check_default(getTemplate("js_check_arg"));
+
+    t_check_default.replace("$jsarg", Getattr(p, INDEX)).pretty_print(code);
+    Printf(code, "{\n");
+  }
 
   if (tm != NULL) {
     Replaceall(tm, "$input", arg);
@@ -1303,9 +1397,37 @@
       Replaceall(tm, "$disown", "0");
     }
     Replaceall(tm, "$symname", Getattr(n, "sym:name"));
-    Printf(wrapper->code, "%s\n", tm);
+    if (!checkAttribute(p, "tmap:in:noblock", "1")) {
+      Printf(code, "{\n");
+    }
+    Printf(code, "%s", tm);
+    if (!checkAttribute(p, "tmap:in:noblock", "1")) {
+      Printf(code, "\n}\n");
+    }
   } else {
     Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(type, 0));
+    return NULL;
+  }
+
+  if (is_optional) {
+    Printf(code, "}\n");
+  }
+
+  // numinputs=0 typemaps are emitted by the legacy code in
+  // emit_attach_parmmaps() in emit.cxx, check the comment there
+  // All generators work around this
+  if (!checkAttribute(p, "tmap:in:numinputs", "0")) {
+    Append(wrapper->code, code);
+  }
+  return code;
+}
+
+String *JSEmitter::emitCheckTypemap(Node *, Parm *p, Wrapper *wrapper, String *arg) {
+  String *tm = Getattr(p, "tmap:check");
+
+  if (tm != NULL) {
+    Replaceall(tm, "$input", arg);
+    Printf(wrapper->code, "%s\n", tm);
   }
 
   return tm;
@@ -1394,13 +1516,11 @@
   if (GetFlag(n, "ismember")) {
     return SWIG_OK;
   }
-
   // if nspace is deactivated, everything goes into the global scope
   if (!GetFlag(n, "feature:nspace")) {
     current_namespace = Getattr(namespaces, "::");
     return SWIG_OK;
   }
-
 // EXPERIMENTAL: we want to use Language::getNSpace() here
 // However, it is not working yet.
 // For namespace functions Language::getNSpace() does not give a valid result
@@ -1409,7 +1529,6 @@
   String *_nspace = lang->getNSpace();
   if (!Equal(nspace, _nspace)) {
     Printf(stdout, "##### Custom vs Language::getNSpace(): %s | %s\n", nspace, _nspace);
-    Swig_print_node(n);
   }
 #endif
 
@@ -1420,7 +1539,6 @@
     // We try to get the namespace from the qualified name (i.e., everything before the last '::')
     nspace = Swig_scopename_prefix(Getattr(n, "name"));
   }
-
   // If there is not even a scopename prefix then it must be global scope
   if (nspace == NULL) {
     current_namespace = Getattr(namespaces, "::");
@@ -1466,7 +1584,7 @@
   Hash *entry = NewHash();
   String *name = NewString(_name);
   Setattr(entry, NAME, Swig_scopename_last(name));
-  Setattr(entry, NAME_MANGLED, Swig_name_mangle(name));
+  Setattr(entry, NAME_MANGLED, Swig_name_mangle_string(name));
   Setattr(entry, PARENT, NewString(parent));
   Setattr(entry, PARENT_MANGLED, NewString(parent_mangled));
 
@@ -1531,7 +1649,7 @@
 
 void JSCEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) {
   Parm *p;
-  String *tm;
+  String *tm = NULL;
 
   // determine an offset index, as members have an extra 'this' argument
   // except: static members and ctors.
@@ -1544,10 +1662,12 @@
   String *argcount = NewString("");
   Printf(argcount, "%d", num_args);
   Setattr(n, ARGCOUNT, argcount);
+  int num_required = emit_num_required(parms) - startIdx;
+  SetInt(n, ARGREQUIRED, num_required);
 
   // process arguments
   int i = 0;
-  for (p = parms; p; i++) {
+  for (p = parms; p;) {
     String *arg = NewString("");
     String *type = Getattr(p, "type");
 
@@ -1560,32 +1680,50 @@
     case Function:
       if (is_member && !is_static && i == 0) {
 	Printv(arg, "thisObject", 0);
+	i++;
       } else {
 	Printf(arg, "argv[%d]", i - startIdx);
+	SetInt(p, INDEX, i - startIdx);
+	i += GetInt(p, "tmap:in:numinputs");
       }
       break;
     case Setter:
       if (is_member && !is_static && i == 0) {
 	Printv(arg, "thisObject", 0);
+	i++;
       } else {
 	Printv(arg, "value", 0);
+	i++;
       }
       break;
     case Ctor:
       Printf(arg, "argv[%d]", i);
+      SetInt(p, INDEX, i);
+      i += GetInt(p, "tmap:in:numinputs");
       break;
     default:
-      Printf(stdout, "Illegal state.");
-      SWIG_exit(EXIT_FAILURE);
+      Printf(stderr, "Illegal MarshallingMode.");
+      Exit(EXIT_FAILURE);
     }
+
     tm = emitInputTypemap(n, p, wrapper, arg);
     Delete(arg);
+
     if (tm) {
       p = Getattr(p, "tmap:in:next");
     } else {
       p = nextSibling(p);
     }
   }
+
+  for (p = parms; p;) {
+    tm = emitCheckTypemap(n, p, wrapper, Getattr(p, "emit:input"));
+    if (tm) {
+      p = Getattr(p, "tmap:check:next");
+    } else {
+      p = nextSibling(p);
+    }
+  }
 }
 
 int JSCEmitter::initialize(Node *n) {
@@ -1599,7 +1737,7 @@
   f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files());
   if (!f_wrap_cpp) {
     FileErrorDisplay(outfile);
-    SWIG_exit(EXIT_FAILURE);
+    Exit(EXIT_FAILURE);
   }
 
   /* Initialization of members */
@@ -1620,6 +1758,8 @@
 
   Swig_banner(f_wrap_cpp);
 
+  Swig_obligatory_macros(f_runtime, "JAVASCRIPT");
+
   return SWIG_OK;
 }
 
@@ -1920,7 +2060,7 @@
   f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files());
   if (!f_wrap_cpp) {
     FileErrorDisplay(outfile);
-    SWIG_exit(EXIT_FAILURE);
+    Exit(EXIT_FAILURE);
   }
 
   f_runtime = NewString("");
@@ -1950,6 +2090,8 @@
 
   Swig_banner(f_wrap_cpp);
 
+  Swig_obligatory_macros(f_runtime, "JAVASCRIPT");
+
   return SWIG_OK;
 }
 
@@ -2166,7 +2308,7 @@
 
 void V8Emitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) {
   Parm *p;
-  String *tm;
+  String *tm = NULL;
 
   int startIdx = 0;
   if (is_member && !is_static && mode != Ctor) {
@@ -2177,9 +2319,11 @@
   String *argcount = NewString("");
   Printf(argcount, "%d", num_args);
   Setattr(n, ARGCOUNT, argcount);
+  int num_required = emit_num_required(parms) - startIdx;
+  SetInt(n, ARGREQUIRED, num_required);
 
   int i = 0;
-  for (p = parms; p; i++) {
+  for (p = parms; p;) {
     String *arg = NewString("");
     String *type = Getattr(p, "type");
 
@@ -2191,30 +2335,40 @@
     case Getter:
       if (is_member && !is_static && i == 0) {
 	Printv(arg, "info.Holder()", 0);
+	i++;
       } else {
 	Printf(arg, "args[%d]", i - startIdx);
+	SetInt(p, INDEX, i - startIdx);
+	i += GetInt(p, "tmap:in:numinputs");
       }
       break;
     case Function:
       if (is_member && !is_static && i == 0) {
 	Printv(arg, "args.Holder()", 0);
+	i++;
       } else {
 	Printf(arg, "args[%d]", i - startIdx);
+	SetInt(p, INDEX, i - startIdx);
+	i += GetInt(p, "tmap:in:numinputs");
       }
       break;
     case Setter:
       if (is_member && !is_static && i == 0) {
 	Printv(arg, "info.Holder()", 0);
+	i++;
       } else {
 	Printv(arg, "value", 0);
+	i++;
       }
       break;
     case Ctor:
       Printf(arg, "args[%d]", i);
+      SetInt(p, INDEX, i);
+      i += GetInt(p, "tmap:in:numinputs");
       break;
     default:
-      Printf(stdout, "Illegal state.");
-      SWIG_exit(EXIT_FAILURE);
+      Printf(stderr, "Illegal MarshallingMode.");
+      Exit(EXIT_FAILURE);
     }
 
     tm = emitInputTypemap(n, p, wrapper, arg);
@@ -2226,6 +2380,15 @@
       p = nextSibling(p);
     }
   }
+
+  for (p = parms; p;) {
+    tm = emitCheckTypemap(n, p, wrapper, Getattr(p, "emit:input"));
+    if (tm) {
+      p = Getattr(p, "tmap:check:next");
+    } else {
+      p = nextSibling(p);
+    }
+  }
 }
 
 int V8Emitter::emitNamespaces() {
@@ -2275,10 +2438,604 @@
   return SWIG_OK;
 }
 
+/**********************************************************************
+ * NAPI: JSEmitter implementation for N-API
+ **********************************************************************/
+
+class NAPIEmitter:public JSEmitter {
+public:
+  NAPIEmitter();
+
+  virtual ~NAPIEmitter();
+  virtual int initialize(Node *n);
+  virtual int dump(Node *n);
+  virtual int close();
+  virtual int enterClass(Node *n);
+  virtual int exitClass(Node *n);
+  virtual int enterVariable(Node *n);
+  virtual int exitVariable(Node *n);
+  virtual int exitFunction(Node *n);
+
+protected:
+  virtual void marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static);
+  virtual int emitNamespaces();
+  virtual int emitCtor(Node *);
+  virtual int emitDtor(Node *);
+  virtual int emitClassMethodDeclaration(Node *);
+
+  virtual const char *getFunctionTemplate(bool is_member);
+  virtual const char *getFunctionDispatcherTemplate(bool is_member);
+  virtual const char *getOverloadedFunctionTemplate(bool is_member);
+  virtual const char *getSetterTemplate(bool is_member);
+  virtual const char *getGetterTemplate(bool is_member);
+
+protected:
+  /* built-in parts */
+  String *f_runtime;
+  String *f_header;
+  String *f_init;
+  String *f_post_init;
+
+  /* class declarations */
+  String *f_class_declarations;
+
+  /* parts for initilizer */
+  String *f_init_namespaces;
+  String *f_init_wrappers;
+  String *f_init_inheritance;
+  String *f_init_static_wrappers;
+  String *f_init_register_classes;
+  String *f_init_register_namespaces;
+
+  // the output cpp file
+  File *f_wrap_cpp;
+
+  String *NULL_STR;
+  String *VETO_SET;
+  String *moduleName;
+
+  // the current index in the class table
+  size_t class_idx;
+};
+
+NAPIEmitter::NAPIEmitter()
+:  JSEmitter(JSEmitter::NAPI), NULL_STR(NewString("0")), VETO_SET(NewString("JS_veto_set_variable")), class_idx(0) {
+}
+
+NAPIEmitter::~NAPIEmitter() {
+  Delete(NULL_STR);
+  Delete(VETO_SET);
+}
+
+int NAPIEmitter::initialize(Node *n) {
+  JSEmitter::initialize(n);
+
+  moduleName = Getattr(n, "name");
+
+  // Get the output file name
+  String *outfile = Getattr(n, "outfile");
+  f_wrap_cpp = NewFile(outfile, "w", SWIG_output_files());
+  if (!f_wrap_cpp) {
+    FileErrorDisplay(outfile);
+    Exit(EXIT_FAILURE);
+  }
+
+  f_runtime = NewString("");
+  f_header = NewString("");
+  f_init = NewString("");
+  f_post_init = NewString("");
+
+  f_class_declarations = NewString("");
+
+  f_init_namespaces = NewString("");
+  f_init_wrappers = NewString("");
+  f_init_inheritance = NewString("");
+  f_init_static_wrappers = NewString("");
+  f_init_register_classes = NewString("");
+  f_init_register_namespaces = NewString("");
+
+  // note: this is necessary for built-in generation of SWIG runtime code
+  Swig_register_filebyname("begin", f_wrap_cpp);
+  Swig_register_filebyname("runtime", f_runtime);
+  Swig_register_filebyname("header", f_header);
+  Swig_register_filebyname("wrapper", f_wrappers);
+  Swig_register_filebyname("init", f_init);
+  Swig_register_filebyname("post-init", f_post_init);
+
+  state.globals(FORCE_CPP, NewString("1"));
+
+  Swig_banner(f_wrap_cpp);
+
+  Swig_obligatory_macros(f_runtime, "JAVASCRIPT");
+
+  return SWIG_OK;
+}
+
+int NAPIEmitter::dump(Node *n) {
+  /* Get the module name */
+  String *module = Getattr(n, "name");
+
+  Template initializer_define(getTemplate("js_initializer_define"));
+  initializer_define.replace("$jsname", module).pretty_print(f_header);
+
+  SwigType_emit_type_table(f_runtime, f_wrappers);
+
+  Printv(f_wrap_cpp, f_runtime, "\n", 0);
+  Printv(f_wrap_cpp, f_header, "\n", 0);
+  Printv(f_wrap_cpp, f_class_declarations, "\n", 0);
+  Printv(f_wrap_cpp, f_wrappers, "\n", 0);
+
+  emitNamespaces();
+
+  String *inheritance = NewStringEmpty();
+  if (Len(f_init_inheritance) > 0) {
+    Template t_inheritance(getTemplate("js_init_inheritance"));
+    t_inheritance.pretty_print(inheritance);
+  }
+
+  // compose the initializer function using a template
+  // filled with sub-parts
+  Template initializer(getTemplate("js_initializer"));
+  initializer.replace("$jsname", moduleName)
+      .replace("$jsnapinspaces", f_init_namespaces)
+      .replace("$jsnapipreinheritance", inheritance)
+      .replace("$jsnapiinitinheritance", f_init_inheritance)
+      .replace("$jsnapiregisterclasses", f_init_register_classes)
+      .replace("$jsnapiregisternspaces", f_init_register_namespaces);
+  Printv(f_init, initializer.str(), 0);
+
+  Printv(f_wrap_cpp, f_init, 0);
+
+  Printv(f_wrap_cpp, f_post_init, 0);
+
+  Delete(inheritance);
+  return SWIG_OK;
+}
+
+int NAPIEmitter::close() {
+  Delete(f_runtime);
+  Delete(f_header);
+  Delete(f_class_declarations);
+  Delete(f_init_namespaces);
+  Delete(f_init_wrappers);
+  Delete(f_init_inheritance);
+  Delete(f_init_static_wrappers);
+  Delete(f_init_register_classes);
+  Delete(f_init_register_namespaces);
+  Delete(f_init);
+  Delete(f_post_init);
+  Delete(f_wrap_cpp);
+  return SWIG_OK;
+}
+
+const char *NAPIEmitter::getFunctionTemplate(bool is_member) {
+  return is_member ? "js_function" : "js_global_function";
+}
+
+const char *NAPIEmitter::getFunctionDispatcherTemplate(bool is_member) {
+  return is_member ? "js_function_dispatcher" : "js_global_function_dispatcher";
+}
+
+const char *NAPIEmitter::getOverloadedFunctionTemplate(bool is_member) {
+  return is_member ? "js_overloaded_function" : "js_global_overloaded_function";
+}
+
+const char *NAPIEmitter::getGetterTemplate(bool is_member) {
+  return is_member ? "js_getter" : "js_global_getter";
+}
+
+const char *NAPIEmitter::getSetterTemplate(bool is_member) {
+  return is_member ? "js_setter" : "js_global_setter";
+}
+
+int NAPIEmitter::enterClass(Node *n) {
+  JSEmitter::enterClass(n);
+
+  //  emit registration of class template
+  String *idx = NewString("");
+  Printf(idx, "%d", class_idx++);
+  Template t_register = getTemplate("jsnapi_registerclass");
+  t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED))
+      .replace("$jsname", state.clazz(NAME))
+      .replace("$jsparent", Getattr(state.clazz("nspace"), NAME_MANGLED))
+      .replace("$jsmangledtype", state.clazz(TYPE_MANGLED))
+      .replace("$jsclassidx", idx)
+      .trim()
+      .pretty_print(f_init_register_classes);
+  Delete(idx);
+
+  // emit inheritance
+  String *baseMangled;
+  Node *baseClass = getBaseClass(n);
+  SetFlag(n, IS_WRAPPED);
+  if (baseClass && GetFlag(baseClass, IS_WRAPPED)) {
+    String *jsName = NewString("");
+    String *nspace = Getattr(baseClass, "sym:nspace");
+    if (Len(nspace) == 0)
+      nspace = Getattr(current_namespace, NAME_MANGLED);
+    Printf(jsName, "%s_%s", nspace, Getattr(baseClass, "sym:name"));
+    baseMangled = SwigType_manglestr(jsName);
+    Delete(jsName);
+
+    f_init_wrappers = Copy(Getattr(baseClass, MEMBER_FUNCTIONS));
+    f_init_static_wrappers = Copy(Getattr(baseClass, STATIC_FUNCTIONS));
+  } else {
+    baseMangled = NewString("SWIG_NAPI_ObjectWrap");
+    f_init_wrappers = NewString("");
+    f_init_static_wrappers = NewString("");
+  }
+  state.clazz(PARENT_MANGLED, baseMangled);
+
+  Template t_setup_inheritance(getTemplate("jsnapi_setup_inheritance"));
+  t_setup_inheritance.replace("$jsmangledname", state.clazz(NAME_MANGLED))
+      .replace("$jswrapper", state.clazz(CTOR))
+      .replace("$jsname", state.clazz(NAME))
+      .replace("$jsparent", baseMangled)
+      .pretty_print(f_init_inheritance);
+
+  // emit declaration of a NAPI class template
+  Template t_decl_class(getTemplate("jsnapi_class_prologue_template"));
+  t_decl_class.replace("$jsmangledname", state.clazz(NAME_MANGLED))
+      .replace("$jsparent", baseMangled)
+      .trim()
+      .pretty_print(f_class_declarations);
+
+  Delete(baseMangled);
+  return SWIG_OK;
+}
+
+int NAPIEmitter::exitClass(Node *n) {
+  if (GetFlag(state.clazz(), IS_ABSTRACT)) {
+    Template t_veto_ctor(getTemplate("js_veto_ctor"));
+    t_veto_ctor.replace("$jsmangledname", state.clazz(NAME_MANGLED))
+	.replace("$jswrapper", state.clazz(CTOR))
+	.replace("$jsname", state.clazz(NAME))
+	.replace("$jsparent", state.clazz(PARENT_MANGLED))
+	.pretty_print(f_wrappers);
+  }
+
+  /* Note: this makes sure that there is a swig_type added for this class */
+  String *clientData = NewString("");
+  Printf(clientData, "&%s_clientData", state.clazz(NAME_MANGLED));
+
+  /* Note: this makes sure that there is a swig_type added for this class */
+  SwigType_remember_clientdata(state.clazz(TYPE_MANGLED), NewString("0"));
+
+  // emit definition of NAPI class template
+  Template t_def_class = getTemplate("jsnapi_class_epilogue_template");
+  t_def_class.replace("$jsmangledname", state.clazz(NAME_MANGLED))
+      .replace("$jsname", state.clazz(NAME))
+      .replace("$jsmangledtype", state.clazz(TYPE_MANGLED))
+      .replace("$jsdtor", state.clazz(DTOR))
+      .trim()
+      .pretty_print(f_class_declarations);
+
+  Template t_class_instance = getTemplate("jsnapi_declare_class_instance");
+  t_class_instance.replace("$jsname", state.clazz(NAME))
+      .replace("$jsmangledname", state.clazz(NAME_MANGLED))
+      .replace("$jsmangledtype", state.clazz(TYPE_MANGLED))
+      .trim()
+      .pretty_print(f_class_declarations);
+
+  Template t_class_template = getTemplate("jsnapi_getclass");
+  t_class_template.replace("$jsname", state.clazz(NAME))
+      .replace("$jsmangledname", state.clazz(NAME_MANGLED))
+      .replace("$jsnapiwrappers", f_init_wrappers)
+      .replace("$jsnapistaticwrappers", f_init_static_wrappers)
+      .replace("$jsparent", state.clazz(PARENT_MANGLED))
+      .trim()
+      .pretty_print(f_class_declarations);
+
+  /* Save these to be reused in the child classes */
+  Setattr(n, MEMBER_FUNCTIONS, f_init_wrappers);
+  Setattr(n, STATIC_FUNCTIONS, f_init_static_wrappers);
+  return SWIG_OK;
+}
+
+int NAPIEmitter::enterVariable(Node *n) {
+  // Somehow, this is not always reset
+  // (some constructs like smart pointers reuse Nodes)
+  UnsetFlag(n, "constant");
+
+  JSEmitter::enterVariable(n);
+
+  state.variable(GETTER, VETO_SET);
+  state.variable(SETTER, VETO_SET);
+
+  return SWIG_OK;
+}
+
+int NAPIEmitter::exitVariable(Node *n) {
+  // Due to special handling of C++ "static const" member variables
+  // (refer to the comment in lang.cxx:Language::staticmembervariableHandler)
+  // a static const member variable may get transformed into a constant
+  // and be emitted by emitConstant which will result calling exitVariable twice
+  if (GetFlag(n, "constant")) {
+    return SWIG_OK;
+  }
+
+  if (GetFlag(n, "ismember")) {
+    String *modifier = NewStringEmpty();
+    if (GetFlag(state.variable(), IS_STATIC) || Equal(Getattr(n, "nodeType"), "enumitem")) {
+      Template t_register = getTemplate("jsnapi_register_static_variable");
+      t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED))
+	  .replace("$jsname", state.variable(NAME))
+	  .replace("$jsgetter", state.variable(GETTER))
+	  .replace("$jssetter", state.variable(SETTER) != VETO_SET ? state.variable(SETTER)
+		   : "JS_veto_set_static_variable")
+	  .trim()
+	  .pretty_print(f_init_static_wrappers);
+      Append(modifier, "static");
+    } else {
+      Template t_register = getTemplate("jsnapi_register_member_variable");
+      t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED))
+	  .replace("$jsname", state.variable(NAME))
+	  .replace("$jsgetter", state.variable(GETTER))
+	  .replace("$jssetter", state.variable(SETTER))
+	  .trim()
+	  .pretty_print(f_init_wrappers);
+    }
+
+    // emit declaration of a class member function
+    Template t_getter = getTemplate("jsnapi_class_method_declaration");
+    t_getter.replace("$jsmangledname", state.clazz(NAME_MANGLED))
+	.replace("$jsname", state.clazz(NAME))
+	.replace("$jsmangledtype", state.clazz(TYPE_MANGLED))
+	.replace("$jsdtor", state.clazz(DTOR))
+	.replace("$jswrapper", state.variable(GETTER))
+	.replace("$jsstatic", modifier)
+	.trim()
+	.pretty_print(f_class_declarations);
+    if (state.variable(SETTER) != VETO_SET) {
+      Template t_setter = getTemplate("jsnapi_class_setter_declaration");
+      t_setter.replace("$jsmangledname", state.clazz(NAME_MANGLED))
+	  .replace("$jsname", state.clazz(NAME))
+	  .replace("$jsmangledtype", state.clazz(TYPE_MANGLED))
+	  .replace("$jsdtor", state.clazz(DTOR))
+	  .replace("$jswrapper", state.variable(SETTER))
+	  .replace("$jsstatic", modifier)
+	  .trim()
+	  .pretty_print(f_class_declarations);
+    }
+    Delete(modifier);
+  } else {
+    Template t_register = getTemplate("jsnapi_register_global_variable");
+    t_register.replace("$jsparent", Getattr(current_namespace, NAME_MANGLED))
+	.replace("$jsname", state.variable(NAME))
+	.replace("$jsgetter", state.variable(GETTER))
+	.replace("$jssetter", state.variable(SETTER))
+	.trim()
+	.pretty_print(f_init_register_namespaces);
+  }
+
+  return SWIG_OK;
+}
+
+int NAPIEmitter::emitClassMethodDeclaration(Node *) {
+  // emit declaration of a class member function
+  Template t_def_class = getTemplate("jsnapi_class_method_declaration");
+  t_def_class.replace("$jsmangledname", state.clazz(NAME_MANGLED))
+      .replace("$jsname", state.clazz(NAME))
+      .replace("$jsmangledtype", state.clazz(TYPE_MANGLED))
+      .replace("$jsdtor", state.clazz(DTOR))
+      .replace("$jswrapper", state.function(WRAPPER_NAME))
+      .replace("$jsstatic", GetFlag(state.function(), IS_STATIC) ? "static" : "")
+      .trim()
+      .pretty_print(f_class_declarations);
+
+  return SWIG_OK;
+}
+
+int NAPIEmitter::exitFunction(Node *n) {
+  bool is_member = GetFlag(n, "ismember") != 0 || GetFlag(n, "feature:extend") != 0;
+
+  // create a dispatcher for overloaded functions
+  bool is_overloaded = GetFlag(n, "sym:overloaded") != 0;
+  if (is_overloaded) {
+    emitClassMethodDeclaration(n);
+    if (!Getattr(n, "sym:nextSibling")) {
+      emitFunctionDispatcher(n, is_member);
+    } else {
+      return SWIG_OK;
+    }
+  }
+  // register the function at the specific context
+  if (is_member) {
+    if (GetFlag(state.function(), IS_STATIC)) {
+      Template t_register = getTemplate("jsnapi_register_static_function");
+      t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED))
+	  .replace("$jsname", state.function(NAME))
+	  .replace("$jswrapper", state.function(WRAPPER_NAME))
+	  .trim()
+	  .pretty_print(f_init_static_wrappers);
+    } else {
+      Template t_register = getTemplate("jsnapi_register_member_function");
+      t_register.replace("$jsmangledname", state.clazz(NAME_MANGLED))
+	  .replace("$jsname", state.function(NAME))
+	  .replace("$jswrapper", state.function(WRAPPER_NAME))
+	  .trim()
+	  .pretty_print(f_init_wrappers);
+    }
+
+    emitClassMethodDeclaration(n);
+  } else {
+    // Note: a global function is treated like a static function
+    //       with the parent being a nspace object instead of class object
+    Template t_register = getTemplate("jsnapi_register_global_function");
+    t_register.replace("$jsparent", Getattr(current_namespace, NAME_MANGLED))
+	.replace("$jsname", state.function(NAME))
+	.replace("$jswrapper", state.function(WRAPPER_NAME))
+	.trim()
+	.pretty_print(f_init_register_namespaces);
+  }
+
+  return SWIG_OK;
+}
+
+void NAPIEmitter::marshalInputArgs(Node *n, ParmList *parms, Wrapper *wrapper, MarshallingMode mode, bool is_member, bool is_static) {
+  Parm *p;
+  String *tm;
+
+  int startIdx = 0;
+  if (is_member && !is_static && mode != Ctor) {
+    startIdx = 1;
+  }
+  // store number of arguments for argument checks
+  int num_args = emit_num_arguments(parms) - startIdx;
+  String *argcount = NewString("");
+  Printf(argcount, "%d", num_args);
+  Setattr(n, ARGCOUNT, argcount);
+  int num_required = emit_num_required(parms) - startIdx;
+  SetInt(n, ARGREQUIRED, num_required);
+
+  int i = 0;
+  for (p = parms; p;) {
+    String *arg = NewString("");
+    String *type = Getattr(p, "type");
+
+    // ignore varargs
+    if (SwigType_isvarargs(type))
+      break;
+
+    switch (mode) {
+    case Getter:
+      if (is_member && !is_static && i == 0) {
+	Printv(arg, "info.This()", 0);
+	i++;
+      } else {
+	Printf(arg, "info[%d]", i - startIdx);
+	SetInt(p, INDEX, i - startIdx);
+	i += GetInt(p, "tmap:in:numinputs");
+      }
+      break;
+    case Function:
+      if (is_member && !is_static && i == 0) {
+	Printv(arg, "info.This()", 0);
+	i++;
+      } else {
+	Printf(arg, "info[%d]", i - startIdx);
+	SetInt(p, INDEX, i - startIdx);
+	i += GetInt(p, "tmap:in:numinputs");
+      }
+      break;
+    case Setter:
+      if (is_member && !is_static && i == 0) {
+	Printv(arg, "info.This()", 0);
+	i++;
+      } else {
+	Printv(arg, "value", 0);
+	i++;
+      }
+      break;
+    case Ctor:
+      Printf(arg, "info[%d]", i);
+      SetInt(p, INDEX, i - startIdx);
+      i += GetInt(p, "tmap:in:numinputs");
+      break;
+    default:
+      Printf(stderr, "Illegal MarshallingMode.");
+      Exit(EXIT_FAILURE);
+    }
+
+    tm = emitInputTypemap(n, p, wrapper, arg);
+    Delete(arg);
+
+    if (tm) {
+      p = Getattr(p, "tmap:in:next");
+    } else {
+      p = nextSibling(p);
+    }
+  }
+
+  for (p = parms; p;) {
+    tm = emitCheckTypemap(n, p, wrapper, Getattr(p, "emit:input"));
+    if (tm) {
+      p = Getattr(p, "tmap:in:next");
+    } else {
+      p = nextSibling(p);
+    }
+  }
+}
+
+int NAPIEmitter::emitNamespaces() {
+  Iterator it;
+  for (it = First(namespaces); it.item; it = Next(it)) {
+    Hash *entry = it.item;
+    String *name = Getattr(entry, NAME);
+    String *name_mangled = Getattr(entry, NAME_MANGLED);
+    String *parent = Getattr(entry, PARENT);
+    String *parent_mangled = Getattr(entry, PARENT_MANGLED);
+
+    bool do_create = true;
+    bool do_register = true;
+
+    if (Equal(parent, "")) {
+      do_register = false;
+    }
+    // Note: 'exports' is by convention the name of the object where
+    // globals are stored into
+    if (Equal(name, "exports")) {
+      do_create = false;
+    }
+
+    if (do_create) {
+      // create namespace object and register it to the parent scope
+      Template t_create_ns = getTemplate("jsnapi_create_namespace");
+      t_create_ns.replace("$jsmangledname", name_mangled)
+	  .trim()
+	  .pretty_print(f_init_namespaces);
+    }
+
+    if (do_register) {
+      Template t_register_ns = getTemplate("jsnapi_register_namespace");
+      t_register_ns.replace("$jsmangledname", name_mangled)
+	  .replace("$jsname", name)
+	  .replace("$jsparent", parent_mangled)
+	  .trim();
+
+      // prepend in order to achieve reversed order of registration statements
+      String *tmp_register_stmt = NewString("");
+      t_register_ns.pretty_print(tmp_register_stmt);
+      Insert(f_init_register_namespaces, 0, tmp_register_stmt);
+      Delete(tmp_register_stmt);
+    }
+  }
+
+  return SWIG_OK;
+}
+
+int NAPIEmitter::emitCtor(Node *n) {
+  int r = JSEmitter::emitCtor(n);
+  if (r != SWIG_OK)
+    return r;
+
+  Template t_getter = getTemplate("jsnapi_class_method_declaration");
+  t_getter.replace("$jsmangledname", state.clazz(NAME_MANGLED))
+      .replace("$jswrapper", Getattr(n, "wrap:name"))
+      .replace("$jsmangledtype", state.clazz(TYPE_MANGLED))
+      .replace("$jsstatic", "")
+      .trim()
+      .pretty_print(f_class_declarations);
+  return SWIG_OK;
+}
+
+int NAPIEmitter::emitDtor(Node *n) {
+  // NAPI destructors must have a class declaration
+  Template t_getter = getTemplate("jsnapi_class_dtor_declaration");
+  t_getter.replace("$jsmangledname", state.clazz(NAME_MANGLED))
+      .trim()
+      .pretty_print(f_class_declarations);
+  return JSEmitter::emitDtor(n);
+}
+
 JSEmitter *swig_javascript_create_V8Emitter() {
   return new V8Emitter();
 }
 
+JSEmitter *swig_javascript_create_NAPIEmitter() {
+  return new NAPIEmitter();
+}
+
 /**********************************************************************
  * Helper implementations
  **********************************************************************/
@@ -2370,7 +3127,7 @@
 
   if (!code_) {
     Printf(stdout, "Template code was null. Illegal input for template.");
-    SWIG_exit(EXIT_FAILURE);
+    Exit(EXIT_FAILURE);
   }
   code = NewString(code_);
   templateName = NewString("");
@@ -2380,7 +3137,7 @@
 
   if (!code_) {
     Printf(stdout, "Template code was null. Illegal input for template.");
-    SWIG_exit(EXIT_FAILURE);
+    Exit(EXIT_FAILURE);
   }
 
   code = NewString(code_);
diff --git a/Source/Modules/lang.cxx b/Source/Modules/lang.cxx
index f7979b6..92f0ceb 100644
--- a/Source/Modules/lang.cxx
+++ b/Source/Modules/lang.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * lang.cxx
  *
@@ -16,13 +16,18 @@
 #include <ctype.h>
 
 /* default mode settings */
+static int directors_allowed = 0;
+static int director_language = 0;
 static int director_mode = 0;
 static int director_protected_mode = 1;
 static int all_protected_mode = 0;
 static int naturalvar_mode = 0;
 Language *Language::this_ = 0;
 
-/* Set director_protected_mode */
+int Swig_directors_enabled() {
+  return director_language && CPlusPlus && (directors_allowed || director_mode);
+}
+
 void Wrapper_director_mode_set(int flag) {
   director_mode = flag;
 }
@@ -74,9 +79,11 @@
 int SmartPointer = 0;
 static Hash *classhash;
 
-extern int GenerateDefault;
 extern int ForceExtern;
 extern int AddExtern;
+extern "C" {
+  extern int UseWrapperSuffix;
+}
 
 /* import modes */
 
@@ -219,104 +226,149 @@
 int Dispatcher::defaultHandler(Node *) {
   return SWIG_OK;
 }
+
 int Dispatcher::extendDirective(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::applyDirective(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::clearDirective(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::constantDirective(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::fragmentDirective(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::importDirective(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::includeDirective(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::insertDirective(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::moduleDirective(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::nativeDirective(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::pragmaDirective(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::typemapDirective(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::typemapitemDirective(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::typemapcopyDirective(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::typesDirective(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::cDeclaration(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::externDeclaration(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::enumDeclaration(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::enumvalueDeclaration(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::enumforwardDeclaration(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::classDeclaration(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::templateDeclaration(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::lambdaDeclaration(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::classforwardDeclaration(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::constructorDeclaration(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::destructorDeclaration(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::accessDeclaration(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::usingDeclaration(Node *n) {
   return defaultHandler(n);
 }
+
 int Dispatcher::namespaceDeclaration(Node *n) {
   return defaultHandler(n);
 }
 
+Dispatcher::AccessMode Dispatcher::accessModeFromString(String *access) {
+  Dispatcher::AccessMode mode = PUBLIC;
+  if (Cmp(access, "public") == 0) {
+    mode = PUBLIC;
+  } else if (Cmp(access, "private") == 0) {
+    mode = PRIVATE;
+  } else if (Cmp(access, "protected") == 0) {
+    mode = PROTECTED;
+  } else {
+    assert(0);
+  }
+  return mode;
+}
+
+
 /* Allocators */
 Language::Language():
 none_comparison(NewString("$arg != 0")),
 director_ctor_code(NewString("")),
 director_prot_ctor_code(0),
+director_multiple_inheritance(1),
+doxygenTranslator(NULL),
 symtabs(NewHash()),
 overloading(0),
 multiinput(0),
-cplus_runtime(0),
-directors(0) {
+cplus_runtime(0) {
   symbolAddScope(""); // create top level/global symbol table scope
   argc_template_string = NewString("argc");
   argv_template_string = NewString("argv[%d]");
@@ -324,17 +376,8 @@
   /* Default director constructor code, passed to Swig_ConstructorToFunction */
   Printv(director_ctor_code, "if ( $comparison ) { /* subclassed */\n", "  $director_new \n", "} else {\n", "  $nondirector_new \n", "}\n", NIL);
 
-  /*
-     Default director 'protected' constructor code, disabled by
-     default. Each language that needs it, has to define it.
-   */
-  director_prot_ctor_code = 0;
-  director_multiple_inheritance = 1;
-  director_language = 0;
   assert(!this_);
   this_ = this;
-
-  doxygenTranslator = NULL;
 }
 
 Language::~Language() {
@@ -418,7 +461,7 @@
  * Returns the alternative value type needed in C++ for class value
  * types. When swig is not sure about using a plain $ltype value,
  * since the class doesn't have a default constructor, or it can't be
- * assigned, you will get back 'SwigValueWrapper<type >'.
+ * assigned, you will get back 'SwigValueWrapper<(type)>'.
  *
  * ----------------------------------------------------------------------------- */
 
@@ -445,12 +488,7 @@
 
 void swig_pragma(char *lang, char *name, char *value) {
   if (strcmp(lang, "swig") == 0) {
-    if ((strcmp(name, "make_default") == 0) || ((strcmp(name, "makedefault") == 0))) {
-      GenerateDefault = 1;
-    } else if ((strcmp(name, "no_default") == 0) || ((strcmp(name, "nodefault") == 0))) {
-      Swig_warning(WARN_DEPRECATED_NODEFAULT, "SWIG", 1, "dangerous, use %%nodefaultctor, %%nodefaultdtor instead.\n");
-      GenerateDefault = 0;
-    } else if (strcmp(name, "attributefunction") == 0) {
+    if (strcmp(name, "attributefunction") == 0) {
       String *nvalue = NewString(value);
       char *s = strchr(Char(nvalue), ':');
       if (!s) {
@@ -722,23 +760,23 @@
   String *code = Getattr(n, "code");
   Parm *kwargs = Getattr(n, "kwargs");
   Node *items = firstChild(n);
-  static int namewarn = 0;
+  static int nameerror = 0;
 
 
   if (code && (Strstr(code, "$source") || (Strstr(code, "$target")))) {
-    Swig_warning(WARN_TYPEMAP_SOURCETARGET, Getfile(n), Getline(n), "Deprecated typemap feature ($source/$target).\n");
-    if (!namewarn) {
-      Swig_warning(WARN_TYPEMAP_SOURCETARGET, Getfile(n), Getline(n), "The use of $source and $target in a typemap declaration is deprecated.\n\
+    Swig_error(Getfile(n), Getline(n), "Obsolete typemap feature ($source/$target).\n");
+    if (!nameerror) {
+      Swig_error(Getfile(n), Getline(n), "The use of $source and $target in a typemap declaration is no longer supported.\n\
 For typemaps related to argument input (in,ignore,default,arginit,check), replace\n\
 $source by $input and $target by $1.   For typemaps related to return values (out,\n\
 argout,ret,except), replace $source by $1 and $target by $result.  See the file\n\
 Doc/Manual/Typemaps.html for complete details.\n");
-      namewarn = 1;
+      nameerror = 1;
     }
   }
 
   if (Strcmp(method, "except") == 0) {
-    Swig_warning(WARN_DEPRECATED_EXCEPT_TM, Getfile(n), Getline(n), "%%typemap(except) is deprecated. Use the %%exception directive.\n");
+    Swig_error(Getfile(n), Getline(n), "%%typemap(except) is no longer supported. Use the %%exception directive.\n");
   }
 
   if (Strcmp(method, "in") == 0) {
@@ -765,16 +803,7 @@
   }
 
   if (Strcmp(method, "ignore") == 0) {
-    Swig_warning(WARN_DEPRECATED_IGNORE_TM, Getfile(n), Getline(n), "%%typemap(ignore) has been replaced by %%typemap(in,numinputs=0).\n");
-
-    Clear(method);
-    Append(method, "in");
-    Hash *k = NewHash();
-    Setattr(k, "name", "numinputs");
-    Setattr(k, "value", "0");
-    set_nextSibling(k, kwargs);
-    Setattr(n, "kwargs", k);
-    kwargs = k;
+    Swig_error(Getfile(n), Getline(n), "%%typemap(ignore) is no longer supported. Use %%typemap(in,numinputs=0).\n");
   }
 
   /* Replace $descriptor() macros */
@@ -879,11 +908,11 @@
   /* discards nodes following the access control rules */
   if (cplus_mode != PUBLIC || !is_public(n)) {
     /* except for friends, they are not affected by access control */
-    int isfriend = Cmp(storage, "friend") == 0;
+    int isfriend = (Strstr(storage, "friend") != NULL);
     if (!isfriend) {
       /* Check what the director needs. If the method is pure virtual, it is always needed.
        * Also wrap non-virtual protected members if asked for (allprotected mode). */
-      if (!(directorsEnabled() && ((is_member_director(CurrentClass, n) && need_nonpublic_member(n)) || isNonVirtualProtectedAccess(n)))) {
+      if (!(Swig_directors_enabled() && ((is_member_director(CurrentClass, n) && need_nonpublic_member(n)) || isNonVirtualProtectedAccess(n)))) {
           return SWIG_NOWRAP;
       }
       // Prevent wrapping protected overloaded director methods more than once -
@@ -1029,17 +1058,6 @@
 	}
       }
     }
-    if (!SwigType_ismutable(ty)) {
-      SetFlag(n, "feature:immutable");
-    }
-    /* If an array and elements are const, then read-only */
-    if (SwigType_isarray(ty)) {
-      SwigType *tya = SwigType_array_type(ty);
-      if (SwigType_isconst(tya)) {
-	SetFlag(n, "feature:immutable");
-      }
-      Delete(tya);
-    }
     DohIncref(type);
     Setattr(n, "type", ty);
     variableHandler(n);
@@ -1058,7 +1076,7 @@
 
 int Language::functionHandler(Node *n) {
   String *storage = Getattr(n, "storage");
-  int isfriend = CurrentClass && Cmp(storage, "friend") == 0;
+  int isfriend = CurrentClass && Strstr(storage, "friend");
   int isstatic = CurrentClass && Swig_storage_isstatic(n) && !(SmartPointer && Getattr(n, "allocate:smartpointeraccess"));
   Parm *p = Getattr(n, "parms");
   if (GetFlag(n, "feature:del")) {
@@ -1084,7 +1102,7 @@
       // This is a member function, set a flag so the documentation type is correct
       SetFlag(n, "memberfunction");
       Node *explicit_n = 0;
-      if (directorsEnabled() && is_member_director(CurrentClass, n) && !extraDirectorProtectedCPPMethodsRequired()) {
+      if (Swig_directors_enabled() && is_member_director(CurrentClass, n) && !extraDirectorProtectedCPPMethodsRequired()) {
 	bool virtual_but_not_pure_virtual = (!(Cmp(storage, "virtual")) && (Cmp(Getattr(n, "value"), "0") != 0));
 	if (virtual_but_not_pure_virtual) {
 	  // Add additional wrapper which makes an explicit call to the virtual method (ie not a virtual call)
@@ -1148,7 +1166,20 @@
   String *extendname = Getattr(n, "extendname");
   String *call = Swig_cfunction_call(extendname ? extendname : name, parms);
   String *cres = Swig_cresult(type, Swig_cresult_name(), call);
-  Setattr(n, "wrap:action", cres);
+  String *friendusing = Getattr(n, "friendusing");
+  if (friendusing) {
+    // Add a using directive to avoid having to possibly fully qualify the call to the friend function.
+    // Unconventional for SWIG generation, but the alternative is to implement Argument Dependent Lookup
+    // as friend functions are quirky and not visible, except for ADL. An ADL implementation would be needed
+    // in order to work out when the friend function is visible or not, in order to determine whether to
+    // rely on ADL (with no qualification) or to fully qualify the call to the friend function made
+    // visible via a matching declaration at namespace scope.
+    String *action = NewStringf("%s\n%s", friendusing, cres);
+    Setattr(n, "wrap:action", action);
+    Delete(action);
+  } else {
+    Setattr(n, "wrap:action", cres);
+  }
   Delete(cres);
   Delete(call);
   functionWrapper(n);
@@ -1261,7 +1292,7 @@
   }
 
   int DirectorExtraCall = 0;
-  if (directorsEnabled() && is_member_director(CurrentClass, n) && !SmartPointer)
+  if (Swig_directors_enabled() && is_member_director(CurrentClass, n) && !SmartPointer)
     if (extraDirectorProtectedCPPMethodsRequired())
       DirectorExtraCall = CWRAP_DIRECTOR_TWO_CALLS;
 
@@ -1307,29 +1338,36 @@
     else
       cname = NewStringf("%s::%s", sname, name);
   } else {
-    String *mname = Swig_name_mangle(ClassName);
+    String *classname_str = SwigType_namestr(ClassName);
+    String *mname = Swig_name_mangle_string(classname_str);
     cname = Swig_name_member(NSpace, mname, name);
     Delete(mname);
+    Delete(classname_str);
   }
   mrename = Swig_name_member(NSpace, ClassPrefix, symname);
 
   if (Extend) {
     String *code = Getattr(n, "code");
     String *defaultargs = Getattr(n, "defaultargs");
-    String *mangled = Swig_name_mangle(mrename);
+    String *mangled = Swig_name_mangle_string(mrename);
     Delete(mrename);
     mrename = mangled;
 
-    if (Getattr(n, "sym:overloaded") && code) {
-      Append(cname, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
-    }
+    if (code) {
+      // See Swig_MethodToFunction() for the explanation of this code.
+      if (Getattr(n, "sym:overloaded")) {
+	Append(cname, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
+      } else if (UseWrapperSuffix) {
+	Append(cname, "__SWIG");
+      }
 
-    if (!defaultargs && code) {
-      /* Hmmm. An added static member.  We have to create a little wrapper for this */
-      String *mangled_cname = Swig_name_mangle(cname);
-      Swig_add_extension_code(n, mangled_cname, parms, type, code, CPlusPlus, 0);
-      Setattr(n, "extendname", mangled_cname);
-      Delete(mangled_cname);
+      if (!defaultargs) {
+	/* Hmmm. An added static member.  We have to create a little wrapper for this */
+	String *mangled_cname = Swig_name_mangle_string(cname);
+	Swig_add_extension_code(n, mangled_cname, parms, type, code, CPlusPlus, 0);
+	Setattr(n, "extendname", mangled_cname);
+	Delete(mangled_cname);
+      }
     }
   }
 
@@ -1428,7 +1466,7 @@
 
     /* Create a function to set the value of the variable */
 
-    int assignable = is_assignable(n);
+    int assignable = !is_immutable(n);
 
     if (SmartPointer) {
       if (!Getattr(CurrentClass, "allocate:smartpointermutable")) { 
@@ -1481,8 +1519,6 @@
 	} else {
 	  String *pname0 = Swig_cparm_name(0, 0);
 	  String *pname1 = Swig_cparm_name(0, 1);
-	  Replace(tm, "$source", pname1, DOH_REPLACE_ANY);
-	  Replace(tm, "$target", target, DOH_REPLACE_ANY);
 	  Replace(tm, "$input", pname1, DOH_REPLACE_ANY);
 	  Replace(tm, "$self", pname0, DOH_REPLACE_ANY);
 	  Setattr(n, "wrap:action", tm);
@@ -1793,6 +1829,8 @@
    */
   SwigType *name = Getattr(n, "name");
   SwigType *decl = Getattr(n, "decl");
+  Setfile(name, Getfile(n));
+  Setline(name, Getline(n));
   if (!SwigType_ispointer(decl) && !SwigType_isreference(decl)) {
     SwigType *pname = Copy(name);
     SwigType_add_pointer(pname);
@@ -1842,20 +1880,82 @@
   String *tmp = SwigType_pop_function(local_decl);
   Delete(local_decl);
   local_decl = tmp;
-  Node *method_id = NewStringf("%s|%s", name, local_decl);
+  String *method_id = NewStringf("%s|%s", name, local_decl);
   Delete(local_decl);
   return method_id;
 }
 
+/* ----------------------------------------------------------------------
+ * Language::unrollOneVirtualMethod()
+ * ---------------------------------------------------------------------- */
+
+void Language::unrollOneVirtualMethod(String *classname, Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase) {
+  if (!checkAttribute(n, "storage", "virtual"))
+    return;
+  if (GetFlag(n, "final"))
+    return;
+
+  String *nodeType = Getattr(n, "nodeType");
+
+  /* we need to add methods(cdecl) and destructor (to check for throw decl) */
+  int is_destructor = (Cmp(nodeType, "destructor") == 0);
+  if ((Cmp(nodeType, "cdecl") == 0) || is_destructor) {
+    String *decl = Getattr(n, "decl");
+    /* extra check for function type and proper access */
+    if (SwigType_isfunction(decl) && (((!protectedbase || dirprot_mode()) && is_public(n)) || need_nonpublic_member(n))) {
+      String *name = Getattr(n, "name");
+      String *method_id = is_destructor ? NewStringf("~destructor") : vtable_method_id(n);
+      /* Make sure that the new method overwrites the existing: */
+      int len = Len(vm);
+      const int DO_NOT_REPLACE = -1;
+      int replace = DO_NOT_REPLACE;
+      for (int i = 0; i < len; i++) {
+	Node *item = Getitem(vm, i);
+	String *check_vmid = Getattr(item, "vmid");
+
+	if (Strcmp(method_id, check_vmid) == 0) {
+	  replace = i;
+	  break;
+	}
+      }
+      /* filling a new method item */
+      String *fqdname = NewStringf("%s::%s", classname, name);
+      Hash *item = NewHash();
+      Setattr(item, "fqdname", fqdname);
+      Node *m = Copy(n);
+
+      /* Store the complete return type - needed for non-simple return types (pointers, references etc.) */
+      SwigType *ty = NewString(Getattr(m, "type"));
+      SwigType_push(ty, decl);
+      if (SwigType_isqualifier(ty)) {
+	Delete(SwigType_pop(ty));
+      }
+      Delete(SwigType_pop_function(ty));
+      Setattr(m, "returntype", ty);
+
+      String *mname = NewStringf("%s::%s", Getattr(parent, "name"), name);
+      /* apply the features of the original method found in the base class */
+      Swig_features_get(Swig_cparse_features(), 0, mname, Getattr(m, "decl"), m);
+      Setattr(item, "methodNode", m);
+      Setattr(item, "vmid", method_id);
+      if (replace == DO_NOT_REPLACE)
+	Append(vm, item);
+      else
+	Setitem(vm, replace, item);
+      Setattr(n, "directorNode", m);
+
+      Delete(mname);
+    }
+    if (is_destructor) {
+      virtual_destructor = 1;
+    }
+  }
+}
 
 /* ----------------------------------------------------------------------
  * Language::unrollVirtualMethods()
  * ---------------------------------------------------------------------- */
-int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_director, int &virtual_destructor, int protectedbase) {
-  Node *ni;
-  String *nodeType;
-  String *classname;
-  String *decl;
+int Language::unrollVirtualMethods(Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase) {
   bool first_base = false;
   // recurse through all base classes to build the vtable
   List *bl = Getattr(n, "bases");
@@ -1864,10 +1964,11 @@
     for (bi = First(bl); bi.item; bi = Next(bi)) {
       if (first_base && !director_multiple_inheritance)
 	break;
-      unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor);
+      unrollVirtualMethods(bi.item, parent, vm, virtual_destructor);
       first_base = true;
     }
   }
+
   // recurse through all protected base classes to build the vtable, as needed
   bl = Getattr(n, "protectedbases");
   if (bl) {
@@ -1875,88 +1976,28 @@
     for (bi = First(bl); bi.item; bi = Next(bi)) {
       if (first_base && !director_multiple_inheritance)
 	break;
-      unrollVirtualMethods(bi.item, parent, vm, default_director, virtual_destructor, 1);
+      unrollVirtualMethods(bi.item, parent, vm, virtual_destructor, 1);
       first_base = true;
     }
   }
+
   // find the methods that need directors
-  classname = Getattr(n, "name");
-  for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
+  String *classname = Getattr(n, "name");
+  for (Node *ni = firstChild(n); ni; ni = nextSibling(ni)) {
     /* we only need to check the virtual members */
-    nodeType = Getattr(ni, "nodeType");
-    int is_using = (Cmp(nodeType, "using") == 0);
-    Node *nn = is_using ? firstChild(ni) : ni; /* assume there is only one child node for "using" nodes */
-    if (is_using) {
-      if (nn)
-	nodeType = Getattr(nn, "nodeType");
-      else
-	continue; // A private "using" node
-    }
-    if (!checkAttribute(nn, "storage", "virtual"))
-      continue;
-    if (GetFlag(nn, "final"))
-      continue;
-    /* we need to add methods(cdecl) and destructor (to check for throw decl) */
-    int is_destructor = (Cmp(nodeType, "destructor") == 0);
-    if ((Cmp(nodeType, "cdecl") == 0) || is_destructor) {
-      decl = Getattr(nn, "decl");
-      /* extra check for function type and proper access */
-      if (SwigType_isfunction(decl) && (((!protectedbase || dirprot_mode()) && is_public(nn)) || need_nonpublic_member(nn))) {
-	String *name = Getattr(nn, "name");
-	Node *method_id = is_destructor ? NewStringf("~destructor") : vtable_method_id(nn);
-	/* Make sure that the new method overwrites the existing: */
-	int len = Len(vm);
-	const int DO_NOT_REPLACE = -1;
-	int replace = DO_NOT_REPLACE;
-	for (int i = 0; i < len; i++) {
-	  Node *item = Getitem(vm, i);
-	  String *check_vmid = Getattr(item, "vmid");
-
-	  if (Strcmp(method_id, check_vmid) == 0) {
-	    replace = i;
-	    break;
-	  }
-	}
-	/* filling a new method item */
-	String *fqdname = NewStringf("%s::%s", classname, name);
-	Hash *item = NewHash();
-	Setattr(item, "fqdname", fqdname);
-	Node *m = Copy(nn);
-
-	/* Store the complete return type - needed for non-simple return types (pointers, references etc.) */
-	SwigType *ty = NewString(Getattr(m, "type"));
-	SwigType_push(ty, decl);
-	if (SwigType_isqualifier(ty)) {
-	  Delete(SwigType_pop(ty));
-	}
-	Delete(SwigType_pop_function(ty));
-	Setattr(m, "returntype", ty);
-
-	String *mname = NewStringf("%s::%s", Getattr(parent, "name"), name);
-	/* apply the features of the original method found in the base class */
-	Swig_features_get(Swig_cparse_features(), 0, mname, Getattr(m, "decl"), m);
-	Setattr(item, "methodNode", m);
-	Setattr(item, "vmid", method_id);
-	if (replace == DO_NOT_REPLACE)
-	  Append(vm, item);
-	else
-	  Setitem(vm, replace, item);
-	Setattr(nn, "directorNode", m);
-
-	Delete(mname);
-      }
-      if (is_destructor) {
-	virtual_destructor = 1;
+    if (Equal(nodeType(ni), "using")) {
+      for (Node *nn = firstChild(ni); nn; nn = Getattr(nn, "sym:nextSibling")) {
+	unrollOneVirtualMethod(classname, nn, parent, vm, virtual_destructor, protectedbase);
       }
     }
+    unrollOneVirtualMethod(classname, ni, parent, vm, virtual_destructor, protectedbase);
   }
 
   /*
      We delete all the nodirector methods. This prevents the
      generation of 'empty' director classes.
 
-     But this has to be done outside the previous 'for'
-     and the recursive loop!.
+     Done once we've collated all the virtual methods into vm.
    */
   if (n == parent) {
     int len = Len(vm);
@@ -2035,7 +2076,6 @@
  * ---------------------------------------------------------------------- */
 
 int Language::classDirectorConstructors(Node *n) {
-  Node *ni;
   String *nodeType;
   Node *parent = Swig_methodclass(n);
   int default_ctor = Getattr(parent, "allocate:default_constructor") ? 1 : 0;
@@ -2043,31 +2083,42 @@
   int constructor = 0;
 
   /* emit constructors */
-  for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
+  List *constructors = NewList();
+  for (Node *ni = firstChild(n); ni; ni = nextSibling(ni)) {
     nodeType = Getattr(ni, "nodeType");
-    if (Cmp(nodeType, "constructor") == 0) {
-      if (GetFlag(ni, "feature:ignore"))
-        continue;
-
-      Parm *parms = Getattr(ni, "parms");
-      if (is_public(ni)) {
-	/* emit public constructor */
-	classDirectorConstructor(ni);
-	constructor = 1;
-	if (default_ctor)
-	  default_ctor = !ParmList_numrequired(parms);
-      } else {
-	/* emit protected constructor if needed */
-	if (need_nonpublic_ctor(ni)) {
-	  classDirectorConstructor(ni);
-	  constructor = 1;
-	  protected_ctor = 1;
-	  if (default_ctor)
-	    default_ctor = !ParmList_numrequired(parms);
-	}
+    if (Equal(nodeType, "constructor")) {
+      Append(constructors, ni);
+    } else if (Equal(nodeType, "using") && GetFlag(ni, "usingctor")) {
+      for (Node *ui = firstChild(ni); ui; ui = nextSibling(ui)) {
+	Append(constructors, ui);
       }
     }
   }
+  for (Iterator it = First(constructors); it.item; it = Next(it)) {
+    Node *ni = it.item;
+    if (GetFlag(ni, "feature:ignore"))
+      continue;
+
+    Parm *parms = Getattr(ni, "parms");
+    if (is_public(ni)) {
+      /* emit public constructor */
+      classDirectorConstructor(ni);
+      constructor = 1;
+      if (default_ctor)
+	default_ctor = !ParmList_numrequired(parms);
+    } else {
+      /* emit protected constructor if needed */
+      if (need_nonpublic_ctor(ni)) {
+	classDirectorConstructor(ni);
+	constructor = 1;
+	protected_ctor = 1;
+	if (default_ctor)
+	  default_ctor = !ParmList_numrequired(parms);
+      }
+    }
+  }
+  Delete(constructors);
+
   /* emit default constructor if needed */
   if (!constructor) {
     if (!default_ctor) {
@@ -2193,13 +2244,13 @@
   }
   List *vtable = NewList();
   int virtual_destructor = 0;
-  unrollVirtualMethods(n, n, vtable, 0, virtual_destructor);
+  unrollVirtualMethods(n, n, vtable, virtual_destructor);
 
   // Emit all the using base::member statements for non virtual members (allprotected mode)
   Node *ni;
   String *using_protected_members_code = NewString("");
   for (ni = Getattr(n, "firstChild"); ni; ni = nextSibling(ni)) {
-    Node *nodeType = Getattr(ni, "nodeType");
+    String *nodeType = nodeType(ni);
     if (Cmp(nodeType, "destructor") == 0 && GetFlag(ni, "final")) {
       String *classtype = Getattr(n, "classtype");
       SWIG_WARN_NODE_BEGIN(ni);
@@ -2210,13 +2261,18 @@
       Delete(using_protected_members_code);
       return SWIG_OK;
     }
-    bool cdeclaration = (Cmp(nodeType, "cdecl") == 0);
-    if (cdeclaration && !GetFlag(ni, "feature:ignore")) {
-      if (isNonVirtualProtectedAccess(ni)) {
-        Node *overloaded = Getattr(ni, "sym:overloaded");
+    Node *nn = ni;
+    bool cdeclaration = Equal(nodeType, "cdecl");
+    if (!cdeclaration && Equal(nodeType, "using")) {
+      nn = Getattr(ni, "firstChild");
+      cdeclaration = nn && Equal(nodeType(nn), "cdecl") ? true : false;
+    }
+    if (cdeclaration && !GetFlag(nn, "feature:ignore")) {
+      if (isNonVirtualProtectedAccess(nn)) {
+        Node *overloaded = Getattr(nn, "sym:overloaded");
         // emit the using base::member statement (but only once if the method is overloaded)
-        if (!overloaded || (overloaded && (overloaded == ni)))
-          Printf(using_protected_members_code, "    using %s::%s;\n", SwigType_namestr(ClassName), Getattr(ni, "name"));
+        if (!overloaded || (overloaded && (overloaded == nn)))
+          Printf(using_protected_members_code, "    using %s::%s;\n", SwigType_namestr(ClassName), Getattr(nn, "name"));
       }
     }
   }
@@ -2249,164 +2305,6 @@
  * Language::classDeclaration()
  * ---------------------------------------------------------------------- */
 
-static void addCopyConstructor(Node *n) {
-  Node *cn = NewHash();
-  set_nodeType(cn, "constructor");
-  Setattr(cn, "access", "public");
-  Setfile(cn, Getfile(n));
-  Setline(cn, Getline(n));
-
-  String *cname = Getattr(n, "name");
-  SwigType *type = Copy(cname);
-  String *name = Swig_scopename_last(cname);
-  String *cc = NewStringf("r.q(const).%s", type);
-  String *decl = NewStringf("f(%s).", cc);
-  String *oldname = Getattr(n, "sym:name");
-
-  if (Getattr(n, "allocate:has_constructor")) {
-    // to work properly with '%rename Class', we must look
-    // for any other constructor in the class, which has not been
-    // renamed, and use its name as oldname.
-    Node *c;
-    for (c = firstChild(n); c; c = nextSibling(c)) {
-      const char *tag = Char(nodeType(c));
-      if (strcmp(tag, "constructor") == 0) {
-	String *cname = Getattr(c, "name");
-	String *csname = Getattr(c, "sym:name");
-	String *clast = Swig_scopename_last(cname);
-	if (Equal(csname, clast)) {
-	  oldname = csname;
-	  break;
-	}
-      }
-    }
-  }
-
-  String *symname = Swig_name_make(cn, cname, name, decl, oldname);
-  if (Strcmp(symname, "$ignore") != 0) {
-    Parm *p = NewParm(cc, "other", n);
-
-    Setattr(cn, "name", name);
-    Setattr(cn, "sym:name", symname);
-    SetFlag(cn, "feature:new");
-    Setattr(cn, "decl", decl);
-    Setattr(cn, "parentNode", n);
-    Setattr(cn, "parms", p);
-    Setattr(cn, "copy_constructor", "1");
-
-    Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
-    Node *on = Swig_symbol_add(symname, cn);
-    Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn);
-    Swig_symbol_setscope(oldscope);
-
-    if (on == cn) {
-      Node *access = NewHash();
-      set_nodeType(access, "access");
-      Setattr(access, "kind", "public");
-      appendChild(n, access);
-      appendChild(n, cn);
-      Setattr(n, "has_copy_constructor", "1");
-      Setattr(n, "copy_constructor_decl", decl);
-      Setattr(n, "allocate:copy_constructor", "1");
-      Delete(access);
-    }
-  }
-  Delete(cn);
-  Delete(name);
-  Delete(decl);
-  Delete(symname);
-}
-
-static void addDefaultConstructor(Node *n) {
-  Node *cn = NewHash();
-  set_nodeType(cn, "constructor");
-  Setattr(cn, "access", "public");
-  Setfile(cn, Getfile(n));
-  Setline(cn, Getline(n));
-
-  String *cname = Getattr(n, "name");
-  String *name = Swig_scopename_last(cname);
-  String *decl = NewString("f().");
-  String *oldname = Getattr(n, "sym:name");
-  String *symname = Swig_name_make(cn, cname, name, decl, oldname);
-  if (Strcmp(symname, "$ignore") != 0) {
-    Setattr(cn, "name", name);
-    Setattr(cn, "sym:name", symname);
-    SetFlag(cn, "feature:new");
-    Setattr(cn, "decl", decl);
-    Setattr(cn, "parentNode", n);
-    Setattr(cn, "default_constructor", "1");
-    Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
-    Node *on = Swig_symbol_add(symname, cn);
-    Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn);
-    Swig_symbol_setscope(oldscope);
-
-    if (on == cn) {
-      Node *access = NewHash();
-      set_nodeType(access, "access");
-      Setattr(access, "kind", "public");
-      appendChild(n, access);
-      appendChild(n, cn);
-      Setattr(n, "has_default_constructor", "1");
-      Setattr(n, "allocate:default_constructor", "1");
-      Delete(access);
-    }
-  }
-  Delete(cn);
-  Delete(name);
-  Delete(decl);
-  Delete(symname);
-}
-
-static void addDestructor(Node *n) {
-  Node *cn = NewHash();
-  set_nodeType(cn, "destructor");
-  Setattr(cn, "access", "public");
-  Setfile(cn, Getfile(n));
-  Setline(cn, Getline(n));
-
-  String *cname = Getattr(n, "name");
-  String *name = Swig_scopename_last(cname);
-  Insert(name, 0, "~");
-  String *decl = NewString("f().");
-  String *symname = Swig_name_make(cn, cname, name, decl, 0);
-  if (Strcmp(symname, "$ignore") != 0) {
-    String *possible_nonstandard_symname = NewStringf("~%s", Getattr(n, "sym:name"));
-
-    Setattr(cn, "name", name);
-    Setattr(cn, "sym:name", symname);
-    Setattr(cn, "decl", "f().");
-    Setattr(cn, "parentNode", n);
-
-    Symtab *oldscope = Swig_symbol_setscope(Getattr(n, "symtab"));
-    Node *nonstandard_destructor = Equal(possible_nonstandard_symname, symname) ? 0 : Swig_symbol_clookup(possible_nonstandard_symname, 0);
-    Node *on = Swig_symbol_add(symname, cn);
-    Swig_features_get(Swig_cparse_features(), Swig_symbol_qualifiedscopename(0), name, decl, cn);
-    Swig_symbol_setscope(oldscope);
-
-    if (on == cn) {
-      // SWIG accepts a non-standard named destructor in %extend that uses a typedef for the destructor name
-      // For example: typedef struct X {} XX; %extend X { ~XX() {...} }
-      // Don't add another destructor if a nonstandard one has been declared
-      if (!nonstandard_destructor) {
-	Node *access = NewHash();
-	set_nodeType(access, "access");
-	Setattr(access, "kind", "public");
-	appendChild(n, access);
-	appendChild(n, cn);
-	Setattr(n, "has_destructor", "1");
-	Setattr(n, "allocate:destructor", "1");
-	Delete(access);
-      }
-    }
-    Delete(possible_nonstandard_symname);
-  }
-  Delete(cn);
-  Delete(name);
-  Delete(decl);
-  Delete(symname);
-}
-
 int Language::classDeclaration(Node *n) {
   String *ochildren = Getattr(n, "feature:onlychildren");
   if (ochildren) {
@@ -2479,44 +2377,19 @@
 
   /* Call classHandler() here */
   if (!ImportMode) {
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       int ndir = GetFlag(n, "feature:director");
       int nndir = GetFlag(n, "feature:nodirector");
       /* 'nodirector' has precedence over 'director' */
       dir = (ndir || nndir) ? (ndir && !nndir) : 0;
     }
-    int abstract = !dir && abstractClassTest(n);
-    int odefault = (GenerateDefault && !GetFlag(n, "feature:nodefault"));
-
-    /* default constructor */
-    if (!abstract && !GetFlag(n, "feature:nodefaultctor") && odefault) {
-      if (!Getattr(n, "has_constructor") && !Getattr(n, "allocate:has_constructor") && (Getattr(n, "allocate:default_constructor"))) {
-	addDefaultConstructor(n);
-      }
-    }
-    /* copy constructor */
-    if (CPlusPlus && !abstract && GetFlag(n, "feature:copyctor")) {
-      if (!Getattr(n, "has_copy_constructor") && !Getattr(n, "allocate:has_copy_constructor")
-	  && (Getattr(n, "allocate:copy_constructor"))
-	  && (!GetFlag(n, "feature:ignore"))) {
-	addCopyConstructor(n);
-      }
-    }
-    /* default destructor */
-    if (!GetFlag(n, "feature:nodefaultdtor") && odefault) {
-      if (!Getattr(n, "has_destructor") && (!Getattr(n, "allocate:has_destructor"))
-	  && (Getattr(n, "allocate:default_destructor"))
-	  && (!GetFlag(n, "feature:ignore"))) {
-	addDestructor(n);
-      }
-    }
 
     if (dir) {
       DirectorClassName = directorClassName(n);
       classDirector(n);
     }
-    /* check for abstract after resolving directors */
 
+    /* check for abstract after resolving directors */
     Abstract = abstractClassTest(n);
     classHandler(n);
   } else {
@@ -2674,19 +2547,24 @@
     Setattr(CurrentClass, "sym:cleanconstructor", "1");
   }
 
-  if ((cplus_mode != PUBLIC)) {
+  if (!is_public(n)) {
     /* check only for director classes */
     if (!Swig_directorclass(CurrentClass) || !need_nonpublic_ctor(n))
       return SWIG_NOWRAP;
   }
 
-  /* Name adjustment for %name */
+  // Name adjustment of constructor when a class has been renamed with %rename
   Swig_save("constructorDeclaration", n, "sym:name", NIL);
 
   {
     String *base = Swig_scopename_last(name);
-    if ((Strcmp(base, symname) == 0) && (Strcmp(symname, ClassPrefix) != 0)) {
-      Setattr(n, "sym:name", ClassPrefix);
+    // Note that it is possible for the constructor to have a different name to the class name in
+    // some target languages, where it is wrapped as a factory type function instead of a constructor.
+    if (Equal(base, symname) && !Equal(symname, ClassPrefix)) {
+      // Adjust name, except when the constructor's name comes from a templated constructor,
+      // where the name passed to %template is used instead.
+      if (!Getattr(n, "template"))
+	Setattr(n, "sym:name", ClassPrefix);
     }
     Delete(base);
   }
@@ -2752,7 +2630,6 @@
       constructorHandler(n);
     }
   }
-  Setattr(CurrentClass, "has_constructor", "1");
 
   Swig_restore(n);
   return SWIG_OK;
@@ -2869,16 +2746,29 @@
     Setattr(n, "sym:name", ClassPrefix);
   }
 
-  String *expected_name = ClassName;
-  String *scope = Swig_scopename_check(ClassName) ? Swig_scopename_prefix(ClassName) : 0;
-  String *actual_name = scope ? NewStringf("%s::%s", scope, name) : NewString(name);
-  Delete(scope);
-  Replace(actual_name, "~", "", DOH_REPLACE_FIRST);
+  String *nprefix = 0;
+  String *nlast = 0;
+  String *tprefix;
+  Swig_scopename_split(ClassName, &nprefix, &nlast);
+  tprefix = SwigType_templateprefix(nlast);
+  String *expected_name = NewStringf("~%s", tprefix);
+
+  String *actual_name = Copy(name);
   if (!Equal(actual_name, expected_name) && !(Getattr(n, "template"))) {
     bool illegal_name = true;
     if (Extend) {
       // Check for typedef names used as a destructor name in %extend. This is deprecated except for anonymous
       // typedef structs which have had their symbol names adjusted to the typedef name in the parser.
+      Replace(actual_name, "~", "", DOH_REPLACE_FIRST);
+      Replace(expected_name, "~", "", DOH_REPLACE_FIRST);
+      if (Len(nprefix) > 0) {
+	String *old_actual_name = actual_name;
+	String *old_expected_name = expected_name;
+	actual_name = NewStringf("%s::%s", nprefix, actual_name);
+	expected_name = NewStringf("%s::%s", nprefix, expected_name);
+	Delete(old_expected_name);
+	Delete(old_actual_name);
+      }
       SwigType *name_resolved = SwigType_typedef_resolve_all(actual_name);
       SwigType *expected_name_resolved = SwigType_typedef_resolve_all(expected_name);
 
@@ -2900,6 +2790,11 @@
     if (illegal_name) {
       Swig_warning(WARN_LANG_ILLEGAL_DESTRUCTOR, input_file, line_number, "Illegal destructor name %s. Ignored.\n", Swig_name_decl(n));
       Swig_restore(n);
+      Delete(tprefix);
+      Delete(nlast);
+      Delete(nprefix);
+      Delete(expected_name);
+      Delete(actual_name);
       return SWIG_NOWRAP;
     }
   }
@@ -2907,6 +2802,11 @@
 
   Setattr(CurrentClass, "has_destructor", "1");
   Swig_restore(n);
+  Delete(tprefix);
+  Delete(nlast);
+  Delete(nprefix);
+  Delete(expected_name);
+  Delete(actual_name);
   return SWIG_OK;
 }
 
@@ -2939,14 +2839,7 @@
  * ---------------------------------------------------------------------- */
 
 int Language::accessDeclaration(Node *n) {
-  String *kind = Getattr(n, "kind");
-  if (Cmp(kind, "public") == 0) {
-    cplus_mode = PUBLIC;
-  } else if (Cmp(kind, "private") == 0) {
-    cplus_mode = PRIVATE;
-  } else if (Cmp(kind, "protected") == 0) {
-    cplus_mode = PROTECTED;
-  }
+  cplus_mode = accessModeFromString(Getattr(n, "kind"));
   return SWIG_OK;
 }
 
@@ -3028,7 +2921,7 @@
   }
 
   /* If no way to set variables.  We simply create functions */
-  int assignable = is_assignable(n);
+  int assignable = !is_immutable(n);
   int flags = use_naturalvar_mode(n);
   if (!GetFlag(n, "wrappedasconstant"))
     flags = flags | Extend;
@@ -3049,8 +2942,6 @@
       }
     } else {
       String *pname0 = Swig_cparm_name(0, 0);
-      Replace(tm, "$source", pname0, DOH_REPLACE_ANY);
-      Replace(tm, "$target", name, DOH_REPLACE_ANY);
       Replace(tm, "$input", pname0, DOH_REPLACE_ANY);
       Setattr(n, "wrap:action", tm);
       Delete(tm);
@@ -3127,8 +3018,8 @@
  * ----------------------------------------------------------------------------- */
 
 int Language::addSymbol(const String *s, const Node *n, const_String_or_char_ptr scope) {
-  //Printf( stdout, "addSymbol: %s %s\n", s, scope );
-  Hash *symbols = Getattr(symtabs, scope ? scope : "");
+  //Printf( stdout, "addSymbol: %s %s %s:%d\n", s, scope, Getfile(n), Getline(n) );
+  Hash *symbols = symbolScopeLookup(scope);
   if (!symbols) {
     symbols = symbolAddScope(scope);
   } else {
@@ -3175,15 +3066,15 @@
  * Language::symbolAddScope()
  *
  * Creates a scope (symbols Hash) for given name. This method is auxiliary,
- * you don't have to call it - addSymbols will lazily create scopes automatically.
+ * you don't have to call it - addSymbol will lazily create scopes automatically.
  * If scope with given name already exists, then do nothing.
  * Returns newly created (or already existing) scope.
  * ----------------------------------------------------------------------------- */
-Hash* Language::symbolAddScope(const_String_or_char_ptr scope) {
+Hash *Language::symbolAddScope(const_String_or_char_ptr scope/*, Node *n*/) {
   Hash *symbols = symbolScopeLookup(scope);
-  if(!symbols) {
+  if (!symbols) {
     // The order in which the following code is executed is important. In the Language
-    // constructor addScope("") is called to create a top level scope.
+    // constructor symbolAddScope("") is called to create a top level scope.
     // Thus we must first add a symbols hash to symtab and only then add pseudo
     // symbols to the top-level scope.
 
@@ -3195,8 +3086,22 @@
     // Alternatively the target language must add it in before attempting to add symbols into the scope.
     const_String_or_char_ptr top_scope = "";
     Hash *topscope_symbols = Getattr(symtabs, top_scope);
-    Hash *pseudo_symbol = NewHash();
-    Setattr(pseudo_symbol, "sym:scope", "1");
+
+    // TODO:
+    //   Stop using pseudo scopes, the symbol Node containing the new scope should be passed into this function.
+    //   This will require explicit calls to symbolScopeLookup() in each language and removing the call from addSymbol().
+    //   addSymbol() should then instead assert that the scope exists.
+    //   All this just to fix up the file/line numbering of the scopes for error reporting.
+    //Node *symbol = n;
+    Node *symbol = Getattr(topscope_symbols, scope);
+
+    Hash *pseudo_symbol = 0;
+    if (symbol) {
+      pseudo_symbol = symbol;
+    } else {
+      pseudo_symbol = NewHash();
+      Setattr(pseudo_symbol, "sym:scope", "1");
+    }
     Setattr(topscope_symbols, scope, pseudo_symbol);
   }
   return symbols;
@@ -3208,7 +3113,7 @@
  * Lookup and returns a symtable (hash) representing given scope. Hash contains
  * all symbols in this scope.
  * ----------------------------------------------------------------------------- */
-Hash* Language::symbolScopeLookup( const_String_or_char_ptr scope ) {
+Hash *Language::symbolScopeLookup(const_String_or_char_ptr scope) {
   Hash *symbols = Getattr(symtabs, scope ? scope : "");
   return symbols;
 }
@@ -3227,7 +3132,7 @@
  * There is no difference from symbolLookup() method except for signature
  * and return type.
  * ----------------------------------------------------------------------------- */
-Hash* Language::symbolScopePseudoSymbolLookup( const_String_or_char_ptr scope )
+Hash *Language::symbolScopePseudoSymbolLookup(const_String_or_char_ptr scope)
 {
   /* Getting top scope */
   const_String_or_char_ptr top_scope = "";
@@ -3254,6 +3159,7 @@
       while (it.key) {
 	String *symname = it.key;
 	Printf(stdout, "  %s\n", symname);
+	//Printf(stdout, "  %s (%s:%d)\n", symname, Getfile(it.item), Getline(it.item));
 	it = Next(it);
       }
     }
@@ -3477,19 +3383,19 @@
 }
 
 /* -----------------------------------------------------------------------------
+ * Language::directorLanguage()
+ * ----------------------------------------------------------------------------- */
+
+void Language::directorLanguage(int val) {
+  director_language = val;
+}
+
+/* -----------------------------------------------------------------------------
  * Language::allow_directors()
  * ----------------------------------------------------------------------------- */
 
 void Language::allow_directors(int val) {
-  directors = val;
-}
-
-/* -----------------------------------------------------------------------------
- * Language::directorsEnabled()
- * ----------------------------------------------------------------------------- */
-
-int Language::directorsEnabled() const {
-  return director_language && CPlusPlus && (directors || director_mode);
+  directors_allowed = val;
 }
 
 /* -----------------------------------------------------------------------------
@@ -3513,7 +3419,7 @@
  * ----------------------------------------------------------------------------- */
 
 int Language::dirprot_mode() const {
-  return directorsEnabled() ? director_protected_mode : 0;
+  return Swig_directors_enabled() ? director_protected_mode : 0;
 }
 
 /* -----------------------------------------------------------------------------
@@ -3549,7 +3455,7 @@
      members, and use %ignore for the method you don't want to add in
      the director class.
    */
-  if (directorsEnabled()) {
+  if (Swig_directors_enabled()) {
     if (is_protected(n)) {
       if (dirprot_mode()) {
 	/* when using dirprot mode, the protected constructors are
@@ -3582,7 +3488,7 @@
  * Language::need_nonpublic_member()
  * ----------------------------------------------------------------------------- */
 int Language::need_nonpublic_member(Node *n) {
-  if (directorsEnabled() && DirectorClassName) {
+  if (Swig_directors_enabled() && DirectorClassName) {
     if (is_protected(n)) {
       if (dirprot_mode()) {
 	/* when using dirprot mode, the protected members are always needed. */
@@ -3624,15 +3530,20 @@
 
   // Check if parameter name is a duplicate.
   int count = 0;
+  Parm *first_duplicate_parm = 0;
   ParmList *plist = Getattr(n, "parms");
   while (plist) {
-    if ((Cmp(pn, Getattr(plist, "name")) == 0))
+    if ((Cmp(pn, Getattr(plist, "name")) == 0)) {
+      if (!first_duplicate_parm)
+	first_duplicate_parm = plist;
       count++;
+    }
     plist = nextSibling(plist);
   }
 
   // If the parameter has no name at all or has a non-unique name, replace it with "argN".
-  if (!pn || count > 1) {
+  // On the assumption that p is pointer/element in plist, only replace the 2nd and subsequent duplicates
+  if (!pn || (count > 1 && p != first_duplicate_parm)) {
     arg = NewStringf("arg%d", arg_num);
   } else {
     // Otherwise, try to use the original C name, but modify it if necessary to avoid conflicting with the language keywords.
@@ -3742,10 +3653,10 @@
 }
 
 /* -----------------------------------------------------------------------------
- * Language::abstractClassTest()
+ * Dispatcher::abstractClassTest()
  * ----------------------------------------------------------------------------- */
 //#define SWIG_DEBUG
-int Language::abstractClassTest(Node *n) {
+int Dispatcher::abstractClassTest(Node *n) {
   /* check for non public operator new */
   if (GetFlag(n, "feature:notabstract"))
     return 0;
@@ -3774,7 +3685,7 @@
 #endif
   if (!labs)
     return 0;			/*strange, but need to be fixed */
-  if (abstracts && !directorsEnabled())
+  if (abstracts && !Swig_directors_enabled())
     return 1;
   if (!GetFlag(n, "feature:director"))
     return 1;
@@ -3787,7 +3698,7 @@
 #endif
     for (int i = 0; i < labs; i++) {
       Node *ni = Getitem(abstracts, i);
-      Node *method_id = vtable_method_id(ni);
+      String *method_id = vtable_method_id(ni);
       if (!method_id)
 	continue;
       bool exists_item = false;
@@ -3837,29 +3748,8 @@
   argv_template_string = Copy(argv);
 }
 
-int Language::is_assignable(Node *n) {
-  if (GetFlag(n, "feature:immutable"))
-    return 0;
-  SwigType *type = Getattr(n, "type");
-  Node *cn = 0;
-  SwigType *ftd = SwigType_typedef_resolve_all(type);
-  SwigType *td = SwigType_strip_qualifiers(ftd);
-  if (SwigType_type(td) == T_USER) {
-    cn = Swig_symbol_clookup(td, 0);
-    if (cn) {
-      if ((Strcmp(nodeType(cn), "class") == 0)) {
-	if (Getattr(cn, "allocate:noassign")) {
-	  SetFlag(n, "feature:immutable");
-	  Delete(ftd);
-	  Delete(td);
-	  return 0;
-	}
-      }
-    }
-  }
-  Delete(ftd);
-  Delete(td);
-  return 1;
+int Language::is_immutable(Node *n) {
+  return GetFlag(n, "feature:immutable");
 }
 
 String *Language::runtimeCode() {
diff --git a/Source/Modules/lua.cxx b/Source/Modules/lua.cxx
index 188b11c..5ca623d 100644
--- a/Source/Modules/lua.cxx
+++ b/Source/Modules/lua.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * lua.cxx
  *
@@ -50,7 +50,7 @@
 /**** Diagnostics:
   With the #define REPORT(), you can change the amount of diagnostics given
   This helps me search the parse tree & figure out what is going on inside SWIG
-  (because its not clear or documented)
+  (because it's not clear or documented)
 */
 #define REPORT(T,D)		// no info:
 //#define REPORT(T,D)   {Printf(stdout,T"\n");} // only title
@@ -304,7 +304,7 @@
     f_begin = NewFile(outfile, "w", SWIG_output_files());
     if (!f_begin) {
       FileErrorDisplay(outfile);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
     f_runtime = NewString("");
     f_init = NewString("");
@@ -329,7 +329,7 @@
     /* Standard stuff for the SWIG runtime section */
     Swig_banner(f_begin);
 
-    Printf(f_runtime, "\n\n#ifndef SWIGLUA\n#define SWIGLUA\n#endif\n\n");
+    Swig_obligatory_macros(f_runtime, "LUA");
 
     emitLuaFlavor(f_runtime);
 
@@ -435,7 +435,7 @@
   /* NEW LANGUAGE NOTE:***********************************************
      This is it!
      you get this one right, and most of your work is done
-     but its going to take some file to get it working right
+     but it's going to take some file to get it working right
      quite a bit of this is generally boilerplate code
      (or stuff I don't understand)
      that which matters will have extra added comments
@@ -556,6 +556,12 @@
        this line adds this into the wrapper code
        NEW LANGUAGE NOTE:END *********************************************** */
     Printv(f->def, "static int ", wname, "(lua_State* L) {", NIL);
+    // SWIG_fail in lua leads to a call to lua_error() which calls longjmp()
+    // which means the destructors of any live function-local C++ objects won't
+    // get run.  To avoid this happening, we wrap almost everything in the
+    // function in a block, and end that right before lua_error() at which
+    // point those destructors will get called.
+    if (CPlusPlus) Append(f->def, "\n{");
 
     /* NEW LANGUAGE NOTE:***********************************************
        this prints the list of args, eg for a C fn
@@ -613,13 +619,9 @@
       }
 
       SwigType *pt = Getattr(p, "type");
-      String *ln = Getattr(p, "lname");
-
       /* Look for an input typemap */
       sprintf(source, "%d", i + 1);
       if ((tm = Getattr(p, "tmap:in"))) {
-	Replaceall(tm, "$source", source);
-	Replaceall(tm, "$target", ln);
 	Replaceall(tm, "$input", source);
 	Setattr(p, "emit:input", source);
 	if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
@@ -678,7 +680,6 @@
     /* Insert constraint checking code */
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:check"))) {
-	Replaceall(tm, "$target", Getattr(p, "lname"));
 	Printv(f->code, tm, "\n", NIL);
 	p = Getattr(p, "tmap:check:next");
       } else {
@@ -690,7 +691,6 @@
     String *cleanup = NewString("");
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:freearg"))) {
-	Replaceall(tm, "$source", Getattr(p, "lname"));
 	Printv(cleanup, tm, "\n", NIL);
 	p = Getattr(p, "tmap:freearg:next");
       } else {
@@ -709,8 +709,6 @@
 	//                      returnval+=GetInt(p,"tmap:argout:numoutputs");
 	//        }
 	//        else returnval++;
-	Replaceall(tm, "$source", Getattr(p, "lname"));
-	Replaceall(tm, "$target", Swig_cresult_name());
 	Replaceall(tm, "$arg", Getattr(p, "emit:input"));
 	Replaceall(tm, "$input", Getattr(p, "emit:input"));
 	Printv(outarg, tm, "\n", NIL);
@@ -740,7 +738,6 @@
       //              returnval+=GetInt(tm,"numoutputs");
       //      }
       //        else returnval++;
-      Replaceall(tm, "$source", Swig_cresult_name());
       if (GetFlag(n, "feature:new")) {
 	Replaceall(tm, "$owner", "1");
       } else {
@@ -762,14 +759,12 @@
     /* Look to see if there is any newfree cleanup code */
     if (GetFlag(n, "feature:new")) {
       if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
-	Replaceall(tm, "$source", Swig_cresult_name());
 	Printf(f->code, "%s\n", tm);
       }
     }
 
     /* See if there is any return cleanup code */
     if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
-      Replaceall(tm, "$source", Swig_cresult_name());
       Printf(f->code, "%s\n", tm);
     }
 
@@ -777,10 +772,12 @@
     /* Close the function */
     Printv(f->code, "return SWIG_arg;\n", NIL);
     // add the failure cleanup code:
-    Printv(f->code, "\nif(0) SWIG_fail;\n", NIL);
-    Printv(f->code, "\nfail:\n", NIL);
-    Printv(f->code, "$cleanup", "lua_error(L);\n", NIL);
-    Printv(f->code, "return SWIG_arg;\n", NIL);
+    Printv(f->code, "\nfail: SWIGUNUSED;\n", "$cleanup", NIL);
+    if (CPlusPlus) Append(f->code, "}\n");
+    Printv(f->code, "lua_error(L);\n", NIL);
+    // lua_error() calls longjmp() but we need a dummy return to avoid compiler
+    // warnings.
+    Printv(f->code, "return 0;\n", NIL);
     Printf(f->code, "}\n");
 
     /* Substitute the cleanup code */
@@ -917,7 +914,7 @@
    * ------------------------------------------------------------ */
 
   void registerVariable(Node *n, bool overwrite = false, String *overwriteLuaScope = 0) {
-    int assignable = is_assignable(n);
+    int assignable = !is_immutable(n);
     String *symname = Getattr(n, "sym:name");
     assert(symname);
 
@@ -1002,6 +999,7 @@
     //    REPORT("variableWrapper", n);
     String *lua_name = Getattr(n, "lua:name");
     assert(lua_name);
+    (void)lua_name;
     current[VARIABLE] = true;
     // let SWIG generate the wrappers
     int result = Language::variableWrapper(n);
@@ -1073,14 +1071,10 @@
     }
 
     if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) {
-      Replaceall(tm, "$source", value);
-      Replaceall(tm, "$target", lua_name);
       Replaceall(tm, "$value", value);
       Replaceall(tm, "$nsname", nsname);
       registerConstant(luaCurrentSymbolNSpace(), tm);
     } else if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
-      Replaceall(tm, "$source", value);
-      Replaceall(tm, "$target", lua_name);
       Replaceall(tm, "$value", value);
       Replaceall(tm, "$nsname", nsname);
       Printf(f_init, "%s\n", tm);
@@ -1109,8 +1103,6 @@
         Setattr(n_v2, "sym:name", lua_name_v2);
         tm_v2 = Swig_typemap_lookup("consttab", n_v2, name, 0);
         if (tm_v2) {
-          Replaceall(tm_v2, "$source", value);
-          Replaceall(tm_v2, "$target", lua_name_v2);
           Replaceall(tm_v2, "$value", value);
           Replaceall(tm_v2, "$nsname", nsname);
           registerConstant(getNSpace(), tm_v2);
@@ -1122,8 +1114,6 @@
             Swig_restore(n);
             return SWIG_ERROR;
           }
-          Replaceall(tm_v2, "$source", value);
-          Replaceall(tm_v2, "$target", lua_name_v2);
           Replaceall(tm_v2, "$value", value);
           Replaceall(tm_v2, "$nsname", nsname);
           Printf(f_init, "%s\n", tm_v2);
@@ -1279,12 +1269,12 @@
       full_proxy_class_name = NewStringf("%s.%s", nspace, proxy_class_name);
 
     assert(full_proxy_class_name);
-    mangled_full_proxy_class_name = Swig_name_mangle(full_proxy_class_name);
+    mangled_full_proxy_class_name = Swig_name_mangle_string(full_proxy_class_name);
 
     SwigType *t = Copy(Getattr(n, "name"));
     SwigType *fr_t = SwigType_typedef_resolve_all(t);	/* Create fully resolved type */
     SwigType *t_tmp = 0;
-    t_tmp = SwigType_typedef_qualified(fr_t);	// Temporal variable
+    t_tmp = SwigType_typedef_qualified(fr_t);	// Temporary variable
     Delete(fr_t);
     fr_t = SwigType_strip_qualifiers(t_tmp);
     String *mangled_fr_t = 0;
@@ -1436,7 +1426,6 @@
     List *baselist = Getattr(n, "bases");
     if (baselist && Len(baselist)) {
       Iterator b;
-      int index = 0;
       b = First(baselist);
       while (b.item) {
 	String *bname = Getattr(b.item, "name");
@@ -1449,7 +1438,6 @@
 	Printf(base_class_names, "\"%s *\",", SwigType_namestr(bname));
 
 	b = Next(b);
-	index++;
       }
     }
     // First, print class static part
@@ -1815,7 +1803,7 @@
     if (nspace == 0 || Len(nspace) == 0)
       mangled_name = NewString("SwigModule");
     else
-      mangled_name = Swig_name_mangle(nspace);
+      mangled_name = Swig_name_mangle_string(nspace);
     String *cname = NewStringf("swig_%s", mangled_name);
 
     Setattr(carrays_hash, "cname", cname);
@@ -2071,8 +2059,8 @@
 	if (GetFlag(carrays_hash, "lua:class_instance")) {
 	  String *static_cls = Getattr(carrays_hash, "lua:class_instance:static_hash");
 	  assert(static_cls);
-	  // static_cls is swig_lua_namespace. This structure can't be use with eLua(LTR)
-	  // Instead structure describing its methods isused
+	  // static_cls is swig_lua_namespace. This structure can't be used with eLua(LTR)
+	  // Instead a structure describing its methods is used
 	  String *static_cls_cname = Getattr(static_cls, "methods:name");
 	  assert(static_cls_cname);
 	  Printv(metatable_tab, tab4, "{LSTRKEY(\".static\"), LROVAL(", static_cls_cname, ")},\n", NIL);
@@ -2134,7 +2122,7 @@
       closeCArraysHash(key, dataOutput);
       Hash *carrays_hash = rawGetCArraysHash(key);
       String *name = 0;		// name - name of the namespace as it should be visible in Lua
-      if (DohLen(key) == 0)	// This is global module
+      if (Len(key) == 0)	// This is global module
 	name = module;
       else
 	name = Getattr(carrays_hash, "name");
@@ -2243,36 +2231,6 @@
 
 };
 
-/* NEW LANGUAGE NOTE:***********************************************
- in order to add you language into swig, you need to make the following changes:
- - write this file (obviously)
- - add into the makefile (not 100% clear on how to do this)
- - edit swigmain.cxx to add your module
- 
-near the top of swigmain.cxx, look for this code & add you own codes
-======= begin change ==========
-extern "C" {
-  Language *swig_tcl(void);
-  Language *swig_python(void);
-  //etc,etc,etc...
-  Language *swig_lua(void);	// this is my code
-}
- 
-  //etc,etc,etc...
- 
-swig_module  modules[] = {
-  {"-guile",     swig_guile,     "Guile"},
-  {"-java",      swig_java,      "Java"},
-  //etc,etc,etc...
-  {"-lua",       swig_lua,       "Lua"},	// this is my code
-  {NULL, NULL, NULL}	// this must come at the end of the list
-};
-======= end change ==========
- 
-This is all that is needed
- 
-NEW LANGUAGE NOTE:END ************************************************/
-
 /* -----------------------------------------------------------------------------
  * swig_lua()    - Instantiate module
  * ----------------------------------------------------------------------------- */
diff --git a/Source/Modules/main.cxx b/Source/Modules/main.cxx
index 72b765b..76b4f9d 100644
--- a/Source/Modules/main.cxx
+++ b/Source/Modules/main.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * main.cxx
  *
@@ -32,14 +32,16 @@
 int CPlusPlus = 0;
 int Extend = 0;			// Extend flag
 int ForceExtern = 0;		// Force extern mode
-int GenerateDefault = 1;	// Generate default constructors
 int Verbose = 0;
 int AddExtern = 0;
 int NoExcept = 0;
-int SwigRuntime = 0;		// 0 = no option, 1 = -runtime, 2 = -noruntime
+extern "C" {
+  int UseWrapperSuffix = 0;	// If 1, append suffix to non-overloaded functions too.
+}
 
-/* Suppress warning messages for private inheritance, preprocessor evaluation etc...
-   WARN_PP_EVALUATION                           202
+/* Suppress warning messages for private inheritance, etc by default.
+   These are enabled by command line option -Wextra.
+
    WARN_PARSE_PRIVATE_INHERIT                   309
    WARN_PARSE_BUILTIN_NAME                      321
    WARN_PARSE_REDUNDANT                         322
@@ -47,7 +49,7 @@
    WARN_TYPE_RVALUE_REF_QUALIFIER_IGNORED       405
    WARN_LANG_OVERLOAD_CONST                     512
  */
-#define EXTRA_WARNINGS "202,309,403,405,512,321,322"
+#define EXTRA_WARNINGS "309,403,405,512,321,322"
 
 extern "C" {
   extern String *ModuleName;
@@ -58,7 +60,7 @@
 /* usage string split into multiple parts otherwise string is too big for some compilers */
 /* naming conventions for commandline options - no underscores, no capital letters, join words together
  * except when using a common prefix, then use '-' to separate, eg the debug-xxx options */
-static const char *usage1 = (const char *) "\
+static const char *usage1 = "\
 \nGeneral Options\n\
      -addextern      - Add extra extern declarations\n\
      -c++            - Enable C++ processing\n\
@@ -74,6 +76,7 @@
      -debug-symbols  - Display target language symbols in the symbol tables\n\
      -debug-csymbols - Display C symbols in the symbol tables\n\
      -debug-lsymbols - Display target language layer symbols\n\
+     -debug-quiet    - Display less parse tree node debug info when using other -debug options\n\
      -debug-tags     - Display information about the tags found in the interface\n\
      -debug-template - Display information for debugging templates\n\
      -debug-top <n>  - Display entire parse tree at stages 1-4, <n> is a csv list of stages\n\
@@ -83,10 +86,10 @@
      -debug-tmused   - Display typemaps used debugging information\n\
      -directors      - Turn on director mode for all the classes, mainly for testing\n\
      -dirprot        - Turn on wrapping of protected members for director classes (default)\n\
-     -D<symbol>      - Define a symbol <symbol> (for conditional compilation)\n\
+     -D<symbol>[=<value>] - Define symbol <symbol> (for conditional compilation)\n\
 ";
 
-static const char *usage2 = (const char *) "\
+static const char *usage2 = "\
      -E              - Preprocess only, does not generate wrapper code\n\
      -external-runtime [file] - Export the SWIG runtime stack\n\
      -fakeversion <v>- Make SWIG fake the program version number to <v>\n\
@@ -107,9 +110,8 @@
      -l<ifile>       - Include SWIG library file <ifile>\n\
 ";
 
-static const char *usage3 = (const char *) "\
+static const char *usage3 = "\
      -macroerrors    - Report errors inside macros\n\
-     -makedefault    - Create default constructors/destructors (the default)\n\
      -M              - List all dependencies\n\
      -MD             - Is equivalent to `-M -MF <file>', except `-E' is not implied\n\
      -MF <file>      - Generate dependencies into <file> and continue generating wrappers\n\
@@ -120,7 +122,6 @@
      -MT <target>    - Set the target of the rule emitted by dependency generation\n\
      -nocontract     - Turn off contract checking\n\
      -nocpperraswarn - Do not treat the preprocessor #error statement as #warning\n\
-     -nodefault      - Do not generate default constructors nor default destructors\n\
      -nodefaultctor  - Do not generate implicit default constructors\n\
      -nodefaultdtor  - Do not generate implicit default destructors\n\
      -nodirprot      - Do not wrap director protected members\n\
@@ -130,17 +131,19 @@
      -notemplatereduce - Disable reduction of the typedefs in templates\n\
 ";
 
-static const char *usage4 = (const char *) "\
+static const char *usage4 = "\
      -O              - Enable the optimization options:\n\
                         -fastdispatch -fvirtual\n\
      -o <outfile>    - Set name of C/C++ output file to <outfile>\n\
      -oh <headfile>  - Set name of C++ output header file for directors to <headfile>\n\
      -outcurrentdir  - Set default output dir to current dir instead of input file's path\n\
      -outdir <dir>   - Set language specific files output directory to <dir>\n\
-     -pcreversion    - Display PCRE version information\n\
+     -pcreversion    - Display PCRE2 version information\n\
      -small          - Compile in virtual elimination and compact mode\n\
+     -std=<standard> - Set the C or C++ language <standard> for inputs\n\
      -swiglib        - Report location of SWIG library and exit\n\
      -templatereduce - Reduce all the typedefs in templates\n\
+     -U<symbol>      - Undefine symbol <symbol>\n\
      -v              - Run in verbose mode\n\
      -version        - Display SWIG version number\n\
      -Wall           - Remove all warning suppression, also implies -Wextra\n\
@@ -192,8 +195,6 @@
 static int dump_tags = 0;
 static int dump_module = 0;
 static int dump_top = 0;
-static int dump_xml = 0;
-static int browse = 0;
 static int dump_typedef = 0;
 static int dump_classes = 0;
 static int werror = 0;
@@ -210,6 +211,8 @@
 enum { STAGE1=1, STAGE2=2, STAGE3=4, STAGE4=8, STAGEOVERFLOW=16 };
 static List *libfiles = 0;
 static List *all_output_files = 0;
+static const char *stdcpp_define = NULL;
+static const char *stdc_define = NULL;
 
 /* -----------------------------------------------------------------------------
  * check_extension()
@@ -233,46 +236,6 @@
 }
 
 /* -----------------------------------------------------------------------------
- * install_opts()
- *
- * Install all command line options as preprocessor symbols
- * ----------------------------------------------------------------------------- */
-
-static void install_opts(int argc, char *argv[]) {
-  int i;
-  int noopt = 0;
-  char *c;
-  for (i = 1; i < (argc - 1); i++) {
-    if (argv[i]) {
-      if ((*argv[i] == '-') && (!isupper(*(argv[i] + 1)))) {
-	String *opt = NewStringf("SWIGOPT%(upper)s", argv[i]);
-	Replaceall(opt, "-", "_");
-	c = Char(opt);
-	noopt = 0;
-	while (*c) {
-	  if (!(isalnum(*c) || (*c == '_'))) {
-	    noopt = 1;
-	    break;
-	  }
-	  c++;
-	}
-	if (((i + 1) < (argc - 1)) && (argv[i + 1]) && (*argv[i + 1] != '-')) {
-	  Printf(opt, " %s", argv[i + 1]);
-	  i++;
-	} else {
-	  Printf(opt, " 1");
-	}
-	if (!noopt) {
-	  /*      Printf(stdout,"%s\n", opt); */
-	  Preprocessor_define(opt, 0);
-	}
-	Delete(opt);
-      }
-    }
-  }
-}
-
-/* -----------------------------------------------------------------------------
  * decode_numbers_list()
  *
  * Decode comma separated list into a binary number of the inputs or'd together
@@ -403,24 +366,33 @@
     outfile = lang->defaultExternalRuntimeFilename();
     if (!outfile) {
       Printf(stderr, "*** Please provide a filename for the external runtime\n");
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
   }
 
   runtime = NewFile(outfile, "w", SWIG_output_files());
   if (!runtime) {
     FileErrorDisplay(outfile);
-    SWIG_exit(EXIT_FAILURE);
+    Exit(EXIT_FAILURE);
   }
 
   Swig_banner(runtime);
   Printf(runtime, "\n");
 
+  s = Swig_include_sys("swigcompat.swg");
+  if (!s) {
+    Printf(stderr, "*** Unable to open 'swigcompat.swg'\n");
+    Delete(runtime);
+    Exit(EXIT_FAILURE);
+  }
+  Printf(runtime, "%s", s);
+  Delete(s);
+
   s = Swig_include_sys("swiglabels.swg");
   if (!s) {
     Printf(stderr, "*** Unable to open 'swiglabels.swg'\n");
     Delete(runtime);
-    SWIG_exit(EXIT_FAILURE);
+    Exit(EXIT_FAILURE);
   }
   Printf(runtime, "%s", s);
   Delete(s);
@@ -429,7 +401,7 @@
   if (!s) {
     Printf(stderr, "*** Unable to open 'swigerrors.swg'\n");
     Delete(runtime);
-    SWIG_exit(EXIT_FAILURE);
+    Exit(EXIT_FAILURE);
   }
   Printf(runtime, "%s", s);
   Delete(s);
@@ -438,7 +410,7 @@
   if (!s) {
     Printf(stderr, "*** Unable to open 'swigrun.swg'\n");
     Delete(runtime);
-    SWIG_exit(EXIT_FAILURE);
+    Exit(EXIT_FAILURE);
   }
   Printf(runtime, "%s", s);
   Delete(s);
@@ -451,13 +423,13 @@
   if (!s) {
     Printf(stderr, "*** Unable to open 'runtime.swg'\n");
     Delete(runtime);
-    SWIG_exit(EXIT_FAILURE);
+    Exit(EXIT_FAILURE);
   }
   Printf(runtime, "%s", s);
   Delete(s);
 
   Delete(runtime);
-  SWIG_exit(EXIT_SUCCESS);
+  Exit(EXIT_SUCCESS);
 }
 
 static void getoptions(int argc, char *argv[]) {
@@ -471,16 +443,20 @@
 	Swig_mark_arg(i);
       } else if (strncmp(argv[i], "-I", 2) == 0) {
 	// Add a new directory search path
-	char *a = Swig_copy_string(argv[i] + 2);
-	Swig_add_directory((DOH *) a);
-	free(a);
+	Swig_add_directory((String_or_char*)(argv[i] + 2));
 	Swig_mark_arg(i);
       } else if (strncmp(argv[i], "-D", 2) == 0) {
 	String *d = NewString(argv[i] + 2);
-	Replace(d, "=", " ", DOH_REPLACE_ANY | DOH_REPLACE_FIRST);
-	Preprocessor_define((DOH *) d, 0);
-	Delete(d);
+	if (Replace(d, "=", " ", DOH_REPLACE_FIRST) == 0) {
+	  // Match C preprocessor behaviour whereby -DFOO sets FOO=1.
+	  Append(d, " 1");
+	}
 	// Create a symbol
+	Preprocessor_define(d, 0);
+	Delete(d);
+	Swig_mark_arg(i);
+      } else if (strncmp(argv[i], "-U", 2) == 0) {
+	Preprocessor_undef(argv[i] + 2);
 	Swig_mark_arg(i);
       } else if (strcmp(argv[i], "-E") == 0) {
 	cpp_only = 1;
@@ -493,13 +469,52 @@
 	Swig_mark_arg(i);
       } else if (strcmp(argv[i], "-c++") == 0) {
 	CPlusPlus = 1;
-	Preprocessor_define((DOH *) "__cplusplus __cplusplus", 0);
 	Swig_cparse_cplusplus(1);
 	Swig_mark_arg(i);
       } else if (strcmp(argv[i], "-c++out") == 0) {
 	// Undocumented
 	Swig_cparse_cplusplusout(1);
 	Swig_mark_arg(i);
+      } else if (strncmp(argv[i], "-std=c", 6) == 0) {
+	const char *std = argv[i] + 6;
+	if (strncmp(std, "++", 2) == 0) {
+	  std += 2;
+	  if (strcmp(std, "98") == 0 || strcmp(std, "03") == 0) {
+	    stdcpp_define = "__cplusplus 199711L";
+	  } else if (strcmp(std, "11") == 0) {
+	    stdcpp_define = "__cplusplus 201103L";
+	  } else if (strcmp(std, "14") == 0) {
+	    stdcpp_define = "__cplusplus 201402L";
+	  } else if (strcmp(std, "17") == 0) {
+	    stdcpp_define = "__cplusplus 201703L";
+	  } else if (strcmp(std, "20") == 0) {
+	    stdcpp_define = "__cplusplus 202002L";
+	  } else if (strcmp(std, "23") == 0) {
+	    stdcpp_define = "__cplusplus 202302L";
+	  } else {
+	    Printf(stderr, "Unrecognised C++ standard version in option '%s'\n", argv[i]);
+	    Exit(EXIT_FAILURE);
+	  }
+	} else {
+	  if (strcmp(std, "89") == 0 || strcmp(std, "90") == 0) {
+	    stdc_define = NULL;
+	  } else if (strcmp(std, "95") == 0) {
+	    stdc_define = "__STDC_VERSION__ 199409L";
+	  } else if (strcmp(std, "99") == 0) {
+	    stdc_define = "__STDC_VERSION__ 199901L";
+	  } else if (strcmp(std, "11") == 0) {
+	    stdc_define = "__STDC_VERSION__ 201112L";
+	  } else if (strcmp(std, "17") == 0 || strcmp(std, "18") == 0) {
+	    // Both GCC and clang accept -std=c18 as well as -std=c17.
+	    stdc_define = "__STDC_VERSION__ 201710L";
+	  } else if (strcmp(std, "23") == 0) {
+	    stdc_define = "__STDC_VERSION__ 202311L";
+	  } else {
+	    Printf(stderr, "Unrecognised C standard version in option '%s'\n", argv[i]);
+	    Exit(EXIT_FAILURE);
+	  }
+	}
+	Swig_mark_arg(i);
       } else if (strcmp(argv[i], "-fcompact") == 0) {
 	Wrapper_compact_print_mode_set(1);
 	Swig_mark_arg(i);
@@ -530,19 +545,11 @@
 	Printf(stdout, "%s\n", version);
 	Delete(version);
 	Swig_mark_arg(i);
-	SWIG_exit(EXIT_SUCCESS);
+	Exit(EXIT_SUCCESS);
       } else if (strcmp(argv[i], "-small") == 0) {
 	Wrapper_compact_print_mode_set(1);
 	Wrapper_virtual_elimination_mode_set(1);
 	Swig_mark_arg(i);
-      } else if (strcmp(argv[i], "-runtime") == 0) { // Used to also accept -c. removed in swig-1.3.36
-	Swig_mark_arg(i);
-	Swig_warning(WARN_DEPRECATED_OPTC, "SWIG", 1, "-runtime, -noruntime command line options are deprecated.\n");
-	SwigRuntime = 1;
-      } else if (strcmp(argv[i], "-noruntime") == 0) {
-	Swig_mark_arg(i);
-	Swig_warning(WARN_DEPRECATED_OPTC, "SWIG", 1, "-runtime, -noruntime command line options are deprecated.\n");
-	SwigRuntime = 2;
       } else if (strcmp(argv[i], "-external-runtime") == 0) {
 	external_runtime = 1;
 	Swig_mark_arg(i);
@@ -551,13 +558,6 @@
 	  Swig_mark_arg(i + 1);
 	  i++;
 	}
-      } else if ((strcmp(argv[i], "-make_default") == 0) || (strcmp(argv[i], "-makedefault") == 0)) {
-	GenerateDefault = 1;
-	Swig_mark_arg(i);
-      } else if ((strcmp(argv[i], "-no_default") == 0) || (strcmp(argv[i], "-nodefault") == 0)) {
-	GenerateDefault = 0;
-	Swig_warning(WARN_DEPRECATED_NODEFAULT, "SWIG", 1, "dangerous, use -nodefaultctor, -nodefaultdtor instead.\n");
-	Swig_mark_arg(i);
       } else if ((strcmp(argv[i], "-nodefaultctor") == 0)) {
 	SWIG_setfeature("feature:nodefaultctor", "1");
 	Swig_mark_arg(i);
@@ -570,14 +570,10 @@
       } else if (strcmp(argv[i], "-noexcept") == 0) {
 	NoExcept = 1;
 	Swig_mark_arg(i);
-      } else if (strcmp(argv[i], "-noextern") == 0) {
-	Swig_warning(WARN_DEPRECATED_NOEXTERN, "SWIG", 1, "-noextern command line option is deprecated; extern is no longer generated by default.\n");
-	AddExtern = 0;
-	Swig_mark_arg(i);
       } else if (strcmp(argv[i], "-addextern") == 0) {
 	AddExtern = 1;
 	Swig_mark_arg(i);
-      } else if ((strcmp(argv[i], "-debug-template") == 0) || (strcmp(argv[i], "-debug_template") == 0) || (strcmp(argv[i], "-show_templates") == 0)) {
+      } else if (strcmp(argv[i], "-debug-template") == 0) {
 	Swig_cparse_debug_templates(1);
 	Swig_mark_arg(i);
       } else if (strcmp(argv[i], "-templatereduce") == 0) {
@@ -593,7 +589,7 @@
 	Printf(stdout, "%s\n", SwigLib);
 	if (SwigLibWinUnix)
 	  Printf(stdout, "%s\n", SwigLibWinUnix);
-	SWIG_exit(EXIT_SUCCESS);
+	Exit(EXIT_SUCCESS);
       } else if (strcmp(argv[i], "-o") == 0) {
 	Swig_mark_arg(i);
 	if (argv[i + 1]) {
@@ -646,7 +642,7 @@
 #endif
 	    );
 	fprintf(stdout, "\nPlease see %s for reporting bugs and further information\n", PACKAGE_BUGREPORT);
-	SWIG_exit(EXIT_SUCCESS);
+	Exit(EXIT_SUCCESS);
       } else if (strcmp(argv[i], "-copyright") == 0) {
 	fprintf(stdout, "\nSWIG Version %s\n", Swig_package_version());
 	fprintf(stdout, "Copyright (c) 1995-1998\n");
@@ -655,7 +651,7 @@
 	fprintf(stdout, "University of Chicago\n");
 	fprintf(stdout, "Copyright (c) 2005-2006\n");
 	fprintf(stdout, "Arizona Board of Regents (University of Arizona)\n");
-	SWIG_exit(EXIT_SUCCESS);
+	Exit(EXIT_SUCCESS);
       } else if (strncmp(argv[i], "-l", 2) == 0) {
 	// Add a new directory search path
 	Append(libfiles, argv[i] + 2);
@@ -698,7 +694,7 @@
 	} else {
 	  Swig_arg_error();
 	}
-      } else if ((strcmp(argv[i], "-debug-typemap") == 0) || (strcmp(argv[i], "-debug_typemap") == 0) || (strcmp(argv[i], "-tm_debug") == 0)) {
+      } else if (strcmp(argv[i], "-debug-typemap") == 0) {
 	tm_debug = 1;
 	Swig_mark_arg(i);
       } else if (strcmp(argv[i], "-debug-tmsearch") == 0) {
@@ -777,6 +773,9 @@
       } else if (strncmp(argv[i], "-w", 2) == 0) {
 	Swig_mark_arg(i);
 	Swig_warnfilter(argv[i] + 2, 1);
+      } else if (strcmp(argv[i], "-debug-quiet") == 0) {
+	Swig_print_quiet(1);
+	Swig_mark_arg(i);
       } else if (strcmp(argv[i], "-debug-symtabs") == 0) {
 	dump_symtabs = 1;
 	Swig_mark_arg(i);
@@ -789,7 +788,7 @@
       } else if (strcmp(argv[i], "-debug-lsymbols") == 0) {
 	dump_lang_symbols = 1;
 	Swig_mark_arg(i);
-      } else if ((strcmp(argv[i], "-debug-tags") == 0) || (strcmp(argv[i], "-dump_tags") == 0)) {
+      } else if (strcmp(argv[i], "-debug-tags") == 0) {
 	dump_tags = 1;
 	Swig_mark_arg(i);
       } else if (strcmp(argv[i], "-debug-top") == 0) {
@@ -818,23 +817,7 @@
 	} else {
 	  Swig_arg_error();
 	}
-      } else if ((strcmp(argv[i], "-dump_tree") == 0) || (strcmp(argv[i], "-dump_top") == 0)) {
-	dump_top |= STAGE4;
-	Swig_mark_arg(i);
-      } else if (strcmp(argv[i], "-dump_module") == 0) {
-	dump_module |= STAGE4;
-	Swig_mark_arg(i);
-      } else if (strcmp(argv[i], "-dump_parse_module") == 0) {
-	dump_module |= STAGE1;
-	Swig_mark_arg(i);
-      } else if (strcmp(argv[i], "-dump_parse_top") == 0) {
-	dump_top |= STAGE1;
-	Swig_mark_arg(i);
-      } else if (strcmp(argv[i], "-dump_xml") == 0) {
-	dump_xml = 1;
-	Swig_mark_arg(i);
       } else if (strcmp(argv[i], "-xmlout") == 0) {
-	dump_xml = 1;
 	Swig_mark_arg(i);
 	if (argv[i + 1]) {
 	  xmlout = NewString(argv[i + 1]);
@@ -845,16 +828,13 @@
       } else if (strcmp(argv[i], "-nocontract") == 0) {
 	Swig_mark_arg(i);
 	Swig_contract_mode_set(0);
-      } else if (strcmp(argv[i], "-browse") == 0) {
-	browse = 1;
-	Swig_mark_arg(i);
-      } else if ((strcmp(argv[i], "-debug-typedef") == 0) || (strcmp(argv[i], "-dump_typedef") == 0)) {
+      } else if (strcmp(argv[i], "-debug-typedef") == 0) {
 	dump_typedef = 1;
 	Swig_mark_arg(i);
-      } else if ((strcmp(argv[i], "-debug-classes") == 0) || (strcmp(argv[i], "-dump_classes") == 0)) {
+      } else if (strcmp(argv[i], "-debug-classes") == 0) {
 	dump_classes = 1;
 	Swig_mark_arg(i);
-      } else if ((strcmp(argv[i], "-debug-memory") == 0) || (strcmp(argv[i], "-dump_memory") == 0)) {
+      } else if (strcmp(argv[i], "-debug-memory") == 0) {
 	memory_debug = 1;
 	Swig_mark_arg(i);
       } else if (strcmp(argv[i], "-Fstandard") == 0) {
@@ -879,9 +859,14 @@
   }
 }
 
+static void SWIG_exit_handler(int status);
+
 int SWIG_main(int argc, char *argv[], const TargetLanguageModule *tlm) {
   char *c;
 
+  /* Set function for Exit() to call. */
+  SetExitHandler(SWIG_exit_handler);
+
   /* Initialize the SWIG core */
   Swig_init();
 
@@ -895,31 +880,7 @@
   // can process options enough to handle -version, etc.
   lang = tlm ? tlm->fac() : new Language;
 
-  // Set up some default symbols (available in both SWIG interface files
-  // and C files)
-
-  Preprocessor_define((DOH *) "SWIG 1", 0);
-  Preprocessor_define((DOH *) "__STDC__", 0);
-
-  // Set the SWIG version value in format 0xAABBCC from package version expected to be in format A.B.C
-  String *package_version = NewString(PACKAGE_VERSION); /* Note that the fakeversion has not been set at this point */
-  char *token = strtok(Char(package_version), ".");
-  String *vers = NewString("SWIG_VERSION 0x");
-  int count = 0;
-  while (token) {
-    int len = (int)strlen(token);
-    assert(len == 1 || len == 2);
-    Printf(vers, "%s%s", (len == 1) ? "0" : "", token);
-    token = strtok(NULL, ".");
-    count++;
-  }
-  Delete(package_version);
-  assert(count == 3);		// Check version format is correct
-
-  /* Turn on contracts */
-
   Swig_contract_mode_set(1);
-  Preprocessor_define(vers, 0);
 
   /* Turn off directors mode */
   Wrapper_director_mode_set(0);
@@ -955,20 +916,14 @@
   libfiles = NewList();
   all_output_files = NewList();
 
-  /* Check for SWIG_FEATURES environment variable */
-
   getoptions(argc, argv);
 
-  // Define the __cplusplus symbol
-  if (CPlusPlus)
-    Preprocessor_define((DOH *) "__cplusplus __cplusplus", 0);
-
   // Parse language dependent options
   lang->main(argc, argv);
 
   if (help) {
     Printf(stdout, "\nNote: 'swig -<lang> -help' displays options for a specific target language.\n\n");
-    SWIG_exit(EXIT_SUCCESS);	// Exit if we're in help mode
+    Exit(EXIT_SUCCESS);	// Exit if we're in help mode
   }
 
   // Check all of the options to make sure we're cool.
@@ -977,10 +932,42 @@
 
   if (CPlusPlus && cparse_cplusplusout) {
     Printf(stderr, "The -c++out option is for C input but C++ input has been requested via -c++\n");
-    SWIG_exit(EXIT_FAILURE);
+    Exit(EXIT_FAILURE);
   }
 
-  install_opts(argc, argv);
+  // Set up some default symbols (available in both SWIG interface files
+  // and C files).  Define all predefined symbols after option parsing so
+  // that attempts to use `-U` to undefine them are consistently handled.
+
+  Preprocessor_define("SWIG 1", 0);
+  Preprocessor_define("__STDC__ 1", 0);
+
+  if (CPlusPlus) {
+    // Default to C++98.
+    if (!stdcpp_define) stdcpp_define = "__cplusplus 199711L";
+    Preprocessor_define(stdcpp_define, 0);
+  } else {
+    if (stdcpp_define) {
+      Printf(stderr, "Option -std=c++XX was used without -c++\n");
+      Exit(EXIT_FAILURE);
+    }
+  }
+
+  if (!CPlusPlus) {
+    // Default to C90 which didn't define __STDC_VERSION__.
+    if (stdc_define) {
+      Preprocessor_define(stdc_define, 0);
+    }
+  } else {
+    if (stdc_define) {
+      Printf(stderr, "Option -std=cXX was used with -c++\n");
+      Exit(EXIT_FAILURE);
+    }
+  }
+
+  String *vers = Swig_package_version_hex();
+  Preprocessor_define(vers, 0);
+  Delete(vers);
 
   // Add language dependent directory to the search path
   {
@@ -1042,7 +1029,7 @@
         File *f_outfile = NewFile(outfile, "w", SWIG_output_files());
         if (!f_outfile) {
           FileErrorDisplay(outfile);
-          SWIG_exit(EXIT_FAILURE);
+          Exit(EXIT_FAILURE);
         } else {
           if (Verbose)
             Printf(stdout, "'%s' checked out from the SWIG library.\n", outfile);
@@ -1061,25 +1048,20 @@
       String *fs = NewString("");
       FILE *df = Swig_open(input_file);
       if (!df) {
-	df = Swig_include_open(input_file);
-	if (!df) {
-	  char *cfile = Char(input_file);
-	  if (cfile && cfile[0] == '-') {
-	    Printf(stderr, "Unable to find option or file '%s', ", input_file);
-	    Printf(stderr, "Use 'swig -help' for more information.\n");
-	  } else {
-	    Printf(stderr, "Unable to find file '%s'.\n", input_file);
-	  }
-	  SWIG_exit(EXIT_FAILURE);
+	char *cfile = Char(input_file);
+	if (cfile && cfile[0] == '-') {
+	  Printf(stderr, "Unable to find option or file '%s', ", input_file);
+	  Printf(stderr, "Use 'swig -help' for more information.\n");
 	} else {
-	  Swig_warning(WARN_DEPRECATED_INPUT_FILE, "SWIG", 1, "Use of the include path to find the input file is deprecated and will not work with ccache. Please include the path when specifying the input file.\n"); // so that behaviour is like c/c++ compilers
+	  Printf(stderr, "Unable to find file '%s'.\n", input_file);
 	}
+	Exit(EXIT_FAILURE);
       }
 
       if (!tlm) {
 	Printf(stderr, "No target language specified.\n");
 	Printf(stderr, "Use 'swig -help' for more information.\n");
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
 
       if (!no_cpp) {
@@ -1103,11 +1085,11 @@
 	fclose(df);
       }
       if (Swig_error_count()) {
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       if (cpp_only) {
 	Printf(stdout, "%s", cpps);
-	SWIG_exit(EXIT_SUCCESS);
+	Exit(EXIT_SUCCESS);
       }
       if (depend) {
 	if (!no_cpp) {
@@ -1129,21 +1111,21 @@
 	    f_dependencies_file = NewFile(dependencies_file, "w", SWIG_output_files());
 	    if (!f_dependencies_file) {
 	      FileErrorDisplay(dependencies_file);
-	      SWIG_exit(EXIT_FAILURE);
+	      Exit(EXIT_FAILURE);
 	    }
 	  } else if (!depend_only) {
 	    String *filename = NewStringf("%s_wrap.%s", basename, depends_extension);
 	    f_dependencies_file = NewFile(filename, "w", SWIG_output_files());
 	    if (!f_dependencies_file) {
 	      FileErrorDisplay(filename);
-	      SWIG_exit(EXIT_FAILURE);
+	      Exit(EXIT_FAILURE);
 	    }
 	  } else
 	    f_dependencies_file = stdout;
 	  if (dependencies_target) {
-	    Printf(f_dependencies_file, "%s: ", dependencies_target);
+	    Printf(f_dependencies_file, "%s: ", Swig_filename_escape_space(dependencies_target));
 	  } else {
-	    Printf(f_dependencies_file, "%s: ", outfile);
+	    Printf(f_dependencies_file, "%s: ", Swig_filename_escape_space(outfile));
 	  }
 	  List *files = Preprocessor_depend();
 	  List *phony_targets = NewList();
@@ -1154,7 +1136,7 @@
                 use_file = 0;
             }
             if (use_file) {
-              Printf(f_dependencies_file, "\\\n  %s ", Getitem(files, i));
+              Printf(f_dependencies_file, "\\\n  %s ", Swig_filename_escape_space(Getitem(files, i)));
               if (depend_phony)
                 Append(phony_targets, Getitem(files, i));
             }
@@ -1162,21 +1144,21 @@
 	  Printf(f_dependencies_file, "\n");
 	  if (depend_phony) {
 	    for (int i = 0; i < Len(phony_targets); i++) {
-	      Printf(f_dependencies_file, "\n%s:\n", Getitem(phony_targets, i));
+	      Printf(f_dependencies_file, "\n%s:\n", Swig_filename_escape_space(Getitem(phony_targets, i)));
 	    }
 	  }
 
 	  if (f_dependencies_file != stdout)
 	    Delete(f_dependencies_file);
 	  if (depend_only)
-	    SWIG_exit(EXIT_SUCCESS);
+	    Exit(EXIT_SUCCESS);
 	  Delete(inputfile_filename);
 	  Delete(basename);
 	  Delete(phony_targets);
 	} else {
 	  Printf(stderr, "Cannot generate dependencies with -nopreprocess\n");
 	  // Actually we could but it would be inefficient when just generating dependencies, as it would be done after Swig_cparse
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	}
       }
       Seek(cpps, 0, SEEK_SET);
@@ -1281,13 +1263,13 @@
     if (top) {
       if (!Getattr(top, "name")) {
 	Printf(stderr, "No module name specified using %%module or -module.\n");
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       } else {
 	/* Set some filename information on the object */
 	String *infile = scanner_get_main_input_file();
 	if (!infile) {
 	  Printf(stderr, "Missing input file in preprocessed output.\n");
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	}
 	Setattr(top, "infile", infile); // Note: if nopreprocess then infile is the original input file, otherwise input_file
 	Setattr(top, "inputfile", input_file);
@@ -1319,15 +1301,12 @@
 	if (tlm->status == Experimental) {
 	  Swig_warning(WARN_LANG_EXPERIMENTAL, "SWIG", 1, "Experimental target language. "
 	    "Target language %s specified by %s is an experimental language. "
-	    "Please read about SWIG experimental languages, http://swig.org/Doc4.0/Introduction.html#Introduction_experimental_status.\n",
+	    "Please read about SWIG experimental languages, https://swig.org/Doc4.0/Introduction.html#Introduction_experimental_status.\n",
 	    tlm->help ? tlm->help : "", tlm->name);
 	}
 
 	lang->top(top);
 
-	if (browse) {
-	  Swig_browser(top, 0);
-	}
 	Delete(infile_filename);
 	Delete(basename);
       }
@@ -1343,7 +1322,7 @@
       Printf(stdout, "debug-module stage 4\n");
       Swig_print_tree(Getattr(top, "module"));
     }
-    if (dump_xml && top) {
+    if (xmlout && top) {
       delete lang;
       lang = 0;
       Swig_print_xml(top, xmlout);
@@ -1361,7 +1340,7 @@
     if (!f_outfiles) {
       Printf(stderr, "Failed to write list of output files to the filename '%s' specified in CCACHE_OUTFILES environment variable - ", outfiles);
       FileErrorDisplay(outfiles);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     } else {
       int i;
       for (i = 0; i < Len(all_output_files); i++)
@@ -1383,22 +1362,22 @@
   error_count += Swig_error_count();
 
   if (error_count != 0)
-    SWIG_exit(error_count);
+    Exit(EXIT_FAILURE);
 
   return 0;
 }
 
 /* -----------------------------------------------------------------------------
- * SWIG_exit()
+ * SWIG_exit_handler()
  *
  * Cleanup and either freeze or exit
  * ----------------------------------------------------------------------------- */
 
-void SWIG_exit(int exit_code) {
+static void SWIG_exit_handler(int status) {
   while (freeze) {
   }
 
-  if (exit_code > 0) {
+  if (status > 0) {
     CloseAllOpenFiles();
 
     /* Remove all generated files */
@@ -1411,6 +1390,4 @@
       }
     }
   }
-
-  exit(exit_code);
 }
diff --git a/Source/Modules/modula3.cxx b/Source/Modules/modula3.cxx
deleted file mode 100644
index c606845..0000000
--- a/Source/Modules/modula3.cxx
+++ /dev/null
@@ -1,3931 +0,0 @@
-/* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3 
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
- *
- * modula3.cxx
- *
- * Modula3 language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-/*
-  Text formatted with
-    indent -sob -br -ce -nut -npsl
-*/
-
-/*
-  Report:
-   - It's not a good concept to use member variables or global variables
-     for passing parameters to functions.
-     It's not a good concept to use functions of superclasses for specific services.
-     E.g. For SWIG this means: Generating accessor functions for member variables
-     is the most common but no general task to be processed in membervariableHandler.
-     Better provide a service function which generates accessor function code
-     and equip this service function with all parameters needed for input (parse node)
-     and output (generated code).
-   - How can I make globalvariableHandler not to generate
-     interface functions to two accessor functions
-     (that don't exist) ?
-   - How can I generate a typemap that turns every C reference argument into
-     its Modula 3 counterpart, that is
-       void test(Complex &z);
-       PROCEDURE test(VAR z:Complex);
-   - neither $*n_mangle nor $*n_type nor $*n_ltype return the type without
-     pointer converted to Modula3 equivalent,
-     $*n_mangle is the variant closest to what I expect
-   - using a typemap like
-         typemap(m3wrapintype) int * %{VAR $1_name: INTEGER%}
-     has the advantages:
-       - one C parameter can be turned into multiple M3 parameters
-       - the argument can be renamed
-   - using typemaps like
-         typemap(m3wrapinmode) int * "VAR"
-         typemap(m3wrapintype) int * "INTEGER"
-     has the advantages:
-       - multiple parameters with same type and default value can be bundled
-       - more conform to the other language modules
-   - Where takes the reduction of multi-typemaps place?
-     How can I preserve all parameters for functions of the intermediary class?
-     The answer is Getattrs(n,"tmap:m3rawintype:next")
-   - Char() can be used to transform a String to (char *)
-     which can be used for output with printf
-   - What is the while (checkAttribute()) loop in functionWrapper good for?
-     Appearently for skipping (numinputs=0) typemaps.
-   - SWIGTYPE const * - typemap is ignored, whereas
-     SWIGTYPE *       - typemap is invoked, why?
-     Had it been (const SWIGTYPE *) instead?
-   - enumeration items should definitely be equipped
-     with its plain numerical value
-     One could add tag 'numvalue' in CParse/parser.y,
-     but it is still possible that someone declares an
-     enumeration using a symbolic constant.
-     I have quickly hacked
-     that the successive number is assigned
-     if "enumvalue" has suffix "+1".
-     The ultimate solution would be to generate a C program
-     which includes the header and outputs all constants.
-     This program might be compiled and run
-     by 'make' or by SWIG and the resulting output is fed back to SWIG.
-   - It's a bad idea to interpret feature value ""
-     'disable feature' because the value ""
-     might be sensible in case of feature:modula3:oldprefix.
-   - What's the difference between "sym:name" and "name" ?
-     "name" is the original name and
-     "sym:name" is probably modified by the user using %rename
-   - Is it possible for 'configure' to find out if m3pp is installed
-     and to invoke it for generated Modula3 files?
-   - It would be better to separate an arguments purpose and its name,
-     because an output variable with name "OUTPUT" is not very descriptive.
-     In case of PLPlot this could be solved by typedefs
-     that assign special purposes to the array types.
-   - Can one interpret $n_basetype as the identifier matched with SWIGTYPE ?
-
-  SWIG's odds:
-   - arguments of type (Node *) for SWIG functions
-     should be most often better (const Node *):
-     Swig_symbol_qualified, Getattr, nodeType, parentNode
-   - unique identifier style instead of
-     NewString, Getattr, firstChild
-   - 'class'.name is qualified,
-     'enum'.name and 'enumitem'.name is not
-   - Swig_symbol_qualified() returns NIL for enumeration nodes
-
-   - Is there a function that creates a C representation of a SWIG type string?
-
-  ToDo:
-   - create WeakRefs only for resources returned by function marked with %newobject
-      -> part of output conversion
-   - clean typemap conception
-      - should a multi-typemap for m3wrapouttype skip the corresponding input parameters?
-        when yes - How to handle inout-arguments? In this case like in-argument.
-   - C++ classes
-   - C++ exceptions
-   - allow for moving RECORD and OBJECT definitions
-     to separate files, with the main type called T
-   - call-back functions
-   - special option: fast access to class members by pointer arithmetic,
-       member offsets can be determined by a C++ program that print them.
-   - emit enumeration definitions when its first item is declared,
-       currently enumerations are emitted at the beginning of the file
-
-  Done:
-   - addThrow should convert the typemap by itself
-      - not possible because routine for attaching mapped types to parameter nodes
-        won't work for the function node
-   - turning error codes into exceptions
-      -> part of output value checking
-   - create WeakRefs for resources allocated by the library
-      -> part of output conversion
-   - TRY..FINALLY..END; can be omitted
-      - if there is no m3wrapfreearg
-      - no exception can be raised in the body (empty RAISES) list
-*/
-
-#include "swigmod.h"
-
-#include <limits.h>		// for INT_MAX
-#include <ctype.h>
-
-#define USAGE_ARG_DIR "m3wrapargdir typemap expect values: in, out, inout\n"
-
-class MODULA3:public Language {
-public:
-  enum block_type { no_block, constant, variable, blocktype, revelation };
-
-private:
-  struct M3File {
-    String *f;
-    Hash *import;
-    block_type bt;
-    /* VC++ 6 doesn't allow the access to 'no_block'
-       if it is a private member of MODULA3 class */
-    M3File():f(NewString("")), import(NewHash()), bt(no_block) {
-    }
-    ~M3File() {
-      Delete(f);
-      Delete(import);
-    }
-
-    /* -----------------------------------------------------------------------------
-     * enterBlock()
-     *
-     * Make sure that a given declaration is written to the right declaration block,
-     * that is constants are written after "CONST" and so on ...
-     * ----------------------------------------------------------------------------- */
-    void enterBlock(block_type newbt) {
-      static const char *ident[] = { "", "\nCONST\n", "\nVAR\n", "\nTYPE\n", "\nREVEAL\n" };
-#ifdef DEBUG
-      if ((bt < 0) || (4 < bt)) {
-	printf("bt %d out of range\n", bt);
-      }
-#endif
-      if (newbt != bt) {
-	Append(f, ident[newbt]);
-	bt = newbt;
-      }
-    }
-
-  };
-
-  static const char *usage;
-  const String *empty_string;
-
-  Hash *swig_types_hash;
-  File *f_begin;
-  File *f_runtime;
-  File *f_header;
-  File *f_wrappers;
-  File *f_init;
-
-  bool proxy_flag;		// Flag for generating proxy classes
-  bool have_default_constructor_flag;
-  bool native_function_flag;	// Flag for when wrapping a native function
-  bool enum_constant_flag;	// Flag for when wrapping an enum or constant
-  bool static_flag;		// Flag for when wrapping a static functions or member variables
-  bool variable_wrapper_flag;	// Flag for when wrapping a nonstatic member variable
-  bool wrapping_member_flag;	// Flag for when wrapping a member variable/enum/const
-  bool global_variable_flag;	// Flag for when wrapping a global variable
-  bool old_variable_names;	// Flag for old style variable names in the intermediary class
-  bool unsafe_module;
-
-  String *m3raw_name;		// raw interface name
-  M3File m3raw_intf;		// raw interface
-  M3File m3raw_impl;		// raw implementation (usually empty)
-  String *m3wrap_name;		// wrapper module
-  M3File m3wrap_intf;
-  M3File m3wrap_impl;
-  String *m3makefile;
-  String *targetlibrary;
-  String *proxy_class_def;
-  String *proxy_class_code;
-  String *proxy_class_name;
-  String *variable_name;	//Name of a variable being wrapped
-  String *variable_type;	//Type of this variable
-  Hash *enumeration_coll;	//Collection of all enumerations.
-  /* The items are nodes with members:
-     "items"  - hash of with key 'itemname' and content 'itemvalue'
-     "max"    - maximum value in item list
-   */
-  String *constant_values;
-  String *constantfilename;
-  String *renamefilename;
-  String *typemapfilename;
-  String *m3raw_imports;	//intermediary class imports from %pragma
-  String *module_imports;	//module imports from %pragma
-  String *m3raw_baseclass;	//inheritance for intermediary class class from %pragma
-  String *module_baseclass;	//inheritance for module class from %pragma
-  String *m3raw_interfaces;	//interfaces for intermediary class class from %pragma
-  String *module_interfaces;	//interfaces for module class from %pragma
-  String *m3raw_class_modifiers;	//class modifiers for intermediary class overridden by %pragma
-  String *m3wrap_modifiers;	//class modifiers for module class overridden by %pragma
-  String *upcasts_code;		//C++ casts for inheritance hierarchies C++ code
-  String *m3raw_cppcasts_code;	//C++ casts up inheritance hierarchies intermediary class code
-  String *destructor_call;	//C++ destructor call if any
-  String *outfile;
-
-  enum type_additions { none, pointer, reference };
-
-public:
-
-  /* -----------------------------------------------------------------------------
-   * MODULA3()
-   * ----------------------------------------------------------------------------- */
-
-MODULA3():
-  empty_string(NewString("")),
-      swig_types_hash(NULL),
-      f_begin(NULL),
-      f_runtime(NULL),
-      f_header(NULL),
-      f_wrappers(NULL),
-      f_init(NULL),
-      proxy_flag(true),
-      have_default_constructor_flag(false),
-      native_function_flag(false),
-      enum_constant_flag(false),
-      static_flag(false),
-      variable_wrapper_flag(false),
-      wrapping_member_flag(false),
-      global_variable_flag(false),
-      old_variable_names(false),
-      unsafe_module(false),
-      m3raw_name(NULL),
-      m3raw_intf(),
-      m3raw_impl(),
-      m3wrap_name(NULL),
-      m3wrap_intf(),
-      m3wrap_impl(),
-      m3makefile(NULL),
-      targetlibrary(NULL),
-      proxy_class_def(NULL),
-      proxy_class_code(NULL),
-      proxy_class_name(NULL),
-      variable_name(NULL),
-      variable_type(NULL),
-      enumeration_coll(NULL),
-      constant_values(NULL),
-      constantfilename(NULL),
-      renamefilename(NULL),
-      typemapfilename(NULL),
-      m3raw_imports(NULL),
-      module_imports(NULL),
-      m3raw_baseclass(NULL),
-      module_baseclass(NULL),
-      m3raw_interfaces(NULL),
-      module_interfaces(NULL),
-      m3raw_class_modifiers(NULL),
-      m3wrap_modifiers(NULL),
-      upcasts_code(NULL),
-      m3raw_cppcasts_code(NULL),
-      destructor_call(NULL),
-      outfile(NULL) {
-  }
-
-  /************** some utility functions ***************/
-
-  /* -----------------------------------------------------------------------------
-   * getMappedType()
-   *
-   * Return the type of 'p' mapped by 'map'.
-   * Print a standard warning if 'p' can't be mapped.
-   * ----------------------------------------------------------------------------- */
-
-  String *getMappedType(Node *p, const char *map) {
-    String *mapattr = NewString("tmap:");
-    Append(mapattr, map);
-
-    String *tm = Getattr(p, mapattr);
-    if (tm == NIL) {
-      Swig_warning(WARN_MODULA3_TYPEMAP_TYPE_UNDEF, input_file, line_number,
-		   "No '%s' typemap defined for type '%s'\n", map, SwigType_str(Getattr(p, "type"), 0));
-    }
-    Delete(mapattr);
-    return tm;
-  }
-
-  /* -----------------------------------------------------------------------------
-   * getMappedTypeNew()
-   *
-   * Similar to getMappedType but uses Swig_type_lookup_new.
-   * ----------------------------------------------------------------------------- */
-
-  String *getMappedTypeNew(Node *n, const char *map, const char *lname = "", bool warn = true) {
-    String *tm = Swig_typemap_lookup(map, n, lname, 0);
-    if ((tm == NIL) && warn) {
-      Swig_warning(WARN_MODULA3_TYPEMAP_TYPE_UNDEF, input_file, line_number,
-		   "No '%s' typemap defined for type '%s'\n", map, SwigType_str(Getattr(n, "type"), 0));
-    }
-    return tm;
-  }
-
-  /* -----------------------------------------------------------------------------
-   * attachMappedType()
-   *
-   * Obtain the type mapped by 'map' and attach it to the node
-   * ----------------------------------------------------------------------------- */
-
-  void attachMappedType(Node *n, const char *map, const char *lname = "") {
-    String *tm = Swig_typemap_lookup(map, n, lname, 0);
-    if (tm != NIL) {
-      String *attr = NewStringf("tmap:%s", map);
-      Setattr(n, attr, tm);
-      Delete(attr);
-    }
-  }
-
-  /* -----------------------------------------------------------------------------
-   * skipIgnored()
-   *
-   * Skip all parameters that have 'numinputs=0'
-   * with respect to a given typemap.
-   * ----------------------------------------------------------------------------- */
-
-  Node *skipIgnored(Node *p, const char *map) {
-    String *niattr = NewStringf("tmap:%s:numinputs", map);
-    String *nextattr = NewStringf("tmap:%s:next", map);
-
-    while ((p != NIL) && checkAttribute(p, niattr, "0")) {
-      p = Getattr(p, nextattr);
-    }
-
-    Delete(nextattr);
-    Delete(niattr);
-    return p;
-  }
-
-  /* -----------------------------------------------------------------------------
-   * isInParam()
-   * isOutParam()
-   *
-   * Check if the parameter is intended for input or for output.
-   * ----------------------------------------------------------------------------- */
-
-  bool isInParam(Node *p) {
-    String *dir = Getattr(p, "tmap:m3wrapargdir");
-//printf("dir for %s: %s\n", Char(Getattr(p,"name")), Char(dir));
-    if ((dir == NIL) || (Strcmp(dir, "in") == 0)
-	|| (Strcmp(dir, "inout") == 0)) {
-      return true;
-    } else if (Strcmp(dir, "out") == 0) {
-      return false;
-    } else {
-      printf("%s", USAGE_ARG_DIR);
-      return false;
-    }
-  }
-
-  bool isOutParam(Node *p) {
-    String *dir = Getattr(p, "tmap:m3wrapargdir");
-    if ((dir == NIL) || (Strcmp(dir, "in") == 0)) {
-      return false;
-    } else if ((Strcmp(dir, "out") == 0) || (Strcmp(dir, "inout") == 0)) {
-      return true;
-    } else {
-      printf("%s", USAGE_ARG_DIR);
-      return false;
-    }
-  }
-
-  /* -----------------------------------------------------------------------------
-   * printAttrs()
-   *
-   * For debugging: Show all attributes of a node and their values.
-   * ----------------------------------------------------------------------------- */
-  void printAttrs(Node *n) {
-    Iterator it;
-    for (it = First(n); it.key != NIL; it = Next(it)) {
-      printf("%s = %s\n", Char(it.key), Char(Getattr(n, it.key)));
-    }
-  }
-
-  /* -----------------------------------------------------------------------------
-   * hasPrefix()
-   *
-   * Check if a string have a given prefix.
-   * ----------------------------------------------------------------------------- */
-  bool hasPrefix(const String *str, const String *prefix) {
-    int len_prefix = Len(prefix);
-    return (Len(str) > len_prefix)
-	&& (Strncmp(str, prefix, len_prefix) == 0);
-  }
-
-  /* -----------------------------------------------------------------------------
-   * getQualifiedName()
-   *
-   * Return fully qualified identifier of n.
-   * ----------------------------------------------------------------------------- */
-#if 0
-  // Swig_symbol_qualified returns NIL for enumeration nodes
-  String *getQualifiedName(Node *n) {
-    String *qual = Swig_symbol_qualified(n);
-    String *name = Getattr(n, "name");
-    if (hasContent(qual)) {
-      return NewStringf("%s::%s", qual, name);
-    } else {
-      return name;
-    }
-  }
-#else
-  String *getQualifiedName(Node *n) {
-    String *name = Copy(Getattr(n, "name"));
-    n = parentNode(n);
-    while (n != NIL) {
-      const String *type = nodeType(n);
-      if ((Strcmp(type, "class") == 0) || (Strcmp(type, "struct") == 0) || (Strcmp(type, "namespace") == 0)) {
-	String *newname = NewStringf("%s::%s", Getattr(n, "name"), name);
-	Delete(name);
-	//name = newname;
-	// Hmpf, the class name is already qualified.
-	return newname;
-      }
-      n = parentNode(n);
-    }
-    //printf("qualified name: %s\n", Char(name));
-    return name;
-  }
-#endif
-
-  /* -----------------------------------------------------------------------------
-   * nameToModula3()
-   *
-   * Turn usual C identifiers like "this_is_an_identifier"
-   * into usual Modula 3 identifier like "thisIsAnIdentifier"
-   * ----------------------------------------------------------------------------- */
-  String *nameToModula3(const String *sym, bool leadingCap) {
-    int len_sym = Len(sym);
-    char *csym = Char(sym);
-    char *m3sym = new char[len_sym + 1];
-    int i, j;
-    bool cap = leadingCap;
-    for (i = 0, j = 0; j < len_sym; j++) {
-      char c = csym[j];
-      if ((c == '_') || (c == ':')) {
-	cap = true;
-      } else {
-	if (isdigit(c)) {
-	  m3sym[i] = c;
-	  cap = true;
-	} else {
-	  if (cap) {
-	    m3sym[i] = (char)toupper(c);
-	  } else {
-	    m3sym[i] = (char)tolower(c);
-	  }
-	  cap = false;
-	}
-	i++;
-      }
-    }
-    m3sym[i] = 0;
-    String *result = NewString(m3sym);
-    delete[]m3sym;
-    return result;
-  }
-
-  /* -----------------------------------------------------------------------------
-   * capitalizeFirst()
-   *
-   * Make the first character upper case.
-   * ----------------------------------------------------------------------------- */
-  String *capitalizeFirst(const String *str) {
-    return NewStringf("%c%s", toupper(*Char(str)), Char(str) + 1);
-  }
-
-  /* -----------------------------------------------------------------------------
-   * prefixedNameToModula3()
-   *
-   * If feature modula3:oldprefix and modula3:newprefix is present
-   * and the C identifier has leading 'oldprefix'
-   * then it is replaced by the 'newprefix'.
-   * The rest is converted to Modula style.
-   * ----------------------------------------------------------------------------- */
-  String *prefixedNameToModula3(Node *n, const String *sym, bool leadingCap) {
-    String *oldPrefix = Getattr(n, "feature:modula3:oldprefix");
-    String *newPrefix = Getattr(n, "feature:modula3:newprefix");
-    String *result = NewString("");
-    char *short_sym = Char(sym);
-    // if at least one prefix feature is present
-    // the replacement takes place
-    if ((oldPrefix != NIL) || (newPrefix != NIL)) {
-      if ((oldPrefix == NIL) || hasPrefix(sym, oldPrefix)) {
-	short_sym += Len(oldPrefix);
-	if (newPrefix != NIL) {
-	  Append(result, newPrefix);
-	}
-      }
-    }
-    String *suffix = nameToModula3(short_sym, leadingCap || hasContent(newPrefix));
-    Append(result, suffix);
-    Delete(suffix);
-    return result;
-  }
-
-  /* -----------------------------------------------------------------------------
-   * hasContent()
-   *
-   * Check if the string exists and contains something.
-   * ----------------------------------------------------------------------------- */
-  bool hasContent(const String *str) {
-    return (str != NIL) && (Strcmp(str, "") != 0);
-  }
-
-  /* -----------------------------------------------------------------------------
-   * openWriteFile()
-   *
-   * Caution: The file must be freshly allocated and will be destroyed
-   *          by this routine.
-   * ----------------------------------------------------------------------------- */
-
-  File *openWriteFile(String *name) {
-    File *file = NewFile(name, "w", SWIG_output_files());
-    if (!file) {
-      FileErrorDisplay(name);
-      SWIG_exit(EXIT_FAILURE);
-    }
-    Delete(name);
-    return file;
-  }
-
-  /* -----------------------------------------------------------------------------
-   * aToL()
-   *
-   * like atol but with additional user warning
-   * ----------------------------------------------------------------------------- */
-
-  long aToL(const String *value) {
-    char *endptr;
-    long numvalue = strtol(Char(value), &endptr, 0);
-    if (*endptr != 0) {
-      Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "The string <%s> does not denote a numeric value.\n", value);
-    }
-    return numvalue;
-  }
-
-  /* -----------------------------------------------------------------------------
-   * strToL()
-   *
-   * like strtol but returns if the conversion was successful
-   * ----------------------------------------------------------------------------- */
-
-  bool strToL(const String *value, long &numvalue) {
-    char *endptr;
-    numvalue = strtol(Char(value), &endptr, 0);
-    return (*endptr == 0);
-  }
-
-  /* -----------------------------------------------------------------------------
-   * evalExpr()
-   *
-   * Evaluate simple expression as they may occur in "enumvalue" attributes.
-   * ----------------------------------------------------------------------------- */
-
-  bool evalExpr(String *value, long &numvalue) {
-    // Split changes file status of String and thus cannot receive 'const' strings
-//printf("evaluate <%s>\n", Char(value));
-    List *summands = Split(value, '+', INT_MAX);
-    Iterator sm = First(summands);
-    numvalue = 0;
-    for (; sm.item != NIL; sm = Next(sm)) {
-      String *smvalue = Getattr(constant_values, sm.item);
-      long smnumvalue;
-      if (smvalue != NIL) {
-	if (!strToL(smvalue, smnumvalue)) {
-//printf("evaluation: abort 0 <%s>\n", Char(smvalue));
-	  return false;
-	}
-      } else {
-	if (!strToL(sm.item, smnumvalue)) {
-//printf("evaluation: abort 1 <%s>\n", Char(sm));
-	  return false;
-	}
-      }
-      numvalue += smnumvalue;
-    }
-//printf("evaluation: return %ld\n", numvalue);
-    return true;
-  }
-
-  /* -----------------------------------------------------------------------------
-   * log2()
-   *
-   * Determine the position of the single bit of a power of two.
-   * Returns true if the given number is a power of two.
-   * ----------------------------------------------------------------------------- */
-
-  bool log2(long n, long &exp) {
-    exp = 0;
-    while (n > 0) {
-      if ((n & 1) != 0) {
-	return n == 1;
-      }
-      exp++;
-      n >>= 1;
-    }
-    return false;
-  }
-
-  /* -----------------------------------------------------------------------------
-   * writeArg
-   *
-   * Write a function argument or RECORD entry definition.
-   * Bundles arguments of same type and default value.
-   * 'name.next==NIL' denotes the end of the entry or argument list.
-   * ----------------------------------------------------------------------------- */
-
-  bool equalNilStr(const String *str0, const String *str1) {
-    if (str0 == NIL) {
-      return (str1 == NIL);
-      //return (str0==NIL) == (str1==NIL);
-    } else {
-      return (str1 != NIL) && (Cmp(str0, str1) == 0);
-      //return Cmp(str0,str1)==0;
-    }
-  }
-
-  struct writeArgState {
-    String *mode, *name, *type, *value;
-    bool hold;
-     writeArgState():mode(NIL), name(NIL), type(NIL), value(NIL), hold(false) {
-    }
-  };
-
-  void writeArg(File *f, writeArgState & state, String *mode, String *name, String *type, String *value) {
-    /* skip the first argument,
-       only store the information for the next call in this case */
-    if (state.name != NIL) {
-      if ((!state.hold) && (state.mode != NIL)) {
-	Printf(f, "%s ", state.mode);
-      }
-      if ((name != NIL) && equalNilStr(state.mode, mode) && equalNilStr(state.type, type) && (state.value == NIL) && (value == NIL)
-	  /* the same expression may have different values
-	     due to side effects of the called function */
-	  /*equalNilStr(state.value,value) */
-	  ) {
-	Printf(f, "%s, ", state.name);
-	state.hold = true;
-      } else {
-	Append(f, state.name);
-	if (state.type != NIL) {
-	  Printf(f, ": %s", state.type);
-	}
-	if (state.value != NIL) {
-	  Printf(f, ":= %s", state.value);
-	}
-	Append(f, ";\n");
-	state.hold = false;
-      }
-    }
-    /* at the next call the current argument will be the previous one */
-    state.mode = mode;
-    state.name = name;
-    state.type = type;
-    state.value = value;
-  }
-
-  /* -----------------------------------------------------------------------------
-   * getProxyName()
-   *
-   * Test to see if a type corresponds to something wrapped with a proxy class
-   * Return NULL if not otherwise the proxy class name
-   * ----------------------------------------------------------------------------- */
-
-  String *getProxyName(SwigType *t) {
-    if (proxy_flag) {
-      Node *n = classLookup(t);
-      if (n) {
-	return Getattr(n, "sym:name");
-      }
-    }
-    return NULL;
-  }
-
-  /*************** language processing ********************/
-
-  /* ------------------------------------------------------------
-   * main()
-   * ------------------------------------------------------------ */
-
-  virtual void main(int argc, char *argv[]) {
-
-    SWIG_library_directory("modula3");
-
-    // Look for certain command line options
-    for (int i = 1; i < argc; i++) {
-      if (argv[i]) {
-	if (strcmp(argv[i], "-generateconst") == 0) {
-	  if (argv[i + 1]) {
-	    constantfilename = NewString(argv[i + 1]);
-	    Swig_mark_arg(i);
-	    Swig_mark_arg(i + 1);
-	    i++;
-	  } else {
-	    Swig_arg_error();
-	  }
-	} else if (strcmp(argv[i], "-generaterename") == 0) {
-	  if (argv[i + 1]) {
-	    renamefilename = NewString(argv[i + 1]);
-	    Swig_mark_arg(i);
-	    Swig_mark_arg(i + 1);
-	    i++;
-	  } else {
-	    Swig_arg_error();
-	  }
-	} else if (strcmp(argv[i], "-generatetypemap") == 0) {
-	  if (argv[i + 1]) {
-	    typemapfilename = NewString(argv[i + 1]);
-	    Swig_mark_arg(i);
-	    Swig_mark_arg(i + 1);
-	    i++;
-	  } else {
-	    Swig_arg_error();
-	  }
-	} else if (strcmp(argv[i], "-noproxy") == 0) {
-	  Swig_mark_arg(i);
-	  proxy_flag = false;
-	} else if (strcmp(argv[i], "-oldvarnames") == 0) {
-	  Swig_mark_arg(i);
-	  old_variable_names = true;
-	} else if (strcmp(argv[i], "-help") == 0) {
-	  Printf(stdout, "%s\n", usage);
-	}
-      }
-    }
-
-    // Add a symbol to the parser for conditional compilation
-    Preprocessor_define("SWIGMODULA3 1", 0);
-
-    // Add typemap definitions
-    SWIG_typemap_lang("modula3");
-    SWIG_config_file("modula3.swg");
-
-    allow_overloading();
-  }
-
-  /* ---------------------------------------------------------------------
-   * top()
-   * --------------------------------------------------------------------- */
-
-  virtual int top(Node *n) {
-    if (hasContent(constantfilename) || hasContent(renamefilename) || hasContent(typemapfilename)) {
-      int result = SWIG_OK;
-      if (hasContent(constantfilename)) {
-	result = generateConstantTop(n) && result;
-      }
-      if (hasContent(renamefilename)) {
-	result = generateRenameTop(n) && result;
-      }
-      if (hasContent(typemapfilename)) {
-	result = generateTypemapTop(n) && result;
-      }
-      return result;
-    } else {
-      return generateM3Top(n);
-    }
-  }
-
-  void scanConstant(File *file, Node *n) {
-    Node *child = firstChild(n);
-    while (child != NIL) {
-      String *constname = NIL;
-      String *type = nodeType(child);
-      if ((Strcmp(type, "enumitem") == 0)
-	  || (Strcmp(type, "constant") == 0)) {
-#if 1
-	constname = getQualifiedName(child);
-#else
-	constname = Getattr(child, "value");
-	if ((!hasContent(constname))
-	    || (('0' <= *Char(constname)) && (*Char(constname) <= '9'))) {
-	  constname = Getattr(child, "name");
-	}
-#endif
-      }
-      if (constname != NIL) {
-	Printf(file, "  printf(\"%%%%constnumeric(%%Lg) %s;\\n\", (long double)%s);\n", constname, constname);
-      }
-      scanConstant(file, child);
-      child = nextSibling(child);
-    }
-  }
-
-  int generateConstantTop(Node *n) {
-    File *file = openWriteFile(NewStringf("%s.c", constantfilename));
-    if (CPlusPlus) {
-      Printf(file, "#include <cstdio>\n");
-    } else {
-      Printf(file, "#include <stdio.h>\n");
-    }
-    Printf(file, "#include \"%s\"\n", input_file);
-    Printf(file, "\n");
-    Printf(file, "int main (int argc, char *argv[]) {\n");
-    Printf(file, "\
-/*This program must work for floating point numbers and integers.\n\
-  Thus all numbers are converted to double precision floating point format.*/\n");
-    scanConstant(file, n);
-    Printf(file, "  return 0;\n");
-    Printf(file, "}\n");
-    Delete(file);
-    return SWIG_OK;
-  }
-
-  void scanRename(File *file, Node *n) {
-    Node *child = firstChild(n);
-    while (child != NIL) {
-      String *type = nodeType(child);
-      if (Strcmp(type, "cdecl") == 0) {
-	ParmList *p = Getattr(child, "parms");
-	if (p != NIL) {
-	  String *name = getQualifiedName(child);
-	  String *m3name = nameToModula3(name, true);
-	  /*don't know how to get the original C type identifiers */
-	  //String *arguments = createCSignature (child);
-	  Printf(file, "%%rename(\"%s\") %s;\n", m3name, name);
-	  /*Printf(file, "%%rename(\"%s\") %s %s(%s);\n",
-	     m3name, Getattr(n,"type"), name, arguments); */
-	  Delete(name);
-	  Delete(m3name);
-	  //Delete (arguments);
-	}
-      }
-      scanRename(file, child);
-      child = nextSibling(child);
-    }
-  }
-
-  int generateRenameTop(Node *n) {
-    File *file = openWriteFile(NewStringf("%s.i", renamefilename));
-    Printf(file, "\
-/* This file was generated from %s\n\
-   by SWIG with option -generaterename. */\n\
-\n", input_file);
-    scanRename(file, n);
-    Delete(file);
-    return SWIG_OK;
-  }
-
-  void scanTypemap(File *file, Node *n) {
-    Node *child = firstChild(n);
-    while (child != NIL) {
-      String *type = nodeType(child);
-      //printf("nodetype %s\n", Char(type));
-      String *storage = Getattr(child, "storage");
-      if ((Strcmp(type, "class") == 0) || ((Strcmp(type, "cdecl") == 0) && (storage != NIL)
-					   && (Strcmp(storage, "typedef") == 0))) {
-	String *name = getQualifiedName(child);
-	String *m3name = nameToModula3(name, true);
-	Printf(file, "%%typemap(\"m3wrapintype\") %s %%{%s%%}\n", name, m3name);
-	Printf(file, "%%typemap(\"m3rawintype\") %s %%{%s%%}\n", name, m3name);
-	Printf(file, "\n");
-      }
-      scanTypemap(file, child);
-      child = nextSibling(child);
-    }
-  }
-
-  int generateTypemapTop(Node *n) {
-    File *file = openWriteFile(NewStringf("%s.i", typemapfilename));
-    Printf(file, "\
-/* This file was generated from %s\n\
-   by SWIG with option -generatetypemap. */\n\
-\n", input_file);
-    scanTypemap(file, n);
-    Delete(file);
-    return SWIG_OK;
-  }
-
-  int generateM3Top(Node *n) {
-    /* Initialize all of the output files */
-    outfile = Getattr(n, "outfile");
-
-    f_begin = NewFile(outfile, "w", SWIG_output_files());
-    if (!f_begin) {
-      FileErrorDisplay(outfile);
-      SWIG_exit(EXIT_FAILURE);
-    }
-    f_runtime = NewString("");
-    f_init = NewString("");
-    f_header = NewString("");
-    f_wrappers = NewString("");
-
-    m3makefile = NewString("");
-
-    /* Register file targets with the SWIG file handler */
-    Swig_register_filebyname("header", f_header);
-    Swig_register_filebyname("wrapper", f_wrappers);
-    Swig_register_filebyname("begin", f_begin);
-    Swig_register_filebyname("runtime", f_runtime);
-    Swig_register_filebyname("init", f_init);
-
-    Swig_register_filebyname("m3rawintf", m3raw_intf.f);
-    Swig_register_filebyname("m3rawimpl", m3raw_impl.f);
-    Swig_register_filebyname("m3wrapintf", m3wrap_intf.f);
-    Swig_register_filebyname("m3wrapimpl", m3wrap_impl.f);
-    Swig_register_filebyname("m3makefile", m3makefile);
-
-    swig_types_hash = NewHash();
-
-    String *name = Getattr(n, "name");
-    // Make the intermediary class and module class names. The intermediary class name can be set in the module directive.
-    Node *optionsnode = Getattr(Getattr(n, "module"), "options");
-    if (optionsnode != NIL) {
-      String *m3raw_name_tmp = Getattr(optionsnode, "m3rawname");
-      if (m3raw_name_tmp != NIL) {
-	m3raw_name = Copy(m3raw_name_tmp);
-      }
-    }
-    if (m3raw_name == NIL) {
-      m3raw_name = NewStringf("%sRaw", name);
-    }
-    Setattr(m3wrap_impl.import, m3raw_name, "");
-
-    m3wrap_name = Copy(name);
-
-    proxy_class_def = NewString("");
-    proxy_class_code = NewString("");
-    m3raw_baseclass = NewString("");
-    m3raw_interfaces = NewString("");
-    m3raw_class_modifiers = NewString("");	// package access only to the intermediary class by default
-    m3raw_imports = NewString("");
-    m3raw_cppcasts_code = NewString("");
-    m3wrap_modifiers = NewString("public");
-    module_baseclass = NewString("");
-    module_interfaces = NewString("");
-    module_imports = NewString("");
-    upcasts_code = NewString("");
-
-    Swig_banner(f_begin);
-
-    Printf(f_runtime, "\n\n#ifndef SWIGMODULA3\n#define SWIGMODULA3\n#endif\n\n");
-
-    Swig_name_register("wrapper", "Modula3_%f");
-    if (old_variable_names) {
-      Swig_name_register("set", "set_%n%v");
-      Swig_name_register("get", "get_%n%v");
-    }
-
-    Printf(f_wrappers, "\n#ifdef __cplusplus\n");
-    Printf(f_wrappers, "extern \"C\" {\n");
-    Printf(f_wrappers, "#endif\n\n");
-
-    constant_values = NewHash();
-    scanForConstPragmas(n);
-    enumeration_coll = NewHash();
-    collectEnumerations(enumeration_coll, n);
-
-    /* Emit code */
-    Language::top(n);
-
-    // Generate m3makefile
-    // This will be unnecessary if SWIG is invoked from Quake.
-    {
-      File *file = openWriteFile(NewStringf("%sm3makefile", SWIG_output_directory()));
-
-      Printf(file, "%% automatically generated quake file for %s\n\n", name);
-
-      /* Write the fragments written by '%insert'
-         collected while 'top' processed the parse tree */
-      Printv(file, m3makefile, NIL);
-
-      Printf(file, "import(\"libm3\")\n");
-      //Printf(file, "import_lib(\"%s\",\"/usr/lib\")\n", name);
-      Printf(file, "module(\"%s\")\n", m3raw_name);
-      Printf(file, "module(\"%s\")\n\n", m3wrap_name);
-
-      if (targetlibrary != NIL) {
-	Printf(file, "library(\"%s\")\n", targetlibrary);
-      } else {
-	Printf(file, "library(\"m3%s\")\n", name);
-      }
-      Delete(file);
-    }
-
-    // Generate the raw interface
-    {
-      File *file = openWriteFile(NewStringf("%s%s.i3", SWIG_output_directory(), m3raw_name));
-
-      emitBanner(file);
-
-      Printf(file, "INTERFACE %s;\n\n", m3raw_name);
-
-      emitImportStatements(m3raw_intf.import, file);
-      Printf(file, "\n");
-
-      // Write the interface generated within 'top'
-      Printv(file, m3raw_intf.f, NIL);
-
-      Printf(file, "\nEND %s.\n", m3raw_name);
-      Delete(file);
-    }
-
-    // Generate the raw module
-    {
-      File *file = openWriteFile(NewStringf("%s%s.m3", SWIG_output_directory(), m3raw_name));
-
-      emitBanner(file);
-
-      Printf(file, "MODULE %s;\n\n", m3raw_name);
-
-      emitImportStatements(m3raw_impl.import, file);
-      Printf(file, "\n");
-
-      // will be empty usually
-      Printv(file, m3raw_impl.f, NIL);
-
-      Printf(file, "BEGIN\nEND %s.\n", m3raw_name);
-      Delete(file);
-    }
-
-    // Generate the interface for the comfort wrappers
-    {
-      File *file = openWriteFile(NewStringf("%s%s.i3", SWIG_output_directory(), m3wrap_name));
-
-      emitBanner(file);
-
-      Printf(file, "INTERFACE %s;\n", m3wrap_name);
-
-      emitImportStatements(m3wrap_intf.import, file);
-      Printf(file, "\n");
-
-      {
-	Iterator it = First(enumeration_coll);
-	if (it.key != NIL) {
-	  Printf(file, "TYPE\n");
-	}
-	for (; it.key != NIL; it = Next(it)) {
-	  Printf(file, "\n");
-	  emitEnumeration(file, it.key, it.item);
-	}
-      }
-
-      // Add the wrapper methods
-      Printv(file, m3wrap_intf.f, NIL);
-
-      // Finish off the class
-      Printf(file, "\nEND %s.\n", m3wrap_name);
-      Delete(file);
-    }
-
-    // Generate the wrapper routines implemented in Modula 3
-    {
-      File *file = openWriteFile(NewStringf("%s%s.m3", SWIG_output_directory(), m3wrap_name));
-
-      emitBanner(file);
-
-      if (unsafe_module) {
-	Printf(file, "UNSAFE ");
-      }
-      Printf(file, "MODULE %s;\n\n", m3wrap_name);
-
-      emitImportStatements(m3wrap_impl.import, file);
-      Printf(file, "\n");
-
-      // Add the wrapper methods
-      Printv(file, m3wrap_impl.f, NIL);
-
-      Printf(file, "\nBEGIN\nEND %s.\n", m3wrap_name);
-      Delete(file);
-    }
-
-    if (upcasts_code)
-      Printv(f_wrappers, upcasts_code, NIL);
-
-    Printf(f_wrappers, "#ifdef __cplusplus\n");
-    Printf(f_wrappers, "}\n");
-    Printf(f_wrappers, "#endif\n");
-
-    // Output a Modula 3 type wrapper class for each SWIG type
-    for (Iterator swig_type = First(swig_types_hash); swig_type.item != NIL; swig_type = Next(swig_type)) {
-      emitTypeWrapperClass(swig_type.key, swig_type.item);
-    }
-
-    Delete(swig_types_hash);
-    swig_types_hash = NULL;
-    Delete(constant_values);
-    constant_values = NULL;
-    Delete(enumeration_coll);
-    enumeration_coll = NULL;
-    Delete(m3raw_name);
-    m3raw_name = NULL;
-    Delete(m3raw_baseclass);
-    m3raw_baseclass = NULL;
-    Delete(m3raw_interfaces);
-    m3raw_interfaces = NULL;
-    Delete(m3raw_class_modifiers);
-    m3raw_class_modifiers = NULL;
-    Delete(m3raw_imports);
-    m3raw_imports = NULL;
-    Delete(m3raw_cppcasts_code);
-    m3raw_cppcasts_code = NULL;
-    Delete(proxy_class_def);
-    proxy_class_def = NULL;
-    Delete(proxy_class_code);
-    proxy_class_code = NULL;
-    Delete(m3wrap_name);
-    m3wrap_name = NULL;
-    Delete(m3wrap_modifiers);
-    m3wrap_modifiers = NULL;
-    Delete(targetlibrary);
-    targetlibrary = NULL;
-    Delete(module_baseclass);
-    module_baseclass = NULL;
-    Delete(module_interfaces);
-    module_interfaces = NULL;
-    Delete(module_imports);
-    module_imports = NULL;
-    Delete(upcasts_code);
-    upcasts_code = NULL;
-    Delete(constantfilename);
-    constantfilename = NULL;
-    Delete(renamefilename);
-    renamefilename = NULL;
-    Delete(typemapfilename);
-    typemapfilename = NULL;
-
-    /* Close all of the files */
-    Dump(f_runtime, f_begin);
-    Dump(f_header, f_begin);
-    Dump(f_wrappers, f_begin);
-    Wrapper_pretty_print(f_init, f_begin);
-    Delete(f_header);
-    Delete(f_wrappers);
-    Delete(f_init);
-    Delete(f_runtime);
-    Delete(f_begin);
-    return SWIG_OK;
-  }
-
-  /* -----------------------------------------------------------------------------
-   * emitBanner()
-   * ----------------------------------------------------------------------------- */
-
-  void emitBanner(File *f) {
-    Printf(f, "(*******************************************************************************\n");
-    Swig_banner_target_lang(f, " *");
-    Printf(f, "*******************************************************************************)\n\n");
-  }
-
-  /* ----------------------------------------------------------------------
-   * nativeWrapper()
-   * ---------------------------------------------------------------------- */
-
-  virtual int nativeWrapper(Node *n) {
-    String *wrapname = Getattr(n, "wrap:name");
-
-    if (!addSymbol(wrapname, n))
-      return SWIG_ERROR;
-
-    if (Getattr(n, "type")) {
-      Swig_save("nativeWrapper", n, "name", NIL);
-      Setattr(n, "name", wrapname);
-      native_function_flag = true;
-      functionWrapper(n);
-      Swig_restore(n);
-      native_function_flag = false;
-    } else {
-      Swig_error(input_file, line_number, "No return type for %%native method %s.\n", Getattr(n, "wrap:name"));
-    }
-
-    return SWIG_OK;
-  }
-
-  /* ----------------------------------------------------------------------
-   * functionWrapper()
-   * ---------------------------------------------------------------------- */
-
-  virtual int functionWrapper(Node *n) {
-    String *type = nodeType(n);
-    String *funcType = Getattr(n, "modula3:functype");
-    String *rawname = Getattr(n, "name");
-    String *symname = Getattr(n, "sym:name");
-    String *capname = capitalizeFirst(symname);
-    //String *wname = Swig_name_wrapper(symname);
-
-    //printf("function: %s\n", Char(symname));
-    //printf(" purpose: %s\n", Char(funcType));
-
-    if (Strcmp(type, "cdecl") == 0) {
-      if (funcType == NIL) {
-	// no wrapper needed for plain functions
-	emitM3RawPrototype(n, rawname, symname);
-	emitM3Wrapper(n, symname);
-      } else if (Strcmp(funcType, "method") == 0) {
-	Setattr(n, "modula3:funcname", capname);
-	emitCWrapper(n, capname);
-	emitM3RawPrototype(n, capname, capname);
-	emitM3Wrapper(n, capname);
-      } else if (Strcmp(funcType, "accessor") == 0) {
-	/*
-	 * Generate the proxy class properties for public member variables.
-	 * Not for enums and constants.
-	 */
-	if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
-	  // Capitalize the first letter in the function name
-	  Setattr(n, "proxyfuncname", capname);
-	  Setattr(n, "imfuncname", symname);
-	  if (hasPrefix(capname, "Set")) {
-	    Setattr(n, "modula3:setname", capname);
-	  } else {
-	    Setattr(n, "modula3:getname", capname);
-	  }
-
-	  emitCWrapper(n, capname);
-	  emitM3RawPrototype(n, capname, capname);
-	  emitM3Wrapper(n, capname);
-	  //proxyClassFunctionHandler(n);
-	}
-#ifdef DEBUG
-      } else {
-	Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Function type <%s> unknown.\n", Char(funcType));
-#endif
-      }
-    } else if ((Strcmp(type, "constructor") == 0) || (Strcmp(type, "destructor") == 0)) {
-      emitCWrapper(n, capname);
-      emitM3RawPrototype(n, capname, capname);
-      emitM3Wrapper(n, capname);
-    }
-// a Java relict
-#if 0
-    if (!(proxy_flag && is_wrapping_class()) && !enum_constant_flag) {
-      emitM3Wrapper(n, capname);
-    }
-#endif
-
-    Delete(capname);
-
-    return SWIG_OK;
-  }
-
-  /* ----------------------------------------------------------------------
-   * emitCWrapper()
-   *
-   * Generate the wrapper in C which calls C++ methods.
-   * ---------------------------------------------------------------------- */
-
-  virtual int emitCWrapper(Node *n, const String *wname) {
-    String *rawname = Getattr(n, "name");
-    String *c_return_type = NewString("");
-    String *cleanup = NewString("");
-    String *outarg = NewString("");
-    String *body = NewString("");
-    Hash *throws_hash = NewHash();
-    ParmList *l = Getattr(n, "parms");
-    SwigType *t = Getattr(n, "type");
-    String *symname = Getattr(n, "sym:name");
-
-    if (!Getattr(n, "sym:overloaded")) {
-      if (!addSymbol(wname, n)) {
-	return SWIG_ERROR;
-      }
-    }
-    // A new wrapper function object
-    Wrapper *f = NewWrapper();
-
-    /* Attach the non-standard typemaps to the parameter list. */
-    Swig_typemap_attach_parms("ctype", l, f);
-
-    /* Get return types */
-    {
-      String *tm = getMappedTypeNew(n, "ctype", "");
-      if (tm != NIL) {
-	Printf(c_return_type, "%s", tm);
-      }
-    }
-
-    bool is_void_return = (Cmp(c_return_type, "void") == 0);
-    if (!is_void_return) {
-      Wrapper_add_localv(f, "cresult", c_return_type, "cresult = 0", NIL);
-    }
-
-    Printv(f->def, " SWIGEXPORT ", c_return_type, " ", wname, "(", NIL);
-
-    // Emit all of the local variables for holding arguments.
-    emit_parameter_variables(l, f);
-
-    /* Attach the standard typemaps */
-    emit_attach_parmmaps(l, f);
-    Setattr(n, "wrap:parms", l);
-
-    // Generate signature and argument conversion for C wrapper
-    {
-      Parm *p;
-      attachParameterNames(n, "tmap:name", "c:wrapname", "m3arg%d");
-      bool gencomma = false;
-      for (p = skipIgnored(l, "in"); p; p = skipIgnored(p, "in")) {
-
-	String *arg = Getattr(p, "c:wrapname");
-	{
-	  /* Get the ctype types of the parameter */
-	  String *c_param_type = getMappedType(p, "ctype");
-	  // Add parameter to C function
-	  Printv(f->def, gencomma ? ", " : "", c_param_type, " ", arg, NIL);
-	  Delete(c_param_type);
-	  gencomma = true;
-	}
-
-	// Get typemap for this argument
-	String *tm = getMappedType(p, "in");
-	if (tm != NIL) {
-	  addThrows(throws_hash, "in", p);
-	  Replaceall(tm, "$input", arg);
-	  Setattr(p, "emit:input", arg);	/*??? */
-	  Printf(f->code, "%s\n", tm);
-	  p = Getattr(p, "tmap:in:next");
-	} else {
-	  p = nextSibling(p);
-	}
-      }
-    }
-
-    /* Insert constraint checking code */
-    {
-      Parm *p;
-      for (p = l; p;) {
-	String *tm = Getattr(p, "tmap:check");
-	if (tm != NIL) {
-	  addThrows(throws_hash, "check", p);
-	  Replaceall(tm, "$target", Getattr(p, "lname"));	/* deprecated */
-	  Replaceall(tm, "$arg", Getattr(p, "emit:input"));	/* deprecated? */
-	  Replaceall(tm, "$input", Getattr(p, "emit:input"));
-	  Printv(f->code, tm, "\n", NIL);
-	  p = Getattr(p, "tmap:check:next");
-	} else {
-	  p = nextSibling(p);
-	}
-      }
-    }
-
-    /* Insert cleanup code */
-    {
-      Parm *p;
-      for (p = l; p;) {
-	String *tm = Getattr(p, "tmap:freearg");
-	if (tm != NIL) {
-	  addThrows(throws_hash, "freearg", p);
-	  Replaceall(tm, "$source", Getattr(p, "emit:input"));	/* deprecated */
-	  Replaceall(tm, "$arg", Getattr(p, "emit:input"));	/* deprecated? */
-	  Replaceall(tm, "$input", Getattr(p, "emit:input"));
-	  Printv(cleanup, tm, "\n", NIL);
-	  p = Getattr(p, "tmap:freearg:next");
-	} else {
-	  p = nextSibling(p);
-	}
-      }
-    }
-
-    /* Insert argument output code */
-    {
-      Parm *p;
-      for (p = l; p;) {
-	String *tm = Getattr(p, "tmap:argout");
-	if (tm != NIL) {
-	  addThrows(throws_hash, "argout", p);
-	  Replaceall(tm, "$source", Getattr(p, "emit:input"));	/* deprecated */
-	  Replaceall(tm, "$target", Getattr(p, "lname"));	/* deprecated */
-	  Replaceall(tm, "$arg", Getattr(p, "emit:input"));	/* deprecated? */
-	  Replaceall(tm, "$result", "cresult");
-	  Replaceall(tm, "$input", Getattr(p, "emit:input"));
-	  Printv(outarg, tm, "\n", NIL);
-	  p = Getattr(p, "tmap:argout:next");
-	} else {
-	  p = nextSibling(p);
-	}
-      }
-    }
-
-    // Get any Modula 3 exception classes in the throws typemap
-    ParmList *throw_parm_list = NULL;
-    if ((throw_parm_list = Getattr(n, "catchlist"))) {
-      Swig_typemap_attach_parms("throws", throw_parm_list, f);
-      Parm *p;
-      for (p = throw_parm_list; p; p = nextSibling(p)) {
-	addThrows(throws_hash, "throws", p);
-      }
-    }
-
-    Setattr(n, "wrap:name", wname);
-
-    // Now write code to make the function call
-    if (!native_function_flag) {
-      String *actioncode = emit_action(n);
-
-      /* Return value if necessary  */
-      String *tm;
-      if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
-	addThrows(throws_hash, "out", n);
-	Replaceall(tm, "$source", Swig_cresult_name());	/* deprecated */
-	Replaceall(tm, "$target", "cresult");	/* deprecated */
-	Replaceall(tm, "$result", "cresult");
-	Printf(f->code, "%s", tm);
-	if (hasContent(tm))
-	  Printf(f->code, "\n");
-      } else {
-	Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(t, 0), rawname);
-      }
-      emit_return_variable(n, t, f);
-    }
-
-    /* Output argument output code */
-    Printv(f->code, outarg, NIL);
-
-    /* Output cleanup code */
-    Printv(f->code, cleanup, NIL);
-
-    /* Look to see if there is any newfree cleanup code */
-    if (GetFlag(n, "feature:new")) {
-      String *tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0);
-      if (tm != NIL) {
-	addThrows(throws_hash, "newfree", n);
-	Replaceall(tm, "$source", Swig_cresult_name());	/* deprecated */
-	Printf(f->code, "%s\n", tm);
-      }
-    }
-
-    /* See if there is any return cleanup code */
-    if (!native_function_flag) {
-      String *tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0);
-      if (tm != NIL) {
-	Replaceall(tm, "$source", Swig_cresult_name());	/* deprecated */
-	Printf(f->code, "%s\n", tm);
-      }
-    }
-
-    /* Finish C wrapper */
-    Printf(f->def, ") {");
-
-    if (!is_void_return)
-      Printv(f->code, "    return cresult;\n", NIL);
-    Printf(f->code, "}\n");
-
-    /* Substitute the cleanup code */
-    Replaceall(f->code, "$cleanup", cleanup);
-
-    /* Substitute the function name */
-    Replaceall(f->code, "$symname", symname);
-
-    if (!is_void_return) {
-      Replaceall(f->code, "$null", "0");
-    } else {
-      Replaceall(f->code, "$null", "");
-    }
-
-    /* Dump the function out */
-    if (!native_function_flag) {
-      Wrapper_print(f, f_wrappers);
-    }
-
-    Delete(c_return_type);
-    Delete(cleanup);
-    Delete(outarg);
-    Delete(body);
-    Delete(throws_hash);
-    DelWrapper(f);
-    return SWIG_OK;
-  }
-
-  /* ----------------------------------------------------------------------
-   * emitM3RawPrototype()
-   *
-   * Generate an EXTERNAL procedure declaration in Modula 3
-   * which is the interface to an existing C routine or a C wrapper.
-   * ---------------------------------------------------------------------- */
-
-  virtual int emitM3RawPrototype(Node *n, const String *cname, const String *m3name) {
-    String *im_return_type = NewString("");
-    //String   *symname = Getattr(n,"sym:name");
-    ParmList *l = Getattr(n, "parms");
-
-    /* Attach the non-standard typemaps to the parameter list. */
-    Swig_typemap_attach_parms("m3rawinmode", l, NULL);
-    Swig_typemap_attach_parms("m3rawintype", l, NULL);
-
-    /* Get return types */
-    bool has_return;
-    {
-      String *tm = getMappedTypeNew(n, "m3rawrettype", "");
-      if (tm != NIL) {
-	Printf(im_return_type, "%s", tm);
-      }
-      has_return = hasContent(tm);
-    }
-
-    /* cname is the original name if 'n' denotes a C function
-       and it is the relabeled name (sym:name) if 'n' denotes a C++ method or similar */
-    m3raw_intf.enterBlock(no_block);
-    Printf(m3raw_intf.f, "\n<* EXTERNAL %s *>\nPROCEDURE %s (", cname, m3name);
-
-    // Generate signature for raw interface
-    {
-      Parm *p;
-      writeArgState state;
-      attachParameterNames(n, "tmap:rawinname", "modula3:rawname", "arg%d");
-      for (p = skipIgnored(l, "m3rawintype"); p; p = skipIgnored(p, "m3rawintype")) {
-
-	/* Get argument passing mode, should be one of VALUE, VAR, READONLY */
-	String *mode = Getattr(p, "tmap:m3rawinmode");
-	String *argname = Getattr(p, "modula3:rawname");
-	String *im_param_type = getMappedType(p, "m3rawintype");
-	addImports(m3raw_intf.import, "m3rawintype", p);
-
-	writeArg(m3raw_intf.f, state, mode, argname, im_param_type, NIL);
-	if (im_param_type != NIL) {
-	  p = Getattr(p, "tmap:m3rawintype:next");
-	} else {
-	  p = nextSibling(p);
-	}
-      }
-      writeArg(m3raw_intf.f, state, NIL, NIL, NIL, NIL);
-    }
-
-    /* Finish M3 raw prototype */
-    Printf(m3raw_intf.f, ")");
-    // neither a C wrapper nor a plain C function may throw an exception
-    //generateThrowsClause(throws_hash, m3raw_intf.f);
-    if (has_return) {
-      Printf(m3raw_intf.f, ": %s", im_return_type);
-    }
-    Printf(m3raw_intf.f, ";\n");
-
-    Delete(im_return_type);
-    return SWIG_OK;
-  }
-
-  /* -----------------------------------------------------------------------
-   * variableWrapper()
-   * ----------------------------------------------------------------------- */
-
-  virtual int variableWrapper(Node *n) {
-    Language::variableWrapper(n);
-    return SWIG_OK;
-  }
-
-  /* -----------------------------------------------------------------------
-   * globalvariableHandler()
-   * ----------------------------------------------------------------------- */
-
-  virtual int globalvariableHandler(Node *n) {
-    SwigType *t = Getattr(n, "type");
-    String *tm;
-
-    // Get the variable type
-    if ((tm = getMappedTypeNew(n, "m3wraptype", ""))) {
-      substituteClassname(t, tm);
-    }
-
-    variable_name = Getattr(n, "sym:name");
-    variable_type = Copy(tm);
-
-    // Get the variable type expressed in terms of Modula 3 equivalents of C types
-    if ((tm = getMappedTypeNew(n, "m3rawtype", ""))) {
-      m3raw_intf.enterBlock(no_block);
-      Printf(m3raw_intf.f, "\n<* EXTERNAL *> VAR %s: %s;\n", variable_name, tm);
-    }
-    // Output the property's accessor methods
-    /*
-       global_variable_flag = true;
-       int ret = Language::globalvariableHandler(n);
-       global_variable_flag = false;
-     */
-
-    Printf(m3wrap_impl.f, "\n\n");
-
-    //return ret;
-    return 1;
-  }
-
-  long getConstNumeric(Node *n) {
-    String *constnumeric = Getfeature(n, "constnumeric");
-    String *name = Getattr(n, "name");
-    long numvalue;
-    if (constnumeric == NIL) {
-      Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Feature 'constnumeric' is necessary to obtain value of %s.\n", name);
-      return 0;
-    } else if (!strToL(constnumeric, numvalue)) {
-      Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number,
-		   "The feature 'constnumeric' of %s specifies value <%s> which is not an integer constant.\n", name, constnumeric);
-      return 0;
-    } else {
-      return numvalue;
-    }
-  }
-
-  /* ------------------------------------------------------------------------
-   * generateIntConstant()
-   *
-   * Considers node as an integer constant definition
-   * and generate a Modula 3 constant definition.
-   * ------------------------------------------------------------------------ */
-  void generateIntConstant(Node *n, String *name) {
-    String *value = Getattr(n, "value");
-    String *type = Getfeature(n, "modula3:constint:type");
-    String *conv = Getfeature(n, "modula3:constint:conv");
-
-    if (name == NIL) {
-      name = Getattr(n, "sym:name");
-    }
-
-    long numvalue;
-    bool isSimpleNum = strToL(value, numvalue);
-    if (!isSimpleNum) {
-      numvalue = getConstNumeric(n);
-    }
-
-    String *m3value;
-    if ((conv == NIL) || ((Strcmp(conv, "set:int") != 0) && (Strcmp(conv, "int:set") != 0))) {
-      /* The original value of the constant has precedence over
-         'constnumeric' feature since we like to keep
-         the style (that is the base) of simple numeric constants */
-      if (isSimpleNum) {
-	if (hasPrefix(value, "0x")) {
-	  m3value = NewStringf("16_%s", Char(value) + 2);
-	} else if ((Len(value) > 1) && (*Char(value) == '0')) {
-	  m3value = NewStringf("8_%s", Char(value) + 1);
-	} else {
-	  m3value = Copy(value);
-	}
-	/* If we cannot easily obtain the value of a numeric constant,
-	   we use the results given by a C compiler. */
-      } else {
-	m3value = Copy(Getfeature(n, "constnumeric"));
-      }
-    } else {
-      // if the value can't be converted, it is ignored
-      if (convertInt(numvalue, numvalue, conv)) {
-	m3value = NewStringf("%d", numvalue);
-      } else {
-	m3value = NIL;
-      }
-    }
-
-    if (m3value != NIL) {
-      m3wrap_intf.enterBlock(constant);
-      Printf(m3wrap_intf.f, "%s", name);
-      if (hasContent(type)) {
-	Printf(m3wrap_intf.f, ": %s", type);
-      }
-      Printf(m3wrap_intf.f, " = %s;\n", m3value);
-      Delete(m3value);
-    }
-  }
-
-  /* -----------------------------------------------------------------------
-   * generateSetConstant()
-   *
-   * Considers node as a set constant definition
-   * and generate a Modula 3 constant definition.
-   * ------------------------------------------------------------------------ */
-  void generateSetConstant(Node *n, String *name) {
-    String *value = Getattr(n, "value");
-    String *type = Getfeature(n, "modula3:constset:type");
-    String *setname = Getfeature(n, "modula3:constset:set");
-    String *basename = Getfeature(n, "modula3:constset:base");
-    String *conv = Getfeature(n, "modula3:constset:conv");
-
-    m3wrap_intf.enterBlock(constant);
-
-    Printf(m3wrap_intf.f, "%s", name);
-    if (type != NIL) {
-      Printf(m3wrap_intf.f, ":%s ", type);
-    }
-    Printf(m3wrap_intf.f, " = %s{", setname);
-
-    long numvalue = 0;
-    if (!strToL(value, numvalue)) {
-      numvalue = getConstNumeric(n);
-    }
-    convertInt(numvalue, numvalue, conv);
-
-    bool isIntType = Strcmp(basename, "CARDINAL") == 0;
-    Hash *items = NIL;
-    if (!isIntType) {
-      Hash *enumeration = Getattr(enumeration_coll, basename);
-      if (enumeration == NIL) {
-	Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "There is no enumeration <%s> as needed for the set.\n", setname);
-	isIntType = true;
-      } else {
-	items = Getattr(enumeration, "items");
-      }
-    }
-
-    bool gencomma = false;
-    int bitpos = 0;
-    while (numvalue > 0) {
-      if ((numvalue & 1) != 0) {
-	if (isIntType) {
-	  if (gencomma) {
-	    Printv(m3wrap_intf.f, ",", NIL);
-	  }
-	  gencomma = true;
-	  Printf(m3wrap_intf.f, "%d", bitpos);
-	} else {
-	  char bitval[15];
-	  sprintf(bitval, "%d", bitpos);
-	  String *bitname = Getattr(items, bitval);
-	  if (bitname == NIL) {
-	    Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Enumeration <%s> has no value <%s>.\n", setname, bitval);
-	  } else {
-	    if (gencomma) {
-	      Printv(m3wrap_intf.f, ",", NIL);
-	    }
-	    gencomma = true;
-	    Printf(m3wrap_intf.f, "%s.%s", basename, bitname);
-	  }
-	}
-      }
-      numvalue >>= 1;
-      bitpos++;
-    }
-    Printf(m3wrap_intf.f, "};\n");
-  }
-
-  void generateConstant(Node *n) {
-    // any of the special interpretation disables the default behaviour
-    String *enumitem = Getfeature(n, "modula3:enumitem:name");
-    String *constset = Getfeature(n, "modula3:constset:name");
-    String *constint = Getfeature(n, "modula3:constint:name");
-    if (hasContent(enumitem) || hasContent(constset) || hasContent(constint)) {
-      if (hasContent(constset)) {
-	generateSetConstant(n, constset);
-      }
-      if (hasContent(constint)) {
-	generateIntConstant(n, constint);
-      }
-    } else {
-      String *value = Getattr(n, "value");
-      String *name = Getattr(n, "sym:name");
-      if (name == NIL) {
-	name = Getattr(n, "name");
-      }
-      m3wrap_intf.enterBlock(constant);
-      Printf(m3wrap_intf.f, "%s = %s;\n", name, value);
-    }
-  }
-
-  void emitEnumeration(File *file, String *name, Node *n) {
-    Printf(file, "%s = {", name);
-    int i;
-    bool gencomma = false;
-    int max = aToL(Getattr(n, "max"));
-    Hash *items = Getattr(n, "items");
-    for (i = 0; i <= max; i++) {
-      if (gencomma) {
-	Printf(file, ",");
-      }
-      Printf(file, "\n");
-      gencomma = true;
-      char numstr[15];
-      sprintf(numstr, "%d", i);
-      String *name = Getattr(items, numstr);
-      if (name != NIL) {
-	Printv(file, name, NIL);
-      } else {
-	Printf(file, "Dummy%d", i);
-      }
-    }
-    Printf(file, "\n};\n");
-  }
-
-  /* -----------------------------------------------------------------------
-   * constantWrapper()
-   *
-   * Handles constants and enumeration items.
-   * ------------------------------------------------------------------------ */
-
-  virtual int constantWrapper(Node *n) {
-    generateConstant(n);
-    return SWIG_OK;
-  }
-
-#if 0
-// enumerations are handled like constant definitions
-  /* -----------------------------------------------------------------------------
-   * enumDeclaration()
-   * ----------------------------------------------------------------------------- */
-
-  virtual int enumDeclaration(Node *n) {
-    String *symname = nameToModula3(Getattr(n, "sym:name"), true);
-    enumerationStart(symname);
-    int result = Language::enumDeclaration(n);
-    enumerationStop();
-    Delete(symname);
-    return result;
-  }
-#endif
-
-  /* -----------------------------------------------------------------------------
-   * enumvalueDeclaration()
-   * ----------------------------------------------------------------------------- */
-
-  virtual int enumvalueDeclaration(Node *n) {
-    generateConstant(n);
-    /*
-       This call would continue processing in the constantWrapper
-       which cannot handle values like "RED+1".
-       return Language::enumvalueDeclaration(n);
-     */
-    return SWIG_OK;
-  }
-
-  /* -----------------------------------------------------------------------------
-   * pragmaDirective()
-   *
-   * Valid Pragmas:
-   * imclassbase            - base (extends) for the intermediary class
-   * imclassclassmodifiers  - class modifiers for the intermediary class
-   * imclasscode            - text (Modula 3 code) is copied verbatim to the intermediary class
-   * imclassimports         - import statements for the intermediary class
-   * imclassinterfaces      - interface (implements) for the intermediary class
-   *
-   * modulebase              - base (extends) for the module class
-   * moduleclassmodifiers    - class modifiers for the module class
-   * modulecode              - text (Modula 3 code) is copied verbatim to the module class
-   * moduleimports           - import statements for the module class
-   * moduleinterfaces        - interface (implements) for the module class
-   *
-   * ----------------------------------------------------------------------------- */
-
-  virtual int pragmaDirective(Node *n) {
-    if (!ImportMode) {
-      String *lang = Getattr(n, "lang");
-      String *code = Getattr(n, "name");
-      String *value = Getattr(n, "value");
-
-      if (Strcmp(lang, "modula3") == 0) {
-
-	String *strvalue = NewString(value);
-	Replaceall(strvalue, "\\\"", "\"");
-/*
-        bool isEnumItem = Strcmp(code, "enumitem") == 0;
-        bool isSetItem  = Strcmp(code, "setitem")  == 0;
-*/
-	if (Strcmp(code, "imclassbase") == 0) {
-	  Delete(m3raw_baseclass);
-	  m3raw_baseclass = Copy(strvalue);
-	} else if (Strcmp(code, "imclassclassmodifiers") == 0) {
-	  Delete(m3raw_class_modifiers);
-	  m3raw_class_modifiers = Copy(strvalue);
-	} else if (Strcmp(code, "imclasscode") == 0) {
-	  Printf(m3raw_intf.f, "%s\n", strvalue);
-	} else if (Strcmp(code, "imclassimports") == 0) {
-	  Delete(m3raw_imports);
-	  m3raw_imports = Copy(strvalue);
-	} else if (Strcmp(code, "imclassinterfaces") == 0) {
-	  Delete(m3raw_interfaces);
-	  m3raw_interfaces = Copy(strvalue);
-	} else if (Strcmp(code, "modulebase") == 0) {
-	  Delete(module_baseclass);
-	  module_baseclass = Copy(strvalue);
-	} else if (Strcmp(code, "moduleclassmodifiers") == 0) {
-	  Delete(m3wrap_modifiers);
-	  m3wrap_modifiers = Copy(strvalue);
-	} else if (Strcmp(code, "modulecode") == 0) {
-	  Printf(m3wrap_impl.f, "%s\n", strvalue);
-	} else if (Strcmp(code, "moduleimports") == 0) {
-	  Delete(module_imports);
-	  module_imports = Copy(strvalue);
-	} else if (Strcmp(code, "moduleinterfaces") == 0) {
-	  Delete(module_interfaces);
-	  module_interfaces = Copy(strvalue);
-	} else if (Strcmp(code, "unsafe") == 0) {
-	  unsafe_module = true;
-	} else if (Strcmp(code, "library") == 0) {
-	  if (targetlibrary) {
-	    Delete(targetlibrary);
-	  }
-	  targetlibrary = Copy(strvalue);
-	} else if (Strcmp(code, "enumitem") == 0) {
-	} else if (Strcmp(code, "constset") == 0) {
-	} else if (Strcmp(code, "constint") == 0) {
-	} else if (Strcmp(code, "makesetofenum") == 0) {
-	  m3wrap_intf.enterBlock(blocktype);
-	  Printf(m3wrap_intf.f, "%sSet = SET OF %s;\n", value, value);
-	} else {
-	  Swig_warning(WARN_MODULA3_UNKNOWN_PRAGMA, input_file, line_number, "Unrecognized pragma <%s>.\n", code);
-	}
-	Delete(strvalue);
-      }
-    }
-    return Language::pragmaDirective(n);
-  }
-
-  void Setfeature(Node *n, const char *feature, const String *value, bool warn = false) {
-    //printf("tag feature <%s> with value <%s>\n", feature, Char(value));
-    String *attr = NewStringf("feature:%s", feature);
-    if ((Setattr(n, attr, value) != 0) && warn) {
-      Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Feature <%s> of %s did already exist.\n", feature, Getattr(n, "name"));
-    }
-    Delete(attr);
-  }
-
-  String *Getfeature(Node *n, const char *feature) {
-    //printf("retrieve feature <%s> with value <%s>\n", feature, Char(value));
-    String *attr = NewStringf("feature:%s", feature);
-    String *result = Getattr(n, attr);
-    Delete(attr);
-    return result;
-  }
-
-  bool convertInt(long in, long &out, const String *mode) {
-    if ((mode == NIL) || (Strcmp(mode, "int:int") == 0) || (Strcmp(mode, "set:set") == 0)) {
-      out = in;
-      return true;
-    } else if (Strcmp(mode, "set:int") == 0) {
-      return log2(in, out);
-    } else if (Strcmp(mode, "int:set") == 0) {
-      out = 1L << in;
-      return unsigned (in) < (sizeof(out) * 8);
-    } else {
-      Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Unknown integer conversion method <%s>.\n", mode);
-      return false;
-    }
-  }
-
-  void collectEnumerations(Hash *enums, Node *n) {
-    Node *child = firstChild(n);
-    while (child != NIL) {
-      String *name = Getattr(child, "name");
-      const bool isConstant = Strcmp(nodeType(child), "constant") == 0;
-      const bool isEnumItem = Strcmp(nodeType(child), "enumitem") == 0;
-      if (isConstant || isEnumItem) {
-//printf("%s%s name %s\n", isConstant?"constant":"", isEnumItem?"enumitem":"", Char(name));
-	{
-	  String *m3name = Getfeature(child, "modula3:enumitem:name");
-	  String *m3enum = Getfeature(child, "modula3:enumitem:enum");
-	  String *conv = Getfeature(child, "modula3:enumitem:conv");
-
-	  if (m3enum != NIL) {
-//printf("m3enum %s\n", Char(m3enum));
-	    if (m3name == NIL) {
-	      m3name = name;
-	    }
-
-	    long max = -1;
-	    Hash *items;
-	    Hash *enumnode = Getattr(enums, m3enum);
-	    if (enumnode == NIL) {
-	      enumnode = NewHash();
-	      items = NewHash();
-	      Setattr(enumnode, "items", items);
-	      Setattr(enums, m3enum, enumnode);
-	    } else {
-	      String *maxstr = Getattr(enumnode, "max");
-	      if (maxstr != NIL) {
-		max = aToL(maxstr);
-	      }
-	      items = Getattr(enumnode, "items");
-	    }
-	    long numvalue;
-	    String *value = Getattr(child, "value");
-//printf("value: %s\n", Char(value));
-	    if ((value == NIL) || (!strToL(value, numvalue))) {
-	      value = Getattr(child, "enumvalue");
-	      if ((value == NIL) || (!evalExpr(value, numvalue))) {
-		numvalue = getConstNumeric(child);
-	      }
-//printf("constnumeric: %s\n", Char(value));
-	    }
-	    Setattr(constant_values, name, NewStringf("%d", numvalue));
-	    if (convertInt(numvalue, numvalue, conv)) {
-	      String *newvalue = NewStringf("%d", numvalue);
-	      String *oldname = Getattr(items, newvalue);
-	      if (oldname != NIL) {
-		Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "The value <%s> is already assigned to <%s>.\n", value, oldname);
-	      }
-//printf("items %p, set %s = %s\n", items, Char(newvalue), Char(m3name));
-	      Setattr(items, newvalue, m3name);
-	      if (max < numvalue) {
-		max = numvalue;
-	      }
-	      Setattr(enumnode, "max", NewStringf("%d", max));
-	    }
-	  }
-	}
-      }
-
-      collectEnumerations(enums, child);
-      child = nextSibling(child);
-    }
-  }
-
-  enum const_pragma_type { cpt_none, cpt_constint, cpt_constset, cpt_enumitem };
-
-  struct const_id_pattern {
-    String *prefix, *parentEnum;
-  };
-
-  void tagConstants(Node *first, String *parentEnum, const const_id_pattern & pat, const String *pragma, List *convdesc) {
-    Node *n = first;
-    while (n != NIL) {
-      String *name = getQualifiedName(n);
-      bool isConstant = Strcmp(nodeType(n), "constant") == 0;
-      bool isEnumItem = Strcmp(nodeType(n), "enumitem") == 0;
-      if ((isConstant || isEnumItem) && ((pat.prefix == NIL) || (hasPrefix(name, pat.prefix))) && ((pat.parentEnum == NIL) || ((parentEnum != NIL)
-															       &&
-															       (Strcmp
-																(pat.parentEnum, parentEnum)
-																== 0)))) {
-	//printf("tag %s\n", Char(name));
-	String *srctype = Getitem(convdesc, 1);
-	String *relationstr = Getitem(convdesc, 3);
-	List *relationdesc = Split(relationstr, ',', 2);
-
-	// transform name from C to Modula3 style
-	String *srcstyle = NIL;
-	String *newprefix = NIL;
-	{
-	  //printf("name conversion <%s>\n", Char(Getitem(convdesc,2)));
-	  List *namedesc = Split(Getitem(convdesc, 2), ',', INT_MAX);
-	  Iterator nameit = First(namedesc);
-	  for (; nameit.item != NIL; nameit = Next(nameit)) {
-	    List *nameassign = Split(nameit.item, '=', 2);
-	    String *tag = Getitem(nameassign, 0);
-	    String *data = Getitem(nameassign, 1);
-	    //printf("name conv <%s> = <%s>\n", Char(tag), Char(data));
-	    if (Strcmp(tag, "srcstyle") == 0) {
-	      srcstyle = Copy(data);
-	    } else if (Strcmp(tag, "prefix") == 0) {
-	      newprefix = Copy(data);
-	    } else {
-	      Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Unknown name conversion tag <%s> with value <%s>.\n", tag, data);
-	    }
-	    Delete(nameassign);
-	  }
-	  Delete(namedesc);
-	}
-	const char *stem = Char(name);
-	if (pat.prefix != NIL) {
-	  //printf("pat.prefix %s for %s\n", Char(pat.prefix), Char(name));
-	  stem += Len(pat.prefix);
-	}
-	String *newname;
-	if (srcstyle && Strcmp(srcstyle, "underscore") == 0) {
-	  if (newprefix != NIL) {
-	    String *newstem = nameToModula3(stem, true);
-	    newname = NewStringf("%s%s", newprefix, newstem);
-	    Delete(newstem);
-	  } else {
-	    newname = nameToModula3(stem, true);
-	  }
-	} else {
-	  if (srcstyle != NIL) {
-	    Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Unknown C identifier style <%s>.\n", srcstyle);
-	  }
-	  newname = Copy(name);
-	}
-
-	if (Strcmp(pragma, "enumitem") == 0) {
-	  if (Len(relationdesc) != 1) {
-	    Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Expected <enumeration>, got <%s>.\n", relationstr);
-	  }
-	  Setfeature(n, "modula3:enumitem:name", newname, true);
-	  Setfeature(n, "modula3:enumitem:enum", relationstr, true);
-	  Setfeature(n, "modula3:enumitem:conv", NewStringf("%s:int", srctype), true);
-	} else if (Strcmp(pragma, "constint") == 0) {
-	  if (Len(relationdesc) != 1) {
-	    Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Expected <ordinal type>, got <%s>.\n", relationstr);
-	  }
-	  Setfeature(n, "modula3:constint:name", newname, true);
-	  Setfeature(n, "modula3:constint:type", Getitem(relationdesc, 0), true);
-	  Setfeature(n, "modula3:constint:conv", NewStringf("%s:int", srctype), true);
-	} else if (Strcmp(pragma, "constset") == 0) {
-	  if (Len(relationdesc) != 2) {
-	    Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Expected <set type,base type>, got <%s>.\n", relationstr);
-	  }
-	  String *settype = Getitem(relationdesc, 0);
-	  Setfeature(n, "modula3:constset:name", newname, true);
-	  //Setfeature(n,"modula3:constset:type",settype,true);
-	  Setfeature(n, "modula3:constset:set", settype, true);
-	  Setfeature(n, "modula3:constset:base", Getitem(relationdesc, 1), true);
-	  Setfeature(n, "modula3:constset:conv", NewStringf("%s:set", srctype), true);
-	}
-
-	Delete(newname);
-	Delete(relationdesc);
-      }
-
-      if (Strcmp(nodeType(n), "enum") == 0) {
-	//printf("explore enum %s, qualification %s\n", Char(name), Char(Swig_symbol_qualified(n)));
-	tagConstants(firstChild(n), name, pat, pragma, convdesc);
-      } else {
-	tagConstants(firstChild(n), NIL, pat, pragma, convdesc);
-      }
-      n = nextSibling(n);
-    }
-  }
-
-  void scanForConstPragmas(Node *n) {
-    Node *child = firstChild(n);
-    while (child != NIL) {
-      const String *type = nodeType(child);
-      if (Strcmp(type, "pragma") == 0) {
-	const String *lang = Getattr(child, "lang");
-	const String *code = Getattr(child, "name");
-	String *value = Getattr(child, "value");
-
-	if (Strcmp(lang, "modula3") == 0) {
-	  const_pragma_type cpt = cpt_none;
-	  if (Strcmp(code, "constint") == 0) {
-	    cpt = cpt_constint;
-	  } else if (Strcmp(code, "constset") == 0) {
-	    cpt = cpt_constset;
-	  } else if (Strcmp(code, "enumitem") == 0) {
-	    cpt = cpt_enumitem;
-	  }
-	  if (cpt != cpt_none) {
-	    const_id_pattern pat = { NIL, NIL };
-
-	    List *convdesc = Split(value, ';', 4);
-	    List *patterndesc = Split(Getitem(convdesc, 0), ',', INT_MAX);
-	    Iterator patternit;
-	    for (patternit = First(patterndesc); patternit.item != NIL; patternit = Next(patternit)) {
-	      List *patternassign = Split(patternit.item, '=', 2);
-	      String *tag = Getitem(patternassign, 0);
-	      String *data = Getitem(patternassign, 1);
-	      if (Strcmp(tag, "prefix") == 0) {
-		pat.prefix = Copy(data);
-	      } else if (Strcmp(tag, "enum") == 0) {
-		pat.parentEnum = Copy(data);
-	      } else {
-		Swig_warning(WARN_MODULA3_BAD_ENUMERATION, input_file, line_number, "Unknown identification tag <%s> with value <%s>.\n", tag, data);
-	      }
-	      Delete(patternassign);
-	    }
-	    tagConstants(child, NIL, pat, code, convdesc);
-
-	    Delete(patterndesc);
-	  }
-	}
-      }
-      scanForConstPragmas(child);
-      child = nextSibling(child);
-    }
-  }
-
-  /* -----------------------------------------------------------------------------
-   * emitProxyClassDefAndCPPCasts()
-   * ----------------------------------------------------------------------------- */
-
-  void emitProxyClassDefAndCPPCasts(Node *n) {
-    String *c_classname = SwigType_namestr(Getattr(n, "name"));
-    String *c_baseclass = NULL;
-    String *baseclass = NULL;
-    String *c_baseclassname = NULL;
-    String *name = Getattr(n, "name");
-
-    /* Deal with inheritance */
-    List *baselist = Getattr(n, "bases");
-    if (baselist) {
-      Iterator base = First(baselist);
-      while (base.item) {
-	if (!GetFlag(base.item, "feature:ignore")) {
-	  String *baseclassname = Getattr(base.item, "name");
-	  if (!c_baseclassname) {
-	    c_baseclassname = baseclassname;
-	    baseclass = Copy(getProxyName(baseclassname));
-	    if (baseclass)
-	      c_baseclass = SwigType_namestr(baseclassname);
-	  } else {
-	    /* Warn about multiple inheritance for additional base class(es) */
-	    String *proxyclassname = Getattr(n, "classtypeobj");
-	    Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
-		"Warning for %s, base %s ignored. Multiple inheritance is not supported in Modula 3.\n", SwigType_namestr(proxyclassname), SwigType_namestr(baseclassname));
-	  }
-	}
-	base = Next(base);
-      }
-    }
-
-    bool derived = baseclass && getProxyName(c_baseclassname);
-    if (!baseclass)
-      baseclass = NewString("");
-
-    // Inheritance from pure Modula 3 classes
-    const String *pure_baseclass = typemapLookup(n, "m3base", name, WARN_NONE);
-    if (hasContent(pure_baseclass) && hasContent(baseclass)) {
-      Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
-		   "Warning for %s, base %s ignored. Multiple inheritance is not supported in Modula 3.\n", name, pure_baseclass);
-    }
-    // Pure Modula 3 interfaces
-    const String *pure_interfaces = typemapLookup(n, derived ? "m3interfaces_derived" : "m3interfaces",
-						  name, WARN_NONE);
-
-    // Start writing the proxy class
-    Printv(proxy_class_def, typemapLookup(n, "m3imports", name, WARN_NONE),	// Import statements
-	   "\n", typemapLookup(n, "m3classmodifiers", name, WARN_MODULA3_TYPEMAP_CLASSMOD_UNDEF),	// Class modifiers
-	   " class $m3classname",	// Class name and bases
-	   (derived || *Char(pure_baseclass) || *Char(pure_interfaces)) ? " : " : "", baseclass, pure_baseclass, ((derived || *Char(pure_baseclass)) && *Char(pure_interfaces)) ?	// Interfaces
-	   ", " : "", pure_interfaces, " {\n", "  private IntPtr swigCPtr;\n",	// Member variables for memory handling
-	   derived ? "" : "  protected bool swigCMemOwn;\n", "\n", "  ", typemapLookup(n, "m3ptrconstructormodifiers", name, WARN_MODULA3_TYPEMAP_PTRCONSTMOD_UNDEF),	// pointer constructor modifiers
-	   " $m3classname(IntPtr cPtr, bool cMemoryOwn) ",	// Constructor used for wrapping pointers
-	   derived ?
-	   ": base($imclassname.$m3classnameTo$baseclass(cPtr), cMemoryOwn) {\n"
-	   : "{\n    swigCMemOwn = cMemoryOwn;\n", "    swigCPtr = cPtr;\n", "  }\n", NIL);
-
-    if (!have_default_constructor_flag) {	// All proxy classes need a constructor
-      Printv(proxy_class_def, "\n", "  protected $m3classname() : this(IntPtr.Zero, false) {\n", "  }\n", NIL);
-    }
-    // C++ destructor is wrapped by the Dispose method
-    // Note that the method name is specified in a typemap attribute called methodname
-    String *destruct = NewString("");
-    const String *tm = NULL;
-    Node *attributes = NewHash();
-    String *destruct_methodname = NULL;
-    if (derived) {
-      tm = typemapLookup(n, "m3destruct_derived", name, WARN_NONE, attributes);
-      destruct_methodname = Getattr(attributes, "tmap:m3destruct_derived:methodname");
-    } else {
-      tm = typemapLookup(n, "m3destruct", name, WARN_NONE, attributes);
-      destruct_methodname = Getattr(attributes, "tmap:m3destruct:methodname");
-    }
-    if (!destruct_methodname) {
-      Swig_error(Getfile(n), Getline(n), "No methodname attribute defined in m3destruct%s typemap for %s\n", (derived ? "_derived" : ""), proxy_class_name);
-    }
-    // Emit the Finalize and Dispose methods
-    if (tm) {
-      // Finalize method
-      if (*Char(destructor_call)) {
-	Printv(proxy_class_def, typemapLookup(n, "m3finalize", name, WARN_NONE), NIL);
-      }
-      // Dispose method
-      Printv(destruct, tm, NIL);
-      if (*Char(destructor_call))
-	Replaceall(destruct, "$imcall", destructor_call);
-      else
-	Replaceall(destruct, "$imcall", "throw new MethodAccessException(\"C++ destructor does not have public access\")");
-      if (*Char(destruct))
-	Printv(proxy_class_def, "\n  public ", derived ? "override" : "virtual", " void ", destruct_methodname, "() ", destruct, "\n", NIL);
-    }
-    Delete(attributes);
-    Delete(destruct);
-
-    // Emit various other methods
-    Printv(proxy_class_def, typemapLookup(n, "m3getcptr", name, WARN_MODULA3_TYPEMAP_GETCPTR_UNDEF),	// getCPtr method
-	   typemapLookup(n, "m3code", name, WARN_NONE),	// extra Modula 3 code
-	   "\n", NIL);
-
-    // Substitute various strings into the above template
-    Replaceall(proxy_class_def, "$m3classname", proxy_class_name);
-    Replaceall(proxy_class_code, "$m3classname", proxy_class_name);
-
-    Replaceall(proxy_class_def, "$baseclass", baseclass);
-    Replaceall(proxy_class_code, "$baseclass", baseclass);
-
-    Replaceall(proxy_class_def, "$imclassname", m3raw_name);
-    Replaceall(proxy_class_code, "$imclassname", m3raw_name);
-
-    // Add code to do C++ casting to base class (only for classes in an inheritance hierarchy)
-    if (derived) {
-      Printv(m3raw_cppcasts_code, "\n  [DllImport(\"", m3wrap_name, "\", EntryPoint=\"Modula3_", proxy_class_name, "To", baseclass, "\")]\n", NIL);
-      Printv(m3raw_cppcasts_code, "  public static extern IntPtr ", "$m3classnameTo$baseclass(IntPtr objectRef);\n", NIL);
-
-      Replaceall(m3raw_cppcasts_code, "$m3classname", proxy_class_name);
-      Replaceall(m3raw_cppcasts_code, "$baseclass", baseclass);
-
-      Printv(upcasts_code,
-	     "SWIGEXPORT long Modula3_$imclazznameTo$imbaseclass",
-	     "(long objectRef) {\n",
-	     "    long baseptr = 0;\n" "    *($cbaseclass **)&baseptr = *($cclass **)&objectRef;\n" "    return baseptr;\n" "}\n", "\n", NIL);
-
-      Replaceall(upcasts_code, "$imbaseclass", baseclass);
-      Replaceall(upcasts_code, "$cbaseclass", c_baseclass);
-      Replaceall(upcasts_code, "$imclazzname", proxy_class_name);
-      Replaceall(upcasts_code, "$cclass", c_classname);
-    }
-    Delete(baseclass);
-  }
-
-  /* ----------------------------------------------------------------------
-   * getAttrString()
-   *
-   * If necessary create and return the string
-   * associated with a certain attribute of 'n'.
-   * ---------------------------------------------------------------------- */
-
-  String *getAttrString(Node *n, const char *attr) {
-    String *str = Getattr(n, attr);
-    if (str == NIL) {
-      str = NewString("");
-      Setattr(n, attr, str);
-    }
-    return str;
-  }
-
-  /* ----------------------------------------------------------------------
-   * getMethodDeclarations()
-   *
-   * If necessary create and return the handle
-   * where the methods of the current access can be written to.
-   * 'n' must be a member of a struct or a class.
-   * ---------------------------------------------------------------------- */
-
-  String *getMethodDeclarations(Node *n) {
-    String *acc_str = Getattr(n, "access");
-    String *methodattr;
-    if (acc_str == NIL) {
-      methodattr = NewString("modula3:method:public");
-    } else {
-      methodattr = NewStringf("modula3:method:%s", acc_str);
-    }
-    String *methods = getAttrString(parentNode(n), Char(methodattr));
-    Delete(methodattr);
-    return methods;
-  }
-
-  /* ----------------------------------------------------------------------
-   * classHandler()
-   * ---------------------------------------------------------------------- */
-
-  virtual int classHandler(Node *n) {
-
-    File *f_proxy = NULL;
-    proxy_class_name = Copy(Getattr(n, "sym:name"));
-    //String *rawname = Getattr(n,"name");
-
-    if (proxy_flag) {
-      if (!addSymbol(proxy_class_name, n))
-	return SWIG_ERROR;
-
-      if (Cmp(proxy_class_name, m3raw_name) == 0) {
-	Printf(stderr, "Class name cannot be equal to intermediary class name: %s\n", proxy_class_name);
-	SWIG_exit(EXIT_FAILURE);
-      }
-
-      if (Cmp(proxy_class_name, m3wrap_name) == 0) {
-	Printf(stderr, "Class name cannot be equal to module class name: %s\n", proxy_class_name);
-	SWIG_exit(EXIT_FAILURE);
-      }
-
-      String *filen = NewStringf("%s%s.m3", SWIG_output_directory(), proxy_class_name);
-      f_proxy = NewFile(filen, "w", SWIG_output_files());
-      if (!f_proxy) {
-	FileErrorDisplay(filen);
-	SWIG_exit(EXIT_FAILURE);
-      }
-      Delete(filen);
-      filen = NULL;
-
-      emitBanner(f_proxy);
-
-      Clear(proxy_class_def);
-      Clear(proxy_class_code);
-
-      have_default_constructor_flag = false;
-      destructor_call = NewString("");
-    }
-
-    /* This will invoke memberfunctionHandler, membervariableHandler ...
-       and finally it may invoke functionWrapper
-       for wrappers and member variable accessors.
-       It will invoke Language:constructorDeclaration
-       which decides whether to call MODULA3::constructorHandler */
-    Language::classHandler(n);
-
-    {
-      String *kind = Getattr(n, "kind");
-      if (Cmp(kind, "struct") == 0) {
-	String *entries = NewString("");
-	Node *child;
-	writeArgState state;
-	for (child = firstChild(n); child != NIL; child = nextSibling(child)) {
-	  String *childType = nodeType(child);
-	  if (Strcmp(childType, "cdecl") == 0) {
-	    String *member = Getattr(child, "sym:name");
-	    ParmList *pl = Getattr(child, "parms");
-	    if (pl == NIL) {
-	      // Get the variable type in Modula 3 type equivalents
-	      String *m3ct = getMappedTypeNew(child, "m3rawtype", "");
-
-	      writeArg(entries, state, NIL, member, m3ct, NIL);
-	    }
-	  }
-	}
-	writeArg(entries, state, NIL, NIL, NIL, NIL);
-
-	m3raw_intf.enterBlock(blocktype);
-	Printf(m3raw_intf.f, "%s =\nRECORD\n%sEND;\n", proxy_class_name, entries);
-
-	Delete(entries);
-
-      } else if (Cmp(kind, "class") == 0) {
-	enum access_privilege { acc_public, acc_protected, acc_private };
-	int max_acc = acc_public;
-
-	const char *acc_name[3] = { "public", "protected", "private" };
-	String *methods[3];
-	int acc;
-	for (acc = acc_public; acc <= acc_private; acc++) {
-	  String *methodattr = NewStringf("modula3:method:%s", acc_name[acc]);
-	  methods[acc] = Getattr(n, methodattr);
-	  Delete(methodattr);
-	  max_acc = max_acc > acc ? max_acc : acc;
-	}
-
-	/* Determine the name of the base class */
-	String *baseclassname = NewString("");
-	{
-	  List *baselist = Getattr(n, "bases");
-	  if (baselist) {
-	    /* Look for the first (principal?) base class -
-	       Modula 3 does not support multiple inheritance */
-	    Iterator base = First(baselist);
-	    if (base.item) {
-	      Append(baseclassname, Getattr(base.item, "sym:name"));
-	      base = Next(base);
-	      if (base.item) {
-		Swig_warning(WARN_MODULA3_MULTIPLE_INHERITANCE, Getfile(n), Getline(n),
-		    "Warning for %s, base %s ignored. Multiple inheritance is not supported in Modula 3.\n",
-		    proxy_class_name, Getattr(base.item, "name"));
-	      }
-	    }
-	  }
-	}
-
-	/* the private class of the base class and only this
-	   need a pointer to the C++ object */
-	bool need_private = !hasContent(baseclassname);
-	max_acc = need_private ? acc_private : max_acc;
-
-	/* Declare C++ object as abstract pointer in Modula 3 */
-	/* The revelation system does not allow us
-	   to imitate the whole class hierarchy of the C++ library,
-	   but at least we can distinguish between classes of different roots. */
-	if (hasContent(baseclassname)) {
-	  m3raw_intf.enterBlock(blocktype);
-	  Printf(m3raw_intf.f, "%s = %s;\n", proxy_class_name, baseclassname);
-	} else {
-	  m3raw_intf.enterBlock(blocktype);
-	  Printf(m3raw_intf.f, "%s <: ADDRESS;\n", proxy_class_name);
-	  m3raw_impl.enterBlock(revelation);
-	  Printf(m3raw_impl.f, "%s = UNTRACED BRANDED REF RECORD (*Dummy*) END;\n", proxy_class_name);
-	}
-
-	String *superclass;
-	m3wrap_intf.enterBlock(blocktype);
-	if (hasContent(methods[acc_public])) {
-	  superclass = NewStringf("%sPublic", proxy_class_name);
-	} else if (hasContent(baseclassname)) {
-	  superclass = Copy(baseclassname);
-	} else {
-	  superclass = NewString("ROOT");
-	}
-	Printf(m3wrap_intf.f, "%s <: %s;\n", proxy_class_name, superclass);
-	Delete(superclass);
-
-	{
-	  static const char *acc_m3suffix[] = { "Public", "Protected", "Private" };
-	  int acc;
-	  for (acc = acc_public; acc <= acc_private; acc++) {
-	    bool process_private = (acc == acc_private) && need_private;
-	    if (hasContent(methods[acc]) || process_private) {
-	      String *subclass = NewStringf("%s%s", proxy_class_name, acc_m3suffix[acc]);
-	      /*
-	         m3wrap_intf.enterBlock(revelation);
-	         Printf(m3wrap_intf.f, "%s <: %s;\n", proxy_class_name, subclass);
-	       */
-	      if (acc == max_acc) {
-		m3wrap_intf.enterBlock(revelation);
-		Printf(m3wrap_intf.f, "%s =\n", proxy_class_name);
-	      } else {
-		m3wrap_intf.enterBlock(blocktype);
-		Printf(m3wrap_intf.f, "%s =\n", subclass);
-	      }
-	      Printf(m3wrap_intf.f, "%s BRANDED OBJECT\n", baseclassname);
-	      if (process_private) {
-		Setattr(m3wrap_intf.import, m3raw_name, "");
-		Printf(m3wrap_intf.f, "cxxObj:%s.%s;\n", m3raw_name, proxy_class_name);
-	      }
-	      if (hasContent(methods[acc])) {
-		Printf(m3wrap_intf.f, "METHODS\n%s", methods[acc]);
-	      }
-	      if (acc == max_acc) {
-		String *overrides = Getattr(n, "modula3:override");
-		Printf(m3wrap_intf.f, "OVERRIDES\n%s", overrides);
-	      }
-	      Printf(m3wrap_intf.f, "END;\n");
-	      Delete(baseclassname);
-	      baseclassname = subclass;
-	    }
-	  }
-	}
-
-	Delete(methods[acc_public]);
-	Delete(methods[acc_protected]);
-	Delete(methods[acc_private]);
-
-      } else {
-	Swig_warning(WARN_MODULA3_TYPECONSTRUCTOR_UNKNOWN, input_file, line_number, "Unknown type constructor %s\n", kind);
-      }
-    }
-
-    if (proxy_flag) {
-
-      emitProxyClassDefAndCPPCasts(n);
-
-      Printv(f_proxy, proxy_class_def, proxy_class_code, NIL);
-
-      Printf(f_proxy, "}\n");
-      Delete(f_proxy);
-      f_proxy = NULL;
-
-      Delete(proxy_class_name);
-      proxy_class_name = NULL;
-      Delete(destructor_call);
-      destructor_call = NULL;
-    }
-    return SWIG_OK;
-  }
-
-  /* ----------------------------------------------------------------------
-   * memberfunctionHandler()
-   * ---------------------------------------------------------------------- */
-
-  virtual int memberfunctionHandler(Node *n) {
-    //printf("begin memberfunctionHandler(%s)\n", Char(Getattr(n,"name")));
-    Setattr(n, "modula3:functype", "method");
-    Language::memberfunctionHandler(n);
-
-    {
-      /* Language::memberfunctionHandler will remove the mapped types
-         that emitM3Wrapper may attach */
-      ParmList *pl = Getattr(n, "parms");
-      Swig_typemap_attach_parms("m3wrapinmode", pl, NULL);
-      Swig_typemap_attach_parms("m3wrapinname", pl, NULL);
-      Swig_typemap_attach_parms("m3wrapintype", pl, NULL);
-      Swig_typemap_attach_parms("m3wrapindefault", pl, NULL);
-      attachParameterNames(n, "tmap:m3wrapinname", "autoname", "arg%d");
-      String *rettype = getMappedTypeNew(n, "m3wrapouttype", "");
-
-      String *methodname = Getattr(n, "sym:name");
-/*
-      if (methodname==NIL) {
-        methodname = Getattr(n,"name");
-      }
-*/
-      String *arguments = createM3Signature(n);
-      String *storage = Getattr(n, "storage");
-      String *overridden = Getattr(n, "override");
-      bool isVirtual = (storage != NIL) && (Strcmp(storage, "virtual") == 0);
-      bool isOverridden = (overridden != NIL)
-	  && (Strcmp(overridden, "1") == 0);
-      if ((!isVirtual) || (!isOverridden)) {
-	{
-	  String *methods = getMethodDeclarations(n);
-	  Printf(methods, "%s(%s)%s%s;%s\n",
-		 methodname, arguments,
-		 hasContent(rettype) ? ": " : "", hasContent(rettype) ? (const String *) rettype : "", isVirtual ? "  (* base method *)" : "");
-	}
-	{
-	  /* this was attached by functionWrapper
-	     invoked by Language::memberfunctionHandler */
-	  String *fname = Getattr(n, "modula3:funcname");
-	  String *overrides = getAttrString(parentNode(n), "modula3:override");
-	  Printf(overrides, "%s := %s;\n", methodname, fname);
-	}
-      }
-    }
-
-    if (proxy_flag) {
-      String *overloaded_name = getOverloadedName(n);
-      String *intermediary_function_name = Swig_name_member(NSPACE_TODO, proxy_class_name, overloaded_name);
-      Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
-      Setattr(n, "imfuncname", intermediary_function_name);
-      proxyClassFunctionHandler(n);
-      Delete(overloaded_name);
-    }
-    //printf("end memberfunctionHandler(%s)\n", Char(Getattr(n,"name")));
-    return SWIG_OK;
-  }
-
-  /* ----------------------------------------------------------------------
-   * staticmemberfunctionHandler()
-   * ---------------------------------------------------------------------- */
-
-  virtual int staticmemberfunctionHandler(Node *n) {
-
-    static_flag = true;
-    Language::staticmemberfunctionHandler(n);
-
-    if (proxy_flag) {
-      String *overloaded_name = getOverloadedName(n);
-      String *intermediary_function_name = Swig_name_member(NSPACE_TODO, proxy_class_name, overloaded_name);
-      Setattr(n, "proxyfuncname", Getattr(n, "sym:name"));
-      Setattr(n, "imfuncname", intermediary_function_name);
-      proxyClassFunctionHandler(n);
-      Delete(overloaded_name);
-    }
-    static_flag = false;
-
-    return SWIG_OK;
-  }
-
-  /* -----------------------------------------------------------------------------
-   * proxyClassFunctionHandler()
-   *
-   * Function called for creating a Modula 3 wrapper function around a c++ function in the 
-   * proxy class. Used for both static and non-static C++ class functions.
-   * C++ class static functions map to Modula 3 static functions.
-   * Two extra attributes in the Node must be available. These are "proxyfuncname" - 
-   * the name of the Modula 3 class proxy function, which in turn will call "imfuncname" - 
-   * the intermediary (PInvoke) function name in the intermediary class.
-   * ----------------------------------------------------------------------------- */
-
-  void proxyClassFunctionHandler(Node *n) {
-    SwigType *t = Getattr(n, "type");
-    ParmList *l = Getattr(n, "parms");
-    Hash *throws_hash = NewHash();
-    String *intermediary_function_name = Getattr(n, "imfuncname");
-    String *proxy_function_name = Getattr(n, "proxyfuncname");
-    String *tm;
-    Parm *p;
-    int i;
-    String *imcall = NewString("");
-    String *return_type = NewString("");
-    String *function_code = NewString("");
-    bool setter_flag = false;
-
-    if (!proxy_flag)
-      return;
-
-    if (l) {
-      if (SwigType_type(Getattr(l, "type")) == T_VOID) {
-	l = nextSibling(l);
-      }
-    }
-
-    /* Attach the non-standard typemaps to the parameter list */
-    Swig_typemap_attach_parms("in", l, NULL);
-    Swig_typemap_attach_parms("m3wraptype", l, NULL);
-    Swig_typemap_attach_parms("m3in", l, NULL);
-
-    /* Get return types */
-    if ((tm = getMappedTypeNew(n, "m3wraptype", ""))) {
-      substituteClassname(t, tm);
-      Printf(return_type, "%s", tm);
-    }
-
-    if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
-      // Properties
-      setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, proxy_class_name, variable_name)))
-		     == 0);
-    }
-
-    /* Start generating the proxy function */
-    Printf(function_code, "  %s ", Getattr(n, "feature:modula3:methodmodifiers"));
-    if (static_flag)
-      Printf(function_code, "static ");
-    if (Getattr(n, "override"))
-      Printf(function_code, "override ");
-    else if (checkAttribute(n, "storage", "virtual"))
-      Printf(function_code, "virtual ");
-
-    Printf(function_code, "%s %s(", return_type, proxy_function_name);
-
-    Printv(imcall, m3raw_name, ".", intermediary_function_name, "(", NIL);
-    if (!static_flag)
-      Printv(imcall, "swigCPtr", NIL);
-
-    emit_mark_varargs(l);
-
-    int gencomma = !static_flag;
-
-    /* Output each parameter */
-    for (i = 0, p = l; p; i++) {
-
-      /* Ignored varargs */
-      if (checkAttribute(p, "varargs:ignore", "1")) {
-	p = nextSibling(p);
-	continue;
-      }
-
-      /* Ignored parameters */
-      if (checkAttribute(p, "tmap:in:numinputs", "0")) {
-	p = Getattr(p, "tmap:in:next");
-	continue;
-      }
-
-      /* Ignore the 'this' argument for variable wrappers */
-      if (!(variable_wrapper_flag && i == 0)) {
-	SwigType *pt = Getattr(p, "type");
-	String *param_type = NewString("");
-
-	/* Get the Modula 3 parameter type */
-	if ((tm = getMappedType(p, "m3wraptype"))) {
-	  substituteClassname(pt, tm);
-	  Printf(param_type, "%s", tm);
-	}
-
-	if (gencomma)
-	  Printf(imcall, ", ");
-
-	String *arg = variable_wrapper_flag ? NewString("value") : makeParameterName(n,
-										     p,
-										     i);
-
-	// Use typemaps to transform type used in Modula 3 wrapper function (in proxy class) to type used in PInvoke function (in intermediary class)
-	if ((tm = getMappedType(p, "in"))) {
-	  addThrows(throws_hash, "in", p);
-	  substituteClassname(pt, tm);
-	  Replaceall(tm, "$input", arg);
-	  Printv(imcall, tm, NIL);
-	}
-
-	/* Add parameter to proxy function */
-	if (gencomma >= 2)
-	  Printf(function_code, ", ");
-	gencomma = 2;
-	Printf(function_code, "%s %s", param_type, arg);
-
-	Delete(arg);
-	Delete(param_type);
-      }
-      p = Getattr(p, "tmap:in:next");
-    }
-
-    Printf(imcall, ")");
-    Printf(function_code, ")");
-
-    // Transform return type used in PInvoke function (in intermediary class) to type used in Modula 3 wrapper function (in proxy class)
-    if ((tm = getMappedTypeNew(n, "m3out", ""))) {
-      addThrows(throws_hash, "m3out", n);
-      if (GetFlag(n, "feature:new"))
-	Replaceall(tm, "$owner", "true");
-      else
-	Replaceall(tm, "$owner", "false");
-      substituteClassname(t, tm);
-      Replaceall(tm, "$imcall", imcall);
-    }
-
-    generateThrowsClause(throws_hash, function_code);
-    Printf(function_code, " %s\n\n", tm ? (const String *) tm : empty_string);
-
-    if (proxy_flag && wrapping_member_flag && !enum_constant_flag) {
-      // Properties
-      if (setter_flag) {
-	// Setter method
-	if ((tm = getMappedTypeNew(n, "m3varin", ""))) {
-	  if (GetFlag(n, "feature:new"))
-	    Replaceall(tm, "$owner", "true");
-	  else
-	    Replaceall(tm, "$owner", "false");
-	  substituteClassname(t, tm);
-	  Replaceall(tm, "$imcall", imcall);
-	  Printf(proxy_class_code, "%s", tm);
-	}
-      } else {
-	// Getter method
-	if ((tm = getMappedTypeNew(n, "m3varout", ""))) {
-	  if (GetFlag(n, "feature:new"))
-	    Replaceall(tm, "$owner", "true");
-	  else
-	    Replaceall(tm, "$owner", "false");
-	  substituteClassname(t, tm);
-	  Replaceall(tm, "$imcall", imcall);
-	  Printf(proxy_class_code, "%s", tm);
-	}
-      }
-    } else {
-      // Normal function call
-      Printv(proxy_class_code, function_code, NIL);
-    }
-
-    Delete(function_code);
-    Delete(return_type);
-    Delete(imcall);
-    Delete(throws_hash);
-  }
-
-  /* ----------------------------------------------------------------------
-   * constructorHandler()
-   * ---------------------------------------------------------------------- */
-
-  virtual int constructorHandler(Node *n) {
-    // this invokes functionWrapper
-    Language::constructorHandler(n);
-
-    if (proxy_flag) {
-      ParmList *l = Getattr(n, "parms");
-
-      Hash *throws_hash = NewHash();
-      String *overloaded_name = getOverloadedName(n);
-      String *imcall = NewString("");
-
-      Printf(proxy_class_code, "  %s %s(", Getattr(n, "feature:modula3:methodmodifiers"), proxy_class_name);
-      Printv(imcall, " : this(", m3raw_name, ".", Swig_name_construct(NSPACE_TODO, overloaded_name), "(", NIL);
-
-      /* Attach the non-standard typemaps to the parameter list */
-      Swig_typemap_attach_parms("in", l, NULL);
-      Swig_typemap_attach_parms("m3wraptype", l, NULL);
-      Swig_typemap_attach_parms("m3in", l, NULL);
-
-      emit_mark_varargs(l);
-
-      int gencomma = 0;
-
-      String *tm;
-      Parm *p = l;
-      int i;
-
-      /* Output each parameter */
-      for (i = 0; p; i++) {
-
-	/* Ignored varargs */
-	if (checkAttribute(p, "varargs:ignore", "1")) {
-	  p = nextSibling(p);
-	  continue;
-	}
-
-	/* Ignored parameters */
-	if (checkAttribute(p, "tmap:in:numinputs", "0")) {
-	  p = Getattr(p, "tmap:in:next");
-	  continue;
-	}
-
-	SwigType *pt = Getattr(p, "type");
-	String *param_type = NewString("");
-
-	/* Get the Modula 3 parameter type */
-	if ((tm = getMappedType(p, "m3wraptype"))) {
-	  substituteClassname(pt, tm);
-	  Printf(param_type, "%s", tm);
-	}
-
-	if (gencomma)
-	  Printf(imcall, ", ");
-
-	String *arg = makeParameterName(n, p, i);
-
-	// Use typemaps to transform type used in Modula 3 wrapper function (in proxy class) to type used in PInvoke function (in intermediary class)
-	if ((tm = getMappedType(p, "in"))) {
-	  addThrows(throws_hash, "in", p);
-	  substituteClassname(pt, tm);
-	  Replaceall(tm, "$input", arg);
-	  Printv(imcall, tm, NIL);
-	}
-
-	/* Add parameter to proxy function */
-	if (gencomma)
-	  Printf(proxy_class_code, ", ");
-	Printf(proxy_class_code, "%s %s", param_type, arg);
-	gencomma = 1;
-
-	Delete(arg);
-	Delete(param_type);
-	p = Getattr(p, "tmap:in:next");
-      }
-
-      Printf(imcall, "), true)");
-
-      Printf(proxy_class_code, ")");
-      Printf(proxy_class_code, "%s", imcall);
-      generateThrowsClause(throws_hash, proxy_class_code);
-      Printf(proxy_class_code, " {\n");
-      Printf(proxy_class_code, "  }\n\n");
-
-      if (!gencomma)		// We must have a default constructor
-	have_default_constructor_flag = true;
-
-      Delete(overloaded_name);
-      Delete(imcall);
-      Delete(throws_hash);
-    }
-
-    return SWIG_OK;
-  }
-
-  /* ----------------------------------------------------------------------
-   * destructorHandler()
-   * ---------------------------------------------------------------------- */
-
-  virtual int destructorHandler(Node *n) {
-    Language::destructorHandler(n);
-    String *symname = Getattr(n, "sym:name");
-
-    if (proxy_flag) {
-      Printv(destructor_call, m3raw_name, ".", Swig_name_destroy(NSPACE_TODO, symname), "(swigCPtr)", NIL);
-    }
-    return SWIG_OK;
-  }
-
-  /* ----------------------------------------------------------------------
-   * membervariableHandler()
-   * ---------------------------------------------------------------------- */
-
-  virtual int membervariableHandler(Node *n) {
-    //printf("begin membervariableHandler(%s)\n", Char(Getattr(n,"name")));
-    SwigType *t = Getattr(n, "type");
-    String *tm;
-
-    // Get the variable type
-    if ((tm = getMappedTypeNew(n, "m3wraptype", ""))) {
-      substituteClassname(t, tm);
-    }
-
-    variable_name = Getattr(n, "sym:name");
-    //printf("member variable: %s\n", Char(variable_name));
-
-    // Output the property's field declaration and accessor methods
-    Printf(proxy_class_code, "  public %s %s {", tm, variable_name);
-
-    Setattr(n, "modula3:functype", "accessor");
-    wrapping_member_flag = true;
-    variable_wrapper_flag = true;
-    Language::membervariableHandler(n);
-    wrapping_member_flag = false;
-    variable_wrapper_flag = false;
-
-    Printf(proxy_class_code, "\n  }\n\n");
-
-    {
-      String *methods = getMethodDeclarations(n);
-      String *overrides = getAttrString(parentNode(n), "modula3:override");
-      SwigType *type = Getattr(n, "type");
-      String *m3name = capitalizeFirst(variable_name);
-      //String *m3name    = nameToModula3(variable_name,true);
-      if (!SwigType_isconst(type)) {
-	{
-	  String *inmode = getMappedTypeNew(n, "m3wrapinmode", "", false);
-	  String *intype = getMappedTypeNew(n, "m3wrapintype", "");
-	  Printf(methods, "set%s(%s val:%s);\n", m3name, (inmode != NIL) ? (const String *) inmode : "", intype);
-	}
-	{
-	  /* this was attached by functionWrapper
-	     invoked by Language::memberfunctionHandler */
-	  String *fname = Getattr(n, "modula3:setname");
-	  Printf(overrides, "set%s := %s;\n", m3name, fname);
-	}
-      }
-      {
-	{
-	  String *outtype = getMappedTypeNew(n, "m3wrapouttype", "");
-	  Printf(methods, "get%s():%s;\n", m3name, outtype);
-	}
-	{
-	  /* this was attached by functionWrapper
-	     invoked by Language::memberfunctionHandler */
-	  String *fname = Getattr(n, "modula3:getname");
-	  Printf(overrides, "get%s := %s;\n", m3name, fname);
-	}
-      }
-      Delete(m3name);
-    }
-    //printf("end membervariableHandler(%s)\n", Char(Getattr(n,"name")));
-
-    return SWIG_OK;
-  }
-
-  /* ----------------------------------------------------------------------
-   * staticmembervariableHandler()
-   * ---------------------------------------------------------------------- */
-
-  virtual int staticmembervariableHandler(Node *n) {
-
-    bool static_const_member_flag = (Getattr(n, "value") == 0);
-    if (static_const_member_flag) {
-      SwigType *t = Getattr(n, "type");
-      String *tm;
-
-      // Get the variable type
-      if ((tm = getMappedTypeNew(n, "m3wraptype", ""))) {
-	substituteClassname(t, tm);
-      }
-      // Output the property's field declaration and accessor methods
-      Printf(proxy_class_code, "  public static %s %s {", tm, Getattr(n, "sym:name"));
-    }
-
-    variable_name = Getattr(n, "sym:name");
-    wrapping_member_flag = true;
-    static_flag = true;
-    Language::staticmembervariableHandler(n);
-    wrapping_member_flag = false;
-    static_flag = false;
-
-    if (static_const_member_flag)
-      Printf(proxy_class_code, "\n  }\n\n");
-
-    return SWIG_OK;
-  }
-
-  /* ----------------------------------------------------------------------
-   * memberconstantHandler()
-   * ---------------------------------------------------------------------- */
-
-  virtual int memberconstantHandler(Node *n) {
-    variable_name = Getattr(n, "sym:name");
-    wrapping_member_flag = true;
-    Language::memberconstantHandler(n);
-    wrapping_member_flag = false;
-    return SWIG_OK;
-  }
-
-  /* -----------------------------------------------------------------------------
-   * getOverloadedName()
-   * ----------------------------------------------------------------------------- */
-
-  String *getOverloadedName(Node *n) {
-    String *overloaded_name = Copy(Getattr(n, "sym:name"));
-
-    if (Getattr(n, "sym:overloaded")) {
-      Printv(overloaded_name, Getattr(n, "sym:overname"), NIL);
-    }
-
-    return overloaded_name;
-  }
-
-  /* -----------------------------------------------------------------------------
-   * emitM3Wrapper()
-   * It is also used for set and get methods of global variables.
-   * ----------------------------------------------------------------------------- */
-
-  void emitM3Wrapper(Node *n, const String *func_name) {
-    SwigType *t = Getattr(n, "type");
-    ParmList *l = Getattr(n, "parms");
-    Hash *throws_hash = NewHash();
-    int num_exceptions = 0;
-    int num_returns = 0;
-    String *rawcall = NewString("");
-    String *reccall = NewString("");
-    String *local_variables = NewString("");
-    String *local_constants = NewString("");
-    String *incheck = NewString("");
-    String *outcheck = NewString("");
-    String *setup = NewString("");
-    String *cleanup = NewString("");
-    String *outarg = NewString("");	/* don't mix up with 'autark' :-] */
-    String *storeout = NewString("");
-    String *result_name = NewString("");
-    String *return_variables = NewString("");
-    const char *result_return = "ret";
-    String *function_code = NewString("");
-    /*several names for the same function */
-    String *raw_name = Getattr(n, "name");	/*original C function name */
-    //String     *func_name = Getattr(n,"sym:name");  /*final Modula3 name chosen by the user*/
-    bool setter_flag = false;
-    int multiretval = GetFlag(n, "feature:modula3:multiretval");
-
-    if (l) {
-      if (SwigType_type(Getattr(l, "type")) == T_VOID) {
-	l = nextSibling(l);
-      }
-    }
-
-    /* Attach the non-standard typemaps to the parameter list */
-    Swig_typemap_attach_parms("m3wrapargvar", l, NULL);
-    Swig_typemap_attach_parms("m3wrapargconst", l, NULL);
-    Swig_typemap_attach_parms("m3wrapargraw", l, NULL);
-    Swig_typemap_attach_parms("m3wrapargdir", l, NULL);
-    Swig_typemap_attach_parms("m3wrapinmode", l, NULL);
-    Swig_typemap_attach_parms("m3wrapinname", l, NULL);
-    Swig_typemap_attach_parms("m3wrapintype", l, NULL);
-    Swig_typemap_attach_parms("m3wrapindefault", l, NULL);
-    Swig_typemap_attach_parms("m3wrapinconv", l, NULL);
-    Swig_typemap_attach_parms("m3wrapincheck", l, NULL);
-    Swig_typemap_attach_parms("m3wrapoutname", l, NULL);
-    Swig_typemap_attach_parms("m3wrapouttype", l, NULL);
-    Swig_typemap_attach_parms("m3wrapoutconv", l, NULL);
-    Swig_typemap_attach_parms("m3wrapoutcheck", l, NULL);
-
-    attachMappedType(n, "m3wrapretraw");
-    attachMappedType(n, "m3wrapretname");
-    attachMappedType(n, "m3wraprettype");
-    attachMappedType(n, "m3wrapretvar");
-    attachMappedType(n, "m3wrapretconv");
-    attachMappedType(n, "m3wrapretcheck");
-
-    Swig_typemap_attach_parms("m3wrapfreearg", l, NULL);
-
-/*
-    Swig_typemap_attach_parms("m3wrapargvar:throws", l, NULL);
-    Swig_typemap_attach_parms("m3wrapargraw:throws", l, NULL);
-    Swig_typemap_attach_parms("m3wrapinconv:throws", l, NULL);
-    Swig_typemap_attach_parms("m3wrapincheck:throws", l, NULL);
-    Swig_typemap_attach_parms("m3wrapoutconv:throws", l, NULL);
-    Swig_typemap_attach_parms("m3wrapoutcheck:throws", l, NULL);
-
-    attachMappedType(n, "m3wrapretvar:throws");
-    attachMappedType(n, "m3wrapretconv:throws");
-    attachMappedType(n, "m3wrapretcheck:throws");
-
-    Swig_typemap_attach_parms("m3wrapfreearg:throws", l, NULL);
-*/
-
-    /* Attach argument names to the parameter list */
-    /* should be a separate procedure making use of hashes */
-    attachParameterNames(n, "tmap:m3wrapinname", "autoname", "arg%d");
-
-    /* Get return types */
-    String *result_m3rawtype = Copy(getMappedTypeNew(n, "m3rawrettype", ""));
-    String *result_m3wraptype = Copy(getMappedTypeNew(n, "m3wraprettype", ""));
-    bool has_return_raw = hasContent(result_m3rawtype);
-    bool has_return_m3 = hasContent(result_m3wraptype);
-    if (has_return_m3) {
-      num_returns++;
-      //printf("%s: %s\n", Char(func_name),Char(result_m3wraptype));
-    }
-
-    String *arguments = createM3Signature(n);
-
-    /* Create local variables or RECORD fields for return values
-       and determine return type that might result from a converted VAR argument. */
-    {
-      writeArgState state;
-      if (multiretval && has_return_m3) {
-	writeArg(return_variables, state, NIL, NewString(result_return), result_m3wraptype, NIL);
-      }
-
-      Parm *p = skipIgnored(l, "m3wrapouttype");
-      while (p != NIL) {
-
-	String *arg = Getattr(p, "tmap:m3wrapoutname");
-	if (arg == NIL) {
-	  arg = Getattr(p, "name");
-	}
-
-	String *tm = Getattr(p, "tmap:m3wrapouttype");
-	if (tm != NIL) {
-	  if (isOutParam(p)) {
-	    if (!multiretval) {
-	      if (num_returns == 0) {
-		Printv(result_name, arg, NIL);
-		Clear(result_m3wraptype);
-		Printv(result_m3wraptype, tm, NIL);
-	      } else {
-		Swig_warning(WARN_MODULA3_TYPEMAP_MULTIPLE_RETURN, input_file, line_number,
-			     "Typemap m3wrapargdir set to 'out' for %s implies a RETURN value, but the routine %s has already one.\nUse %%multiretval feature.\n",
-			     SwigType_str(Getattr(p, "type"), 0), raw_name);
-	      }
-	    }
-	    num_returns++;
-	    addImports(m3wrap_intf.import, "m3wrapouttype", p);
-	    writeArg(return_variables, state, NIL, arg, tm, NIL);
-	  }
-	  p = skipIgnored(Getattr(p, "tmap:m3wrapouttype:next"), "m3wrapouttype");
-	} else {
-	  p = nextSibling(p);
-	}
-      }
-      writeArg(return_variables, state, NIL, NIL, NIL, NIL);
-
-      if (multiretval) {
-	Printv(result_name, Swig_cresult_name(), NIL);
-	Printf(result_m3wraptype, "%sResult", func_name);
-	m3wrap_intf.enterBlock(blocktype);
-	Printf(m3wrap_intf.f, "%s =\nRECORD\n%sEND;\n", result_m3wraptype, return_variables);
-	Printf(local_variables, "%s: %s;\n", result_name, result_m3wraptype);
-      } else {
-	Append(local_variables, return_variables);
-      }
-    }
-
-    /* Declare local constants e.g. for storing argument names. */
-    {
-      Parm *p = l;
-      while (p != NIL) {
-
-	String *arg = Getattr(p, "autoname");
-
-	String *tm = Getattr(p, "tmap:m3wrapargconst");
-	if (tm != NIL) {
-	  addImports(m3wrap_impl.import, "m3wrapargconst", p);
-	  Replaceall(tm, "$input", arg);
-	  Printv(local_constants, tm, "\n", NIL);
-	  p = Getattr(p, "tmap:m3wrapargconst:next");
-	} else {
-	  p = nextSibling(p);
-	}
-
-      }
-    }
-
-    /* Declare local variables e.g. for converted input values. */
-    {
-      String *tm = getMappedTypeNew(n, "m3wrapretvar", "", false);
-      if (tm != NIL) {
-	addImports(m3wrap_impl.import, "m3wrapretvar", n);
-	addThrows(throws_hash, "m3wrapretvar", n);
-	Printv(local_variables, tm, "\n", NIL);
-      }
-
-      Parm *p = l;
-      while (p != NIL) {
-
-	String *arg = Getattr(p, "autoname");
-
-	tm = Getattr(p, "tmap:m3wrapargvar");
-	if (tm != NIL) {
-	  /* exceptions that may be raised but can't be caught,
-	     thus we won't count them in num_exceptions */
-	  addImports(m3wrap_impl.import, "m3wrapargvar", p);
-	  addThrows(throws_hash, "m3wrapargvar", p);
-	  Replaceall(tm, "$input", arg);
-	  Printv(local_variables, tm, "\n", NIL);
-	  p = Getattr(p, "tmap:m3wrapargvar:next");
-	} else {
-	  p = nextSibling(p);
-	}
-
-      }
-    }
-
-    /* Convert input values from Modula 3 to C. */
-    {
-      Parm *p = l;
-      while (p != NIL) {
-
-	String *arg = Getattr(p, "autoname");
-
-	String *tm = Getattr(p, "tmap:m3wrapinconv");
-	if (tm != NIL) {
-	  addImports(m3wrap_impl.import, "m3wrapinconv", p);
-	  num_exceptions += addThrows(throws_hash, "m3wrapinconv", p);
-	  Replaceall(tm, "$input", arg);
-	  Printv(setup, tm, "\n", NIL);
-	  p = Getattr(p, "tmap:m3wrapinconv:next");
-	} else {
-	  p = nextSibling(p);
-	}
-
-      }
-    }
-
-    /* Generate checks for input value integrity. */
-    {
-      Parm *p = l;
-      while (p != NIL) {
-
-	String *arg = Getattr(p, "autoname");
-
-	String *tm = Getattr(p, "tmap:m3wrapincheck");
-	if (tm != NIL) {
-	  addImports(m3wrap_impl.import, "m3wrapincheck", p);
-	  num_exceptions += addThrows(throws_hash, "m3wrapincheck", p);
-	  Replaceall(tm, "$input", arg);
-	  Printv(incheck, tm, "\n", NIL);
-	  p = Getattr(p, "tmap:m3wrapincheck:next");
-	} else {
-	  p = nextSibling(p);
-	}
-
-      }
-    }
-
-    Printv(rawcall, m3raw_name, ".", func_name, "(", NIL);
-    /* Arguments to the raw C function */
-    {
-      bool gencomma = false;
-      Parm *p = l;
-      while (p != NIL) {
-	if (gencomma) {
-	  Printf(rawcall, ", ");
-	}
-	gencomma = true;
-	addImports(m3wrap_impl.import, "m3wrapargraw", p);
-	num_exceptions += addThrows(throws_hash, "m3wrapargraw", p);
-
-	String *arg = Getattr(p, "autoname");
-	String *qualarg = NewString("");
-	if (!isInParam(p)) {
-	  String *tmparg = Getattr(p, "tmap:m3wrapoutname");
-	  if (tmparg != NIL) {
-	    arg = tmparg;
-	  }
-	  if (multiretval /*&& isOutParam(p) - automatically fulfilled */ ) {
-	    Printf(qualarg, "%s.", result_name);
-	  }
-	}
-	Append(qualarg, arg);
-	Setattr(p, "m3outarg", qualarg);
-
-	String *tm = Getattr(p, "tmap:m3wrapargraw");
-	if (tm != NIL) {
-	  Replaceall(tm, "$input", arg);
-	  Replaceall(tm, "$output", qualarg);
-	  Printv(rawcall, tm, NIL);
-	  p = Getattr(p, "tmap:m3wrapargraw:next");
-	} else {
-	  //Printv(rawcall, Getattr(p,"lname"), NIL);
-	  Printv(rawcall, qualarg, NIL);
-	  p = nextSibling(p);
-	}
-	Delete(qualarg);
-      }
-    }
-    Printf(rawcall, ")");
-
-    /* Check for error codes and integrity of results */
-    {
-      String *tm = getMappedTypeNew(n, "m3wrapretcheck", "", false);
-      if (tm != NIL) {
-	addImports(m3wrap_impl.import, "m3wrapretcheck", n);
-	num_exceptions += addThrows(throws_hash, "m3wrapretcheck", n);
-	Printv(outcheck, tm, "\n", NIL);
-      }
-
-      Parm *p = l;
-      while (p != NIL) {
-	tm = Getattr(p, "tmap:m3wrapoutcheck");
-	if (tm != NIL) {
-	  String *arg = Getattr(p, "autoname");
-	  String *outarg = Getattr(p, "m3outarg");
-	  addImports(m3wrap_impl.import, "m3wrapoutcheck", p);
-	  num_exceptions += addThrows(throws_hash, "m3wrapoutcheck", p);
-	  //substituteClassname(Getattr(p,"type"), tm);
-	  Replaceall(tm, "$input", arg);
-	  Replaceall(tm, "$output", outarg);
-	  Printv(outcheck, tm, "\n", NIL);
-	  p = Getattr(p, "tmap:m3wrapoutcheck:next");
-	} else {
-	  p = nextSibling(p);
-	}
-      }
-    }
-
-    /* Convert the results to Modula 3 data structures and
-       put them in the record prepared for returning */
-    {
-      /* m3wrapretconv is processed
-         when it is clear if there is some output conversion and checking code */
-      Parm *p = l;
-      while (p != NIL) {
-	String *tm = Getattr(p, "tmap:m3wrapoutconv");
-	if (tm != NIL) {
-	  String *arg = Getattr(p, "autoname");
-	  String *outarg = Getattr(p, "m3outarg");
-	  addImports(m3wrap_impl.import, "m3wrapoutconv", n);
-	  num_exceptions += addThrows(throws_hash, "m3wrapoutconv", p);
-	  //substituteClassname(Getattr(p,"type"), tm);
-	  Replaceall(tm, "$input", arg);
-	  Replaceall(tm, "$output", outarg);
-	  Printf(storeout, "%s := %s;\n", outarg, tm);
-	  p = Getattr(p, "tmap:m3wrapoutconv:next");
-	} else {
-	  p = nextSibling(p);
-	}
-      }
-    }
-
-    /* Generate cleanup code */
-    {
-      Parm *p = l;
-      while (p != NIL) {
-	String *tm = Getattr(p, "tmap:m3wrapfreearg");
-	if (tm != NIL) {
-	  String *arg = Getattr(p, "autoname");
-	  String *outarg = Getattr(p, "m3outarg");
-	  addImports(m3wrap_impl.import, "m3wrapfreearg", p);
-	  num_exceptions += addThrows(throws_hash, "m3wrapfreearg", p);
-	  //substituteClassname(Getattr(p,"type"), tm);
-	  Replaceall(tm, "$input", arg);
-	  Replaceall(tm, "$output", outarg);
-	  Printv(cleanup, tm, "\n", NIL);
-	  p = Getattr(p, "tmap:m3wrapfreearg:next");
-	} else {
-	  p = nextSibling(p);
-	}
-      }
-    }
-
-    {
-      /* Currently I don't know how a typemap similar to the original 'out' typemap
-         could help returning the return value. */
-      /* Receive result from call to raw library function */
-      if (!has_return_raw) {
-	/*
-	   rawcall(arg1);
-	   result.val := arg1;
-	   RETURN result;
-	 */
-	/*
-	   rawcall(arg1);
-	   RETURN arg1;
-	 */
-	Printf(reccall, "%s;\n", rawcall);
-
-	if (hasContent(result_name)) {
-	  Printf(outarg, "RETURN %s;\n", result_name);
-	}
-      } else {
-	/*
-	   arg0 := rawcall(arg1);
-	   result.ret := Convert(arg0);
-	   result.val := arg1;
-	   RETURN result;
-	 */
-	/*
-	   arg0 := rawcall();
-	   RETURN Convert(arg0);
-	 */
-	/*
-	   RETURN rawcall();
-	 */
-	String *return_raw = getMappedTypeNew(n, "m3wrapretraw", "", false);
-	String *return_conv = getMappedTypeNew(n, "m3wrapretconv", "", false);
-
-	/* immediate RETURN would skip result checking */
-	if ((hasContent(outcheck) || hasContent(storeout)
-	     || hasContent(cleanup)) && (!hasContent(result_name))
-	    && (return_raw == NIL)) {
-	  Printv(result_name, Swig_cresult_name(), NIL);
-	  Printf(local_variables, "%s: %s;\n", result_name, result_m3wraptype);
-	}
-
-	String *result_lvalue = Copy(result_name);
-	if (multiretval) {
-	  Printf(result_lvalue, ".%s", result_return);
-	}
-	if (return_raw != NIL) {
-	  Printf(reccall, "%s := %s;\n", return_raw, rawcall);
-	} else if (hasContent(result_name)) {
-	  Printf(reccall, "%s := %s;\n", result_lvalue, rawcall);
-	} else {
-	  Printf(outarg, "RETURN %s;\n", rawcall);
-	}
-	if (return_conv != NIL) {
-	  addImports(m3wrap_impl.import, "m3wrapretconv", n);
-	  num_exceptions += addThrows(throws_hash, "m3wrapretconv", n);
-	  if (hasContent(result_name)) {
-	    Printf(reccall, "%s := %s;\n", result_lvalue, return_conv);
-	    Printf(outarg, "RETURN %s;\n", result_name);
-	  } else {
-	    Printf(outarg, "RETURN %s;\n", return_conv);
-	  }
-	} else {
-	  if (hasContent(result_name)) {
-	    Printf(outarg, "RETURN %s;\n", result_name);
-	  }
-	}
-      }
-    }
-
-    /* Create procedure header */
-    {
-      String *header = NewStringf("PROCEDURE %s (%s)",
-				  func_name, arguments);
-
-      if ((num_returns > 0) || multiretval) {
-	Printf(header, ": %s", result_m3wraptype);
-      }
-      generateThrowsClause(throws_hash, header);
-
-      Append(function_code, header);
-
-      m3wrap_intf.enterBlock(no_block);
-      Printf(m3wrap_intf.f, "%s;\n\n", header);
-    }
-
-    {
-      String *body = NewStringf("%s%s%s%s%s",
-				incheck,
-				setup,
-				reccall,
-				outcheck,
-				storeout);
-
-      String *exc_handler;
-      if (hasContent(cleanup) && (num_exceptions > 0)) {
-	exc_handler = NewStringf("TRY\n%sFINALLY\n%sEND;\n", body, cleanup);
-      } else {
-	exc_handler = NewStringf("%s%s", body, cleanup);
-      }
-
-      Printf(function_code, " =\n%s%s%s%sBEGIN\n%s%sEND %s;\n\n",
-	     hasContent(local_constants) ? "CONST\n" : "", local_constants,
-	     hasContent(local_variables) ? "VAR\n" : "", local_variables, exc_handler, outarg, func_name);
-
-      Delete(exc_handler);
-      Delete(body);
-    }
-
-    m3wrap_impl.enterBlock(no_block);
-    if (proxy_flag && global_variable_flag) {
-      setter_flag = (Cmp(Getattr(n, "sym:name"), Swig_name_set(NSPACE_TODO, variable_name)) == 0);
-      // Properties
-      if (setter_flag) {
-	// Setter method
-	String *tm = getMappedTypeNew(n, "m3varin", "");
-	if (tm != NIL) {
-	  if (GetFlag(n, "feature:new")) {
-	    Replaceall(tm, "$owner", "true");
-	  } else {
-	    Replaceall(tm, "$owner", "false");
-	  }
-	  substituteClassname(t, tm);
-	  Replaceall(tm, "$rawcall", rawcall);
-	  Replaceall(tm, "$vartype", variable_type);	/* $type is already replaced by some super class */
-	  Replaceall(tm, "$var", variable_name);
-	  Printf(m3wrap_impl.f, "%s", tm);
-	}
-      } else {
-	// Getter method
-	String *tm = getMappedTypeNew(n, "m3varout", "");
-	if (tm != NIL) {
-	  if (GetFlag(n, "feature:new"))
-	    Replaceall(tm, "$owner", "true");
-	  else
-	    Replaceall(tm, "$owner", "false");
-	  substituteClassname(t, tm);
-	  Replaceall(tm, "$rawcall", rawcall);
-	  Replaceall(tm, "$vartype", variable_type);
-	  Replaceall(tm, "$var", variable_name);
-	  Printf(m3wrap_impl.f, "%s", tm);
-	}
-      }
-    } else {
-      // Normal function call
-      Printv(m3wrap_impl.f, function_code, NIL);
-    }
-
-    Delete(arguments);
-    Delete(return_variables);
-    Delete(local_variables);
-    Delete(local_constants);
-    Delete(outarg);
-    Delete(incheck);
-    Delete(outcheck);
-    Delete(setup);
-    Delete(cleanup);
-    Delete(storeout);
-    Delete(function_code);
-    Delete(result_name);
-    Delete(result_m3wraptype);
-    Delete(reccall);
-    Delete(rawcall);
-    Delete(throws_hash);
-  }
-
-  /*----------------------------------------------------------------------
-   * replaceSpecialVariables()
-   *--------------------------------------------------------------------*/
-
-  virtual void replaceSpecialVariables(String *method, String *tm, Parm *parm) {
-    (void)method;
-    SwigType *type = Getattr(parm, "type");
-    substituteClassname(type, tm);
-  }
-
-  /* -----------------------------------------------------------------------------
-   * substituteClassname()
-   *
-   * Substitute the special variable $m3classname with the proxy class name for classes/structs/unions 
-   * that SWIG knows about.
-   * Otherwise use the $descriptor name for the Modula 3 class name. Note that the $&m3classname substitution
-   * is the same as a $&descriptor substitution, ie one pointer added to descriptor name.
-   * Inputs:
-   *   pt - parameter type
-   *   tm - typemap contents that might contain the special variable to be replaced
-   * Outputs:
-   *   tm - typemap contents complete with the special variable substitution
-   * Return:
-   *   substitution_performed - flag indicating if a substitution was performed
-   * ----------------------------------------------------------------------------- */
-
-  bool substituteClassname(SwigType *pt, String *tm) {
-    bool substitution_performed = false;
-    if (Strstr(tm, "$m3classname") || Strstr(tm, "$&m3classname")) {
-      String *classname = getProxyName(pt);
-      if (classname) {
-	Replaceall(tm, "$&m3classname", classname);	// getProxyName() works for pointers to classes too
-	Replaceall(tm, "$m3classname", classname);
-      } else {			// use $descriptor if SWIG does not know anything about this type. Note that any typedefs are resolved.
-	String *descriptor = NULL;
-	SwigType *type = Copy(SwigType_typedef_resolve_all(pt));
-
-	if (Strstr(tm, "$&m3classname")) {
-	  SwigType_add_pointer(type);
-	  descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type));
-	  Replaceall(tm, "$&m3classname", descriptor);
-	} else {		// $m3classname
-	  descriptor = NewStringf("SWIGTYPE%s", SwigType_manglestr(type));
-	  Replaceall(tm, "$m3classname", descriptor);
-	}
-
-	// Add to hash table so that the type wrapper classes can be created later
-	Setattr(swig_types_hash, descriptor, type);
-	Delete(descriptor);
-	Delete(type);
-      }
-      substitution_performed = true;
-    }
-    return substitution_performed;
-  }
-
-  /* -----------------------------------------------------------------------------
-   * attachParameterNames()
-   *
-   * Inputs: 
-   *   n      - Node of a function declaration
-   *   tmid   - attribute name for overriding C argument names,
-   *              e.g. "tmap:m3wrapinname",
-   *              don't forget to attach the mapped types before
-   *   nameid - attribute for attaching the names,
-   *              e.g. "modula3:inname"
-   *   fmt    - format for the argument name containing %d
-   *              e.g. "arg%d"
-   * ----------------------------------------------------------------------------- */
-
-  void attachParameterNames(Node *n, const char *tmid, const char *nameid, const char *fmt) {
-    /* Use C parameter name if present and unique,
-       otherwise create an 'arg%d' name */
-    Hash *hash = NewHash();
-    Parm *p = Getattr(n, "parms");
-    int count = 0;
-    while (p != NIL) {
-      String *name = Getattr(p, tmid);
-      if (name == NIL) {
-	name = Getattr(p, "name");
-      }
-      String *newname;
-      if ((!hasContent(name)) || (Getattr(hash, name) != NIL)) {
-	newname = NewStringf(fmt, count);
-      } else {
-	newname = Copy(name);
-      }
-      if (1 == Setattr(hash, newname, "1")) {
-	Swig_warning(WARN_MODULA3_DOUBLE_ID, input_file, line_number, "Argument '%s' twice.\n", newname);
-      }
-      Setattr(p, nameid, newname);
-//      Delete(newname);
-      p = nextSibling(p);
-      count++;
-    }
-    Delete(hash);
-  }
-
-  /* -----------------------------------------------------------------------------
-   * createM3Signature()
-   *
-   * Create signature of M3 wrapper procedure
-   * Call attachParameterNames and attach mapped types before!
-   *   m3wrapintype, m3wrapinmode, m3wrapindefault
-   * ----------------------------------------------------------------------------- */
-
-  String *createM3Signature(Node *n) {
-    String *arguments = NewString("");
-    Parm *p = skipIgnored(Getattr(n, "parms"), "m3wrapintype");
-    writeArgState state;
-    while (p != NIL) {
-
-      /* Get the M3 parameter type */
-      String *tm = getMappedType(p, "m3wrapintype");
-      if (tm != NIL) {
-	if (isInParam(p)) {
-	  addImports(m3wrap_intf.import, "m3wrapintype", p);
-	  addImports(m3wrap_impl.import, "m3wrapintype", p);
-	  String *mode = Getattr(p, "tmap:m3wrapinmode");
-	  String *deflt = Getattr(p, "tmap:m3wrapindefault");
-	  String *arg = Getattr(p, "autoname");
-	  SwigType *pt = Getattr(p, "type");
-	  substituteClassname(pt, tm);	/* do we need this ? */
-
-	  writeArg(arguments, state, mode, arg, tm, deflt);
-	}
-	p = skipIgnored(Getattr(p, "tmap:m3wrapintype:next"), "m3wrapintype");
-      } else {
-	p = nextSibling(p);
-      }
-    }
-    writeArg(arguments, state, NIL, NIL, NIL, NIL);
-    return (arguments);
-  }
-
-/* not used any longer
-    - try SwigType_str if required again */
-#if 0
-  /* -----------------------------------------------------------------------------
-   * createCSignature()
-   *
-   * Create signature of C function
-   * ----------------------------------------------------------------------------- */
-
-  String *createCSignature(Node *n) {
-    String *arguments = NewString("");
-    bool gencomma = false;
-    Node *p;
-    for (p = Getattr(n, "parms"); p != NIL; p = nextSibling(p)) {
-      if (gencomma) {
-	Append(arguments, ",");
-      }
-      gencomma = true;
-      String *type = Getattr(p, "type");
-      String *ctype = getMappedTypeNew(type, "ctype");
-      Append(arguments, ctype);
-    }
-    return arguments;
-  }
-#endif
-
-  /* -----------------------------------------------------------------------------
-   * emitTypeWrapperClass()
-   * ----------------------------------------------------------------------------- */
-
-  void emitTypeWrapperClass(String *classname, SwigType *type) {
-    Node *n = NewHash();
-    Setfile(n, input_file);
-    Setline(n, line_number);
-
-    String *filen = NewStringf("%s%s.m3", SWIG_output_directory(), classname);
-    File *f_swigtype = NewFile(filen, "w", SWIG_output_files());
-    if (!f_swigtype) {
-      FileErrorDisplay(filen);
-      SWIG_exit(EXIT_FAILURE);
-    }
-    String *swigtype = NewString("");
-
-    // Emit banner name
-    emitBanner(f_swigtype);
-
-    // Pure Modula 3 baseclass and interfaces
-    const String *pure_baseclass = typemapLookup(n, "m3base", type, WARN_NONE);
-    const String *pure_interfaces = typemapLookup(n, "m3interfaces", type, WARN_NONE);
-
-    // Emit the class
-    Printv(swigtype, typemapLookup(n, "m3imports", type, WARN_NONE),	// Import statements
-	   "\n", typemapLookup(n, "m3classmodifiers", type, WARN_MODULA3_TYPEMAP_CLASSMOD_UNDEF),	// Class modifiers
-	   " class $m3classname",	// Class name and bases
-	   *Char(pure_baseclass) ? " : " : "", pure_baseclass, *Char(pure_interfaces) ?	// Interfaces
-	   " : " : "", pure_interfaces, " {\n", "  private IntPtr swigCPtr;\n", "\n", "  ", typemapLookup(n, "m3ptrconstructormodifiers", type, WARN_MODULA3_TYPEMAP_PTRCONSTMOD_UNDEF),	// pointer constructor modifiers
-	   " $m3classname(IntPtr cPtr, bool bFutureUse) {\n",	// Constructor used for wrapping pointers
-	   "    swigCPtr = cPtr;\n", "  }\n", "\n", "  protected $m3classname() {\n",	// Default constructor
-	   "    swigCPtr = IntPtr.Zero;\n", "  }\n", typemapLookup(n, "m3getcptr", type, WARN_MODULA3_TYPEMAP_GETCPTR_UNDEF),	// getCPtr method
-	   typemapLookup(n, "m3code", type, WARN_NONE),	// extra Modula 3 code
-	   "}\n", "\n", NIL);
-
-    Replaceall(swigtype, "$m3classname", classname);
-    Printv(f_swigtype, swigtype, NIL);
-
-    Delete(f_swigtype);
-    Delete(filen);
-    Delete(swigtype);
-  }
-
-  /* -----------------------------------------------------------------------------
-   * typemapLookup()
-   * n - for input only and must contain info for Getfile(n) and Getline(n) to work
-   * tmap_method - typemap method name
-   * type - typemap type to lookup
-   * warning - warning number to issue if no typemaps found
-   * typemap_attributes - the typemap attributes are attached to this node and will 
-   *   also be used for temporary storage if non null
-   * return is never NULL, unlike Swig_typemap_lookup()
-   * ----------------------------------------------------------------------------- */
-
-  const String *typemapLookup(Node *n, const_String_or_char_ptr tmap_method, SwigType *type, int warning, Node *typemap_attributes = 0) {
-    Node *node = !typemap_attributes ? NewHash() : typemap_attributes;
-    Setattr(node, "type", type);
-    Setfile(node, Getfile(n));
-    Setline(node, Getline(n));
-    const String *tm = Swig_typemap_lookup(tmap_method, node, "", 0);
-    if (!tm) {
-      tm = empty_string;
-      if (warning != WARN_NONE)
-	Swig_warning(warning, Getfile(n), Getline(n), "No %s typemap defined for %s\n", tmap_method, SwigType_str(type, 0));
-    }
-    if (!typemap_attributes)
-      Delete(node);
-    return tm;
-  }
-
-  /* -----------------------------------------------------------------------------
-   * addThrows()
-   *
-   * Add all exceptions to a hash that are associated with the 'typemap'.
-   * Return number the number of these exceptions.
-   * ----------------------------------------------------------------------------- */
-
-  int addThrows(Hash *throws_hash, const String *typemap, Node *parameter) {
-    // Get the comma separated throws clause - held in "throws" attribute in the typemap passed in
-    int len = 0;
-    String *throws_attribute = NewStringf("%s:throws", typemap);
-
-    addImports(m3wrap_intf.import, throws_attribute, parameter);
-    addImports(m3wrap_impl.import, throws_attribute, parameter);
-
-    String *throws = getMappedTypeNew(parameter, Char(throws_attribute), "", false);
-    //printf("got exceptions %s for %s\n", Char(throws), Char(throws_attribute));
-
-    if (throws) {
-      // Put the exception classes in the throws clause into a temporary List
-      List *temp_classes_list = Split(throws, ',', INT_MAX);
-      len = Len(temp_classes_list);
-
-      // Add the exception classes to the node throws list, but don't duplicate if already in list
-      if (temp_classes_list /*&& hasContent(temp_classes_list) */ ) {
-	for (Iterator cls = First(temp_classes_list); cls.item != NIL; cls = Next(cls)) {
-	  String *exception_class = NewString(cls.item);
-	  Replaceall(exception_class, " ", "");	// remove spaces
-	  Replaceall(exception_class, "\t", "");	// remove tabs
-	  if (hasContent(exception_class)) {
-	    // $m3classname substitution
-	    SwigType *pt = Getattr(parameter, "type");
-	    substituteClassname(pt, exception_class);
-	    // Don't duplicate the exception class in the throws clause
-	    //printf("add exception %s\n", Char(exception_class));
-	    Setattr(throws_hash, exception_class, "1");
-	  }
-	  Delete(exception_class);
-	}
-      }
-      Delete(temp_classes_list);
-    }
-    Delete(throws_attribute);
-    return len;
-  }
-
-  /* -----------------------------------------------------------------------------
-   * generateThrowsClause()
-   * ----------------------------------------------------------------------------- */
-
-  void generateThrowsClause(Hash *throws_hash, String *code) {
-    // Add the throws clause into code
-    if (Len(throws_hash) > 0) {
-      Iterator cls = First(throws_hash);
-      Printf(code, " RAISES {%s", cls.key);
-      for (cls = Next(cls); cls.key != NIL; cls = Next(cls)) {
-	Printf(code, ", %s", cls.key);
-      }
-      Printf(code, "}");
-    }
-  }
-
-  /* -----------------------------------------------------------------------------
-   * addImports()
-   *
-   * Add all imports that are needed for contents of 'typemap'.
-   * ----------------------------------------------------------------------------- */
-
-  void addImports(Hash *imports_hash, const String *typemap, Node *node) {
-    // Get the comma separated throws clause - held in "throws" attribute in the typemap passed in
-    String *imports_attribute = NewStringf("%s:import", typemap);
-    String *imports = getMappedTypeNew(node, Char(imports_attribute), "", false);
-    //printf("got imports %s for %s\n", Char(imports), Char(imports_attribute));
-
-    if (imports != NIL) {
-      List *import_list = Split(imports, ',', INT_MAX);
-
-      // Add the exception classes to the node imports list, but don't duplicate if already in list
-      if (import_list != NIL) {
-	for (Iterator imp = First(import_list); imp.item != NIL; imp = Next(imp)) {
-	  List *import_pair = Split(imp.item, ' ', 3);
-	  if (Len(import_pair) == 1) {
-	    Setattr(imports_hash, Getitem(import_pair, 0), "");
-	  } else if ((Len(import_pair) == 3)
-		     && Strcmp(Getitem(import_pair, 1), "AS") == 0) {
-	    Setattr(imports_hash, Getitem(import_pair, 0), Getitem(import_pair, 2));
-	  } else {
-	    Swig_warning(WARN_MODULA3_BAD_IMPORT, input_file, line_number,
-			 "Malformed import '%s' for typemap '%s' defined for type '%s'\n", imp, typemap, SwigType_str(Getattr(node, "type"), 0));
-	  }
-	  Delete(import_pair);
-	}
-      }
-      Delete(import_list);
-    }
-    Delete(imports_attribute);
-  }
-
-  /* -----------------------------------------------------------------------------
-   * emitImportStatements()
-   * ----------------------------------------------------------------------------- */
-
-  void emitImportStatements(Hash *imports_hash, String *code) {
-    // Add the imports statements into code
-    Iterator imp = First(imports_hash);
-    while (imp.key != NIL) {
-      Printf(code, "IMPORT %s", imp.key);
-      String *imp_as = imp.item;
-      if (hasContent(imp_as)) {
-	Printf(code, " AS %s", imp_as);
-      }
-      Printf(code, ";\n");
-      imp = Next(imp);
-    }
-  }
-
-};				/* class MODULA3 */
-
-/* -----------------------------------------------------------------------------
- * swig_modula3()    - Instantiate module
- * ----------------------------------------------------------------------------- */
-
-extern "C" Language *swig_modula3(void) {
-  return new MODULA3();
-}
-
-/* -----------------------------------------------------------------------------
- * Static member variables
- * ----------------------------------------------------------------------------- */
-
-const char *MODULA3::usage = "\
-Modula 3 Options (available with -modula3)\n\
-     -generateconst <file>   - Generate code for computing numeric values of constants\n\
-     -generaterename <file>  - Generate suggestions for %rename\n\
-     -generatetypemap <file> - Generate templates for some basic typemaps\n\
-     -oldvarnames            - Old intermediary method names for variable wrappers\n\
-\n";
-
-/*
-     -generateconst <file> - stem of the .c source file for computing the numeric values of constants\n\
-     -generaterename <file> - stem of the .i source file containing %rename suggestions\n\
-     -generatetypemap <file> - stem of the .i source file containing typemap patterns\n\
-*/
diff --git a/Source/Modules/mzscheme.cxx b/Source/Modules/mzscheme.cxx
index 7886813..d1bf085 100644
--- a/Source/Modules/mzscheme.cxx
+++ b/Source/Modules/mzscheme.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * mzscheme.cxx
  *
@@ -12,7 +12,6 @@
  * ----------------------------------------------------------------------------- */
 
 #include "swigmod.h"
-
 #include <ctype.h>
 
 static const char *usage = "\
@@ -66,7 +65,7 @@
       if (argv[i]) {
 	if (strcmp(argv[i], "-help") == 0) {
 	  fputs(usage, stdout);
-	  SWIG_exit(0);
+	  Exit(EXIT_SUCCESS);
 	} else if (strcmp(argv[i], "-prefix") == 0) {
 	  if (argv[i + 1]) {
 	    prefix = NewString(argv[i + 1]);
@@ -130,7 +129,7 @@
     f_begin = NewFile(outfile, "w", SWIG_output_files());
     if (!f_begin) {
       FileErrorDisplay(outfile);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
     f_runtime = NewString("");
     f_init = NewString("");
@@ -148,7 +147,7 @@
 
     Swig_banner(f_begin);
 
-    Printf(f_runtime, "\n\n#ifndef SWIGMZSCHEME\n#define SWIGMZSCHEME\n#endif\n\n");
+    Swig_obligatory_macros(f_runtime, "MZSCHEME");
 
     module = Getattr(n, "name");
 
@@ -322,8 +321,6 @@
       }
       // Handle parameter types.
       if ((tm = Getattr(p, "tmap:in"))) {
-	Replaceall(tm, "$source", source);
-	Replaceall(tm, "$target", target);
 	Replaceall(tm, "$input", source);
 	Setattr(p, "emit:input", source);
 	Printv(f->code, tm, "\n", NIL);
@@ -343,7 +340,6 @@
     /* Insert constraint checking code */
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:check"))) {
-	Replaceall(tm, "$target", Getattr(p, "lname"));
 	Printv(f->code, tm, "\n", NIL);
 	p = Getattr(p, "tmap:check:next");
       } else {
@@ -355,8 +351,6 @@
 
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:argout"))) {
-	Replaceall(tm, "$source", Getattr(p, "emit:input"));	/* Deprecated */
-	Replaceall(tm, "$target", Getattr(p, "lname"));	/* Deprecated */
 	Replaceall(tm, "$arg", Getattr(p, "emit:input"));
 	Replaceall(tm, "$input", Getattr(p, "emit:input"));
 	Printv(outarg, tm, "\n", NIL);
@@ -371,7 +365,6 @@
     /* Insert cleanup code */
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:freearg"))) {
-	Replaceall(tm, "$target", Getattr(p, "lname"));
 	Printv(cleanup, tm, "\n", NIL);
 	p = Getattr(p, "tmap:freearg:next");
       } else {
@@ -385,8 +378,6 @@
 
     // Now have return value, figure out what to do with it.
     if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
-      Replaceall(tm, "$source", Swig_cresult_name());
-      Replaceall(tm, "$target", "values[0]");
       Replaceall(tm, "$result", "values[0]");
       if (GetFlag(n, "feature:new"))
 	Replaceall(tm, "$owner", "1");
@@ -408,14 +399,12 @@
 
     if (GetFlag(n, "feature:new")) {
       if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
-	Replaceall(tm, "$source", Swig_cresult_name());
 	Printv(f->code, tm, "\n", NIL);
       }
     }
     // Free any memory allocated by the function being wrapped..
 
     if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
-      Replaceall(tm, "$source", Swig_cresult_name());
       Printv(f->code, tm, "\n", NIL);
     }
     // Wrap things up (in a manner of speaking)
@@ -453,7 +442,7 @@
 	Printv(df->def, "static Scheme_Object *\n", dname, "(int argc, Scheme_Object **argv) {", NIL);
 	Printv(df->code, dispatch, "\n", NIL);
 	Printf(df->code, "scheme_signal_error(\"No matching function for overloaded '%s'\");\n", iname);
-	Printf(df->code, "return NULL;\n", iname);
+	Printf(df->code, "return NULL;\n");
 	Printv(df->code, "}\n", NIL);
 	Wrapper_print(df, f_wrappers);
 	Printf(init_func_def, "scheme_add_global(\"%s\", scheme_make_prim_w_arity(%s,\"%s\",%d,%d),menv);\n", proc_name, dname, proc_name, 0, maxargs);
@@ -521,8 +510,6 @@
 	/* Check for a setting of the variable value */
 	Printf(f->code, "if (argc) {\n");
 	if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
-	  Replaceall(tm, "$source", "argv[0]");
-	  Replaceall(tm, "$target", name);
 	  Replaceall(tm, "$input", "argv[0]");
 	  Replaceall(tm, "$argnum", "1");
 	  emit_action_code(n, f->code, tm);
@@ -535,8 +522,6 @@
       // of evaluating or setting)
 
       if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
-	Replaceall(tm, "$source", name);
-	Replaceall(tm, "$target", "swig_result");
 	Replaceall(tm, "$result", "swig_result");
 	/* Printf (f->code, "%s\n", tm); */
 	emit_action_code(n, f->code, tm);
@@ -584,7 +569,7 @@
 
     // Make a static variable;
 
-    Printf(var_name, "_wrap_const_%s", Swig_name_mangle(Getattr(n, "sym:name")));
+    Printf(var_name, "_wrap_const_%s", Swig_name_mangle_string(Getattr(n, "sym:name")));
 
     // Build the name for scheme.
     Printv(proc_name, iname, NIL);
@@ -609,9 +594,7 @@
       Printv(rvalue, "'", temp, "'", NIL);
     }
     if ((tm = Swig_typemap_lookup("constant", n, name, 0))) {
-      Replaceall(tm, "$source", rvalue);
       Replaceall(tm, "$value", rvalue);
-      Replaceall(tm, "$target", name);
       Printf(f_init, "%s\n", tm);
     } else {
       // Create variable and assign it a value
@@ -658,8 +641,6 @@
    * classHandler()
    * ------------------------------------------------------------ */
   virtual int classHandler(Node *n) {
-    String *mangled_classname = 0;
-    String *real_classname = 0;
     String *scm_structname = NewString("");
     SwigType *ctype_ptr = NewStringf("p.%s", getClassType());
 
@@ -675,14 +656,11 @@
     convert_proto_tab = NewString("");
 
     struct_name = Getattr(n, "sym:name");
-    mangled_struct_name = Swig_name_mangle(Getattr(n, "sym:name"));
+    mangled_struct_name = Swig_name_mangle_string(Getattr(n, "sym:name"));
 
     Printv(scm_structname, struct_name, NIL);
     Replaceall(scm_structname, "_", "-");
 
-    real_classname = Getattr(n, "name");
-    mangled_classname = Swig_name_mangle(real_classname);
-
     Printv(fieldnames_tab, "static const char *_swig_struct_", cls_swigtype, "_field_names[] = { \n", NIL);
 
     Printv(convert_proto_tab, "static Scheme_Object *_swig_convert_struct_", cls_swigtype, "(", SwigType_str(ctype_ptr, "ptr"), ");\n", NIL);
@@ -712,7 +690,6 @@
 	   " = SWIG_MzScheme_new_scheme_struct(menv, \"", scm_structname, "\", ",
 	   "_swig_struct_", cls_swigtype, "_field_names_cnt,", "(char**) _swig_struct_", cls_swigtype, "_field_names);\n", NIL);
 
-    Delete(mangled_classname);
     Delete(swigtype_ptr);
     swigtype_ptr = 0;
     Delete(fieldnames_tab);
diff --git a/Source/Modules/nested.cxx b/Source/Modules/nested.cxx
index 0fcd5ad..1f62e0d 100644
--- a/Source/Modules/nested.cxx
+++ b/Source/Modules/nested.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * nested.cxx
  *
@@ -58,22 +58,6 @@
 	if (value && Len(value)) {
 	  Setattr(n, "hasvalue", "1");
 	}
-	if (type) {
-	  SwigType *ty;
-	  SwigType *tmp = 0;
-	  if (decl) {
-	    ty = tmp = Copy(type);
-	    SwigType_push(ty, decl);
-	  } else {
-	    ty = type;
-	  }
-	  if (!SwigType_ismutable(ty)) {
-	    SetFlag(n, "hasconsttype");
-	    SetFlag(n, "feature:immutable");
-	  }
-	  if (tmp)
-	    Delete(tmp);
-	}
 	if (!type) {
 	  Printf(stderr, "notype name %s\n", name);
 	}
@@ -143,39 +127,8 @@
       if (Getattr(n, "sym:weak")) {
 	Setattr(n, "sym:name", symname);
       } else {
-	String *e = NewStringEmpty();
-	String *en = NewStringEmpty();
-	String *ec = NewStringEmpty();
-	int redefined = Swig_need_redefined_warn(n, c, true);
-	if (redefined) {
-	  Printf(en, "Identifier '%s' redefined (ignored)", symname);
-	  Printf(ec, "previous definition of '%s'", symname);
-	} else {
-	  Printf(en, "Redundant redeclaration of '%s'", symname);
-	  Printf(ec, "previous declaration of '%s'", symname);
-	}
-	if (Cmp(symname, Getattr(n, "name"))) {
-	  Printf(en, " (Renamed from '%s')", SwigType_namestr(Getattr(n, "name")));
-	}
-	Printf(en, ",");
-	if (Cmp(symname, Getattr(c, "name"))) {
-	  Printf(ec, " (Renamed from '%s')", SwigType_namestr(Getattr(c, "name")));
-	}
-	Printf(ec, ".");
-	SWIG_WARN_NODE_BEGIN(n);
-	if (redefined) {
-	  Swig_warning(WARN_PARSE_REDEFINED, Getfile(n), Getline(n), "%s\n", en);
-	  Swig_warning(WARN_PARSE_REDEFINED, Getfile(c), Getline(c), "%s\n", ec);
-	} else {
-	  Swig_warning(WARN_PARSE_REDUNDANT, Getfile(n), Getline(n), "%s\n", en);
-	  Swig_warning(WARN_PARSE_REDUNDANT, Getfile(c), Getline(c), "%s\n", ec);
-	}
-	SWIG_WARN_NODE_END(n);
-	Printf(e, "%s:%d:%s\n%s:%d:%s\n", Getfile(n), Getline(n), en, Getfile(c), Getline(c), ec);
-	Setattr(n, "error", e);
-	Delete(e);
-	Delete(en);
-	Delete(ec);
+	int inclass = 1;
+	Swig_symbol_conflict_warn(n, c, symname, inclass);
       }
     }
   }
@@ -396,7 +349,7 @@
 	Delete(ins);
 	Delattr(c, "nested:outer");
       } else {
-	// global unnamed struct - ignore it and it's instances
+	// global unnamed struct - ignore it and its instances
 	SetFlag(c, "feature:ignore");
 	while (next && Getattr(next, "nested:unnamedtype") == c) {
 	  SetFlag(next, "feature:ignore");
diff --git a/Source/Modules/ocaml.cxx b/Source/Modules/ocaml.cxx
index 6f2a349..82a8f4b 100644
--- a/Source/Modules/ocaml.cxx
+++ b/Source/Modules/ocaml.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * ocaml.cxx
  *
@@ -12,14 +12,12 @@
  * ----------------------------------------------------------------------------- */
 
 #include "swigmod.h"
-
 #include <ctype.h>
 
 static const char *usage = "\
 Ocaml Options (available with -ocaml)\n\
      -oldvarnames    - Old intermediary method names for variable wrappers\n\
      -prefix <name>  - Set a prefix <name> to be prepended to all names\n\
-     -suffix <name>  - Deprecated alias for general option -cppext\n\
      -where          - Emit library location\n\
 \n";
 
@@ -70,7 +68,7 @@
 	   "if ( $comparison ) { /* subclassed */\n",
 	   "  $director_new \n", "} else {\n", "  caml_failwith(\"accessing abstract class or protected constructor\"); \n", "}\n", NIL);
     director_multiple_inheritance = 1;
-    director_language = 1;
+    directorLanguage();
   }
  
   String *Swig_class_name(Node *n) {
@@ -99,10 +97,10 @@
       if (argv[i]) {
 	if (strcmp(argv[i], "-help") == 0) {
 	  fputs(usage, stdout);
-	  SWIG_exit(0);
+	  Exit(EXIT_SUCCESS);
 	} else if (strcmp(argv[i], "-where") == 0) {
 	  PrintIncludeArg();
-	  SWIG_exit(0);
+	  Exit(EXIT_SUCCESS);
 	} else if (strcmp(argv[i], "-prefix") == 0) {
 	  if (argv[i + 1]) {
 	    prefix = NewString(argv[i + 1]);
@@ -112,15 +110,6 @@
 	  } else {
 	    Swig_arg_error();
 	  }
-	} else if (strcmp(argv[i], "-suffix") == 0) {
-	  if (argv[i + 1]) {
-	    Printf(stderr, "swig: warning: -suffix option deprecated.  SWIG 3.0.4 and later provide a -cppext option which should be used instead.\n");
-	    SWIG_config_cppext(argv[i + 1]);
-	    Swig_mark_arg(i);
-	    Swig_mark_arg(i + 1);
-	    i++;
-	  } else
-	    Swig_arg_error();
 	} else if (strcmp(argv[i], "-oldvarnames") == 0) {
 	  Swig_mark_arg(i);
 	  old_variable_names = true;
@@ -228,7 +217,7 @@
     f_begin = NewFile(outfile, "w", SWIG_output_files());
     if (!f_begin) {
       FileErrorDisplay(outfile);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
     f_runtime = NewString("");
     f_init = NewString("");
@@ -277,7 +266,7 @@
 
     Swig_banner(f_begin);
 
-    Printf(f_runtime, "\n\n#ifndef SWIGOCAML\n#define SWIGOCAML\n#endif\n\n");
+    Swig_obligatory_macros(f_runtime, "OCAML");
 
     Printf(f_runtime, "#define SWIG_MODULE \"%s\"\n", module);
     /* Module name */
@@ -292,7 +281,7 @@
 
     Printf(f_int_to_enum, "let int_to_enum x y =\n" "    match (x : c_enum_type) with\n" "      `unknown -> C_enum (`Int y)\n");
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Printf(f_runtime, "#define SWIG_DIRECTORS\n");
     }
 
@@ -311,12 +300,12 @@
     String *mlfilen = NewStringf("%s%s", SWIG_output_directory(), mlfile);
     if ((f_mlout = NewFile(mlfilen, "w", SWIG_output_files())) == 0) {
       FileErrorDisplay(mlfilen);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
     String *mlifilen = NewStringf("%s%s", SWIG_output_directory(), mlifile);
     if ((f_mliout = NewFile(mlifilen, "w", SWIG_output_files())) == 0) {
       FileErrorDisplay(mlifilen);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
     emitBanner(f_mlout);
     emitBanner(f_mliout);
@@ -341,7 +330,7 @@
     Printf(f_enumtypes_type, "]\n");
     Printf(f_enumtypes_value, "]\n\n" "type c_obj = c_enum_value c_obj_t\n");
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       // Insert director runtime into the f_runtime file (make it occur before %header section)
       Swig_insert_file("director_common.swg", f_runtime);
       Swig_insert_file("director.swg", f_runtime);
@@ -398,26 +387,18 @@
    */
 
   void oc_SwigType_del_reference(SwigType *t) {
-    char *c = Char(t);
-    if (strncmp(c, "q(", 2) == 0) {
-      Delete(SwigType_pop(t));
-      c = Char(t);
+    if (SwigType_isqualifier(t)) {
+      SwigType_del_qualifier(t);
     }
-    if (strncmp(c, "r.", 2)) {
-      printf("Fatal error. SwigType_del_pointer applied to non-pointer.\n");
-      abort();
-    }
-    Replace(t, "r.", "", DOH_REPLACE_ANY | DOH_REPLACE_FIRST);
+    SwigType_del_reference(t);
   }
 
   void oc_SwigType_del_array(SwigType *t) {
-    char *c = Char(t);
-    if (strncmp(c, "q(", 2) == 0) {
-      Delete(SwigType_pop(t));
-      c = Char(t);
+    if (SwigType_isqualifier(t)) {
+      SwigType_del_qualifier(t);
     }
-    if (strncmp(c, "a(", 2) == 0) {
-      Delete(SwigType_pop(t));
+    if (SwigType_isarray(t)) {
+      SwigType_del_array(t);
     }
   }
 
@@ -532,8 +513,8 @@
       Setattr(seen_constructors, mangled_name, "true");
     }
     // writing the function wrapper function
-    Printv(f->def, "SWIGEXT CAML_VALUE ", wname, " (", NIL);
-    Printv(f->def, "CAML_VALUE args", NIL);
+    Printv(f->def, "SWIGEXT value ", wname, " (", NIL);
+    Printv(f->def, "value args", NIL);
     Printv(f->def, ")\n{", NIL);
 
     /* Define the scheme name in C. This define is used by several
@@ -542,7 +523,7 @@
 
     // adds local variables
     Wrapper_add_local(f, "args", "CAMLparam1(args)");
-    Wrapper_add_local(f, "ret", "SWIG_CAMLlocal2(swig_result,rv)");
+    Wrapper_add_local(f, "ret", "CAMLlocal2(swig_result,rv)");
     d = SwigType_typedef_qualified(d);
     emit_parameter_variables(l, f);
 
@@ -590,8 +571,6 @@
       }
       // Handle parameter types.
       if ((tm = Getattr(p, "tmap:in"))) {
-	Replaceall(tm, "$source", source);
-	Replaceall(tm, "$target", target);
 	Replaceall(tm, "$input", source);
 	Setattr(p, "emit:input", source);
 	Printv(f->code, tm, "\n", NIL);
@@ -611,7 +590,6 @@
     /* Insert constraint checking code */
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:check"))) {
-	Replaceall(tm, "$target", Getattr(p, "lname"));
 	Printv(f->code, tm, "\n", NIL);
 	p = Getattr(p, "tmap:check:next");
       } else {
@@ -623,8 +601,6 @@
 
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:argout"))) {
-	Replaceall(tm, "$source", Getattr(p, "emit:input"));	/* Deprecated */
-	Replaceall(tm, "$target", Getattr(p, "lname"));	/* Deprecated */
 	Replaceall(tm, "$arg", Getattr(p, "emit:input"));
 	Replaceall(tm, "$input", Getattr(p, "emit:input"));
 	Replaceall(tm, "$ntype", normalizeTemplatedClassName(Getattr(p, "type")));
@@ -640,7 +616,6 @@
     /* Insert cleanup code */
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:freearg"))) {
-	Replaceall(tm, "$target", Getattr(p, "lname"));
 	Printv(cleanup, tm, "\n", NIL);
 	p = Getattr(p, "tmap:freearg:next");
       } else {
@@ -681,8 +656,6 @@
     String *actioncode = emit_action(n);
 
     if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
-      Replaceall(tm, "$source", "swig_result");
-      Replaceall(tm, "$target", "rv");
       Replaceall(tm, "$result", "rv");
       Replaceall(tm, "$ntype", return_type_normalized);
       Printv(f->code, tm, "\n", NIL);
@@ -701,14 +674,12 @@
 
     if (GetFlag(n, "feature:new")) {
       if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
-	Replaceall(tm, "$source", "swig_result");
 	Printv(f->code, tm, "\n", NIL);
       }
     }
 
     /* See if there is any return cleanup code */
     if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
-      Replaceall(tm, "$source", Swig_cresult_name());
       Printf(f->code, "%s\n", tm);
       Delete(tm);
     }
@@ -716,7 +687,6 @@
     // Free any memory allocated by the function being wrapped..
 
     if ((tm = Swig_typemap_lookup("swig_result", n, Swig_cresult_name(), 0))) {
-      Replaceall(tm, "$source", Swig_cresult_name());
       Printv(f->code, tm, "\n", NIL);
     }
     // Wrap things up (in a manner of speaking)
@@ -738,7 +708,7 @@
 						  "free(argv);\n" "CAMLreturn(%s(args));\n",
 						  &maxargs);
 
-	Wrapper_add_local(df, "argv", "CAML_VALUE *argv");
+	Wrapper_add_local(df, "argv", "value *argv");
 
 	/* Undifferentiate name .. this is the dispatch function */
 	wname = Swig_name_wrapper(iname);
@@ -747,9 +717,9 @@
 	Append(wname, module);
 
 	Printv(df->def,
-	       "SWIGEXT CAML_VALUE ", wname, "(CAML_VALUE args) {\n" "  CAMLparam1(args);\n" "  int i;\n" "  int argc = caml_list_length(args);\n", NIL);
+	       "SWIGEXT value ", wname, "(value args) {\n" "  CAMLparam1(args);\n" "  int i;\n" "  int argc = caml_list_length(args);\n", NIL);
 	Printv(df->code,
-	       "argv = (CAML_VALUE *)malloc( argc * sizeof( CAML_VALUE ) );\n"
+	       "argv = (value *)malloc( argc * sizeof( value ) );\n"
 	       "for( i = 0; i < argc; i++ ) {\n" "  argv[i] = caml_list_nth(args,i);\n" "}\n", NIL);
 	Printv(df->code, dispatch, "\nfree(argv);\n", NIL);
 	Node *sibl = n;
@@ -842,24 +812,21 @@
     Printv(proc_name, iname, NIL);
     Setattr(n, "wrap:name", proc_name);
 
-    Printf(f->def, "SWIGEXT CAML_VALUE %s(CAML_VALUE args) {\n", var_name);
+    Printf(f->def, "SWIGEXT value %s(value args) {\n", var_name);
     // Printv(f->def, "#define FUNC_NAME \"", proc_name, "\"", NIL);
 
     Wrapper_add_local(f, "args", "CAMLparam1(args)");
-    Wrapper_add_local(f, "swig_result", "SWIG_CAMLlocal1(swig_result)");
+    Wrapper_add_local(f, "swig_result", "CAMLlocal1(swig_result)");
     Printf(f->code, "swig_result = Val_unit;\n");
 
-    if (!GetFlag(n, "feature:immutable")) {
+    int assignable = !is_immutable(n);
+    if (assignable) {
       /* Check for a setting of the variable value */
       Printf(f->code, "if (args != Val_int(0)) {\n");
       if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
-	Replaceall(tm, "$source", "args");
-	Replaceall(tm, "$target", name);
 	Replaceall(tm, "$input", "args");
 	emit_action_code(n, f->code, tm);
       } else if ((tm = Swig_typemap_lookup("in", n, name, 0))) {
-	Replaceall(tm, "$source", "args");
-	Replaceall(tm, "$target", name);
 	Replaceall(tm, "$input", "args");
 	emit_action_code(n, f->code, tm);
       } else {
@@ -871,13 +838,9 @@
     // of evaluating or setting)
 
     if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
-      Replaceall(tm, "$source", name);
-      Replaceall(tm, "$target", "swig_result");
       Replaceall(tm, "$result", "swig_result");
       emit_action_code(n, f->code, tm);
     } else if ((tm = Swig_typemap_lookup("out", n, name, 0))) {
-      Replaceall(tm, "$source", name);
-      Replaceall(tm, "$target", "swig_result");
       Replaceall(tm, "$result", "swig_result");
       emit_action_code(n, f->code, tm);
     } else {
@@ -891,7 +854,7 @@
 
     // Now add symbol to the Ocaml interpreter
 
-    if (GetFlag(n, "feature:immutable")) {
+    if (!assignable) {
       Printf(f_mlbody, "external _%s : c_obj -> Swig.c_obj = \"%s\" \n", mname, var_name);
       Printf(f_mlibody, "val _%s : c_obj -> Swig.c_obj\n", iname);
       if (const_enum) {
@@ -1134,7 +1097,7 @@
 
     if (sizeof_feature) {
       Printf(f_wrappers,
-	     "SWIGEXT CAML_VALUE _wrap_%s_sizeof( CAML_VALUE args ) {\n"
+	     "SWIGEXT value _wrap_%s_sizeof( value args ) {\n"
 	     "    CAMLparam1(args);\n" "    CAMLreturn(Val_int(sizeof(%s)));\n" "}\n", mangled_name, name_normalized);
 
       Printf(f_mlbody, "external __%s_sizeof : unit -> int = " "\"_wrap_%s_sizeof\"\n", mangled_name, mangled_name);
@@ -1209,6 +1172,7 @@
   /*
    * Produce the symbol name that ocaml will use when referring to the 
    * target item.  I wonder if there's a better way to do this:
+   * (WF - use Swig_name_mangle_string/Swig_name_mangle_type)
    *
    * I shudder to think about doing it with a hash lookup, but that would
    * make a couple of things easier:
@@ -1237,6 +1201,8 @@
     Replaceall(out, "=", "_xx_equals");
     Replaceall(out, "/", "_xx_slash");
     Replaceall(out, ".", "_xx_dot");
+    Replaceall(out, "?", "_xx_question");
+    Replaceall(out, ":", "_xx_colon");
     return out;
   }
 
@@ -1266,6 +1232,7 @@
 
   int enumvalueDeclaration(Node *n) {
     String *name = Getattr(n, "name");
+    String *symname = Getattr(n, "sym:name");
     SwigType *qtype = 0;
 
     if (name_qualifier_type) {
@@ -1273,8 +1240,8 @@
       Printv(qtype, name, NIL);
     }
 
-    if (const_enum && qtype && name && !Getattr(seen_enumvalues, name)) {
-      Setattr(seen_enumvalues, name, "true");
+    if (const_enum && qtype && symname && !Getattr(seen_enumvalues, symname)) {
+      Setattr(seen_enumvalues, symname, "true");
       SetFlag(n, "feature:immutable");
       Setattr(n, "feature:enumvalue", "1");	// this does not appear to be used
 
@@ -1283,10 +1250,10 @@
       String *evname = SwigType_manglestr(qtype);
       Insert(evname, 0, "SWIG_ENUM_");
 
-      Setattr(n, "feature:enumvname", name);
+      Setattr(n, "feature:enumvname", symname);
       Setattr(n, "feature:symname", evname);
       Delete(evname);
-      Printf(f_enumtypes_value, "| `%s\n", name);
+      Printf(f_enumtypes_value, "| `%s\n", symname);
 
       return Language::enumvalueDeclaration(n);
     } else
@@ -1492,14 +1459,14 @@
 	if (is_void)
 	  Printf(w->code, "%s;\n", super_call);
 	else
-	  Printf(w->code, "CAMLreturn_type(%s);\n", super_call);
+	  Printf(w->code, "CAMLreturnT(%s, %s);\n", SwigType_str(returntype, 0), super_call);
 	Delete(super_call);
       } else {
 	Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
 	       SwigType_namestr(name));
       }
     } else {
-      Wrapper_add_local(w, "swig_result", "SWIG_CAMLlocal2(swig_result, args)");
+      Wrapper_add_local(w, "swig_result", "CAMLlocal2(swig_result, args)");
       /* attach typemaps to arguments (C/C++ -> Ocaml) */
       String *arglist = NewString("");
 
@@ -1514,20 +1481,8 @@
       int i;
       char source[256];
 
-      int outputs = 0;
-      if (!is_void)
-	outputs++;
-
       /* build argument list and type conversion string */
       for (i = 0, idx = 0, p = l; i < num_arguments; i++) {
-
-	while (Getattr(p, "tmap:ignore")) {
-	  p = Getattr(p, "tmap:ignore:next");
-	}
-
-	if (Getattr(p, "tmap:directorargout") != 0)
-	  outputs++;
-
 	String *pname = Getattr(p, "name");
 	String *ptype = Getattr(p, "type");
 
@@ -1581,7 +1536,7 @@
 	    if (target) {
 	      String *director = NewStringf("director_%s", mangle);
 	      Wrapper_add_localv(w, director, "Swig::Director *", director, "= 0", NIL);
-	      Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL);
+	      Wrapper_add_localv(w, source, "value", source, "= Val_unit", NIL);
 	      Printf(wrap_args, "%s = dynamic_cast<Swig::Director *>(%s);\n", director, nonconst);
 	      Printf(wrap_args, "if (!%s) {\n", director);
 	      Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
@@ -1591,7 +1546,7 @@
 	      Delete(director);
 	      Printv(arglist, source, NIL);
 	    } else {
-	      Wrapper_add_localv(w, source, "CAML_VALUE", source, "= Val_unit", NIL);
+	      Wrapper_add_localv(w, source, "value", source, "= Val_unit", NIL);
 	      Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE%s, 0);\n", source, nonconst, mangle);
 	      //Printf(wrap_args, "%s = SWIG_NewPointerObj(%s, SWIGTYPE_p_%s, 0);\n", 
 	      //       source, nonconst, base);
@@ -1618,8 +1573,8 @@
 
       /* pass the method call on to the OCaml object */
       Printv(w->code,
-	     "swig_result = caml_swig_alloc(1,C_list);\n" "SWIG_Store_field(swig_result,0,args);\n" "args = swig_result;\n" "swig_result = Val_unit;\n", 0);
-      Printf(w->code, "static CAML_VALUE *swig_ocaml_func_val = NULL;\n" "if (!swig_ocaml_func_val) {\n");
+	     "swig_result = caml_swig_alloc(1,C_list);\n" "Store_field(swig_result,0,args);\n" "args = swig_result;\n" "swig_result = Val_unit;\n", 0);
+      Printf(w->code, "static const value *swig_ocaml_func_val = NULL;\n" "if (!swig_ocaml_func_val) {\n");
       Printf(w->code, "  swig_ocaml_func_val = caml_named_value(\"swig_runmethod\");\n  }\n");
       Printf(w->code, "swig_result = caml_callback3(*swig_ocaml_func_val,swig_get_self(),caml_copy_string(\"%s\"),args);\n", Getattr(n, "name"));
       /* exception handling */
@@ -1629,7 +1584,7 @@
       }
       if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
 	Printf(w->code, "if (!%s) {\n", Swig_cresult_name());
-	Printf(w->code, "  CAML_VALUE error = *caml_named_value(\"director_except\");\n");
+	Printf(w->code, "  value error = *caml_named_value(\"director_except\");\n");
 	Replaceall(tm, "$error", "error");
 	Printv(w->code, Str(tm), "\n", NIL);
 	Printf(w->code, "}\n");
@@ -1681,20 +1636,13 @@
     /* any existing helper functions to handle this? */
     if (!is_void) {
       if (!(ignored_method && !pure_virtual)) {
-	/* A little explanation:
-	 * The director_enum test case makes a method whose return type
-	 * is an enum type.  returntype here is "int".  gcc complains
-	 * about an implicit enum conversion, and although i don't strictly
-	 * agree with it, I'm working on fixing the error:
-	 *
-	 * Below is what I came up with.  It's not great but it should
-	 * always essentially work.
-	 */
+	String *rettype = SwigType_str(returntype, 0);
 	if (!SwigType_isreference(returntype)) {
-	  Printf(w->code, "CAMLreturn_type((%s)c_result);\n", SwigType_lstr(returntype, ""));
+	  Printf(w->code, "CAMLreturnT(%s, (%s)c_result);\n", rettype, rettype);
 	} else {
-	  Printf(w->code, "CAMLreturn_type(*c_result);\n");
+	  Printf(w->code, "CAMLreturnT(%s, (%s)*c_result);\n", rettype, rettype);
 	}
+	Delete(rettype);
       }
     } else {
       Printf(w->code, "CAMLreturn0;\n");
@@ -1750,7 +1698,7 @@
     Parm *p, *q;
     ParmList *superparms = Getattr(n, "parms");
     ParmList *parms = CopyParmList(superparms);
-    String *type = NewString("CAML_VALUE");
+    String *type = NewString("value");
     p = NewParm(type, NewString("self"), n);
     q = Copy(p);
     set_nextSibling(q, superparms);
@@ -1803,18 +1751,18 @@
     Parm *p, *q;
     ParmList *superparms = Getattr(n, "parms");
     ParmList *parms = CopyParmList(superparms);
-    String *type = NewString("CAML_VALUE");
+    String *type = NewString("value");
     p = NewParm(type, NewString("self"), n);
     q = Copy(p);
     set_nextSibling(p, parms);
 
     {
       Wrapper *w = NewWrapper();
-      Printf(w->def, "SwigDirector_%s::SwigDirector_%s(CAML_VALUE self) : Swig::Director(self) { }", classname, classname);
+      Printf(w->def, "SwigDirector_%s::SwigDirector_%s(value self) : Swig::Director(self) { }", classname, classname);
       Wrapper_print(w, f_directors);
       DelWrapper(w);
     }
-    Printf(f_directors_h, "    SwigDirector_%s(CAML_VALUE self);\n", classname);
+    Printf(f_directors_h, "    SwigDirector_%s(value self);\n", classname);
     Delete(classname);
     Setattr(n, "parms", q);
     return Language::classDirectorDefaultConstructor(n);
diff --git a/Source/Modules/octave.cxx b/Source/Modules/octave.cxx
index 1297d24..a85320b 100644
--- a/Source/Modules/octave.cxx
+++ b/Source/Modules/octave.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * octave.cxx
  *
@@ -85,7 +85,7 @@
     enable_cplus_runtime_mode();
     allow_overloading();
     director_multiple_inheritance = 1;
-    director_language = 1;
+    directorLanguage();
     docs = NewHash();
   }
 
@@ -119,7 +119,7 @@
 	} else if (strcmp(argv[i], "-nocppcast") == 0) {
 	  Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
 	  Swig_mark_arg(i);
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
         }
       }
     }
@@ -167,7 +167,7 @@
     f_begin = NewFile(outfile, "w", SWIG_output_files());
     if (!f_begin) {
       FileErrorDisplay(outfile);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
     f_runtime = NewString("");
     f_header = NewString("");
@@ -190,7 +190,7 @@
 
     Swig_banner(f_begin);
 
-    Printf(f_runtime, "\n\n#ifndef SWIGOCTAVE\n#define SWIGOCTAVE\n#endif\n\n");
+    Swig_obligatory_macros(f_runtime, "OCTAVE");
 
     Printf(f_runtime, "#define SWIG_name_d      \"%s\"\n", module);
     Printf(f_runtime, "#define SWIG_name        %s\n", module);
@@ -199,7 +199,7 @@
     Printf(f_runtime, "#define SWIG_global_name      \"%s\"\n", global_name);
     Printf(f_runtime, "#define SWIG_op_prefix        \"%s\"\n", op_prefix);
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Printf(f_runtime, "#define SWIG_DIRECTORS\n");
       Swig_banner(f_directors_h);
       if (dirprot_mode()) {
@@ -224,7 +224,7 @@
     if (Len(docs))
       emit_doc_texinfo();
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Swig_insert_file("director_common.swg", f_runtime);
       Swig_insert_file("director.swg", f_runtime);
     }
@@ -237,7 +237,7 @@
     Dump(f_runtime, f_begin);
     Dump(f_header, f_begin);
     Dump(f_doc, f_begin);
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Dump(f_directors_h, f_begin);
       Dump(f_directors, f_begin);
     }
@@ -567,6 +567,10 @@
     Wrapper *f = NewWrapper();
     Octave_begin_function(n, f->def, iname, overname, !overloaded);
 
+    // Start default try block to execute
+    // cleanup code if exception is thrown
+    Printf(f->code, "try {\n");
+
     emit_parameter_variables(l, f);
     emit_attach_parmmaps(l, f);
     Setattr(n, "wrap:parms", l);
@@ -607,9 +611,7 @@
         sprintf(source, "args(%d)", j);
         Setattr(p, "emit:input", source);
 
-        Replaceall(tm, "$source", Getattr(p, "emit:input"));
         Replaceall(tm, "$input", Getattr(p, "emit:input"));
-        Replaceall(tm, "$target", Getattr(p, "lname"));
 
         if (Getattr(p, "wrap:disown") || (Getattr(p, "tmap:in:disown"))) {
           Replaceall(tm, "$disown", "SWIG_POINTER_DISOWN");
@@ -654,7 +656,6 @@
     // Insert constraint checking code
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:check"))) {
-        Replaceall(tm, "$target", Getattr(p, "lname"));
         Printv(f->code, tm, "\n", NIL);
         p = Getattr(p, "tmap:check:next");
       } else {
@@ -677,7 +678,6 @@
           }
         }
         if (tm && (Len(tm) != 0)) {
-          Replaceall(tm, "$source", Getattr(p, "lname"));
           Printv(cleanup, tm, "\n", NIL);
         }
         p = Getattr(p, "tmap:freearg:next");
@@ -690,8 +690,6 @@
     String *outarg = NewString("");
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:argout"))) {
-        Replaceall(tm, "$source", Getattr(p, "lname"));
-        Replaceall(tm, "$target", "_outp");
         Replaceall(tm, "$result", "_outp");
         Replaceall(tm, "$arg", Getattr(p, "emit:input"));
         Replaceall(tm, "$input", Getattr(p, "emit:input"));
@@ -719,8 +717,6 @@
 
     // Return the function value
     if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
-      Replaceall(tm, "$source", Swig_cresult_name());
-      Replaceall(tm, "$target", "_outv");
       Replaceall(tm, "$result", "_outv");
 
       if (GetFlag(n, "feature:new"))
@@ -741,22 +737,31 @@
 
     if (GetFlag(n, "feature:new")) {
       if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
-        Replaceall(tm, "$source", Swig_cresult_name());
         Printf(f->code, "%s\n", tm);
       }
     }
 
     if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
-      Replaceall(tm, "$source", Swig_cresult_name());
       Replaceall(tm, "$result", "_outv");
       Printf(f->code, "%s\n", tm);
       Delete(tm);
     }
 
     Printf(f->code, "return _out;\n");
-    Printf(f->code, "fail:\n");	// we should free locals etc if this happens
+
+    // Execute cleanup code if branched to fail: label
+    Printf(f->code, "fail:\n");
     Printv(f->code, cleanup, NIL);
     Printf(f->code, "return octave_value_list();\n");
+
+    // Execute cleanup code if exception was thrown
+    Printf(f->code, "}\n");
+    Printf(f->code, "catch(...) {\n");
+    Printv(f->code, cleanup, NIL);
+    Printf(f->code, "throw;\n");
+    Printf(f->code, "}\n");
+
+    // End wrapper function
     Printf(f->code, "}\n");
 
     /* Substitute the cleanup code */
@@ -800,7 +805,7 @@
     Printf(tmp, "}");
     Wrapper_add_local(f, "argv", tmp);
     Printv(f->code, dispatch, "\n", NIL);
-    Printf(f->code, "error(\"No matching function for overload\");\n", iname);
+    Printf(f->code, "error(\"No matching function for overload\");\n");
     Printf(f->code, "return octave_value_list();\n");
     Printv(f->code, "}\n", NIL);
 
@@ -830,12 +835,10 @@
     String *setwname = Swig_name_wrapper(setname);
 
     Octave_begin_function(n, setf->def, setname, setwname, true);
-    Printf(setf->def, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1,0)) return octave_value_list();", iname);
-    if (is_assignable(n)) {
+    Printf(setf->code, "if (!SWIG_check_num_args(\"%s_set\",args.length(),1,1,0)) return octave_value_list();\n", iname);
+    if (!is_immutable(n)) {
       Setattr(n, "wrap:name", setname);
       if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
-        Replaceall(tm, "$source", "args(0)");
-        Replaceall(tm, "$target", name);
         Replaceall(tm, "$input", "args(0)");
         if (Getattr(n, "tmap:varin:implicitconv")) {
           Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
@@ -845,8 +848,9 @@
       } else {
         Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s.\n", SwigType_str(t, 0));
       }
+      Append(setf->code, "return octave_value_list();\n");
       Append(setf->code, "fail:\n");
-      Printf(setf->code, "return octave_value_list();\n");
+      Append(setf->code, "return octave_value_list();\n");
     } else {
       Printf(setf->code, "return octave_set_immutable(args,nargout);");
     }
@@ -858,18 +862,16 @@
     Octave_begin_function(n, getf->def, getname, getwname, true);
     Wrapper_add_local(getf, "obj", "octave_value obj");
     if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
-      Replaceall(tm, "$source", name);
-      Replaceall(tm, "$target", "obj");
       Replaceall(tm, "$result", "obj");
       addfail = emit_action_code(n, getf->code, tm);
       Delete(tm);
     } else {
       Swig_warning(WARN_TYPEMAP_VAROUT_UNDEF, input_file, line_number, "Unable to read variable of type %s\n", SwigType_str(t, 0));
     }
-    Append(getf->code, "  return obj;\n");
+    Append(getf->code, "return obj;\n");
     if (addfail) {
       Append(getf->code, "fail:\n");
-      Append(getf->code, "  return octave_value_list();\n");
+      Append(getf->code, "return octave_value_list();\n");
     }
     Append(getf->code, "}\n");
     Wrapper_print(getf, f_wrappers);
@@ -904,8 +906,6 @@
       value = wname;
     }
     if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
-      Replaceall(tm, "$source", value);
-      Replaceall(tm, "$target", name);
       Replaceall(tm, "$value", cppvalue ? cppvalue : value);
       Replaceall(tm, "$nsname", iname);
       Printf(f_init, "%s\n", tm);
@@ -946,7 +946,7 @@
     // This is a bug, due to the fact that swig_type -> octave_class mapping
     // is 1-to-n.
     static Hash *emitted = NewHash();
-    String *mangled_classname = Swig_name_mangle(Getattr(n, "name"));
+    String *mangled_classname = Swig_name_mangle_type(Getattr(n, "name"));
     if (Getattr(emitted, mangled_classname)) {
       Delete(mangled_classname);
       return SWIG_NOWRAP;
@@ -964,13 +964,14 @@
     SwigType_add_pointer(t);
 
     // Replace storing a pointer to underlying class with a smart pointer (intended for use with non-intrusive smart pointers)
-    SwigType *smart = Swig_cparse_smartptr(n);
+    SwigType *smart = Getattr(n, "smart");
     String *wrap_class = NewStringf("&_wrap_class_%s", class_name);
     if (smart) {
-      SwigType_add_pointer(smart);
-      SwigType_remember_clientdata(smart, wrap_class);
+      SwigType *psmart = Copy(smart);
+      SwigType_add_pointer(psmart);
+      SwigType_remember_clientdata(psmart, wrap_class);
+      Delete(psmart);
     }
-    //String *wrap_class = NewStringf("&_wrap_class_%s", class_name);
     SwigType_remember_clientdata(t, wrap_class);
 
     int use_director = Swig_directorclass(n);
@@ -1003,7 +1004,6 @@
     List *baselist = Getattr(n, "bases");
     if (baselist && Len(baselist)) {
       Iterator b;
-      int index = 0;
       b = First(baselist);
       while (b.item) {
         String *bname = Getattr(b.item, "name");
@@ -1016,7 +1016,6 @@
         Printf(base_class_names, "\"%s\",", bname_mangled);
         Printf(base_class, "0,");
         b = Next(b);
-        index++;
         Delete(bname_mangled);
       }
     }
@@ -1049,7 +1048,6 @@
 
     Delete(base_class);
     Delete(base_class_names);
-    Delete(smart);
     Delete(t);
     Delete(s_members_tab);
     s_members_tab = 0;
diff --git a/Source/Modules/overload.cxx b/Source/Modules/overload.cxx
index 5d27810..f6cd213 100644
--- a/Source/Modules/overload.cxx
+++ b/Source/Modules/overload.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * overload.cxx
  *
@@ -21,6 +21,7 @@
 String *argv_template_string;
 String *argc_template_string;
 
+namespace {
 struct Overloaded {
   Node *n;			/* Node                               */
   int argc;			/* Argument count                     */
@@ -28,6 +29,7 @@
   int error;			/* Ambiguity error                    */
   bool implicitconv_function;	/* For ordering implicitconv functions*/
 };
+}
 
 static int fast_dispatch_mode = 0;
 static int cast_dispatch_mode = 0;
@@ -337,7 +339,6 @@
 	Setattr(nodes[i].n, "overload:ignore", "1");
       Append(result, nodes[i].n);
       // Printf(stdout,"[ %d ] %d    %s\n", i, nodes[i].implicitconv_function, ParmList_errorstr(nodes[i].parms));
-      // Swig_print_node(nodes[i].n);
       if (i == nnodes-1 || nodes[i].argc != nodes[i+1].argc) {
 	if (argc_changed_index+2 < nnodes && (nodes[argc_changed_index+1].argc == nodes[argc_changed_index+2].argc)) {
 	  // Add additional implicitconv functions in same order as already ranked.
@@ -349,7 +350,6 @@
 	      SetFlag(nodes[j].n, "implicitconvtypecheckoff");
 	      Append(result, nodes[j].n);
 	      // Printf(stdout,"[ %d ] %d +  %s\n", j, nodes[j].implicitconv_function, ParmList_errorstr(nodes[j].parms));
-	      // Swig_print_node(nodes[j].n);
 	    }
 	  }
 	}
@@ -560,10 +560,12 @@
 	  }
 	}
 	if (!Getattr(pj, "tmap:in:SWIGTYPE") && Getattr(pj, "tmap:typecheck:SWIGTYPE")) {
-	  /* we emit  a warning if the argument defines the 'in' typemap, but not the 'typecheck' one */
+	  /* we emit a warning if the argument defines the 'in' typemap, but not the 'typecheck' one */
 	  Swig_warning(WARN_TYPEMAP_TYPECHECK_UNDEF, Getfile(ni), Getline(ni),
 		       "Overloaded method %s with no explicit typecheck typemap for arg %d of type '%s'\n",
 		       Swig_name_decl(n), j, SwigType_str(Getattr(pj, "type"), 0));
+	  Swig_warning(WARN_TYPEMAP_TYPECHECK_UNDEF, Getfile(ni), Getline(ni),
+		      "Dispatching calls to this method may not work correctly, see the 'Typemaps and Overloading' section in Typemaps chapter of the documentation\n");
 	}
 	Parm *pj1 = Getattr(pj, "tmap:in:next");
 	if (pj1)
@@ -735,10 +737,12 @@
 	  }
 	}
 	if (!Getattr(pj, "tmap:in:SWIGTYPE") && Getattr(pj, "tmap:typecheck:SWIGTYPE")) {
-	  /* we emit  a warning if the argument defines the 'in' typemap, but not the 'typecheck' one */
+	  /* we emit a warning if the argument defines the 'in' typemap, but not the 'typecheck' one */
 	  Swig_warning(WARN_TYPEMAP_TYPECHECK_UNDEF, Getfile(ni), Getline(ni),
 		       "Overloaded method %s with no explicit typecheck typemap for arg %d of type '%s'\n",
 		       Swig_name_decl(n), j, SwigType_str(Getattr(pj, "type"), 0));
+	  Swig_warning(WARN_TYPEMAP_TYPECHECK_UNDEF, Getfile(ni), Getline(ni),
+		       "Dispatching calls to this method may not work correctly, see: https://www.swig.org/Doc4.1/Typemaps.html#Typemaps_overloading\n");
 	}
 	Parm *pj1 = Getattr(pj, "tmap:in:next");
 	if (pj1)
@@ -809,7 +813,7 @@
     }
 
     if (num_arguments) {
-      Printf(f, "int _v;\n");
+      Printf(f, "int _v = 0;\n");
     }
 
     int num_braces = 0;
@@ -832,10 +836,12 @@
 	num_braces++;
       }
       if (!Getattr(pj, "tmap:in:SWIGTYPE") && Getattr(pj, "tmap:typecheck:SWIGTYPE")) {
-	/* we emit  a warning if the argument defines the 'in' typemap, but not the 'typecheck' one */
+	/* we emit a warning if the argument defines the 'in' typemap, but not the 'typecheck' one */
 	Swig_warning(WARN_TYPEMAP_TYPECHECK_UNDEF, Getfile(ni), Getline(ni),
 		     "Overloaded method %s with no explicit typecheck typemap for arg %d of type '%s'\n",
 		     Swig_name_decl(n), j, SwigType_str(Getattr(pj, "type"), 0));
+	Swig_warning(WARN_TYPEMAP_TYPECHECK_UNDEF, Getfile(ni), Getline(ni),
+		     "Dispatching calls to this method may not work correctly, see the 'Typemaps and Overloading' section in Typemaps chapter of the documentation\n");
       }
       Parm *pk = Getattr(pj, "tmap:in:next");
       if (pk)
diff --git a/Source/Modules/perl5.cxx b/Source/Modules/perl5.cxx
index dfa85f3..85133a7 100644
--- a/Source/Modules/perl5.cxx
+++ b/Source/Modules/perl5.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * perl5.cxx
  *
@@ -21,7 +21,7 @@
      -const          - Wrap constants as constants and not variables (implies -proxy)\n\
      -nopm           - Do not generate the .pm file\n\
      -noproxy        - Don't create proxy classes\n\
-     -proxy          - Create proxy classes\n\
+     -proxy          - Create proxy classes (enabled by default)\n\
      -static         - Omit code related to dynamic loading\n\
 \n";
 
@@ -118,12 +118,12 @@
 class PERL5:public Language {
 public:
 
-  PERL5():Language () {
+  PERL5() {
     Clear(argc_template_string);
     Printv(argc_template_string, "items", NIL);
     Clear(argv_template_string);
     Printv(argv_template_string, "ST(%d)", NIL);
-    director_language = 1;
+    directorLanguage();
   }
 
   /* Test to see if a type corresponds to something wrapped with a shadow class */
@@ -154,11 +154,11 @@
 	if (strcmp(argv[i], "-package") == 0) {
 	  Printv(stderr,
 		 "*** -package is no longer supported\n*** use the directive '%module A::B::C' in your interface file instead\n*** see the Perl section in the manual for details.\n", NIL);
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	} else if (strcmp(argv[i], "-interface") == 0) {
 	  Printv(stderr,
 		 "*** -interface is no longer supported\n*** use the directive '%module A::B::C' in your interface file instead\n*** see the Perl section in the manual for details.\n", NIL);
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	} else if (strcmp(argv[i], "-exportall") == 0) {
 	  export_all = 1;
 	  Swig_mark_arg(i);
@@ -197,7 +197,7 @@
 	} else if (strcmp(argv[i], "-nocppcast") == 0) {
 	  Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
 	  Swig_mark_arg(i);
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	}
       }
     }
@@ -276,7 +276,7 @@
     f_begin = NewFile(outfile, "w", SWIG_output_files());
     if (!f_begin) {
       FileErrorDisplay(outfile);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
     f_runtime = NewString("");
     f_init = NewString("");
@@ -285,11 +285,11 @@
     f_directors_h = NewString("");
     f_directors = NewString("");
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
       if (!f_runtime_h) {
 	FileErrorDisplay(outfile_h);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
     }
 
@@ -319,9 +319,9 @@
 
     Swig_banner(f_begin);
 
-    Printf(f_runtime, "\n\n#ifndef SWIGPERL\n#define SWIGPERL\n#endif\n\n");
+    Swig_obligatory_macros(f_runtime, "PERL");
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Printf(f_runtime, "#define SWIG_DIRECTORS\n");
     }
     Printf(f_runtime, "#define SWIG_CASTRANK_MODE\n");
@@ -341,7 +341,7 @@
       fprintf(stdout, "top: using namespace_module: %s\n", Char(namespace_module));
     }
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Swig_banner(f_directors_h);
       Printf(f_directors_h, "\n");
       Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", underscore_module);
@@ -407,7 +407,7 @@
       String *filen = NewStringf("%s%s", SWIG_output_directory(), pmfile);
       if ((f_pm = NewFile(filen, "w", SWIG_output_files())) == 0) {
 	FileErrorDisplay(filen);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       Delete(filen);
       filen = NULL;
@@ -445,13 +445,7 @@
 
     Printv(magic,
            "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n",
-	   "#ifdef PERL_OBJECT\n",
-	   "#define MAGIC_CLASS _wrap_", underscore_module, "_var::\n",
-	   "class _wrap_", underscore_module, "_var : public CPerlObj {\n",
-	   "public:\n",
-	   "#else\n",
 	   "#define MAGIC_CLASS\n",
-	   "#endif\n",
 	   "SWIGCLASS_STATIC int swig_magic_readonly(pTHX_ SV *SWIGUNUSEDPARM(sv), MAGIC *SWIGUNUSEDPARM(mg)) {\n",
 	   tab4, "MAGIC_PPERL\n", tab4, "croak(\"Value is read-only.\");\n", tab4, "return 0;\n", "}\n", NIL);
 
@@ -460,7 +454,7 @@
     /* emit wrappers */
     Language::top(n);
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       // Insert director runtime into the f_runtime file (make it occur before %header section)
       Swig_insert_file("director_common.swg", f_runtime);
       Swig_insert_file("director.swg", f_runtime);
@@ -470,7 +464,6 @@
 
     /* Dump out variable wrappers */
 
-    Printv(magic, "\n\n#ifdef PERL_OBJECT\n", "};\n", "#endif\n", NIL);
     Printv(magic, "\n#ifdef __cplusplus\n}\n#endif\n", NIL);
 
     Printf(f_header, "%s\n", magic);
@@ -619,7 +612,7 @@
     Dump(f_runtime, f_begin);
     Dump(f_header, f_begin);
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Dump(f_directors_h, f_runtime_h);
       Printf(f_runtime_h, "\n");
       Printf(f_runtime_h, "#endif\n");
@@ -725,14 +718,11 @@
 
       /* Produce string representation of source and target arguments */
       sprintf(source, "ST(%d)", i);
-      String *target = Getattr(p, "lname");
 
       if (i >= num_required) {
 	Printf(f->code, "    if (items > %d) {\n", i);
       }
       if ((tm = Getattr(p, "tmap:in"))) {
-	Replaceall(tm, "$target", target);
-	Replaceall(tm, "$source", source);
 	Replaceall(tm, "$input", source);
 	Setattr(p, "emit:input", source);	/* Save input location */
 
@@ -767,7 +757,6 @@
     /* Insert constraint checking code */
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:check"))) {
-	Replaceall(tm, "$target", Getattr(p, "lname"));
 	Printv(f->code, tm, "\n", NIL);
 	p = Getattr(p, "tmap:check:next");
       } else {
@@ -778,7 +767,6 @@
     /* Insert cleanup code */
     for (i = 0, p = l; p; i++) {
       if ((tm = Getattr(p, "tmap:freearg"))) {
-	Replaceall(tm, "$source", Getattr(p, "lname"));
 	Replaceall(tm, "$arg", Getattr(p, "emit:input"));
 	Replaceall(tm, "$input", Getattr(p, "emit:input"));
 	Printv(cleanup, tm, "\n", NIL);
@@ -793,8 +781,6 @@
     for (i = 0, p = l; p; i++) {
       if ((tm = Getattr(p, "tmap:argout"))) {
 	SwigType *t = Getattr(p, "type");
-	Replaceall(tm, "$source", Getattr(p, "lname"));
-	Replaceall(tm, "$target", "ST(argvi)");
 	Replaceall(tm, "$result", "ST(argvi)");
 	if (is_shadow(t)) {
 	  Replaceall(tm, "$shadow", "SWIG_SHADOW");
@@ -855,8 +841,6 @@
 
     if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
       SwigType *t = Getattr(n, "type");
-      Replaceall(tm, "$source", Swig_cresult_name());
-      Replaceall(tm, "$target", "ST(argvi)");
       Replaceall(tm, "$result", "ST(argvi)");
       if (is_shadow(t)) {
 	Replaceall(tm, "$shadow", "SWIG_SHADOW");
@@ -884,13 +868,11 @@
 
     if (GetFlag(n, "feature:new")) {
       if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
-	Replaceall(tm, "$source", Swig_cresult_name());
 	Printf(f->code, "%s\n", tm);
       }
     }
 
     if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
-      Replaceall(tm, "$source", Swig_cresult_name());
       Printf(f->code, "%s\n", tm);
     }
 
@@ -987,7 +969,8 @@
 
     /* Create a Perl function for setting the variable value */
 
-    if (!GetFlag(n, "feature:immutable")) {
+    int assignable = !is_immutable(n);
+    if (assignable) {
       Setattr(n, "wrap:name", set_name);
       Printf(setf->def, "SWIGCLASS_STATIC int %s(pTHX_ SV* sv, MAGIC * SWIGUNUSEDPARM(mg)) {\n", set_name);
       Printv(setf->code, tab4, "MAGIC_PPERL\n", NIL);
@@ -995,8 +978,6 @@
       /* Check for a few typemaps */
       tm = Swig_typemap_lookup("varin", n, name, 0);
       if (tm) {
-	Replaceall(tm, "$source", "sv");
-	Replaceall(tm, "$target", name);
 	Replaceall(tm, "$input", "sv");
 	/* Printf(setf->code,"%s\n", tm); */
 	emit_action_code(n, setf->code, tm);
@@ -1019,9 +1000,7 @@
     Printv(getf->code, tab4, "MAGIC_PPERL\n", NIL);
 
     if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
-      Replaceall(tm, "$target", "sv");
       Replaceall(tm, "$result", "sv");
-      Replaceall(tm, "$source", name);
       if (is_shadow(t)) {
 	Replaceall(tm, "$shadow", "SWIG_SHADOW");
       } else {
@@ -1053,7 +1032,7 @@
       tt = NewString("0");
     }
     /* Now add symbol to the PERL interpreter */
-    if (GetFlag(n, "feature:immutable")) {
+    if (!assignable) {
       Printv(variable_tab, tab4, "{ \"", cmodule, "::", iname, "\", MAGIC_CLASS swig_magic_readonly, MAGIC_CLASS ", get_name, ",", tt, " },\n", NIL);
 
     } else {
@@ -1111,8 +1090,6 @@
     }
 
     if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) {
-      Replaceall(tm, "$source", value);
-      Replaceall(tm, "$target", name);
       Replaceall(tm, "$value", value);
       if (is_shadow(type)) {
 	Replaceall(tm, "$shadow", "SWIG_SHADOW");
@@ -1121,8 +1098,6 @@
       }
       Printf(constant_tab, "%s,\n", tm);
     } else if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
-      Replaceall(tm, "$source", value);
-      Replaceall(tm, "$target", name);
       Replaceall(tm, "$value", value);
       if (is_shadow(type)) {
 	Replaceall(tm, "$shadow", "SWIG_SHADOW");
@@ -1540,67 +1515,67 @@
     if ((blessed) && (!Getattr(n, "sym:nextSibling"))) {
 
       if (Strstr(symname, "__eq__")) {
-	DohSetInt(operators, "__eq__", 1);
+	SetInt(operators, "__eq__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__ne__")) {
-	DohSetInt(operators, "__ne__", 1);
+	SetInt(operators, "__ne__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__assign__")) {
-	DohSetInt(operators, "__assign__", 1);
+	SetInt(operators, "__assign__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__str__")) {
-	DohSetInt(operators, "__str__", 1);
+	SetInt(operators, "__str__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__add__")) {
-	DohSetInt(operators, "__add__", 1);
+	SetInt(operators, "__add__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__sub__")) {
-	DohSetInt(operators, "__sub__", 1);
+	SetInt(operators, "__sub__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__mul__")) {
-	DohSetInt(operators, "__mul__", 1);
+	SetInt(operators, "__mul__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__div__")) {
-	DohSetInt(operators, "__div__", 1);
+	SetInt(operators, "__div__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__mod__")) {
-	DohSetInt(operators, "__mod__", 1);
+	SetInt(operators, "__mod__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__and__")) {
-	DohSetInt(operators, "__and__", 1);
+	SetInt(operators, "__and__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__or__")) {
-	DohSetInt(operators, "__or__", 1);
+	SetInt(operators, "__or__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__not__")) {
-	DohSetInt(operators, "__not__", 1);
+	SetInt(operators, "__not__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__gt__")) {
-	DohSetInt(operators, "__gt__", 1);
+	SetInt(operators, "__gt__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__ge__")) {
-	DohSetInt(operators, "__ge__", 1);
+	SetInt(operators, "__ge__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__lt__")) {
-	DohSetInt(operators, "__lt__", 1);
+	SetInt(operators, "__lt__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__le__")) {
-	DohSetInt(operators, "__le__", 1);
+	SetInt(operators, "__le__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__neg__")) {
-	DohSetInt(operators, "__neg__", 1);
+	SetInt(operators, "__neg__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__plusplus__")) {
-	DohSetInt(operators, "__plusplus__", 1);
+	SetInt(operators, "__plusplus__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__minmin__")) {
-	DohSetInt(operators, "__minmin__", 1);
+	SetInt(operators, "__minmin__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__mineq__")) {
-	DohSetInt(operators, "__mineq__", 1);
+	SetInt(operators, "__mineq__", 1);
 	have_operators = 1;
       } else if (Strstr(symname, "__pluseq__")) {
-	DohSetInt(operators, "__pluseq__", 1);
+	SetInt(operators, "__pluseq__", 1);
 	have_operators = 1;
       }
 
@@ -2208,14 +2183,6 @@
 	  continue;
 	}
 
-	/* old style?  caused segfaults without the p!=0 check
-	   in the for() condition, and seems dangerous in the
-	   while loop as well.
-	   while (Getattr(p, "tmap:ignore")) {
-	   p = Getattr(p, "tmap:ignore:next");
-	   }
-	 */
-
 	if (Getattr(p, "tmap:directorargout") != 0)
 	  outputs++;
 
@@ -2341,7 +2308,7 @@
 	Replaceall(tm, "$error", "ERRSV");
 	Printv(w->code, Str(tm), "\n", NIL);
       } else {
-	Printf(w->code, "  Swig::DirectorMethodException::raise(ERRSV);\n", classname, pyname);
+	Printf(w->code, "  Swig::DirectorMethodException::raise(ERRSV);\n");
       }
       Append(w->code, "}\n");
       Delete(tm);
diff --git a/Source/Modules/php.cxx b/Source/Modules/php.cxx
index 1edbd87..aad3c6d 100644
--- a/Source/Modules/php.cxx
+++ b/Source/Modules/php.cxx
@@ -1,10 +1,10 @@
 /* -----------------------------------------------------------------------------
- * This file is part of SWIG, which is licensed as a whole under version 3 
+ * This file is part of SWIG, which is licensed as a whole under version 3
  * (or any later version) of the GNU General Public License. Some additional
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * php.cxx
  *
@@ -12,72 +12,37 @@
  * -----------------------------------------------------------------------------
  */
 
-/* FIXME: PHP OO wrapping TODO list:
- *
- * Medium term:
- *
- * Handle default parameters on overloaded methods in PHP where possible.
- *   (Mostly done - just need to handle cases of overloaded methods with
- *   default parameters...)
- *   This is an optimisation - we could handle this case using a PHP
- *   default value, but currently we treat it as we would for a default
- *   value which is a compound C++ expression (i.e. as if we had a
- *   method with two overloaded forms instead of a single method with
- *   a default parameter value).
- *
- * Long term:
- *
- * Sort out locale-dependent behaviour of strtod() - it's harmless unless
- *   SWIG ever sets the locale and DOH/base.c calls atof, so we're probably
- *   OK currently at least.
- */
-
-/*
- * TODO: Replace remaining stderr messages with Swig_error or Swig_warning
- * (may need to add more WARN_PHP_xxx codes...)
- */
-
 #include "swigmod.h"
-
+#include <algorithm>
 #include <ctype.h>
 #include <errno.h>
+#include <limits.h>
 
 static const char *usage = "\
-PHP 7 Options (available with -php7)\n\
-     -noproxy         - Don't generate proxy classes.\n\
+PHP Options (available with -php7)\n\
      -prefix <prefix> - Prepend <prefix> to all class names in PHP wrappers\n\
 \n";
 
-/* The original class wrappers for PHP stored the pointer to the C++ class in
- * the object property _cPtr.  If we use the same name for the member variable
- * which we put the pointer to the C++ class in, then the flat function
- * wrappers will automatically pull it out without any changes being required.
- * FIXME: Isn't using a leading underscore a bit suspect here?
- */
-#define SWIG_PTR "_cPtr"
+// How to wrap non-class functions, variables and constants:
+// FIXME: Make this specifiable and also allow a real namespace.
 
-/* This is the name of the hash where the variables existing only in PHP
- * classes are stored.
- */
-#define SWIG_DATA "_pData"
+// Wrap as global PHP names.
+static bool wrap_nonclass_global = true;
 
-static int constructors = 0;
-static String *NOTCLASS = NewString("Not a class");
-static Node *classnode = 0;
+// Wrap in a class to fake a namespace (for compatibility with SWIG's behaviour
+// before PHP added namespaces.
+static bool wrap_nonclass_fake_class = true;
+
 static String *module = 0;
 static String *cap_module = 0;
 static String *prefix = 0;
 
-static String *shadow_classname = 0;
-
 static File *f_begin = 0;
 static File *f_runtime = 0;
 static File *f_runtime_h = 0;
 static File *f_h = 0;
-static File *f_phpcode = 0;
 static File *f_directors = 0;
 static File *f_directors_h = 0;
-static String *phpfilename = 0;
 
 static String *s_header;
 static String *s_wrappers;
@@ -85,7 +50,6 @@
 static String *r_init;		// RINIT user code
 static String *s_shutdown;	// MSHUTDOWN user code
 static String *r_shutdown;	// RSHUTDOWN user code
-static String *s_vinit;		// varinit initialization code.
 static String *s_vdecl;
 static String *s_cinit;		// consttab initialization code.
 static String *s_oinit;
@@ -93,31 +57,57 @@
 static String *s_entry;
 static String *cs_entry;
 static String *all_cs_entry;
+static String *fake_cs_entry;
+static String *s_creation;
 static String *pragma_incl;
 static String *pragma_code;
 static String *pragma_phpinfo;
 static String *pragma_version;
-static String *s_oowrappers;
-static String *s_fakeoowrappers;
-static String *s_phpclasses;
+
+static String *class_name = NULL;
+static String *base_class = NULL;
+static String *destructor_action = NULL;
+static String *magic_set = NULL;
+static String *magic_get = NULL;
+static String *magic_isset = NULL;
+
+// Class used as pseudo-namespace for compatibility.
+static String *fake_class_name() {
+  static String *result = NULL;
+  if (!result) {
+    result = Len(prefix) ? prefix : module;
+    if (!fake_cs_entry) {
+      fake_cs_entry = NewStringf("static const zend_function_entry class_%s_functions[] = {\n", result);
+    }
+
+    Printf(s_creation, "static zend_class_entry *SWIG_Php_ce_%s;\n\n",result);
+
+    Printf(s_oinit, "  INIT_CLASS_ENTRY(internal_ce, \"%s\", class_%s_functions);\n", result, result);
+    Printf(s_oinit, "  SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", result);
+    Printf(s_oinit, "\n");
+  }
+  return result;
+}
+
+static String *swig_wrapped_interface_ce() {
+  static String *result = NULL;
+  if (!result) {
+    result = NewStringf("SWIG_Php_swig_wrapped_interface_ce");
+    Printf(s_oinit, "  INIT_CLASS_ENTRY(%s, \"SWIG\\\\wrapped\", NULL);\n", result);
+  }
+  return result;
+}
 
 /* To reduce code size (generated and compiled) we only want to emit each
  * different arginfo once, so we need to track which have been used.
  */
 static Hash *arginfo_used;
 
-/* Variables for using PHP classes */
-static Node *current_class = 0;
-
-static Hash *shadow_get_vars;
-static Hash *shadow_set_vars;
-static Hash *zend_types = 0;
+/* Track non-class pointer types we need to to wrap */
+static Hash *raw_pointer_types = 0;
 
 static int shadow = 1;
 
-static bool class_has_ctor = false;
-static String *wrapping_member_constant = NULL;
-
 // These static variables are used to pass some state from Handlers into functionWrapper
 static enum {
   standard = 0,
@@ -126,76 +116,403 @@
   membervar,
   staticmembervar,
   constructor,
-  directorconstructor
+  destructor,
+  directorconstructor,
+  directordisown
 } wrapperType = standard;
 
 extern "C" {
   static void (*r_prevtracefunc) (const SwigType *t, String *mangled, String *clientdata) = 0;
 }
 
-static void SwigPHP_emit_resource_registrations() {
-  Iterator ki;
-  bool emitted_default_dtor = false;
-
-  if (!zend_types)
+static void SwigPHP_emit_pointer_type_registrations() {
+  if (!raw_pointer_types)
     return;
 
-  ki = First(zend_types);
-  if (ki.key)
-    Printf(s_oinit, "\n  /* Register resource destructors for pointer types */\n");
+  Iterator ki = First(raw_pointer_types);
+  if (!ki.key)
+    return;
+
+  Printf(s_wrappers, "/* class object handlers for pointer wrappers */\n");
+  Printf(s_wrappers, "static zend_object_handlers swig_ptr_object_handlers;\n\n");
+
+  Printf(s_wrappers, "/* Object Creation Method for pointer wrapping class */\n");
+  Printf(s_wrappers, "static zend_object *swig_ptr_object_new(zend_class_entry *ce) {\n");
+  Printf(s_wrappers, "  swig_object_wrapper *obj = (swig_object_wrapper*)zend_object_alloc(sizeof(swig_object_wrapper), ce);\n");
+  Printf(s_wrappers, "  zend_object_std_init(&obj->std, ce);\n");
+  Printf(s_wrappers, "  object_properties_init(&obj->std, ce);\n");
+  Printf(s_wrappers, "  obj->std.handlers = &swig_ptr_object_handlers;\n");
+  Printf(s_wrappers, "  obj->newobject = 0;\n");
+  Printf(s_wrappers, "  return &obj->std;\n");
+  Printf(s_wrappers, "}\n\n");
+
+  Printf(s_wrappers, "/* Implement __toString equivalent, since that worked for the old-style resource wrapped pointers. */\n");
+  Append(s_wrappers, "#if PHP_MAJOR_VERSION > 8 || PHP_MINOR_VERSION >= 2\n");
+  Printf(s_wrappers, "static ZEND_RESULT_CODE swig_ptr_cast_object(zend_object *zobj, zval *retval, int type) {\n");
+  Append(s_wrappers, "#else\n");
+  Printf(s_wrappers, "static int swig_ptr_cast_object(zend_object *zobj, zval *retval, int type) {\n");
+  Append(s_wrappers, "#endif\n");
+  Printf(s_wrappers, "  if (type == IS_STRING) {\n");
+  Printf(s_wrappers, "    swig_object_wrapper *obj = swig_php_fetch_object(zobj);\n");
+  Printv(s_wrappers, "    ZVAL_NEW_STR(retval, zend_strpprintf(0, \"SWIGPointer(%p,owned=%d)\", obj->ptr, obj->newobject));\n", NIL);
+  Printf(s_wrappers, "    return SUCCESS;\n");
+  Printf(s_wrappers, "  }\n");
+  Printf(s_wrappers, "  return FAILURE;\n");
+  Printf(s_wrappers, "}\n\n");
+
+  Printf(s_oinit, "\n  /* Register classes to represent non-class pointer types */\n");
+  Printf(s_oinit, "  swig_ptr_object_handlers = *zend_get_std_object_handlers();\n");
+  Printf(s_oinit, "  swig_ptr_object_handlers.offset = XtOffsetOf(swig_object_wrapper, std);\n");
+  Printf(s_oinit, "  swig_ptr_object_handlers.cast_object = swig_ptr_cast_object;\n");
+
   while (ki.key) {
-    DOH *key = ki.key;
-    Node *class_node = ki.item;
-    String *human_name = key;
-    String *rsrc_dtor_name = NULL;
+    String *type = ki.key;
 
-    // write out body
-    if (class_node != NOTCLASS) {
-      String *destructor = Getattr(class_node, "destructor");
-      human_name = Getattr(class_node, "sym:name");
-      if (!human_name)
-        human_name = Getattr(class_node, "name");
-      // Do we have a known destructor for this type?
-      if (destructor) {
-	rsrc_dtor_name = NewStringf("_wrap_destroy%s", key);
-	// Write out custom destructor function
-	Printf(s_wrappers, "static ZEND_RSRC_DTOR_FUNC(%s) {\n", rsrc_dtor_name);
-        Printf(s_wrappers, "  %s(res, SWIGTYPE%s->name);\n", destructor, key);
-	Printf(s_wrappers, "}\n");
-      }
-    }
+    String *swig_wrapped = swig_wrapped_interface_ce();
+    Printf(s_creation, "/* class entry for pointer to %s */\n", type);
+    Printf(s_creation, "static zend_class_entry *SWIG_Php_ce_%s;\n\n", type);
 
-    if (!rsrc_dtor_name) {
-      rsrc_dtor_name = NewString("_swig_default_rsrc_destroy");
-      if (!emitted_default_dtor) {
-	// Write out custom destructor function
-	Printf(s_wrappers, "static ZEND_RSRC_DTOR_FUNC(%s) {\n", rsrc_dtor_name);
-	Printf(s_wrappers, "  efree(res->ptr);\n");
-	Printf(s_wrappers, "}\n");
-	emitted_default_dtor = true;
-      }
-    }
-
-    // declare le_swig_<mangled> to store php registration
-    Printf(s_vdecl, "static int le_swig_%s=0; /* handle for %s */\n", key, human_name);
-
-    // register with php
-    Printf(s_oinit, "  le_swig_%s=zend_register_list_destructors_ex"
-		    "(%s, NULL, SWIGTYPE%s->name, module_number);\n", key, rsrc_dtor_name, key);
-
-    // store php type in class struct
-    Printf(s_oinit, "  SWIG_TypeClientData(SWIGTYPE%s,&le_swig_%s);\n", key, key);
-
-    Delete(rsrc_dtor_name);
+    Printf(s_oinit, "  INIT_CLASS_ENTRY(internal_ce, \"%s\\\\%s\", NULL);\n", "SWIG", type);
+    Printf(s_oinit, "  SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", type);
+    Printf(s_oinit, "  SWIG_Php_ce_%s->create_object = swig_ptr_object_new;\n", type);
+    Printv(s_oinit, "  zend_do_implement_interface(SWIG_Php_ce_", type, ", &", swig_wrapped, ");\n", NIL);
+    Printf(s_oinit, "  SWIG_TypeClientData(SWIGTYPE%s,SWIG_Php_ce_%s);\n", type, type);
+    Printf(s_oinit, "\n");
 
     ki = Next(ki);
   }
 }
 
+static Hash *create_php_type_flags() {
+  Hash *h = NewHash();
+  Setattr(h, "array", "MAY_BE_ARRAY");
+  Setattr(h, "bool", "MAY_BE_BOOL");
+  Setattr(h, "callable", "MAY_BE_CALLABLE");
+  Setattr(h, "float", "MAY_BE_DOUBLE");
+  Setattr(h, "int", "MAY_BE_LONG");
+  Setattr(h, "iterable", "MAY_BE_ITERABLE");
+  Setattr(h, "mixed", "MAY_BE_MIXED");
+  Setattr(h, "null", "MAY_BE_NULL");
+  Setattr(h, "object", "MAY_BE_OBJECT");
+  Setattr(h, "resource", "MAY_BE_RESOURCE");
+  Setattr(h, "string", "MAY_BE_STRING");
+  Setattr(h, "void", "MAY_BE_VOID");
+  return h;
+}
+
+static Hash *php_type_flags = create_php_type_flags();
+
+// php_class + ":" + php_method -> PHPTypes*
+// ":" + php_function -> PHPTypes*
+static Hash *all_phptypes = NewHash();
+
+// php_class_name -> php_parent_class_name
+static Hash *php_parent_class = NewHash();
+
+// Track if a method is directed in a descendent class.
+// php_class + ":" + php_method -> boolean (using SetFlag()/GetFlag()).
+static Hash *has_directed_descendent = NewHash();
+
+// Track required return type for parent class methods.
+// php_class + ":" + php_method -> List of php types.
+static Hash *parent_class_method_return_type = NewHash();
+
+// Class encapsulating the machinery to add PHP type declarations.
+class PHPTypes {
+  // List with an entry for each parameter and one for the return type.
+  //
+  // We assemble the types in here before emitting them so for an overloaded
+  // function we combine the type declarations from each overloaded form.
+  List *merged_types;
+
+  // List with an entry for each parameter which is passed "byref" in any
+  // overloaded form.  We use this to pass such parameters by reference in
+  // the dispatch function.  If NULL, no parameters are passed by reference.
+  List *byref;
+
+  // The id string used in the name of the arginfo for this object.
+  String *arginfo_id;
+
+  // The feature:php:type value: 0, 1 or -1 for "compatibility".
+  int php_type_flag;
+
+  // Does the node for this have directorNode set?
+  bool has_director_node;
+
+  // Track if all the overloads of a method are static.
+  //
+  // We should only flag a dispatch method as ACC_STATIC if all the dispatched
+  // to methods are static.  If we have both static and non-static methods in
+  // the overloaded set we omit ACC_STATIC, and then all the methods are
+  // callable (though the static ones only via an object).  If we set
+  // ACC_STATIC we get a crash on an attempt to call a non-static method.
+  bool all_overloads_static;
+
+  // Used to clamp the required number of parameters in the arginfo to be
+  // compatible with any parent class version of the method.
+  int num_required;
+
+  int get_byref(int key) const {
+    return byref && key < Len(byref) && Getitem(byref, key) != None;
+  }
+
+  int size() const {
+    return std::max(Len(merged_types), Len(byref));
+  }
+
+  String *get_phptype(int key, String *classtypes, List *more_return_types = NULL) {
+    Clear(classtypes);
+    // We want to minimise the list of class types by not redundantly listing
+    // a class for which a super-class is also listed.  This canonicalisation
+    // allows for more sharing of arginfo (which reduces module size), makes
+    // for a cleaner list if it's shown to the user, and also will speed up
+    // module load a bit.
+    Hash *classes = NewHash();
+    DOH *types = Getitem(merged_types, key);
+    String *result = NewStringEmpty();
+    if (more_return_types) {
+      if (types != None) {
+	merge_type_lists(types, more_return_types);
+      }
+    }
+    if (types != None) {
+      SortList(types, NULL);
+      String *prev = NULL;
+      for (Iterator i = First(types); i.item; i = Next(i)) {
+	if (prev && Equal(prev, i.item)) {
+	  // Skip duplicates when merging.
+	  continue;
+	}
+	String *c = Getattr(php_type_flags, i.item);
+	if (c) {
+	  if (Len(result) > 0) Append(result, "|");
+	  Append(result, c);
+	} else {
+	  SetFlag(classes, i.item);
+	}
+	prev = i.item;
+      }
+    }
+
+    // Remove entries for which a super-class is also listed.
+    Iterator i = First(classes);
+    while (i.key) {
+      String *this_class = i.key;
+      // We must advance the iterator early so we don't delete the element it
+      // points to.
+      i = Next(i);
+      String *parent = this_class;
+      while ((parent = Getattr(php_parent_class, parent)) != NULL) {
+	if (GetFlag(classes, parent)) {
+	  Delattr(classes, this_class);
+	  break;
+	}
+      }
+    }
+
+    List *sorted_classes = SortedKeys(classes, Strcmp);
+    for (i = First(sorted_classes); i.item; i = Next(i)) {
+      if (Len(classtypes) > 0) Append(classtypes, "|");
+      Append(classtypes, prefix);
+      Append(classtypes, i.item);
+    }
+    Delete(sorted_classes);
+
+    // Make the mask 0 if there are only class names specified.
+    if (Len(result) == 0) {
+      Append(result, "0");
+    }
+    return result;
+  }
+
+public:
+  PHPTypes(Node *n)
+    : merged_types(NewList()),
+      byref(NULL),
+      num_required(INT_MAX) {
+    String *php_type_feature = Getattr(n, "feature:php:type");
+    php_type_flag = 0;
+    if (php_type_feature != NULL) {
+      if (Equal(php_type_feature, "1")) {
+	php_type_flag = 1;
+      } else if (!Equal(php_type_feature, "0")) {
+	php_type_flag = -1;
+      }
+    }
+    arginfo_id = Copy(Getattr(n, "sym:name"));
+    has_director_node = (Getattr(n, "directorNode") != NULL);
+    all_overloads_static = true;
+  }
+
+  ~PHPTypes() {
+    Delete(merged_types);
+    Delete(byref);
+  }
+
+  void not_all_static() { all_overloads_static = false; }
+
+  bool get_all_static() const { return all_overloads_static; }
+
+  void adjust(int num_required_, bool php_constructor) {
+    num_required = std::min(num_required, num_required_);
+    if (php_constructor) {
+      // Don't add a return type declaration for a PHP __construct method
+      // (because there it has no return type as far as PHP is concerned).
+      php_type_flag = 0;
+    }
+  }
+
+  String *get_arginfo_id() const {
+    return arginfo_id;
+  }
+
+  // key is 0 for return type, or >= 1 for parameters numbered from 1
+  List *process_phptype(Node *n, int key, const String_or_char *attribute_name);
+
+  // Merge entries from o_merge_list into merge_list, skipping any entries
+  // already present.
+  //
+  // Both merge_list and o_merge_list should be in sorted order.
+  static void merge_type_lists(List *merge_list, List *o_merge_list);
+
+  void merge_from(const PHPTypes* o);
+
+  void set_byref(int key) {
+    if (!byref) {
+      byref = NewList();
+    }
+    while (Len(byref) <= key) {
+      Append(byref, None);
+    }
+    // If any overload takes a particular parameter by reference then the
+    // dispatch function also needs to take that parameter by reference so
+    // we can just set unconditionally here.
+    Setitem(byref, key, ""); // Just needs to be something != None.
+  }
+
+  void emit_arginfo(DOH *item, String *key) {
+    Setmark(item, 1);
+    char *colon_ptr = Strchr(key, ':');
+    assert(colon_ptr);
+    int colon = (int)(colon_ptr - Char(key));
+    if (colon > 0 && Strcmp(colon_ptr + 1, "__construct") != 0) {
+      // See if there's a parent class which implements this method, and if so
+      // emit its arginfo and then merge its PHPTypes into ours as we need to
+      // be compatible with it (whether it is virtual or not).
+      String *this_class = NewStringWithSize(Char(key), colon);
+      String *parent = this_class;
+      while ((parent = Getattr(php_parent_class, parent)) != NULL) {
+	String *k = NewStringf("%s%s", parent, colon_ptr);
+	DOH *item = Getattr(all_phptypes, k);
+	if (item) {
+	  PHPTypes *p = (PHPTypes*)Data(item);
+	  if (!Getmark(item)) {
+	    p->emit_arginfo(item, k);
+	  }
+	  merge_from(p);
+	  Delete(k);
+	  break;
+	}
+	Delete(k);
+      }
+      Delete(this_class);
+    }
+
+    // We want to only emit each different arginfo once, as that reduces the
+    // size of both the generated source code and the compiled extension
+    // module.  The parameters at this level are just named arg1, arg2, etc
+    // so the arginfo will be the same for any function with the same number
+    // of parameters and (if present) PHP type declarations for parameters and
+    // return type.
+    //
+    // We generate the arginfo we want (taking care to normalise, e.g. the
+    // lists of types are unique and in sorted order), then use the
+    // arginfo_used Hash to see if we've already generated it.
+    String *out_phptype = NULL;
+    String *out_phpclasses = NewStringEmpty();
+
+    // We provide a simple way to generate PHP return type declarations
+    // except for directed methods.  The point of directors is to allow
+    // subclassing in the target language, and if the wrapped method has
+    // a return type declaration then an overriding method in user code
+    // needs to have a compatible declaration.
+    //
+    // The upshot of this is that enabling return type declarations for
+    // existing bindings would break compatibility with user code written
+    // for an older version.  For parameters however the situation is
+    // different because if the parent class declares types for parameters
+    // a subclass overriding the function will be compatible whether it
+    // declares them or not.
+    //
+    // directorNode being present seems to indicate if this method or one
+    // it inherits from is directed, which is what we care about here.
+    // Using (!is_member_director(n)) would get it wrong for testcase
+    // director_frob.
+    if (php_type_flag && (php_type_flag > 0 || !has_director_node)) {
+      if (!GetFlag(has_directed_descendent, key)) {
+	out_phptype = get_phptype(0, out_phpclasses, Getattr(parent_class_method_return_type, key));
+      }
+    }
+
+    // ### in arginfo_code will be replaced with the id once that is known.
+    String *arginfo_code = NewStringEmpty();
+    if (out_phptype) {
+      if (Len(out_phpclasses)) {
+	Replace(out_phpclasses, "\\", "\\\\", DOH_REPLACE_ANY);
+	Printf(arginfo_code, "ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(swig_arginfo_###, 0, %d, %s, %s)\n", num_required, out_phpclasses, out_phptype);
+      } else {
+	Printf(arginfo_code, "ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(swig_arginfo_###, 0, %d, %s)\n", num_required, out_phptype);
+      }
+    } else {
+      Printf(arginfo_code, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_###, 0, 0, %d)\n", num_required);
+    }
+
+    int phptypes_size = size();
+    for (int param_count = 1; param_count < phptypes_size; ++param_count) {
+      String *phpclasses = NewStringEmpty();
+      String *phptype = get_phptype(param_count, phpclasses);
+
+      int byref = get_byref(param_count);
+
+      // FIXME: Should we be doing byref for return value as well?
+
+      if (phptype) {
+	if (Len(phpclasses)) {
+	  // We need to double any backslashes (which are PHP namespace
+	  // separators) in the PHP class names as they get turned into
+	  // C strings by the ZEND_ARG_OBJ_TYPE_MASK macro.
+	  Replace(phpclasses, "\\", "\\\\", DOH_REPLACE_ANY);
+	  Printf(arginfo_code, " ZEND_ARG_OBJ_TYPE_MASK(%d,arg%d,%s,%s,NULL)\n", byref, param_count, phpclasses, phptype);
+	} else {
+	  Printf(arginfo_code, " ZEND_ARG_TYPE_MASK(%d,arg%d,%s,NULL)\n", byref, param_count, phptype);
+	}
+      } else {
+	Printf(arginfo_code, " ZEND_ARG_INFO(%d,arg%d)\n", byref, param_count);
+      }
+    }
+    Printf(arginfo_code, "ZEND_END_ARG_INFO()\n");
+
+    String *arginfo_id_same = Getattr(arginfo_used, arginfo_code);
+    if (arginfo_id_same) {
+      Printf(s_arginfo, "#define swig_arginfo_%s swig_arginfo_%s\n", arginfo_id, arginfo_id_same);
+    } else {
+      // Not had this arginfo before.
+      Setattr(arginfo_used, arginfo_code, arginfo_id);
+      arginfo_code = Copy(arginfo_code);
+      Replace(arginfo_code, "###", arginfo_id, DOH_REPLACE_FIRST);
+      Append(s_arginfo, arginfo_code);
+    }
+    Delete(arginfo_code);
+    arginfo_code = NULL;
+  }
+};
+
+static PHPTypes *phptypes = NULL;
+
 class PHP : public Language {
 public:
   PHP() {
-    director_language = 1;
+    directorLanguage();
   }
 
   /* ------------------------------------------------------------
@@ -215,7 +532,7 @@
 	} else {
 	  Swig_arg_error();
 	}
-      } else if ((strcmp(argv[i], "-noshadow") == 0) || (strcmp(argv[i], "-noproxy") == 0)) {
+      } else if ((strcmp(argv[i], "-noshadow") == 0)) {
 	shadow = 0;
 	Swig_mark_arg(i);
       } else if (strcmp(argv[i], "-help") == 0) {
@@ -258,7 +575,7 @@
     f_begin = NewFile(outfile, "w", SWIG_output_files());
     if (!f_begin) {
       FileErrorDisplay(outfile);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
     f_runtime = NewStringEmpty();
 
@@ -269,21 +586,20 @@
     r_shutdown = NewStringEmpty();
     s_header = NewString("/* header section */\n");
     s_wrappers = NewString("/* wrapper section */\n");
+    s_creation = NewStringEmpty();
     /* subsections of the init section */
-    s_vinit = NewStringEmpty();
     s_vdecl = NewString("/* vdecl subsection */\n");
     s_cinit = NewString("  /* cinit subsection */\n");
     s_oinit = NewString("  /* oinit subsection */\n");
     pragma_phpinfo = NewStringEmpty();
-    s_phpclasses = NewString("/* PHP Proxy Classes */\n");
     f_directors_h = NewStringEmpty();
     f_directors = NewStringEmpty();
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
       if (!f_runtime_h) {
 	FileErrorDisplay(outfile_h);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
     }
 
@@ -301,22 +617,46 @@
 
     Swig_banner(f_begin);
 
-    Printf(f_runtime, "\n\n#ifndef SWIGPHP\n#define SWIGPHP\n#endif\n\n");
+    Swig_obligatory_macros(f_runtime, "PHP");
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Printf(f_runtime, "#define SWIG_DIRECTORS\n");
     }
 
+    // We need to include php.h before string.h gets included, at least with
+    // PHP 8.2.  Otherwise string.h is included without _GNU_SOURCE being
+    // included and memrchr() doesn't get declared, and then inline code in
+    // the PHP headers defines _GNU_SOURCE, includes string.h (which is a
+    // no op thanks to the include gaurds), then tries to use memrchr() and
+    // fails.
+    //
+    // We also need to suppress -Wdeclaration-after-statement if enabled
+    // since with PHP 8.2 zend_operators.h contains inline code which triggers
+    // this warning and our testsuite uses with option and -Werror.  I don't
+    // see a good way to only do this within our testsuite, but disabling
+    // it globally like this shouldn't be problematic.
+    Append(f_runtime,
+	   "\n"
+	   "#if defined __GNUC__ && !defined __cplusplus\n"
+	   "# if __GNUC__ >= 4\n"
+	   "#  pragma GCC diagnostic push\n"
+	   "#  pragma GCC diagnostic ignored \"-Wdeclaration-after-statement\"\n"
+	   "# endif\n"
+	   "#endif\n"
+	   "#include \"php.h\"\n"
+	   "#if defined __GNUC__ && !defined __cplusplus\n"
+	   "# if __GNUC__ >= 4\n"
+	   "#  pragma GCC diagnostic pop\n"
+	   "# endif\n"
+	   "#endif\n\n");
+
     /* Set the module name */
     module = Copy(Getattr(n, "name"));
     cap_module = NewStringf("%(upper)s", module);
     if (!prefix)
       prefix = NewStringEmpty();
 
-    Printf(f_runtime, "#define SWIG_PREFIX \"%s\"\n", prefix);
-    Printf(f_runtime, "#define SWIG_PREFIX_LEN %lu\n", (unsigned long)Len(prefix));
-
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Swig_banner(f_directors_h);
       Printf(f_directors_h, "\n");
       Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", cap_module);
@@ -327,36 +667,6 @@
       Delete(filename);
     }
 
-    /* PHP module file */
-    filen = NewStringEmpty();
-    Printv(filen, SWIG_output_directory(), module, ".php", NIL);
-    phpfilename = NewString(filen);
-
-    f_phpcode = NewFile(filen, "w", SWIG_output_files());
-    if (!f_phpcode) {
-      FileErrorDisplay(filen);
-      SWIG_exit(EXIT_FAILURE);
-    }
-
-    Printf(f_phpcode, "<?php\n\n");
-
-    Swig_banner(f_phpcode);
-
-    Printf(f_phpcode, "\n");
-    Printf(f_phpcode, "// Try to load our extension if it's not already loaded.\n");
-    Printf(f_phpcode, "if (!extension_loaded('%s')) {\n", module);
-    Printf(f_phpcode, "  if (strtolower(substr(PHP_OS, 0, 3)) === 'win') {\n");
-    Printf(f_phpcode, "    if (!dl('php_%s.dll')) return;\n", module);
-    Printf(f_phpcode, "  } else {\n");
-    Printf(f_phpcode, "    // PHP_SHLIB_SUFFIX gives 'dylib' on MacOS X but modules are 'so'.\n");
-    Printf(f_phpcode, "    if (PHP_SHLIB_SUFFIX === 'dylib') {\n");
-    Printf(f_phpcode, "      if (!dl('%s.so')) return;\n", module);
-    Printf(f_phpcode, "    } else {\n");
-    Printf(f_phpcode, "      if (!dl('%s.'.PHP_SHLIB_SUFFIX)) return;\n", module);
-    Printf(f_phpcode, "    }\n");
-    Printf(f_phpcode, "  }\n");
-    Printf(f_phpcode, "}\n\n");
-
     /* sub-sections of the php file */
     pragma_code = NewStringEmpty();
     pragma_incl = NewStringEmpty();
@@ -364,76 +674,11 @@
 
     /* Initialize the rest of the module */
 
-    Printf(s_oinit, "  ZEND_INIT_MODULE_GLOBALS(%s, %s_init_globals, NULL);\n", module, module);
-
     /* start the header section */
-    Printf(s_header, "ZEND_BEGIN_MODULE_GLOBALS(%s)\n", module);
-    Printf(s_header, "const char *error_msg;\n");
-    Printf(s_header, "int error_code;\n");
-    Printf(s_header, "ZEND_END_MODULE_GLOBALS(%s)\n", module);
-    Printf(s_header, "ZEND_DECLARE_MODULE_GLOBALS(%s)\n", module);
-    Printf(s_header, "#define SWIG_ErrorMsg() ZEND_MODULE_GLOBALS_ACCESSOR(%s, error_msg)\n", module);
-    Printf(s_header, "#define SWIG_ErrorCode() ZEND_MODULE_GLOBALS_ACCESSOR(%s, error_code)\n", module);
-
-    /* The following can't go in Lib/php/phprun.swg as it uses SWIG_ErrorMsg(), etc
-     * which has to be dynamically generated as it depends on the module name.
-     */
-    Append(s_header, "#ifdef __GNUC__\n");
-    Append(s_header, "static void SWIG_FAIL(void) __attribute__ ((__noreturn__));\n");
-    Append(s_header, "#endif\n\n");
-    Append(s_header, "static void SWIG_FAIL(void) {\n");
-    Append(s_header, "    zend_error(SWIG_ErrorCode(), \"%s\", SWIG_ErrorMsg());\n");
-    // zend_error() should never return with the parameters we pass, but if it
-    // does, we really don't want to let SWIG_FAIL() return.  This also avoids
-    // a warning about returning from a function marked as "__noreturn__".
-    Append(s_header, "    abort();\n");
-    Append(s_header, "}\n\n");
-
-    Printf(s_header, "static void %s_init_globals(zend_%s_globals *globals ) {\n", module, module);
-    Printf(s_header, "  globals->error_msg = default_error_msg;\n");
-    Printf(s_header, "  globals->error_code = default_error_code;\n");
-    Printf(s_header, "}\n");
-
-    Printf(s_header, "static void SWIG_ResetError(void) {\n");
-    Printf(s_header, "  SWIG_ErrorMsg() = default_error_msg;\n");
-    Printf(s_header, "  SWIG_ErrorCode() = default_error_code;\n");
-    Printf(s_header, "}\n");
-
-    Append(s_header, "\n");
-    Printf(s_header, "ZEND_NAMED_FUNCTION(_wrap_swig_%s_alter_newobject) {\n", module);
-    Append(s_header, "  zval args[2];\n");
-    Append(s_header, "  swig_object_wrapper *value;\n");
-    Append(s_header, "\n");
-    Append(s_header, "  SWIG_ResetError();\n");
-    Append(s_header, "  if(ZEND_NUM_ARGS() != 2 || zend_get_parameters_array_ex(2, args) != SUCCESS) {\n");
-    Append(s_header, "    WRONG_PARAM_COUNT;\n");
-    Append(s_header, "  }\n");
-    Append(s_header, "\n");
-    Append(s_header, "  value = (swig_object_wrapper *) Z_RES_VAL(args[0]);\n");
-    Append(s_header, "  value->newobject = zval_is_true(&args[1]);\n");
-    Append(s_header, "\n");
-    Append(s_header, "  return;\n");
-    Append(s_header, "}\n");
-    Printf(s_header, "ZEND_NAMED_FUNCTION(_wrap_swig_%s_get_newobject) {\n", module);
-    Append(s_header, "  zval args[1];\n");
-    Append(s_header, "  swig_object_wrapper *value;\n");
-    Append(s_header, "\n");
-    Append(s_header, "  SWIG_ResetError();\n");
-    Append(s_header, "  if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_array_ex(1, args) != SUCCESS) {\n");
-    Append(s_header, "    WRONG_PARAM_COUNT;\n");
-    Append(s_header, "  }\n");
-    Append(s_header, "\n");
-    Append(s_header, "  value = (swig_object_wrapper *) Z_RES_VAL(args[0]);\n");
-    Append(s_header, "  RETVAL_LONG(value->newobject);\n");
-    Append(s_header, "\n");
-    Append(s_header, "  return;\n");
-    Append(s_header, "}\n");
-
     Printf(s_header, "#define SWIG_name  \"%s\"\n", module);
     Printf(s_header, "#ifdef __cplusplus\n");
     Printf(s_header, "extern \"C\" {\n");
     Printf(s_header, "#endif\n");
-    Printf(s_header, "#include \"php.h\"\n");
     Printf(s_header, "#include \"php_ini.h\"\n");
     Printf(s_header, "#include \"ext/standard/info.h\"\n");
     Printf(s_header, "#include \"php_%s.h\"\n", module);
@@ -441,7 +686,7 @@
     Printf(s_header, "}\n");
     Printf(s_header, "#endif\n\n");
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       // Insert director runtime
       Swig_insert_file("director_common.swg", s_header);
       Swig_insert_file("director.swg", s_header);
@@ -453,7 +698,7 @@
     f_h = NewFile(filen, "w", SWIG_output_files());
     if (!f_h) {
       FileErrorDisplay(filen);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
 
     Swig_banner(f_h);
@@ -479,30 +724,49 @@
     /* holds all the per-class function entry sections */
     all_cs_entry = NewString("/* class entry subsection */\n");
     cs_entry = NULL;
+    fake_cs_entry = NULL;
 
     Printf(s_entry, "/* Every non-class user visible function must have an entry here */\n");
-    Printf(s_entry, "static zend_function_entry %s_functions[] = {\n", module);
+    Printf(s_entry, "static const zend_function_entry module_%s_functions[] = {\n", module);
 
     /* Emit all of the code */
     Language::top(n);
 
-    SwigPHP_emit_resource_registrations();
+    /* Emit all the arginfo.  We sort the keys so the output order doesn't depend on
+     * hashkey order.
+     */
+    {
+      List *sorted_keys = SortedKeys(all_phptypes, Strcmp);
+      for (Iterator k = First(sorted_keys); k.item; k = Next(k)) {
+	DOH *val = Getattr(all_phptypes, k.item);
+	if (!Getmark(val)) {
+	  PHPTypes *p = (PHPTypes*)Data(val);
+	  p->emit_arginfo(val, k.item);
+	}
+      }
+      Delete(sorted_keys);
+    }
+
+    SwigPHP_emit_pointer_type_registrations();
+    Dump(s_creation, s_header);
+    Delete(s_creation);
+    s_creation = NULL;
 
     /* start the init section */
     {
-      String * s_init_old = s_init;
+      String *s_init_old = s_init;
       s_init = NewString("/* init section */\n");
       Printv(s_init, "zend_module_entry ", module, "_module_entry = {\n", NIL);
       Printf(s_init, "    STANDARD_MODULE_HEADER,\n");
       Printf(s_init, "    \"%s\",\n", module);
-      Printf(s_init, "    %s_functions,\n", module);
+      Printf(s_init, "    module_%s_functions,\n", module);
       Printf(s_init, "    PHP_MINIT(%s),\n", module);
       if (Len(s_shutdown) > 0) {
 	Printf(s_init, "    PHP_MSHUTDOWN(%s),\n", module);
       } else {
 	Printf(s_init, "    NULL, /* No MSHUTDOWN code */\n");
       }
-      if (Len(r_init) > 0 || Len(s_vinit) > 0) {
+      if (Len(r_init) > 0) {
 	Printf(s_init, "    PHP_RINIT(%s),\n", module);
       } else {
 	Printf(s_init, "    NULL, /* No RINIT code */\n");
@@ -523,14 +787,14 @@
 	Printf(s_init, "    NO_VERSION_YET,\n");
       }
       Printf(s_init, "    STANDARD_MODULE_PROPERTIES\n");
-      Printf(s_init, "};\n");
-      Printf(s_init, "zend_module_entry* SWIG_module_entry = &%s_module_entry;\n\n", module);
+      Printf(s_init, "};\n\n");
 
       Printf(s_init, "#ifdef __cplusplus\n");
       Printf(s_init, "extern \"C\" {\n");
       Printf(s_init, "#endif\n");
-      // We want to write "SWIGEXPORT ZEND_GET_MODULE(%s)" but ZEND_GET_MODULE
-      // in PHP7 has "extern "C" { ... }" around it so we can't do that.
+      // We want to write "SWIGEXPORT ZEND_GET_MODULE(%s)" but the definition
+      // of ZEND_GET_MODULE has "extern "C" { ... }" around it so we can't do
+      // that.
       Printf(s_init, "SWIGEXPORT zend_module_entry *get_module(void) { return &%s_module_entry; }\n", module);
       Printf(s_init, "#ifdef __cplusplus\n");
       Printf(s_init, "}\n");
@@ -547,9 +811,6 @@
      * things are being called in the wrong order
      */
 
-    //    Printv(s_init,s_resourcetypes,NIL);
-    /* We need this after all classes written out by ::top */
-    Printf(s_oinit, "  CG(active_class_entry) = NULL;\n");
     Printf(s_oinit, "  /* end oinit subsection */\n");
     Printf(s_init, "%s\n", s_oinit);
 
@@ -563,27 +824,14 @@
     Printf(s_init, "}\n\n");
 
     // Now do REQUEST init which holds any user specified %rinit, and also vinit
-    if (Len(r_init) > 0 || Len(s_vinit) > 0) {
+    if (Len(r_init) > 0) {
       Printf(f_h, "PHP_RINIT_FUNCTION(%s);\n", module);
 
       Printf(s_init, "PHP_RINIT_FUNCTION(%s)\n{\n", module);
-      if (Len(r_init) > 0) {
-	Printv(s_init,
-	       "/* rinit section */\n",
-	       r_init, "\n",
-	       NIL);
-      }
-
-      if (Len(s_vinit) > 0) {
-	/* finish our init section which will have been used by class wrappers */
-	Printv(s_init,
-	       "  /* vinit subsection */\n",
-	       s_vinit, "\n"
-	       "  /* end vinit subsection */\n",
-	       NIL);
-	Clear(s_vinit);
-      }
-      Delete(s_vinit);
+      Printv(s_init,
+	     "/* rinit section */\n",
+	     r_init, "\n",
+	     NIL);
 
       Printf(s_init, "  return SUCCESS;\n");
       Printf(s_init, "}\n\n");
@@ -635,7 +883,7 @@
      * function really needs totally redoing.
      */
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Dump(f_directors_h, f_runtime_h);
       Printf(f_runtime_h, "\n");
       Printf(f_runtime_h, "#endif\n");
@@ -648,14 +896,17 @@
 
     Dump(f_runtime, f_begin);
     Printv(f_begin, s_header, NIL);
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Dump(f_directors, f_begin);
     }
     Printv(f_begin, s_vdecl, s_wrappers, NIL);
-    Printv(f_begin, all_cs_entry, "\n\n", s_arginfo, "\n\n", s_entry,
-	" SWIG_ZEND_NAMED_FE(swig_", module, "_alter_newobject,_wrap_swig_", module, "_alter_newobject,NULL)\n"
-	" SWIG_ZEND_NAMED_FE(swig_", module, "_get_newobject,_wrap_swig_", module, "_get_newobject,NULL)\n"
+    Printv(f_begin, s_arginfo, "\n\n", all_cs_entry, "\n\n", s_entry,
 	" ZEND_FE_END\n};\n\n", NIL);
+    if (fake_cs_entry) {
+      Printv(f_begin, fake_cs_entry, " ZEND_FE_END\n};\n\n", NIL);
+      Delete(fake_cs_entry);
+      fake_cs_entry = NULL;
+    }
     Printv(f_begin, s_init, NIL);
     Delete(s_header);
     Delete(s_wrappers);
@@ -668,78 +919,135 @@
     Delete(f_begin);
     Delete(arginfo_used);
 
-    Printf(f_phpcode, "%s\n%s\n", pragma_incl, pragma_code);
-    if (s_fakeoowrappers) {
-      Printf(f_phpcode, "abstract class %s {", Len(prefix) ? prefix : module);
-      Printf(f_phpcode, "%s", s_fakeoowrappers);
-      Printf(f_phpcode, "}\n\n");
-      Delete(s_fakeoowrappers);
-      s_fakeoowrappers = NULL;
+    if (Len(pragma_incl) > 0 || Len(pragma_code) > 0) {
+      /* PHP module file */
+      String *php_filename = NewStringEmpty();
+      Printv(php_filename, SWIG_output_directory(), module, ".php", NIL);
+
+      File *f_phpcode = NewFile(php_filename, "w", SWIG_output_files());
+      if (!f_phpcode) {
+	FileErrorDisplay(php_filename);
+	Exit(EXIT_FAILURE);
+      }
+
+      Printf(f_phpcode, "<?php\n\n");
+
+      if (Len(pragma_incl) > 0) {
+	Printv(f_phpcode, pragma_incl, "\n", NIL);
+      }
+
+      if (Len(pragma_code) > 0) {
+	Printv(f_phpcode, pragma_code, "\n", NIL);
+      }
+
+      Delete(f_phpcode);
+      Delete(php_filename);
     }
-    Printf(f_phpcode, "%s\n", s_phpclasses);
-    Delete(f_phpcode);
 
     return SWIG_OK;
   }
 
   /* Just need to append function names to function table to register with PHP. */
-  void create_command(String *cname, String *iname, Node *n) {
+  void create_command(String *cname, String *fname, Node *n, bool dispatch, String *modes) {
     // This is for the single main zend_function_entry record
-    Printf(f_h, "ZEND_NAMED_FUNCTION(%s);\n", iname);
-
-    // We want to only emit each different arginfo once, as that reduces the
-    // size of both the generated source code and the compiled extension
-    // module.  To do this, we name the arginfo to encode the number of
-    // parameters and which (if any) are passed by reference by using a
-    // sequence of 0s (for non-reference) and 1s (for by references).
     ParmList *l = Getattr(n, "parms");
-    String * arginfo_code = NewStringEmpty();
-    for (Parm *p = l; p; p = Getattr(p, "tmap:in:next")) {
-      /* Ignored parameters */
-      if (checkAttribute(p, "tmap:in:numinputs", "0")) {
-	continue;
+    if (cname && !Strstr(Getattr(n, "storage"), "friend")) {
+      Printf(f_h, "static PHP_METHOD(%s%s,%s);\n", prefix, cname, fname);
+      if (wrapperType != staticmemberfn &&
+	  wrapperType != staticmembervar &&
+	  !Equal(fname, "__construct")) {
+	// Skip the first entry in the parameter list which is the this pointer.
+	if (l) l = Getattr(l, "tmap:in:next");
+	// FIXME: does this throw the phptype key value off?
       }
-      Append(arginfo_code, GetFlag(p, "tmap:in:byref") ? "1" : "0");
+    } else {
+      if (dispatch) {
+	Printf(f_h, "static ZEND_NAMED_FUNCTION(%s);\n", fname);
+      } else {
+	Printf(f_h, "static PHP_FUNCTION(%s);\n", fname);
+      }
     }
 
-    if (!GetFlag(arginfo_used, arginfo_code)) {
-      // Not had this one before, so emit it.
-      SetFlag(arginfo_used, arginfo_code);
-      Printf(s_arginfo, "ZEND_BEGIN_ARG_INFO_EX(swig_arginfo_%s, 0, 0, 0)\n", arginfo_code);
-      for (const char * p = Char(arginfo_code); *p; ++p) {
-	Printf(s_arginfo, " ZEND_ARG_PASS_INFO(%c)\n", *p);
-      }
-      Printf(s_arginfo, "ZEND_END_ARG_INFO()\n");
-    }
+    phptypes->adjust(emit_num_required(l), Equal(fname, "__construct") ? true : false);
 
-    String * s = cs_entry;
+    String *arginfo_id = phptypes->get_arginfo_id();
+    String *s = cs_entry;
     if (!s) s = s_entry;
-    Printf(s, " SWIG_ZEND_NAMED_FE(%(lower)s,%s,swig_arginfo_%s)\n", cname, iname, arginfo_code);
-    Delete(arginfo_code);
+    if (cname && !Strstr(Getattr(n, "storage"), "friend")) {
+      Printf(all_cs_entry, " PHP_ME(%s%s,%s,swig_arginfo_%s,%s)\n", prefix, cname, fname, arginfo_id, modes);
+    } else {
+      if (dispatch) {
+	if (wrap_nonclass_global) {
+	  Printf(s, " ZEND_NAMED_FE(%(lower)s,%s,swig_arginfo_%s)\n", Getattr(n, "sym:name"), fname, arginfo_id);
+	}
+
+	if (wrap_nonclass_fake_class) {
+	  (void)fake_class_name();
+	  Printf(fake_cs_entry, " ZEND_NAMED_ME(%(lower)s,%s,swig_arginfo_%s,ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)\n", Getattr(n, "sym:name"), fname, arginfo_id);
+	}
+      } else {
+	if (wrap_nonclass_global) {
+	  Printf(s, " PHP_FE(%s,swig_arginfo_%s)\n", fname, arginfo_id);
+	}
+
+	if (wrap_nonclass_fake_class) {
+	  String *fake_class = fake_class_name();
+	  Printf(fake_cs_entry, " PHP_ME(%s,%s,swig_arginfo_%s,ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)\n", fake_class, fname, arginfo_id);
+	}
+      }
+    }
   }
 
   /* ------------------------------------------------------------
    * dispatchFunction()
    * ------------------------------------------------------------ */
-  void dispatchFunction(Node *n) {
+  void dispatchFunction(Node *n, int constructor) {
     /* Last node in overloaded chain */
 
     int maxargs;
     String *tmp = NewStringEmpty();
-    if (Swig_directorclass(n) && wrapperType == directorconstructor) {
-      /* We have an extra 'this' parameter. */
-      SetFlag(n, "wrap:this");
-    }
     String *dispatch = Swig_overload_dispatch(n, "%s(INTERNAL_FUNCTION_PARAM_PASSTHRU); return;", &maxargs);
 
     /* Generate a dispatch wrapper for all overloaded functions */
 
     Wrapper *f = NewWrapper();
     String *symname = Getattr(n, "sym:name");
-    String *wname = Swig_name_wrapper(symname);
+    String *wname = NULL;
+    String *modes = NULL;
+    bool constructorRenameOverload = false;
 
-    create_command(symname, wname, n);
-    Printv(f->def, "ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL);
+    if (constructor) {
+      if (!Equal(class_name, Getattr(n, "constructorHandler:sym:name"))) {
+	// Renamed constructor - turn into static factory method
+	constructorRenameOverload = true;
+	wname = Copy(Getattr(n, "constructorHandler:sym:name"));
+      } else {
+	wname = NewString("__construct");
+      }
+    } else if (class_name) {
+      wname = Getattr(n, "wrapper:method:name");
+    } else {
+      wname = Swig_name_wrapper(symname);
+    }
+
+    if (constructor) {
+      modes = NewString("ZEND_ACC_PUBLIC | ZEND_ACC_CTOR");
+      if (constructorRenameOverload) {
+	Append(modes, " | ZEND_ACC_STATIC");
+      }
+    } else if (phptypes->get_all_static()) {
+      modes = NewString("ZEND_ACC_PUBLIC | ZEND_ACC_STATIC");
+    } else {
+      modes = NewString("ZEND_ACC_PUBLIC");
+    }
+
+    create_command(class_name, wname, n, true, modes);
+
+    if (class_name && !Strstr(Getattr(n, "storage"), "friend")) {
+      Printv(f->def, "static PHP_METHOD(", prefix, class_name, ",", wname, ") {\n", NIL);
+    } else {
+      Printv(f->def, "static ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL);
+    }
 
     Wrapper_add_local(f, "argc", "int argc");
 
@@ -754,37 +1062,207 @@
 
     Printv(f->code, dispatch, "\n", NIL);
 
-    Printf(f->code, "SWIG_ErrorCode() = E_ERROR;\n");
-    Printf(f->code, "SWIG_ErrorMsg() = \"No matching function for overloaded '%s'\";\n", symname);
-    Printv(f->code, "SWIG_FAIL();\n", NIL);
-
+    Printf(f->code, "zend_throw_exception(zend_ce_type_error, \"No matching function for overloaded '%s'\", 0);\n", symname);
+    Printv(f->code, "fail:\n", NIL);
+    Printv(f->code, "return;\n", NIL);
     Printv(f->code, "}\n", NIL);
     Wrapper_print(f, s_wrappers);
 
     DelWrapper(f);
     Delete(dispatch);
     Delete(tmp);
-    Delete(wname);
   }
 
   /* ------------------------------------------------------------
    * functionWrapper()
    * ------------------------------------------------------------ */
 
-  /* Helper method for PHP::functionWrapper */
-  bool is_class(SwigType *t) {
-    Node *n = classLookup(t);
-    if (n) {
-      String *r = Getattr(n, "php:proxy");	// Set by classDeclaration()
-      if (!r)
-	r = Getattr(n, "sym:name");	// Not seen by classDeclaration yet, but this is the name
-      if (r)
+  /* Helper function to check if class is wrapped */
+  bool is_class_wrapped(String *className) {
+    if (!className)
+      return false;
+    Node *n = symbolLookup(className);
+    return n && Getattr(n, "classtype") != NULL;
+  }
+
+  void generate_magic_property_methods(Node *class_node) {
+    String *swig_base = base_class;
+    if (Equal(swig_base, "Exception") || !is_class_wrapped(swig_base)) {
+      swig_base = NULL;
+    }
+
+    static bool generated_magic_arginfo = false;
+    if (!generated_magic_arginfo) {
+      // Create arginfo entries for __get, __set and __isset.
+      Append(s_arginfo,
+	     "ZEND_BEGIN_ARG_INFO_EX(swig_magic_arginfo_get, 0, 0, 1)\n"
+	     " ZEND_ARG_TYPE_MASK(0,arg1,MAY_BE_STRING,NULL)\n"
+	     "ZEND_END_ARG_INFO()\n");
+      Append(s_arginfo,
+	     "ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(swig_magic_arginfo_set, 0, 1, MAY_BE_VOID)\n"
+	     " ZEND_ARG_TYPE_MASK(0,arg1,MAY_BE_STRING,NULL)\n"
+	     " ZEND_ARG_INFO(0,arg2)\n"
+	     "ZEND_END_ARG_INFO()\n");
+      Append(s_arginfo,
+	     "ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(swig_magic_arginfo_isset, 0, 1, MAY_BE_BOOL)\n"
+	     " ZEND_ARG_TYPE_MASK(0,arg1,MAY_BE_STRING,NULL)\n"
+	     "ZEND_END_ARG_INFO()\n");
+      generated_magic_arginfo = true;
+    }
+
+    Wrapper *f = NewWrapper();
+
+    Printf(f_h, "PHP_METHOD(%s%s,__set);\n", prefix, class_name);
+    Printf(all_cs_entry, " PHP_ME(%s%s,__set,swig_magic_arginfo_set,ZEND_ACC_PUBLIC)\n", prefix, class_name);
+    Printf(f->code, "PHP_METHOD(%s%s,__set) {\n", prefix, class_name);
+
+    Printf(f->code, "  swig_object_wrapper *arg = SWIG_Z_FETCH_OBJ_P(ZEND_THIS);\n");
+    Printf(f->code, "  zval args[2];\n zval tempZval;\n  zend_string *arg2 = 0;\n\n");
+    Printf(f->code, "  if(ZEND_NUM_ARGS() != 2 || zend_get_parameters_array_ex(2, args) != SUCCESS) {\n");
+    Printf(f->code, "\tWRONG_PARAM_COUNT;\n}\n\n");
+    Printf(f->code, "  if (!arg) {\n");
+    Printf(f->code, "    zend_throw_exception(zend_ce_type_error, \"this pointer is NULL\", 0);\n");
+    Printf(f->code, "    return;\n");
+    Printf(f->code, "  }\n");
+    Printf(f->code, "  arg2 = Z_STR(args[0]);\n\n");
+
+    Printf(f->code, "if (!arg2) {\n  RETVAL_NULL();\n}\n");
+    if (magic_set) {
+      Append(f->code, magic_set);
+    }
+    Printf(f->code, "\nelse if (strcmp(ZSTR_VAL(arg2),\"thisown\") == 0) {\n");
+    Printf(f->code, "arg->newobject = zval_get_long(&args[1]);\n");
+    if (Swig_directorclass(class_node)) {
+      Printv(f->code, "if (arg->newobject == 0) {\n",
+		      "  Swig::Director *director = SWIG_DIRECTOR_CAST((", Getattr(class_node, "classtype"), "*)(arg->ptr));\n",
+		      "  if (director) director->swig_disown();\n",
+		      "}\n", NIL);
+    }
+    if (swig_base) {
+      Printf(f->code, "} else {\nPHP_MN(%s%s___set)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n", prefix, swig_base);
+    } else if (GetFlag(class_node, "feature:php:allowdynamicproperties")) {
+      Printf(f->code, "} else {\nadd_property_zval_ex(ZEND_THIS, ZSTR_VAL(arg2), ZSTR_LEN(arg2), &args[1]);\n");
+    }
+    Printf(f->code, "}\n");
+
+    Printf(f->code, "fail:\n");
+    Printf(f->code, "return;\n");
+    Printf(f->code, "}\n\n\n");
+
+
+    Printf(f_h, "PHP_METHOD(%s%s,__get);\n", prefix, class_name);
+    Printf(all_cs_entry, " PHP_ME(%s%s,__get,swig_magic_arginfo_get,ZEND_ACC_PUBLIC)\n", prefix, class_name);
+    Printf(f->code, "PHP_METHOD(%s%s,__get) {\n",prefix, class_name);
+
+    Printf(f->code, "  swig_object_wrapper *arg = SWIG_Z_FETCH_OBJ_P(ZEND_THIS);\n");
+    Printf(f->code, "  zval args[1];\n zval tempZval;\n  zend_string *arg2 = 0;\n\n");
+    Printf(f->code, "  if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_array_ex(1, args) != SUCCESS) {\n");
+    Printf(f->code, "\tWRONG_PARAM_COUNT;\n}\n\n");
+    Printf(f->code, "  if (!arg) {\n");
+    Printf(f->code, "    zend_throw_exception(zend_ce_type_error, \"this pointer is NULL\", 0);\n");
+    Printf(f->code, "    return;\n");
+    Printf(f->code, "  }\n");
+    Printf(f->code, "  arg2 = Z_STR(args[0]);\n\n");
+
+    Printf(f->code, "if (!arg2) {\n  RETVAL_NULL();\n}\n");
+    if (magic_get) {
+      Append(f->code, magic_get);
+    }
+    Printf(f->code, "\nelse if (strcmp(ZSTR_VAL(arg2),\"thisown\") == 0) {\n");
+    Printf(f->code, "if(arg->newobject) {\nRETVAL_LONG(1);\n}\nelse {\nRETVAL_LONG(0);\n}\n}\n\n");
+    Printf(f->code, "else {\n");
+    if (swig_base) {
+      Printf(f->code, "PHP_MN(%s%s___get)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, swig_base);
+    } else {
+      // __get is only called if the property isn't set on the zend_object.
+      Printf(f->code, "RETVAL_NULL();\n}\n");
+    }
+
+    Printf(f->code, "fail:\n");
+    Printf(f->code, "return;\n");
+    Printf(f->code, "}\n\n\n");
+
+
+    Printf(f_h, "PHP_METHOD(%s%s,__isset);\n", prefix, class_name);
+    Printf(all_cs_entry, " PHP_ME(%s%s,__isset,swig_magic_arginfo_isset,ZEND_ACC_PUBLIC)\n", prefix, class_name);
+    Printf(f->code, "PHP_METHOD(%s%s,__isset) {\n",prefix, class_name);
+
+    Printf(f->code, "  swig_object_wrapper *arg = SWIG_Z_FETCH_OBJ_P(ZEND_THIS);\n");
+    Printf(f->code, "  zval args[1];\n  zend_string *arg2 = 0;\n\n");
+    Printf(f->code, "  if(ZEND_NUM_ARGS() != 1 || zend_get_parameters_array_ex(1, args) != SUCCESS) {\n");
+    Printf(f->code, "\tWRONG_PARAM_COUNT;\n}\n\n");
+    Printf(f->code, "  if(!arg) {\n");
+    Printf(f->code, "    zend_throw_exception(zend_ce_type_error, \"this pointer is NULL\", 0);\n");
+    Printf(f->code, "    return;\n");
+    Printf(f->code, "  }\n");
+    Printf(f->code, "  arg2 = Z_STR(args[0]);\n\n");
+
+    Printf(f->code, "if (!arg2) {\n  RETVAL_FALSE;\n}\n");
+    Printf(f->code, "\nelse if (strcmp(ZSTR_VAL(arg2),\"thisown\") == 0) {\n");
+    Printf(f->code, "RETVAL_TRUE;\n}\n\n");
+    if (magic_isset) {
+      Append(f->code, magic_isset);
+    }
+    Printf(f->code, "else {\n");
+    if (swig_base) {
+      Printf(f->code, "PHP_MN(%s%s___isset)(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n}\n", prefix, swig_base);
+    } else {
+      // __isset is only called if the property isn't set on the zend_object.
+      Printf(f->code, "RETVAL_FALSE;\n}\n");
+    }
+
+    Printf(f->code, "fail:\n");
+    Printf(f->code, "return;\n");
+    Printf(f->code, "}\n\n\n");
+
+    Wrapper_print(f, s_wrappers);
+    DelWrapper(f);
+    f = NULL;
+
+    Delete(magic_set);
+    Delete(magic_get);
+    Delete(magic_isset);
+    magic_set = NULL;
+    magic_get = NULL;
+    magic_isset = NULL;
+  }
+
+  String *getAccessMode(String *access) {
+    if (Cmp(access, "protected") == 0) {
+      return NewString("ZEND_ACC_PROTECTED");
+    } else if (Cmp(access, "private") == 0) {
+      return NewString("ZEND_ACC_PRIVATE");
+    }
+    return NewString("ZEND_ACC_PUBLIC");
+  }
+
+  bool is_setter_method(Node *n) {
+    const char *p = GetChar(n, "sym:name");
+    if (strlen(p) > 4) {
+      p += strlen(p) - 4;
+      if (strcmp(p, "_set") == 0) {
 	return true;
+      }
+    }
+    return false;
+  }
+
+  bool is_getter_method(Node *n) {
+    const char *p = GetChar(n, "sym:name");
+    if (strlen(p) > 4) {
+      p += strlen(p) - 4;
+      if (strcmp(p, "_get") == 0) {
+	return true;
+      }
     }
     return false;
   }
 
   virtual int functionWrapper(Node *n) {
+    if (wrapperType == directordisown) {
+      // Handled via __set magic method - no explicit wrapper method wanted.
+      return SWIG_OK;
+    }
     String *name = GetChar(n, "name");
     String *iname = GetChar(n, "sym:name");
     SwigType *d = Getattr(n, "type");
@@ -799,44 +1277,151 @@
     String *tm;
     Wrapper *f;
 
-    String *wname;
+    String *wname = NewStringEmpty();
+    String *overloadwname = NULL;
     int overloaded = 0;
-    String *overname = 0;
+    String *modes = NULL;
+    bool static_setter = false;
+    bool static_getter = false;
 
-    if (Cmp(nodeType, "destructor") == 0) {
-      // We just generate the Zend List Destructor and let Zend manage the
-      // reference counting.  There's no explicit destructor, but the user can
-      // just do `$obj = null;' to remove a reference to an object.
-      return CreateZendListDestructor(n);
+    modes = getAccessMode(Getattr(n, "access"));
+
+    if (constructor) {
+      Append(modes, " | ZEND_ACC_CTOR");
     }
-    // Test for overloading;
+    if (wrapperType == staticmemberfn || Cmp(Getattr(n, "storage"), "static") == 0) {
+      Append(modes, " | ZEND_ACC_STATIC");
+    }
+    if (GetFlag(n, "abstract") && Swig_directorclass(Swig_methodclass(n)) && !is_member_director(n))
+      Append(modes, " | ZEND_ACC_ABSTRACT");
+
     if (Getattr(n, "sym:overloaded")) {
       overloaded = 1;
-      overname = Getattr(n, "sym:overname");
+      overloadwname = NewString(Swig_name_wrapper(iname));
+      Printf(overloadwname, "%s", Getattr(n, "sym:overname"));
     } else {
       if (!addSymbol(iname, n))
 	return SWIG_ERROR;
     }
 
-    wname = Swig_name_wrapper(iname);
-    if (overname) {
-      Printf(wname, "%s", overname);
+    if (constructor) {
+      if (!Equal(class_name, Getattr(n, "constructorHandler:sym:name"))) {
+	// Renamed constructor - turn into static factory method
+	wname = Copy(Getattr(n, "constructorHandler:sym:name"));
+      } else {
+	wname = NewString("__construct");
+      }
+    } else if (wrapperType == membervar) {
+      wname = Copy(Getattr(n, "membervariableHandler:sym:name"));
+      if (is_setter_method(n)) {
+	Append(wname, "_set");
+      } else if (is_getter_method(n)) {
+	Append(wname, "_get");
+      }
+    } else if (wrapperType == memberfn) {
+      wname = Getattr(n, "memberfunctionHandler:sym:name");
+    } else if (wrapperType == staticmembervar) {
+      // Shape::nshapes -> nshapes
+      wname = Getattr(n, "staticmembervariableHandler:sym:name");
+
+      /* We get called twice for getter and setter methods. But to maintain
+	 compatibility, Shape::nshapes() is being used for both setter and
+	 getter methods. So using static_setter and static_getter variables
+	 to generate half of the code each time.
+       */
+      static_setter = is_setter_method(n);
+
+      if (is_getter_method(n)) {
+	// This is to overcome types that can't be set and hence no setter.
+	if (!Equal(Getattr(n, "feature:immutable"), "1"))
+	  static_getter = true;
+      }
+    } else if (wrapperType == staticmemberfn) {
+      wname = Getattr(n, "staticmemberfunctionHandler:sym:name");
+    } else {
+      if (class_name) {
+	if (Strstr(Getattr(n, "storage"), "friend") && Cmp(Getattr(n, "view"), "globalfunctionHandler") == 0) {
+	  wname = iname;
+	} else {
+	  wname = Getattr(n, "destructorHandler:sym:name");
+	}
+      } else {
+	wname = iname;
+      }
+    }
+
+    if (wrapperType == destructor) {
+      // We don't explicitly wrap the destructor for PHP - Zend manages the
+      // reference counting, and the user can just do `$obj = null;' or similar
+      // to remove a reference to an object.
+      Setattr(n, "wrap:name", wname);
+      (void)emit_action(n);
+      return SWIG_OK;
+    }
+
+    if (!static_getter) {
+      // Create or find existing PHPTypes.
+      phptypes = NULL;
+
+      String *key;
+      if (class_name && !Strstr(Getattr(n, "storage"), "friend")) {
+	key = NewStringf("%s:%s", class_name, wname);
+      } else {
+	key = NewStringf(":%s", wname);
+      }
+
+      PHPTypes *p = (PHPTypes*)GetVoid(all_phptypes, key);
+      if (p) {
+	// We already have an entry so use it.
+	phptypes = p;
+	Delete(key);
+      } else {
+	phptypes = new PHPTypes(n);
+	SetVoid(all_phptypes, key, phptypes);
+      }
+      if (!(wrapperType == staticmemberfn || Cmp(Getattr(n, "storage"), "static") == 0)) {
+	phptypes->not_all_static();
+      }
     }
 
     f = NewWrapper();
 
+    if (static_getter) {
+      Printf(f->def, "{\n");
+    }
+
     String *outarg = NewStringEmpty();
     String *cleanup = NewStringEmpty();
 
-    Printv(f->def, "ZEND_NAMED_FUNCTION(", wname, ") {\n", NIL);
+    if (!overloaded) {
+      if (!static_getter) {
+	if (class_name && !Strstr(Getattr(n, "storage"), "friend")) {
+	  Printv(f->def, "static PHP_METHOD(", prefix, class_name, ",", wname, ") {\n", NIL);
+	} else {
+	  if (wrap_nonclass_global) {
+	    Printv(f->def, "static PHP_METHOD(", fake_class_name(), ",", wname, ") {\n",
+			   "  PHP_FN(", wname, ")(INTERNAL_FUNCTION_PARAM_PASSTHRU);\n",
+			   "}\n\n", NIL);
+	  }
+
+	  if (wrap_nonclass_fake_class) {
+	    Printv(f->def, "static PHP_FUNCTION(", wname, ") {\n", NIL);
+	  }
+	}
+      }
+    } else {
+      Printv(f->def, "static ZEND_NAMED_FUNCTION(", overloadwname, ") {\n", NIL);
+    }
 
     emit_parameter_variables(l, f);
     /* Attach standard typemaps */
 
     emit_attach_parmmaps(l, f);
-    // Not issued for overloaded functions.
-    if (!overloaded) {
-      create_command(iname, wname, n);
+
+    if (wrapperType == memberfn || wrapperType == membervar) {
+      // Assign "this" to arg1 and remove first entry from ParmList l.
+      Printf(f->code, "arg1 = (%s)SWIG_Z_FETCH_OBJ_P(ZEND_THIS)->ptr;\n", SwigType_lstr(Getattr(l, "type"), ""));
+      l = nextSibling(l);
     }
 
     // wrap:parms is used by overload resolution.
@@ -846,18 +1431,16 @@
     int num_required = emit_num_required(l);
     numopt = num_arguments - num_required;
 
-    if (wrapperType == directorconstructor)
-      num_arguments++;
-
     if (num_arguments > 0) {
       String *args = NewStringEmpty();
-      if (wrapperType == directorconstructor)
-        Wrapper_add_local(f, "arg0", "zval * arg0");
       Printf(args, "zval args[%d]", num_arguments);
       Wrapper_add_local(f, "args", args);
       Delete(args);
       args = NULL;
     }
+    if (wrapperType == directorconstructor) {
+      Wrapper_add_local(f, "arg0", "zval *arg0 = ZEND_THIS");
+    }
 
     // This generated code may be called:
     // 1) as an object method, or
@@ -867,14 +1450,18 @@
 
     // NOTE: possible we ignore this_ptr as a param for native constructor
 
-    Printf(f->code, "SWIG_ResetError();\n");
-
     if (numopt > 0) {		// membervariable wrappers do not have optional args
       Wrapper_add_local(f, "arg_count", "int arg_count");
       Printf(f->code, "arg_count = ZEND_NUM_ARGS();\n");
       Printf(f->code, "if(arg_count<%d || arg_count>%d ||\n", num_required, num_arguments);
       Printf(f->code, "   zend_get_parameters_array_ex(arg_count,args)!=SUCCESS)\n");
       Printf(f->code, "\tWRONG_PARAM_COUNT;\n\n");
+    } else if (static_setter || static_getter) {
+      if (num_arguments == 0) {
+	Printf(f->code, "if(ZEND_NUM_ARGS() == 0) {\n");
+      } else {
+	Printf(f->code, "if(ZEND_NUM_ARGS() == %d && zend_get_parameters_array_ex(%d, args) == SUCCESS) {\n", num_arguments, num_arguments);
+      }
     } else {
       if (num_arguments == 0) {
 	Printf(f->code, "if(ZEND_NUM_ARGS() != 0) {\n");
@@ -883,8 +1470,6 @@
       }
       Printf(f->code, "WRONG_PARAM_COUNT;\n}\n\n");
     }
-    if (wrapperType == directorconstructor)
-      Printf(f->code, "arg0 = &args[0];\n  \n");
 
     /* Now convert from PHP to C variables */
     // At this point, argcount if used is the number of deliberately passed args
@@ -896,60 +1481,53 @@
     // _this and not the first argument.
     // This may mean looking at Language::memberfunctionHandler
 
-    int limit = num_arguments;
-    if (wrapperType == directorconstructor)
-      limit--;
-    for (i = 0, p = l; i < limit; i++) {
-      String *source;
-
+    for (i = 0, p = l; i < num_arguments; i++) {
       /* Skip ignored arguments */
-      //while (Getattr(p,"tmap:ignore")) { p = Getattr(p,"tmap:ignore:next");}
       while (checkAttribute(p, "tmap:in:numinputs", "0")) {
 	p = Getattr(p, "tmap:in:next");
       }
 
-      SwigType *pt = Getattr(p, "type");
-
-      if (wrapperType == directorconstructor) {
-	source = NewStringf("args[%d]", i+1);
-      } else {
-	source = NewStringf("args[%d]", i);
-      }
-
-      String *ln = Getattr(p, "lname");
-
       /* Check if optional */
       if (i >= num_required) {
 	Printf(f->code, "\tif(arg_count > %d) {\n", i);
       }
 
-      if ((tm = Getattr(p, "tmap:in"))) {
-	Replaceall(tm, "$source", &source);
-	Replaceall(tm, "$target", ln);
-	Replaceall(tm, "$input", source);
-	Setattr(p, "emit:input", source);
-	Printf(f->code, "%s\n", tm);
-	if (i == 0 && Getattr(p, "self")) {
-	  Printf(f->code, "\tif(!arg1) SWIG_PHP_Error(E_ERROR, \"this pointer is NULL\");\n");
-	}
-	p = Getattr(p, "tmap:in:next");
-	if (i >= num_required) {
-	  Printf(f->code, "}\n");
-	}
-	continue;
-      } else {
+      tm = Getattr(p, "tmap:in");
+      if (!tm) {
+	SwigType *pt = Getattr(p, "type");
 	Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
+	p = nextSibling(p);
+	continue;
       }
-      if (i >= num_required) {
+
+      phptypes->process_phptype(p, i + 1, "tmap:in:phptype");
+      if (GetFlag(p, "tmap:in:byref")) phptypes->set_byref(i + 1);
+
+      String *source = NewStringf("args[%d]", i);
+      Replaceall(tm, "$input", source);
+      Setattr(p, "emit:input", source);
+      Printf(f->code, "%s\n", tm);
+      if (i == 0 && Getattr(p, "self")) {
+	Printf(f->code, "\tif(!arg1) {\n");
+	Printf(f->code, "\t  zend_throw_exception(zend_ce_type_error, \"this pointer is NULL\", 0);\n");
+	Printf(f->code, "\t  return;\n");
 	Printf(f->code, "\t}\n");
       }
+
+      if (i >= num_required) {
+	Printf(f->code, "}\n");
+      }
+
+      p = Getattr(p, "tmap:in:next");
+
       Delete(source);
     }
 
     if (is_member_director(n)) {
+      Wrapper_add_local(f, "director", "Swig::Director *director = 0");
+      Append(f->code, "director = SWIG_DIRECTOR_CAST(arg1);\n");
       Wrapper_add_local(f, "upcall", "bool upcall = false");
-      Printf(f->code, "upcall = !Swig::Director::swig_is_overridden_method(\"%s%s\", \"%s\");\n",
-	  prefix, Swig_class_name(Swig_methodclass(n)), name);
+      Printf(f->code, "upcall = (director && (director->swig_get_self()==Z_OBJ_P(ZEND_THIS)));\n");
     }
 
     Swig_director_emit_dynamic_cast(n, f);
@@ -957,7 +1535,6 @@
     /* Insert constraint checking code */
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:check"))) {
-	Replaceall(tm, "$target", Getattr(p, "lname"));
 	Printv(f->code, tm, "\n", NIL);
 	p = Getattr(p, "tmap:check:next");
       } else {
@@ -968,7 +1545,6 @@
     /* Insert cleanup code */
     for (i = 0, p = l; p; i++) {
       if ((tm = Getattr(p, "tmap:freearg"))) {
-	Replaceall(tm, "$source", Getattr(p, "lname"));
 	Printv(cleanup, tm, "\n", NIL);
 	p = Getattr(p, "tmap:freearg:next");
       } else {
@@ -977,13 +1553,8 @@
     }
 
     /* Insert argument output code */
-    bool hasargout = false;
     for (i = 0, p = l; p; i++) {
       if ((tm = Getattr(p, "tmap:argout")) && Len(tm)) {
-	hasargout = true;
-	Replaceall(tm, "$source", Getattr(p, "lname"));
-	//      Replaceall(tm,"$input",Getattr(p,"lname"));
-	Replaceall(tm, "$target", "return_value");
 	Replaceall(tm, "$result", "return_value");
 	Replaceall(tm, "$arg", Getattr(p, "emit:input"));
 	Replaceall(tm, "$input", Getattr(p, "emit:input"));
@@ -994,16 +1565,21 @@
       }
     }
 
-    Setattr(n, "wrap:name", wname);
+    if (!overloaded) {
+      Setattr(n, "wrap:name", wname);
+    } else {
+      Setattr(n, "wrap:name", overloadwname);
+    }
+    Setattr(n, "wrapper:method:name", wname);
+
+    bool php_constructor = (constructor && Cmp(class_name, Getattr(n, "constructorHandler:sym:name")) == 0);
 
     /* emit function call */
     String *actioncode = emit_action(n);
 
     if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
       Replaceall(tm, "$input", Swig_cresult_name());
-      Replaceall(tm, "$source", Swig_cresult_name());
-      Replaceall(tm, "$target", "return_value");
-      Replaceall(tm, "$result", "return_value");
+      Replaceall(tm, "$result", php_constructor ? "ZEND_THIS" : "return_value");
       Replaceall(tm, "$owner", newobject ? "1" : "0");
       Printf(f->code, "%s\n", tm);
     } else {
@@ -1011,11 +1587,39 @@
     }
     emit_return_variable(n, d, f);
 
+    List *return_types = phptypes->process_phptype(n, 0, "tmap:out:phptype");
+
+    if (class_name && !Strstr(Getattr(n, "storage"), "friend")) {
+      if (is_member_director(n)) {
+	String *parent = class_name;
+	while ((parent = Getattr(php_parent_class, parent)) != NULL) {
+	  // Mark this method name as having no return type declaration for all
+	  // classes we're derived from.
+	  SetFlag(has_directed_descendent, NewStringf("%s:%s", parent, wname));
+	}
+      } else if (return_types) {
+	String *parent = class_name;
+	while ((parent = Getattr(php_parent_class, parent)) != NULL) {
+	  String *key = NewStringf("%s:%s", parent, wname);
+	  // The parent class method needs to have a superset of the possible
+	  // return types of methods with the same name in subclasses.
+	  List *v = Getattr(parent_class_method_return_type, key);
+	  if (!v) {
+	    // New entry.
+	    Setattr(parent_class_method_return_type, key, Copy(return_types));
+	  } else {
+	    // Update existing entry.
+	    PHPTypes::merge_type_lists(v, return_types);
+	  }
+	}
+      }
+    }
+
     if (outarg) {
       Printv(f->code, outarg, NIL);
     }
 
-    if (cleanup) {
+    if (static_setter && cleanup) {
       Printv(f->code, cleanup, NIL);
     }
 
@@ -1033,15 +1637,20 @@
       Delete(tm);
     }
 
-    Printf(f->code, "thrown:\n");
-    Printf(f->code, "return;\n");
+    if (static_getter) {
+      Printf(f->code, "}\n");
+    }
 
-    /* Error handling code */
-    Printf(f->code, "fail:\n");
-    Printv(f->code, cleanup, NIL);
-    Append(f->code, "SWIG_FAIL();\n");
+    if (static_setter || static_getter) {
+      Printf(f->code, "}\n");
+    }
 
-    Printf(f->code, "}\n");
+    if (!static_setter) {
+      Printf(f->code, "fail:\n");
+      Printv(f->code, cleanup, NIL);
+      Printf(f->code, "return;\n");
+      Printf(f->code, "}\n");
+    }
 
     Replaceall(f->code, "$cleanup", cleanup);
     Replaceall(f->code, "$symname", iname);
@@ -1050,827 +1659,14 @@
     DelWrapper(f);
     f = NULL;
 
-    if (overloaded && !Getattr(n, "sym:nextSibling")) {
-      dispatchFunction(n);
-    }
-
-    Delete(wname);
-    wname = NULL;
-
-    if (!shadow) {
-      return SWIG_OK;
-    }
-
-    // Handle getters and setters.
-    if (wrapperType == membervar) {
-      const char *p = Char(iname);
-      if (strlen(p) > 4) {
-	p += strlen(p) - 4;
-	String *varname = Getattr(n, "membervariableHandler:sym:name");
-	if (strcmp(p, "_get") == 0) {
-	  Setattr(shadow_get_vars, varname, Getattr(n, "type"));
-	} else if (strcmp(p, "_set") == 0) {
-	  Setattr(shadow_set_vars, varname, iname);
-	}
+    if (overloaded) {
+      if (!Getattr(n, "sym:nextSibling")) {
+	dispatchFunction(n, constructor);
       }
-      return SWIG_OK;
-    }
-
-    // Only look at non-overloaded methods and the last entry in each overload
-    // chain (we check the last so that wrap:parms and wrap:name have been set
-    // for them all).
-    if (overloaded && Getattr(n, "sym:nextSibling") != 0)
-      return SWIG_OK;
-
-    if (!s_oowrappers)
-      s_oowrappers = NewStringEmpty();
-
-    if (newobject || wrapperType == memberfn || wrapperType == staticmemberfn || wrapperType == standard || wrapperType == staticmembervar) {
-      bool handle_as_overload = false;
-      String **arg_names;
-      String **arg_values;
-      unsigned char * byref;
-      // Method or static method or plain function.
-      const char *methodname = 0;
-      String *output = s_oowrappers;
-      if (constructor) {
-	class_has_ctor = true;
-	// Skip the Foo:: prefix.
-	char *ptr = strrchr(GetChar(current_class, "sym:name"), ':');
-	if (ptr) {
-	  ptr++;
-	} else {
-	  ptr = GetChar(current_class, "sym:name");
-	}
-	if (strcmp(ptr, GetChar(n, "constructorHandler:sym:name")) == 0) {
-	  methodname = "__construct";
-	} else {
-	  // The class has multiple constructors and this one is
-	  // renamed, so this will be a static factory function
-	  methodname = GetChar(n, "constructorHandler:sym:name");
-	}
-      } else if (wrapperType == memberfn) {
-	methodname = Char(Getattr(n, "memberfunctionHandler:sym:name"));
-      } else if (wrapperType == staticmemberfn) {
-	methodname = Char(Getattr(n, "staticmemberfunctionHandler:sym:name"));
-      } else if (wrapperType == staticmembervar) {
-	// Static member variable, wrapped as a function due to PHP limitations.
-	methodname = Char(Getattr(n, "staticmembervariableHandler:sym:name"));
-      } else {			// wrapperType == standard
-	methodname = Char(iname);
-	if (!s_fakeoowrappers)
-	  s_fakeoowrappers = NewStringEmpty();
-	output = s_fakeoowrappers;
+    } else {
+      if (!static_setter) {
+	create_command(class_name, wname, n, false, modes);
       }
-
-      bool really_overloaded = overloaded ? true : false;
-      int min_num_of_arguments = emit_num_required(l);
-      int max_num_of_arguments = emit_num_arguments(l);
-
-      Hash *ret_types = NewHash();
-      Setattr(ret_types, d, d);
-
-      bool non_void_return = (Cmp(d, "void") != 0);
-
-      if (overloaded) {
-	// Look at all the overloaded versions of this method in turn to
-	// decide if it's really an overloaded method, or just one where some
-	// parameters have default values.
-	Node *o = Getattr(n, "sym:overloaded");
-	while (o) {
-	  if (o == n) {
-	    o = Getattr(o, "sym:nextSibling");
-	    continue;
-	  }
-
-	  SwigType *d2 = Getattr(o, "type");
-	  if (!d2) {
-	    assert(constructor);
-	  } else if (!Getattr(ret_types, d2)) {
-	    Setattr(ret_types, d2, d2);
-	    non_void_return = non_void_return || (Cmp(d2, "void") != 0);
-	  }
-
-	  ParmList *l2 = Getattr(o, "wrap:parms");
-	  int num_arguments = emit_num_arguments(l2);
-	  int num_required = emit_num_required(l2);
-	  if (num_required < min_num_of_arguments)
-	    min_num_of_arguments = num_required;
-
-	  if (num_arguments > max_num_of_arguments) {
-	    max_num_of_arguments = num_arguments;
-	  }
-	  o = Getattr(o, "sym:nextSibling");
-	}
-
-	o = Getattr(n, "sym:overloaded");
-	while (o) {
-	  if (o == n) {
-	    o = Getattr(o, "sym:nextSibling");
-	    continue;
-	  }
-
-	  ParmList *l2 = Getattr(o, "wrap:parms");
-	  Parm *p = l, *p2 = l2;
-	  if (wrapperType == memberfn) {
-	    p = nextSibling(p);
-	    p2 = nextSibling(p2);
-	  }
-	  while (p && p2) {
-	    if (Cmp(Getattr(p, "type"), Getattr(p2, "type")) != 0)
-	      break;
-	    if (Cmp(Getattr(p, "name"), Getattr(p2, "name")) != 0)
-	      break;
-	    String *value = Getattr(p, "value");
-	    String *value2 = Getattr(p2, "value");
-	    if (value && !value2)
-	      break;
-	    if (!value && value2)
-	      break;
-	    if (value) {
-	      if (Cmp(value, value2) != 0)
-		break;
-	    }
-	    p = nextSibling(p);
-	    p2 = nextSibling(p2);
-	  }
-	  if (p && p2)
-	    break;
-	  // One parameter list is a prefix of the other, so check that all
-	  // remaining parameters of the longer list are optional.
-	  if (p2)
-	    p = p2;
-	  while (p && Getattr(p, "value"))
-	    p = nextSibling(p);
-	  if (p)
-	    break;
-	  o = Getattr(o, "sym:nextSibling");
-	}
-	if (!o) {
-	  // This "overloaded method" is really just one with default args.
-	  really_overloaded = false;
-	}
-      }
-
-      if (wrapperType == memberfn) {
-	// Allow for the "this" pointer.
-	--min_num_of_arguments;
-	--max_num_of_arguments;
-      }
-
-      arg_names = (String **) malloc(max_num_of_arguments * sizeof(String *));
-      if (!arg_names) {
-	/* FIXME: How should this be handled?  The rest of SWIG just seems
-	 * to not bother checking for malloc failing! */
-	fprintf(stderr, "Malloc failed!\n");
-	SWIG_exit(EXIT_FAILURE);
-      }
-      for (i = 0; i < max_num_of_arguments; ++i) {
-	arg_names[i] = NULL;
-      }
-
-      arg_values = (String **) malloc(max_num_of_arguments * sizeof(String *));
-      byref = (unsigned char *) malloc(max_num_of_arguments);
-      if (!arg_values || !byref) {
-	/* FIXME: How should this be handled?  The rest of SWIG just seems
-	 * to not bother checking for malloc failing! */
-	fprintf(stderr, "Malloc failed!\n");
-	SWIG_exit(EXIT_FAILURE);
-      }
-      for (i = 0; i < max_num_of_arguments; ++i) {
-	arg_values[i] = NULL;
-	byref[i] = false;
-      }
-
-      Node *o;
-      if (overloaded) {
-	o = Getattr(n, "sym:overloaded");
-      } else {
-	o = n;
-      }
-      while (o) {
-	int argno = 0;
-	Parm *p = Getattr(o, "wrap:parms");
-	if (wrapperType == memberfn)
-	  p = nextSibling(p);
-	while (p) {
-	  if (GetInt(p, "tmap:in:numinputs") == 0) {
-	    p = nextSibling(p);
-	    continue;
-	  }
-	  assert(0 <= argno && argno < max_num_of_arguments);
-	  byref[argno] = GetFlag(p, "tmap:in:byref");
-	  String *&pname = arg_names[argno];
-	  const char *pname_cstr = GetChar(p, "name");
-	  // Just get rid of the C++ namespace part for now.
-	  const char *ptr = NULL;
-	  if (pname_cstr && (ptr = strrchr(pname_cstr, ':'))) {
-	    pname_cstr = ptr + 1;
-	  }
-	  if (!pname_cstr) {
-	    // Unnamed parameter, e.g. int foo(int);
-	  } else if (!pname) {
-	    pname = NewString(pname_cstr);
-	  } else {
-	    size_t len = strlen(pname_cstr);
-	    size_t spc = 0;
-	    size_t len_pname = strlen(Char(pname));
-	    while (spc + len <= len_pname) {
-	      if (strncmp(pname_cstr, Char(pname) + spc, len) == 0) {
-		char ch = ((char *) Char(pname))[spc + len];
-		if (ch == '\0' || ch == ' ') {
-		  // Already have this pname_cstr.
-		  pname_cstr = NULL;
-		  break;
-		}
-	      }
-	      char *p = strchr(Char(pname) + spc, ' ');
-	      if (!p)
-		break;
-	      spc = (p + 4) - Char(pname);
-	    }
-	    if (pname_cstr) {
-	      Printf(pname, " or_%s", pname_cstr);
-	    }
-	  }
-	  String *value = NewString(Getattr(p, "value"));
-	  if (Len(value)) {
-	    /* Check that value is a valid constant in PHP (and adjust it if
-	     * necessary, or replace it with "?" if it's just not valid). */
-	    SwigType *type = Getattr(p, "type");
-	    switch (SwigType_type(type)) {
-	      case T_BOOL: {
-		if (Strcmp(value, "true") == 0 || Strcmp(value, "false") == 0)
-		  break;
-		char *p;
-		errno = 0;
-		long n = strtol(Char(value), &p, 0);
-	        Clear(value);
-		if (errno || *p) {
-		  Append(value, "?");
-		} else if (n) {
-		  Append(value, "true");
-		} else {
-		  Append(value, "false");
-		}
-		break;
-	      }
-	      case T_CHAR:
-	      case T_SCHAR:
-	      case T_SHORT:
-	      case T_INT:
-	      case T_LONG:
-	      case T_LONGLONG: {
-		char *p;
-		errno = 0;
-		long n = strtol(Char(value), &p, 0);
-		(void) n;
-		if (errno || *p) {
-		  Clear(value);
-		  Append(value, "?");
-		}
-		break;
-	      }
-	      case T_UCHAR:
-	      case T_USHORT:
-	      case T_UINT:
-	      case T_ULONG:
-	      case T_ULONGLONG: {
-		char *p;
-		errno = 0;
-		unsigned int n = strtoul(Char(value), &p, 0);
-		(void) n;
-		if (errno || *p) {
-		  Clear(value);
-		  Append(value, "?");
-		}
-		break;
-	      }
-	      case T_FLOAT:
-	      case T_DOUBLE:
-	      case T_LONGDOUBLE: {
-		char *p;
-		errno = 0;
-		/* FIXME: strtod is locale dependent... */
-		double val = strtod(Char(value), &p);
-		if (errno || *p) {
-		  Clear(value);
-		  Append(value, "?");
-		} else if (strchr(Char(value), '.') == 0) {
-		  // Ensure value is a double constant, not an integer one.
-		  Append(value, ".0");
-		  double val2 = strtod(Char(value), &p);
-		  if (errno || *p || val != val2) {
-		    Clear(value);
-		    Append(value, "?");
-		  }
-		}
-		break;
-	      }
-	      case T_STRING:
-		if (Len(value) < 2) {
-		  // How can a string (including "" be less than 2 characters?)
-		  Clear(value);
-		  Append(value, "?");
-		} else {
-		  const char *v = Char(value);
-		  if (v[0] != '"' || v[Len(value) - 1] != '"') {
-		    Clear(value);
-		    Append(value, "?");
-		  }
-		  // Strings containing "$" require special handling, but we do
-		  // that later.
-		}
-		break;
-	      case T_VOID:
-		assert(false);
-		break;
-	      case T_POINTER: {
-		const char *v = Char(value);
-		if (v[0] == '(') {
-		  // Handle "(void*)0", "(TYPE*)0", "(char*)NULL", etc.
-		  v += strcspn(v + 1, "*()") + 1;
-		  if (*v == '*') {
-		    do {
-		      v++;
-		      v += strspn(v, " \t");
-		    } while (*v == '*');
-		    if (*v++ == ')') {
-		      v += strspn(v, " \t");
-		      String * old = value;
-		      value = NewString(v);
-		      Delete(old);
-		    }
-		  }
-		}
-		if (Strcmp(value, "NULL") == 0 ||
-		    Strcmp(value, "nullptr") == 0 ||
-		    Strcmp(value, "0") == 0 ||
-		    Strcmp(value, "0L") == 0) {
-		  Clear(value);
-		  Append(value, "null");
-		} else {
-		  Clear(value);
-		  Append(value, "?");
-		}
-		break;
-	      }
-	      default:
-		/* Safe default */
-		Clear(value);
-		Append(value, "?");
-		break;
-	    }
-
-	    if (!arg_values[argno]) {
-	      arg_values[argno] = value;
-	      value = NULL;
-	    } else if (Cmp(arg_values[argno], value) != 0) {
-	      // If a parameter has two different default values in
-	      // different overloaded forms of the function, we can't
-	      // set its default in PHP.  Flag this by setting its
-	      // default to `?'.
-	      Delete(arg_values[argno]);
-	      arg_values[argno] = NewString("?");
-	    }
-	  } else if (arg_values[argno]) {
-	    // This argument already has a default value in another overloaded
-	    // form, but doesn't in this form.  So don't try to do anything
-	    // clever, just let the C wrappers resolve the overload and set the
-	    // default values.
-	    //
-	    // This handling is safe, but I'm wondering if it may be overly
-	    // conservative (FIXME) in some cases.  It seems it's only bad when
-	    // there's an overloaded form with the appropriate number of
-	    // parameters which doesn't want the default value, but I need to
-	    // think about this more.
-	    Delete(arg_values[argno]);
-	    arg_values[argno] = NewString("?");
-	  }
-	  Delete(value);
-	  p = nextSibling(p);
-	  ++argno;
-	}
-	if (!really_overloaded)
-	  break;
-	o = Getattr(o, "sym:nextSibling");
-      }
-
-      /* Clean up any parameters which haven't yet got names, or whose
-       * names clash. */
-      Hash *seen = NewHash();
-      /* We need $this to refer to the current class, so can't allow it
-       * to be used as a parameter. */
-      Setattr(seen, "this", seen);
-
-      for (int argno = 0; argno < max_num_of_arguments; ++argno) {
-	String *&pname = arg_names[argno];
-	if (pname) {
-	  Replaceall(pname, " ", "_");
-	} else {
-	  /* We get here if the SWIG .i file has "int foo(int);" */
-	  pname = NewStringEmpty();
-	  Printf(pname, "arg%d", argno + 1);
-	}
-	// Check if we've already used this parameter name.
-	while (Getattr(seen, pname)) {
-	  // Append "_" to clashing names until they stop clashing...
-	  Printf(pname, "_");
-	}
-	Setattr(seen, Char(pname), seen);
-
-	if (arg_values[argno] && Cmp(arg_values[argno], "?") == 0) {
-	  handle_as_overload = true;
-	}
-      }
-      Delete(seen);
-      seen = NULL;
-
-      String *invoke = NewStringEmpty();
-      String *prepare = NewStringEmpty();
-      String *args = NewStringEmpty();
-
-      if (!handle_as_overload && !(really_overloaded && max_num_of_arguments > min_num_of_arguments)) {
-	Printf(invoke, "%s(", iname);
-	if (wrapperType == memberfn) {
-	  Printf(invoke, "$this->%s", SWIG_PTR);
-	}
-	for (int i = 0; i < max_num_of_arguments; ++i) {
-	  if (i)
-	    Printf(args, ",");
-	  if (i || wrapperType == memberfn)
-	    Printf(invoke, ",");
-	  if (byref[i]) Printf(args, "&");
-	  String *value = arg_values[i];
-	  if (value) {
-	    const char *v = Char(value);
-	    if (v[0] == '"') {
-	      /* In a PHP double quoted string, $ needs to be escaped as \$. */
-	      Replaceall(value, "$", "\\$");
-	    }
-	    Printf(args, "$%s=%s", arg_names[i], value);
-	  } else if (constructor && strcmp(methodname, "__construct") == 0 && i >= 1 && i < min_num_of_arguments) {
-	    // We need to be able to call __construct($resource).
-	    Printf(args, "$%s=null", arg_names[i]);
-	  } else {
-	    Printf(args, "$%s", arg_names[i]);
-	  }
-	  Printf(invoke, "$%s", arg_names[i]);
-	}
-	Printf(invoke, ")");
-      } else {
-	int i;
-	for (i = 0; i < min_num_of_arguments; ++i) {
-	  if (i)
-	    Printf(args, ",");
-	  Printf(args, "$%s", arg_names[i]);
-	}
-	String *invoke_args = NewStringEmpty();
-	if (wrapperType == memberfn) {
-	  Printf(invoke_args, "$this->%s", SWIG_PTR);
-	  if (min_num_of_arguments > 0)
-	    Printf(invoke_args, ",");
-	}
-	Printf(invoke_args, "%s", args);
-	if (constructor && min_num_of_arguments > 1) {
-	  // We need to be able to call __construct($resource).
-	  Clear(args);
-	  Printf(args, "$%s", arg_names[0]);
-	  for (i = 1; i < min_num_of_arguments; ++i) {
-	    Printf(args, ",");
-	    Printf(args, "$%s=null", arg_names[i]);
-	  }
-	}
-	bool had_a_case = false;
-	int last_handled_i = i - 1;
-	for (; i < max_num_of_arguments; ++i) {
-	  if (i)
-	    Printf(args, ",");
-	  const char *value = Char(arg_values[i]);
-	  // FIXME: (really_overloaded && handle_as_overload) is perhaps a
-	  // little conservative, but it doesn't hit any cases that it
-	  // shouldn't for Xapian at least (and we need it to handle
-	  // "Enquire::get_mset()" correctly).
-	  bool non_php_default = ((really_overloaded && handle_as_overload) ||
-				  !value || strcmp(value, "?") == 0);
-	  if (non_php_default)
-	    value = "null";
-	  Printf(args, "$%s=%s", arg_names[i], value);
-	  if (non_php_default) {
-	    if (!had_a_case) {
-	      Printf(prepare, "\t\tswitch (func_num_args()) {\n");
-	      had_a_case = true;
-	    }
-	    Printf(prepare, "\t\t");
-	    while (last_handled_i < i) {
-	      Printf(prepare, "case %d: ", ++last_handled_i);
-	    }
-	    if (non_void_return) {
-	      if ((!directorsEnabled() || !Swig_directorclass(n)) && !constructor) {
-		Append(prepare, "$r=");
-	      } else if (wrapperType == staticmemberfn || wrapperType == staticmembervar) {
-		Append(prepare, "$r=");
-	      } else {
-		Printf(prepare, "$this->%s=", SWIG_PTR);
-	      }
-	    }
-	    if (!directorsEnabled() || !Swig_directorclass(n) || !constructor) {
-	      Printf(prepare, "%s(%s); break;\n", iname, invoke_args);
-	    } else if (!i) {
-	      Printf(prepare, "%s($_this%s); break;\n", iname, invoke_args);
-	    } else {
-	      Printf(prepare, "%s($_this, %s); break;\n", iname, invoke_args);
-	    }
-	  }
-	  if (i || wrapperType == memberfn)
-	    Printf(invoke_args, ",");
-	  Printf(invoke_args, "$%s", arg_names[i]);
-	}
-	Printf(prepare, "\t\t");
-	if (had_a_case)
-	  Printf(prepare, "default: ");
-	if (non_void_return) {
-	  if ((!directorsEnabled() || !Swig_directorclass(n)) && !constructor) {
-	    Append(prepare, "$r=");
-	  } else if (wrapperType == staticmemberfn || wrapperType == staticmembervar) {
-	    Append(prepare, "$r=");
-	  } else {
-	    Printf(prepare, "$this->%s=", SWIG_PTR);
-	  }
-	}
-
-	if (!directorsEnabled() || !Swig_directorclass(n) || !constructor) {
-	  Printf(prepare, "%s(%s);\n", iname, invoke_args);
-	} else {
-	  Printf(prepare, "%s($_this, %s);\n", iname, invoke_args);
-	}
-	if (had_a_case)
-	  Printf(prepare, "\t\t}\n");
-	Delete(invoke_args);
-	Printf(invoke, "$r");
-      }
-
-      Printf(output, "\n");
-      // If it's a member function or a class constructor...
-      if (wrapperType == memberfn || (constructor && current_class)) {
-	String *acc = NewString(Getattr(n, "access"));
-	// If a base has the same method with public access, then PHP
-	// requires to have it here as public as well
-	Node *bases = Getattr(Swig_methodclass(n), "bases");
-	if (bases && Strcmp(acc, "public") != 0) {
-	  String *warnmsg = 0;
-	  int haspublicbase = 0;
-	  Iterator i = First(bases);
-	  while (i.item) {
-	    Node *j = firstChild(i.item);
-	    while (j) {
-	      String *jname = Getattr(j, "name");
-	      if (!jname || Strcmp(jname, Getattr(n, "name")) != 0) {
-		j = nextSibling(j);
-		continue;
-	      }
-	      if (Strcmp(nodeType(j), "cdecl") == 0) {
-		if (!Getattr(j, "access") || checkAttribute(j, "access", "public")) {
-		  haspublicbase = 1;
-		}
-	      } else if (Strcmp(nodeType(j), "using") == 0 && firstChild(j) && Strcmp(nodeType(firstChild(j)), "cdecl") == 0) {
-		if (!Getattr(firstChild(j), "access") || checkAttribute(firstChild(j), "access", "public")) {
-		  haspublicbase = 1;
-		}
-	      }
-	      if (haspublicbase) {
-		  warnmsg = NewStringf("Modifying the access of '%s::%s' to public, as the base '%s' has it as public as well.\n", Getattr(current_class, "classtype"), Getattr(n, "name"), Getattr(i.item, "classtype"));
-		  break;
-	      }
-	      j = nextSibling(j);
-	    }
-	    i = Next(i);
-	    if (haspublicbase) {
-	      break;
-	    }
-	  }
-	  if (Getattr(n, "access") && haspublicbase) {
-	    Delete(acc);
-	    acc = NewStringEmpty(); // implicitly public
-	    Swig_warning(WARN_PHP_PUBLIC_BASE, input_file, line_number, Char(warnmsg));
-	    Delete(warnmsg);
-	  }
-	}
-
-	if (Cmp(acc, "public") == 0) {
-	  // The default visibility for methods is public, so don't specify
-	  // that explicitly to keep the wrapper size down.
-	  Delete(acc);
-	  acc = NewStringEmpty();
-	} else if (Cmp(acc, "") != 0) {
-	  Append(acc, " ");
-	}
-
-	if (constructor) {
-	  // Discriminate between the PHP constructor and a C++ constructor
-	  // renamed to become a factory function in PHP.
-	  bool php_constructor = (strcmp(methodname, "__construct") == 0);
-	  const char * arg0 = NULL;
-	  if (max_num_of_arguments > 0) {
-	    arg0 = Char(arg_names[0]);
-	  } else if (php_constructor) {
-	    // The PHP constructor needs to be able to wrap a resource, but a
-	    // renamed constructor doesn't.
-	    arg0 = "res";
-	    Delete(args);
-	    args = NewString("$res=null");
-	  }
-	  String *mangled_type = SwigType_manglestr(Getattr(n, "type"));
-	  if (!php_constructor) {
-	    // A renamed constructor should be a static method.
-	    Append(acc, "static ");
-	  }
-	  Printf(output, "\t%sfunction %s(%s) {\n", acc, methodname, args);
-	  if (php_constructor) {
-	    // The PHP constructor needs to be able to wrap a resource, but a
-	    // renamed constructor doesn't.
-	    Printf(output, "\t\tif (is_resource($%s) && get_resource_type($%s) === '%s') {\n", arg0, arg0, mangled_type);
-	    Printf(output, "\t\t\t$this->%s=$%s;\n", SWIG_PTR, arg0);
-	    Printf(output, "\t\t\treturn;\n");
-	    Printf(output, "\t\t}\n");
-	  }
-	} else {
-	  Printf(output, "\t%sfunction %s(%s) {\n", acc, methodname, args);
-	}
-	Delete(acc);
-      } else if (wrapperType == staticmembervar) {
-	// We're called twice for a writable static member variable - first
-	// with "foo_set" and then with "foo_get" - so generate half the
-	// wrapper function each time.
-	//
-	// For a const static member, we only get called once.
-	static bool started = false;
-	if (!started) {
-	  Printf(output, "\tstatic function %s() {\n", methodname);
-	  if (max_num_of_arguments) {
-	    // Setter.
-	    Printf(output, "\t\tif (func_num_args()) {\n");
-	    Printf(output, "\t\t\t%s(func_get_arg(0));\n", iname);
-	    Printf(output, "\t\t\treturn;\n");
-	    Printf(output, "\t\t}\n");
-	    started = true;
-	    goto done;
-	  }
-	}
-	started = false;
-      } else {
-	Printf(output, "\tstatic function %s(%s) {\n", methodname, args);
-      }
-
-      if (!constructor)
-	Printf(output, "%s", prepare);
-      if (constructor) {
-	if (!directorsEnabled() || !Swig_directorclass(n)) {
-	  if (!Len(prepare)) {
-	    if (strcmp(methodname, "__construct") == 0) {
-	      Printf(output, "\t\t$this->%s=%s;\n", SWIG_PTR, invoke);
-	    } else {
-	      String *classname = Swig_class_name(current_class);
-	      Printf(output, "\t\treturn new %s%s(%s);\n", prefix, classname, invoke);
-	    }
-	  }
-	} else {
-	  Node *parent = Swig_methodclass(n);
-	  String *classname = Swig_class_name(parent);
-	  Printf(output, "\t\tif (get_class($this) === '%s%s') {\n", prefix, classname);
-	  Printf(output, "\t\t\t$_this = null;\n");
-	  Printf(output, "\t\t} else {\n");
-	  Printf(output, "\t\t\t$_this = $this;\n");
-	  Printf(output, "\t\t}\n");
-	  if (!Len(prepare)) {
-	    if (num_arguments > 1) {
-	      Printf(output, "\t\t$this->%s=%s($_this, %s);\n", SWIG_PTR, iname, args);
-	    } else {
-	      Printf(output, "\t\t$this->%s=%s($_this);\n", SWIG_PTR, iname);
-	    }
-	  }
-	}
-	Printf(output, "%s", prepare);
-      } else if (!non_void_return && !hasargout) {
-	if (Cmp(invoke, "$r") != 0)
-	  Printf(output, "\t\t%s;\n", invoke);
-      } else if (is_class(d)) {
-	if (Cmp(invoke, "$r") != 0)
-	  Printf(output, "\t\t$r=%s;\n", invoke);
-	if (Len(ret_types) == 1) {
-	  /* If d is abstract we can't create a new wrapper type d. */
-	  Node *d_class = classLookup(d);
-	  int is_abstract = 0;
-	  if (Getattr(d_class, "abstracts")) {
-	    is_abstract = 1;
-	  }
-	  if (newobject || !is_abstract) {
-	    Printf(output, "\t\tif (is_resource($r)) {\n");
-	    if (Getattr(classLookup(Getattr(n, "type")), "module")) {
-	      /*
-	       * _p_Foo -> Foo, _p_ns__Bar -> Bar
-	       * TODO: do this in a more elegant way
-	       */
-	      if (Len(prefix) == 0) {
-		Printf(output, "\t\t\t$c=substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));\n");
-	      } else {
-		Printf(output, "\t\t\t$c='%s'.substr(get_resource_type($r), (strpos(get_resource_type($r), '__') ? strpos(get_resource_type($r), '__') + 2 : 3));\n", prefix);
-	      }
-	      Printf(output, "\t\t\tif (class_exists($c)) return new $c($r);\n");
-	      Printf(output, "\t\t\treturn new %s%s($r);\n", prefix, Getattr(classLookup(d), "sym:name"));
-	    } else {
-	      Printf(output, "\t\t\t$c = new stdClass();\n");
-	      Printf(output, "\t\t\t$c->" SWIG_PTR " = $r;\n");
-	      Printf(output, "\t\t\treturn $c;\n");
-	    }
-	    Printf(output, "\t\t}\n\t\treturn $r;\n");
-	  } else {
-	    Printf(output, "\t\t$this->%s = $r;\n", SWIG_PTR);
-	    Printf(output, "\t\treturn $this;\n");
-	  }
-	} else {
-	  Printf(output, "\t\tif (!is_resource($r)) return $r;\n");
-	  String *wrapobj = NULL;
-	  String *common = NULL;
-	  Iterator i = First(ret_types);
-	  while (i.item) {
-	    SwigType *ret_type = i.item;
-	    i = Next(i);
-	    String *mangled = NewString("_p");
-	    Printf(mangled, "%s", SwigType_manglestr(ret_type));
-	    Node *class_node = Getattr(zend_types, mangled);
-	    if (!class_node) {
-	      /* This is needed when we're returning a pointer to a type
-	       * rather than returning the type by value or reference. */
-	      Delete(mangled);
-	      mangled = NewString(SwigType_manglestr(ret_type));
-	      class_node = Getattr(zend_types, mangled);
-	      if (!class_node) {
-		// Return type isn't an object, so will be handled by the
-		// !is_resource() check before the switch.
-		continue;
-	      }
-	    }
-	    const char *classname = GetChar(class_node, "sym:name");
-	    if (!classname)
-	      classname = GetChar(class_node, "name");
-	    String * action = NewStringEmpty();
-	    if (classname)
-	      Printf(action, "return new %s%s($r);\n", prefix, classname);
-            else
-	      Printf(action, "return $r;\n");
-	    if (!wrapobj) {
-		wrapobj = NewString("\t\tswitch (get_resource_type($r)) {\n");
-		common = action;
-	    } else {
-		if (common && Cmp(common, action) != 0) {
-		    Delete(common);
-		    common = NULL;
-		}
-	    }
-	    Printf(wrapobj, "\t\t");
-	    if (i.item) {
-	      Printf(wrapobj, "case '%s': ", mangled);
-	    } else {
-	      Printf(wrapobj, "default: ");
-	    }
-	    Printv(wrapobj, action, NIL);
-	    if (action != common) Delete(action);
-	    Delete(mangled);
-	  }
-	  Printf(wrapobj, "\t\t}\n");
-	  if (common) {
-	      // All cases have the same action, so eliminate the switch
-	      // wrapper.
-	      Printf(output, "\t\t%s", common);
-	      Delete(common);
-	  } else {
-	      Printv(output, wrapobj, NIL);
-	  }
-	  Delete(wrapobj);
-	}
-      } else {
-	if (non_void_return || hasargout) {
-	  Printf(output, "\t\treturn %s;\n", invoke);
-	} else if (Cmp(invoke, "$r") != 0) {
-	  Printf(output, "\t\t%s;\n", invoke);
-	}
-      }
-      Printf(output, "\t}\n");
-
-done:
-      Delete(prepare);
-      Delete(invoke);
-      free(arg_values);
-
-      Delete(args);
-      args = NULL;
-
-      for (int i = 0; i < max_num_of_arguments; ++i) {
-	Delete(arg_names[i]);
-      }
-      free(arg_names);
-      arg_names = NULL;
     }
 
     return SWIG_OK;
@@ -1880,57 +1676,13 @@
    * globalvariableHandler()
    * ------------------------------------------------------------ */
 
-  virtual int globalvariableHandler(Node *n) {
-    char *name = GetChar(n, "name");
-    char *iname = GetChar(n, "sym:name");
-    SwigType *t = Getattr(n, "type");
-    String *tm;
-
-    /* First do the wrappers such as name_set(), name_get()
-     * as provided by the baseclass's implementation of variableWrapper
-     */
-    if (Language::globalvariableHandler(n) == SWIG_NOWRAP) {
-      return SWIG_NOWRAP;
-    }
-
-    if (!addSymbol(iname, n))
-      return SWIG_ERROR;
-
-    /* First link C variables to PHP */
-
-    tm = Swig_typemap_lookup("varinit", n, name, 0);
-    if (tm) {
-      Replaceall(tm, "$target", name);
-      Printf(s_vinit, "%s\n", tm);
-    } else {
-      Swig_error(input_file, line_number, "Unable to link with type %s\n", SwigType_str(t, 0));
-    }
-
-    /* Now generate PHP -> C sync blocks */
-    /*
-       tm = Swig_typemap_lookup("varin", n, name, 0);
-       if(tm) {
-       Replaceall(tm, "$symname", iname);
-       Printf(f_c->code, "%s\n", tm);
-       } else {
-       Swig_error(input_file, line_number, "Unable to link with type %s\n", SwigType_str(t, 0));
-       }
-     */
-    /* Now generate C -> PHP sync blocks */
-    /*
-       if(!GetFlag(n,"feature:immutable")) {
-
-       tm = Swig_typemap_lookup("varout", n, name, 0);
-       if(tm) {
-       Replaceall(tm, "$symname", iname);
-       Printf(f_php->code, "%s\n", tm);
-       } else {
-       Swig_error(input_file, line_number, "Unable to link with type %s\n", SwigType_str(t, 0));
-       }
-       }
-     */
-    return SWIG_OK;
-  }
+  /* PHP doesn't support intercepting reads and writes to global variables
+   * (nor static property reads and writes so we can't wrap them as static
+   * properties on a dummy class) so just let SWIG do its default thing and
+   * wrap them as name_get() and name_set().
+   */
+  //virtual int globalvariableHandler(Node *n) {
+  //}
 
   /* ------------------------------------------------------------
    * constantWrapper()
@@ -1949,48 +1701,43 @@
 
     SwigType_remember(type);
 
-    if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) {
-      Replaceall(tm, "$source", value);
-      Replaceall(tm, "$target", name);
-      Replaceall(tm, "$value", value);
-      Printf(s_cinit, "%s\n", tm);
-    }
-
-    if (shadow) {
-      String *enumvalue = GetChar(n, "enumvalue");
-      String *set_to = iname;
-
-      if (!enumvalue) {
-	enumvalue = GetChar(n, "enumvalueex");
-      }
-
-      if (enumvalue && *Char(enumvalue)) {
-	// Check for a simple constant expression which is valid in PHP.
-	// If we find one, initialise the const member with it; otherwise
-	// we initialise it using the C/C++ wrapped constant.
-	const char *p;
-	for (p = Char(enumvalue); *p; ++p) {
-	  if (!isdigit((unsigned char)*p) && !strchr(" +-", *p)) {
-	    // FIXME: enhance to handle `<previous_enum> + 1' which is what
-	    // we get for enums that don't have an explicit value set.
-	    break;
-	  }
+    String *wrapping_member_constant = Getattr(n, "memberconstantHandler:sym:name");
+    if (!wrapping_member_constant) {
+      {
+	tm = Swig_typemap_lookup("consttab", n, name, 0);
+	Replaceall(tm, "$value", value);
+	if (Getattr(n, "tmap:consttab:rinit")) {
+	  Printf(r_init, "%s\n", tm);
+	} else {
+	  Printf(s_cinit, "%s\n", tm);
 	}
-	if (!*p)
-	  set_to = enumvalue;
       }
 
-      if (wrapping_member_constant) {
-	if (!s_oowrappers)
-	  s_oowrappers = NewStringEmpty();
-	Printf(s_oowrappers, "\n\tconst %s = %s;\n", wrapping_member_constant, set_to);
+      {
+	tm = Swig_typemap_lookup("classconsttab", n, name, 0);
+
+	Replaceall(tm, "$class", fake_class_name());
+	Replaceall(tm, "$const_name", iname);
+	Replaceall(tm, "$value", value);
+	if (Getattr(n, "tmap:classconsttab:rinit")) {
+	  Printf(r_init, "%s\n", tm);
+	} else {
+	  Printf(s_cinit, "%s\n", tm);
+	}
+      }
+    } else {
+      tm = Swig_typemap_lookup("classconsttab", n, name, 0);
+      Replaceall(tm, "$class", class_name);
+      Replaceall(tm, "$const_name", wrapping_member_constant);
+      Replaceall(tm, "$value", value);
+      if (Getattr(n, "tmap:classconsttab:rinit")) {
+	Printf(r_init, "%s\n", tm);
       } else {
-	if (!s_fakeoowrappers)
-	  s_fakeoowrappers = NewStringEmpty();
-	Printf(s_fakeoowrappers, "\n\tconst %s = %s;\n", iname, set_to);
+	Printf(s_cinit, "%s\n", tm);
       }
     }
 
+    wrapperType = standard;
     return SWIG_OK;
   }
 
@@ -2039,11 +1786,6 @@
    * ------------------------------------------------------------ */
 
   virtual int classDeclaration(Node *n) {
-    if (!Getattr(n, "feature:onlychildren")) {
-      String *symname = Getattr(n, "sym:name");
-      Setattr(n, "php:proxy", symname);
-    }
-
     return Language::classDeclaration(n);
   }
 
@@ -2052,219 +1794,240 @@
    * ------------------------------------------------------------ */
 
   virtual int classHandler(Node *n) {
-    constructors = 0;
-    current_class = n;
+    String *symname = Getattr(n, "sym:name");
+
+    class_name = symname;
+    base_class = NULL;
+    destructor_action = NULL;
+
+    Printf(all_cs_entry, "static const zend_function_entry class_%s_functions[] = {\n", class_name);
+
+    // namespace code to introduce namespaces into wrapper classes.
+    //if (nameSpace != NULL)
+      //Printf(s_oinit, "INIT_CLASS_ENTRY(internal_ce, \"%s\\\\%s\", class_%s_functions);\n", nameSpace, class_name, class_name);
+    //else
+    Printf(s_oinit, "  INIT_CLASS_ENTRY(internal_ce, \"%s%s\", class_%s_functions);\n", prefix, class_name, class_name);
 
     if (shadow) {
       char *rename = GetChar(n, "sym:name");
 
       if (!addSymbol(rename, n))
 	return SWIG_ERROR;
-      shadow_classname = NewString(rename);
-
-      shadow_get_vars = NewHash();
-      shadow_set_vars = NewHash();
 
       /* Deal with inheritance */
       List *baselist = Getattr(n, "bases");
       if (baselist) {
 	Iterator base = First(baselist);
-	while (base.item && GetFlag(base.item, "feature:ignore")) {
-	  base = Next(base);
-	}
-	base = Next(base);
-	if (base.item) {
-	  /* Warn about multiple inheritance for additional base class(es) */
-	  while (base.item) {
-	    if (GetFlag(base.item, "feature:ignore")) {
-	      base = Next(base);
-	      continue;
+	while (base.item) {
+	  if (!GetFlag(base.item, "feature:ignore")) {
+	    if (!base_class) {
+	      base_class = Getattr(base.item, "sym:name");
+	    } else {
+	      /* Warn about multiple inheritance for additional base class(es) */
+	      String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0);
+	      String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0);
+	      Swig_warning(WARN_PHP_MULTIPLE_INHERITANCE, input_file, line_number,
+			   "Warning for %s, base %s ignored. Multiple inheritance is not supported in PHP.\n", proxyclassname, baseclassname);
 	    }
-	    String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0);
-	    String *baseclassname = SwigType_str(Getattr(base.item, "name"), 0);
-	    Swig_warning(WARN_PHP_MULTIPLE_INHERITANCE, input_file, line_number,
-			 "Warning for %s, base %s ignored. Multiple inheritance is not supported in PHP.\n", proxyclassname, baseclassname);
-	    base = Next(base);
 	  }
-	}
-      }
-    }
-
-    classnode = n;
-    Language::classHandler(n);
-    classnode = 0;
-
-    if (shadow) {
-      List *baselist = Getattr(n, "bases");
-      Iterator ki, base;
-
-      if (baselist) {
-	base = First(baselist);
-	while (base.item && GetFlag(base.item, "feature:ignore")) {
 	  base = Next(base);
 	}
-      } else {
-	base.item = NULL;
       }
-
-      if (Getattr(n, "abstracts") && !GetFlag(n, "feature:notabstract")) {
-	Printf(s_phpclasses, "abstract ");
-      }
-
-      Printf(s_phpclasses, "class %s%s ", prefix, shadow_classname);
-      String *baseclass = NULL;
-      if (base.item && Getattr(base.item, "module")) {
-	baseclass = Getattr(base.item, "sym:name");
-	if (!baseclass)
-	  baseclass = Getattr(base.item, "name");
-	Printf(s_phpclasses, "extends %s%s ", prefix, baseclass);
-      } else if (GetFlag(n, "feature:exceptionclass")) {
-	Append(s_phpclasses, "extends Exception ");
-      }
-      {
-	Node *node = NewHash();
-	Setattr(node, "type", Getattr(n, "name"));
-	Setfile(node, Getfile(n));
-	Setline(node, Getline(n));
-	String * interfaces = Swig_typemap_lookup("phpinterfaces", node, "", 0);
-	if (interfaces) {
-	  Printf(s_phpclasses, "implements %s ", interfaces);
-	}
-	Delete(node);
-      }
-      Printf(s_phpclasses, "{\n\tpublic $%s=null;\n", SWIG_PTR);
-      if (!baseclass) {
-	// Only store this in the base class (NB !baseclass means we *are*
-	// a base class...)
-	Printf(s_phpclasses, "\tprotected $%s=array();\n", SWIG_DATA);
-      }
-
-      // Write property SET handlers
-      ki = First(shadow_set_vars);
-      if (ki.key) {
-	// This class has setters.
-	Printf(s_phpclasses, "\n\tfunction __set($var,$value) {\n");
-	// FIXME: tune this threshold...
-	if (Len(shadow_set_vars) <= 2) {
-	  // Not many setters, so avoid call_user_func.
-	  for (; ki.key; ki = Next(ki)) {
-	    DOH *key = ki.key;
-	    String *iname = ki.item;
-	    Printf(s_phpclasses, "\t\tif ($var === '%s') return %s($this->%s,$value);\n", key, iname, SWIG_PTR);
-	  }
-	} else {
-	  Printf(s_phpclasses, "\t\t$func = '%s_'.$var.'_set';\n", shadow_classname);
-	  Printf(s_phpclasses, "\t\tif (function_exists($func)) return call_user_func($func,$this->%s,$value);\n", SWIG_PTR);
-	}
-	Printf(s_phpclasses, "\t\tif ($var === 'thisown') return swig_%s_alter_newobject($this->%s,$value);\n", module, SWIG_PTR);
-	if (baseclass) {
-	  Printf(s_phpclasses, "\t\t%s%s::__set($var,$value);\n", prefix, baseclass);
-	} else {
-	  Printf(s_phpclasses, "\t\t$this->%s[$var] = $value;\n", SWIG_DATA);
-	}
-	Printf(s_phpclasses, "\t}\n");
-      } else {
-	Printf(s_phpclasses, "\n\tfunction __set($var,$value) {\n");
-	Printf(s_phpclasses, "\t\tif ($var === 'thisown') return swig_%s_alter_newobject($this->%s,$value);\n", module, SWIG_PTR);
-	if (baseclass) {
-	  Printf(s_phpclasses, "\t\t%s%s::__set($var,$value);\n", prefix, baseclass);
-	} else {
-	  Printf(s_phpclasses, "\t\t$this->%s[$var] = $value;\n", SWIG_DATA);
-	}
-	Printf(s_phpclasses, "\t}\n");
-      }
-
-      // Write property GET handlers
-      ki = First(shadow_get_vars);
-      if (ki.key) {
-	// This class has getters.
-	Printf(s_phpclasses, "\n\tfunction __get($var) {\n");
-	int non_class_getters = 0;
-	for (; ki.key; ki = Next(ki)) {
-	  DOH *key = ki.key;
-	  SwigType *d = ki.item;
-	  if (!is_class(d)) {
-	    ++non_class_getters;
-	    continue;
-	  }
-	  Printv(s_phpclasses, "\t\tif ($var === '", key, "') return new ", prefix, Getattr(classLookup(d), "sym:name"), "(", shadow_classname, "_", key, "_get($this->", SWIG_PTR, "));\n", NIL);
-	}
-	// FIXME: tune this threshold...
-	if (non_class_getters <= 2) {
-	  // Not many non-class getters, so avoid call_user_func.
-	  for (ki = First(shadow_get_vars); non_class_getters && ki.key;  ki = Next(ki)) {
-	    DOH *key = ki.key;
-	    SwigType *d = ki.item;
-	    if (is_class(d)) continue;
-	    Printv(s_phpclasses, "\t\tif ($var === '", key, "') return ", shadow_classname, "_", key, "_get($this->", SWIG_PTR, ");\n", NIL);
-	    --non_class_getters;
-	  }
-	} else {
-	  Printf(s_phpclasses, "\t\t$func = '%s_'.$var.'_get';\n", shadow_classname);
-	  Printf(s_phpclasses, "\t\tif (function_exists($func)) return call_user_func($func,$this->%s);\n", SWIG_PTR);
-	}
-	Printf(s_phpclasses, "\t\tif ($var === 'thisown') return swig_%s_get_newobject($this->%s);\n", module, SWIG_PTR);
-	if (baseclass) {
-	  Printf(s_phpclasses, "\t\treturn %s%s::__get($var);\n", prefix, baseclass);
-	} else {
-	  // Reading an unknown property name gives null in PHP.
-	  Printf(s_phpclasses, "\t\treturn $this->%s[$var];\n", SWIG_DATA);
-	}
-	Printf(s_phpclasses, "\t}\n");
-
-	/* __isset() should return true for read-only properties, so check for
-	 * *_get() not *_set(). */
-	Printf(s_phpclasses, "\n\tfunction __isset($var) {\n");
-	Printf(s_phpclasses, "\t\tif (function_exists('%s_'.$var.'_get')) return true;\n", shadow_classname);
-	Printf(s_phpclasses, "\t\tif ($var === 'thisown') return true;\n");
-	if (baseclass) {
-	  Printf(s_phpclasses, "\t\treturn %s%s::__isset($var);\n", prefix, baseclass);
-	} else {
-	  Printf(s_phpclasses, "\t\treturn array_key_exists($var, $this->%s);\n", SWIG_DATA);
-	}
-	Printf(s_phpclasses, "\t}\n");
-      } else {
-	Printf(s_phpclasses, "\n\tfunction __get($var) {\n");
-	Printf(s_phpclasses, "\t\tif ($var === 'thisown') return swig_%s_get_newobject($this->%s);\n", module, SWIG_PTR);
-	if (baseclass) {
-	  Printf(s_phpclasses, "\t\treturn %s%s::__get($var);\n", prefix, baseclass);
-	} else {
-	  Printf(s_phpclasses, "\t\treturn $this->%s[$var];\n", SWIG_DATA);
-	}
-	Printf(s_phpclasses, "\t}\n");
-	Printf(s_phpclasses, "\n\tfunction __isset($var) {\n");
-	Printf(s_phpclasses, "\t\tif ($var === 'thisown') return true;\n");
-	if (baseclass) {
-	  Printf(s_phpclasses, "\t\treturn %s%s::__isset($var);\n", prefix, baseclass);
-	} else {
-	  Printf(s_phpclasses, "\t\treturn array_key_exists($var, $this->%s);\n", SWIG_DATA);
-	}
-	Printf(s_phpclasses, "\t}\n");
-      }
-
-      if (!class_has_ctor) {
-	Printf(s_phpclasses, "\tfunction __construct($h) {\n");
-	Printf(s_phpclasses, "\t\t$this->%s=$h;\n", SWIG_PTR);
-	Printf(s_phpclasses, "\t}\n");
-      }
-
-      if (s_oowrappers) {
-	Printf(s_phpclasses, "%s", s_oowrappers);
-	Delete(s_oowrappers);
-	s_oowrappers = NULL;
-      }
-      class_has_ctor = false;
-
-      Printf(s_phpclasses, "}\n\n");
-
-      Delete(shadow_classname);
-      shadow_classname = NULL;
-
-      Delete(shadow_set_vars);
-      shadow_set_vars = NULL;
-      Delete(shadow_get_vars);
-      shadow_get_vars = NULL;
     }
+
+    if (GetFlag(n, "feature:exceptionclass") && Getattr(n, "feature:except")) {
+      /* PHP requires thrown objects to be instances of or derived from
+       * Exception, so that really needs to take priority over any
+       * explicit base class.
+       */
+      if (base_class) {
+	String *proxyclassname = SwigType_str(Getattr(n, "classtypeobj"), 0);
+	Swig_warning(WARN_PHP_MULTIPLE_INHERITANCE, input_file, line_number,
+		     "Warning for %s, base %s ignored. Multiple inheritance is not supported in PHP.\n", proxyclassname, base_class);
+      }
+      base_class = NewString("Exception");
+    }
+
+    if (!base_class) {
+      Printf(s_oinit, "  SWIG_Php_ce_%s = zend_register_internal_class(&internal_ce);\n", class_name);
+    } else if (Equal(base_class, "Exception")) {
+      Printf(s_oinit, "  SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, zend_ce_exception);\n", class_name);
+    } else if (is_class_wrapped(base_class)) {
+      Printf(s_oinit, "  SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, SWIG_Php_ce_%s);\n", class_name, base_class);
+      Setattr(php_parent_class, class_name, base_class);
+    } else {
+      Printf(s_oinit, "  {\n");
+      Printf(s_oinit, "    swig_type_info *type_info = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, \"_p_%s\");\n", base_class);
+      Printf(s_oinit, "    SWIG_Php_ce_%s = zend_register_internal_class_ex(&internal_ce, (zend_class_entry*)(type_info ? type_info->clientdata : NULL));\n", class_name);
+      Printf(s_oinit, "  }\n");
+    }
+
+    if (Getattr(n, "abstracts") && !GetFlag(n, "feature:notabstract")) {
+      Printf(s_oinit, "  SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS;\n", class_name);
+    }
+    if (GetFlag(n, "feature:php:allowdynamicproperties")) {
+      Append(s_oinit, "#ifdef ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES\n");
+      Printf(s_oinit, "  SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_ALLOW_DYNAMIC_PROPERTIES;\n", class_name);
+      Append(s_oinit, "#endif\n");
+    } else {
+      Append(s_oinit, "#ifdef ZEND_ACC_NO_DYNAMIC_PROPERTIES\n");
+      Printf(s_oinit, "  SWIG_Php_ce_%s->ce_flags |= ZEND_ACC_NO_DYNAMIC_PROPERTIES;\n", class_name);
+      Append(s_oinit, "#endif\n");
+    }
+    String *swig_wrapped = swig_wrapped_interface_ce();
+    Printv(s_oinit, "  zend_do_implement_interface(SWIG_Php_ce_", class_name, ", &", swig_wrapped, ");\n", NIL);
+
+    {
+      Node *node = NewHash();
+      Setattr(node, "type", Getattr(n, "name"));
+      Setfile(node, Getfile(n));
+      Setline(node, Getline(n));
+      String *interfaces = Swig_typemap_lookup("phpinterfaces", node, "", 0);
+      Replaceall(interfaces, " ", "");
+      if (interfaces && Len(interfaces) > 0) {
+	// It seems we need to wait until RINIT time to look up class entries
+	// for interfaces by name.  The downside is that this then happens for
+	// every request.
+	//
+	// Most pre-defined interfaces are accessible via zend_class_entry*
+	// variables declared in the PHP C API - these we can use at MINIT
+	// time, so we special case them.  This will also be a little faster
+	// than looking up by name.
+	Printv(s_header,
+	       "#ifdef __cplusplus\n",
+	       "extern \"C\" {\n",
+	       "#endif\n",
+	       NIL);
+
+	String *r_init_prefix = NewStringEmpty();
+
+	List *interface_list = Split(interfaces, ',', -1);
+	int num_interfaces = Len(interface_list);
+	for (int i = 0; i < num_interfaces; ++i) {
+	  String *interface = Getitem(interface_list, i);
+	  // We generate conditional code in both minit and rinit - then we or the user
+	  // just need to define SWIG_PHP_INTERFACE_xxx_CE (and optionally
+	  // SWIG_PHP_INTERFACE_xxx_HEADER) to handle interface `xxx` at minit-time.
+	  Printv(s_header,
+		 "#ifdef SWIG_PHP_INTERFACE_", interface, "_HEADER\n",
+		 "# include SWIG_PHP_INTERFACE_", interface, "_HEADER\n",
+		 "#endif\n",
+		 NIL);
+	  Printv(s_oinit,
+		 "#ifdef SWIG_PHP_INTERFACE_", interface, "_CE\n",
+		 "  zend_do_implement_interface(SWIG_Php_ce_", class_name, ", SWIG_PHP_INTERFACE_", interface, "_CE);\n",
+		 "#endif\n",
+		 NIL);
+	  Printv(r_init_prefix,
+		 "#ifndef SWIG_PHP_INTERFACE_", interface, "_CE\n",
+		 "  {\n",
+		 "    zend_class_entry *swig_interface_ce = zend_lookup_class(zend_string_init(\"", interface, "\", sizeof(\"", interface, "\") - 1, 0));\n",
+		 "    if (swig_interface_ce)\n",
+		 "      zend_do_implement_interface(SWIG_Php_ce_", class_name, ", swig_interface_ce);\n",
+                 "    else\n",
+                 "      zend_throw_exception(zend_ce_error, \"Interface \\\"", interface, "\\\" not found\", 0);\n",
+		 "  }\n",
+		 "#endif\n",
+		 NIL);
+	}
+
+	// Handle interfaces at the start of rinit so that they're added
+	// before any potential constant objects, etc which might be created
+	// later in rinit.
+	Insert(r_init, 0, r_init_prefix);
+	Delete(r_init_prefix);
+
+	Printv(s_header,
+	       "#ifdef __cplusplus\n",
+	       "}\n",
+	       "#endif\n",
+	       NIL);
+      }
+      Delete(interfaces);
+    }
+
+    Language::classHandler(n);
+
+    static bool emitted_base_object_handlers = false;
+    if (!emitted_base_object_handlers) {
+      Printf(s_creation, "static zend_object_handlers Swig_Php_base_object_handlers;\n\n");
+
+      // Set up a base zend_object_handlers structure which we can use as-is
+      // for classes without a destructor, and copy as the basis for other
+      // classes.
+      Printf(s_oinit, "  Swig_Php_base_object_handlers = *zend_get_std_object_handlers();\n");
+      Printf(s_oinit, "  Swig_Php_base_object_handlers.offset = XtOffsetOf(swig_object_wrapper, std);\n");
+      Printf(s_oinit, "  Swig_Php_base_object_handlers.clone_obj = NULL;\n");
+      emitted_base_object_handlers = true;
+    }
+
+    Printf(s_creation, "static zend_class_entry *SWIG_Php_ce_%s;\n\n", class_name);
+
+    if (Getattr(n, "has_destructor")) {
+      if (destructor_action ? Equal(destructor_action, "free((char *) arg1);") : !CPlusPlus) {
+	// We can use a single function if the destructor action calls free()
+	// (either explicitly or as the default in C-mode) since free() doesn't
+	// care about the object's type.  We currently only check for the exact
+	// code that Swig_cdestructor_call() emits.
+	static bool emitted_common_cdestructor = false;
+	if (!emitted_common_cdestructor) {
+	  Printf(s_creation, "static zend_object_handlers Swig_Php_common_c_object_handlers;\n\n");
+	  Printf(s_creation, "static void SWIG_Php_common_c_free_obj(zend_object *object) {free(SWIG_Php_free_obj(object));}\n\n");
+	  Printf(s_creation, "static zend_object *SWIG_Php_common_c_create_object(zend_class_entry *ce) {return SWIG_Php_do_create_object(ce, &Swig_Php_common_c_object_handlers);}\n");
+
+	  Printf(s_oinit, "  Swig_Php_common_c_object_handlers = Swig_Php_base_object_handlers;\n");
+	  Printf(s_oinit, "  Swig_Php_common_c_object_handlers.free_obj = SWIG_Php_common_c_free_obj;\n");
+
+	  emitted_common_cdestructor = true;
+	}
+
+	Printf(s_oinit, "  SWIG_Php_ce_%s->create_object = SWIG_Php_common_c_create_object;\n", class_name);
+      } else {
+	Printf(s_creation, "static zend_object_handlers %s_object_handlers;\n", class_name);
+	Printf(s_creation, "static zend_object *SWIG_Php_create_object_%s(zend_class_entry *ce) {return SWIG_Php_do_create_object(ce, &%s_object_handlers);}\n", class_name, class_name);
+
+	Printf(s_creation, "static void SWIG_Php_free_obj_%s(zend_object *object) {",class_name);
+	String *type = Getattr(n, "classtype");
+	// Special case handling the delete call generated by
+	// Swig_cppdestructor_call() and generate simpler code.
+	if (destructor_action && !Equal(destructor_action, "delete arg1;")) {
+	  Printv(s_creation, "\n"
+		 "  ", type, " *arg1 = (" , type, " *)SWIG_Php_free_obj(object);\n"
+		 "  if (arg1) {\n"
+		 "    ", destructor_action, "\n"
+		 "  }\n", NIL);
+	} else {
+	  Printf(s_creation, "delete (%s *)SWIG_Php_free_obj(object);", type);
+	}
+	Printf(s_creation, "}\n\n");
+
+	Printf(s_oinit, "  SWIG_Php_ce_%s->create_object = SWIG_Php_create_object_%s;\n", class_name, class_name);
+	Printf(s_oinit, "  %s_object_handlers = Swig_Php_base_object_handlers;\n", class_name);
+	Printf(s_oinit, "  %s_object_handlers.free_obj = SWIG_Php_free_obj_%s;\n", class_name, class_name);
+      }
+    } else {
+      static bool emitted_destructorless_create_object = false;
+      if (!emitted_destructorless_create_object) {
+	emitted_destructorless_create_object = true;
+	Printf(s_creation, "static zend_object *SWIG_Php_create_object(zend_class_entry *ce) {return SWIG_Php_do_create_object(ce, &Swig_Php_base_object_handlers);}\n", class_name);
+      }
+
+      Printf(s_oinit, "  SWIG_Php_ce_%s->create_object = SWIG_Php_create_object;\n", class_name);
+    }
+
+    // If not defined we aren't wrapping any functions which use this type as a
+    // parameter or return value, in which case we don't need the clientdata
+    // set.
+    Printf(s_oinit, "#ifdef SWIGTYPE_p%s\n", SwigType_manglestr(Getattr(n, "classtypeobj")));
+    Printf(s_oinit, "  SWIG_TypeClientData(SWIGTYPE_p%s,SWIG_Php_ce_%s);\n", SwigType_manglestr(Getattr(n, "classtypeobj")), class_name);
+    Printf(s_oinit, "#endif\n");
+    Printf(s_oinit, "\n");
+
+    generate_magic_property_methods(n);
+    Printf(all_cs_entry, " ZEND_FE_END\n};\n\n");
+
+    class_name = NULL;
+    base_class = NULL;
     return SWIG_OK;
   }
 
@@ -2285,6 +2048,27 @@
    * ------------------------------------------------------------ */
 
   virtual int membervariableHandler(Node *n) {
+    if (magic_set == NULL) {
+      magic_set = NewStringEmpty();
+      magic_get = NewStringEmpty();
+      magic_isset = NewStringEmpty();
+    }
+
+    String *v_name = GetChar(n, "name");
+
+    Printf(magic_set, "\nelse if (strcmp(ZSTR_VAL(arg2),\"%s\") == 0) {\n", v_name);
+    Printf(magic_set, "ZVAL_STRING(&tempZval, \"%s_set\");\n", v_name);
+    Printf(magic_set, "call_user_function(EG(function_table),ZEND_THIS,&tempZval,return_value,1,&args[1]);\n");
+    Printf(magic_set, "zval_ptr_dtor(&tempZval);\n}\n");
+
+    Printf(magic_get, "\nelse if (strcmp(ZSTR_VAL(arg2),\"%s\") == 0) {\n", v_name);
+    Printf(magic_get, "ZVAL_STRING(&tempZval, \"%s_get\");\n", v_name);
+    Printf(magic_get, "call_user_function(EG(function_table),ZEND_THIS,&tempZval,return_value,0,NULL);\n");
+    Printf(magic_get, "zval_ptr_dtor(&tempZval);\n}\n");
+
+    Printf(magic_isset, "\nelse if (strcmp(ZSTR_VAL(arg2),\"%s\") == 0) {\n", v_name);
+    Printf(magic_isset, "RETVAL_TRUE;\n}\n");
+
     wrapperType = membervar;
     Language::membervariableHandler(n);
     wrapperType = standard;
@@ -2325,9 +2109,7 @@
    * ------------------------------------------------------------ */
 
   virtual int constructorHandler(Node *n) {
-    constructors++;
     if (Swig_directorclass(n)) {
-      String *name = GetChar(Swig_methodclass(n), "name");
       String *ctype = GetChar(Swig_methodclass(n), "classtype");
       String *sname = GetChar(Swig_methodclass(n), "sym:name");
       String *args = NewStringEmpty();
@@ -2352,10 +2134,12 @@
       Delete(director_ctor_code);
       director_ctor_code = NewStringEmpty();
       director_prot_ctor_code = NewStringEmpty();
-      Printf(director_ctor_code, "if (Z_TYPE_P(arg0) == IS_NULL) { /* not subclassed */\n");
-      Printf(director_prot_ctor_code, "if (Z_TYPE_P(arg0) == IS_NULL) { /* not subclassed */\n");
-      Printf(director_ctor_code, "  %s = (%s *)new %s(%s);\n", Swig_cresult_name(), ctype, ctype, args);
-      Printf(director_prot_ctor_code, "  SWIG_PHP_Error(E_ERROR, \"accessing abstract class or protected constructor\");\n", name, name, args);
+      Printf(director_ctor_code, "if (Z_OBJCE_P(arg0) == SWIG_Php_ce_%s) { /* not subclassed */\n", class_name);
+      Printf(director_prot_ctor_code, "if (Z_OBJCE_P(arg0) == SWIG_Php_ce_%s) { /* not subclassed */\n", class_name);
+      Printf(director_ctor_code, "  %s = new %s(%s);\n", Swig_cresult_name(), ctype, args);
+      Printf(director_prot_ctor_code,
+	     "  zend_throw_exception(zend_ce_type_error, \"accessing abstract class or protected constructor\", 0);\n"
+	     "  return;\n");
       if (i) {
 	Insert(args, 0, ", ");
       }
@@ -2374,71 +2158,13 @@
   }
 
   /* ------------------------------------------------------------
-   * CreateZendListDestructor()
+   * destructorHandler()
    * ------------------------------------------------------------ */
-  //virtual int destructorHandler(Node *n) {
-  //}
-  int CreateZendListDestructor(Node *n) {
-    String *name = GetChar(Swig_methodclass(n), "name");
-    String *iname = GetChar(n, "sym:name");
-    ParmList *l = Getattr(n, "parms");
-
-    String *destructorname = NewStringEmpty();
-    Printf(destructorname, "_%s", Swig_name_wrapper(iname));
-    Setattr(classnode, "destructor", destructorname);
-
-    Wrapper *f = NewWrapper();
-    Printf(f->def, "/* This function is designed to be called by the zend list destructors */\n");
-    Printf(f->def, "/* to typecast and do the actual destruction */\n");
-    Printf(f->def, "static void %s(zend_resource *res, const char *type_name) {\n", destructorname);
-
-    Wrapper_add_localv(f, "value", "swig_object_wrapper *value=(swig_object_wrapper *) res->ptr", NIL);
-    Wrapper_add_localv(f, "ptr", "void *ptr=value->ptr", NIL);
-    Wrapper_add_localv(f, "newobject", "int newobject=value->newobject", NIL);
-
-    emit_parameter_variables(l, f);
-    emit_attach_parmmaps(l, f);
-
-    // Get type of first arg, thing to be destructed
-    // Skip ignored arguments
-    Parm *p = l;
-    //while (Getattr(p,"tmap:ignore")) {p = Getattr(p,"tmap:ignore:next");}
-    while (checkAttribute(p, "tmap:in:numinputs", "0")) {
-      p = Getattr(p, "tmap:in:next");
-    }
-    SwigType *pt = Getattr(p, "type");
-
-    Printf(f->code, "  efree(value);\n");
-    Printf(f->code, "  if (! newobject) return; /* can't delete it! */\n");
-    Printf(f->code, "  arg1 = (%s)SWIG_ConvertResourceData(ptr, type_name, SWIGTYPE%s);\n", SwigType_lstr(pt, 0), SwigType_manglestr(pt));
-    Printf(f->code, "  if (! arg1) zend_error(E_ERROR, \"%s resource already free'd\");\n", Char(name));
-
-    Setattr(n, "wrap:name", destructorname);
-
-    String *actioncode = emit_action(n);
-    Append(f->code, actioncode);
-    Delete(actioncode);
-
-    Printf(f->code, "thrown:\n");
-    Append(f->code, "return;\n");
-    Append(f->code, "fail:\n");
-    Append(f->code, "SWIG_FAIL();\n");
-    Printf(f->code, "}\n");
-
-    Wrapper_print(f, s_wrappers);
-    DelWrapper(f);
-
-    return SWIG_OK;
-  }
-
-  /* ------------------------------------------------------------
-   * memberconstantHandler()
-   * ------------------------------------------------------------ */
-
-  virtual int memberconstantHandler(Node *n) {
-    wrapping_member_constant = Getattr(n, "sym:name");
-    Language::memberconstantHandler(n);
-    wrapping_member_constant = NULL;
+  virtual int destructorHandler(Node *n) {
+    wrapperType = destructor;
+    Language::destructorHandler(n);
+    destructor_action = Getattr(n, "wrap:action");
+    wrapperType = standard;
     return SWIG_OK;
   }
 
@@ -2583,7 +2309,7 @@
     Append(w->def, " {");
     Append(declaration, ";\n");
 
-    /* declare method return value 
+    /* declare method return value
      * if the return value is a reference or const reference, a specialized typemap must
      * handle it, including declaration of c_result ($result).
      */
@@ -2612,12 +2338,10 @@
 	Delete(super_call);
       } else {
 	Printf(w->code, "Swig::DirectorPureVirtualException::raise(\"Attempted to invoke pure virtual method %s::%s\");\n", SwigType_namestr(c_classname),
-	    SwigType_namestr(name));
+	       SwigType_namestr(name));
       }
     } else {
       /* attach typemaps to arguments (C/C++ -> PHP) */
-      String *parse_args = NewStringEmpty();
-
       Swig_director_parms_fixup(l);
 
       /* remove the wrapper 'w' since it was producing spurious temps */
@@ -2627,10 +2351,6 @@
 
       Parm *p;
 
-      int outputs = 0;
-      if (!is_void)
-	outputs++;
-
       /* build argument list and type conversion string */
       idx = 0;
       p = l;
@@ -2640,9 +2360,6 @@
 	  continue;
 	}
 
-	if (Getattr(p, "tmap:directorargout") != 0)
-	  outputs++;
-
 	String *pname = Getattr(p, "name");
 	String *ptype = Getattr(p, "type");
 
@@ -2655,9 +2372,7 @@
 	    Delete(input);
 	    Replaceall(tm, "$owner", "0");
 	    Printv(wrap_args, tm, "\n", NIL);
-	    Putc('O', parse_args);
 	  } else {
-	    Append(parse_args, parse);
 	    Setattr(p, "emit:directorinput", pname);
 	    Replaceall(tm, "$input", pname);
 	    Replaceall(tm, "$owner", "0");
@@ -2676,25 +2391,6 @@
 	p = nextSibling(p);
       }
 
-      /* exception handling */
-      bool error_used_in_typemap = false;
-      tm = Swig_typemap_lookup("director:except", n, Swig_cresult_name(), 0);
-      if (!tm) {
-	tm = Getattr(n, "feature:director:except");
-	if (tm)
-	  tm = Copy(tm);
-      }
-      if ((tm) && Len(tm) && (Strcmp(tm, "1") != 0)) {
-	if (Replaceall(tm, "$error", "error")) {
-	  /* Only declare error if it is used by the typemap. */
-	  error_used_in_typemap = true;
-	  Append(w->code, "int error;\n");
-	}
-      } else {
-	Delete(tm);
-	tm = NULL;
-      }
-
       if (!idx) {
 	Printf(w->code, "zval *args = NULL;\n");
       } else {
@@ -2703,24 +2399,34 @@
       // typemap_directorout testcase requires that 0 can be assigned to the
       // variable named after the result of Swig_cresult_name(), so that can't
       // be a zval - make it a pointer to one instead.
-      Printf(w->code, "zval swig_zval_result, swig_funcname;\n", Swig_cresult_name());
+      Printf(w->code, "zval swig_zval_result;\n");
       Printf(w->code, "zval * SWIGUNUSED %s = &swig_zval_result;\n", Swig_cresult_name());
-      const char * funcname = GetChar(n, "sym:name");
-      Printf(w->code, "ZVAL_STRINGL(&swig_funcname, \"%s\", %d);\n", funcname, strlen(funcname));
 
       /* wrap complex arguments to zvals */
-      Printv(w->code, wrap_args, NIL);
+      Append(w->code, wrap_args);
 
-      if (error_used_in_typemap) {
-	Append(w->code, "error = ");
-      }
-      Append(w->code, "call_user_function(EG(function_table), &swig_self, &swig_funcname,");
-      Printf(w->code, " &swig_zval_result, %d, args);\n", idx);
+      const char *funcname = GetChar(n, "sym:name");
+      Append(w->code, "{\n");
+      Printf(w->code, "zend_string *swig_funcname = zend_string_init(\"%s\", %d, 0);\n", funcname, strlen(funcname));
+      Append(w->code, "zend_function *swig_zend_func = zend_std_get_method(&Z_OBJ(swig_self), swig_funcname, NULL);\n");
+      Append(w->code, "zend_string_release(swig_funcname);\n");
+      Printf(w->code, "if (swig_zend_func) zend_call_known_instance_method(swig_zend_func, Z_OBJ(swig_self), &swig_zval_result, %d, args);\n", idx);
 
-      if (tm) {
-	Printv(w->code, Str(tm), "\n", NIL);
-	Delete(tm);
+      /* exception handling */
+      tm = Swig_typemap_lookup("director:except", n, Swig_cresult_name(), 0);
+      if (!tm) {
+	tm = Getattr(n, "feature:director:except");
+	if (tm)
+	  tm = Copy(tm);
       }
+      if (!tm || Len(tm) == 0 || Equal(tm, "1")) {
+	// Skip marshalling the return value as there isn't one.
+	tm = NewString("if ($error) SWIG_fail;");
+      }
+
+      Replaceall(tm, "$error", "EG(exception)");
+      Printv(w->code, Str(tm), "\n}\n{\n", NIL);
+      Delete(tm);
 
       /* marshal return value from PHP to C/C++ type */
 
@@ -2749,8 +2455,8 @@
 	  Delete(tm);
 	} else {
 	  Swig_warning(WARN_TYPEMAP_DIRECTOROUT_UNDEF, input_file, line_number,
-	      "Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(returntype, 0), SwigType_namestr(c_classname),
-	      SwigType_namestr(name));
+		       "Unable to use return type %s in director method %s::%s (skipping method).\n", SwigType_str(returntype, 0),
+		       SwigType_namestr(c_classname), SwigType_namestr(name));
 	  status = SWIG_ERROR;
 	}
       }
@@ -2767,12 +2473,13 @@
 	}
       }
 
-      Delete(parse_args);
+      Append(w->code, "}\n");
+
       Delete(cleanup);
       Delete(outarg);
     }
 
-    Append(w->code, "thrown:\n");
+    Append(w->code, "fail: ;\n");
     if (!is_void) {
       if (!(ignored_method && !pure_virtual)) {
 	String *rettype = SwigType_str(returntype, 0);
@@ -2783,12 +2490,7 @@
 	}
 	Delete(rettype);
       }
-    } else {
-      Append(w->code, "return;\n");
     }
-
-    Append(w->code, "fail:\n");
-    Append(w->code, "SWIG_FAIL();\n");
     Append(w->code, "}\n");
 
     // We expose protected methods via an extra public inline method which makes a straight call to the wrapped class' method
@@ -2823,36 +2525,168 @@
     return status;
   }
 
-  int classDirectorDisown(Node *) {
-    return SWIG_OK;
+  int classDirectorDisown(Node *n) {
+    wrapperType = directordisown;
+    int result = Language::classDirectorDisown(n);
+    wrapperType = standard;
+    return result;
   }
 };				/* class PHP */
 
 static PHP *maininstance = 0;
 
-// We use this function to be able to write out zend_register_list_destructor_ex
-// lines for most things in the type table
+List *PHPTypes::process_phptype(Node *n, int key, const String_or_char *attribute_name) {
+
+  while (Len(merged_types) <= key) {
+    Append(merged_types, NewList());
+  }
+
+  String *phptype = Getattr(n, attribute_name);
+  if (!phptype || Len(phptype) == 0) {
+    // There's no type declaration, so any merged version has no type declaration.
+    //
+    // Use a DOH None object as a marker to indicate there's no type
+    // declaration for this parameter/return value (you can't store NULL as a
+    // value in a DOH List).
+    Setitem(merged_types, key, None);
+    return NULL;
+  }
+
+  DOH *merge_list = Getitem(merged_types, key);
+  if (merge_list == None) return NULL;
+
+  List *types = Split(phptype, '|', -1);
+  String *first_type = Getitem(types, 0);
+  if (Char(first_type)[0] == '?') {
+    if (Len(types) > 1) {
+      Printf(stderr, "warning: Invalid phptype: '%s' (can't use ? and | together)\n", phptype);
+    }
+    // Treat `?foo` just like `foo|null`.
+    Append(types, "null");
+    Setitem(types, 0, NewString(Char(first_type) + 1));
+  }
+
+  SortList(types, NULL);
+  String *prev = NULL;
+  for (Iterator i = First(types); i.item; i = Next(i)) {
+    if (prev && Equal(prev, i.item)) {
+      Printf(stderr, "warning: Invalid phptype: '%s' (duplicate entry for '%s')\n", phptype, i.item);
+      continue;
+    }
+
+    if (key > 0 && Equal(i.item, "void")) {
+      // Reject void for parameter type.
+      Printf(stderr, "warning: Invalid phptype: '%s' ('%s' can't be used as a parameter phptype)\n", phptype, i.item);
+      continue;
+    }
+
+    if (Equal(i.item, "SWIGTYPE")) {
+      String *type = Getattr(n, "type");
+      Node *class_node = maininstance->classLookup(type);
+      if (class_node) {
+	// FIXME: Prefix classname with a backslash to prevent collisions
+	// with built-in types?  Or are non of those valid anyway and so will
+	// have been renamed at this point?
+	Append(merge_list, Getattr(class_node, "sym:name"));
+      } else {
+	// SWIG wraps a pointer to a non-object type as an object in a PHP
+	// class named based on the SWIG-mangled C/C++ type.
+	//
+	// FIXME: We should check this is actually a known pointer to
+	// non-object type so we complain about `phptype="SWIGTYPE"` being
+	// used for PHP types like `int` or `string` (currently this only
+	// fails at runtime and the error isn't very helpful).  We could
+	// check the condition
+	//
+	//   raw_pointer_types && Getattr(raw_pointer_types, SwigType_manglestr(type))
+	//
+	// except that raw_pointer_types may not have been fully filled in when
+	// we are called.
+	Append(merge_list, NewStringf("SWIG\\%s", SwigType_manglestr(type)));
+      }
+    } else {
+      Append(merge_list, i.item);
+    }
+    prev = i.item;
+  }
+  SortList(merge_list, NULL);
+  return merge_list;
+}
+
+void PHPTypes::merge_type_lists(List *merge_list, List *o_merge_list) {
+  int i = 0, j = 0;
+  while (j < Len(o_merge_list)) {
+    String *candidate = Getitem(o_merge_list, j);
+    while (i < Len(merge_list)) {
+      int cmp = Cmp(Getitem(merge_list, i), candidate);
+      if (cmp == 0)
+	goto handled;
+      if (cmp > 0)
+	break;
+      ++i;
+    }
+    Insert(merge_list, i, candidate);
+    ++i;
+handled:
+    ++j;
+  }
+}
+
+void PHPTypes::merge_from(const PHPTypes* o) {
+  num_required = std::min(num_required, o->num_required);
+
+  if (o->byref) {
+    if (byref == NULL) {
+      byref = Copy(o->byref);
+    } else {
+      int len = std::min(Len(byref), Len(o->byref));
+      // Start at 1 because we only want to merge parameter types, and key 0 is
+      // the return type.
+      for (int key = 1; key < len; ++key) {
+	if (Getitem(byref, key) == None &&
+	    Getitem(o->byref, key) != None) {
+	  Setitem(byref, key, "");
+	}
+      }
+      for (int key = len; key < Len(o->byref); ++key) {
+	Append(byref, Getitem(o->byref, key));
+      }
+    }
+  }
+
+  int len = std::min(Len(merged_types), Len(o->merged_types));
+  for (int key = 0; key < len; ++key) {
+    DOH *merge_list = Getitem(merged_types, key);
+    // None trumps anything else in the merge.
+    if (merge_list == None) continue;
+    DOH *o_merge_list = Getitem(o->merged_types, key);
+    if (o_merge_list == None) {
+      Setitem(merged_types, key, None);
+      continue;
+    }
+    merge_type_lists(merge_list, o_merge_list);
+  }
+  // Copy over any additional entries.
+  for (int key = len; key < Len(o->merged_types); ++key) {
+    Append(merged_types, Copy(Getitem(o->merged_types, key)));
+  }
+}
+
+// Collect non-class pointer types from the type table so we can set up PHP
+// classes for them later.
+//
 // NOTE: it's a function NOT A PHP::METHOD
 extern "C" {
 static void typetrace(const SwigType *ty, String *mangled, String *clientdata) {
-  Node *class_node;
-  if (!zend_types) {
-    zend_types = NewHash();
-  }
-  // we want to know if the type which reduced to this has a constructor
-  if ((class_node = maininstance->classLookup(ty))) {
-    if (!Getattr(zend_types, mangled)) {
-      // OK it may have been set before by a different SwigType but it would
-      // have had the same underlying class node I think
-      // - it is certainly required not to have different originating class
-      // nodes for the same SwigType
-      Setattr(zend_types, mangled, class_node);
+  if (maininstance->classLookup(ty) == NULL) {
+    // a non-class pointer
+    if (!raw_pointer_types) {
+      raw_pointer_types = NewHash();
     }
-  } else {			// a non-class pointer
-    Setattr(zend_types, mangled, NOTCLASS);
+    Setattr(raw_pointer_types, mangled, mangled);
   }
   if (r_prevtracefunc)
-    (*r_prevtracefunc) (ty, mangled, (String *) clientdata);
+    (*r_prevtracefunc) (ty, mangled, clientdata);
 }
 }
 
diff --git a/Source/Modules/pike.cxx b/Source/Modules/pike.cxx
deleted file mode 100644
index b8ed403..0000000
--- a/Source/Modules/pike.cxx
+++ /dev/null
@@ -1,904 +0,0 @@
-/* ----------------------------------------------------------------------------- 
- * This file is part of SWIG, which is licensed as a whole under version 3 
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
- *
- * pike.cxx
- *
- * Pike language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-/*
- * Notes:
- *
- * - The current approach used for "out" typemaps is inconsistent with
- *   how "out" typemaps are handled by other language modules. Instead
- *   of converting the C/C++ type ($1) to a Pike object type (e.g. a
- *   struct svalue), we're just calling the appropriate push_XXX
- *   (e.g. push_int) to push the return value onto the stack.
- *
- * - Pike classes can't have static member functions or data, so we need
- *   to find some other appropriate mapping for C++ static member functions
- *   and data.
- *
- * - Pike doesn't seem to provide any default way to print the memory
- *   address, etc. for extension objects. Should we do something here?
- *
- */
-
-#include "swigmod.h"
-
-#include <ctype.h>		// for isalnum()
-
-static const char *usage = "\
-Pike Options (available with -pike)\n\
-     [no additional options]\n\
-\n";
-
-class PIKE:public Language {
-private:
-
-  File *f_begin;
-  File *f_runtime;
-  File *f_header;
-  File *f_wrappers;
-  File *f_init;
-  File *f_classInit;
-
-  String *PrefixPlusUnderscore;
-  int current;
-
-  // Wrap modes
-  enum {
-    NO_CPP,
-    MEMBER_FUNC,
-    CONSTRUCTOR,
-    DESTRUCTOR,
-    MEMBER_VAR,
-    CLASS_CONST,
-    STATIC_FUNC,
-    STATIC_VAR
-  };
-
-public:
-
-  /* ---------------------------------------------------------------------
-   * PIKE()
-   *
-   * Initialize member data
-   * --------------------------------------------------------------------- */
-
-   PIKE() {
-    f_begin = 0;
-    f_runtime = 0;
-    f_header = 0;
-    f_wrappers = 0;
-    f_init = 0;
-    f_classInit = 0;
-    PrefixPlusUnderscore = 0;
-    current = NO_CPP;
-  }
-
-  /* ---------------------------------------------------------------------
-   * main()
-   *
-   * Parse command line options and initializes variables.
-   * --------------------------------------------------------------------- */
-  
-   virtual void main(int argc, char *argv[]) {
-
-    /* Set location of SWIG library */
-    SWIG_library_directory("pike");
-
-    /* Look for certain command line options */
-    for (int i = 1; i < argc; i++) {
-      if (argv[i]) {
-	if (strcmp(argv[i], "-help") == 0) {
-	  fputs(usage, stdout);
-	}
-      }
-    }
-
-    /* Add a symbol to the parser for conditional compilation */
-    Preprocessor_define("SWIGPIKE 1", 0);
-
-    /* Set language-specific configuration file */
-    SWIG_config_file("pike.swg");
-
-    /* Set typemap language */
-    SWIG_typemap_lang("pike");
-
-    /* Enable overloaded methods support */
-    allow_overloading();
-  }
-
-  /* ---------------------------------------------------------------------
-   * top()
-   * --------------------------------------------------------------------- */
-
-  virtual int top(Node *n) {
-    /* Get the module name */
-    String *module = Getattr(n, "name");
-
-    /* Get the output file name */
-    String *outfile = Getattr(n, "outfile");
-
-    /* Open the output file */
-    f_begin = NewFile(outfile, "w", SWIG_output_files());
-    if (!f_begin) {
-      FileErrorDisplay(outfile);
-      SWIG_exit(EXIT_FAILURE);
-    }
-    f_runtime = NewString("");
-    f_init = NewString("");
-    f_classInit = NewString("");
-    f_header = NewString("");
-    f_wrappers = NewString("");
-
-    /* Register file targets with the SWIG file handler */
-    Swig_register_filebyname("header", f_header);
-    Swig_register_filebyname("wrapper", f_wrappers);
-    Swig_register_filebyname("begin", f_begin);
-    Swig_register_filebyname("runtime", f_runtime);
-    Swig_register_filebyname("init", f_init);
-    Swig_register_filebyname("classInit", f_classInit);
-
-    /* Standard stuff for the SWIG runtime section */
-    Swig_banner(f_begin);
-
-    Printf(f_runtime, "\n\n#ifndef SWIGPIKE\n#define SWIGPIKE\n#endif\n\n");
-
-    Printf(f_header, "#define SWIG_init    pike_module_init\n");
-    Printf(f_header, "#define SWIG_name    \"%s\"\n\n", module);
-
-    /* Change naming scheme for constructors and destructors */
-    Swig_name_register("construct", "%n%c_create");
-    Swig_name_register("destroy", "%n%c_destroy");
-
-    /* Current wrap type */
-    current = NO_CPP;
-
-    /* Emit code for children */
-    Language::top(n);
-
-    /* Close the initialization function */
-    Printf(f_init, "}\n");
-    SwigType_emit_type_table(f_runtime, f_wrappers);
-
-    /* Close all of the files */
-    Dump(f_runtime, f_begin);
-    Dump(f_header, f_begin);
-    Dump(f_wrappers, f_begin);
-    Wrapper_pretty_print(f_init, f_begin);
-
-    Delete(f_header);
-    Delete(f_wrappers);
-    Delete(f_init);
-    Delete(f_classInit);
-    Delete(f_runtime);
-    Delete(f_begin);
-
-    /* Done */
-    return SWIG_OK;
-  }
-
-  /* ------------------------------------------------------------
-   * validIdentifier()
-   * ------------------------------------------------------------ */
-
-  virtual int validIdentifier(String *s) {
-    char *c = Char(s);
-    const char *c0 = c;
-    const char *c1 = c0 + 1;
-    while (*c) {
-      if (*c == '`' && c == c0) {
-	c++;
-	continue;
-      }
-      if ((*c == '+' || *c == '-' || *c == '*' || *c == '/') && c == c1) {
-	c++;
-	continue;
-      }
-      if (!(isalnum(*c) || (*c == '_')))
-	return 0;
-      c++;
-    }
-    return 1;
-  }
-
-  /* ------------------------------------------------------------
-   * importDirective()
-   * ------------------------------------------------------------ */
-
-  virtual int importDirective(Node *n) {
-    String *modname = Getattr(n, "module");
-    if (modname) {
-      Printf(f_init, "pike_require(\"%s\");\n", modname);
-    }
-    return Language::importDirective(n);
-  }
-
-  /* ------------------------------------------------------------
-   * strip()
-   *
-   * For names that begin with the current class prefix plus an
-   * underscore (e.g. "Foo_enum_test"), return the base function
-   * name (i.e. "enum_test").
-   * ------------------------------------------------------------ */
-
-  String *strip(const DOHconst_String_or_char_ptr name) {
-    String *s = Copy(name);
-    if (Strncmp(name, PrefixPlusUnderscore, Len(PrefixPlusUnderscore)) != 0) {
-      return s;
-    }
-    Replaceall(s, PrefixPlusUnderscore, "");
-    return s;
-  }
-
-  /* ------------------------------------------------------------
-   * add_method()
-   * ------------------------------------------------------------ */
-
-  void add_method(const DOHconst_String_or_char_ptr name, const DOHconst_String_or_char_ptr function, const DOHconst_String_or_char_ptr description) {
-    String *rename = NULL;
-    switch (current) {
-    case NO_CPP:
-      rename = NewString(name);
-      Printf(f_init, "ADD_FUNCTION(\"%s\", %s, tFunc(%s), 0);\n", rename, function, description);
-      break;
-    case STATIC_FUNC:
-    case STATIC_VAR:
-      rename = NewString(name);
-      Printf(f_init, "ADD_FUNCTION(\"%s\", %s, tFunc(%s), 0);\n", rename, function, description);
-      break;
-    case CONSTRUCTOR:
-    case DESTRUCTOR:
-    case MEMBER_FUNC:
-    case MEMBER_VAR:
-      rename = strip(name);
-      Printf(f_classInit, "ADD_FUNCTION(\"%s\", %s, tFunc(%s), 0);\n", rename, function, description);
-      break;
-    case CLASS_CONST: // shouldn't have gotten here for CLASS_CONST nodes
-    default: // what is this?
-      assert(false);
-    }
-    Delete(rename);
-  }
-
-  /* ---------------------------------------------------------------------
-   * functionWrapper()
-   *
-   * Create a function declaration and register it with the interpreter.
-   * --------------------------------------------------------------------- */
-
-  virtual int functionWrapper(Node *n) {
-
-    String *name = Getattr(n, "name");
-    String *iname = Getattr(n, "sym:name");
-    SwigType *d = Getattr(n, "type");
-    ParmList *l = Getattr(n, "parms");
-
-    Parm *p;
-    String *tm;
-    int i;
-
-    String *overname = 0;
-    if (Getattr(n, "sym:overloaded")) {
-      overname = Getattr(n, "sym:overname");
-    } else {
-      if (!addSymbol(iname, n))
-	return SWIG_ERROR;
-    }
-
-    Wrapper *f = NewWrapper();
-
-    // Emit all of the local variables for holding arguments.
-    emit_parameter_variables(l, f);
-
-    /* Attach the standard typemaps */
-    emit_attach_parmmaps(l, f);
-    Setattr(n, "wrap:parms", l);
-
-    /* Get number of required and total arguments */
-    int num_arguments = emit_num_arguments(l);
-    int varargs = emit_isvarargs(l);
-
-    /* Which input argument to start with? */
-    int start = (current == MEMBER_FUNC || current == MEMBER_VAR || current == DESTRUCTOR) ? 1 : 0;
-
-    /* Offset to skip over the attribute name */
-    // int offset = (current == MEMBER_VAR) ? 1 : 0;
-    int offset = 0;
-
-    String *wname = Swig_name_wrapper(iname);
-    if (overname) {
-      Append(wname, overname);
-    }
-    Setattr(n, "wrap:name", wname);
-
-    Printv(f->def, "static void ", wname, "(INT32 args) {", NIL);
-
-    /* Generate code for argument marshalling */
-    String *description = NewString("");
-    char source[64];
-    for (i = 0, p = l; i < num_arguments; i++) {
-
-      while (checkAttribute(p, "tmap:in:numinputs", "0")) {
-	p = Getattr(p, "tmap:in:next");
-      }
-
-      SwigType *pt = Getattr(p, "type");
-      String *ln = Getattr(p, "lname");
-
-      if (i < start) {
-	String *lstr = SwigType_lstr(pt, 0);
-	Printf(f->code, "%s = (%s) THIS;\n", ln, lstr);
-	Delete(lstr);
-      } else {
-	/* Look for an input typemap */
-	sprintf(source, "Pike_sp[%d-args]", i - start + offset);
-	if ((tm = Getattr(p, "tmap:in"))) {
-	  Replaceall(tm, "$source", source);
-	  Replaceall(tm, "$target", ln);
-	  Replaceall(tm, "$input", source);
-	  Setattr(p, "emit:input", source);
-	  Printf(f->code, "%s\n", tm);
-	  String *pikedesc = Getattr(p, "tmap:in:pikedesc");
-	  if (pikedesc) {
-	    Printv(description, pikedesc, " ", NIL);
-	  }
-	  p = Getattr(p, "tmap:in:next");
-	  continue;
-	} else {
-	  Swig_warning(WARN_TYPEMAP_IN_UNDEF, input_file, line_number, "Unable to use type %s as a function argument.\n", SwigType_str(pt, 0));
-	  break;
-	}
-      }
-      p = nextSibling(p);
-    }
-
-    /* Check for trailing varargs */
-    if (varargs) {
-      if (p && (tm = Getattr(p, "tmap:in"))) {
-	Replaceall(tm, "$input", "varargs");
-	Printv(f->code, tm, "\n", NIL);
-      }
-    }
-
-    /* Insert constraint checking code */
-    for (p = l; p;) {
-      if ((tm = Getattr(p, "tmap:check"))) {
-	Replaceall(tm, "$target", Getattr(p, "lname"));
-	Printv(f->code, tm, "\n", NIL);
-	p = Getattr(p, "tmap:check:next");
-      } else {
-	p = nextSibling(p);
-      }
-    }
-
-    /* Insert cleanup code */
-    String *cleanup = NewString("");
-    for (p = l; p;) {
-      if ((tm = Getattr(p, "tmap:freearg"))) {
-	Replaceall(tm, "$source", Getattr(p, "lname"));
-	Printv(cleanup, tm, "\n", NIL);
-	p = Getattr(p, "tmap:freearg:next");
-      } else {
-	p = nextSibling(p);
-      }
-    }
-
-    /* Insert argument output code */
-    String *outarg = NewString("");
-    for (p = l; p;) {
-      if ((tm = Getattr(p, "tmap:argout"))) {
-	Replaceall(tm, "$source", Getattr(p, "lname"));
-	Replaceall(tm, "$target", "resultobj");
-	Replaceall(tm, "$arg", Getattr(p, "emit:input"));
-	Replaceall(tm, "$input", Getattr(p, "emit:input"));
-	Printv(outarg, tm, "\n", NIL);
-	p = Getattr(p, "tmap:argout:next");
-      } else {
-	p = nextSibling(p);
-      }
-    }
-
-    /* Emit the function call */
-    String *actioncode = emit_action(n);
-
-    /* Clear the return stack */
-    Printf(actioncode, "pop_n_elems(args);\n");
-
-    /* Return the function value */
-    if (current == CONSTRUCTOR) {
-      Printv(actioncode, "THIS = (void *) ", Swig_cresult_name(), ";\n", NIL);
-      Printv(description, ", tVoid", NIL);
-    } else if (current == DESTRUCTOR) {
-      Printv(description, ", tVoid", NIL);
-    } else {
-      Printv(description, ", ", NIL);
-      if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
-        actioncode = 0;
-	Replaceall(tm, "$source", Swig_cresult_name());
-	Replaceall(tm, "$target", "resultobj");
-	Replaceall(tm, "$result", "resultobj");
-	if (GetFlag(n, "feature:new")) {
-	  Replaceall(tm, "$owner", "1");
-	} else {
-	  Replaceall(tm, "$owner", "0");
-	}
-	String *pikedesc = Getattr(n, "tmap:out:pikedesc");
-	if (pikedesc) {
-	  Printv(description, pikedesc, NIL);
-	}
-	Printf(f->code, "%s\n", tm);
-      } else {
-	Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
-      }
-    }
-    if (actioncode) {
-      Append(f->code, actioncode);
-      Delete(actioncode);
-    }
-    emit_return_variable(n, d, f);
-
-    /* Output argument output code */
-    Printv(f->code, outarg, NIL);
-
-    /* Output cleanup code */
-    Printv(f->code, cleanup, NIL);
-
-    /* Look to see if there is any newfree cleanup code */
-    if (GetFlag(n, "feature:new")) {
-      if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
-	Replaceall(tm, "$source", Swig_cresult_name());
-	Printf(f->code, "%s\n", tm);
-      }
-    }
-
-    /* See if there is any return cleanup code */
-    if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
-      Replaceall(tm, "$source", Swig_cresult_name());
-      Printf(f->code, "%s\n", tm);
-    }
-
-    /* Close the function */
-    Printf(f->code, "}\n");
-
-    /* Substitute the cleanup code */
-    Replaceall(f->code, "$cleanup", cleanup);
-
-    /* Substitute the function name */
-    Replaceall(f->code, "$symname", iname);
-    Replaceall(f->code, "$result", "resultobj");
-
-    /* Dump the function out */
-    Wrapper_print(f, f_wrappers);
-
-    /* Now register the function with the interpreter. */
-    if (!Getattr(n, "sym:overloaded")) {
-      add_method(iname, wname, description);
-    } else {
-      if (!Getattr(n, "sym:nextSibling")) {
-	dispatchFunction(n);
-      }
-    }
-
-    Delete(cleanup);
-    Delete(outarg);
-    Delete(description);
-    Delete(wname);
-    DelWrapper(f);
-
-    return SWIG_OK;
-  }
-
-  /* ------------------------------------------------------------
-   * dispatchFunction()
-   *
-   * Emit overloading dispatch function
-   * ------------------------------------------------------------ */
-
-  void dispatchFunction(Node *n) {
-    /* Last node in overloaded chain */
-
-    int maxargs;
-    String *tmp = NewString("");
-    String *dispatch = Swig_overload_dispatch(n, "%s(args); return;", &maxargs);
-
-    /* Generate a dispatch wrapper for all overloaded functions */
-
-    Wrapper *f = NewWrapper();
-    String *symname = Getattr(n, "sym:name");
-    String *wname = Swig_name_wrapper(symname);
-
-    Printf(f->def, "static void %s(INT32 args) {", wname);
-
-    Wrapper_add_local(f, "argc", "INT32 argc");
-    Printf(tmp, "struct svalue argv[%d]", maxargs);
-    Wrapper_add_local(f, "argv", tmp);
-    Wrapper_add_local(f, "ii", "INT32 ii");
-
-    Printf(f->code, "argc = args;\n");
-    Printf(f->code, "for (ii = 0; (ii < argc) && (ii < %d); ii++) {\n", maxargs);
-    Printf(f->code, "argv[ii] = Pike_sp[ii-args];\n");
-    Printf(f->code, "}\n");
-
-    Replaceall(dispatch, "$args", "self, args");
-    Printv(f->code, dispatch, "\n", NIL);
-    Printf(f->code, "Pike_error(\"No matching function for overloaded '%s'.\");\n", symname);
-    Printv(f->code, "}\n", NIL);
-
-    Wrapper_print(f, f_wrappers);
-
-    String *description = NewString("");
-    Printf(description, "tAny,");
-    if (current == CONSTRUCTOR || current == DESTRUCTOR) {
-      Printf(description, " tVoid");
-    } else {
-      String *pd = Getattr(n, "tmap:out:pikedesc");
-      if (pd)
-	Printf(description, " %s", pd);
-    }
-    add_method(symname, wname, description);
-    Delete(description);
-
-    DelWrapper(f);
-    Delete(dispatch);
-    Delete(tmp);
-    Delete(wname);
-  }
-
-  /* ------------------------------------------------------------
-   * variableWrapper()
-   * ------------------------------------------------------------ */
-
-  virtual int variableWrapper(Node *n) {
-    return Language::variableWrapper(n);
-  }
-
-  /* ------------------------------------------------------------
-   * constantWrapper()
-   * ------------------------------------------------------------ */
-
-  virtual int constantWrapper(Node *n) {
-
-    Swig_require("constantWrapper", n, "*sym:name", "type", "value", NIL);
-
-    String *symname = Getattr(n, "sym:name");
-    SwigType *type = Getattr(n, "type");
-    String *value = Getattr(n, "value");
-    bool is_enum_item = (Cmp(nodeType(n), "enumitem") == 0);
-
-    if (SwigType_type(type) == T_MPOINTER) {
-      /* Special hook for member pointer */
-      String *wname = Swig_name_wrapper(symname);
-      Printf(f_header, "static %s = %s;\n", SwigType_str(type, wname), value);
-      value = wname;
-    } else if (SwigType_type(type) == T_CHAR && is_enum_item) {
-      type = NewSwigType(T_INT);
-      Setattr(n, "type", type);
-    }
-
-    /* Perform constant typemap substitution */
-    String *tm = Swig_typemap_lookup("constant", n, value, 0);
-    if (tm) {
-      Replaceall(tm, "$source", value);
-      Replaceall(tm, "$target", symname);
-      Replaceall(tm, "$symname", symname);
-      Replaceall(tm, "$value", value);
-      Printf(f_init, "%s\n", tm);
-    } else {
-      Swig_warning(WARN_TYPEMAP_CONST_UNDEF, input_file, line_number, "Unsupported constant value %s = %s\n", SwigType_str(type, 0), value);
-    }
-
-    Swig_restore(n);
-
-    return SWIG_OK;
-  }
-
-  /* ------------------------------------------------------------ 
-   * nativeWrapper()
-   * ------------------------------------------------------------ */
-
-  virtual int nativeWrapper(Node *n) {
-    //   return Language::nativeWrapper(n);
-    String *name = Getattr(n, "sym:name");
-    String *wrapname = Getattr(n, "wrap:name");
-
-    if (!addSymbol(wrapname, n))
-      return SWIG_ERROR;
-
-    add_method(name, wrapname, 0);
-    return SWIG_OK;
-  }
-
-  /* ------------------------------------------------------------
-   * enumDeclaration()
-   * ------------------------------------------------------------ */
-
-  virtual int enumDeclaration(Node *n) {
-    return Language::enumDeclaration(n);
-  }
-
-  /* ------------------------------------------------------------
-   * enumvalueDeclaration()
-   * ------------------------------------------------------------ */
-
-  virtual int enumvalueDeclaration(Node *n) {
-    return Language::enumvalueDeclaration(n);
-  }
-
-  /* ------------------------------------------------------------
-   * classDeclaration()
-   * ------------------------------------------------------------ */
-
-  virtual int classDeclaration(Node *n) {
-    return Language::classDeclaration(n);
-  }
-
-  /* ------------------------------------------------------------
-   * classHandler()
-   * ------------------------------------------------------------ */
-
-  virtual int classHandler(Node *n) {
-
-    String *symname = Getattr(n, "sym:name");
-    if (!addSymbol(symname, n))
-      return SWIG_ERROR;
-
-    PrefixPlusUnderscore = NewStringf("%s_", getClassPrefix());
-
-    Printf(f_classInit, "start_new_program();\n");
-
-    /* Handle inheritance */
-    List *baselist = Getattr(n, "bases");
-    if (baselist && Len(baselist) > 0) {
-      Iterator base = First(baselist);
-      while (base.item) {
-	String *basename = Getattr(base.item, "name");
-	SwigType *basetype = NewString(basename);
-	SwigType_add_pointer(basetype);
-	SwigType_remember(basetype);
-	String *basemangle = SwigType_manglestr(basetype);
-	Printf(f_classInit, "low_inherit((struct program *) SWIGTYPE%s->clientdata, 0, 0, 0, 0, 0);\n", basemangle);
-	Delete(basemangle);
-	Delete(basetype);
-	base = Next(base);
-      }
-    } else {
-      Printf(f_classInit, "ADD_STORAGE(swig_object_wrapper);\n");
-    }
-
-    Language::classHandler(n);
-
-    /* Accessors for member variables */
-    /*
-       List *membervariables = Getattr(n,"membervariables");
-       if (membervariables && Len(membervariables) > 0) {
-       membervariableAccessors(membervariables);
-       }
-     */
-
-    /* Done, close the class and dump its definition to the init function */
-    Printf(f_classInit, "add_program_constant(\"%s\", pr = end_program(), 0);\n", symname);
-    Dump(f_classInit, f_init);
-    Clear(f_classInit);
-
-    SwigType *tt = NewString(symname);
-    SwigType_add_pointer(tt);
-    SwigType_remember(tt);
-    String *tm = SwigType_manglestr(tt);
-    Printf(f_init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) pr);\n", tm);
-    Delete(tm);
-    Delete(tt);
-
-    Delete(PrefixPlusUnderscore);
-    PrefixPlusUnderscore = 0;
-
-    return SWIG_OK;
-  }
-
-  /* ------------------------------------------------------------
-   * memberfunctionHandler()
-   *
-   * Method for adding C++ member function
-   * ------------------------------------------------------------ */
-
-  virtual int memberfunctionHandler(Node *n) {
-    current = MEMBER_FUNC;
-    Language::memberfunctionHandler(n);
-    current = NO_CPP;
-    return SWIG_OK;
-  }
-
-  /* ------------------------------------------------------------
-   * constructorHandler()
-   *
-   * Method for adding C++ member constructor
-   * ------------------------------------------------------------ */
-
-  virtual int constructorHandler(Node *n) {
-    current = CONSTRUCTOR;
-    Language::constructorHandler(n);
-    current = NO_CPP;
-    return SWIG_OK;
-  }
-
-  /* ------------------------------------------------------------
-   * destructorHandler()
-   * ------------------------------------------------------------ */
-
-  virtual int destructorHandler(Node *n) {
-    current = DESTRUCTOR;
-    Language::destructorHandler(n);
-    current = NO_CPP;
-    return SWIG_OK;
-  }
-
-  /* ------------------------------------------------------------
-   * membervariableAccessors()
-   * ------------------------------------------------------------ */
-
-  void membervariableAccessors(List *membervariables) {
-    String *name;
-    Iterator i;
-    bool need_setter;
-    String *funcname;
-
-    /* If at least one of them is mutable, we need a setter */
-    need_setter = false;
-    i = First(membervariables);
-    while (i.item) {
-      if (!GetFlag(i.item, "feature:immutable")) {
-	need_setter = true;
-	break;
-      }
-      i = Next(i);
-    }
-
-    /* Create a function to set the values of the (mutable) variables */
-    if (need_setter) {
-      Wrapper *wrapper = NewWrapper();
-      String *setter = Swig_name_member(NSPACE_TODO, getClassPrefix(), "`->=");
-      String *wname = Swig_name_wrapper(setter);
-      Printv(wrapper->def, "static void ", wname, "(INT32 args) {", NIL);
-      Printf(wrapper->locals, "char *name = (char *) STR0(Pike_sp[0-args].u.string);\n");
-
-      i = First(membervariables);
-      while (i.item) {
-	if (!GetFlag(i.item, "feature:immutable")) {
-	  name = Getattr(i.item, "name");
-	  funcname = Swig_name_wrapper(Swig_name_set(NSPACE_TODO, Swig_name_member(NSPACE_TODO, getClassPrefix(), name)));
-	  Printf(wrapper->code, "if (!strcmp(name, \"%s\")) {\n", name);
-	  Printf(wrapper->code, "%s(args);\n", funcname);
-	  Printf(wrapper->code, "return;\n");
-	  Printf(wrapper->code, "}\n");
-	  Delete(funcname);
-	}
-	i = Next(i);
-      }
-
-      /* Close the function */
-      Printf(wrapper->code, "pop_n_elems(args);\n");
-      Printf(wrapper->code, "}\n");
-
-      /* Dump wrapper code to the output file */
-      Wrapper_print(wrapper, f_wrappers);
-
-      /* Register it with Pike */
-      String *description = NewString("tStr tFloat, tVoid");
-      add_method("`->=", wname, description);
-      Delete(description);
-
-      /* Clean up */
-      Delete(wname);
-      Delete(setter);
-      DelWrapper(wrapper);
-    }
-
-    /* Create a function to get the values of the (mutable) variables */
-    Wrapper *wrapper = NewWrapper();
-    String *getter = Swig_name_member(NSPACE_TODO, getClassPrefix(), "`->");
-    String *wname = Swig_name_wrapper(getter);
-    Printv(wrapper->def, "static void ", wname, "(INT32 args) {", NIL);
-    Printf(wrapper->locals, "char *name = (char *) STR0(Pike_sp[0-args].u.string);\n");
-
-    i = First(membervariables);
-    while (i.item) {
-      name = Getattr(i.item, "name");
-      funcname = Swig_name_wrapper(Swig_name_get(NSPACE_TODO, Swig_name_member(NSPACE_TODO, getClassPrefix(), name)));
-      Printf(wrapper->code, "if (!strcmp(name, \"%s\")) {\n", name);
-      Printf(wrapper->code, "%s(args);\n", funcname);
-      Printf(wrapper->code, "return;\n");
-      Printf(wrapper->code, "}\n");
-      Delete(funcname);
-      i = Next(i);
-    }
-
-    /* Close the function */
-    Printf(wrapper->code, "pop_n_elems(args);\n");
-    Printf(wrapper->code, "}\n");
-
-    /* Dump wrapper code to the output file */
-    Wrapper_print(wrapper, f_wrappers);
-
-    /* Register it with Pike */
-    String *description = NewString("tStr, tMix");
-    add_method("`->", wname, description);
-    Delete(description);
-
-    /* Clean up */
-    Delete(wname);
-    Delete(getter);
-    DelWrapper(wrapper);
-  }
-
-  /* ------------------------------------------------------------
-   * membervariableHandler()
-   * ------------------------------------------------------------ */
-
-  virtual int membervariableHandler(Node *n) {
-    List *membervariables = Getattr(getCurrentClass(), "membervariables");
-    if (!membervariables) {
-      membervariables = NewList();
-      Setattr(getCurrentClass(), "membervariables", membervariables);
-    }
-    Append(membervariables, n);
-    current = MEMBER_VAR;
-    Language::membervariableHandler(n);
-    current = NO_CPP;
-    return SWIG_OK;
-  }
-
-  /* -----------------------------------------------------------------------
-   * staticmemberfunctionHandler()
-   *
-   * Wrap a static C++ function
-   * ---------------------------------------------------------------------- */
-
-  virtual int staticmemberfunctionHandler(Node *n) {
-    current = STATIC_FUNC;
-    Language::staticmemberfunctionHandler(n);
-    current = NO_CPP;
-    return SWIG_OK;
-  }
-
-  /* ------------------------------------------------------------
-   * memberconstantHandler()
-   *
-   * Create a C++ constant
-   * ------------------------------------------------------------ */
-
-  virtual int memberconstantHandler(Node *n) {
-    current = CLASS_CONST;
-    constantWrapper(n);
-    current = NO_CPP;
-    return SWIG_OK;
-  }
-
-  /* ---------------------------------------------------------------------
-   * staticmembervariableHandler()
-   * --------------------------------------------------------------------- */
-
-  virtual int staticmembervariableHandler(Node *n) {
-    current = STATIC_VAR;
-    Language::staticmembervariableHandler(n);
-    current = NO_CPP;
-    return SWIG_OK;
-  }
-};
-
-/* -----------------------------------------------------------------------------
- * swig_pike()    - Instantiate module
- * ----------------------------------------------------------------------------- */
-
-static Language *new_swig_pike() {
-  return new PIKE();
-}
-extern "C" Language *swig_pike(void) {
-  return new_swig_pike();
-}
diff --git a/Source/Modules/python.cxx b/Source/Modules/python.cxx
index ea31af0..905a026 100644
--- a/Source/Modules/python.cxx
+++ b/Source/Modules/python.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * python.cxx
  *
@@ -12,13 +12,12 @@
  * ----------------------------------------------------------------------------- */
 
 #include "swigmod.h"
-#include <limits.h>
 #include "cparse.h"
+#include <limits.h>
 #include <ctype.h>
 #include <errno.h>
-#include "pydoc.h"
-
 #include <stdint.h>
+#include "pydoc.h"
 
 #define PYSHADOW_MEMBER  0x2
 #define WARN_PYTHON_MULTIPLE_INH 405
@@ -69,12 +68,12 @@
 static int max_bases = 0;
 static int builtin_bases_needed = 0;
 
-static int py3 = 0;
-
 /* C++ Support + Shadow Classes */
 
-static int have_constructor;
-static int have_repr;
+static int have_constructor = 0;
+static int have_repr = 0;
+static bool have_builtin_static_member_method_callback = false;
+static bool have_fast_proxy_static_member_method_callback = false;
 static String *real_classname;
 
 /* Thread Support */
@@ -91,8 +90,10 @@
 static int extranative = 0;
 static int nortti = 0;
 static int relativeimport = 0;
+static int flat_static_method = 0;
 
 /* flags for the make_autodoc function */
+namespace {
 enum autodoc_t {
   AUTODOC_CLASS,
   AUTODOC_CTOR,
@@ -103,7 +104,7 @@
   AUTODOC_CONST,
   AUTODOC_VAR
 };
-
+}
 
 static const char *usage1 = "\
 Python Options (available with -python)\n\
@@ -115,6 +116,7 @@
      -doxygen        - Convert C++ doxygen comments to pydoc comments in proxy classes\n\
      -extranative    - Return extra native wrappers for C++ std containers wherever possible\n\
      -fastproxy      - Use fast proxy mechanism for member methods\n\
+     -flatstaticmethod         - Generate additional flattened Python methods for C++ static methods\n\
      -globals <name> - Set <name> used to access C global variable (default: 'cvar')\n\
      -interface <mod>- Set low-level C/C++ module name to <mod> (default: module name prefixed by '_')\n\
      -keyword        - Use keyword arguments\n";
@@ -126,7 +128,6 @@
      -nortti         - Disable the use of the native C++ RTTI with directors\n\
      -nothreads      - Disable thread support for the entire interface\n\
      -olddefs        - Keep the old method definitions when using -fastproxy\n\
-     -py3            - Generate code with Python 3 specific features and syntax\n\
      -relativeimport - Use relative Python imports\n\
      -threads        - Add thread support for all the interface\n\
      -O              - Enable the following optimization options:\n\
@@ -219,7 +220,7 @@
 	   "  $director_new \n",
 	   "} else {\n", "  SWIG_SetErrorMsg(PyExc_RuntimeError,\"accessing abstract class or protected constructor\"); \n", "  SWIG_fail;\n", "}\n", NIL);
     director_multiple_inheritance = 1;
-    director_language = 1;
+    directorLanguage();
   }
 
   ~PYTHON() {
@@ -313,7 +314,6 @@
 	  } else {
 	    Swig_arg_error();
 	  }
-	  /* end added */
 	} else if (strcmp(argv[i], "-globals") == 0) {
 	  if (argv[i + 1]) {
 	    global_name = NewString(argv[i + 1]);
@@ -371,6 +371,9 @@
 	} else if (strcmp(argv[i], "-extranative") == 0) {
 	  extranative = 1;
 	  Swig_mark_arg(i);
+	} else if (strcmp(argv[i], "-flatstaticmethod") == 0) {
+	  flat_static_method = 1;
+	  Swig_mark_arg(i);
 	} else if (strcmp(argv[i], "-noh") == 0) {
 	  no_header_file = 1;
 	  Swig_mark_arg(i);
@@ -389,10 +392,6 @@
 	  fputs(usage1, stdout);
 	  fputs(usage2, stdout);
 	  fputs(usage3, stdout);
-	} else if (strcmp(argv[i], "-py3") == 0) {
-	  py3 = 1;
-	  Preprocessor_define("SWIGPYTHON_PY3", 0);
-	  Swig_mark_arg(i);
 	} else if (strcmp(argv[i], "-builtin") == 0) {
 	  builtin = 1;
 	  Preprocessor_define("SWIGPYTHON_BUILTIN", 0);
@@ -408,7 +407,10 @@
 		   strcmp(argv[i], "-modernargs") == 0 ||
 		   strcmp(argv[i], "-noproxydel") == 0 ||
 		   strcmp(argv[i], "-safecstrings") == 0) {
-	  Printf(stderr, "Deprecated command line option: %s. This option is now always on.\n", argv[i]);
+	  Printf(stderr, "Deprecated command line option: %s. Ignored, this option is now always on.\n", argv[i]);
+	  Swig_mark_arg(i);
+	} else if (strcmp(argv[i], "-py3") == 0) {
+	  Printf(stderr, "Deprecated command line option: %s. Ignored, this option is no longer supported.\n", argv[i]);
 	  Swig_mark_arg(i);
 	} else if (strcmp(argv[i], "-aliasobj0") == 0 ||
 		   strcmp(argv[i], "-buildnone") == 0 ||
@@ -436,14 +438,23 @@
 		   strcmp(argv[i], "-oldrepr") == 0 ||
 		   strcmp(argv[i], "-outputtuple") == 0 ||
 		   strcmp(argv[i], "-proxydel") == 0) {
-	  Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
+	  Printf(stderr, "Deprecated command line option: %s. This option is no longer available.\n", argv[i]);
 	  Swig_mark_arg(i);
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	}
 
       }
     }
 
+    if (builtin && !shadow) {
+      Printf(stderr, "Incompatible options -builtin and -noproxy specified.\n");
+      Exit(EXIT_FAILURE);
+    }
+
+    if (fastproxy) {
+      Preprocessor_define("SWIGPYTHON_FASTPROXY", 0);
+    }
+
     if (doxygen)
       doxygenTranslator = new PyDocConverter(doxygen_translator_flags);
 
@@ -496,22 +507,22 @@
 	  }
 	  if (Getattr(options, "nocastmode")) {
 	    Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "nocastmode");
-	    SWIG_exit(EXIT_FAILURE);
+	    Exit(EXIT_FAILURE);
 	  }
 	  if (Getattr(options, "extranative")) {
 	    extranative = 1;
 	  }
 	  if (Getattr(options, "noextranative")) {
 	    Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "noextranative");
-	    SWIG_exit(EXIT_FAILURE);
+	    Exit(EXIT_FAILURE);
 	  }
 	  if (Getattr(options, "outputtuple")) {
 	    Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "outputtuple");
-	    SWIG_exit(EXIT_FAILURE);
+	    Exit(EXIT_FAILURE);
 	  }
 	  if (Getattr(options, "nooutputtuple")) {
 	    Printf(stderr, "Deprecated module option: %s. This option is no longer supported.\n", "nooutputtuple");
-	    SWIG_exit(EXIT_FAILURE);
+	    Exit(EXIT_FAILURE);
 	  }
 	  mod_docstring = Getattr(options, "docstring");
 	  package = Getattr(options, "package");
@@ -530,7 +541,7 @@
     f_begin = NewFile(outfile, "w", SWIG_output_files());
     if (!f_begin) {
       FileErrorDisplay(outfile);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
     f_runtime = NewString("");
     f_init = NewString("");
@@ -549,12 +560,12 @@
       f_builtins = NewString("");
     }
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       if (!no_header_file) {
 	f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
 	if (!f_runtime_h) {
 	  FileErrorDisplay(outfile_h);
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	}
       } else {
 	f_runtime_h = f_runtime;
@@ -576,9 +587,9 @@
 
     Swig_banner(f_begin);
 
-    Printf(f_runtime, "\n\n#ifndef SWIGPYTHON\n#define SWIGPYTHON\n#endif\n\n");
+    Swig_obligatory_macros(f_runtime, "PYTHON");
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Printf(f_runtime, "#define SWIG_DIRECTORS\n");
     }
 
@@ -611,6 +622,10 @@
       Printf(f_runtime, "#define SWIGPYTHON_BUILTIN\n");
     }
 
+    if (fastproxy) {
+      Printf(f_runtime, "#define SWIGPYTHON_FASTPROXY\n");
+    }
+
     Printf(f_runtime, "\n");
 
     Printf(f_header, "#ifdef SWIG_TypeQuery\n");
@@ -623,7 +638,7 @@
     module = Copy(Getattr(n, "name"));
     mainmodule = Getattr(n, "name");
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Swig_banner(f_directors_h);
       Printf(f_directors_h, "\n");
       Printf(f_directors_h, "#ifndef SWIG_%s_WRAP_H_\n", module);
@@ -655,7 +670,7 @@
 	Insert(module, 0, "_");
       if ((f_shadow_py = NewFile(filen, "w", SWIG_output_files())) == 0) {
 	FileErrorDisplay(filen);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       Delete(filen);
       filen = NULL;
@@ -696,9 +711,11 @@
         Printv(default_import_code, tab4, "from ", module, " import *\n", NULL);
       }
 
-      /* Need builtins to qualify names like Exception that might also be
-         defined in this module (try both Python 3 and Python 2 names) */
-      Printv(f_shadow, "try:\n", tab4, "import builtins as __builtin__\n", "except ImportError:\n", tab4, "import __builtin__\n", NULL);
+      if (!builtin) {
+	/* Need builtins to qualify names like Exception that might also be
+	   defined in this module (try both Python 3 and Python 2 names) */
+	Printv(f_shadow, "try:\n", tab4, "import builtins as __builtin__\n", "except ImportError:\n", tab4, "import __builtin__\n", NULL);
+      }
 
       if (!builtin && fastproxy) {
 	Printf(f_shadow, "\n");
@@ -706,58 +723,54 @@
 	Printf(f_shadow, "_swig_new_static_method = %s.SWIG_PyStaticMethod_New\n", module);
       }
 
-      Printv(f_shadow, "\n",
-	     "def _swig_repr(self):\n",
-	     tab4, "try:\n",
-	     tab4, tab4, "strthis = \"proxy of \" + self.this.__repr__()\n",
-	     tab4, "except __builtin__.Exception:\n",
-	     tab4, tab4, "strthis = \"\"\n",
-	     tab4, "return \"<%s.%s; %s >\" % (self.__class__.__module__, self.__class__.__name__, strthis,)\n\n", NIL);
+      if (!builtin) {
+	Printv(f_shadow, "\n",
+	       "def _swig_repr(self):\n",
+	       tab4, "try:\n",
+	       tab4, tab4, "strthis = \"proxy of \" + self.this.__repr__()\n",
+	       tab4, "except __builtin__.Exception:\n",
+	       tab4, tab4, "strthis = \"\"\n",
+	       tab4, "return \"<%s.%s; %s >\" % (self.__class__.__module__, self.__class__.__name__, strthis,)\n\n", NIL);
 
-      Printv(f_shadow,  "\n",
-	     "def _swig_setattr_nondynamic_instance_variable(set):\n",
-	     tab4, "def set_instance_attr(self, name, value):\n",
-#ifdef USE_THISOWN
-	     tab4, tab4, "if name in (\"this\", \"thisown\"):\n",
-	     tab4, tab4, tab4, "set(self, name, value)\n",
-#else
-	     tab4, tab4, "if name == \"thisown\":\n",
-	     tab4, tab4, tab4, "self.this.own(value)\n",
-	     tab4, tab4, "elif name == \"this\":\n",
-	     tab4, tab4, tab4, "set(self, name, value)\n",
-#endif
-	     tab4, tab4, "elif hasattr(self, name) and isinstance(getattr(type(self), name), property):\n",
-	     tab4, tab4, tab4, "set(self, name, value)\n",
-	     tab4, tab4, "else:\n",
-	     tab4, tab4, tab4, "raise AttributeError(\"You cannot add instance attributes to %s\" % self)\n",
-	     tab4, "return set_instance_attr\n\n", NIL);
+	Printv(f_shadow, "\n",
+	       "def _swig_setattr_nondynamic_instance_variable(set):\n",
+	       tab4, "def set_instance_attr(self, name, value):\n",
+	       tab4, tab4, "if name == \"this\":\n",
+	       tab4, tab4, tab4, "set(self, name, value)\n",
+	       tab4, tab4, "elif name == \"thisown\":\n",
+	       tab4, tab4, tab4, "self.this.own(value)\n",
+	       tab4, tab4, "elif hasattr(self, name) and isinstance(getattr(type(self), name), property):\n",
+	       tab4, tab4, tab4, "set(self, name, value)\n",
+	       tab4, tab4, "else:\n",
+	       tab4, tab4, tab4, "raise AttributeError(\"You cannot add instance attributes to %s\" % self)\n",
+	       tab4, "return set_instance_attr\n\n", NIL);
 
-      Printv(f_shadow,  "\n",
-	     "def _swig_setattr_nondynamic_class_variable(set):\n",
-	     tab4, "def set_class_attr(cls, name, value):\n",
-	     tab4, tab4, "if hasattr(cls, name) and not isinstance(getattr(cls, name), property):\n",
-	     tab4, tab4, tab4, "set(cls, name, value)\n",
-	     tab4, tab4, "else:\n",
-	     tab4, tab4, tab4, "raise AttributeError(\"You cannot add class attributes to %s\" % cls)\n",
-	     tab4, "return set_class_attr\n\n", NIL);
+	Printv(f_shadow, "\n",
+	       "def _swig_setattr_nondynamic_class_variable(set):\n",
+	       tab4, "def set_class_attr(cls, name, value):\n",
+	       tab4, tab4, "if hasattr(cls, name) and not isinstance(getattr(cls, name), property):\n",
+	       tab4, tab4, tab4, "set(cls, name, value)\n",
+	       tab4, tab4, "else:\n",
+	       tab4, tab4, tab4, "raise AttributeError(\"You cannot add class attributes to %s\" % cls)\n",
+	       tab4, "return set_class_attr\n\n", NIL);
 
-      Printv(f_shadow,  "\n",
-	     "def _swig_add_metaclass(metaclass):\n",
-	     tab4, "\"\"\"Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass\"\"\"\n",
-	     tab4, "def wrapper(cls):\n",
-	     tab4, tab4, "return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())\n",
-	     tab4, "return wrapper\n\n", NIL);
+	Printv(f_shadow, "\n",
+	       "def _swig_add_metaclass(metaclass):\n",
+	       tab4, "\"\"\"Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass\"\"\"\n",
+	       tab4, "def wrapper(cls):\n",
+	       tab4, tab4, "return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())\n",
+	       tab4, "return wrapper\n\n", NIL);
 
-      Printv(f_shadow,  "\n",
-	     "class _SwigNonDynamicMeta(type):\n",
-	     tab4, "\"\"\"Meta class to enforce nondynamic attributes (no new attributes) for a class\"\"\"\n",
-	     tab4, "__setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)\n",
-	     "\n", NIL);
+	Printv(f_shadow, "\n",
+	       "class _SwigNonDynamicMeta(type):\n",
+	       tab4, "\"\"\"Meta class to enforce nondynamic attributes (no new attributes) for a class\"\"\"\n",
+	       tab4, "__setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)\n",
+	       "\n", NIL);
 
-      Printv(f_shadow, "\n", NIL);
+	Printv(f_shadow, "\n", NIL);
 
-      if (directorsEnabled()) {
-	Printv(f_shadow, "import weakref\n\n", NIL);
+	if (Swig_directors_enabled())
+	  Printv(f_shadow, "import weakref\n\n", NIL);
       }
     }
     // Include some information in the code
@@ -792,7 +805,7 @@
     /* emit code */
     Language::top(n);
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       // Insert director runtime into the f_runtime file (make it occur before %header section)
       Swig_insert_file("director_common.swg", f_runtime);
       Swig_insert_file("director.swg", f_runtime);
@@ -804,7 +817,8 @@
     Printf(f_wrappers, "%s\n", methods);
     Append(methods_proxydocs, "\t { NULL, NULL, 0, NULL }\n");
     Append(methods_proxydocs, "};\n");
-    Printf(f_wrappers, "%s\n", methods_proxydocs);
+    if ((fastproxy && !builtin) || have_fast_proxy_static_member_method_callback)
+      Printf(f_wrappers, "%s\n", methods_proxydocs);
 
     if (builtin) {
       Dump(f_builtins, f_wrappers);
@@ -814,6 +828,10 @@
 
     Append(const_code, "{0, 0, 0, 0.0, 0, 0}};\n");
     Printf(f_wrappers, "%s\n", const_code);
+
+    if (have_fast_proxy_static_member_method_callback)
+      Printf(f_init, "  SWIG_Python_FixMethods(SwigMethods_proxydocs, swig_const_table, swig_types, swig_type_initial);\n\n");
+
     initialize_threads(f_init);
 
     Printf(f_init, "#if PY_VERSION_HEX >= 0x03000000\n");
@@ -846,8 +864,6 @@
 	Printv(f_shadow_py, "\n", f_shadow_begin, "\n", NIL);
 
       Printv(f_shadow_py, "\nfrom sys import version_info as _swig_python_version_info\n", NULL);
-      Printv(f_shadow_py, "if _swig_python_version_info < (2, 7, 0):\n", NULL);
-      Printv(f_shadow_py, tab4, "raise RuntimeError(\"Python 2.7 or later required\")\n\n", NULL);
 
       if (Len(f_shadow_after_begin) > 0)
 	Printv(f_shadow_py, f_shadow_after_begin, "\n", NIL);
@@ -859,8 +875,10 @@
 	Printv(f_shadow_py, default_import_code, NIL);
       }
 
-      Printv(f_shadow_py, "\n", f_shadow, "\n", NIL);
-      Printv(f_shadow_py, f_shadow_stubs, "\n", NIL);
+      if (Len(f_shadow) > 0)
+	Printv(f_shadow_py, "\n", f_shadow, "\n", NIL);
+      if (Len(f_shadow_stubs) > 0)
+	Printv(f_shadow_py, f_shadow_stubs, "\n", NIL);
       Delete(f_shadow_py);
     }
 
@@ -868,7 +886,7 @@
     Dump(f_runtime, f_begin);
     Dump(f_header, f_begin);
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Dump(f_directors_h, f_runtime_h);
       Printf(f_runtime_h, "\n");
       Printf(f_runtime_h, "#endif\n");
@@ -905,15 +923,15 @@
    * as a replacement of new.instancemethod in Python 3.
    * ------------------------------------------------------------ */
   int add_pyinstancemethod_new() {
-    String *name = NewString("SWIG_PyInstanceMethod_New");
-    String *line = NewString("");
-    Printf(line, "\t { \"%s\", %s, METH_O, NULL},\n", name, name);
-    Append(methods, line);
-    if (fastproxy) {
+    if (!builtin && fastproxy) {
+      String *name = NewString("SWIG_PyInstanceMethod_New");
+      String *line = NewString("");
+      Printf(line, "\t { \"%s\", %s, METH_O, NULL},\n", name, name);
+      Append(methods, line);
       Append(methods_proxydocs, line);
+      Delete(line);
+      Delete(name);
     }
-    Delete(line);
-    Delete(name);
     return 0;
   }
 
@@ -923,7 +941,7 @@
    * generated for static methods when using -fastproxy
    * ------------------------------------------------------------ */
   int add_pystaticmethod_new() {
-    if (fastproxy) {
+    if (!builtin && fastproxy) {
       String *name = NewString("SWIG_PyStaticMethod_New");
       String *line = NewString("");
       Printf(line, "\t { \"%s\", %s, METH_O, NULL},\n", name, name);
@@ -1473,19 +1491,28 @@
   /* ------------------------------------------------------------
    * build_combined_docstring()
    *
-   * Build the full docstring which may be a combination of the
-   * explicit docstring and autodoc string or, if none of them
-   * is specified, obtained by translating Doxygen comment to
-   * Python.
+   * Build the full docstring:
+   * Use the docstring if there is one present otherwise
+   * use the Doxygen comment if there is one present.
+   * Ignore autodoc if there is a Doxygen comment, otherwise
+   * create the autodoc string and append to any docstring.
    *
    * Return new string to be deleted by caller (never NIL but
    * may be empty if there is no docstring).
    * ------------------------------------------------------------ */
 
   String *build_combined_docstring(Node *n, autodoc_t ad_type, const String *indent = "", bool low_level = false) {
+    bool add_autodoc = true;
     String *docstr = Getattr(n, "feature:docstring");
-    if (docstr && Len(docstr)) {
-      docstr = Copy(docstr);
+    if (docstr) {
+      // Simplify the code below by just ignoring empty docstrings.
+      if (!Len(docstr))
+	docstr = NULL;
+      else
+	docstr = Copy(docstr);
+    }
+
+    if (docstr) {
       char *t = Char(docstr);
       if (*t == '{') {
 	Delitem(docstr, 0);
@@ -1493,26 +1520,10 @@
       }
     }
 
-    if (Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")) {
-      String *autodoc = make_autodoc(n, ad_type, low_level);
-      if (autodoc && Len(autodoc) > 0) {
-	if (docstr && Len(docstr)) {
-	  Append(autodoc, "\n");
-	  Append(autodoc, docstr);
-	}
-
-	String *tmp = autodoc;
-	autodoc = docstr;
-	docstr = tmp;
-      }
-
-      Delete(autodoc);
-    }
-
-    if (!docstr || !Len(docstr)) {
-      if (doxygen) {
+    if (!docstr) {
+      if (doxygen && doxygenTranslator->hasDocumentation(n)) {
 	docstr = Getattr(n, "python:docstring");
-	if (!docstr && doxygenTranslator->hasDocumentation(n)) {
+	if (!docstr) {
 	  docstr = doxygenTranslator->getDocumentation(n, 0);
 
 	  // Avoid rebuilding it again the next time: notice that we can't do
@@ -1528,9 +1539,26 @@
 	  // the cached object!
 	  docstr = Copy(docstr);
 	}
+	add_autodoc = false;
       }
     }
 
+    if (add_autodoc && Getattr(n, "feature:autodoc") && !GetFlag(n, "feature:noautodoc")) {
+      String *autodoc = make_autodoc(n, ad_type, low_level);
+      if (autodoc && Len(autodoc) > 0) {
+	if (docstr) {
+	  Append(autodoc, "\n");
+	  Append(autodoc, docstr);
+	}
+
+	String *tmp = autodoc;
+	autodoc = docstr;
+	docstr = tmp;
+      }
+
+      Delete(autodoc);
+    }
+
     if (!docstr)
       docstr = NewString("");
 
@@ -1564,7 +1592,8 @@
 
   String *docstring(Node *n, autodoc_t ad_type, const String *indent, bool low_level = false) {
     String *docstr = build_combined_docstring(n, ad_type, indent, low_level);
-    if (!Len(docstr))
+    const int len = Len(docstr);
+    if (!len)
       return docstr;
 
     // Notice that all comments are created as raw strings (prefix "r"),
@@ -1577,9 +1606,32 @@
     // escape '\x'. '\' may additionally appear in verbatim or htmlonly sections
     // of doxygen doc, Latex expressions, ...
     String *doc = NewString("");
-    Append(doc, "r\"\"\"");
+
+    // Determine which kind of quotes to use as delimiters: for single line
+    // strings we can avoid problems with having a quote as the last character
+    // of the docstring by using different kind of quotes as delimiters. For
+    // multi-line strings this problem doesn't arise, as we always have a new
+    // line or spaces at the end of it, but it still does no harm to do it for
+    // them too.
+    //
+    // Note: we use double quotes by default, i.e. if there is no reason to
+    // prefer using single ones, for consistency with the older SWIG versions.
+    const bool useSingleQuotes = (Char(docstr))[len - 1] == '"';
+
+    Append(doc, useSingleQuotes ? "r'''" : "r\"\"\"");
+
+    // We also need to avoid having triple quotes of whichever type we use, as
+    // this would break Python doc string syntax too. Unfortunately there is no
+    // way to have triple quotes inside of raw-triple-quoted string, so we have
+    // to break the string in parts and rely on concatenation of the adjacent
+    // string literals.
+    if (useSingleQuotes)
+      Replaceall(docstr, "'''", "''' \"'''\" '''");
+    else
+      Replaceall(docstr, "\"\"\"", "\"\"\" '\"\"\"' \"\"\"");
+
     Append(doc, docstr);
-    Append(doc, "\"\"\"");
+    Append(doc, useSingleQuotes ? "'''" : "\"\"\"");
     Delete(docstr);
 
     return doc;
@@ -1846,16 +1898,20 @@
 	    String *str = Getattr(n, "feature:docstring");
 	    if (!str || Len(str) == 0) {
 	      if (builtin) {
-		String *name = Getattr(n, "name");
-		String *rname = add_explicit_scope(SwigType_namestr(name));
+		SwigType *name = Getattr(n, "name");
+		SwigType *sname = add_explicit_scope(name);
+		String *rname = SwigType_namestr(sname);
 		Printf(doc, "%s", rname);
+		Delete(sname);
 		Delete(rname);
 	      } else {
+		String *classname_str = SwigType_namestr(real_classname);
 		if (CPlusPlus) {
-		  Printf(doc, "Proxy of C++ %s class.", SwigType_namestr(real_classname));
+		  Printf(doc, "Proxy of C++ %s class.", classname_str);
 		} else {
-		  Printf(doc, "Proxy of C %s struct.", SwigType_namestr(real_classname));
+		  Printf(doc, "Proxy of C %s struct.", classname_str);
 		}
+		Delete(classname_str);
 	      }
 	    }
 	  }
@@ -2219,7 +2275,7 @@
       return parms;
     }
 
-    bool funcanno = py3 ? true : false;
+    bool funcanno = Equal(Getattr(n, "feature:python:annotations"), "c") ? true : false;
     String *params = NewString("");
     String *_params = make_autodocParmList(n, false, ((in_class || has_self_for_count)? 2 : 1), is_calling, funcanno);
 
@@ -2335,8 +2391,25 @@
       if (ret)
 	ret = SwigType_str(ret, 0);
     }
-    return (ret && py3) ? NewStringf(" -> \"%s\"", ret)
-	: NewString("");
+    bool funcanno = Equal(Getattr(n, "feature:python:annotations"), "c") ? true : false;
+    return (ret && funcanno) ? NewStringf(" -> \"%s\"", ret) : NewString("");
+  }
+
+  /* ------------------------------------------------------------
+   * variableAnnotation()
+   *
+   * Helper function for constructing a variable annotation
+   * ------------------------------------------------------------ */
+
+  String *variableAnnotation(Node *n) {
+    String *type = Getattr(n, "type");
+    if (type)
+      type = SwigType_str(type, 0);
+    bool anno = Equal(Getattr(n, "feature:python:annotations"), "c") ? true : false;
+    anno = GetFlag(n, "feature:python:annotations:novar") ? false : anno;
+    String *annotation = (type && anno) ? NewStringf(": \"%s\"", type) : NewString("");
+    Delete(type);
+    return annotation;
   }
 
   /* ------------------------------------------------------------
@@ -2441,6 +2514,7 @@
       Printf(methods, "\"swig_ptr: %s\"", Getattr(n, "feature:callback:name"));
       if (fastproxy) {
 	Printf(methods_proxydocs, "\"swig_ptr: %s\"", Getattr(n, "feature:callback:name"));
+	have_fast_proxy_static_member_method_callback = true;
       }
     } else {
       Append(methods, "NULL");
@@ -2458,7 +2532,7 @@
   /* ------------------------------------------------------------
    * dispatchFunction()
    * ------------------------------------------------------------ */
-  void dispatchFunction(Node *n, String *linkage, int funpack = 0, bool builtin_self = false, bool builtin_ctor = false, bool director_class = false) {
+  void dispatchFunction(Node *n, String *linkage, int funpack = 0, bool builtin_self = false, bool builtin_ctor = false, bool director_class = false, bool use_static_method = false) {
     /* Last node in overloaded chain */
 
     bool add_self = builtin_self && (!builtin_ctor || director_class);
@@ -2493,9 +2567,14 @@
     String *symname = Getattr(n, "sym:name");
     String *wname = Swig_name_wrapper(symname);
 
-    const char *builtin_kwargs = builtin_ctor ? ", PyObject *SWIGUNUSEDPARM(kwargs)" : "";
+    const char *builtin_kwargs = builtin_ctor ? ", PyObject *kwargs" : "";
     Printv(f->def, linkage, builtin_ctor ? "int " : "PyObject *", wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL);
 
+    if (builtin) {
+      /* Avoid warning if the self parameter is not used. */
+      Append(f->code, "(void)self;\n");
+    }
+
     Wrapper_add_local(f, "argc", "Py_ssize_t argc");
     Printf(tmp, "PyObject *argv[%d] = {0}", maxargs + 1);
     Wrapper_add_local(f, "argv", tmp);
@@ -2503,6 +2582,9 @@
     if (!fastunpack) {
       Wrapper_add_local(f, "ii", "Py_ssize_t ii");
 
+      if (builtin_ctor)
+	Printf(f->code, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", symname);
+
       if (maxargs - (add_self ? 1 : 0) > 0) {
         Append(f->code, "if (!PyTuple_Check(args)) SWIG_fail;\n");
         Append(f->code, "argc = PyObject_Length(args);\n");
@@ -2518,8 +2600,9 @@
       if (add_self)
 	Append(f->code, "argc++;\n");
     } else {
-      String *iname = Getattr(n, "sym:name");
-      Printf(f->code, "if (!(argc = SWIG_Python_UnpackTuple(args, \"%s\", 0, %d, argv%s))) SWIG_fail;\n", iname, maxargs, add_self ? "+1" : "");
+      if (builtin_ctor)
+	Printf(f->code, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", symname);
+      Printf(f->code, "if (!(argc = SWIG_Python_UnpackTuple(args, \"%s\", 0, %d, argv%s))) SWIG_fail;\n", symname, maxargs, add_self ? "+1" : "");
       if (add_self)
 	Append(f->code, "argv[0] = self;\n");
       else
@@ -2553,11 +2636,11 @@
     Printv(f->code, "}\n", NIL);
     Wrapper_print(f, f_wrappers);
     Node *p = Getattr(n, "sym:previousSibling");
-    if (!builtin_self)
+    if (!builtin_self && (use_static_method || !builtin))
       add_method(symname, wname, 0, p);
 
     /* Create a shadow for this function (if enabled and not in a member function) */
-    if (!builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER))) {
+    if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER) && use_static_method) {
       emitFunctionShadowHelper(n, in_class ? f_shadow_stubs : f_shadow, symname, 0);
     }
     DelWrapper(f);
@@ -2635,6 +2718,7 @@
     int constructor = (!Cmp(nodeType, "constructor"));
     int destructor = (!Cmp(nodeType, "destructor"));
     String *storage = Getattr(n, "storage");
+    int isfriend = Strstr(storage, "friend") != NULL;
     /* Only the first constructor is handled as init method. Others
        constructor can be emitted via %rename */
     int handled_as_init = 0;
@@ -2661,7 +2745,6 @@
     bool add_self = builtin_self && (!builtin_ctor || director_class);
     bool builtin_getter = (builtin && GetFlag(n, "memberget"));
     bool builtin_setter = (builtin && GetFlag(n, "memberset") && !builtin_getter);
-    char const *self_param = builtin ? "self" : "SWIGUNUSEDPARM(self)";
     char const *wrap_return = builtin_ctor ? "int " : "PyObject *";
     String *linkage = NewString("SWIGINTERN ");
     String *wrapper_name = Swig_name_wrapper(iname);
@@ -2700,8 +2783,12 @@
       --tuple_required;
     }
     num_fixed_arguments = tuple_required;
+
+    // builtin handles/checks kwargs by default except in constructor wrappers so we need to explicitly handle them in the C constructor wrapper
+    // The check below is for zero arguments. Sometimes (eg directors) self is the first argument for a method with zero arguments.
     if (((num_arguments == 0) && (num_required == 0)) || ((num_arguments == 1) && (num_required == 1) && Getattr(l, "self")))
-      allow_kwargs = 0;
+      if (!builtin_ctor)
+	allow_kwargs = 0;
     varargs = emit_isvarargs(l);
 
     String *wname = Copy(wrapper_name);
@@ -2709,12 +2796,12 @@
       Append(wname, overname);
     }
 
-    const char *builtin_kwargs = builtin_ctor ? ", PyObject *SWIGUNUSEDPARM(kwargs)" : "";
+    const char *builtin_kwargs = builtin_ctor ? ", PyObject *kwargs" : "";
     if (!allow_kwargs || overname) {
       if (!varargs) {
-	Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL);
+	Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL);
       } else {
-	Printv(f->def, linkage, wrap_return, wname, "__varargs__", "(PyObject *", self_param, ", PyObject *args, PyObject *varargs) {", NIL);
+	Printv(f->def, linkage, wrap_return, wname, "__varargs__", "(PyObject *self, PyObject *args, PyObject *varargs", builtin_kwargs, ") {", NIL);
       }
       if (allow_kwargs) {
 	Swig_warning(WARN_LANG_OVERLOAD_KEYWORD, input_file, line_number, "Can't use keyword arguments with overloaded functions (%s).\n", Swig_name_decl(n));
@@ -2725,9 +2812,15 @@
 	Swig_warning(WARN_LANG_VARARGS_KEYWORD, input_file, line_number, "Can't wrap varargs with keyword arguments enabled\n");
 	varargs = 0;
       }
-      Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args, PyObject *kwargs) {", NIL);
+      Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args, PyObject *kwargs) {", NIL);
     }
-    if (!builtin || !in_class || tuple_arguments > 0) {
+
+    if (!builtin) {
+      /* Avoid warning if the self parameter is not used. */
+      Append(f->code, "(void)self;\n");
+    }
+
+    if (!builtin || !in_class || tuple_arguments > 0 || builtin_ctor) {
       if (!allow_kwargs) {
 	Append(parse_args, "    if (!PyArg_ParseTuple(args, \"");
       } else {
@@ -2753,7 +2846,7 @@
 
     /* Generate code for argument marshalling */
     if (funpack) {
-      if (num_arguments > 0 && !overname) {
+      if (num_arguments > (builtin_self && !constructor ? 1 : 0) && !overname) {
 	sprintf(source, "PyObject *swig_obj[%d]", num_arguments);
 	Wrapper_add_localv(f, "swig_obj", source, NIL);
       }
@@ -2823,8 +2916,6 @@
 	  } else {
 	    Replaceall(tm, "$self", "obj0");
 	  }
-	  Replaceall(tm, "$source", source);
-	  Replaceall(tm, "$target", ln);
 	  Replaceall(tm, "$input", source);
 	  Setattr(p, "emit:input", source);	/* Save the location of the object */
 
@@ -2876,26 +2967,27 @@
       Printv(f->locals, "  char * kwnames[] = ", kwargs, ";\n", NIL);
     }
 
-    if (builtin && !funpack && in_class && tuple_arguments == 0) {
-      Printf(parse_args, "    if (args && PyTuple_Check(args) && PyTuple_GET_SIZE(args) > 0) SWIG_exception_fail(SWIG_TypeError, \"%s takes no arguments\");\n", iname);
-    } else if (use_parse || allow_kwargs) {
+    if (use_parse || allow_kwargs) {
       Printf(parse_args, ":%s\"", iname);
       Printv(parse_args, arglist, ")) SWIG_fail;\n", NIL);
       funpack = 0;
     } else {
       Clear(parse_args);
+
       if (funpack) {
 	Clear(f->def);
 	if (overname) {
 	  if (noargs) {
-	    Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {", NIL);
+	    Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, Py_ssize_t nobjs, PyObject **SWIGUNUSEDPARM(swig_obj)) {", NIL);
 	  } else {
-	    Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", Py_ssize_t nobjs, PyObject **swig_obj) {", NIL);
+	    Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {", NIL);
 	  }
 	  Printf(parse_args, "if ((nobjs < %d) || (nobjs > %d)) SWIG_fail;\n", num_required, num_arguments);
 	} else {
 	  int is_tp_call = Equal(Getattr(n, "feature:python:slot"), "tp_call");
-	  Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL);
+	  Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL);
+	  if (builtin_ctor)
+	    Printf(parse_args, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", iname);
 	  if (onearg && !builtin_ctor && !is_tp_call) {
 	    Printf(parse_args, "if (!args) SWIG_fail;\n");
 	    Append(parse_args, "swig_obj[0] = args;\n");
@@ -2906,8 +2998,14 @@
 	  }
 	}
       } else {
-	Printf(parse_args, "if (!PyArg_UnpackTuple(args, \"%s\", %d, %d", iname, num_fixed_arguments, tuple_arguments);
-	Printv(parse_args, arglist, ")) SWIG_fail;\n", NIL);
+	if (builtin_ctor)
+	  Printf(parse_args, "if (!SWIG_Python_CheckNoKeywords(kwargs, \"%s\")) SWIG_fail;\n", iname);
+	if (builtin && in_class && tuple_arguments == 0) {
+	  Printf(parse_args, "    if (args && PyTuple_Check(args) && PyTuple_GET_SIZE(args) > 0) SWIG_exception_fail(SWIG_TypeError, \"%s takes no arguments\");\n", iname);
+	} else {
+	  Printf(parse_args, "if (!PyArg_UnpackTuple(args, \"%s\", %d, %d", iname, num_fixed_arguments, tuple_arguments);
+	  Printv(parse_args, arglist, ")) SWIG_fail;\n", NIL);
+	}
       }
     }
 
@@ -2925,7 +3023,6 @@
     /* Insert constraint checking code */
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:check"))) {
-	Replaceall(tm, "$target", Getattr(p, "lname"));
 	Printv(f->code, tm, "\n", NIL);
 	p = Getattr(p, "tmap:check:next");
       } else {
@@ -2947,7 +3044,6 @@
 	  }
 	}
 	if (tm && (Len(tm) != 0)) {
-	  Replaceall(tm, "$source", Getattr(p, "lname"));
 	  Printv(cleanup, tm, "\n", NIL);
 	}
 	p = Getattr(p, "tmap:freearg:next");
@@ -2959,8 +3055,6 @@
     /* Insert argument output code */
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:argout"))) {
-	Replaceall(tm, "$source", Getattr(p, "lname"));
-	Replaceall(tm, "$target", "resultobj");
 	Replaceall(tm, "$arg", Getattr(p, "emit:input"));
 	Replaceall(tm, "$input", Getattr(p, "emit:input"));
 	Printv(outarg, tm, "\n", NIL);
@@ -3049,8 +3143,6 @@
       } else {
 	Replaceall(tm, "$self", "obj0");
       }
-      Replaceall(tm, "$source", Swig_cresult_name());
-      Replaceall(tm, "$target", "resultobj");
       Replaceall(tm, "$result", "resultobj");
       if (builtin_ctor) {
 	Replaceall(tm, "$owner", "SWIG_BUILTIN_INIT");
@@ -3063,27 +3155,9 @@
 	  Replaceall(tm, "$owner", "0");
 	}
       }
-      // FIXME: this will not try to unwrap directors returned as non-director
-      //        base class pointers!
 
-      /* New addition to unwrap director return values so that the original
-       * python object is returned instead.
-       */
-#if 1
-      int unwrap = 0;
-      String *decl = Getattr(n, "decl");
-      int is_pointer = SwigType_ispointer_return(decl);
-      int is_reference = SwigType_isreference_return(decl);
-      if (is_pointer || is_reference) {
-	String *type = Getattr(n, "type");
-	//Node *classNode = Swig_methodclass(n);
-	//Node *module = Getattr(classNode, "module");
-	Node *module = Getattr(parent, "module");
-	Node *target = Swig_directormap(module, type);
-	if (target)
-	  unwrap = 1;
-      }
-      if (unwrap) {
+      // Unwrap return values that are director classes so that the original Python object is returned instead. 
+      if (!constructor && Swig_director_can_unwrap(n)) {
 	Wrapper_add_local(f, "director", "Swig::Director *director = 0");
 	Printf(f->code, "director = SWIG_DIRECTOR_CAST(%s);\n", Swig_cresult_name());
 	Append(f->code, "if (director) {\n");
@@ -3095,9 +3169,7 @@
       } else {
 	Printf(f->code, "%s\n", tm);
       }
-#else
-      Printf(f->code, "%s\n", tm);
-#endif
+
       Delete(tm);
     } else {
       Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s in function %s.\n", SwigType_str(d, 0), name);
@@ -3116,7 +3188,6 @@
     /* Look to see if there is any newfree cleanup code */
     if (GetFlag(n, "feature:new")) {
       if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
-	Replaceall(tm, "$source", Swig_cresult_name());
 	Printf(f->code, "%s\n", tm);
 	Delete(tm);
       }
@@ -3124,7 +3195,6 @@
 
     /* See if there is any return cleanup code */
     if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
-      Replaceall(tm, "$source", Swig_cresult_name());
       Printf(f->code, "%s\n", tm);
       Delete(tm);
     }
@@ -3153,6 +3223,9 @@
       Printv(f->code, "  return -1;\n", NIL);
     } else {
       if (GetFlag(n, "feature:python:maybecall")) {
+	Append(f->code, "  if (PyErr_Occurred() && !PyErr_ExceptionMatches(PyExc_TypeError)) {\n");
+	Append(f->code, "    return NULL;\n");
+	Append(f->code, "  }\n");
 	Append(f->code, "  PyErr_Clear();\n");
 	Append(f->code, "  Py_INCREF(Py_NotImplemented);\n");
 	Append(f->code, "  return Py_NotImplemented;\n");
@@ -3187,9 +3260,9 @@
       f = NewWrapper();
       if (funpack) {
 	// Note: funpack is currently always false for varargs
-	Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", Py_ssize_t nobjs, PyObject **swig_obj) {", NIL);
+	Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, Py_ssize_t nobjs, PyObject **swig_obj) {", NIL);
       } else {
-	Printv(f->def, linkage, wrap_return, wname, "(PyObject *", self_param, ", PyObject *args", builtin_kwargs, ") {", NIL);
+	Printv(f->def, linkage, wrap_return, wname, "(PyObject *self, PyObject *args", builtin_kwargs, ") {", NIL);
       }
       Wrapper_add_local(f, "resultobj", builtin_ctor ? "int resultobj" : "PyObject *resultobj");
       Wrapper_add_local(f, "varargs", "PyObject *varargs");
@@ -3207,10 +3280,10 @@
 	Printf(f->code, "  Py_XINCREF(swig_obj[i + %d]);\n", num_fixed_arguments);
 	Printf(f->code, "}\n");
       } else {
-	Printf(f->code, "newargs = PyTuple_GetSlice(args,0,%d);\n", num_fixed_arguments);
-	Printf(f->code, "varargs = PyTuple_GetSlice(args,%d,PyTuple_Size(args));\n", num_fixed_arguments);
+	Printf(f->code, "newargs = PyTuple_GetSlice(args, 0, %d);\n", num_fixed_arguments);
+	Printf(f->code, "varargs = PyTuple_GetSlice(args, %d, PyTuple_Size(args));\n", num_fixed_arguments);
       }
-      Printf(f->code, "resultobj = %s__varargs__(%s,newargs,varargs);\n", wname, builtin ? "self" : "NULL");
+      Printf(f->code, "resultobj = %s__varargs__(%s, newargs, varargs%s);\n", wname, builtin ? "self" : "NULL", strlen(builtin_kwargs) == 0 ? "" : ", kwargs");
       Append(f->code, "Py_XDECREF(newargs);\n");
       Append(f->code, "Py_XDECREF(varargs);\n");
       Append(f->code, "return resultobj;\n");
@@ -3218,18 +3291,20 @@
       Wrapper_print(f, f_wrappers);
     }
 
+    bool use_static_method = flat_static_method || !Swig_storage_isstatic_custom(n, "staticmemberfunctionHandler:storage");
     /* Now register the function with the interpreter.   */
     if (!Getattr(n, "sym:overloaded")) {
-      if (!builtin_self)
+      if (!builtin_self && (use_static_method || !builtin))
 	add_method(iname, wname, allow_kwargs, n, funpack, num_required, num_arguments);
 
       /* Create a shadow for this function (if enabled and not in a member function) */
-      if (!builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER))) {
+      if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER) && use_static_method) {
 	emitFunctionShadowHelper(n, in_class ? f_shadow_stubs : f_shadow, iname, allow_kwargs);
       }
+
     } else {
       if (!Getattr(n, "sym:nextSibling")) {
-	dispatchFunction(n, linkage, funpack, builtin_self, builtin_ctor, director_class);
+	dispatchFunction(n, linkage, funpack, builtin_self, builtin_ctor, director_class, use_static_method);
       }
     }
 
@@ -3300,7 +3375,7 @@
     if (in_class && builtin) {
       /* Handle operator overloads for builtin types */
       String *slot = Getattr(n, "feature:python:slot");
-      if (slot) {
+      if (slot && !isfriend) {
 	String *func_type = Getattr(n, "feature:python:slot:functype");
 	String *closure_decl = getClosure(func_type, wrapper_name, overname ? 0 : funpack);
 	String *feature_name = NewStringf("feature:python:%s", slot);
@@ -3382,15 +3457,14 @@
       Printf(f_init, "#endif\n");
       Printf(f_init, "\t }\n");
       Printf(f_init, "\t PyDict_SetItemString(md, \"%s\", globals);\n", global_name);
-      Printf(f_init, "\t Py_DECREF(globals);\n");
       if (builtin)
 	Printf(f_init, "\t SwigPyBuiltin_AddPublicSymbol(public_interface, \"%s\");\n", global_name);
       have_globals = 1;
-      if (!builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER))) {
+      if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER)) {
 	Printf(f_shadow_stubs, "%s = %s.%s\n", global_name, module, global_name);
       }
     }
-    int assignable = is_assignable(n);
+    int assignable = !is_immutable(n);
 
     if (!builtin && shadow && !assignable && !in_class)
       Printf(f_shadow_stubs, "%s = %s.%s\n", iname, global_name, iname);
@@ -3410,8 +3484,6 @@
       }
       Printf(setf->def, "SWIGINTERN int %s(PyObject *_val) {", varsetname);
       if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
-	Replaceall(tm, "$source", "_val");
-	Replaceall(tm, "$target", name);
 	Replaceall(tm, "$input", "_val");
 	if (Getattr(n, "tmap:varin:implicitconv")) {
 	  Replaceall(tm, "$implicitconv", get_implicitconv_flag(n));
@@ -3452,8 +3524,6 @@
       Append(getf->code, "  (void)self;\n");
     }
     if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
-      Replaceall(tm, "$source", name);
-      Replaceall(tm, "$target", "pyobj");
       Replaceall(tm, "$result", "pyobj");
       addfail = emit_action_code(n, getf->code, tm);
       Delete(tm);
@@ -3533,8 +3603,6 @@
     }
 
     if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) {
-      Replaceall(tm, "$source", value);
-      Replaceall(tm, "$target", name);
       Replaceall(tm, "$value", value);
       Printf(const_code, "%s,\n", tm);
       Delete(tm);
@@ -3549,10 +3617,8 @@
     }
 
     if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
-      Replaceall(tm, "$source", value);
-      Replaceall(tm, "$target", name);
       Replaceall(tm, "$value", value);
-      if (needs_swigconstant(n) && !builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER)) && (!in_class || !Getattr(n, "feature:python:callback"))) {
+      if (needs_swigconstant(n) && !builtin && shadow && !(shadow & PYSHADOW_MEMBER) && (!in_class || !Getattr(n, "feature:python:callback"))) {
 	// Generate `*_swigconstant()` method which registers the new constant.
 	//
 	// *_swigconstant methods are required for constants of class type.
@@ -3562,7 +3628,7 @@
 	// class type (the SWIG_init() is called before shadow classes are
 	// defined and registered).
         Printf(f_wrappers, "SWIGINTERN PyObject *%s_swigconstant(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {\n", iname);
-        Printf(f_wrappers, tab2 "PyObject *module;\n", tm);
+        Printf(f_wrappers, tab2 "PyObject *module;\n");
         Printf(f_wrappers, tab2 "PyObject *d;\n");
 	Printf(f_wrappers, tab2 "if (!SWIG_Python_UnpackTuple(args, \"swigconstant\", 1, 1, &module)) return NULL;\n");
         Printf(f_wrappers, tab2 "d = PyModule_GetDict(module);\n");
@@ -3590,7 +3656,7 @@
       return SWIG_NOWRAP;
     }
 
-    if (!builtin && (shadow) && (!(shadow & PYSHADOW_MEMBER))) {
+    if (!builtin && shadow && !(shadow & PYSHADOW_MEMBER)) {
       String *f_s;
       if (!in_class) {
 	f_s = f_shadow;
@@ -3825,11 +3891,7 @@
 	String *symname = Getattr(n, "sym:name");
 	String *mrename = Swig_name_disown(NSPACE_TODO, symname);	//Getattr(n, "name"));
 	Printv(f_shadow, tab4, "def __disown__(self):\n", NIL);
-#ifdef USE_THISOWN
-	Printv(f_shadow, tab8, "self.thisown = 0\n", NIL);
-#else
 	Printv(f_shadow, tab8, "self.this.disown()\n", NIL);
-#endif
 	Printv(f_shadow, tab8, module, ".", mrename, "(self)\n", NIL);
 	Printv(f_shadow, tab8, "return weakref.proxy(self)\n", NIL);
 	Delete(mrename);
@@ -3868,40 +3930,45 @@
    * classHandler()
    * ------------------------------------------------------------ */
 
-  String *add_explicit_scope(String *s) {
+  SwigType *add_explicit_scope(SwigType *s) {
     if (!Strstr(s, "::")) {
-      String *ss = NewStringf("::%s", s);
-      Delete(s);
-      s = ss;
+      return NewStringf("::%s", s);
     }
-    return s;
+    return Copy(s);
   }
 
   void builtin_pre_decl(Node *n) {
-    String *name = Getattr(n, "name");
-    String *rname = add_explicit_scope(SwigType_namestr(name));
-    String *mname = SwigType_manglestr(rname);
+    SwigType *name = Getattr(n, "name");
+    SwigType *sname = add_explicit_scope(name);
+    String *rname = SwigType_namestr(sname);
+    String *mname = SwigType_manglestr(sname);
 
     Printf(f_init, "\n/* type '%s' */\n", rname);
     Printf(f_init, "    builtin_pytype = (PyTypeObject *)&SwigPyBuiltin_%s_type;\n", mname);
     Printf(f_init, "    builtin_pytype->tp_dict = d = PyDict_New();\n");
 
+    Delete(sname);
     Delete(rname);
     Delete(mname);
   }
 
   void builtin_post_decl(File *f, Node *n) {
-    String *name = Getattr(n, "name");
-    String *pname = Copy(name);
+    SwigType *name = Getattr(n, "name");
+    SwigType *pname = Copy(name);
     SwigType_add_pointer(pname);
     String *symname = Getattr(n, "sym:name");
-    String *rname = add_explicit_scope(SwigType_namestr(name));
-    String *mname = SwigType_manglestr(rname);
+    SwigType *sname = add_explicit_scope(name);
+    String *rname = SwigType_namestr(sname);
+    String *mname = SwigType_manglestr(sname);
     String *pmname = SwigType_manglestr(pname);
     String *templ = NewStringf("SwigPyBuiltin_%s", mname);
     int funpack = fastunpack;
     static String *tp_new = NewString("PyType_GenericNew");
 
+    if (have_builtin_static_member_method_callback) {
+      Printf(f_init, "  SWIG_Python_FixMethods(SwigPyBuiltin_%s_methods, swig_const_table, swig_types, swig_type_initial);\n", mname);
+    }
+
     Printv(f_init, "  SwigPyBuiltin_SetMetaType(builtin_pytype, metatype);\n", NIL);
 
     // We can’t statically initialize a structure member with a function defined in another C module
@@ -3972,7 +4039,7 @@
       if (GetFlag(mgetset, "static")) {
 	Printf(f, "static PyGetSetDef %s_def = %s;\n", gspair, entry);
 	Printf(f_init, "static_getset = SwigPyStaticVar_new_getset(metatype, &%s_def);\n", gspair);
-	Printf(f_init, "PyDict_SetItemString(d, static_getset->d_getset->name, (PyObject *) static_getset);\n", memname);
+	Printf(f_init, "PyDict_SetItemString(d, static_getset->d_getset->name, (PyObject *) static_getset);\n");
 	Printf(f_init, "Py_DECREF(static_getset);\n");
       } else {
 	Printf(getset_def, "    %s,\n", entry);
@@ -3995,15 +4062,17 @@
       Printf(f, "  PyTuple_SET_ITEM(tuple, 0, other);\n");
       Printf(f, "  Py_XINCREF(other);\n");
     }
-    Iterator rich_iter = First(richcompare);
+    List *richcompare_list = SortedKeys(richcompare, 0);
+    Iterator rich_iter = First(richcompare_list);
     if (rich_iter.item) {
       Printf(f, "  switch (op) {\n");
       for (; rich_iter.item; rich_iter = Next(rich_iter))
-	Printf(f, "    case %s : result = %s(self, %s); break;\n", rich_iter.key, rich_iter.item, funpack ? "other" : "tuple");
+	Printf(f, "    case %s : result = %s(self, %s); break;\n", rich_iter.item, Getattr(richcompare, rich_iter.item), funpack ? "other" : "tuple");
       Printv(f, "    default : break;\n", NIL);
       Printf(f, "  }\n");
     }
-    Printv(f, "  if (!result) {\n", NIL);
+    Delete(richcompare_list);
+    Printv(f, "  if (!result && !PyErr_Occurred()) {\n", NIL);
     Printv(f, "    if (SwigPyObject_Check(self) && SwigPyObject_Check(other)) {\n", NIL);
     Printv(f, "      result = SwigPyObject_richcompare((SwigPyObject *)self, (SwigPyObject *)other, op);\n", NIL);
     Printv(f, "    } else {\n", NIL);
@@ -4066,7 +4135,11 @@
     printSlot(f, getSlot(n, "feature:python:tp_basicsize", tp_basicsize), "tp_basicsize");
     printSlot(f, getSlot(n, "feature:python:tp_itemsize"), "tp_itemsize");
     printSlot(f, getSlot(n, "feature:python:tp_dealloc", tp_dealloc_bad), "tp_dealloc", "destructor");
+    Printv(f, "#if PY_VERSION_HEX < 0x030800b4\n", NIL);
     printSlot(f, getSlot(n, "feature:python:tp_print"), "tp_print", "printfunc");
+    Printv(f, "#else\n", NIL);
+    printSlot(f, getSlot(n, "feature:python:tp_vectorcall_offset"), "tp_vectorcall_offset", "Py_ssize_t");
+    Printv(f, "#endif\n", NIL);
     printSlot(f, getSlot(n, "feature:python:tp_getattr"), "tp_getattr", "getattrfunc");
     printSlot(f, getSlot(n, "feature:python:tp_setattr"), "tp_setattr", "setattrfunc");
     Printv(f, "#if PY_VERSION_HEX >= 0x03000000\n", NIL);
@@ -4128,6 +4201,16 @@
     Printv(f, "#if PY_VERSION_HEX >= 0x03040000\n", NIL);
     printSlot(f, getSlot(n, "feature:python:tp_finalize"), "tp_finalize", "destructor");
     Printv(f, "#endif\n", NIL);
+    Printv(f, "#if PY_VERSION_HEX >= 0x03080000\n", NIL);
+    printSlot(f, getSlot(n, "feature:python:tp_vectorcall"), "tp_vectorcall", "vectorcallfunc");
+    Printv(f, "#endif\n", NIL);
+    Printv(f, "#if (PY_VERSION_HEX >= 0x03080000) && (PY_VERSION_HEX < 0x03090000)\n", NIL);
+    printSlot(f, getSlot(), "tp_print");
+    Printv(f, "#endif\n", NIL);
+    Printv(f, "#if PY_VERSION_HEX >= 0x030c0000\n", NIL);
+    printSlot(f, getSlot(n, "feature:python:tp_watched"), "tp_watched", "char");
+    Printv(f, "#endif\n", NIL);
+
     Printv(f, "#ifdef COUNT_ALLOCS\n", NIL);
     printSlot(f, getSlot(n, "feature:python:tp_allocs"), "tp_allocs", "Py_ssize_t");
     printSlot(f, getSlot(n, "feature:python:tp_frees"), "tp_frees", "Py_ssize_t");
@@ -4143,6 +4226,9 @@
     printSlot(f, getSlot(n, "feature:python:am_await"), "am_await", "unaryfunc");
     printSlot(f, getSlot(n, "feature:python:am_aiter"), "am_aiter", "unaryfunc");
     printSlot(f, getSlot(n, "feature:python:am_anext"), "am_anext", "unaryfunc");
+    Printv(f, "# if PY_VERSION_HEX >= 0x030a0000\n", NIL);
+    printSlot(f, getSlot(n, "feature:python:am_send"), "am_send", "sendfunc");
+    Printv(f, "# endif\n", NIL);
     Printf(f, "  },\n");
     Printv(f, "#endif\n", NIL);
 
@@ -4255,18 +4341,38 @@
     // struct _dictkeysobject *ht_cached_keys;
     printSlot(f, getSlot(n, "feature:python:ht_cached_keys"), "ht_cached_keys");
     Printv(f, "#endif\n", NIL);
+
+    // PyObject *ht_module;
+    Printv(f, "#if PY_VERSION_HEX >= 0x03090000\n", NIL);
+    printSlot(f, getSlot(n, "feature:python:ht_module"), "ht_module", "PyObject *");
+    Printv(f, "#endif\n", NIL);
+
+    // char *_ht_tpname;
+    Printv(f, "#if PY_VERSION_HEX >= 0x030b0000\n", NIL);
+    printSlot(f, getSlot(n, "feature:python:_ht_tpname"), "_ht_tpname", "char *");
+
+    // struct _specialization_cache _spec_cache;
+    Printf(f, "  {\n");
+    printSlot(f, getSlot(n, "feature:python:getitem"), "getitem", "PyObject *");
+    Printv(f, "#if PY_VERSION_HEX >= 0x030c0000\n", NIL);
+    printSlot(f, getSlot(n, "feature:python:getitem_version"), "getitem_version", "uint32_t");
+    Printv(f, "#endif\n", NIL);
+    Printf(f, "  }\n");
+    Printv(f, "#endif\n", NIL);
     Printf(f, "};\n\n");
 
     String *clientdata = NewString("");
     Printf(clientdata, "&%s_clientdata", templ);
     SwigType_remember_mangleddata(pmname, clientdata);
 
-    SwigType *smart = Swig_cparse_smartptr(n);
+    SwigType *smart = Getattr(n, "smart");
     if (smart) {
-      SwigType_add_pointer(smart);
-      String *smart_pmname = SwigType_manglestr(smart);
+      SwigType *psmart = Copy(smart);
+      SwigType_add_pointer(psmart);
+      String *smart_pmname = SwigType_manglestr(psmart);
       SwigType_remember_mangleddata(smart_pmname, clientdata);
       Delete(smart_pmname);
+      Delete(psmart);
     }
 
     String *clientdata_klass = NewString("0");
@@ -4291,10 +4397,10 @@
     Printv(f_init, "    d = md;\n", NIL);
 
     Delete(clientdata);
-    Delete(smart);
+    Delete(sname);
     Delete(rname);
-    Delete(pname);
     Delete(mname);
+    Delete(pname);
     Delete(pmname);
     Delete(templ);
     Delete(tp_flags);
@@ -4321,6 +4427,7 @@
       /* Create new strings for building up a wrapper function */
       have_constructor = 0;
       have_repr = 0;
+      have_builtin_static_member_method_callback = false;
 
       class_name = Getattr(n, "sym:name");
       real_classname = Getattr(n, "name");
@@ -4378,10 +4485,9 @@
 
       /* dealing with abstract base class */
       String *abcs = Getattr(n, "feature:python:abc");
-      if (py3 && abcs) {
-	if (Len(base_class)) {
+      if (abcs) {
+	if (Len(base_class) > 0)
 	  Printv(base_class, ", ", NIL);
-	}
 	Printv(base_class, abcs, NIL);
       }
 
@@ -4391,16 +4497,16 @@
 	  Setattr(n, "feature:python:tp_doc", ds);
 	  Delete(ds);
 	} else {
-	  String *name = Getattr(n, "name");
-	  String *rname = add_explicit_scope(SwigType_namestr(name));
+	  SwigType *name = Getattr(n, "name");
+	  SwigType *sname = add_explicit_scope(name);
+	  String *rname = SwigType_namestr(sname);
 	  Setattr(n, "feature:python:tp_doc", rname);
+	  Delete(sname);
 	  Delete(rname);
 	}
       } else {
-	if (!py3) {
-	  if (GetFlag(n, "feature:python:nondynamic"))
-	    Printv(f_shadow, "@_swig_add_metaclass(_SwigNonDynamicMeta)\n", NIL);
-	}
+	if (GetFlag(n, "feature:python:nondynamic"))
+	  Printv(f_shadow, "@_swig_add_metaclass(_SwigNonDynamicMeta)\n", NIL);
 	Printv(f_shadow, "class ", class_name, NIL);
 
 	if (Len(base_class)) {
@@ -4410,7 +4516,11 @@
 	    Printf(f_shadow, "(Exception)");
 	  } else {
 	    Printf(f_shadow, "(object");
-	    Printf(f_shadow, py3 && GetFlag(n, "feature:python:nondynamic") ? ", metaclass=_SwigNonDynamicMeta" : "", ")");
+	    /* Replace @_swig_add_metaclass above with below when support for python 2.7 is dropped
+	    if (GetFlag(n, "feature:python:nondynamic")) {
+	      Printf(f_shadow, ", metaclass=_SwigNonDynamicMeta");
+	    }
+	    */
 	    Printf(f_shadow, ")");
 	  }
 	}
@@ -4464,7 +4574,7 @@
     if (shadow) {
       /* Generate a class registration function */
       // Replace storing a pointer to underlying class with a smart pointer (intended for use with non-intrusive smart pointers)
-      SwigType *smart = Swig_cparse_smartptr(n);
+      SwigType *smart = Getattr(n, "smart");
       SwigType *ct = Copy(smart ? smart : real_classname);
       SwigType_add_pointer(ct);
       SwigType *realct = Copy(real_classname);
@@ -4486,7 +4596,6 @@
 	add_method(cname, cname, 0, 0, 1, 1, 1);
 	Delete(cname);
       }
-      Delete(smart);
       Delete(ct);
       Delete(realct);
       if (!have_constructor) {
@@ -4525,7 +4634,8 @@
       }
 
       shadow_indent = 0;
-      Printf(f_shadow_file, "%s\n", f_shadow_stubs);
+      if (Len(f_shadow_stubs) > 0)
+	Printf(f_shadow_file, "%s\n", f_shadow_stubs);
       Clear(f_shadow_stubs);
     }
 
@@ -4681,6 +4791,7 @@
       Swig_restore(n);
     }
 
+    int kw = (check_kwargs(n) && !Getattr(n, "sym:overloaded")) ? 1 : 0;
     if (builtin && in_class) {
       if ((GetFlagAttr(n, "feature:extend") || checkAttribute(n, "access", "public"))
 	  && !Getattr(class_members, symname)) {
@@ -4695,7 +4806,7 @@
 	else if (funpack && argcount == 1)
 	  Append(pyflags, "METH_O");
 	else
-	  Append(pyflags, "METH_VARARGS");
+	  Append(pyflags, kw ? "METH_VARARGS|METH_KEYWORDS" : "METH_VARARGS");
 	// Cast via void(*)(void) to suppress GCC -Wcast-function-type warning.
 	// Python should always call the function correctly, but the Python C
 	// API requires us to store it in function pointer of a different type.
@@ -4703,6 +4814,11 @@
 	  String *ds = cdocstring(n, AUTODOC_STATICFUNC);
 	  Printf(builtin_methods, "  { \"%s\", (PyCFunction)(void(*)(void))%s, %s, \"%s\" },\n", symname, wname, pyflags, ds);
 	  Delete(ds);
+	} else if (Getattr(n, "feature:callback")) {
+	  String *ds = NewStringf("swig_ptr: %s", Getattr(n, "feature:callback:name"));
+	  Printf(builtin_methods, "  { \"%s\", (PyCFunction)(void(*)(void))%s, %s, \"%s\" },\n", symname, wname, pyflags, ds);
+	  Delete(ds);
+	  have_builtin_static_member_method_callback = true;
 	} else {
 	  Printf(builtin_methods, "  { \"%s\", (PyCFunction)(void(*)(void))%s, %s, \"\" },\n", symname, wname, pyflags);
 	}
@@ -4721,7 +4837,6 @@
       String *staticfunc_name = NewString(fastproxy ? "_swig_new_static_method" : "staticmethod");
       bool fast = (fastproxy && !have_addtofunc(n)) || Getattr(n, "feature:callback");
       if (!fast || olddefs) {
-	int kw = (check_kwargs(n) && !Getattr(n, "sym:overloaded")) ? 1 : 0;
 	String *parms = make_pyParmList(n, false, false, kw);
 	String *callParms = make_pyParmList(n, false, true, kw);
 	Printv(f_shadow, "\n", tab4, "@staticmethod", NIL);
@@ -4818,6 +4933,7 @@
 	      String *classname = Swig_class_name(parent);
 	      String *rclassname = Swig_class_name(getCurrentClass());
 	      assert(rclassname);
+	      (void)rclassname;
 
 	      String *parms = make_pyParmList(n, true, false, allow_kwargs);
 	      /* Pass 'self' only if using director */
@@ -4865,9 +4981,6 @@
 	      if (have_pythonprepend(n))
 		Printv(f_shadow_stubs, indent_pythoncode(pythonprepend(n), tab4, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
 	      Printv(f_shadow_stubs, tab4, "val = ", funcCall(subfunc, callParms), "\n", NIL);
-#ifdef USE_THISOWN
-	      Printv(f_shadow_stubs, tab4, "val.thisown = 1\n", NIL);
-#endif
 	      if (have_pythonappend(n))
 		Printv(f_shadow_stubs, indent_pythoncode(pythonappend(n), tab4, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
 	      Printv(f_shadow_stubs, tab4, "return val\n", NIL);
@@ -4923,12 +5036,6 @@
 	  Printv(f_shadow, tab8, docstring(n, AUTODOC_DTOR, tab8), "\n", NIL);
 	if (have_pythonprepend(n))
 	  Printv(f_shadow, indent_pythoncode(pythonprepend(n), tab8, Getfile(n), Getline(n), "%pythonprepend or %feature(\"pythonprepend\")"), "\n", NIL);
-#ifdef USE_THISOWN
-	Printv(f_shadow, tab8, "try:\n", NIL);
-	Printv(f_shadow, tab8, tab4, "if self.thisown:", module, ".", Swig_name_destroy(NSPACE_TODO, symname), "(self)\n", NIL);
-	Printv(f_shadow, tab8, "except __builtin__.Exception: pass\n", NIL);
-#else
-#endif
 	if (have_pythonappend(n))
 	  Printv(f_shadow, indent_pythoncode(pythonappend(n), tab8, Getfile(n), Getline(n), "%pythonappend or %feature(\"pythonappend\")"), "\n", NIL);
 	Printv(f_shadow, tab8, "pass\n", NIL);
@@ -4955,13 +5062,18 @@
       String *mname = Swig_name_member(NSPACE_TODO, class_name, symname);
       String *setname = Swig_name_set(NSPACE_TODO, mname);
       String *getname = Swig_name_get(NSPACE_TODO, mname);
-      int assignable = is_assignable(n);
-      Printv(f_shadow, tab4, symname, " = property(", module, ".", getname, NIL);
+      int assignable = !is_immutable(n);
+      String *variable_annotation = variableAnnotation(n);
+      Printv(f_shadow, tab4, symname, variable_annotation, " = property(", module, ".", getname, NIL);
       if (assignable)
 	Printv(f_shadow, ", ", module, ".", setname, NIL);
-      if (have_docstring(n))
-	Printv(f_shadow, ", doc=", docstring(n, AUTODOC_VAR, tab4), NIL);
+      if (have_docstring(n)) {
+	String *s = docstring(n, AUTODOC_VAR, tab4);
+	if (Len(s))
+	  Printv(f_shadow, ", doc=", s, NIL);
+      }
       Printv(f_shadow, ")\n", NIL);
+      Delete(variable_annotation);
       Delete(mname);
       Delete(setname);
       Delete(getname);
@@ -5005,7 +5117,7 @@
 	add_method(getname, wrapgetname, 0);
 	Wrapper_print(f, f_wrappers);
 	DelWrapper(f);
-	int assignable = is_assignable(n);
+	int assignable = !is_immutable(n);
 	if (assignable) {
 	  int funpack = fastunpack;
 	  Wrapper *f = NewWrapper();
@@ -5026,8 +5138,11 @@
 	  Printv(f_shadow, tab4, symname, " = property(", module, ".", getname, NIL);
 	  if (assignable)
 	    Printv(f_shadow, ", ", module, ".", setname, NIL);
-	  if (have_docstring(n))
-	    Printv(f_shadow, ", doc=", docstring(n, AUTODOC_VAR, tab4), NIL);
+	  if (have_docstring(n)) {
+	    String *s = docstring(n, AUTODOC_VAR, tab4);
+	    if (Len(s))
+	      Printv(f_shadow, ", doc=", s, NIL);
+	  }
 	  Printv(f_shadow, ")\n", NIL);
 	}
 	String *getter = Getattr(n, "pybuiltin:getter");
@@ -5336,14 +5451,6 @@
 	continue;
       }
 
-      /* old style?  caused segfaults without the p!=0 check
-         in the for() condition, and seems dangerous in the
-         while loop as well.
-         while (Getattr(p, "tmap:ignore")) {
-         p = Getattr(p, "tmap:ignore:next");
-         }
-       */
-
       if (Getattr(p, "tmap:directorargout") != 0)
 	outputs++;
 
diff --git a/Source/Modules/r.cxx b/Source/Modules/r.cxx
index bb43dad..2b1a9b7 100644
--- a/Source/Modules/r.cxx
+++ b/Source/Modules/r.cxx
@@ -5,7 +5,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * r.cxx
  *
@@ -36,11 +36,6 @@
   if(Strncmp(b, "struct ", 7) == 0)
     Replace(b, "struct ", "", DOH_REPLACE_FIRST);
 
-  /* Printf(stdout, "<getRTypeName> %s,base = %s\n", t, b);
-     for(i = 0; i < Len(els); i++)
-     Printf(stdout, "%d) %s, ", i, Getitem(els,i));
-     Printf(stdout, "\n"); */
-
   for(i = 0; i < Len(els); i++) {
     String *el = Getitem(els, i);
     if(Strcmp(el, "p.") == 0 || Strncmp(el, "a(", 2) == 0) {
@@ -56,13 +51,6 @@
   Insert(tmp, 0, retName);
   return tmp;
 
-  /*
-    if(count)
-    return(b);
-
-    Delete(b);
-    return(NewString(""));
-  */
 }
 
 /* --------------------------------------------------------------
@@ -101,7 +89,6 @@
 static String * getRClassNameCopyStruct(String *retType, int addRef) {
   String *tmp = NewString("");
 
-#if 1
   List *l = SwigType_split(retType);
   int n = Len(l);
   if(!l || n == 0) {
@@ -127,24 +114,6 @@
     }
   }
 
-#else
-  char *retName = Char(SwigType_manglestr(retType));
-  if(!retName)
-    return(tmp);
-
-  if(addRef) {
-    while(retName && strlen(retName) > 1 &&
-	  strncmp(retName, "_p", 2) == 0)  {
-      retName += 2;
-      Printf(tmp, "Ref");
-    }
-  }
-
-  if(retName[0] == '_')
-    retName ++;
-  Insert(tmp, 0, retName);
-#endif
-
   return tmp;
 }
 
@@ -246,8 +215,7 @@
 
   int typedefHandler(Node *n);
 
-  static List *Swig_overload_rank(Node *n,
-	                          bool script_lang_wrapping);
+  static List *Swig_overload_rank(Node *n, bool script_lang_wrapping);
 
   int memberfunctionHandler(Node *n) {
     if (debugMode)
@@ -274,8 +242,8 @@
     return status;
   }
 
-  // Not used:
   String *runtimeCode();
+  void replaceSpecialVariables(String *method, String *tm, Parm *parm);
 
 protected:
   int addRegistrationRoutine(String *rname, int nargs);
@@ -285,12 +253,7 @@
   int generateCopyRoutines(Node *n);
   int DumpCode(Node *n);
 
-  int OutputMemberReferenceMethod(String *className, int isSet, List *el, File *out);
-  int OutputArrayMethod(String *className, List *el, File *out);
-  int OutputClassMemberTable(Hash *tb, File *out);
-  int OutputClassMethodsTable(File *out);
-  int OutputClassAccessInfo(Hash *tb, File *out);
-
+  int OutputMemberReferenceMethod(String *className, int isSet, List *memberList, List *nameList, List *typeList, File *out);
   int defineArrayAccessors(SwigType *type);
 
   void addNamespaceFunction(String *name) {
@@ -334,10 +297,14 @@
 
 
   void addAccessor(String *memberName, Wrapper *f,
-		   String *name, int isSet = -1);
+		   String *name, String *methodSetGet);
 
   static int getFunctionPointerNumArgs(Node *n, SwigType *tt);
 
+  // filtering of class member lists by function type. Used in constructing accessors
+  // are we allowed to use stl style functors to customise this?
+  List* filterMemberList(List *class_member_function_types, List *class_member_other, String *R_MEMBER, bool equal);
+
 protected:
   bool copyStruct;
   bool memoryProfile;
@@ -360,18 +327,25 @@
   String *s_namespace;
 
   // State variables that carry information across calls to functionWrapper()
-  // from  member accessors and class declarations.
+  // from member accessors and class declarations.
   String *opaqueClassDeclaration;
   int processing_variable;
   int processing_member_access_function;
   String *member_name;
   String *class_name;
 
+  String *R_MEMBER_NORMAL;
+  String *R_MEMBER_SET;
+  String *R_MEMBER_GET;
 
   int processing_class_member_function;
-  List *class_member_functions;
-  List *class_member_set_functions;
-
+  // Spread out the lists so that they are simpler to process
+  // by storing the type of the method (i.e. set, get or nothing)
+  // and having separate lists for name, membername and wrapper
+  List *class_member_function_types;
+  List *class_member_function_names;
+  List *class_member_function_membernames;
+  List *class_member_function_wrappernames;
   /* */
   Hash *ClassMemberTable;
   Hash *ClassMethodsTable;
@@ -429,9 +403,14 @@
   processing_member_access_function(0),
   member_name(0),
   class_name(0),
+  R_MEMBER_NORMAL(NewString("normal")),
+  R_MEMBER_SET(NewString("set")),
+  R_MEMBER_GET(NewString("get")),
   processing_class_member_function(0),
-  class_member_functions(0),
-  class_member_set_functions(0),
+  class_member_function_types(0),
+  class_member_function_names(0),
+  class_member_function_membernames(0),
+  class_member_function_wrappernames(0),
   ClassMemberTable(0),
   ClassMethodsTable(0),
   SClassDefs(0),
@@ -510,7 +489,7 @@
   SwigType *funcparams = SwigType_functionpointer_decompose(rettype);
   String *rtype = SwigType_str(rettype, 0);
 
-  //   ParmList *parms = Getattr(n, "parms");
+  // ParmList *parms = Getattr(n, "parms");
   // memory leak
   ParmList *parms = SwigType_function_parms(SwigType_del_pointer(Copy(t)), n);
 
@@ -654,7 +633,6 @@
     if(returnTM) {
       String *tm = returnTM;
       Replaceall(tm,"$input", "r_swig_cb_data->retValue");
-      Replaceall(tm,"$target", Swig_cresult_name());
       replaceRClass(tm, rettype);
       Replaceall(tm,"$owner", "0");
       Replaceall(tm,"$disown","0");
@@ -720,18 +698,6 @@
 }
 
 
-
-#if 0
-int R::cDeclaration(Node *n) {
-  SwigType *t = Getattr(n, "type");
-  SwigType *name = Getattr(n, "name");
-  if (debugMode)
-    Printf(stdout, "cDeclaration (%s): %s\n", name, SwigType_lstr(t, 0));
-  return Language::cDeclaration(n);
-}
-#endif
-
-
 /* -------------------------------------------------------------
  *  Method from Language that is called to start the entire
  *  processing off, i.e. the generation of the code.
@@ -755,6 +721,8 @@
     Swig_register_filebyname("snamespace", s_namespace);
     Printf(s_namespace, "useDynLib(%s)\n", DllName);
   }
+  // Register the naming functions
+  Swig_name_register("wrapper", "R_swig_%f");
 
   /* Associate the different streams with names so that they can be used in %insert directives by the
      typemap code. */
@@ -771,8 +739,7 @@
 
   Swig_banner(f_begin);
 
-  Printf(f_runtime, "\n\n#ifndef SWIGR\n#define SWIGR\n#endif\n\n");
-
+  Swig_obligatory_macros(f_runtime, "R");
 
   Swig_banner_target_lang(s_init, "#");
   outputCommandLineArguments(s_init);
@@ -836,7 +803,7 @@
   File *scode = NewFile(output_filename, "w", SWIG_output_files());
   if (!scode) {
     FileErrorDisplay(output_filename);
-    SWIG_exit(EXIT_FAILURE);
+    Exit(EXIT_FAILURE);
   }
   Delete(output_filename);
 
@@ -851,7 +818,7 @@
   File *runtime = NewFile(outfile,"w", SWIG_output_files());
   if (!runtime) {
     FileErrorDisplay(outfile);
-    SWIG_exit(EXIT_FAILURE);
+    Exit(EXIT_FAILURE);
   }
 
   Printf(runtime, "%s", f_begin);
@@ -868,7 +835,7 @@
     File *ns = NewFile(output_filename, "w", SWIG_output_files());
     if (!ns) {
       FileErrorDisplay(output_filename);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
     Delete(output_filename);
 
@@ -888,7 +855,33 @@
 }
 
 
+List *R::filterMemberList(List *class_member_types, 
+                          List *class_member_other, 
+                          String *R_MEMBER, bool equal) {
+  // filters class_member_other based on whether corresponding elements of
+  // class_member_function_types are equal or notequal to R_MEMBER
+  List *CM = NewList();
+  Iterator ftype, other;
 
+  for (ftype = First(class_member_types), other = First(class_member_other);
+       ftype.item; 
+       ftype=Next(ftype), other=Next(other)) {
+    // verbose, clean up later if the overall structure works
+    if (equal) {
+      if (ftype.item == R_MEMBER) {
+        Append(CM, other.item);
+      }
+    } else {
+      if (ftype.item != R_MEMBER) {
+        Append(CM, other.item);
+      }
+    }
+  }
+  return(CM);
+}
+
+# if 0
+// not called
 /* -------------------------------------------------------------
  * We may need to do more.... so this is left as a
  * stub for the moment.
@@ -945,7 +938,7 @@
  * The entries are indexed by <class name>_set and
  * <class_name>_get. Each entry is a List *.
 
- * out - the stram where the code is to be written. This is the S
+ * out - the stream where the code is to be written. This is the S
  * code stream as we generate only S code here.
  * --------------------------------------------------------------*/
 
@@ -975,9 +968,6 @@
       isSet = strcmp(ptr, "_set") == 0;
     }
 
-    //        OutputArrayMethod(className, el, out);  
-    OutputMemberReferenceMethod(className, isSet, el, out);
-
     if(outputNamespaceInfo)
       Printf(s_namespace, "\"%s\"%s", className, i < n-1 ? "," : "");
   }
@@ -988,6 +978,8 @@
   return n;
 }
 
+// end not used
+#endif
 /* --------------------------------------------------------------
  * Write the methods for $ or $<- for accessing a member field in an
  * struct or union (or class).
@@ -1000,9 +992,10 @@
  * out - the stream where we write the code.
  * --------------------------------------------------------------*/
 
-int R::OutputMemberReferenceMethod(String *className, int isSet,
-				   List *el, File *out) {
-  int numMems = Len(el), j;
+int R::OutputMemberReferenceMethod(String *className, int isSet,  
+				   List *memberList, List *nameList,
+				   List *typeList, File *out) {
+  int numMems = Len(memberList), j;
   int varaccessor = 0;
   if (numMems == 0)
     return SWIG_OK;
@@ -1017,13 +1010,12 @@
 
   Node *itemList = NewHash();
   bool has_prev = false;
-  for(j = 0; j < numMems; j+=3) {
-    String *item = Getitem(el, j);
-    String *dup = Getitem(el, j + 1);
-    char *ptr = Char(dup);
-    ptr = &ptr[Len(dup) - 3];
+  for(j = 0; j < numMems; j++) {
+    String *item = Getitem(memberList, j);
+    String *dup = Getitem(nameList, j);
+    String *setgetmethod = Getitem(typeList, j);
 
-    if (!strcmp(ptr, "get"))
+    if (setgetmethod == R_MEMBER_GET)
       varaccessor++;
 
     if (Getattr(itemList, item))
@@ -1053,30 +1045,20 @@
 
   if (!isSet && varaccessor > 0) {
     Printf(f->code, "%svaccessors = c(", tab8);
-    int first = 1;
-    for(j = 0; j < numMems; j+=3) {
-      String *item = Getitem(el, j);
-      String *dup = Getitem(el, j + 1);
-      char *ptr = Char(dup);
-      ptr = &ptr[Len(dup) - 3];
+    bool first = true;
+    for(j = 0; j < numMems; j++) {
+      String *item = Getitem(memberList, j);
+      String *setgetmethod = Getitem(typeList, j);
 
-      if (!strcmp(ptr, "get")) {
+      // Check the type here instead of the name
+      if (setgetmethod == R_MEMBER_GET) {
 	Printf(f->code, "%s'%s'", first ? "" : ", ", item);
-	first = 0;
+	first = false;
       }
     }
     Printf(f->code, ");\n");
   }
 
-
-  /*    Printv(f->code, tab8,
-	"idx = pmatch(name, names(accessorFuns))\n",
-	tab8,
-	"if(is.na(idx)) {\n",
-	tab8, tab4,
-	"stop(\"No ", (isSet ? "modifiable" : "accessible"), " field named \", name, \" in ", className,
-	": fields are \", paste(names(accessorFuns), sep = \", \")",
-	")", "\n}\n", NIL); */
   Printv(f->code, ";", tab8,
 	 "idx = pmatch(name, names(accessorFuns));\n",
 	 tab8,
@@ -1098,8 +1080,8 @@
   }
   Printf(f->code, "}\n");
 
-
-  Printf(out, "# Start of accessor method for %s\n", className);
+  String *classname_str = SwigType_namestr(className);
+  Printf(out, "# Start of accessor method for %s\n", classname_str);
   Printf(out, "setMethod('$%s', '_p%s', ",
 	 isSet ? "<-" : "",
 	 getRClassName(className));
@@ -1115,55 +1097,16 @@
     Printf(out, ");\n");
   }
 
+  Printf(out, "# end of accessor method for %s\n", classname_str);
+
+  Delete(classname_str);
   DelWrapper(attr);
   DelWrapper(f);
 
-  Printf(out, "# end of accessor method for %s\n", className);
-
   return SWIG_OK;
 }
 
 /* -------------------------------------------------------------
- * Write the methods for [ or [<- for accessing a member field in an
- * struct or union (or class).
- * className - the name of the struct or union (e.g. Bar for struct Bar)
- * el - a list of length  2 * # accessible member elements  + 1.
- *     The first element is the name of the class.
- *     The other pairs are  member name and the name of the R function to access it.
- * out - the stream where we write the code.
- * --------------------------------------------------------------*/
-
-int R::OutputArrayMethod(String *className, List *el, File *out) {
-  int numMems = Len(el), j;
-
-  if(!el || numMems == 0)
-    return(0);
-
-  Printf(out, "# start of array methods for %s\n", className);
-  for(j = 0; j < numMems; j+=3) {
-    String *item = Getitem(el, j);
-    String *dup = Getitem(el, j + 1);
-    if (!Strcmp(item, "__getitem__")) {
-      Printf(out,
-	     "setMethod('[', '_p%s', function(x, i, j, ..., drop =TRUE) ",
-	     getRClassName(className));
-      Printf(out, "  sapply(i, function (n)  %s(x, as.integer(n-1))))\n\n", dup);
-    }
-    if (!Strcmp(item, "__setitem__")) {
-      Printf(out, "setMethod('[<-', '_p%s', function(x, i, j, ..., value)",
-	     getRClassName(className));
-      Printf(out, "  sapply(1:length(i), function(n) %s(x, as.integer(i[n]-1), value[n])))\n\n", dup);
-    }
-
-  }
-
-  Printf(out, "# end of array methods for %s\n", className);
-
-  return SWIG_OK;
-}
-
-
-/* -------------------------------------------------------------
  * Called when a enumeration is to be processed.
  * We want to call the R function defineEnumeration().
  * tdname is the typedef of the enumeration, i.e. giving its name.
@@ -1207,7 +1150,6 @@
     Printf(enum_def_calls, "defineEnumeration(\"%s\",\n .values=c(%s))\n\n", ename, enum_values);
     Delete(enum_values);
     Delete(ename);
-    //Delete(symname);
   }
   return SWIG_OK;
 }
@@ -1335,31 +1277,21 @@
  * --------------------------------------------------------------*/
 
 void R::addAccessor(String *memberName, Wrapper *wrapper, String *name,
-		    int isSet) {
-  if(isSet < 0) {
-    int n = Len(name);
-    char *ptr = Char(name);
-    if (n>4) {
-      isSet = Strcmp(NewString(&ptr[n-4]), "_set") == 0;
-    }
+		    String *methodSetGet) {
+
+  if (!class_member_function_names) {
+    class_member_function_names = NewList();
+    class_member_function_membernames = NewList();
+    class_member_function_wrappernames = NewList();
+    class_member_function_types = NewList();
   }
-
-  List *l = isSet ? class_member_set_functions : class_member_functions;
-
-  if(!l) {
-    l = NewList();
-    if(isSet)
-      class_member_set_functions = l;
-    else
-      class_member_functions = l;
-  }
-
-  Append(l, memberName);
-  Append(l, name);
-
+  Append(class_member_function_types, methodSetGet);
+  Append(class_member_function_names, name);
+  Append(class_member_function_membernames, memberName);
+  
   String *tmp = NewString("");
   Wrapper_print(wrapper, tmp);
-  Append(l, tmp);
+  Append(class_member_function_wrappernames, tmp);
   // if we could put the wrapper in directly:       Append(l, Copy(sfun));
   if (debugMode)
     Printf(stdout, "Adding accessor: %s (%s) => %s\n", memberName, name, tmp);
@@ -1367,13 +1299,14 @@
 
 #define MAX_OVERLOAD 256
 
+namespace {
 struct Overloaded {
   Node      *n;          /* Node                               */
   int        argc;       /* Argument count                     */
   ParmList  *parms;      /* Parameters used for overload check */
   int        error;      /* Ambiguity error                    */
 };
-
+}
 
 List * R::Swig_overload_rank(Node *n,
 	                     bool script_lang_wrapping) {
@@ -1390,11 +1323,6 @@
       c = Getattr(c,"sym:nextSibling");
       continue;
     }
-    /*    if (SmartPointer && Getattr(c,"cplus:staticbase")) {
-	  c = Getattr(c,"sym:nextSibling");
-	  continue;
-	  } */
-
     /* Make a list of all the declarations (methods) that are overloaded with
      * this one particular method name */
 
@@ -1612,8 +1540,6 @@
       if (nodes[i].error)
 	Setattr(nodes[i].n, "overload:ignore", "1");
       Append(result,nodes[i].n);
-      //      Printf(stdout,"[ %d ] %s\n", i, ParmList_errorstr(nodes[i].parms));
-      //      Swig_print_node(nodes[i].n);
     }
   }
   return result;
@@ -1640,7 +1566,8 @@
   Printv(f->code,
 	 "argtypes <- mapply(class, list(...));\n",
 	 "argv <- list(...);\n",
-	 "argc <- length(argtypes);\n", NIL );
+	 "argc <- length(argtypes);\n",
+	 "f <- NULL;\n", NIL);
 
   Printf(f->code, "# dispatch functions %d\n", nfunc);
   int cur_args = -1;
@@ -1668,52 +1595,38 @@
 	first_compare = false;
       }
       Printv(f->code, "if (", NIL);
-      for (p =pi, j = 0 ; j < num_arguments ; j++) {
+      for (p = pi, j = 0 ; j < num_arguments ; j++) {
+	SwigType *pt = Getattr(p, "type");
 	if (debugMode) {
 	  Swig_print_node(p);
 	}
 	String *tm = Swig_typemap_lookup("rtype", p, "", 0);
-	if(tm) {
-	  replaceRClass(tm, Getattr(p, "type"));
+	if (tm) {
+	  replaceRClass(tm, pt);
 	}
 
-	String *tmcheck = Swig_typemap_lookup("rtypecheck", p, "", 0);
+	/* Check if type have a %typemap(rtypecheck) */
+	String *tmcheck = Getattr(p,"tmap:rtypecheck");
 	if (tmcheck) {
-	  String *tmp = NewString("");
-	  Printf(tmp, "argv[[%d]]", j+1);
-	  Replaceall(tmcheck, "$arg", tmp);
-	  Printf(tmp, "argtype[%d]", j+1);
-	  Replaceall(tmcheck, "$argtype", tmp);
-	  if (tm) {
-	    Replaceall(tmcheck, "$rtype", tm);
-	  }
+	  tmcheck = Copy(tmcheck);
+	  String *tmp_argtype = NewStringf("argtypes[%d]", j+1);
+	  Replaceall(tmcheck, "$argtype", tmp_argtype);
+	  String *tmp_arg = NewStringf("argv[[%d]]", j+1);
+	  Replaceall(tmcheck, "$arg", tmp_arg);
+	  replaceRClass(tmcheck, pt);
 	  if (debugMode) {
 	    Printf(stdout, "<rtypecheck>%s\n", tmcheck);
 	  }
-	  Printf(f->code, "%s(%s)",
-		 j == 0 ? "" : " && ",
-		 tmcheck);
-	  p = Getattr(p, "tmap:in:next");
-	  continue;
-	}
-	// Below should be migrated into rtypecheck typemaps
-	if (tm) {
-	  Printf(f->code, "%s", j == 0 ? "" : " && ");
-	  if (Strcmp(tm, "numeric") == 0) {
-	    Printf(f->code, "is.numeric(argv[[%d]])", j+1);
-	  } else if (Strcmp(tm, "integer") == 0) {
-	    Printf(f->code, "(is.integer(argv[[%d]]) || is.numeric(argv[[%d]]))", j+1, j+1);
-	  } else if (Strcmp(tm, "character") == 0) {
-	    Printf(f->code, "is.character(argv[[%d]])", j+1);
+	  if (num_arguments == 1) {
+	    Printf(f->code, "%s", tmcheck);
 	  } else {
-	    if (SwigType_ispointer(Getattr(p, "type")))
-	      Printf(f->code, "(extends(argtypes[%d], '%s') || is.null(argv[[%d]]))", j+1, tm, j+1);
-	    else
-	      Printf(f->code, "extends(argtypes[%d], '%s')", j+1, tm);
+	    Printf(f->code, "%s(%s)", j == 0 ? "" : " && ", tmcheck);
 	  }
-	}
-	if (!SwigType_ispointer(Getattr(p, "type"))) {
-	  Printf(f->code, " && length(argv[[%d]]) == 1", j+1);
+	  Delete(tmcheck);
+	  Delete(tmp_arg);
+	  Delete(tmp_argtype);
+	} else {
+	  Swig_warning(WARN_R_TYPEMAP_RTYPECHECK_UNDEF, input_file, line_number, "No rtypecheck typemap defined for %s\n", SwigType_str(pt, 0));
 	}
 	p = Getattr(p, "tmap:in:next");
       }
@@ -1723,11 +1636,12 @@
     }
   }
   if (cur_args != -1) {
-    Printf(f->code, "} else {\n"
-	   "stop(\"cannot find overloaded function for %s with argtypes (\","
-	   "toString(argtypes),\")\");\n"
-	   "}", sfname);
+    Printf(f->code, "};\n");
   }
+  Printf(f->code, "if (is.null(f)) {\n"
+      "stop(\"cannot find overloaded function for %s with argtypes (\","
+      "toString(argtypes),\")\");\n"
+      "}", sfname);
   Printv(f->code, ";\nf(...)", NIL);
   Printv(f->code, ";\n}", NIL);
   Wrapper_print(f, sfile);
@@ -1815,14 +1729,9 @@
     /* Add the name of this member to a list for this class_name.
        We will dump all these at the end. */
 
-    int n = Len(iname);
-    char *ptr = Char(iname);
-    bool isSet(0);
-    if (n > 4) isSet = Strcmp(NewString(&ptr[n-4]), "_set") == 0;
+    bool isSet = GetFlag(n, "memberset") ? true : false;
 
-
-    String *tmp = NewString("");
-    Printf(tmp, "%s_%s", class_name, isSet ? "set" : "get");
+    String *tmp = NewString(isSet ? Swig_name_set(NSPACE_TODO, class_name) : Swig_name_get(NSPACE_TODO, class_name));
 
     List *memList = Getattr(ClassMemberTable, tmp);
     if(!memList) {
@@ -1839,7 +1748,7 @@
   int nargs;
 
   String *wname = Swig_name_wrapper(iname);
-  Replace(wname, "_wrap", "R_swig", DOH_REPLACE_FIRST);
+
   if(overname)
     Append(wname, overname);
   Setattr(n,"wrap:name", wname);
@@ -1859,11 +1768,6 @@
   if(!isVoidReturnType)
     addCopyParam = addCopyParameter(rtype);
 
-
-  // Can we get the nodeType() of the type node! and see if it is a struct.
-  //    int addCopyParam = SwigType_isclass(rtype);
-
-  //    if(addCopyParam)
   if (debugMode)
     Printf(stdout, "Adding a .copy argument to %s for %s = %s\n",
 	   iname, type, addCopyParam ? "yes" : "no");
@@ -1887,6 +1791,7 @@
   Swig_typemap_attach_parms("scoercein", l, f);
   Swig_typemap_attach_parms("scoerceout", l, f);
   Swig_typemap_attach_parms("scheck", l, f);
+  Swig_typemap_attach_parms("rtypecheck", l, f);
 
   emit_parameter_variables(l, f);
   emit_attach_parmmaps(l,f);
@@ -1916,27 +1821,20 @@
     int nargs = -1;
     String *funcptr_name = processType(tt, p, &nargs);
 
-    //      SwigType *tp = Getattr(p, "type");
-    String   *name  = Getattr(p,"name");
-    String   *lname  = Getattr(p,"lname");
+    String *name = makeParameterName(n, p, i+1, false);
+    String *lname = Getattr(p, "lname");
 
-    // R keyword renaming
     if (name) {
-      if (Swig_name_warning(p, 0, name, 0)) {
-	name = 0;
-      } else {
-	/* If we have a :: in the parameter name because we are accessing a static member of a class, say, then
-	   we need to remove that prefix. */
-	while (Strstr(name, "::")) {
-	  //XXX need to free.
-	  name = NewStringf("%s", Strchr(name, ':') + 2);
-	  if (debugMode)
-	    Printf(stdout, "+++  parameter name with :: in it %s\n", name);
-	}
+      /* If we have a :: in the parameter name because we are accessing a static member of a class, say, then
+	 we need to remove that prefix. */
+      while (Strstr(name, "::")) {
+	String *oldname = name;
+	name = NewStringf("%s", Strchr(name, ':') + 2);
+	if (debugMode)
+	  Printf(stdout, "+++  parameter name with :: in it %s\n", name);
+	Delete(oldname);
       }
     }
-    if (!name || Len(name) == 0)
-      name = NewStringf("s_arg%d", i+1);
 
     name = replaceInitialDash(name);
 
@@ -1978,7 +1876,7 @@
 	       name, " = getNativeSymbolInfo(", name, ");",
 	       "\n};\n",
 	       "if(is(", name, ", \"NativeSymbolInfo\")) {\n",
-	       name, " = ", name, "$address", ";\n}\n",
+	       name, " = ", name, "$address", ";\n};\n",
 	       "if(is(", name, ", \"ExternalReference\")) {\n",
 	       name, " = ", name, "@ref;\n}\n",
 	       "}; \n",
@@ -1992,8 +1890,6 @@
 
     if ((tm = Getattr(p,"tmap:scheck"))) {
 
-      Replaceall(tm,"$target", lname);
-      Replaceall(tm,"$source", name);
       Replaceall(tm,"$input", name);
       replaceRClass(tm, Getattr(p, "type"));
       Printf(sfun->code,"%s\n",tm);
@@ -2004,8 +1900,6 @@
     curP = p;
     if ((tm = Getattr(p,"tmap:in"))) {
 
-      Replaceall(tm,"$target", lname);
-      Replaceall(tm,"$source", name);
       Replaceall(tm,"$input", name);
 
       if (Getattr(p,"wrap:disown") || (Getattr(p,"tmap:in:disown"))) {
@@ -2057,6 +1951,13 @@
   }
 
   Printv(f->def, ")\n{\n", NIL);
+  // SWIG_fail in R leads to a call to Rf_error() which calls longjmp()
+  // which means the destructors of any live function-local C++ objects won't
+  // get run.  To avoid this happening, we wrap almost everything in the
+  // function in a block, and end that right before Rf_error() at which
+  // point those destructors will get called.
+  if (CPlusPlus) Append(f->def, "{\n");
+
   Printv(sfun->def, ")\n{\n", NIL);
 
 
@@ -2064,8 +1965,9 @@
   String *cleanup = NewString("");
   for (p = l; p;) {
     if ((tm = Getattr(p, "tmap:freearg"))) {
-      Replaceall(tm, "$source", Getattr(p, "lname"));
-      Printv(cleanup, tm, "\n", NIL);
+      if (tm && (Len(tm) != 0)) {
+        Printv(cleanup, tm, "\n", NIL);
+      }
       p = Getattr(p, "tmap:freearg:next");
     } else {
       p = nextSibling(p);
@@ -2079,7 +1981,6 @@
       //       String *lname =  Getattr(p, "lname");
       numOutArgs++;
       String *pos = NewStringf("%d", numOutArgs);
-      Replaceall(tm,"$source", Getattr(p, "lname"));
       Replaceall(tm,"$result", "r_ans");
       Replaceall(tm,"$n", pos); // The position into which to store the answer.
       Replaceall(tm,"$arg", Getattr(p, "emit:input"));
@@ -2112,18 +2013,7 @@
       Replaceall(tm,"$owner", "0");
     }
 
-#if 0
-    if(addCopyParam) {
-      Printf(f->code, "if(LOGICAL(s_swig_copy)[0]) {\n");
-      Printf(f->code, "/* Deal with returning a reference. */\nr_ans = R_NilValue;\n");
-      Printf(f->code, "}\n else {\n");
-    }
-#endif
     Printf(f->code, "%s\n", tm);
-#if 0
-    if(addCopyParam)
-      Printf(f->code, "}\n"); /* end of if(s_swig_copy) ... else { ... } */
-#endif
 
   } else {
     Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number,
@@ -2157,20 +2047,20 @@
   }
 
   /* Output cleanup code */
-  Printv(f->code, cleanup, NIL);
-  Delete(cleanup);
+  int need_cleanup = Len(cleanup) != 0;
+  if (need_cleanup) {
+    Printv(f->code, cleanup, NIL);
+  }
 
   /* Look to see if there is any newfree cleanup code */
   if (GetFlag(n, "feature:new")) {
     if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
-      Replaceall(tm, "$source", Swig_cresult_name());	/* deprecated */
       Printf(f->code, "%s\n", tm);
     }
   }
 
   /* See if there is any return cleanup code */
   if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
-    Replaceall(tm, "$source", Swig_cresult_name());
     Printf(f->code, "%s\n", tm);
     Delete(tm);
   }
@@ -2179,17 +2069,7 @@
 
   /*If the user gave us something to convert the result in  */
   if ((tm = Swig_typemap_lookup("scoerceout", n, Swig_cresult_name(), sfun))) {
-    Replaceall(tm,"$source","ans");
     Replaceall(tm,"$result","ans");
-    if (constructor) {
-      Node * parent = Getattr(n, "parentNode");
-      String * smartname = Getattr(parent, "feature:smartptr");
-      if (smartname) {
-	smartname = getRClassName(smartname, 1, 1);
-	Replaceall(tm, "$R_class", smartname);
-	Delete(smartname);
-      }
-    }
     if (debugMode) {
       Printf(stdout, "Calling replace B: %s, %s, %s\n", Getattr(n, "type"), Getattr(n, "sym:name"), getNSpace());
     }
@@ -2207,7 +2087,7 @@
 	{
 	  String *finalizer = NewString(iname);
 	  Replace(finalizer, "new_", "", DOH_REPLACE_FIRST);
-	  Printf(sfun->code, "reg.finalizer(ans@ref, delete_%s)\n", finalizer);
+	  Printf(sfun->code, "reg.finalizer(ans@ref, delete_%s);\n", finalizer);
 	}
       Printf(sfun->code, "ans\n");
     }
@@ -2215,7 +2095,19 @@
   if (destructor)
     Printv(f->code, "R_ClearExternalPtr(self);\n", NIL);
 
-  Printv(f->code, "return r_ans;\n}\n", NIL);
+  Printv(f->code, "return r_ans;\n", NIL);
+  
+  /* Error handling code */
+  Printv(f->code, "fail: SWIGUNUSED;\n", NIL);
+  if (need_cleanup) {
+    Printv(f->code, cleanup, NIL);
+  }
+  if (CPlusPlus) Append(f->code, "}\n");
+  Printv(f->code, "  Rf_error(\"%s %s\", SWIG_ErrorType(SWIG_lasterror_code), SWIG_lasterror_msg);\n", NIL);
+  Printv(f->code, "  return R_NilValue;\n", NIL);
+  Delete(cleanup);
+  
+  Printv(f->code, "}\n", NIL);
   Printv(sfun->code, "\n}", NIL);
 
   /* Substitute the function name */
@@ -2261,7 +2153,13 @@
      Would like to be able to do this so that we can potentially insert
   */
   if(processing_member_access_function || processing_class_member_function) {
-    addAccessor(member_name, sfun, iname);
+    String *method_type = R_MEMBER_NORMAL;
+    if (GetFlag(n, "memberset")) {
+      method_type = R_MEMBER_SET;
+    } else if (GetFlag(n, "memberget")) {
+      method_type = R_MEMBER_GET;
+    }
+    addAccessor(member_name, sfun, iname, method_type);
   }
 
   if (Getattr(n, "sym:overloaded") &&
@@ -2369,7 +2267,6 @@
 
 void R::registerClass(Node *n) {
   String *name = Getattr(n, "name");
-  String *kind = Getattr(n, "kind");
 
   if (debugMode)
     Swig_print_node(n);
@@ -2378,7 +2275,7 @@
     Setattr(SClassDefs, sname, sname);
     String *base;
 
-    if(Strcmp(kind, "class") == 0) {
+    if (CPlusPlus && (Strcmp(nodeType(n), "class") == 0)) {
       base = NewString("");
       List *l = Getattr(n, "bases");
       if(Len(l)) {
@@ -2398,31 +2295,6 @@
 
     Printf(s_classes, "setClass('%s', contains = %s)\n", sname, base);
     Delete(base);
-    String *smartptr = Getattr(n, "feature:smartptr");
-    if (smartptr) {
-      List *l = Getattr(n, "bases");
-      SwigType *spt = Swig_cparse_type(smartptr);
-      String *smart = SwigType_typedef_resolve_all(spt);
-      String *smart_rname = SwigType_manglestr(smart);
-      Printf(s_classes, "setClass('_p%s', contains = c('%s'", smart_rname, sname);
-      Delete(spt);
-      Delete(smart);
-      Delete(smart_rname);
-      for(int i = 0; i < Len(l); i++) {
-	Node * b = Getitem(l, i);
-	smartptr = Getattr(b, "feature:smartptr");
-	if (smartptr) {
-	  spt = Swig_cparse_type(smartptr);
-	  smart = SwigType_typedef_resolve_all(spt);
-	  smart_rname = SwigType_manglestr(smart);
-	  Printf(s_classes, ", '_p%s'", smart_rname);
-	  Delete(spt);
-	  Delete(smart);
-	  Delete(smart_rname);
-	}
-      }
-      Printf(s_classes, "))\n");
-    }
   }
 }
 
@@ -2455,20 +2327,49 @@
   opaqueClassDeclaration = NULL;
 
 
-  // OutputArrayMethod(name, class_member_functions, sfile);
-  if (class_member_functions)
-    OutputMemberReferenceMethod(name, 0, class_member_functions, sfile);
-  if (class_member_set_functions)
-    OutputMemberReferenceMethod(name, 1, class_member_set_functions, sfile);
+  if (class_member_function_types) {
 
-  if(class_member_functions) {
-    Delete(class_member_functions);
-    class_member_functions = NULL;
-  }
-  if(class_member_set_functions) {
-    Delete(class_member_set_functions);
-    class_member_set_functions = NULL;
-  }
+    // collect the "set" methods
+    List *class_set_membernames   = filterMemberList(class_member_function_types, 
+                                                     class_member_function_membernames, R_MEMBER_SET, true);
+    List *class_set_functionnames = filterMemberList(class_member_function_types, 
+                                                     class_member_function_names, R_MEMBER_SET, true);
+    // this one isn't used - collecting to keep code simpler
+    List *class_set_functiontypes = filterMemberList(class_member_function_types, 
+                                                     class_member_function_types, R_MEMBER_SET, true);
+
+    // collect the others
+    List *class_other_membernames   = filterMemberList(class_member_function_types, 
+                                                       class_member_function_membernames, R_MEMBER_SET, false);
+    List *class_other_functionnames = filterMemberList(class_member_function_types, 
+                                                       class_member_function_names, R_MEMBER_SET, false);
+    List *class_other_functiontypes = filterMemberList(class_member_function_types, 
+                                                       class_member_function_types, R_MEMBER_SET, false);
+
+    if (Len(class_other_membernames) > 0) {
+      OutputMemberReferenceMethod(name, 0, class_other_membernames, class_other_functionnames, class_other_functiontypes, sfile);
+    }
+    if (Len(class_set_membernames) > 0) {
+      OutputMemberReferenceMethod(name, 1, class_set_membernames, class_set_functionnames, class_set_functiontypes, sfile);
+    }
+    Delete(class_set_membernames);
+    Delete(class_set_functionnames);
+    Delete(class_set_functiontypes);
+    Delete(class_other_membernames);
+    Delete(class_other_functionnames);
+    Delete(class_other_functiontypes);
+ }
+
+  if (class_member_function_types) {
+    Delete(class_member_function_types);
+    class_member_function_types = NULL;
+    Delete(class_member_function_names);
+    class_member_function_names = NULL;
+    Delete(class_member_function_membernames);
+    class_member_function_membernames = NULL;
+    Delete(class_member_function_wrappernames);
+    class_member_function_wrappernames = NULL;
+   }
   if (Getattr(n, "has_destructor")) {
     Printf(sfile, "setMethod('delete', '_p%s', function(obj) {delete%s(obj)})\n", getRClassName(name), getRClassName(name));
 
@@ -2494,9 +2395,6 @@
 	c = nextSibling(c);
 	continue;
       }
-#if 0
-      tp = getRType(c);
-#else
       tp = Swig_typemap_lookup("rtype", c, "", 0);
       if(!tp) {
 	c = nextSibling(c);
@@ -2523,7 +2421,7 @@
       // returns ""  tp = processType(elType, c, NULL);
       //	    Printf(stdout, "<classDeclaration> elType %p\n", elType);
       //	    tp = getRClassNameCopyStruct(Getattr(c, "type"), 1);
-#endif
+
       String *elNameT = replaceInitialDash(elName);
       Printf(def, "%s%s = \"%s\"", tab8, elNameT, tp);
       firstItem = false;
@@ -2622,7 +2520,7 @@
 
 
   Printf(sfile, "# Start definition of copy methods for %s\n", rclassName);
-  Printf(sfile, "setMethod('copyToR', '_p_%s', CopyToR%s);\n", rclassName,
+  Printf(sfile, "setMethod('copyToR', '_p%s', CopyToR%s);\n", mangledName,
 	 mangledName);
   Printf(sfile, "setMethod('copyToC', '%s', CopyToC%s);\n\n", rclassName,
 	 mangledName);
@@ -2716,6 +2614,16 @@
   return s;
 }
 
+/*----------------------------------------------------------------------
+ * replaceSpecialVariables()
+ *--------------------------------------------------------------------*/
+
+void R::replaceSpecialVariables(String *method, String *tm, Parm *parm) {
+  (void)method;
+  SwigType *type = Getattr(parm, "type");
+  replaceRClass(tm, type);
+}
+
 
 /* -----------------------------------------------------------------------
  * Called when SWIG wants to initialize this
@@ -2793,7 +2701,7 @@
     } else if (strcmp(argv[i], "-nocppcast") == 0) {
       Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
       Swig_mark_arg(i);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
 
     if (debugMode) {
@@ -2842,7 +2750,7 @@
  *----------------------------------------------------------------------- */
 String * R::processType(SwigType *t, Node *n, int *nargs) {
   //XXX Need to handle typedefs, e.g.
-  //  a type which is a typedef  to a function pointer.
+  //  a type which is a typedef to a function pointer.
 
   SwigType *tmp = Getattr(n, "tdname");
   if (debugMode)
@@ -2884,10 +2792,6 @@
     return tmp;
   }
 
-#if 0
-  SwigType_isfunction(t) && SwigType_ispointer(t)
-#endif
-
     return NULL;
 }
 
diff --git a/Source/Modules/ruby.cxx b/Source/Modules/ruby.cxx
index 6a1e16d..fea6177 100644
--- a/Source/Modules/ruby.cxx
+++ b/Source/Modules/ruby.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * ruby.cxx
  *
@@ -85,7 +85,7 @@
 
     /* Mangled name */
     Delete(mname);
-    mname = Swig_name_mangle(cname);
+    mname = Swig_name_mangle_string(cname);
 
     /* Renamed class name */
     Clear(name);
@@ -106,9 +106,10 @@
 
   char *strip(const_String_or_char_ptr s) {
     Clear(temp);
-    Append(temp, s);
     if (Strncmp(s, prefix, Len(prefix)) == 0) {
-      Replaceall(temp, prefix, "");
+      Append(temp, Char(s) + Len(prefix));
+    } else {
+      Append(temp, s);
     }
     return Char(temp);
   }
@@ -116,6 +117,7 @@
 
 
 /* flags for the make_autodoc function */
+namespace {
 enum autodoc_t {
   AUTODOC_CLASS,
   AUTODOC_CTOR,
@@ -127,6 +129,7 @@
   AUTODOC_SETTER,
   AUTODOC_NONE
 };
+}
 
 static const char *usage = "\
 Ruby Options (available with -ruby)\n\
@@ -822,7 +825,7 @@
           "  $director_new \n",
           "} else {\n", "  rb_raise(rb_eRuntimeError,\"accessing abstract class or protected constructor\"); \n", "  return Qnil;\n", "}\n", NIL);
       director_multiple_inheritance = 0;
-      director_language = 1;
+      directorLanguage();
     }
 
   /* ---------------------------------------------------------------------
@@ -851,19 +854,6 @@
 	  } else {
 	    Swig_arg_error();
 	  }
-	}
-	else if (strcmp(argv[i], "-feature") == 0) {
-	  fprintf( stderr, "Warning: Ruby -feature option is deprecated, "
-		   "please use -initname instead.\n");
-	  if (argv[i + 1]) {
-	    char *name = argv[i + 1];
-	    feature = NewString(name);
-	    Swig_mark_arg(i);
-	    Swig_mark_arg(i + 1);
-	    i++;
-	  } else {
-	    Swig_arg_error();
-	  }
 	} else if (strcmp(argv[i], "-globalmodule") == 0) {
 	  useGlobalModule = true;
 	  Swig_mark_arg(i);
@@ -895,7 +885,7 @@
 	} else if (strcmp(argv[i], "-nocppcast") == 0) {
 	  Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
 	  Swig_mark_arg(i);
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	}
       }
     }
@@ -1034,13 +1024,13 @@
 
     if (!outfile) {
       Printf(stderr, "Unable to determine outfile\n");
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
 
     f_begin = NewFile(outfile, "w", SWIG_output_files());
     if (!f_begin) {
       FileErrorDisplay(outfile);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
 
     f_runtime = NewString("");
@@ -1052,15 +1042,15 @@
     f_directors_helpers = NewString("");
     f_initbeforefunc = NewString("");
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       if (!outfile_h) {
         Printf(stderr, "Unable to determine outfile_h\n");
-        SWIG_exit(EXIT_FAILURE);
+        Exit(EXIT_FAILURE);
       }
       f_runtime_h = NewFile(outfile_h, "w", SWIG_output_files());
       if (!f_runtime_h) {
 	FileErrorDisplay(outfile_h);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
     }
 
@@ -1084,9 +1074,9 @@
 
     Swig_banner(f_begin);
 
-    Printf(f_runtime, "\n\n#ifndef SWIGRUBY\n#define SWIGRUBY\n#endif\n\n");
+    Swig_obligatory_macros(f_runtime, "RUBY");
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Printf(f_runtime, "#define SWIG_DIRECTORS\n");
     }
 
@@ -1101,7 +1091,7 @@
     /* Set module name */
     set_module(Char(Getattr(n, "name")));
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       /* Build a version of the module name for use in a C macro name. */
       String *module_macro = Copy(module);
       Replaceall(module_macro, "::", "__");
@@ -1162,7 +1152,7 @@
 
     Language::top(n);
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       // Insert director runtime into the f_runtime file (make it occur before %header section)
       Swig_insert_file("director_common.swg", f_runtime);
       Swig_insert_file("director.swg", f_runtime);
@@ -1176,7 +1166,7 @@
     Dump(f_runtime, f_begin);
     Dump(f_header, f_begin);
 
-    if (directorsEnabled()) {
+    if (Swig_directors_enabled()) {
       Dump(f_directors_helpers, f_begin);
       Dump(f_directors, f_begin);
       Dump(f_directors_h, f_runtime_h);
@@ -1425,16 +1415,14 @@
    * applyInputTypemap()
    *
    * Look up the appropriate "in" typemap for this parameter (p),
-   * substitute the correct strings for the $target and $input typemap
-   * parameters, and dump the resulting code to the wrapper file.
+   * substitute the correct strings for the typemap parameters, and dump the
+   * resulting code to the wrapper file.
    * --------------------------------------------------------------------- */
 
-  Parm *applyInputTypemap(Parm *p, String *ln, String *source, Wrapper *f, String *symname) {
+  Parm *applyInputTypemap(Parm *p, String *source, Wrapper *f, String *symname) {
     String *tm;
     SwigType *pt = Getattr(p, "type");
     if ((tm = Getattr(p, "tmap:in"))) {
-      Replaceall(tm, "$target", ln);
-      Replaceall(tm, "$source", source);
       Replaceall(tm, "$input", source);
       Replaceall(tm, "$symname", symname);
 
@@ -1474,10 +1462,8 @@
     Parm *p;
     String *tm;
     String *source;
-    String *target;
 
     source = NewString("");
-    target = NewString("");
 
     bool ctor_director = (current == CONSTRUCTOR_INITIALIZE && Swig_directorclass(n));
 
@@ -1498,7 +1484,6 @@
       p = skipIgnoredArgs(p);
 
       String *pn = Getattr(p, "name");
-      String *ln = Getattr(p, "lname");
 
       /* Produce string representation of source argument */
       Clear(source);
@@ -1510,10 +1495,6 @@
 	Printf(source, "argv[%d]", i - start);
       }
 
-      /* Produce string representation of target argument */
-      Clear(target);
-      Printf(target, "%s", Char(ln));
-
       if (i >= (numreq)) {	/* Check if parsing an optional argument */
 	Printf(f->code, "    if (argc > %d) {\n", i - start);
       }
@@ -1526,7 +1507,7 @@
       }
 
       /* Look for an input typemap */
-      p = applyInputTypemap(p, ln, source, f, Getattr(n, "name"));
+      p = applyInputTypemap(p, source, f, Getattr(n, "name"));
       if (i >= numreq) {
 	Printf(f->code, "}\n");
       }
@@ -1553,7 +1534,6 @@
     }
 
     Delete(source);
-    Delete(target);
   }
 
   /* ---------------------------------------------------------------------
@@ -1569,7 +1549,6 @@
     String *tm;
     for (p = l; p;) {
       if ((tm = Getattr(p, "tmap:check"))) {
-	Replaceall(tm, "$target", Getattr(p, "lname"));
 	Printv(f->code, tm, "\n", NIL);
 	p = Getattr(p, "tmap:check:next");
       } else {
@@ -1591,7 +1570,6 @@
     for (Parm *p = l; p;) {
       if ((tm = Getattr(p, "tmap:freearg"))) {
 	if (Len(tm) != 0) {
-	  Replaceall(tm, "$source", Getattr(p, "lname"));
 	  Printv(cleanup, tm, "\n", NIL);
 	}
 	p = Getattr(p, "tmap:freearg:next");
@@ -1613,8 +1591,6 @@
     String *tm;
     for (Parm *p = l; p;) {
       if ((tm = Getattr(p, "tmap:argout"))) {
-	Replaceall(tm, "$source", Getattr(p, "lname"));
-	Replaceall(tm, "$target", "vresult");
 	Replaceall(tm, "$result", "vresult");
 	Replaceall(tm, "$arg", Getattr(p, "emit:input"));
 	Replaceall(tm, "$input", Getattr(p, "emit:input"));
@@ -1828,12 +1804,12 @@
 	Node *pn = Swig_methodclass(n);
 	String *symname = Getattr(pn, "sym:name");
 	String *action = Getattr(n, "wrap:action");
-	if (directorsEnabled()) {
+	if (Swig_directors_enabled()) {
 	  String *classname = NewStringf("const char *classname SWIGUNUSED = \"%s::%s\"", module, symname);
 	  Wrapper_add_local(f, "classname", classname);
 	}
 	if (action) {
-          SwigType *smart = Swig_cparse_smartptr(pn);
+	  SwigType *smart = Getattr(pn, "smart");
 	  String *result_name = NewStringf("%s%s", smart ? "smart" : "", Swig_cresult_name());
 	  if (smart) {
 	    String *result_var = NewStringf("%s *%s = 0", SwigType_namestr(smart), result_name);
@@ -1845,7 +1821,6 @@
 	    Printf(action, "\nSWIG_RubyAddTracking(%s, self);", result_name);
 	  }
 	  Delete(result_name);
-	  Delete(smart);
 	}
       }
 
@@ -1876,34 +1851,14 @@
           actioncode = 0;
           if (tm) {
             Replaceall(tm, "$result", "vresult");
-            Replaceall(tm, "$source", Swig_cresult_name());
-            Replaceall(tm, "$target", "vresult");
 
             if (GetFlag(n, "feature:new"))
               Replaceall(tm, "$owner", "SWIG_POINTER_OWN");
             else
               Replaceall(tm, "$owner", "0");
 
-#if 1
-            // FIXME: this will not try to unwrap directors returned as non-director
-            //        base class pointers!
-
-            /* New addition to unwrap director return values so that the original
-             * Ruby object is returned instead. 
-             */
-            bool unwrap = false;
-            String *decl = Getattr(n, "decl");
-            int is_pointer = SwigType_ispointer_return(decl);
-            int is_reference = SwigType_isreference_return(decl);
-            if (is_pointer || is_reference) {
-              String *type = Getattr(n, "type");
-              Node *parent = Swig_methodclass(n);
-              Node *modname = Getattr(parent, "module");
-              Node *target = Swig_directormap(modname, type);
-              if (target)
-                unwrap = true;
-            }
-            if (unwrap) {
+            // Unwrap return values that are director classes so that the original Ruby object is returned instead. 
+            if (Swig_director_can_unwrap(n)) {
               Wrapper_add_local(f, "director", "Swig::Director *director = 0");
               Printf(f->code, "director = dynamic_cast<Swig::Director *>(%s);\n", Swig_cresult_name());
               Printf(f->code, "if (director) {\n");
@@ -1915,9 +1870,7 @@
             } else {
               Printf(f->code, "%s\n", tm);
             }
-#else
-            Printf(f->code, "%s\n", tm);
-#endif
+
             Delete(tm);
           } else {
             Swig_warning(WARN_TYPEMAP_OUT_UNDEF, input_file, line_number, "Unable to use return type %s.\n", SwigType_str(t, 0));
@@ -1934,16 +1887,17 @@
     /* Extra code needed for new and initialize methods */
     if (current == CONSTRUCTOR_ALLOCATE) {
       Node *pn = Swig_methodclass(n);
-      SwigType *smart = Swig_cparse_smartptr(pn);
-      if (smart)
-	SwigType_add_pointer(smart);
-      String *classtype = smart ? smart : t;
+      SwigType *smart = Getattr(pn, "smart");
+      SwigType *psmart = smart ? Copy(smart) : 0;
+      if (psmart)
+	SwigType_add_pointer(psmart);
+      SwigType *classtype = psmart ? psmart : t;
       need_result = 1;
       Printf(f->code, "VALUE vresult = SWIG_NewClassInstance(self, SWIGTYPE%s);\n", Char(SwigType_manglestr(classtype)));
       Printf(f->code, "#ifndef HAVE_RB_DEFINE_ALLOC_FUNC\n");
       Printf(f->code, "rb_obj_call_init(vresult, argc, argv);\n");
       Printf(f->code, "#endif\n");
-      Delete(smart);
+      Delete(psmart);
     } else if (current == CONSTRUCTOR_INITIALIZE) {
       need_result = 1;
     }
@@ -1971,11 +1925,10 @@
     }
 
 
-    /* Look for any remaining cleanup.  This processes the %new directive */
+    /* Look for any remaining cleanup.  This processes the %newobject directive */
     if (current != CONSTRUCTOR_ALLOCATE && GetFlag(n, "feature:new")) {
       tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0);
       if (tm) {
-	Replaceall(tm, "$source", Swig_cresult_name());
 	Printv(f->code, tm, "\n", NIL);
 	Delete(tm);
       }
@@ -1984,7 +1937,6 @@
     /* Special processing on return value. */
     tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0);
     if (tm) {
-      Replaceall(tm, "$source", Swig_cresult_name());
       Printv(f->code, tm, NIL);
       Delete(tm);
     }
@@ -2116,9 +2068,9 @@
       sibl = Getattr(sibl, "sym:previousSibling");	// go all the way up
 
     // Constructors will be treated specially
-    const bool isCtor = (!Cmp(Getattr(sibl, "nodeType"), "constructor"));
-    const bool isMethod = ( Cmp(Getattr(sibl, "ismember"), "1") == 0 &&
-			    (!isCtor) );
+    String *siblNodeType = Getattr(sibl, "nodeType");
+    const bool isCtor = (Equal(siblNodeType, "constructor"));
+    const bool isMethod = (Equal(siblNodeType, "cdecl") && GetFlag(sibl, "ismember") && !isCtor);
 
     // Construct real method name
     String* methodName = NewString("");
@@ -2138,7 +2090,7 @@
     String *protoTypes = NewString("");
     do {
       Append( protoTypes, "\n\"    ");
-      if (!isCtor) {
+      if (!isCtor && !Equal(siblNodeType, "using")) {
 	SwigType *type = SwigType_str(Getattr(sibl, "type"), NULL);
 	Printv(protoTypes, type, " ", NIL);
 	Delete(type);
@@ -2191,6 +2143,12 @@
     String *tm;
     String *getfname, *setfname;
     Wrapper *getf, *setf;
+    int assignable = !is_immutable(n);
+
+    // Determine whether virtual global variables shall be used
+    // which have different getter and setter signatures,
+    // see https://docs.ruby-lang.org/en/2.6.0/extension_rdoc.html#label-Global+Variables+Shared+Between+C+and+Ruby
+    const bool use_virtual_var = (current == NO_CPP && useGlobalModule);
 
     getf = NewWrapper();
     setf = NewWrapper();
@@ -2201,15 +2159,13 @@
     getfname = Swig_name_wrapper(getname);
     Setattr(n, "wrap:name", getfname);
     Printv(getf->def, "SWIGINTERN VALUE\n", getfname, "(", NIL);
-    Printf(getf->def, "VALUE self");
+    Printf(getf->def, (use_virtual_var) ? "ID id, VALUE *data" : "VALUE self");
     Printf(getf->def, ") {");
     Wrapper_add_local(getf, "_val", "VALUE _val");
 
     tm = Swig_typemap_lookup("varout", n, name, 0);
     if (tm) {
       Replaceall(tm, "$result", "_val");
-      Replaceall(tm, "$target", "_val");
-      Replaceall(tm, "$source", name);
       /* Printv(getf->code,tm, NIL); */
       addfail = emit_action_code(n, getf->code, tm);
     } else {
@@ -2224,8 +2180,8 @@
 
     Wrapper_print(getf, f_wrappers);
 
-    if (!is_assignable(n)) {
-      setfname = NewString("NULL");
+    if (!assignable) {
+      setfname = NewString("(rb_gvar_setter_t *)NULL");
     } else {
       /* create setter */
       String* docs = docstring(n, AUTODOC_SETTER);
@@ -2235,40 +2191,45 @@
       String *setname = Swig_name_set(NSPACE_TODO, iname);
       setfname = Swig_name_wrapper(setname);
       Setattr(n, "wrap:name", setfname);
-      Printv(setf->def, "SWIGINTERN VALUE\n", setfname, "(VALUE self, ", NIL);
-      Printf(setf->def, "VALUE _val) {");
+      Printf(setf->def, "SWIGINTERN ");
+      if (use_virtual_var) {
+        Printv(setf->def, "void\n", setfname, "(VALUE _val, ID id, VALUE *data) {", NIL);
+      } else {
+        Printv(setf->def, "VALUE\n", setfname, "(VALUE self, VALUE _val) {", NIL);
+      }
       tm = Swig_typemap_lookup("varin", n, name, 0);
       if (tm) {
 	Replaceall(tm, "$input", "_val");
-	Replaceall(tm, "$source", "_val");
-	Replaceall(tm, "$target", name);
 	/* Printv(setf->code,tm,"\n",NIL); */
 	emit_action_code(n, setf->code, tm);
       } else {
 	Swig_warning(WARN_TYPEMAP_VARIN_UNDEF, input_file, line_number, "Unable to set variable of type %s\n", SwigType_str(t, 0));
       }
-      Printv(setf->code, tab4, "return _val;\n", NIL);
-      Printf(setf->code, "fail:\n");
-      Printv(setf->code, tab4, "return Qnil;\n", NIL);
+      if (use_virtual_var) {
+        Printf(setf->code, "fail:\n");
+        Printv(setf->code, tab4, "return;\n", NIL);
+      } else {
+        Printv(setf->code, tab4, "return _val;\n", NIL);
+        Printf(setf->code, "fail:\n");
+        Printv(setf->code, tab4, "return Qnil;\n", NIL);
+      }
       Printf(setf->code, "}\n");
       Wrapper_print(setf, f_wrappers);
       Delete(setname);
     }
 
-    /* define accessor method */
-    if (CPlusPlus) {
-      Insert(getfname, 0, "VALUEFUNC(");
-      Append(getfname, ")");
-      Insert(setfname, 0, "VALUEFUNC(");
-      Append(setfname, ")");
-    }
+    /* define accessor methods */
+    Insert(getfname, 0, "VALUEFUNC(");
+    Append(getfname, ")");
+    Insert(setfname, 0, (use_virtual_var) ? "SWIG_RUBY_VOID_ANYARGS_FUNC(" : "VALUEFUNC(");
+    Append(setfname, ")");
 
     String *s = NewString("");
     switch (current) {
     case STATIC_VAR:
       /* C++ class variable */
       Printv(s, tab4, "rb_define_singleton_method(", klass->vname, ", \"", klass->strip(iname), "\", ", getfname, ", 0);\n", NIL);
-      if (!GetFlag(n, "feature:immutable")) {
+      if (assignable) {
 	Printv(s, tab4, "rb_define_singleton_method(", klass->vname, ", \"", klass->strip(iname), "=\", ", setfname, ", 1);\n", NIL);
       }
       Printv(klass->init, s, NIL);
@@ -2279,14 +2240,11 @@
       assert(current == NO_CPP);
       if (!useGlobalModule) {
 	Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", iname, "\", ", getfname, ", 0);\n", NIL);
-	if (!GetFlag(n, "feature:immutable")) {
+	if (assignable) {
 	  Printv(s, tab4, "rb_define_singleton_method(", modvar, ", \"", iname, "=\", ", setfname, ", 1);\n", NIL);
 	}
       } else {
-	Printv(s, tab4, "rb_define_global_method(\"", iname, "\", ", getfname, ", 0);\n", NIL);
-	if (!GetFlag(n, "feature:immutable")) {
-	  Printv(s, tab4, "rb_define_global_method(\"", iname, "=\", ", setfname, ", 1);\n", NIL);
-	}
+	Printv(s, tab4, "rb_define_virtual_variable(\"$", iname, "\", ", getfname, ", ", setfname, ");\n", NIL);
       }
       Printv(f_init, s, NIL);
       Delete(s);
@@ -2353,8 +2311,6 @@
     if (!tm)
       tm = Swig_typemap_lookup("constcode", n, value, 0);
     if (tm) {
-      Replaceall(tm, "$source", value);
-      Replaceall(tm, "$target", iname);
       Replaceall(tm, "$symname", iname);
       Replaceall(tm, "$value", value);
       if (current == CLASS_CONST) {
@@ -2443,12 +2399,13 @@
 	  SwigType *btype = NewString(basename);
 	  SwigType_add_pointer(btype);
 	  SwigType_remember(btype);
-	  SwigType *smart = Swig_cparse_smartptr(base.item);
-	  if (smart) {
-	    SwigType_add_pointer(smart);
-	    SwigType_remember(smart);
+	  SwigType *smart = Getattr(base.item, "smart");
+	  SwigType *psmart = smart ? Copy(smart) : 0;
+	  if (psmart) {
+	    SwigType_add_pointer(psmart);
+	    SwigType_remember(psmart);
 	  }
-	  String *bmangle = SwigType_manglestr(smart ? smart : btype);
+	  String *bmangle = SwigType_manglestr(psmart ? psmart : btype);
 	  if (multipleInheritance) {
 	    Insert(bmangle, 0, "((swig_class *) SWIGTYPE");
 	    Append(bmangle, "->clientdata)->mImpl");
@@ -2459,7 +2416,7 @@
 	    Replaceall(klass->init, "$super", bmangle);
 	  }
 	  Delete(bmangle);
-	  Delete(smart);
+	  Delete(psmart);
 	  Delete(btype);
 	}
 	base = Next(base);
@@ -2560,15 +2517,16 @@
     SwigType *tt = NewString(name);
     SwigType_add_pointer(tt);
     SwigType_remember(tt);
-    SwigType *smart = Swig_cparse_smartptr(n);
-    if (smart) {
-      SwigType_add_pointer(smart);
-      SwigType_remember(smart);
+    SwigType *smart = Getattr(n, "smart");
+    SwigType *psmart = smart ? Copy(smart) : 0;
+    if (psmart) {
+      SwigType_add_pointer(psmart);
+      SwigType_remember(psmart);
     }
-    String *tm = SwigType_manglestr(smart ? smart : tt);
+    String *tm = SwigType_manglestr(psmart ? psmart : tt);
     Printf(klass->init, "SWIG_TypeClientData(SWIGTYPE%s, (void *) &SwigClass%s);\n", tm, valid_name);
     Delete(tm);
-    Delete(smart);
+    Delete(psmart);
     Delete(tt);
     Delete(valid_name);
 
@@ -2801,7 +2759,7 @@
     Printf(f_wrappers, "%s", docs);
     Delete(docs);
 
-    if (is_assignable(n)) {
+    if (!is_immutable(n)) {
       String* docs = docstring(n, AUTODOC_SETTER);
       Printf(f_wrappers, "%s", docs);
       Delete(docs);
@@ -2856,7 +2814,7 @@
     Printf(f_wrappers, "%s", docs);
     Delete(docs);
 
-    if (is_assignable(n)) {
+    if (!is_immutable(n)) {
       String* docs = docstring(n, AUTODOC_SETTER);
       Printf(f_wrappers, "%s", docs);
       Delete(docs);
@@ -3190,12 +3148,6 @@
       /* build argument list and type conversion string */
       idx = 0; p = l;
       while ( p ) {
-
-	if (Getattr(p, "tmap:ignore")) {
-	  p = Getattr(p, "tmap:ignore:next");
-	  continue;
-	}
-
 	if (Getattr(p, "tmap:directorargout") != 0)
 	  outputs++;
 
diff --git a/Source/Modules/s-exp.cxx b/Source/Modules/s-exp.cxx
deleted file mode 100644
index fe3b1fa..0000000
--- a/Source/Modules/s-exp.cxx
+++ /dev/null
@@ -1,402 +0,0 @@
-/* ----------------------------------------------------------------------------- 
- * This file is part of SWIG, which is licensed as a whole under version 3 
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
- *
- * s-exp.cxx
- *
- * A parse tree represented as Lisp s-expressions.
- * ----------------------------------------------------------------------------- */
-
-#include "swigmod.h"
-#include "dohint.h"
-
-static const char *usage = "\
-S-Exp Options (available with -sexp)\n\
-     -typemaplang <lang> - Typemap language\n\n";
-
-//static Node *view_top = 0;
-static File *out = 0;
-
-class Sexp:public Language {
-  int indent_level;
-  DOHHash *print_circle_hash;
-  int print_circle_count;
-  int hanging_parens;
-  bool need_whitespace;
-  bool need_newline;
-
-public:
-  Sexp():
-    indent_level(0),
-    print_circle_hash(0),
-    print_circle_count(0),
-    hanging_parens(0),
-    need_whitespace(0),
-    need_newline(0) {
-  }
-  
-  virtual ~ Sexp() {
-  }
-
-  virtual void main(int argc, char *argv[]) {
-    // Add a symbol to the parser for conditional compilation
-    Preprocessor_define("SWIGSEXP 1", 0);
-
-    SWIG_typemap_lang("sexp");
-    for (int iX = 0; iX < argc; iX++) {
-      if (strcmp(argv[iX], "-typemaplang") == 0) {
-	Swig_mark_arg(iX);
-	iX++;
-	SWIG_typemap_lang(argv[iX]);
-	Swig_mark_arg(iX);
-	continue;
-      }
-      if (strcmp(argv[iX], "-help") == 0) {
-	fputs(usage, stdout);
-      }
-    }
-  }
-
-  /* Top of the parse tree */
-  virtual int top(Node *n) {
-    if (out == 0) {
-      String *outfile = Getattr(n, "outfile");
-      Replaceall(outfile, "_wrap.cxx", ".lisp");
-      Replaceall(outfile, "_wrap.c", ".lisp");
-      out = NewFile(outfile, "w", SWIG_output_files());
-      if (!out) {
-	FileErrorDisplay(outfile);
-	SWIG_exit(EXIT_FAILURE);
-      }
-    }
-    String *f_sink = NewString("");
-    Swig_register_filebyname("header", f_sink);
-    Swig_register_filebyname("wrapper", f_sink);
-    Swig_register_filebyname("begin", f_sink);
-    Swig_register_filebyname("runtime", f_sink);
-    Swig_register_filebyname("init", f_sink);
-
-    Swig_banner_target_lang(out, ";;;");
-
-    Language::top(n);
-    Printf(out, "\n");
-    Printf(out, ";;; Lisp parse tree produced by SWIG\n");
-    print_circle_hash = NewHash();
-    print_circle_count = 0;
-    hanging_parens = 0;
-    need_whitespace = 0;
-    need_newline = 0;
-    Sexp_print_node(n);
-    flush_parens();
-    return SWIG_OK;
-  }
-
-  void print_indent() {
-    int i;
-    for (i = 0; i < indent_level; i++) {
-      Printf(out, " ");
-    }
-  }
-
-  void open_paren(const String *oper) {
-    flush_parens();
-    Printf(out, "(");
-    if (oper)
-      Printf(out, "%s ", oper);
-    indent_level += 2;
-  }
-
-  void close_paren(bool neednewline = false) {
-    hanging_parens++;
-    if (neednewline)
-      print_lazy_whitespace();
-    indent_level -= 2;
-  }
-
-  void flush_parens() {
-    int i;
-    if (hanging_parens) {
-      for (i = 0; i < hanging_parens; i++)
-	Printf(out, ")");
-      hanging_parens = 0;
-      need_newline = true;
-      need_whitespace = true;
-    }
-    if (need_newline) {
-      Printf(out, "\n");
-      print_indent();
-      need_newline = false;
-      need_whitespace = false;
-    } else if (need_whitespace) {
-      Printf(out, " ");
-      need_whitespace = false;
-    }
-  }
-
-  void print_lazy_whitespace() {
-    need_whitespace = 1;
-  }
-
-  void print_lazy_newline() {
-    need_newline = 1;
-  }
-
-  bool internal_key_p(DOH *key) {
-    return ((Cmp(key, "nodeType") == 0)
-	    || (Cmp(key, "firstChild") == 0)
-	    || (Cmp(key, "lastChild") == 0)
-	    || (Cmp(key, "parentNode") == 0)
-	    || (Cmp(key, "nextSibling") == 0)
-	    || (Cmp(key, "previousSibling") == 0)
-	    || (Cmp(key, "csym:nextSibling") == 0)
-	    || (Cmp(key, "csym:previousSibling") == 0)
-	    || (Cmp(key, "typepass:visit") == 0)
-	    || (Cmp(key, "allocate:visit") == 0)
-	    || (*(Char(key)) == '$'));
-  }
-
-  bool boolean_key_p(DOH *key) {
-    return ((Cmp(key, "allocate:default_constructor") == 0)
-	    || (Cmp(key, "allocate:default_destructor") == 0)
-	    || (Cmp(key, "allows_typedef") == 0)
-	    || (Cmp(key, "feature:immutable") == 0));
-  }
-
-  bool list_key_p(DOH *key) {
-    return ((Cmp(key, "parms") == 0)
-	    || (Cmp(key, "baselist") == 0));
-  }
-
-  bool plist_key_p(DOH *key)
-      // true if KEY is the name of data that is a mapping from keys to
-      // values, which should be printed as a plist.
-  {
-    return ((Cmp(key, "typescope") == 0));
-  }
-
-  bool maybe_plist_key_p(DOH *key) {
-    return (Strncmp(key, "tmap:", 5) == 0);
-  }
-
-  bool print_circle(DOH *obj, bool list_p)
-      // We have a complex object, which might be referenced several
-      // times, or even recursively.  Use Lisp's reader notation for
-      // circular structures (#n#, #n=).
-      //
-      // An object can be printed in list-mode or object-mode; LIST_P toggles.
-      // return TRUE if OBJ still needs to be printed
-  {
-    flush_parens();
-    // Following is a silly hack.  It works around the limitation of
-    // DOH's hash tables that only work with string keys!
-    char address[32];
-    sprintf(address, "%p%c", obj, list_p ? 'L' : 'O');
-    DOH *placeholder = Getattr(print_circle_hash, address);
-    if (placeholder) {
-      Printv(out, placeholder, NIL);
-      return false;
-    } else {
-      String *placeholder = NewStringf("#%d#", ++print_circle_count);
-      Setattr(print_circle_hash, address, placeholder);
-      Printf(out, "#%d=", print_circle_count);
-      return true;
-    }
-  }
-
-  void Sexp_print_value_of_key(DOH *value, DOH *key) {
-    if ((Cmp(key, "parms") == 0) || (Cmp(key, "wrap:parms") == 0)
-	|| (Cmp(key, "kwargs") == 0) || (Cmp(key, "pattern") == 0))
-      Sexp_print_parms(value);
-    else if (plist_key_p(key))
-      Sexp_print_plist(value);
-    else if (maybe_plist_key_p(key)) {
-      if (DohIsMapping(value))
-	Sexp_print_plist(value);
-      else
-	Sexp_print_doh(value);
-    } else if (list_key_p(key))
-      Sexp_print_list(value);
-    else if (boolean_key_p(key))
-      Sexp_print_boolean(value);
-    else
-      Sexp_print_doh(value);
-  }
-
-  void Sexp_print_boolean(DOH *obj) {
-    flush_parens();
-    /* See DOH/Doh/base.c, DohGetInt() */
-    if (DohIsString(obj)) {
-      if (atoi(Char(obj)) != 0)
-	Printf(out, "t");
-      else
-	Printf(out, "nil");
-    } else
-      Printf(out, "nil");
-  }
-
-  void Sexp_print_list(DOH *obj) {
-    if (print_circle(obj, true)) {
-      open_paren(NIL);
-      for (; obj; obj = nextSibling(obj)) {
-	Sexp_print_doh(obj);
-	print_lazy_whitespace();
-      }
-      close_paren(true);
-    }
-  }
-
-  void Sexp_print_parms(DOH *obj) {
-    // print it as a list of plists
-    if (print_circle(obj, true)) {
-      open_paren(NIL);
-      for (; obj; obj = nextSibling(obj)) {
-	if (DohIsMapping(obj)) {
-	  Iterator k;
-	  open_paren(NIL);
-	  for (k = First(obj); k.key; k = Next(k)) {
-	    if (!internal_key_p(k.key)) {
-	      DOH *value = Getattr(obj, k.key);
-	      Sexp_print_as_keyword(k.key);
-	      Sexp_print_value_of_key(value, k.key);
-	      print_lazy_whitespace();
-	    }
-	  }
-	  close_paren(true);
-	} else
-	  Sexp_print_doh(obj);
-	print_lazy_whitespace();
-      }
-      close_paren(true);
-    }
-  }
-
-  void Sexp_print_doh(DOH *obj) {
-    flush_parens();
-    if (DohIsString(obj)) {
-      String *o = Str(obj);
-      Replaceall(o, "\\", "\\\\");
-      Replaceall(o, "\"", "\\\"");
-      Printf(out, "\"%s\"", o);
-      Delete(o);
-    } else {
-      if (print_circle(obj, false)) {
-	// Dispatch type
-	if (nodeType(obj)) {
-	  Sexp_print_node(obj);
-	}
-
-	else if (DohIsMapping(obj)) {
-	  Iterator k;
-	  open_paren(NIL);
-	  for (k = First(obj); k.key; k = Next(k)) {
-	    if (!internal_key_p(k.key)) {
-	      DOH *value = Getattr(obj, k.key);
-	      flush_parens();
-	      open_paren(NIL);
-	      Sexp_print_doh(k.key);
-	      Printf(out, " . ");
-	      Sexp_print_value_of_key(value, k.key);
-	      close_paren();
-	    }
-	  }
-	  close_paren();
-	} else if (strcmp(ObjType(obj)->objname, "List") == 0) {
-	  int i;
-	  open_paren(NIL);
-	  for (i = 0; i < Len(obj); i++) {
-	    DOH *item = Getitem(obj, i);
-	    Sexp_print_doh(item);
-	  }
-	  close_paren();
-	} else {
-	  // What is it?
-	  Printf(out, "#<DOH %s %p>", ObjType(obj)->objname, obj);
-	}
-      }
-    }
-  }
-
-  void Sexp_print_as_keyword(const DOH *k) {
-    /* Print key, replacing ":" with "-" because : is CL's package prefix */
-    flush_parens();
-    String *key = NewString(k);
-    Replaceall(key, ":", "-");
-    Replaceall(key, "_", "-");
-    Printf(out, ":%s ", key);
-    Delete(key);
-  }
-
-  void Sexp_print_plist_noparens(DOH *obj) {
-    /* attributes map names to objects */
-    Iterator k;
-    bool first;
-    for (k = First(obj), first = true; k.key; k = Next(k), first = false) {
-      if (!internal_key_p(k.key)) {
-	DOH *value = Getattr(obj, k.key);
-	flush_parens();
-	if (!first) {
-	  Printf(out, " ");
-	}
-	Sexp_print_as_keyword(k.key);
-	/* Print value */
-	Sexp_print_value_of_key(value, k.key);
-      }
-    }
-  }
-
-  void Sexp_print_plist(DOH *obj) {
-    flush_parens();
-    if (print_circle(obj, true)) {
-      open_paren(NIL);
-      Sexp_print_plist_noparens(obj);
-      close_paren();
-    }
-  }
-
-  void Sexp_print_attributes(Node *obj) {
-    Sexp_print_plist_noparens(obj);
-  }
-
-  void Sexp_print_node(Node *obj) {
-    Node *cobj;
-    open_paren(nodeType(obj));
-    /* A node has an attribute list... */
-    Sexp_print_attributes(obj);
-    /* ... and child nodes. */
-    cobj = firstChild(obj);
-    if (cobj) {
-      print_lazy_newline();
-      flush_parens();
-      Sexp_print_as_keyword("children");
-      open_paren(NIL);
-      for (; cobj; cobj = nextSibling(cobj)) {
-	Sexp_print_node(cobj);
-      }
-      close_paren();
-    }
-    close_paren();
-  }
-
-
-  virtual int functionWrapper(Node *n) {
-    ParmList *l = Getattr(n, "parms");
-    Wrapper *f = NewWrapper();
-    emit_attach_parmmaps(l, f);
-    Setattr(n, "wrap:parms", l);
-    DelWrapper(f);
-    return SWIG_OK;
-  }
-
-};
-
-
-static Language *new_swig_sexp() {
-  return new Sexp();
-}
-extern "C" Language *swig_sexp(void) {
-  return new_swig_sexp();
-}
diff --git a/Source/Modules/scilab.cxx b/Source/Modules/scilab.cxx
index 23e45f7..d3ce4c6 100644
--- a/Source/Modules/scilab.cxx
+++ b/Source/Modules/scilab.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * scilab.cxx
  *
@@ -12,9 +12,10 @@
  * --------------------------------------------------------------------------*/
 
 #include "swigmod.h"
+#include <cstddef>
+#include <cstdlib>
 
 static const int SCILAB_IDENTIFIER_NAME_CHAR_MAX = 24;
-static const int SCILAB_VARIABLE_NAME_CHAR_MAX = SCILAB_IDENTIFIER_NAME_CHAR_MAX - 4;
 
 static const char *usage = (char *) " \
 Scilab options (available with -scilab)\n \
@@ -25,7 +26,7 @@
      -buildersources <files>                - Add the (comma separated) files <files> to the builder sources\n \
      -builderverbositylevel <level>         - Set the builder verbosity level to <level> (default 0: off, 2: high)\n \
      -gatewayxml <gateway_id>               - Generate gateway xml with the given <gateway_id>\n \
-     -targetversion <scilab_major_version>  - Generate for Scilab target (major) version (default: 5)\n \
+     -gatewayxml6                           - Generate gateway xml for Scilab 6\n \
 \n";
 
 
@@ -40,11 +41,11 @@
 
   String *variablesCode;
 
-  int targetVersion;
-
   bool generateBuilder;
   File *builderFile;
   String *builderCode;
+  String *builderCode5;
+  String *builderCode6;
   int builderFunctionCount;
 
   List *sourceFileList;
@@ -64,9 +65,16 @@
   String *gatewayID;
   int primitiveID;
 
+  bool createGatewayXMLV6;
+  File *gatewayXMLFileV6;
+  String *gatewayXMLV6;
+
   bool createLoader;
   File *loaderFile;
   String *loaderScript;
+  String *loaderScript5;
+  String *loaderScript6;
+  int loaderFunctionCount;
 public:
 
   /* ------------------------------------------------------------------------
@@ -74,8 +82,6 @@
    * ----------------------------------------------------------------------*/
 
   virtual void main(int argc, char *argv[]) {
-    targetVersion = 5;
-
     generateBuilder = false;
     sourceFileList = NewList();
     cflags = NewList();
@@ -92,6 +98,10 @@
     gatewayXMLFile = NULL;
     gatewayID = NULL;
 
+    createGatewayXMLV6 = false;
+    gatewayXMLV6 = NULL;
+    gatewayXMLFileV6 = NULL;
+
     createLoader = true;
     loaderFile = NULL;
     loaderScript = NULL;
@@ -99,23 +109,23 @@
     /* Manage command line arguments */
     for (int argIndex = 1; argIndex < argc; argIndex++) {
       if (argv[argIndex] != NULL) {
-	      if (strcmp(argv[argIndex], "-help") == 0) {
-	        Printf(stdout, "%s\n", usage);
-	      } else if (strcmp(argv[argIndex], "-builder") == 0) {
-	        Swig_mark_arg(argIndex);
-	        generateBuilder = true;
-	        createLoader = false;
-	      } else if (strcmp(argv[argIndex], "-buildersources") == 0) {
-	        if (argv[argIndex + 1] != NULL) {
-	          Swig_mark_arg(argIndex);
-	          char *sourceFile = strtok(argv[argIndex + 1], ",");
-	          while (sourceFile != NULL) {
-	            Insert(sourceFileList, Len(sourceFileList), sourceFile);
-	            sourceFile = strtok(NULL, ",");
-	          }
-	          Swig_mark_arg(argIndex + 1);
-	        }
-	      } else if (strcmp(argv[argIndex], "-buildercflags") == 0) {
+	if (strcmp(argv[argIndex], "-help") == 0) {
+	  Printf(stdout, "%s\n", usage);
+	} else if (strcmp(argv[argIndex], "-builder") == 0) {
+	  Swig_mark_arg(argIndex);
+	  generateBuilder = true;
+	  createLoader = false;
+	} else if (strcmp(argv[argIndex], "-buildersources") == 0) {
+	  if (argv[argIndex + 1] != NULL) {
+	    Swig_mark_arg(argIndex);
+	    char *sourceFile = strtok(argv[argIndex + 1], ",");
+	    while (sourceFile != NULL) {
+	      Insert(sourceFileList, Len(sourceFileList), sourceFile);
+	      sourceFile = strtok(NULL, ",");
+	    }
+	    Swig_mark_arg(argIndex + 1);
+	  }
+	} else if (strcmp(argv[argIndex], "-buildercflags") == 0) {
           Swig_mark_arg(argIndex);
           if (argv[argIndex + 1] != NULL) {
             Insert(cflags, Len(cflags), argv[argIndex + 1]);
@@ -140,12 +150,9 @@
           createGatewayXML = true;
           gatewayID = NewString(argv[argIndex + 1]);
           Swig_mark_arg(argIndex + 1);
-        } else if (strcmp(argv[argIndex], "-targetversion") == 0) {
-          if (argv[argIndex + 1] != NULL) {
-            Swig_mark_arg(argIndex);
-            targetVersion = atoi(argv[argIndex + 1]);
-            Swig_mark_arg(argIndex + 1);
-          }
+        } else if (strcmp(argv[argIndex], "-gatewayxml6") == 0) {
+          Swig_mark_arg(argIndex);
+          createGatewayXMLV6 = true;
         }
       }
     }
@@ -188,7 +195,7 @@
     beginSection = NewFile(outputFilename, "w", SWIG_output_files());
     if (!beginSection) {
       FileErrorDisplay(outputFilename);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
     runtimeSection = NewString("");
     initSection = NewString("");
@@ -205,7 +212,7 @@
     /* Output module initialization code */
     Swig_banner(beginSection);
 
-    Printf(runtimeSection, "\n\n#ifndef SWIGSCILAB\n#define SWIGSCILAB\n#endif\n\n");
+    Swig_obligatory_macros(runtimeSection, "SCILAB");
 
     // Gateway header source merged with wrapper source in nobuilder mode
     if (!generateBuilder)
@@ -221,16 +228,24 @@
       createGatewayXMLFile(gatewayName);
     }
 
+    // Create gateway XML V6 if required
+    if (createGatewayXMLV6) {
+      createGatewayXMLFileV6(gatewayName);
+    }
+
     // Create loader script if required
     if (createLoader) {
       createLoaderFile(gatewayLibraryName);
     }
 
     // Module initialization function
+    String *smallFunctionName = createSmallIdentifierName(gatewayName, SCILAB_IDENTIFIER_NAME_CHAR_MAX - 5);
     String *gatewayInitFunctionName = NewStringf("%s_Init", gatewayName);
+    String *gatewayInitSmallFunctionName = NewStringf("%s_Init", smallFunctionName);
+    String *wrapperFunctionName = NewStringf("SWIG_%s_Init", gatewayName);
 
     /* Add initialization function to builder table */
-    addFunctionToScilab(gatewayInitFunctionName, gatewayInitFunctionName);
+    addFunctionToScilab(gatewayInitFunctionName, gatewayInitSmallFunctionName, wrapperFunctionName);
 
     // Add helper functions to builder table
     addHelperFunctions();
@@ -254,7 +269,7 @@
 
     // Add Builder footer code and save
     if (generateBuilder) {
-      saveBuilderFile(gatewayName);
+      saveBuilderFile(gatewayLibraryName);
     }
 
     /* Close the init function and rename with module name */
@@ -279,6 +294,9 @@
     if (createGatewayXML) {
       saveGatewayXMLFile();
     }
+    if (createGatewayXMLV6) {
+      saveGatewayXMLFileV6();
+    }
 
     if (createLoader) {
       saveLoaderFile(gatewayLibraryName);
@@ -316,6 +334,8 @@
 
     /* Get some useful attributes of this function */
     String *functionName = Getattr(node, "sym:name");
+    String *smallFunctionName = createSmallIdentifierName(functionName);
+
     SwigType *functionReturnType = Getattr(node, "type");
     ParmList *functionParamsList = Getattr(node, "parms");
 
@@ -345,7 +365,7 @@
     }
 
     /* Write the wrapper function definition (standard Scilab gateway function prototype) */
-    Printv(wrapper->def, "int ", overloadedName, "(SWIG_GatewayParameters) {", NIL);
+    Printv(wrapper->def, "SWIGEXPORT int ", overloadedName, "(SWIG_GatewayParameters) {", NIL);
 
     /* Emit all of the local variables for holding arguments */
     // E.g.: double arg1;
@@ -472,7 +492,6 @@
       String *tm;
       if ((tm = Getattr(param, "tmap:freearg"))) {
 	if (tm && (Len(tm) != 0)) {
-	  Replaceall(tm, "$source", Getattr(param, "lname"));
 	  Printf(wrapper->code, "%s\n", tm);
 	}
 	param = Getattr(param, "tmap:freearg:next");
@@ -484,7 +503,6 @@
     /* See if there is any return cleanup code */
     String *tm;
     if ((tm = Swig_typemap_lookup("ret", node, Swig_cresult_name(), 0))) {
-      Replaceall(tm, "$source", Swig_cresult_name());
       Printf(wrapper->code, "%s\n", tm);
       Delete(tm);
     }
@@ -500,10 +518,12 @@
     Replaceall(wrapper->code, "$symname", functionName);
 
     /* Set CheckInputArgument and CheckOutputArgument input arguments */
-    /* In Scilab there is always one output even if not defined */
-    if (minOutputArguments == 0) {
+    if (maxOutputArguments < 1) {
       maxOutputArguments = 1;
     }
+    if (minOutputArguments == 1) {
+      minOutputArguments = 0;
+    }
     String *argnumber = NewString("");
     Printf(argnumber, "%d", minInputArguments);
     Replaceall(wrapper->code, "$mininputarguments", argnumber);
@@ -523,16 +543,14 @@
     /* Dump the function out */
     Wrapper_print(wrapper, wrappersSection);
 
-    String *scilabFunctionName = checkIdentifierName(functionName, SCILAB_IDENTIFIER_NAME_CHAR_MAX);
-
     /* Update builder.sce contents */
     if (isLastOverloaded) {
-      addFunctionToScilab(scilabFunctionName, wrapperName);
+      addFunctionToScilab(functionName, smallFunctionName, wrapperName);
       dispatchFunction(node);
     }
 
     if (!isOverloaded) {
-      addFunctionToScilab(scilabFunctionName, wrapperName);
+      addFunctionToScilab(functionName, smallFunctionName, wrapperName);
     }
 
     /* tidy up */
@@ -558,7 +576,7 @@
     String *dispatch = Swig_overload_dispatch(node, "return %s(SWIG_GatewayArguments);", &maxargs);
     String *tmp = NewString("");
 
-    Printv(wrapper->def, "int ", wrapperName, "(SWIG_GatewayParameters) {\n", NIL);
+    Printv(wrapper->def, "SWIGEXPORT int ", wrapperName, "(SWIG_GatewayParameters) {\n", NIL);
 
     /* Get the number of the parameters */
     Wrapper_add_local(wrapper, "argc", "int argc = SWIG_NbInputArgument(pvApiCtx)");
@@ -593,21 +611,20 @@
     /* Get information about variable */
     String *origVariableName = Getattr(node, "name");	// Ex: Shape::nshapes
     String *variableName = Getattr(node, "sym:name");	// Ex; Shape_nshapes (can be used for function names, ...)
-
-    // Variable names can have SCILAB_VARIABLE_NAME_CHAR_MAX because of suffixes "_get" or "_set" added to function
-    String *scilabVariableName = checkIdentifierName(variableName, SCILAB_VARIABLE_NAME_CHAR_MAX);
+    String *smallVariableName = createSmallIdentifierName(variableName, SCILAB_IDENTIFIER_NAME_CHAR_MAX - 4);
 
     /* Manage GET function */
     Wrapper *getFunctionWrapper = NewWrapper();
     String *getFunctionName = Swig_name_get(NSPACE_TODO, variableName);
-    String *scilabGetFunctionName = Swig_name_get(NSPACE_TODO, scilabVariableName);
+    String *scilabGetFunctionName = Swig_name_get(NSPACE_TODO, variableName);
+    String *scilabGetSmallFunctionName = Swig_name_get(NSPACE_TODO, smallVariableName);
 
     Setattr(node, "wrap:name", getFunctionName);
-    Printv(getFunctionWrapper->def, "int ", getFunctionName, "(SWIG_GatewayParameters) {\n", NIL);
+    Printv(getFunctionWrapper->def, "SWIGEXPORT int ", getFunctionName, "(SWIG_GatewayParameters) {\n", NIL);
 
     /* Check the number of input and output */
     Printf(getFunctionWrapper->def, "SWIG_CheckInputArgument(pvApiCtx, 0, 0);\n");
-    Printf(getFunctionWrapper->def, "SWIG_CheckOutputArgument(pvApiCtx, 1, 1);\n");
+    Printf(getFunctionWrapper->def, "SWIG_CheckOutputArgument(pvApiCtx, 0, 1);\n");
     Printf(getFunctionWrapper->def, "SWIG_Scilab_SetApiContext(pvApiCtx);\n");
 
     String *varoutTypemap = Swig_typemap_lookup("varout", node, origVariableName, 0);
@@ -623,20 +640,21 @@
     Wrapper_print(getFunctionWrapper, wrappersSection);
 
     /* Add function to builder table */
-    addFunctionToScilab(scilabGetFunctionName, getFunctionName);
+    addFunctionToScilab(scilabGetFunctionName, scilabGetSmallFunctionName, getFunctionName);
 
     /* Manage SET function */
-    if (is_assignable(node)) {
+    if (!is_immutable(node)) {
       Wrapper *setFunctionWrapper = NewWrapper();
       String *setFunctionName = Swig_name_set(NSPACE_TODO, variableName);
-      String *scilabSetFunctionName = Swig_name_set(NSPACE_TODO, scilabVariableName);
+      String *scilabSetFunctionName = Swig_name_set(NSPACE_TODO, variableName);
+      String *scilabSetSmallFunctionName = Swig_name_set(NSPACE_TODO, smallVariableName);
 
       Setattr(node, "wrap:name", setFunctionName);
-      Printv(setFunctionWrapper->def, "int ", setFunctionName, "(SWIG_GatewayParameters) {\n", NIL);
+      Printv(setFunctionWrapper->def, "SWIGEXPORT int ", setFunctionName, "(SWIG_GatewayParameters) {\n", NIL);
 
       /* Check the number of input and output */
       Printf(setFunctionWrapper->def, "SWIG_CheckInputArgument(pvApiCtx, 1, 1);\n");
-      Printf(setFunctionWrapper->def, "SWIG_CheckOutputArgument(pvApiCtx, 1, 1);\n");
+      Printf(setFunctionWrapper->def, "SWIG_CheckOutputArgument(pvApiCtx, 0, 1);\n");
       Printf(setFunctionWrapper->def, "SWIG_Scilab_SetApiContext(pvApiCtx);\n");
 
       String *varinTypemap = Swig_typemap_lookup("varin", node, origVariableName, 0);
@@ -650,7 +668,7 @@
       Wrapper_print(setFunctionWrapper, wrappersSection);
 
       /* Add function to builder table */
-      addFunctionToScilab(scilabSetFunctionName, setFunctionName);
+      addFunctionToScilab(scilabSetFunctionName, scilabSetSmallFunctionName, setFunctionName);
 
       DelWrapper(setFunctionWrapper);
     }
@@ -686,10 +704,9 @@
 
 	constantTypemap = Swig_typemap_lookup("scilabconstcode", node, nodeName, 0);
 	if (constantTypemap != NULL) {
-	  String *scilabConstantName = checkIdentifierName(constantName, SCILAB_IDENTIFIER_NAME_CHAR_MAX);
 
 	  Setattr(node, "wrap:name", constantName);
-	  Replaceall(constantTypemap, "$result", scilabConstantName);
+	  Replaceall(constantTypemap, "$result", constantName);
 	  Replaceall(constantTypemap, "$value", constantValue);
 
 	  emit_action_code(node, variablesCode, constantTypemap);
@@ -707,19 +724,21 @@
       Delete(str);
       constantValue = wname;
     }
+
     // Constant names can have SCILAB_VARIABLE_NAME_CHAR_MAX because of suffixes "_get" added to function
-    String *scilabConstantName = checkIdentifierName(constantName, SCILAB_VARIABLE_NAME_CHAR_MAX);
+    String *smallConstantName = createSmallIdentifierName(constantName, SCILAB_IDENTIFIER_NAME_CHAR_MAX - 4);
 
     /* Create GET function to get the constant value */
     Wrapper *getFunctionWrapper = NewWrapper();
     String *getFunctionName = Swig_name_get(NSPACE_TODO, constantName);
-    String *scilabGetFunctionName = Swig_name_get(NSPACE_TODO, scilabConstantName);
+    String *scilabGetSmallFunctionName = Swig_name_get(NSPACE_TODO, smallConstantName);
     Setattr(node, "wrap:name", getFunctionName);
-    Printv(getFunctionWrapper->def, "int ", getFunctionName, "(SWIG_GatewayParameters) {\n", NIL);
+    Setattr(node, "wrap:name", getFunctionName);
+    Printv(getFunctionWrapper->def, "SWIGEXPORT int ", getFunctionName, "(SWIG_GatewayParameters) {\n", NIL);
 
     /* Check the number of input and output */
     Printf(getFunctionWrapper->def, "SWIG_CheckInputArgument(pvApiCtx, 0, 0);\n");
-    Printf(getFunctionWrapper->def, "SWIG_CheckOutputArgument(pvApiCtx, 1, 1);\n");
+    Printf(getFunctionWrapper->def, "SWIG_CheckOutputArgument(pvApiCtx, 0, 1);\n");
     Printf(getFunctionWrapper->def, "SWIG_Scilab_SetApiContext(pvApiCtx);\n");
 
     constantTypemap = Swig_typemap_lookup("constcode", node, nodeName, 0);
@@ -737,7 +756,7 @@
     Wrapper_print(getFunctionWrapper, wrappersSection);
 
     /* Add the function to Scilab  */
-    addFunctionToScilab(scilabGetFunctionName, getFunctionName);
+    addFunctionToScilab(getFunctionName, scilabGetSmallFunctionName, getFunctionName);
 
     DelWrapper(getFunctionWrapper);
 
@@ -784,78 +803,13 @@
     return Language::enumvalueDeclaration(node);
   }
 
-  /* ---------------------------------------------------------------------
-   * membervariableHandler()
-   * --------------------------------------------------------------------- */
-  virtual int membervariableHandler(Node *node) {
-    checkMemberIdentifierName(node, SCILAB_VARIABLE_NAME_CHAR_MAX);
-    return Language::membervariableHandler(node);
-  }
-
-  /* -----------------------------------------------------------------------
-   * checkIdentifierName()
-   * If Scilab target version is lower than 6:
-   *   truncates (and displays a warning) too long member identifier names
-   *   (applies on members of structs, classes...)
-   *   (Scilab 5 identifier names are limited to 24 chars max)
-   * ----------------------------------------------------------------------- */
-
-  String *checkIdentifierName(String *name, int char_size_max) {
-    String *scilabIdentifierName;
-    if (targetVersion <= 5) {
-			if (Len(name) > char_size_max) {
-				scilabIdentifierName = DohNewStringWithSize(name, char_size_max);
-				Swig_warning(WARN_SCILAB_TRUNCATED_NAME, input_file, line_number,
-					"Identifier name '%s' exceeds 24 characters and has been truncated to '%s'.\n", name, scilabIdentifierName);
-			} else
-      scilabIdentifierName = name;
-		} else {
-			scilabIdentifierName = DohNewString(name);
-		}
-		return scilabIdentifierName;
-  }
-
-  /* -----------------------------------------------------------------------
-   * checkMemberIdentifierName()
-   * If Scilab target version is lower than 6:
-   *   truncates (and displays a warning) too long member identifier names
-   *   (applies on members of structs, classes...)
-   *   (Scilab 5 identifier names are limited to 24 chars max)
-   * ----------------------------------------------------------------------- */
-
-  void checkMemberIdentifierName(Node *node, int char_size_max) {
-    if (targetVersion <= 5) {
-      String *memberName = Getattr(node, "sym:name");
-      Node *containerNode = parentNode(node);
-      String *containerName = Getattr(containerNode, "sym:name");
-      int lenContainerName = Len(containerName);
-      int lenMemberName = Len(memberName);
-
-      if (lenContainerName + lenMemberName + 1 > char_size_max) {
-        int lenScilabMemberName = char_size_max - lenContainerName - 1;
-
-        if (lenScilabMemberName > 0) {
-	        String *scilabMemberName = DohNewStringWithSize(memberName, lenScilabMemberName);
-	        Setattr(node, "sym:name", scilabMemberName);
-	        Swig_warning(WARN_SCILAB_TRUNCATED_NAME, input_file, line_number,
-		        "Wrapping functions names for member '%s.%s' will exceed 24 characters, "
-		        "so member name has been truncated to '%s'.\n", containerName, memberName, scilabMemberName);
-        } else {
-	        Swig_error(input_file, line_number,
-		        "Wrapping functions names for member '%s.%s' will exceed 24 characters, "
-		        "please rename the container of member '%s'.\n", containerName, memberName, containerName);
-        }
-      }
-    }
-  }
-
   /* -----------------------------------------------------------------------
    * addHelperFunctions()
    * ----------------------------------------------------------------------- */
 
   void addHelperFunctions() {
-    addFunctionToScilab("SWIG_this", "SWIG_this");
-    addFunctionToScilab("SWIG_ptr", "SWIG_ptr");
+    addFunctionToScilab("SWIG_this", "SWIG_this", "SWIG_this");
+    addFunctionToScilab("SWIG_ptr", "SWIG_ptr", "SWIG_ptr");
   }
 
   /* -----------------------------------------------------------------------
@@ -863,20 +817,24 @@
    * Declare a wrapped function in Scilab (builder, gateway, XML, ...)
    * ----------------------------------------------------------------------- */
 
-  void addFunctionToScilab(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr wrapperFunctionName) {
+  void addFunctionToScilab(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr scilabSmallFunctionName, const_String_or_char_ptr wrapperFunctionName) {
     if (!generateBuilder)
-      addFunctionInGatewayHeader(scilabFunctionName, wrapperFunctionName);
+      addFunctionInGatewayHeader(scilabFunctionName, scilabSmallFunctionName, wrapperFunctionName);
 
     if (generateBuilder) {
-      addFunctionInScriptTable(scilabFunctionName, wrapperFunctionName, builderCode);
+      addFunctionInScriptTable(scilabFunctionName, scilabSmallFunctionName, wrapperFunctionName, builderCode5, builderCode6);
     }
 
     if (createLoader) {
-      addFunctionInLoader(scilabFunctionName);
+      addFunctionInLoader(scilabFunctionName, scilabSmallFunctionName);
     }
 
     if (gatewayXMLFile) {
-      Printf(gatewayXML, "<PRIMITIVE gatewayId=\"%s\" primitiveId=\"%d\" primitiveName=\"%s\"/>\n", gatewayID, primitiveID++, scilabFunctionName);
+      Printf(gatewayXML, "<PRIMITIVE gatewayId=\"%s\" primitiveId=\"%d\" primitiveName=\"%s\"/>\n", gatewayID, primitiveID++, scilabSmallFunctionName);
+    }
+
+    if (gatewayXMLFileV6) {
+      Printf(gatewayXMLV6, "<gateway name=\"%s\" function=\"%s\" type=\"0\"/>\n", scilabFunctionName, scilabFunctionName);
     }
   }
 
@@ -890,12 +848,14 @@
     builderFile = NewFile(builderFilename, "w", SWIG_output_files());
     if (!builderFile) {
       FileErrorDisplay(builderFilename);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
     emitBanner(builderFile);
 
     builderFunctionCount = 0;
     builderCode = NewString("");
+    builderCode5 = NewString("");
+    builderCode6 = NewString("");
     Printf(builderCode, "mode(-1);\n");
     Printf(builderCode, "lines(0);\n");	/* Useful for automatic tests */
 
@@ -945,7 +905,8 @@
       }
     }
 
-    Printf(builderCode, "table = [");
+    Printf(builderCode5, "table = [ ..\n");
+    Printf(builderCode6, "table = [ ..\n");
   }
 
   /* -----------------------------------------------------------------------
@@ -953,11 +914,13 @@
    * Add a function wrapper in the function table of generated builder script
    * ----------------------------------------------------------------------- */
 
-  void addFunctionInScriptTable(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr wrapperFunctionName, String *scriptCode) {
+  void addFunctionInScriptTable(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr scilabSmallFunctionName, const_String_or_char_ptr wrapperFunctionName, String *scriptCode5, String *scriptCode6) {
     if (++builderFunctionCount % 10 == 0) {
-      Printf(scriptCode, "];\ntable = [table;");
+      Printf(scriptCode5, "];\ntable = [table; ..\n");
+      Printf(scriptCode6, "];\ntable = [table; ..\n");
     }
-    Printf(scriptCode, "\"%s\",\"%s\";", scilabFunctionName, wrapperFunctionName);
+    Printf(scriptCode5, "\"%s\",\"%s\"; ..\n", scilabSmallFunctionName, wrapperFunctionName);
+    Printf(scriptCode6, "\"%s\",\"%s\"; ..\n", scilabFunctionName, wrapperFunctionName);
   }
 
   /* -----------------------------------------------------------------------
@@ -965,7 +928,26 @@
    * ----------------------------------------------------------------------- */
 
   void saveBuilderFile(String *gatewayName) {
-    Printf(builderCode, "];\n");
+    Printf(builderCode5, "];\n");
+    Printf(builderCode6, "];\n");
+
+    if (Equal(builderCode5, builderCode6)) {
+      Append(builderCode, builderCode6);
+    } else {
+      Printf(builderCode, "ver = getversion('scilab');\n");
+      Printf(builderCode, "if ver(1) < 6 then\n");
+      Printf(builderCode, "  // version is less or equal to 5.5.2\n");
+      Printf(builderCode, "  \n");
+      Append(builderCode, builderCode5);
+      Printf(builderCode, "  \n");
+      Printf(builderCode, "else\n");
+      Printf(builderCode, "  // version is 6.0.0 or more\n");
+      Printf(builderCode, "  \n");
+      Append(builderCode, builderCode6);
+      Printf(builderCode, "  \n");
+      Printf(builderCode, "end\n");
+    }
+
     Printf(builderCode, "ierr = 0;\n");
     Printf(builderCode, "if ~isempty(table) then\n");
     Printf(builderCode, "  ierr = execstr(\"ilib_build(''%s'', table, files, libs, [], ldflags, cflags);\", 'errcatch');\n", gatewayName);
@@ -978,10 +960,45 @@
     Printf(builderCode, "  error(ierr, err_msg);\n");
     Printf(builderCode, "end\n");
     Printv(builderFile, builderCode, NIL);
+
+    Delete(builderCode);
     Delete(builderFile);
   }
 
   /* -----------------------------------------------------------------------
+   * createGatewayXMLFileV6()
+   * This XML file is used by Scilab 6 in the context of internal modules or
+   * to get the function list.
+   * ----------------------------------------------------------------------- */
+
+  void createGatewayXMLFileV6(String *gatewayName) {
+    String *gatewayXMLFilename = NewStringf("%s_gateway.xml", gatewayName);
+    gatewayXMLFileV6 = NewFile(gatewayXMLFilename, "w", SWIG_output_files());
+    if (!gatewayXMLFileV6) {
+      FileErrorDisplay(gatewayXMLFilename);
+      Exit(EXIT_FAILURE);
+    }
+    // Add a slightly modified SWIG banner to the gateway XML ("--modify" is illegal in XML)
+    gatewayXMLV6 = NewString("");
+    Printf(gatewayXMLV6, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
+    Printf(gatewayXMLV6, "<!DOCTYPE module SYSTEM \"../../functions/xml/gateway.dtd\">\n");
+    Printf(gatewayXMLV6, "<!--\n");
+    Swig_banner_target_lang(gatewayXMLV6, "");
+    Printf(gatewayXMLV6, "-->\n");
+    Printf(gatewayXMLV6, "<module name=\"%s\">\n", gatewayName);
+  }
+
+  /* -----------------------------------------------------------------------
+   * saveGatewayXMLFileV6()
+   * ----------------------------------------------------------------------- */
+
+  void saveGatewayXMLFileV6() {
+    Printf(gatewayXMLV6, "</module>\n");
+    Printv(gatewayXMLFileV6, gatewayXMLV6, NIL);
+    Delete(gatewayXMLFileV6);
+  }
+
+  /* -----------------------------------------------------------------------
    * createGatewayXMLFile()
    * This XML file is used by Scilab in the context of internal modules
    * ----------------------------------------------------------------------- */
@@ -991,17 +1008,13 @@
     gatewayXMLFile = NewFile(gatewayXMLFilename, "w", SWIG_output_files());
     if (!gatewayXMLFile) {
       FileErrorDisplay(gatewayXMLFilename);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
     // Add a slightly modified SWIG banner to the gateway XML ("--modify" is illegal in XML)
     gatewayXML = NewString("");
     Printf(gatewayXML, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
     Printf(gatewayXML, "<!--\n");
-    Printf(gatewayXML, "This file was automatically generated by SWIG (http://www.swig.org).\n");
-    Printf(gatewayXML, "Version %s\n", Swig_package_version());
-    Printf(gatewayXML, "\n");
-    Printf(gatewayXML, "Do not make changes to this file unless you know what you are doing - modify\n");
-    Printf(gatewayXML, "the SWIG interface file instead.\n");
+    Swig_banner_target_lang(gatewayXML, "");
     Printf(gatewayXML, "-->\n");
     Printf(gatewayXML, "<GATEWAY name=\"%s\">\n", gatewayName);
 
@@ -1040,7 +1053,7 @@
     Printf(gatewayHeaderV6, "#ifdef __cplusplus\n");
     Printf(gatewayHeaderV6, "extern \"C\"\n");
     Printf(gatewayHeaderV6, "#endif\n");
-    Printf(gatewayHeaderV6, "int %s(wchar_t *pwstFuncName) {\n", gatewayLibraryName);
+    Printf(gatewayHeaderV6, "SWIGEXPORT int %s(wchar_t *pwstFuncName) {\n", gatewayLibraryName);
     Printf(gatewayHeaderV6, "\n");
   }
 
@@ -1049,13 +1062,13 @@
    * Add a function in the gateway header
    * ----------------------------------------------------------------------- */
 
-  void addFunctionInGatewayHeader(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr wrapperFunctionName) {
+  void addFunctionInGatewayHeader(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr scilabSmallFunctionName, const_String_or_char_ptr wrapperFunctionName) {
     if (gatewayHeaderV5 == NULL) {
       gatewayHeaderV5 = NewString("");
       Printf(gatewayHeaderV5, "static GenericTable Tab[] = {\n");
     } else
       Printf(gatewayHeaderV5, ",\n");
-    Printf(gatewayHeaderV5, " {(Myinterfun)sci_gateway, (GT)%s, (char *)\"%s\"}", wrapperFunctionName, scilabFunctionName);
+    Printf(gatewayHeaderV5, " {(Myinterfun)sci_gateway, (GT)%s, (char *)\"%s\"}", wrapperFunctionName, scilabSmallFunctionName);
 
     Printf(gatewayHeaderV6, "if (wcscmp(pwstFuncName, L\"%s\") == 0) { addCStackFunction((wchar_t *)L\"%s\", &%s, (wchar_t *)MODULE_NAME); }\n", scilabFunctionName, scilabFunctionName, wrapperFunctionName);
   }
@@ -1071,7 +1084,7 @@
     Printf(gatewayHeaderV5, "#ifdef __cplusplus\n");
     Printf(gatewayHeaderV5, "extern \"C\" {\n");
     Printf(gatewayHeaderV5, "#endif\n");
-    Printf(gatewayHeaderV5, "int C2F(%s)() {\n", gatewayLibraryName);
+    Printf(gatewayHeaderV5, "SWIGEXPORT int C2F(%s)() {\n", gatewayLibraryName);
     Printf(gatewayHeaderV5, "  Rhs = Max(0, Rhs);\n");
     Printf(gatewayHeaderV5, "  if (*(Tab[Fin-1].f) != NULL) {\n");
     Printf(gatewayHeaderV5, "    if(pvApiCtx == NULL) {\n");
@@ -1090,10 +1103,10 @@
     Printf(gatewayHeaderV6, "return 1;\n");
     Printf(gatewayHeaderV6, "};\n");
 
-    Printf(gatewayHeader, "#if SWIG_SCILAB_VERSION >= 600\n");
-    Printv(gatewayHeader, gatewayHeaderV6, NIL);
-    Printf(gatewayHeader, "#else\n");
+    Printf(gatewayHeader, "#if SCI_VERSION_MAJOR < 6\n");
     Printv(gatewayHeader, gatewayHeaderV5, NIL);
+    Printf(gatewayHeader, "#else\n");
+    Printv(gatewayHeader, gatewayHeaderV6, NIL);
     Printf(gatewayHeader, "#endif\n");
   }
 
@@ -1108,18 +1121,20 @@
     loaderFile = NewFile(loaderFilename, "w", SWIG_output_files());
     if (!loaderFile) {
       FileErrorDisplay(loaderFilename);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
 
     emitBanner(loaderFile);
 
-    loaderScript = NewString("");
-    Printf(loaderScript, "%s_path = get_absolute_file_path('loader.sce');\n", gatewayLibraryName);
-    Printf(loaderScript, "[bOK, ilib] = c_link('%s');\n", gatewayLibraryName);
-    Printf(loaderScript, "if bOK then\n");
-    Printf(loaderScript, "  ulink(ilib);\n");
-    Printf(loaderScript, "end\n");
-    Printf(loaderScript, "list_functions = [..\n");
+    loaderFunctionCount = 0;
+    loaderScript = NewString("function loader_function()\n");
+    Printf(loaderScript, "  p = get_absolute_file_path('loader.sce');\n", gatewayLibraryName);
+    Printf(loaderScript, "  [bOK, ilib] = c_link('%s');\n", gatewayLibraryName);
+    Printf(loaderScript, "  if bOK then\n");
+    Printf(loaderScript, "    ulink(ilib);\n");
+    Printf(loaderScript, "  end\n");
+    loaderScript5 = NewString("    list_functions = [ ..\n");
+    loaderScript6 = NewString("    list_functions = [ ..\n");
   }
 
   /* -----------------------------------------------------------------------
@@ -1127,8 +1142,13 @@
    * Add a function in the loader script table
    * ----------------------------------------------------------------------- */
 
-  void addFunctionInLoader(const_String_or_char_ptr scilabFunctionName) {
-    Printf(loaderScript, "  '%s'; ..\n", scilabFunctionName);
+  void addFunctionInLoader(const_String_or_char_ptr scilabFunctionName, const_String_or_char_ptr scilabSmallFunctionName) {
+    if (++loaderFunctionCount % 10 == 0) {
+      Printf(loaderScript5, "    ];\n    list_functions = [list_functions; ..\n");
+      Printf(loaderScript6, "    ];\n    list_functions = [list_functions; ..\n");
+    }
+    Printf(loaderScript5, "      '%s'; ..\n", scilabSmallFunctionName);
+    Printf(loaderScript6, "      '%s'; ..\n", scilabFunctionName);
   }
 
   /* -----------------------------------------------------------------------
@@ -1137,18 +1157,66 @@
    * ----------------------------------------------------------------------- */
 
   void saveLoaderFile(String *gatewayLibraryName) {
-    Printf(loaderScript, "];\n");
-    Printf(loaderScript, "addinter(fullfile(%s_path, '%s' + getdynlibext()), '%s', list_functions);\n",
-	   gatewayLibraryName, gatewayLibraryName, gatewayLibraryName);
-    Printf(loaderScript, "clear %s_path;\n", gatewayLibraryName);
-    Printf(loaderScript, "clear bOK;\n");
-    Printf(loaderScript, "clear ilib;\n");
-    Printf(loaderScript, "clear list_functions;\n");
+    Printf(loaderScript5, "    ];\n");
+    Printf(loaderScript6, "    ];\n");
+
+    if (Equal(loaderScript5, loaderScript6)) {
+      Append(loaderScript, loaderScript6);
+    } else {
+      Printf(loaderScript, "  ver = getversion('scilab');\n");
+      Printf(loaderScript, "  if ver(1) < 6 then\n");
+      Printf(loaderScript, "    // version is less or equal to 5.5.2\n");
+      Printf(loaderScript, "    \n");
+      Append(loaderScript, loaderScript5);
+      Delete(loaderScript5);
+      Printf(loaderScript, "    \n");
+      Printf(loaderScript, "  else\n");
+      Printf(loaderScript, "    // version is 6.0.0 or more\n");
+      Printf(loaderScript, "    \n");
+      Append(loaderScript, loaderScript6);
+      Delete(loaderScript6);
+      Printf(loaderScript, "    \n");
+      Printf(loaderScript, "  end\n");
+    }
+
+    Printf(loaderScript, "  addinter(p + '%s' + getdynlibext(), '%s', list_functions);\n", gatewayLibraryName, gatewayLibraryName);
+    Printf(loaderScript, "endfunction\n");
+    Printf(loaderScript, "loader_function();\n");
+    Printf(loaderScript, "clear loader_function;\n");
     Printv(loaderFile, loaderScript, NIL);
 
+    Delete(loaderScript);
     Delete(loaderFile);
   }
 
+  /* -----------------------------------------------------------------------
+   * createSmallIdentifierName()
+   * Create a Scilab small identifier to be used by Scilab 5
+   * ----------------------------------------------------------------------- */
+
+  String* createSmallIdentifierName(String* name, int outputLen = SCILAB_IDENTIFIER_NAME_CHAR_MAX) {
+    char* s = Char(name);
+    int nameLen = Len(s);
+
+    // truncate and preserve common suffix
+    if (outputLen > 4 && nameLen > outputLen) {
+      String* smallName = NewStringWithSize(name, outputLen);
+      char* smallNameStr = (char*) Data(smallName);
+
+      if (s[nameLen-4] == '_' && s[nameLen - 3] == 'g' && s[nameLen - 2] == 'e' && s[nameLen - 1] == 't') {
+        // get
+        memcpy(&smallNameStr[outputLen - 4], &s[nameLen - 4], 4);
+      } else if (s[nameLen-4] == '_' && s[nameLen - 3] == 's' && s[nameLen - 2] == 'e' && s[nameLen - 1] == 't') {
+        // set
+        memcpy(&smallNameStr[outputLen - 4], &s[nameLen - 4], 4);
+      }
+
+      return smallName;
+    }
+    
+    return name;
+  }
+
 };
 
 extern "C" Language *swig_scilab(void) {
diff --git a/Source/Modules/swigmain.cxx b/Source/Modules/swigmain.cxx
index 8d52af1..90fe2f0 100644
--- a/Source/Modules/swigmain.cxx
+++ b/Source/Modules/swigmain.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * swigmain.cxx
  *
@@ -52,9 +52,9 @@
 
 static TargetLanguageModule modules[] = {
   {"-allegrocl", NULL, "ALLEGROCL", Disabled},
+  {"-cffi", NULL, "CFFI", Disabled},
   {"-chicken", NULL, "CHICKEN", Disabled},
   {"-clisp", NULL, "CLISP", Disabled},
-  {"-cffi", NULL, "CFFI", Disabled},
   {"-csharp", swig_csharp, "C#", Supported},
   {"-d", swig_d, "D", Supported},
   {"-go", swig_go, "Go", Supported},
@@ -70,7 +70,7 @@
   {"-perl5", swig_perl5, "Perl 5", Supported},
   {"-php", swig_php, NULL, Supported},
   {"-php5", NULL, "PHP 5", Disabled},
-  {"-php7", swig_php, "PHP 7", Supported},
+  {"-php7", swig_php, "PHP 8 or later", Supported},
   {"-pike", NULL, "Pike", Disabled},
   {"-python", swig_python, "Python", Supported},
   {"-r", swig_r, "R (aka GNU S)", Supported},
@@ -84,11 +84,6 @@
   {NULL, NULL, NULL, Disabled}
 };
 
-#ifdef MACSWIG
-#include <console.h>
-#include <SIOUX.h>
-#endif
-
 //-----------------------------------------------------------------
 // main()
 //
@@ -98,15 +93,15 @@
 void SWIG_merge_envopt(const char *env, int oargc, char *oargv[], int *nargc, char ***nargv) {
   if (!env) {
     *nargc = oargc;
-    *nargv = (char **)malloc(sizeof(char *) * (oargc + 1));
+    *nargv = (char **)Malloc(sizeof(char *) * (oargc + 1));
     memcpy(*nargv, oargv, sizeof(char *) * (oargc + 1));
     return;
   }
 
   int argc = 1;
   int arge = oargc + 1024;
-  char **argv = (char **) malloc(sizeof(char *) * (arge + 1));
-  char *buffer = (char *) malloc(2048);
+  char **argv = (char **) Malloc(sizeof(char *) * (arge + 1));
+  char *buffer = (char *) Malloc(2048);
   char *b = buffer;
   char *be = b + 1023;
   const char *c = env;
@@ -139,11 +134,11 @@
   size_t option_len = end - start;
 
   // Preserve the NULL pointer at argv[argc]
-  new_argv = (char **)realloc(new_argv, (new_argc + 2) * sizeof(char *));
+  new_argv = (char **)Realloc(new_argv, (new_argc + 2) * sizeof(char *));
   memmove(&new_argv[index + 1], &new_argv[index], sizeof(char *) * (new_argc + 1 - index));
   new_argc++;
 
-  new_argv[index] = (char *)malloc(option_len + 1);
+  new_argv[index] = (char *)Malloc(option_len + 1);
   memcpy(new_argv[index], start, option_len);
   new_argv[index][option_len] = '\0';
 
@@ -163,7 +158,7 @@
   i = 1;
   while (i < new_argc) {
     if (new_argv[i] && new_argv[i][0] == '@' && (f = fopen(&new_argv[i][1], "r"))) {
-      char c;
+      int ci;
       char *b;
       char *be = &buffer[BUFFER_SIZE];
       int quote = 0;
@@ -174,7 +169,8 @@
       insert = i;
       b = buffer;
 
-      while ((c = fgetc(f)) != EOF) {
+      while ((ci = fgetc(f)) != EOF) {
+        const char c = static_cast<char>(ci);
         if (escape) {
           if (b != be) {
             *b = c;
@@ -218,14 +214,11 @@
   int argc;
   char **argv;
 
+  /* Check for SWIG_FEATURES environment variable */
+
   SWIG_merge_envopt(getenv("SWIG_FEATURES"), margc, margv, &argc, &argv);
   merge_options_files(&argc, &argv);
 
-#ifdef MACSWIG
-  SIOUXSettings.asktosaveonclose = false;
-  argc = ccommand(&argv);
-#endif
-
   Swig_init_args(argc, argv);
 
   /* Get options */
@@ -246,7 +239,7 @@
 	    Printf(stderr, "Target language option %s (%s) is no longer supported.\n", language_module->name, language_module->help);
 	  else
 	    Printf(stderr, "Target language option %s is no longer supported.\n", language_module->name);
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	}
       } else if ((strcmp(argv[i], "-help") == 0) || (strcmp(argv[i], "--help") == 0)) {
 	if (strcmp(argv[i], "--help") == 0)
diff --git a/Source/Modules/swigmod.h b/Source/Modules/swigmod.h
index bfb93d1..c146d17 100644
--- a/Source/Modules/swigmod.h
+++ b/Source/Modules/swigmod.h
@@ -4,15 +4,15 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * swigmod.h
  *
  * Main header file for SWIG modules.
  * ----------------------------------------------------------------------------- */
 
-#ifndef SWIG_SWIGMOD_H_
-#define SWIG_SWIGMOD_H_
+#ifndef SWIG_SWIGMOD_H
+#define SWIG_SWIGMOD_H
 
 #include "swig.h"
 #include "preprocessor.h"
@@ -33,7 +33,6 @@
 extern int NoExcept;		// -no_except option
 extern int Abstract;		// abstract base class
 extern int SmartPointer;	// smart pointer methods being emitted
-extern int SwigRuntime;
 
 /* Overload "argc" and "argv" */
 extern String *argv_template_string;
@@ -99,6 +98,8 @@
 
 protected:
   AccessMode cplus_mode;
+  AccessMode accessModeFromString(String *access);
+  int abstractClassTest(Node *n);	/* Is class really abstract? */
 };
 
 /* ----------------------------------------------------------------------------
@@ -196,7 +197,7 @@
   virtual int classDirector(Node *n);
   virtual int classDirectorInit(Node *n);
   virtual int classDirectorEnd(Node *n);
-  virtual int unrollVirtualMethods(Node *n, Node *parent, List *vm, int default_director, int &virtual_destructor, int protectedbase = 0);
+  virtual int unrollVirtualMethods(Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase = 0);
   virtual int classDirectorConstructor(Node *n);
   virtual int classDirectorDefaultConstructor(Node *n);
   virtual int classDirectorMethod(Node *n, Node *parent, String *super);
@@ -211,13 +212,12 @@
   virtual int addInterfaceSymbol(const String *interface_name, Node *n, const_String_or_char_ptr scope = "");
   virtual void dumpSymbols();
   virtual Node *symbolLookup(const String *s, const_String_or_char_ptr scope = ""); /* Symbol lookup */
-  virtual Hash* symbolAddScope(const_String_or_char_ptr scope);
+  virtual Hash* symbolAddScope(const_String_or_char_ptr scope/*, Node *n = 0*/);
   virtual Hash* symbolScopeLookup(const_String_or_char_ptr scope);
   virtual Hash* symbolScopePseudoSymbolLookup(const_String_or_char_ptr scope);
   static Node *classLookup(const SwigType *s); /* Class lookup      */
   static Node *enumLookup(SwigType *s);	/* Enum lookup       */
-  virtual int abstractClassTest(Node *n);	/* Is class really abstract? */
-  virtual int is_assignable(Node *n);	/* Is variable assignable? */
+  virtual int is_immutable(Node *n);	/* Is variable assignable? */
   virtual String *runtimeCode();	/* returns the language specific runtime code */
   virtual String *defaultExternalRuntimeFilename();	/* the default filename for the external runtime */
   virtual void replaceSpecialVariables(String *method, String *tm, Parm *parm); /* Language specific special variable substitutions for $typemap() */
@@ -228,12 +228,12 @@
   /* Returns the cplus_runtime mode */
   int cplus_runtime_mode();
 
+  /* Flag for language to support directors */
+  void directorLanguage(int val = 1);
+
   /* Allow director related code generation */
   void allow_directors(int val = 1);
 
-  /* Return true if directors are enabled */
-  int directorsEnabled() const;
-
   /* Allow director protected members related code generation */
   void allow_dirprot(int val = 1);
 
@@ -243,10 +243,10 @@
   /* Returns the dirprot mode */
   int dirprot_mode() const;
 
-  /* Check if the non public constructor is  needed (for directors) */
+  /* Check if the non public constructor is needed (for directors) */
   int need_nonpublic_ctor(Node *n);
 
-  /* Check if the non public member is  needed (for directors) */
+  /* Check if the non public member is needed (for directors) */
   int need_nonpublic_member(Node *n);
 
   /* Set none comparison string */
@@ -333,24 +333,23 @@
   /* Director constructor "template" code */
   String *director_ctor_code;
 
-  /* Director 'protected' constructor "template" code */
+  /* Director 'protected' constructor "template" code, disabled by
+     default. Each language that needs it, has to define it. */
   String *director_prot_ctor_code;
 
   /* Director allows multiple inheritance */
   int director_multiple_inheritance;
 
-  /* Director language module */
-  int director_language;
-
   /* Used to translate Doxygen comments to target documentation format */
   class DoxygenTranslator *doxygenTranslator;
 
 private:
+  void unrollOneVirtualMethod(String *classname, Node *n, Node *parent, List *vm, int &virtual_destructor, int protectedbase);
+
   Hash *symtabs; /* symbol tables */
   int overloading;
   int multiinput;
   int cplus_runtime;
-  int directors;
   static Language *this_;
 };
 
@@ -394,6 +393,7 @@
 List *Swig_overload_rank(Node *n, bool script_lang_wrapping);
 SwigType *cplus_value_type(SwigType *t);
 
+int Swig_directors_enabled();
 /* directors.cxx start */
 String *Swig_csuperclass_call(String *base, String *method, ParmList *l);
 String *Swig_class_declaration(Node *n, String *name);
@@ -403,6 +403,7 @@
 String *Swig_director_declaration(Node *n);
 void Swig_director_emit_dynamic_cast(Node *n, Wrapper *f);
 void Swig_director_parms_fixup(ParmList *parms);
+bool Swig_director_can_unwrap(Node *n);
 /* directors.cxx end */
 
 /* Utilities */
@@ -428,16 +429,14 @@
   void Swig_print_with_location(DOH *object, int count = -1);
 }
 
+void Swig_default_allocators(Node *n);
+void Swig_process_types(Node *n);
+
 /* Contracts */
 void Swig_contracts(Node *n);
 void Swig_contract_mode_set(int flag);
 int Swig_contract_mode_get();
 
-/* Browser */
-void Swig_browser(Node *n, int);
-void Swig_default_allocators(Node *n);
-void Swig_process_types(Node *n);
-
 /* Nested classes */
 void Swig_nested_process_classes(Node *n);
 void Swig_nested_name_unnamed_c_structs(Node *n);
diff --git a/Source/Modules/tcl8.cxx b/Source/Modules/tcl8.cxx
index 7a78ede..02d580c 100644
--- a/Source/Modules/tcl8.cxx
+++ b/Source/Modules/tcl8.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * tcl8.cxx
  *
@@ -113,7 +113,7 @@
 	} else if (strcmp(argv[i], "-nocppcast") == 0) {
 	  Printf(stderr, "Deprecated command line option: %s. This option is no longer supported.\n", argv[i]);
 	  Swig_mark_arg(i);
-	  SWIG_exit(EXIT_FAILURE);
+	  Exit(EXIT_FAILURE);
 	}
       }
     }
@@ -138,7 +138,7 @@
     f_begin = NewFile(outfile, "w", SWIG_output_files());
     if (!f_begin) {
       FileErrorDisplay(outfile);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
     f_runtime = NewString("");
     f_init = NewString("");
@@ -161,7 +161,7 @@
 
     Swig_banner(f_begin);
 
-    Printf(f_runtime, "\n\n#ifndef SWIGTCL\n#define SWIGTCL\n#endif\n\n");
+    Swig_obligatory_macros(f_runtime, "TCL");
 
     /* Set the module name, namespace, and prefix */
 
@@ -182,7 +182,7 @@
 
       if ((f_shadow = NewFile(filen, "w", SWIG_output_files())) == 0) {
 	FileErrorDisplay(filen);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
       f_shadow_stubs = NewString("");
 
@@ -302,7 +302,7 @@
     }
     Setattr(n, "wrap:name", wname);
 
-    Printv(f->def, "SWIGINTERN int\n ", wname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {", NIL);
+    Printv(f->def, "SWIGINTERN int\n ", wname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) {", NIL);
 
     // Emit all of the local variables for holding arguments.
     emit_parameter_variables(parms, f);
@@ -336,8 +336,6 @@
       if ((tm = Getattr(p, "tmap:in"))) {
 	String *parse = Getattr(p, "tmap:in:parse");
 	if (!parse) {
-	  Replaceall(tm, "$target", ln);
-	  Replaceall(tm, "$source", source);
 	  Replaceall(tm, "$input", source);
 	  Setattr(p, "emit:input", source);
 
@@ -401,7 +399,6 @@
     /* Insert constraint checking code */
     for (p = parms; p;) {
       if ((tm = Getattr(p, "tmap:check"))) {
-	Replaceall(tm, "$target", Getattr(p, "lname"));
 	Printv(f->code, tm, "\n", NIL);
 	p = Getattr(p, "tmap:check:next");
       } else {
@@ -414,7 +411,6 @@
       if (!checkAttribute(p, "tmap:in:numinputs", "0")
 	  && !Getattr(p, "tmap:in:parse") && (tm = Getattr(p, "tmap:freearg"))) {
 	if (Len(tm) != 0) {
-	  Replaceall(tm, "$source", Getattr(p, "lname"));
 	  Printv(cleanup, tm, "\n", NIL);
 	}
 	p = Getattr(p, "tmap:freearg:next");
@@ -426,12 +422,9 @@
     /* Insert argument output code */
     for (i = 0, p = parms; p; i++) {
       if ((tm = Getattr(p, "tmap:argout"))) {
-	Replaceall(tm, "$source", Getattr(p, "lname"));
 #ifdef SWIG_USE_RESULTOBJ
-	Replaceall(tm, "$target", "resultobj");
 	Replaceall(tm, "$result", "resultobj");
 #else
-	Replaceall(tm, "$target", "(Tcl_GetObjResult(interp))");
 	Replaceall(tm, "$result", "(Tcl_GetObjResult(interp))");
 #endif
 	Replaceall(tm, "$arg", Getattr(p, "emit:input"));
@@ -450,12 +443,9 @@
 
     /* Return value if necessary  */
     if ((tm = Swig_typemap_lookup_out("out", n, Swig_cresult_name(), f, actioncode))) {
-      Replaceall(tm, "$source", Swig_cresult_name());
 #ifdef SWIG_USE_RESULTOBJ
-      Replaceall(tm, "$target", "resultobj");
       Replaceall(tm, "$result", "resultobj");
 #else
-      Replaceall(tm, "$target", "(Tcl_GetObjResult(interp))");
       Replaceall(tm, "$result", "(Tcl_GetObjResult(interp))");
 #endif
       if (GetFlag(n, "feature:new")) {
@@ -478,13 +468,11 @@
     /* Look for any remaining cleanup */
     if (GetFlag(n, "feature:new")) {
       if ((tm = Swig_typemap_lookup("newfree", n, Swig_cresult_name(), 0))) {
-	Replaceall(tm, "$source", Swig_cresult_name());
 	Printf(f->code, "%s\n", tm);
       }
     }
 
     if ((tm = Swig_typemap_lookup("ret", n, Swig_cresult_name(), 0))) {
-      Replaceall(tm, "$source", Swig_cresult_name());
       Printf(f->code, "%s\n", tm);
     }
 #ifdef SWIG_USE_RESULTOBJ
@@ -516,8 +504,8 @@
 	Wrapper *df = NewWrapper();
 	String *dname = Swig_name_wrapper(iname);
 
-	Printv(df->def, "SWIGINTERN int\n", dname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) {", NIL);
-	Printf(df->code, "Tcl_Obj *CONST *argv = objv+1;\n");
+	Printv(df->def, "SWIGINTERN int\n", dname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) {", NIL);
+	Printf(df->code, "Tcl_Obj *const *argv = objv+1;\n");
 	Printf(df->code, "int argc = objc-1;\n");
 	Printv(df->code, dispatch, "\n", NIL);
 	Node *sibl = n;
@@ -580,13 +568,11 @@
     Printv(getf->def, "SWIGINTERN const char *", getfname, "(ClientData clientData SWIGUNUSED, Tcl_Interp *interp, char *name1, char *name2, int flags) {", NIL);
     Wrapper_add_local(getf, "value", "Tcl_Obj *value = 0");
     if ((tm = Swig_typemap_lookup("varout", n, name, 0))) {
-      Replaceall(tm, "$source", name);
-      Replaceall(tm, "$target", "value");
       Replaceall(tm, "$result", "value");
       /* Printf(getf->code, "%s\n",tm); */
       addfail = emit_action_code(n, getf->code, tm);
       Printf(getf->code, "if (value) {\n");
-      Printf(getf->code, "Tcl_SetVar2(interp,name1,name2,Tcl_GetStringFromObj(value,NULL), flags);\n");
+      Printf(getf->code, "Tcl_SetVar2(interp,name1,name2,Tcl_GetString(value), flags);\n");
       Printf(getf->code, "Tcl_DecrRefCount(value);\n");
       Printf(getf->code, "}\n");
       Printf(getf->code, "return NULL;\n");
@@ -604,7 +590,7 @@
     DelWrapper(getf);
 
     /* Try to create a function setting a variable */
-    if (is_assignable(n)) {
+    if (!is_immutable(n)) {
       setf = NewWrapper();
       setname = Swig_name_set(NSPACE_TODO, iname);
       setfname = Swig_name_wrapper(setname);
@@ -616,8 +602,6 @@
         Wrapper_add_local(setf, "name1o", "Tcl_Obj *name1o = 0");
 
         if ((tm = Swig_typemap_lookup("varin", n, name, 0))) {
-	  Replaceall(tm, "$source", "value");
-	  Replaceall(tm, "$target", name);
 	  Replaceall(tm, "$input", "value");
 	  Printf(setf->code, "name1o = Tcl_NewStringObj(name1,-1);\n");
 	  Printf(setf->code, "value = Tcl_ObjGetVar2(interp, name1o, 0, flags);\n");
@@ -690,14 +674,10 @@
     }
 
     if ((tm = Swig_typemap_lookup("consttab", n, name, 0))) {
-      Replaceall(tm, "$source", value);
-      Replaceall(tm, "$target", name);
       Replaceall(tm, "$value", value);
       Replaceall(tm, "$nsname", nsname);
       Printf(const_tab, "%s,\n", tm);
     } else if ((tm = Swig_typemap_lookup("constcode", n, name, 0))) {
-      Replaceall(tm, "$source", value);
-      Replaceall(tm, "$target", name);
       Replaceall(tm, "$value", value);
       Replaceall(tm, "$nsname", nsname);
       Printf(f_init, "%s\n", tm);
@@ -732,7 +712,7 @@
   virtual int classHandler(Node *n) {
     static Hash *emitted = NewHash();
     String *mangled_classname = 0;
-    String *real_classname = 0;
+    SwigType *real_classname = 0;
 
     have_constructor = 0;
     have_destructor = 0;
@@ -760,7 +740,7 @@
       return SWIG_ERROR;
 
     real_classname = Getattr(n, "name");
-    mangled_classname = Swig_name_mangle(real_classname);
+    mangled_classname = Swig_name_mangle_type(real_classname);
 
     if (Getattr(emitted, mangled_classname))
       return SWIG_NOWRAP;
@@ -826,7 +806,7 @@
       int index = 0;
       b = First(baselist);
       while (b.item) {
-	String *bname = Getattr(b.item, "name");
+	SwigType *bname = Getattr(b.item, "name");
 	if ((!bname) || GetFlag(b.item, "feature:ignore") || (!Getattr(b.item, "module"))) {
 	  b = Next(b);
 	  continue;
@@ -836,7 +816,7 @@
 	  Printv(base_classes, bname, " ", NIL);
 	  Printv(base_class_init, "    ", bname, "Ptr::constructor $ptr\n", NIL);
 	}
-	String *bmangle = Swig_name_mangle(bname);
+	String *bmangle = Swig_name_mangle_type(bname);
 	//      Printv(f_wrappers,"extern swig_class _wrap_class_", bmangle, ";\n", NIL);
 	//      Printf(base_class,"&_wrap_class_%s",bmangle);
 	Printf(base_class, "0");
@@ -845,6 +825,7 @@
 
 	//Printf(f_init,"/* Register base : %s */\n", bmangle);
 	//Printf(f_init,"swig_%s_bases[%d] = (swig_class *) SWIG_TypeQuery(\"%s *\")->clientdata;\n",  mangled_classname, index, SwigType_namestr(bname));
+	(void)index;
 	b = Next(b);
 	index++;
 	Putc(',', base_class);
@@ -909,7 +890,7 @@
       //  Add methods
       if (have_methods) {
 	Printv(ptrclass, imethods, NIL);
-      };
+      }
 
       //  Close out the pointer class
       Printv(ptrclass, "}\n\n", NIL);
@@ -967,7 +948,7 @@
     if (!itcl) {
       Printv(cmd_tab, tab4, "{ SWIG_prefix \"", class_name, "\", (swig_wrapper_func) SWIG_ObjectConstructor, (ClientData)&_wrap_class_", mangled_classname,
 	     "},\n", NIL);
-    };
+    }
 
     Delete(t);
     Delete(mangled_classname);
@@ -1043,7 +1024,7 @@
 	Printv(imethods, "{ ", ns_name, "::", class_name, "_", realname, " $swigobj", NIL);
       } else {
 	Printv(imethods, "{ ", class_name, "_", realname, " $swigobj", NIL);
-      };
+      }
 
       pnum = 0;
       for (p = l; p; p = nextSibling(p)) {
diff --git a/Source/Modules/typepass.cxx b/Source/Modules/typepass.cxx
index 8dbf086..aa35c4e 100644
--- a/Source/Modules/typepass.cxx
+++ b/Source/Modules/typepass.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * typepass.cxx
  *
@@ -253,47 +253,35 @@
     int len = Len(ilist);
     int i;
     for (i = 0; i < len; i++) {
-      Node *n = Getitem(ilist, i);
-      String *bname = Getattr(n, "name");
-      Node *bclass = n;		/* Getattr(n,"class"); */
+      Node *bclass = Getitem(ilist, i);
+      SwigType *bname = Getattr(bclass, "name");
       Hash *scopes = Getattr(bclass, "typescope");
       SwigType_inherit(clsname, bname, cast, 0);
       if (ispublic && !GetFlag(bclass, "feature:ignore")) {
-	String *smartptr = Getattr(first, "feature:smartptr");
-	if (smartptr) {
-	  SwigType *smart = Swig_cparse_smartptr(first);
-	  if (smart) {
-	    /* Record a (fake) inheritance relationship between smart pointer
-	       and smart pointer to base class, so that smart pointer upcasts
-	       are automatically generated. */
-	    SwigType *bsmart = Copy(smart);
-	    SwigType *rclsname = SwigType_typedef_resolve_all(clsname);
-	    SwigType *rbname = SwigType_typedef_resolve_all(bname);
-	    int replace_count = Replaceall(bsmart, rclsname, rbname);
-	    if (replace_count == 0) {
-	      // If no replacement made, it will be because rclsname is fully resolved, but the
-	      // type in the smartptr feature used a typedef or not fully resolved name.
-	      String *firstname = Getattr(first, "name");
-	      Replaceall(bsmart, firstname, rbname);
-	    }
-	    Delete(rclsname);
-	    Delete(rbname);
+	String *smart = Getattr(first, "smart");
+	if (smart) {
+	  /* Record a (fake) inheritance relationship between smart pointer
+	     and smart pointer to base class, so that smart pointer upcasts
+	     are automatically generated. */
+	  SwigType *bsmart = Getattr(bclass, "smart");
+	  if (bsmart) {
 	    String *smartnamestr = SwigType_namestr(smart);
 	    String *bsmartnamestr = SwigType_namestr(bsmart);
+
 	    /* construct casting code */
 	    String *convcode = NewStringf("\n    *newmemory = SWIG_CAST_NEW_MEMORY;\n    return (void *) new %s(*(%s *)$from);\n", bsmartnamestr, smartnamestr);
-	    Delete(bsmartnamestr);
-	    Delete(smartnamestr);
+
 	    /* setup inheritance relationship between smart pointer templates */
 	    SwigType_inherit(smart, bsmart, 0, convcode);
-	    if (!GetFlag(bclass, "feature:smartptr"))
-	      Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Base class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(bclass, "name")), SwigType_namestr(Getattr(first, "name")));
+
+	    Delete(bsmartnamestr);
+	    Delete(smartnamestr);
 	    Delete(convcode);
-	    Delete(bsmart);
+	  } else {
+	    Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Base class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(bclass, "name")), SwigType_namestr(Getattr(first, "name")));
 	  }
-	  Delete(smart);
 	} else {
-	  if (GetFlag(bclass, "feature:smartptr"))
+	  if (GetFlag(bclass, "smart"))
 	    Swig_warning(WARN_LANG_SMARTPTR_MISSING, Getfile(first), Getline(first), "Derived class '%s' of '%s' is not similarly marked as a smart pointer.\n", SwigType_namestr(Getattr(first, "name")), SwigType_namestr(Getattr(bclass, "name")));
 	}
       }
@@ -454,8 +442,10 @@
 	    SwigType_typedef_class(fname);
 	    scopename = Copy(fname);
 	  } else {
-	    Swig_warning(WARN_TYPE_REDEFINED, Getfile(n), Getline(n), "Template '%s' was already wrapped,\n", SwigType_namestr(name));
-	    Swig_warning(WARN_TYPE_REDEFINED, Getfile(cn), Getline(cn), "previous wrap of '%s'.\n", SwigType_namestr(Getattr(cn, "name")));
+	    // Arguably the parser should instead ignore these duplicate template instantiations, in particular for ensuring the first parsed instantiation is used
+	    SetFlag(n, "feature:ignore");
+	    Swig_warning(WARN_TYPE_REDEFINED, Getfile(n), Getline(n), "Duplicate template instantiation of '%s' with name '%s' ignored,\n", SwigType_namestr(name), Getattr(n, "sym:name"));
+	    Swig_warning(WARN_TYPE_REDEFINED, Getfile(cn), Getline(cn), "previous instantiation of '%s' with name '%s'.\n", SwigType_namestr(Getattr(cn, "name")), Getattr(cn, "sym:name"));
 	    scopename = 0;
 	  }
 	} else {
@@ -510,6 +500,16 @@
     SwigType_new_scope(scopename);
     SwigType_attach_symtab(Getattr(n, "symtab"));
 
+    if (!GetFlag(n, "feature:ignore")) {
+      SwigType *smart = Swig_cparse_smartptr(n);
+      if (smart) {
+	// Resolve the type in 'feature:smartptr' in the scope of the class it is attached to
+	normalize_type(smart);
+	Setattr(n, "smart", smart);
+	Delete(smart);
+      }
+    }
+
     /* Inherit type definitions into the class */
     if (name && !(GetFlag(n, "nested") && !checkAttribute(n, "access", "public") && 
       (GetFlag(n, "feature:flatnested") || Language::instance()->nestedClassesSupport() == Language::NCS_None))) {
@@ -961,7 +961,7 @@
       if (Getattr(c, "sym:overloaded") != checkoverloaded) {
         Printf(stdout, "sym:overloaded error c:%p checkoverloaded:%p\n", c, checkoverloaded);
         Swig_print_node(c);
-        SWIG_exit(EXIT_FAILURE);
+        Exit(EXIT_FAILURE);
       }
 
       String *decl = Strcmp(nodeType(c), "using") == 0 ? NewString("------") : Getattr(c, "decl");
@@ -969,7 +969,7 @@
       if (!Getattr(c, "sym:overloaded")) {
         Printf(stdout, "sym:overloaded error.....%p\n", c);
         Swig_print_node(c);
-        SWIG_exit(EXIT_FAILURE);
+        Exit(EXIT_FAILURE);
       }
       c = Getattr(c, "sym:nextSibling");
     }
@@ -1011,189 +1011,16 @@
       } else {
 	ns = 0;
       }
-      if (!ns) {
-	if (is_public(n)) {
-	  Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(n), Getline(n), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(n, "uname")));
-	}
-      } else {
+      // Note that Allocate::usingDeclaration will warn when using member is not found (when ns is zero)
+      if (ns) {
 	/* Only a single symbol is being used.  There are only a few symbols that
 	   we actually care about.  These are typedef, class declarations, and enum */
 	String *ntype = nodeType(ns);
-	if (Strcmp(ntype, "cdecl") == 0) {
+	if (Equal(ntype, "cdecl") || Equal(ntype, "constructor")) {
 	  if (checkAttribute(ns, "storage", "typedef")) {
 	    /* A typedef declaration */
 	    String *uname = Getattr(n, "uname");
 	    SwigType_typedef_using(uname);
-	  } else {
-	    /* A normal C declaration. */
-	    if ((inclass) && (!GetFlag(n, "feature:ignore")) && (Getattr(n, "sym:name"))) {
-	      Node *c = ns;
-	      Node *unodes = 0, *last_unodes = 0;
-	      int ccount = 0;
-	      String *symname = Getattr(n, "sym:name");
-	      while (c) {
-		if (Strcmp(nodeType(c), "cdecl") == 0) {
-		  if (!(Swig_storage_isstatic(c)
-			|| checkAttribute(c, "storage", "typedef")
-			|| checkAttribute(c, "storage", "friend")
-			|| (Getattr(c, "feature:extend") && !Getattr(c, "code"))
-			|| GetFlag(c, "feature:ignore"))) {
-
-		    /* Don't generate a method if the method is overridden in this class, 
-		     * for example don't generate another m(bool) should there be a Base::m(bool) :
-		     * struct Derived : Base { 
-		     *   void m(bool);
-		     *   using Base::m;
-		     * };
-		     */
-		    String *csymname = Getattr(c, "sym:name");
-		    if (!csymname || (Strcmp(csymname, symname) == 0)) {
-		      {
-			String *decl = Getattr(c, "decl");
-			Node *over = Getattr(n, "sym:overloaded");
-			int match = 0;
-			while (over) {
-			  String *odecl = Getattr(over, "decl");
-			  if (Cmp(decl, odecl) == 0) {
-			    match = 1;
-			    break;
-			  }
-			  over = Getattr(over, "sym:nextSibling");
-			}
-			if (match) {
-			  c = Getattr(c, "csym:nextSibling");
-			  continue;
-			}
-		      }
-		      Node *nn = copyNode(c);
-		      Delattr(nn, "access");	// access might be different from the method in the base class
-		      Setattr(nn, "access", Getattr(n, "access"));
-		      if (!Getattr(nn, "sym:name"))
-			Setattr(nn, "sym:name", symname);
-
-		      if (!GetFlag(nn, "feature:ignore")) {
-			ParmList *parms = CopyParmList(Getattr(c, "parms"));
-			int is_pointer = SwigType_ispointer_return(Getattr(nn, "decl"));
-			int is_void = checkAttribute(nn, "type", "void") && !is_pointer;
-			Setattr(nn, "parms", parms);
-			Delete(parms);
-			if (Getattr(n, "feature:extend")) {
-			  String *ucode = is_void ? NewStringf("{ self->%s(", Getattr(n, "uname")) : NewStringf("{ return self->%s(", Getattr(n, "uname"));
-
-			  for (ParmList *p = parms; p;) {
-			    Append(ucode, Getattr(p, "name"));
-			    p = nextSibling(p);
-			    if (p)
-			      Append(ucode, ",");
-			  }
-			  Append(ucode, "); }");
-			  Setattr(nn, "code", ucode);
-			  Delete(ucode);
-			}
-			ParmList *throw_parm_list = Getattr(c, "throws");
-			if (throw_parm_list)
-			  Setattr(nn, "throws", CopyParmList(throw_parm_list));
-			ccount++;
-			if (!last_unodes) {
-			  last_unodes = nn;
-			  unodes = nn;
-			} else {
-			  Setattr(nn, "previousSibling", last_unodes);
-			  Setattr(last_unodes, "nextSibling", nn);
-			  Setattr(nn, "sym:previousSibling", last_unodes);
-			  Setattr(last_unodes, "sym:nextSibling", nn);
-			  Setattr(nn, "sym:overloaded", unodes);
-			  Setattr(unodes, "sym:overloaded", unodes);
-			  last_unodes = nn;
-			}
-		      } else {
-			Delete(nn);
-		      }
-		    }
-		  }
-		}
-		c = Getattr(c, "csym:nextSibling");
-	      }
-	      if (unodes) {
-		set_firstChild(n, unodes);
-		if (ccount > 1) {
-		  if (!Getattr(n, "sym:overloaded")) {
-		    Setattr(n, "sym:overloaded", n);
-		    Setattr(n, "sym:overname", "_SWIG_0");
-		  }
-		}
-	      }
-
-	      /* Hack the parse tree symbol table for overloaded methods. Replace the "using" node with the
-	       * list of overloaded methods we have just added in as child nodes to the "using" node.
-	       * The node will still exist, it is just the symbol table linked list of overloaded methods
-	       * which is hacked. */
-	      if (Getattr(n, "sym:overloaded")) {
-		int cnt = 0;
-#ifdef DEBUG_OVERLOADED
-		Node *debugnode = n;
-		show_overloaded(n);
-#endif
-		if (!firstChild(n)) {
-		  // Remove from overloaded list ('using' node does not actually end up adding in any methods)
-		  Node *ps = Getattr(n, "sym:previousSibling");
-		  Node *ns = Getattr(n, "sym:nextSibling");
-		  if (ps) {
-		    Setattr(ps, "sym:nextSibling", ns);
-		  }
-		  if (ns) {
-		    Setattr(ns, "sym:previousSibling", ps);
-		  }
-		} else {
-		  // The 'using' node results in methods being added in - slot in the these methods here 
-		  Node *ps = Getattr(n, "sym:previousSibling");
-		  Node *ns = Getattr(n, "sym:nextSibling");
-		  Node *fc = firstChild(n);
-		  Node *pp = fc;
-
-		  Node *firstoverloaded = Getattr(n, "sym:overloaded");
-		  if (firstoverloaded == n) {
-		    // This 'using' node we are cutting out was the first node in the overloaded list. 
-		    // Change the first node in the list to its first sibling
-		    Delattr(firstoverloaded, "sym:overloaded");
-		    Node *nnn = Getattr(firstoverloaded, "sym:nextSibling");
-		    firstoverloaded = fc;
-		    while (nnn) {
-		      Setattr(nnn, "sym:overloaded", firstoverloaded);
-		      nnn = Getattr(nnn, "sym:nextSibling");
-		    }
-		  }
-		  while (pp) {
-		    Node *ppn = Getattr(pp, "sym:nextSibling");
-		    Setattr(pp, "sym:overloaded", firstoverloaded);
-		    Setattr(pp, "sym:overname", NewStringf("%s_%d", Getattr(n, "sym:overname"), cnt++));
-		    if (ppn)
-		      pp = ppn;
-		    else
-		      break;
-		  }
-		  if (ps) {
-		    Setattr(ps, "sym:nextSibling", fc);
-		    Setattr(fc, "sym:previousSibling", ps);
-		  }
-		  if (ns) {
-		    Setattr(ns, "sym:previousSibling", pp);
-		    Setattr(pp, "sym:nextSibling", ns);
-		  }
-#ifdef DEBUG_OVERLOADED
-		  debugnode = firstoverloaded;
-#endif
-		}
-		Delattr(n, "sym:previousSibling");
-		Delattr(n, "sym:nextSibling");
-		Delattr(n, "sym:overloaded");
-		Delattr(n, "sym:overname");
-#ifdef DEBUG_OVERLOADED
-		show_overloaded(debugnode);
-#endif
-		clean_overloaded(n);	// Needed?
-	      }
-	    }
 	  }
 	} else if ((Strcmp(ntype, "class") == 0) || ((Strcmp(ntype, "classforward") == 0))) {
 	  /* We install the using class name as kind of a typedef back to the original class */
diff --git a/Source/Modules/uffi.cxx b/Source/Modules/uffi.cxx
deleted file mode 100644
index 10a53a5..0000000
--- a/Source/Modules/uffi.cxx
+++ /dev/null
@@ -1,405 +0,0 @@
-/* ----------------------------------------------------------------------------- 
- * This file is part of SWIG, which is licensed as a whole under version 3 
- * (or any later version) of the GNU General Public License. Some additional
- * terms also apply to certain portions of SWIG. The full details of the SWIG
- * license and copyrights can be found in the LICENSE and COPYRIGHT files
- * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
- *
- * uffi.cxx
- *
- * Uffi language module for SWIG.
- * ----------------------------------------------------------------------------- */
-
-// TODO: remove remnants of lisptype
-
-#include "swigmod.h"
-
-static const char *usage = "\
-UFFI Options (available with -uffi)\n\
-     -identifier-converter <type or funcname> - \n\
-                       Specifies the type of conversion to do on C identifiers\n\
-                       to convert them to symbols. There are two built-in\n\
-                       converters: 'null' and 'lispify'. The default is\n\
-                       'null'. If you supply a name other than one of the\n\
-                       built-ins, then a function by that name will be\n\
-                       called to convert identifiers to symbols.\n\
-";
-
-class UFFI:public Language {
-public:
-
-  virtual void main(int argc, char *argv[]);
-  virtual int top(Node *n);
-  virtual int functionWrapper(Node *n);
-  virtual int constantWrapper(Node *n);
-  virtual int classHandler(Node *n);
-  virtual int membervariableHandler(Node *n);
-
-};
-
-static File *f_cl = 0;
-
-static struct {
-  int count;
-  String **entries;
-} defined_foreign_types;
-
-static String *identifier_converter = NewString("identifier-convert-null");
-
-static int any_varargs(ParmList *pl) {
-  Parm *p;
-
-  for (p = pl; p; p = nextSibling(p)) {
-    if (SwigType_isvarargs(Getattr(p, "type")))
-      return 1;
-  }
-
-  return 0;
-}
-
-
-/* utilities */
-/* returns new string w/ parens stripped */
-static String *strip_parens(String *string) {
-  char *s = Char(string), *p;
-  int len = Len(string);
-  String *res;
-
-  if (len == 0 || s[0] != '(' || s[len - 1] != ')') {
-    return NewString(string);
-  }
-
-  p = (char *) malloc(len - 2 + 1);
-  if (!p) {
-    Printf(stderr, "Malloc failed\n");
-    SWIG_exit(EXIT_FAILURE);
-  }
-
-  strncpy(p, s + 1, len - 1);
-  p[len - 2] = 0;		/* null terminate */
-
-  res = NewString(p);
-  free(p);
-
-  return res;
-}
-
-
-static String *convert_literal(String *num_param, String *type) {
-  String *num = strip_parens(num_param), *res;
-  char *s = Char(num);
-
-  /* Make sure doubles use 'd' instead of 'e' */
-  if (!Strcmp(type, "double")) {
-    String *updated = Copy(num);
-    if (Replace(updated, "e", "d", DOH_REPLACE_ANY) > 1) {
-      Printf(stderr, "Weird!! number %s looks invalid.\n", num);
-      SWIG_exit(EXIT_FAILURE);
-    }
-    Delete(num);
-    return updated;
-  }
-
-  if (SwigType_type(type) == T_CHAR) {
-    /* Use CL syntax for character literals */
-    return NewStringf("#\\%s", num_param);
-  } else if (SwigType_type(type) == T_STRING) {
-    /* Use CL syntax for string literals */
-    return NewStringf("\"%s\"", num_param);
-  }
-
-  if (Len(num) < 2 || s[0] != '0') {
-    return num;
-  }
-
-  /* octal or hex */
-
-  res = NewStringf("#%c%s", s[1] == 'x' ? 'x' : 'o', s + 2);
-  Delete(num);
-
-  return res;
-}
-
-static void add_defined_foreign_type(String *type) {
-  if (!defined_foreign_types.count) {
-    /* Make fresh */
-    defined_foreign_types.count = 1;
-    defined_foreign_types.entries = (String **) malloc(sizeof(String *));
-  } else {
-    /* make room */
-    defined_foreign_types.count++;
-    defined_foreign_types.entries = (String **)
-	realloc(defined_foreign_types.entries, defined_foreign_types.count * sizeof(String *));
-  }
-
-  if (!defined_foreign_types.entries) {
-    Printf(stderr, "Out of memory\n");
-    SWIG_exit(EXIT_FAILURE);
-  }
-
-  /* Fill in the new data */
-  defined_foreign_types.entries[defined_foreign_types.count - 1] = Copy(type);
-
-}
-
-
-static String *get_ffi_type(Node *n, SwigType *ty, const_String_or_char_ptr name) {
-  Node *node = NewHash();
-  Setattr(node, "type", ty);
-  Setattr(node, "name", name);
-  Setfile(node, Getfile(n));
-  Setline(node, Getline(n));
-  const String *tm = Swig_typemap_lookup("ffitype", node, "", 0);
-  Delete(node);
-
-  if (tm) {
-    return NewString(tm);
-  } else {
-    SwigType *tr = SwigType_typedef_resolve_all(ty);
-    char *type_reduced = Char(tr);
-    int i;
-
-    //Printf(stdout,"convert_type %s\n", ty);
-    if (SwigType_isconst(tr)) {
-      SwigType_pop(tr);
-      type_reduced = Char(tr);
-    }
-
-    if (SwigType_ispointer(type_reduced) || SwigType_isarray(ty) || !strncmp(type_reduced, "p.f", 3)) {
-      return NewString(":pointer-void");
-    }
-
-    for (i = 0; i < defined_foreign_types.count; i++) {
-      if (!Strcmp(ty, defined_foreign_types.entries[i])) {
-	return NewStringf("#.(%s \"%s\" :type :type)", identifier_converter, ty);
-      }
-    }
-
-    if (!Strncmp(type_reduced, "enum ", 5)) {
-      return NewString(":int");
-    }
-
-    Printf(stderr, "Unsupported data type: %s (was: %s)\n", type_reduced, ty);
-    SWIG_exit(EXIT_FAILURE);
-  }
-  return 0;
-}
-
-static String *get_lisp_type(Node *n, SwigType *ty, const_String_or_char_ptr name) {
-  Node *node = NewHash();
-  Setattr(node, "type", ty);
-  Setattr(node, "name", name);
-  Setfile(node, Getfile(n));
-  Setline(node, Getline(n));
-  const String *tm = Swig_typemap_lookup("lisptype", node, "", 0);
-  Delete(node);
-
-  return tm ? NewString(tm) : NewString("");
-}
-
-void UFFI::main(int argc, char *argv[]) {
-  int i;
-
-  Preprocessor_define("SWIGUFFI 1", 0);
-  SWIG_library_directory("uffi");
-  SWIG_config_file("uffi.swg");
-
-
-  for (i = 1; i < argc; i++) {
-    if (!strcmp(argv[i], "-identifier-converter")) {
-      char *conv = argv[i + 1];
-
-      if (!conv)
-	Swig_arg_error();
-
-      Swig_mark_arg(i);
-      Swig_mark_arg(i + 1);
-      i++;
-
-      /* check for built-ins */
-      if (!strcmp(conv, "lispify")) {
-	Delete(identifier_converter);
-	identifier_converter = NewString("identifier-convert-lispify");
-      } else if (!strcmp(conv, "null")) {
-	Delete(identifier_converter);
-	identifier_converter = NewString("identifier-convert-null");
-      } else {
-	/* Must be user defined */
-	Delete(identifier_converter);
-	identifier_converter = NewString(conv);
-      }
-    }
-
-    if (!strcmp(argv[i], "-help")) {
-      Printf(stdout, "%s\n", usage);
-    }
-  }
-}
-
-int UFFI::top(Node *n) {
-  String *module = Getattr(n, "name");
-  String *output_filename = NewString("");
-  File *f_null = NewString("");
-
-  Printf(output_filename, "%s%s.cl", SWIG_output_directory(), module);
-
-
-  f_cl = NewFile(output_filename, "w", SWIG_output_files());
-  if (!f_cl) {
-    FileErrorDisplay(output_filename);
-    SWIG_exit(EXIT_FAILURE);
-  }
-
-  Swig_register_filebyname("header", f_null);
-  Swig_register_filebyname("begin", f_null);
-  Swig_register_filebyname("runtime", f_null);
-  Swig_register_filebyname("wrapper", f_cl);
-
-  Swig_banner_target_lang(f_cl, ";;");
-
-  Printf(f_cl, "\n"
-	 ";; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10; package: %s -*-\n\n(defpackage :%s\n  (:use :common-lisp :uffi))\n\n(in-package :%s)\n",
-	 module, module, module);
-  Printf(f_cl, "(eval-when (compile load eval)\n  (defparameter *swig-identifier-converter* '%s))\n", identifier_converter);
-
-  Language::top(n);
-
-  Delete(f_cl);			// Delete the handle, not the file
-  Delete(f_null);
-
-  return SWIG_OK;
-}
-
-int UFFI::functionWrapper(Node *n) {
-  String *funcname = Getattr(n, "sym:name");
-  ParmList *pl = Getattr(n, "parms");
-  Parm *p;
-  int argnum = 0, first = 1;
-//  int varargs = 0;
-
-  //Language::functionWrapper(n);
-
-  Printf(f_cl, "(swig-defun \"%s\"\n", funcname);
-  Printf(f_cl, "  (");
-
-  /* Special cases */
-
-  if (ParmList_len(pl) == 0) {
-    Printf(f_cl, ":void");
-  } else if (any_varargs(pl)) {
-    Printf(f_cl, "#| varargs |#");
-//    varargs = 1;
-  } else {
-    for (p = pl; p; p = nextSibling(p), argnum++) {
-      String *argname = Getattr(p, "name");
-      SwigType *argtype = Getattr(p, "type");
-      String *ffitype = get_ffi_type(n, argtype, argname);
-      String *lisptype = get_lisp_type(n, argtype, argname);
-      int tempargname = 0;
-
-      if (!argname) {
-	argname = NewStringf("arg%d", argnum);
-	tempargname = 1;
-      }
-
-      if (!first) {
-	Printf(f_cl, "\n   ");
-      }
-      Printf(f_cl, "(%s %s %s)", argname, ffitype, lisptype);
-      first = 0;
-
-      Delete(ffitype);
-      Delete(lisptype);
-      if (tempargname)
-	Delete(argname);
-
-    }
-  }
-  Printf(f_cl, ")\n");		/* finish arg list */
-  Printf(f_cl, "  :returning %s\n"
-	 //"  :strings-convert t\n"
-	 //"  :call-direct %s\n"
-	 //"  :optimize-for-space t"
-	 ")\n", get_ffi_type(n, Getattr(n, "type"), Swig_cresult_name())
-	 //,varargs ? "nil"  : "t"
-      );
-
-
-  return SWIG_OK;
-}
-
-int UFFI::constantWrapper(Node *n) {
-  String *type = Getattr(n, "type");
-  String *converted_value = convert_literal(Getattr(n, "value"), type);
-  String *name = Getattr(n, "sym:name");
-
-#if 0
-  Printf(stdout, "constant %s is of type %s. value: %s\n", name, type, converted_value);
-#endif
-
-  Printf(f_cl, "(swig-defconstant \"%s\" %s)\n", name, converted_value);
-
-  Delete(converted_value);
-
-  return SWIG_OK;
-}
-
-// Includes structs
-int UFFI::classHandler(Node *n) {
-
-  String *name = Getattr(n, "sym:name");
-  String *kind = Getattr(n, "kind");
-  Node *c;
-
-  if (Strcmp(kind, "struct")) {
-    Printf(stderr, "Don't know how to deal with %s kind of class yet.\n", kind);
-    Printf(stderr, " (name: %s)\n", name);
-    SWIG_exit(EXIT_FAILURE);
-  }
-
-  Printf(f_cl, "(swig-def-struct \"%s\"\n \n", name);
-
-  for (c = firstChild(n); c; c = nextSibling(c)) {
-    SwigType *type = Getattr(c, "type");
-    SwigType *decl = Getattr(c, "decl");
-    if (type) {
-      type = Copy(type);
-      SwigType_push(type, decl);
-      String *lisp_type;
-
-      if (Strcmp(nodeType(c), "cdecl")) {
-	Printf(stderr, "Structure %s has a slot that we can't deal with.\n", name);
-	Printf(stderr, "nodeType: %s, name: %s, type: %s\n", nodeType(c), Getattr(c, "name"), Getattr(c, "type"));
-	SWIG_exit(EXIT_FAILURE);
-      }
-
-      /* Printf(stdout, "Converting %s in %s\n", type, name); */
-      lisp_type = get_ffi_type(n, type, Getattr(c, "sym:name"));
-
-      Printf(f_cl, "  (#.(%s \"%s\" :type :slot) %s)\n", identifier_converter, Getattr(c, "sym:name"), lisp_type);
-
-      Delete(lisp_type);
-    }
-  }
-
-  // Language::classHandler(n);
-
-  Printf(f_cl, " )\n");
-
-  /* Add this structure to the known lisp types */
-  //Printf(stdout, "Adding %s foreign type\n", name);
-  add_defined_foreign_type(name);
-
-  return SWIG_OK;
-}
-
-int UFFI::membervariableHandler(Node *n) {
-  Language::membervariableHandler(n);
-  return SWIG_OK;
-}
-
-
-extern "C" Language *swig_uffi(void) {
-  return new UFFI();
-}
diff --git a/Source/Modules/utils.cxx b/Source/Modules/utils.cxx
index 2964ed3..2d956c4 100644
--- a/Source/Modules/utils.cxx
+++ b/Source/Modules/utils.cxx
@@ -4,14 +4,14 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * utils.cxx
  *
  * Various utility functions.
  * ----------------------------------------------------------------------------- */
 
-#include <swigmod.h>
+#include "swigmod.h"
 
 int is_public(Node *n) {
   String *access = Getattr(n, "access");
@@ -66,7 +66,11 @@
   return result;
 }
 
-/* Clean overloaded list.  Removes templates, ignored, and errors */
+/* -----------------------------------------------------------------------------
+ * clean_overloaded()
+ *
+ * Clean overloaded list.  Removes templates, ignored, and errors.
+ * ----------------------------------------------------------------------------- */
 
 void clean_overloaded(Node *n) {
   Node *nn = Getattr(n, "sym:overloaded");
@@ -89,6 +93,7 @@
       Delattr(nn, "sym:previousSibling");
       Delattr(nn, "sym:nextSibling");
       Delattr(nn, "sym:overloaded");
+      Delattr(nn, "sym:overname");
       nn = ns;
       continue;
     } else {
@@ -102,6 +107,8 @@
     if (Getattr(n, "sym:overloaded"))
       Delattr(n, "sym:overloaded");
   }
+
+  Swig_symbol_fix_overname(Getattr(n, "sym:overloaded"));
 }
 
 /* -----------------------------------------------------------------------------
@@ -115,6 +122,7 @@
   SetMaxHashExpand(count);
 }
 
+
 extern "C" {
 
 /* -----------------------------------------------------------------------------
diff --git a/Source/Modules/xml.cxx b/Source/Modules/xml.cxx
index 5f09056..28611c5 100644
--- a/Source/Modules/xml.cxx
+++ b/Source/Modules/xml.cxx
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * xml.cxx
  *
@@ -16,9 +16,7 @@
 static const char *usage = "\
 XML Options (available with -xml)\n\
      -xmllang <lang> - Typedef language\n\
-     -xmllite        - More lightweight version of XML\n\
-     ------\n\
-     deprecated (use -o): -xml <output.xml> - Use <output.xml> as output file (extension .xml mandatory)\n";
+     -xmllite        - More lightweight version of XML\n";
 
 static File *out = 0;
 static int xmllite = 0;
@@ -39,23 +37,6 @@
   virtual void main(int argc, char *argv[]) {
     SWIG_typemap_lang("xml");
     for (int iX = 0; iX < argc; iX++) {
-      if (strcmp(argv[iX], "-xml") == 0) {
-	char *extension = 0;
-	if (iX + 1 >= argc)
-	  continue;
-	extension = argv[iX + 1] + strlen(argv[iX + 1]) - 4;
-	if (strcmp(extension, ".xml"))
-	  continue;
-	iX++;
-	Swig_mark_arg(iX);
-	String *outfile = NewString(argv[iX]);
-	out = NewFile(outfile, "w", SWIG_output_files());
-	if (!out) {
-	  FileErrorDisplay(outfile);
-	  SWIG_exit(EXIT_FAILURE);
-	}
-	continue;
-      }
       if (strcmp(argv[iX], "-xmllang") == 0) {
 	Swig_mark_arg(iX);
 	iX++;
@@ -89,7 +70,7 @@
       out = NewFile(outfile, "w", SWIG_output_files());
       if (!out) {
 	FileErrorDisplay(outfile);
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       }
     }
     Printf(out, "<?xml version=\"1.0\" ?> \n");
@@ -118,7 +99,7 @@
     String *k;
     indent_level += 4;
     print_indent(0);
-    Printf(out, "<attributelist id=\"%ld\" addr=\"%p\" >\n", ++id, obj);
+    Printf(out, "<attributelist id=\"%ld\" addr=\"%p\">\n", ++id, obj);
     indent_level += 4;
     Iterator ki;
     ki = First(obj);
@@ -175,7 +156,7 @@
     }
     indent_level -= 4;
     print_indent(0);
-    Printf(out, "</attributelist >\n");
+    Printf(out, "</attributelist>\n");
     indent_level -= 4;
   }
 
@@ -183,7 +164,7 @@
     Node *cobj;
 
     print_indent(0);
-    Printf(out, "<%s id=\"%ld\" addr=\"%p\" >\n", nodeType(obj), ++id, obj);
+    Printf(out, "<%s id=\"%ld\" addr=\"%p\">\n", nodeType(obj), ++id, obj);
     Xml_print_attributes(obj);
     cobj = firstChild(obj);
     if (cobj) {
@@ -196,32 +177,32 @@
       Printf(out, "\n");
     }
     print_indent(0);
-    Printf(out, "</%s >\n", nodeType(obj));
+    Printf(out, "</%s>\n", nodeType(obj));
   }
 
 
   void Xml_print_parmlist(ParmList *p, const char* markup = "parmlist") {
 
     print_indent(0);
-    Printf(out, "<%s id=\"%ld\" addr=\"%p\" >\n", markup, ++id, p);
+    Printf(out, "<%s id=\"%ld\" addr=\"%p\">\n", markup, ++id, p);
     indent_level += 4;
     while (p) {
       print_indent(0);
       Printf(out, "<parm id=\"%ld\">\n", ++id);
       Xml_print_attributes(p);
       print_indent(0);
-      Printf(out, "</parm >\n");
+      Printf(out, "</parm>\n");
       p = nextSibling(p);
     }
     indent_level -= 4;
     print_indent(0);
-    Printf(out, "</%s >\n", markup);
+    Printf(out, "</%s>\n", markup);
   }
 
   void Xml_print_baselist(List *p) {
 
     print_indent(0);
-    Printf(out, "<baselist id=\"%ld\" addr=\"%p\" >\n", ++id, p);
+    Printf(out, "<baselist id=\"%ld\" addr=\"%p\">\n", ++id, p);
     indent_level += 4;
     Iterator s;
     for (s = First(p); s.item; s = Next(s)) {
@@ -232,7 +213,7 @@
     }
     indent_level -= 4;
     print_indent(0);
-    Printf(out, "</baselist >\n");
+    Printf(out, "</baselist>\n");
   }
 
   String *Xml_escape_string(String *str) {
@@ -272,21 +253,21 @@
   void Xml_print_hash(Hash *p, const char *markup) {
 
     print_indent(0);
-    Printf(out, "<%s id=\"%ld\" addr=\"%p\" >\n", markup, ++id, p);
+    Printf(out, "<%s id=\"%ld\" addr=\"%p\">\n", markup, ++id, p);
     Xml_print_attributes(p);
     indent_level += 4;
     Iterator n = First(p);
     while (n.key) {
       print_indent(0);
-      Printf(out, "<%ssitem id=\"%ld\" addr=\"%p\" >\n", markup, ++id, n.item);
+      Printf(out, "<%ssitem id=\"%ld\" addr=\"%p\">\n", markup, ++id, n.item);
       Xml_print_attributes(n.item);
       print_indent(0);
-      Printf(out, "</%ssitem >\n", markup);
+      Printf(out, "</%ssitem>\n", markup);
       n = Next(n);
     }
     indent_level -= 4;
     print_indent(0);
-    Printf(out, "</%s >\n", markup);
+    Printf(out, "</%s>\n", markup);
   }
 
 };
@@ -300,18 +281,14 @@
  * up being a post-processing version of the tree.
  * ----------------------------------------------------------------------------- */
 
-void Swig_print_xml(DOH *obj, String *filename) {
+void Swig_print_xml(Node *obj, String *filename) {
   XML xml;
   xmllite = 1;
 
-  if (!filename) {
-    out = stdout;
-  } else {
-    out = NewFile(filename, "w", SWIG_output_files());
-    if (!out) {
-      FileErrorDisplay(filename);
-      SWIG_exit(EXIT_FAILURE);
-    }
+  out = NewFile(filename, "w", SWIG_output_files());
+  if (!out) {
+    FileErrorDisplay(filename);
+    Exit(EXIT_FAILURE);
   }
 
   Printf(out, "<?xml version=\"1.0\" ?> \n");
diff --git a/Source/Preprocessor/cpp.c b/Source/Preprocessor/cpp.c
index 557b548..6edd366 100644
--- a/Source/Preprocessor/cpp.c
+++ b/Source/Preprocessor/cpp.c
@@ -4,14 +4,14 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * cpp.c
  *
  * An implementation of a C preprocessor plus some support for additional
  * SWIG directives.
  *
- * - SWIG directives such as %include, %extern, and %import are handled
+ * - SWIG directives such as %include and %import are handled
  * - A new macro %define ... %enddef can be used for multiline macros
  * - No preprocessing is performed in %{ ... %} blocks
  * - Lines beginning with %# are stripped down to #... and passed through.
@@ -42,7 +42,7 @@
 /* Test a character to see if it valid in an identifier (after the first letter) */
 #define isidchar(c) ((isalnum(c)) || (c == '_') || (c == '$'))
 
-static DOH *Preprocessor_replace(DOH *);
+static DOH *Preprocessor_replace(DOH *, DOH *);
 
 /* Skip whitespace */
 static void skip_whitespace(String *s, String *out) {
@@ -113,7 +113,7 @@
   const char *s = Char(str);
   int isdigits = (*s != 0);
   while (*s) {
-    if (!isdigit(*s)) {
+    if (!isdigit((int)*s)) {
       isdigits = 0;
       break;
     }
@@ -157,7 +157,6 @@
 static String *kpp_dinclude = 0;
 static String *kpp_dimport = 0;
 static String *kpp_dbeginfile = 0;
-static String *kpp_dextern = 0;
 
 static String *kpp_LINE = 0;
 static String *kpp_FILE = 0;
@@ -194,7 +193,6 @@
   kpp_dinclude = NewString("%include");
   kpp_dimport = NewString("%import");
   kpp_dbeginfile = NewString("%beginfile");
-  kpp_dextern = NewString("%extern");
   kpp_ddefine = NewString("%define");
   kpp_dline = NewString("%line");
 
@@ -243,7 +241,6 @@
   Delete(kpp_dinclude);
   Delete(kpp_dimport);
   Delete(kpp_dbeginfile);
-  Delete(kpp_dextern);
   Delete(kpp_ddefine);
   Delete(kpp_dline);
 
@@ -571,6 +568,18 @@
 }
 
 /* -----------------------------------------------------------------------------
+ * Preprocessor_defined()
+ *
+ * Check if a macro is defined.
+ * ----------------------------------------------------------------------------- */
+int Preprocessor_defined(const_String_or_char_ptr str) {
+  Hash *symbols;
+  assert(cpp);
+  symbols = Getattr(cpp, kpp_symbols);
+  return Getattr(symbols, str) != NULL;
+}
+
+/* -----------------------------------------------------------------------------
  * find_args()
  *
  * Isolates macro arguments and returns them in a list.   For each argument,
@@ -707,7 +716,7 @@
       Putc(c, fn);
     if (isspace(c))
       Ungetc(c, str);
-    preprocessed_str = Preprocessor_replace(fn);
+    preprocessed_str = Preprocessor_replace(fn, NULL);
     Seek(preprocessed_str, 0, SEEK_SET);
     Delete(fn);
 
@@ -741,14 +750,35 @@
     opt = NewString("(");
     while (((c = Getc(str)) != EOF)) {
       Putc(c, opt);
-      if (c == ')') {
-	level--;
-	if (!level)
-	  return opt;
+      switch (c) {
+	case ')':
+	  level--;
+	  if (!level)
+	    return opt;
+	  break;
+	case '(':
+	  level++;
+	  break;
+	case '"':
+	  /* Skip over quoted strings */
+	  while (1) {
+	    c = Getc(str);
+	    if (c == EOF)
+	      goto bad;
+	    Putc(c, opt);
+	    if (c == '"')
+	      break;
+	    if (c == '\\') {
+	      c = Getc(str);
+	      if (c == EOF)
+		goto bad;
+	      Putc(c, opt);
+	    }
+	  }
+	  break;
       }
-      if (c == '(')
-	level++;
     }
+bad:
     Delete(opt);
     return 0;
   } else {
@@ -764,7 +794,7 @@
  * of error occurred.
  * name - name of the macro
  * args - arguments passed to the macro
- * line_file - only used for line/file name when reporting errors
+ * line_file - global context, used for line/file name when reporting errors
  * ----------------------------------------------------------------------------- */
 
 static String *expand_macro(String *name, List *args, String *line_file) {
@@ -882,9 +912,9 @@
       DOH *arg, *aname;
       String *reparg;
       arg = Getitem(args, i);	/* Get an argument value */
-      reparg = Preprocessor_replace(arg);
+      reparg = Preprocessor_replace(arg, NULL);
       aname = Getitem(margs, i);	/* Get macro argument name */
-      if (strstr(Char(ns), "\001")) {
+      if (strchr(Char(ns), '\001')) {
 	/* Try to replace a quoted version of the argument */
 	Clear(temp);
 	Clear(tempa);
@@ -892,7 +922,7 @@
 	Printf(tempa, "\"%s\"", arg);
 	Replace(ns, temp, tempa, DOH_REPLACE_ID_END);
       }
-      if (strstr(Char(ns), "\002")) {
+      if (strchr(Char(ns), '\002')) {
 	/* Look for concatenation tokens */
 	Clear(temp);
 	Clear(tempa);
@@ -916,7 +946,7 @@
 	Clear(temp);
 	Printf(temp, "`%s`", aname);
 	c = Char(arg);
-	if (*c == '\"') {
+	if (*c == '"') {
 	  rep = arg;
 	} else {
 	  Clear(tempa);
@@ -928,15 +958,15 @@
 
       /* Non-standard mangle expansions.  
          The #@Name is replaced by mangle_arg(Name). */
-      if (strstr(Char(ns), "\004")) {
-	String *marg = Swig_string_mangle(arg);
+      if (strchr(Char(ns), '\004')) {
+	String *marg = Swig_name_mangle_string(arg);
 	Clear(temp);
 	Printf(temp, "\004%s", aname);
 	Replace(ns, temp, marg, DOH_REPLACE_ID_END);
 	Delete(marg);
       }
-      if (strstr(Char(ns), "\005")) {
-	String *marg = Swig_string_mangle(arg);
+      if (strchr(Char(ns), '\005')) {
+	String *marg = Swig_name_mangle_string(arg);
 	Clear(temp);
 	Clear(tempa);
 	Printf(temp, "\005%s", aname);
@@ -988,7 +1018,7 @@
   /* Expand this macro even further */
   Setattr(macro, kpp_expanded, "1");
 
-  e = Preprocessor_replace(ns);
+  e = Preprocessor_replace(ns, line_file);
 
   Delattr(macro, kpp_expanded);
   Delete(ns);
@@ -1026,7 +1056,7 @@
 }
 
 /* -----------------------------------------------------------------------------
- * DOH *Preprocessor_replace(DOH *s)
+ * DOH *Preprocessor_replace(DOH *s, DOH *line_file)
  *
  * Performs a macro substitution on a string s.  Returns a new string with
  * substitutions applied.   This function works by walking down s and looking
@@ -1036,7 +1066,7 @@
 
 /* #define SWIG_PUT_BUFF  */
 
-static DOH *Preprocessor_replace(DOH *s) {
+static DOH *Preprocessor_replace(DOH *s, DOH *line_file) {
   DOH *ns, *symbols, *m;
   int c, i, state = 0;
   String *id = NewStringEmpty();
@@ -1170,14 +1200,36 @@
 	} else if (Equal(kpp_hash_if, id) || Equal(kpp_hash_elif, id)) {
 	  expand_defined_operator = 1;
 	  Append(ns, id);
-	  /*
-	} else if (Equal("%#if", id) || Equal("%#ifdef", id)) {
-	  Swig_warning(998, Getfile(s), Getline(s), "Found: %s preprocessor directive.\n", id);
-	  Append(ns, id);
 	} else if (Equal("#ifdef", id) || Equal("#ifndef", id)) {
-	  Swig_warning(998, Getfile(s), Getline(s), "The %s preprocessor directive does not work in macros, try #if instead.\n", id);
-	  Append(ns, id);
-	  */
+	  /* Evaluate the defined-ness check and substitute `#if 0` or `#if 1`. */
+	  int allow = 0;
+	  skip_whitespace(s, 0);
+	  c = Getc(s);
+	  if (isidchar(c)) {
+	    DOH *arg = NewStringEmpty();
+	    Putc(c, arg);
+	    while (((c = Getc(s)) != EOF)) {
+	      if (!isidchar(c)) {
+		Ungetc(c, s);
+		break;
+	      }
+	      Putc(c, arg);
+	    }
+	    if (Equal("#ifdef", id)) {
+	      if (Getattr(symbols, arg)) allow = 1;
+	    } else {
+	      if (!Getattr(symbols, arg)) allow = 1;
+	    }
+	    Delete(arg);
+	  } else {
+	    Ungetc(c, s);
+	    Swig_error(Getfile(s), Getline(s), "Missing identifier for %s.\n", id);
+	  }
+	  if (allow) {
+	    Append(ns, "#if 1");
+	  } else {
+	    Append(ns, "#if 0");
+	  }
 	} else if ((m = Getattr(symbols, id))) {
 	  /* See if the macro is defined in the preprocessor symbol table */
 	  DOH *args = 0;
@@ -1259,14 +1311,31 @@
       Replaceall(fn, "\\", "\\\\");
       Printf(ns, "\"%s\"", fn);
       Delete(fn);
-    } else if (Getattr(symbols, id)) {
-      DOH *e;
+    } else if ((m = Getattr(symbols, id))) {
       /* Yes.  There is a macro here */
+      /* If it expects arguments, they must come from `line_file` */
+      DOH *args = 0;
+      DOH *e;
+      int macro_additional_lines = 0;
       /* See if the macro expects arguments */
-      e = expand_macro(id, 0, s);
-      if (e)
+      if (Getattr(m, kpp_args) && line_file) {
+        /* Yep.  We need to go find the arguments and do a substitution */
+        int line = Getline(line_file);
+        args = find_args(line_file, 1, id);
+        macro_additional_lines = Getline(line_file) - line;
+        assert(macro_additional_lines >= 0);
+      } else {
+        args = 0;
+      }
+      e = expand_macro(id, args, s);
+      if (e) {
 	Append(ns, e);
+      }
+      while (macro_additional_lines--) {
+	Putc('\n', ns);
+      }
       Delete(e);
+      Delete(args);
     } else {
       Append(ns, id);
     }
@@ -1322,7 +1391,7 @@
   DOH *echunk;
   Seek(chunk, 0, SEEK_SET);
   if (allow) {
-    echunk = Preprocessor_replace(chunk);
+    echunk = Preprocessor_replace(chunk, NULL);
     addline(ns, echunk, allow);
     Delete(echunk);
   } else {
@@ -1335,14 +1404,14 @@
   push/pop_imported(): helper functions for defining and undefining
   SWIGIMPORTED (when %importing a file).
  */
-static void push_imported() {
+static void push_imported(void) {
   if (imported_depth == 0) {
     Preprocessor_define("SWIGIMPORTED 1", 0);
   }
   ++imported_depth;
 }
 
-static void pop_imported() {
+static void pop_imported(void) {
   --imported_depth;
   if (imported_depth == 0) {
     Preprocessor_undef("SWIGIMPORTED");
@@ -1411,8 +1480,9 @@
 	Ungetc(c, s);
       }
       break;
-    case 1:			/* Non-preprocessor directive */
+    case 1: {			/* Non-preprocessor directive */
       /* Look for SWIG directives */
+state1:
       if (c == '%') {
 	state = 100;
 	break;
@@ -1433,16 +1503,19 @@
       } else if (c == '/')
 	state = 30;		/* Comment */
       break;
+    }
 
     case 30:			/* Possibly a comment string of some sort */
       start_line = Getline(s);
-      Putc(c, chunk);
       if (c == '/')
 	state = 31;
       else if (c == '*')
 	state = 32;
-      else
+      else {
 	state = 1;
+	goto state1; /* Process this character the same as if it wasn't preceded by a `/`. */
+      }
+      Putc(c, chunk);
       break;
     case 31:
       Putc(c, chunk);
@@ -1593,7 +1666,7 @@
 	    copy_location(m, v);
 	    if (Len(v)) {
 	      Swig_error_silent(1);
-	      v1 = Preprocessor_replace(v);
+	      v1 = Preprocessor_replace(v, NULL);
 	      Swig_error_silent(0);
 	      /*              Printf(stdout,"checking '%s'\n", v1); */
 	      if (!checkpp_id(v1)) {
@@ -1675,7 +1748,7 @@
 	  int val;
 	  String *sval;
 	  expand_defined_operator = 1;
-	  sval = Preprocessor_replace(value);
+	  sval = Preprocessor_replace(value, NULL);
 	  start_level = level;
 	  Seek(sval, 0, SEEK_SET);
 	  /*      Printf(stdout,"Evaluating '%s'\n", sval); */
@@ -1686,7 +1759,7 @@
 	      Seek(value, 0, SEEK_SET);
 	      Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "Could not evaluate expression '%s'\n", value);
 	      if (msg)
-		Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "Error: '%s'\n", msg);
+		Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "%s\n", msg);
 	      allow = 0;
 	    } else {
 	      if (val == 0)
@@ -1711,7 +1784,7 @@
 	    int val;
 	    String *sval;
 	    expand_defined_operator = 1;
-	    sval = Preprocessor_replace(value);
+	    sval = Preprocessor_replace(value, NULL);
 	    Seek(sval, 0, SEEK_SET);
 	    if (Len(sval) > 0) {
 	      val = Preprocessor_expr(sval, &e);
@@ -1720,7 +1793,7 @@
 		Seek(value, 0, SEEK_SET);
 		Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "Could not evaluate expression '%s'\n", value);
 		if (msg)
-		  Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "Error: '%s'\n", msg);
+		  Swig_warning(WARN_PP_EVALUATION, Getfile(value), Getline(value), "%s\n", msg);
 		allow = 0;
 	      } else {
 		if (val)
@@ -1802,7 +1875,7 @@
 	  if (*c) {
 	    if (strncmp(c, "nowarn=", 7) == 0) {
 	      String *val = NewString(c + 7);
-	      String *nowarn = Preprocessor_replace(val);
+	      String *nowarn = Preprocessor_replace(val, NULL);
 	      Swig_warnfilter(nowarn, 1);
 	      Delete(nowarn);
 	      Delete(val);
@@ -1896,7 +1969,7 @@
       if (!isidchar(c)) {
 	Ungetc(c, s);
 	/* Look for common SWIG directives  */
-	if (Equal(decl, kpp_dinclude) || Equal(decl, kpp_dimport) || Equal(decl, kpp_dextern)) {
+	if (Equal(decl, kpp_dinclude) || Equal(decl, kpp_dimport)) {
 	  /* Got some kind of file inclusion directive, eg: %import(option1="value1") "filename" */
 	  if (allow) {
 	    DOH *s1, *s2, *fn, *opt;
@@ -1904,11 +1977,6 @@
 	    String *filename_whitespace = NewStringEmpty();
 	    int sysfile = 0;
 
-	    if (Equal(decl, kpp_dextern)) {
-	      Swig_warning(WARN_DEPRECATED_EXTERN, Getfile(s), Getline(s), "%%extern is deprecated. Use %%import instead.\n");
-	      Clear(decl);
-	      Append(decl, "%%import");
-	    }
 	    skip_whitespace(s, options_whitespace);
 	    opt = get_options(s);
 
@@ -2055,8 +2123,7 @@
       break;
     default:
       Printf(stderr, "cpp: Invalid parser state %d\n", state);
-      abort();
-      break;
+      Exit(EXIT_FAILURE);
     }
   }
   while (level > 0) {
diff --git a/Source/Preprocessor/expr.c b/Source/Preprocessor/expr.c
index a365889..c14f7ed 100644
--- a/Source/Preprocessor/expr.c
+++ b/Source/Preprocessor/expr.c
@@ -4,12 +4,17 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * expr.c
  *
  * Integer arithmetic expression evaluator used to handle expressions
  * encountered during preprocessing.
+ *
+ * Note that this is used for expressions in `#if` and the like, but not
+ * for expressions in `#define` which SWIG wraps as constants - for those
+ * we inject a `%constant` directive which is handled by the parser in
+ * `Source/CParse/parser.y`.
  * ----------------------------------------------------------------------------- */
 
 #include "swig.h"
@@ -18,8 +23,19 @@
 static Scanner *scan = 0;
 
 typedef struct {
+  /* One of the EXPR_xxx values defined below. */
   int op;
+  /* op == EXPR_OP: value is the token specifying which operator.
+   *
+   * op == EXPR_VALUE && svalue == NULL: Numeric expression value.
+   *
+   * Otherwise unused.
+   */
   long value;
+  /* op == EXPR_VALUE: If non-NULL, string expression value; if NULL see value.
+   *
+   * Otherwise unused.
+   */
   String *svalue;
 } exprval;
 
@@ -27,7 +43,12 @@
 #define  EXPR_VALUE    2
 #define  EXPR_OP       3
 #define  EXPR_GROUP    4
-#define  EXPR_UMINUS   100
+
+/* Special token values used here to distinguish from SWIG_TOKEN_MINUS
+ * and SWIG_TOKEN_PLUS (which we use here for a two argument versions).
+ */
+#define  OP_UMINUS   100
+#define  OP_UPLUS    101
 
 static exprval stack[256];	/* Parsing stack       */
 static int sp = 0;		/* Stack pointer       */
@@ -36,9 +57,11 @@
 static const char *errmsg = 0;	/* Parsing error       */
 
 /* Initialize the precedence table for various operators.  Low values have higher precedence */
-static void init_precedence() {
+static void init_precedence(void) {
   prec[SWIG_TOKEN_NOT] = 10;
-  prec[EXPR_UMINUS] = 10;
+  prec[SWIG_TOKEN_LNOT] = 10;
+  prec[OP_UMINUS] = 10;
+  prec[OP_UPLUS] = 10;
   prec[SWIG_TOKEN_STAR] = 20;
   prec[SWIG_TOKEN_SLASH] = 20;
   prec[SWIG_TOKEN_PERCENT] = 20;
@@ -46,16 +69,15 @@
   prec[SWIG_TOKEN_MINUS] = 30;
   prec[SWIG_TOKEN_LSHIFT] = 40;
   prec[SWIG_TOKEN_RSHIFT] = 40;
-  prec[SWIG_TOKEN_AND] = 50;
-  prec[SWIG_TOKEN_XOR] = 60;
-  prec[SWIG_TOKEN_OR] = 70;
-  prec[SWIG_TOKEN_EQUALTO] = 80;
-  prec[SWIG_TOKEN_NOTEQUAL] = 80;
-  prec[SWIG_TOKEN_LESSTHAN] = 80;
-  prec[SWIG_TOKEN_GREATERTHAN] = 80;
-  prec[SWIG_TOKEN_LTEQUAL] = 80;
-  prec[SWIG_TOKEN_GTEQUAL] = 80;
-  prec[SWIG_TOKEN_LNOT] = 90;
+  prec[SWIG_TOKEN_LESSTHAN] = 50;
+  prec[SWIG_TOKEN_GREATERTHAN] = 50;
+  prec[SWIG_TOKEN_LTEQUAL] = 50;
+  prec[SWIG_TOKEN_GTEQUAL] = 50;
+  prec[SWIG_TOKEN_EQUALTO] = 60;
+  prec[SWIG_TOKEN_NOTEQUAL] = 60;
+  prec[SWIG_TOKEN_AND] = 70;
+  prec[SWIG_TOKEN_XOR] = 80;
+  prec[SWIG_TOKEN_OR] = 90;
   prec[SWIG_TOKEN_LAND] = 100;
   prec[SWIG_TOKEN_LOR] = 110;
   expr_init = 1;
@@ -63,11 +85,12 @@
 
 #define UNARY_OP(token) (((token) == SWIG_TOKEN_NOT) || \
 			 ((token) == SWIG_TOKEN_LNOT) || \
-			 ((token) == EXPR_UMINUS))
+			 ((token) == OP_UMINUS) || \
+			 ((token) == OP_UPLUS))
 
 /* Reduce a single operator on the stack */
 /* return 0 on failure, 1 on success */
-static int reduce_op() {
+static int reduce_op(void) {
   long op_token = stack[sp - 1].value;
   assert(sp > 0);
   assert(stack[sp - 1].op == EXPR_OP);
@@ -115,7 +138,6 @@
     default:
       errmsg = "Syntax error: bad binary operator for strings";
       return 0;
-      break;
     }
   } else {
     switch (op_token) {
@@ -183,10 +205,14 @@
       stack[sp - 1].value = !stack[sp].value;
       sp--;
       break;
-    case EXPR_UMINUS:
+    case OP_UMINUS:
       stack[sp - 1].value = -stack[sp].value;
       sp--;
       break;
+    case OP_UPLUS:
+      stack[sp - 1].value = stack[sp].value;
+      sp--;
+      break;
     case SWIG_TOKEN_SLASH:
       if (stack[sp].value != 0) {
 	stack[sp - 2].value = stack[sp - 2].value / stack[sp].value;
@@ -216,7 +242,6 @@
     default:
       errmsg = "Syntax error: bad operator";
       return 0;
-      break;
     }
   }
   stack[sp].op = EXPR_VALUE;
@@ -278,48 +303,78 @@
 
   /* Put initial state onto the stack */
   stack[sp].op = EXPR_TOP;
-  stack[sp].value = 0;
 
   while (1) {
     /* Look at the top of the stack */
     switch (stack[sp].op) {
     case EXPR_TOP:
-      /* An expression.   Can be a number or another expression enclosed in parens */
+      /* EXPR_TOP is a place-holder which can only appear on the top of the
+       * stack.  We can reduce it to any expression - a number, a string, an
+       * unary operator, or another expression enclosed in parentheses.
+       */
       token = expr_token(scan);
       if (!token) {
 	errmsg = "Expected an expression";
 	*error = 1;
 	return 0;
       }
-      if ((token == SWIG_TOKEN_INT) || (token == SWIG_TOKEN_UINT) || (token == SWIG_TOKEN_LONG) || (token == SWIG_TOKEN_ULONG)) {
+      if (token == SWIG_TOKEN_BOOL) {
+	/* A boolean value.  Reduce EXPR_TOP to an EXPR_VALUE */
+	String *cc = Scanner_text(scan);
+	if (Strcmp(cc, "true") == 0) {
+	  stack[sp].value = (long) 1;
+	} else {
+	  stack[sp].value = (long) 0;
+	}
+	stack[sp].svalue = 0;
+	stack[sp].op = EXPR_VALUE;
+      } else if ((token == SWIG_TOKEN_INT) || (token == SWIG_TOKEN_UINT) || (token == SWIG_TOKEN_LONG) || (token == SWIG_TOKEN_ULONG)) {
 	/* A number.  Reduce EXPR_TOP to an EXPR_VALUE */
 	char *c = Char(Scanner_text(scan));
-	stack[sp].value = (long) strtol(c, 0, 0);
+	if (c[0] == '0' && (c[1] == 'b' || c[1] == 'B')) {
+	  /* strtol() doesn't handle binary constants */
+	  stack[sp].value = (long) strtol(c + 2, 0, 2);
+	} else {
+	  stack[sp].value = (long) strtol(c, 0, 0);
+	}
 	stack[sp].svalue = 0;
-	/*        stack[sp].value = (long) atol(Char(Scanner_text(scan))); */
 	stack[sp].op = EXPR_VALUE;
-      } else if (token == SWIG_TOKEN_PLUS) {
-      } else if ((token == SWIG_TOKEN_MINUS) || (token == SWIG_TOKEN_LNOT) || (token == SWIG_TOKEN_NOT)) {
+      } else if ((token == SWIG_TOKEN_MINUS) || (token == SWIG_TOKEN_PLUS) || (token == SWIG_TOKEN_LNOT) || (token == SWIG_TOKEN_NOT)) {
 	if (token == SWIG_TOKEN_MINUS)
-	  token = EXPR_UMINUS;
+	  token = OP_UMINUS;
+	else if (token == SWIG_TOKEN_PLUS)
+	  token = OP_UPLUS;
 	stack[sp].value = token;
-	stack[sp++].op = EXPR_OP;
+	stack[sp].op = EXPR_OP;
+	sp++;
 	stack[sp].op = EXPR_TOP;
-	stack[sp].svalue = 0;
       } else if (token == SWIG_TOKEN_LPAREN) {
-	stack[sp++].op = EXPR_GROUP;
+	stack[sp].op = EXPR_GROUP;
+	sp++;
 	stack[sp].op = EXPR_TOP;
-	stack[sp].value = 0;
-	stack[sp].svalue = 0;
       } else if (token == SWIG_TOKEN_ENDLINE) {
       } else if (token == SWIG_TOKEN_STRING) {
 	stack[sp].svalue = NewString(Scanner_text(scan));
 	stack[sp].op = EXPR_VALUE;
       } else if (token == SWIG_TOKEN_ID) {
+	int next_token = expr_token(scan);
+	if (next_token == SWIG_TOKEN_LPAREN) {
+	  /* This is a use of an unknown function-like macro so we emit a
+	   * warning.
+	   */
+	  errmsg = "Use of undefined function-like macro";
+	  *error = 1;
+	  return 0;
+	}
+	Scanner_pushtoken(scan, next_token, Scanner_text(scan));
+
+	/* Defined macros have been expanded already so this is an unknown
+	 * macro, which gets treated as zero.
+	 */
 	stack[sp].value = 0;
 	stack[sp].svalue = 0;
 	stack[sp].op = EXPR_VALUE;
-      } else if ((token == SWIG_TOKEN_FLOAT) || (token == SWIG_TOKEN_DOUBLE)) {
+      } else if (token == SWIG_TOKEN_FLOAT || token == SWIG_TOKEN_DOUBLE || token == SWIG_TOKEN_LONGDOUBLE) {
 	errmsg = "Floating point constant in preprocessor expression";
 	*error = 1;
 	return 0;
@@ -327,7 +382,9 @@
 	goto syntax_error;
       break;
     case EXPR_VALUE:
-      /* A value is on the stack.   We may reduce or evaluate depending on what the next token is */
+      /* A value is on top of the stack.  We may reduce or evaluate depending
+       * on what the next token is.
+       */
       token = expr_token(scan);
       if (!token) {
 	/* End of input. Might have to reduce if an operator is on stack */
@@ -371,7 +428,6 @@
 	  stack[sp].value = token;
 	  sp++;
 	  stack[sp].op = EXPR_TOP;
-	  stack[sp].value = 0;
 	} else {
 	  if (stack[sp - 1].op != EXPR_OP)
 	    goto syntax_error_expected_operator;
@@ -390,7 +446,6 @@
 	  stack[sp].value = token;
 	  sp++;
 	  stack[sp].op = EXPR_TOP;
-	  stack[sp].value = 0;
 	}
 	break;
       case SWIG_TOKEN_RPAREN:
@@ -406,8 +461,11 @@
 	  goto extra_rparen;
 	stack[sp - 1].op = EXPR_VALUE;
 	stack[sp - 1].value = stack[sp].value;
+	stack[sp - 1].svalue = stack[sp].svalue;
 	sp--;
 	break;
+      case SWIG_TOKEN_LTEQUALGT:
+	goto spaceship_not_allowed;
       default:
 	goto syntax_error_expected_operator;
 	break;
@@ -416,7 +474,7 @@
 
     default:
       fprintf(stderr, "Internal error in expression evaluator.\n");
-      abort();
+      Exit(EXIT_FAILURE);
     }
   }
 
@@ -439,6 +497,11 @@
   errmsg = "Extra \')\'";
   *error = 1;
   return 0;
+
+spaceship_not_allowed:
+  errmsg = "Spaceship operator (<=>) not allowed in preprocessor expression";
+  *error = 1;
+  return 0;
 }
 
 /* -----------------------------------------------------------------------------
@@ -447,6 +510,6 @@
  * Return error message set by the evaluator (if any)
  * ----------------------------------------------------------------------------- */
 
-const char *Preprocessor_expr_error() {
+const char *Preprocessor_expr_error(void) {
   return errmsg;
 }
diff --git a/Source/Preprocessor/preprocessor.h b/Source/Preprocessor/preprocessor.h
index 4c24f48..9f9537b 100644
--- a/Source/Preprocessor/preprocessor.h
+++ b/Source/Preprocessor/preprocessor.h
@@ -4,15 +4,15 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * preprocessor.h
  *
  * SWIG preprocessor module.
  * ----------------------------------------------------------------------------- */
 
-#ifndef SWIG_PREPROCESSOR_H_
-#define SWIG_PREPROCESSOR_H_
+#ifndef SWIG_PREPROCESSOR_H
+#define SWIG_PREPROCESSOR_H
 
 #include "swigwarn.h"
 
@@ -23,6 +23,7 @@
   extern const char *Preprocessor_expr_error(void);
   extern Hash *Preprocessor_define(const_String_or_char_ptr str, int swigmacro);
   extern void Preprocessor_undef(const_String_or_char_ptr name);
+  extern int Preprocessor_defined(const_String_or_char_ptr str);
   extern void Preprocessor_init(void);
   extern void Preprocessor_delete(void);
   extern String *Preprocessor_parse(String *s);
diff --git a/Source/README b/Source/README
index 814ec45..0889333 100644
--- a/Source/README
+++ b/Source/README
@@ -13,13 +13,3 @@
  Source/Modules      -  Language modules.
 
  Source/Include      -  Include files.
-
-Historic directories which may be in CVS, but have been removed:
-
- Source/Modules1.1   -  Old SWIG-1.1 modules. Empty.
-
- Source/LParse       -  Experimental parser.  Officially dead
-                        as CParse is more capable.
-
- Source/SWIG1.1      -  Old SWIG1.1 core. Completely empty now.
-
diff --git a/Source/Swig/cwrap.c b/Source/Swig/cwrap.c
index d6e5e0c..927eec5 100644
--- a/Source/Swig/cwrap.c
+++ b/Source/Swig/cwrap.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * cwrap.c
  *
@@ -15,6 +15,8 @@
 #include "swig.h"
 #include "cparse.h"
 
+extern int UseWrapperSuffix;
+
 static const char *cresult_variable_name = "result";
 
 static Parm *nonvoid_parms(Parm *p) {
@@ -294,7 +296,7 @@
 	  Delete(defname);
 	  Delete(defvalue);
 	}
-      } else if (!pvalue && ((tycode == T_POINTER) || (tycode == T_STRING) || (tycode == T_WSTRING))) {
+      } else if (!pvalue && ((tycode == T_POINTER) || (tycode == T_STRING) || (tycode == T_WSTRING) || (tycode == T_ARRAY))) {
 	pvalue = (String *) "0";
       }
       if (!altty) {
@@ -427,10 +429,14 @@
       String *rcaststr = SwigType_rcaststr(rpt, pname);
 
       if (comma) {
-	Printv(func, ",", rcaststr, NIL);
-      } else {
-	Append(func, rcaststr);
+	Append(func, ",");
       }
+
+      if (cparse_cplusplus && SwigType_type(rpt) == T_USER)
+	Printv(func, "SWIG_STD_MOVE(", rcaststr, ")", NIL);
+      else
+	Printv(func, rcaststr, NIL);
+
       Delete(rpt);
       Delete(pname);
       Delete(rcaststr);
@@ -632,7 +638,7 @@
  * If you define SWIG_FAST_REC_SEARCH, the method will set the found
  * 'attr' in the target class 'n'. If not, the method will set the
  * 'noattr' one. This prevents of having to navigate the entire
- * hierarchy tree everytime, so, it is an O(1) method...  or something
+ * hierarchy tree every time, so, it is an O(1) method...  or something
  * like that. However, it populates all the parsed classes with the
  * 'attr' and/or 'noattr' attributes.
  *
@@ -869,7 +875,7 @@
     String *parentclassname = 0;
     if (parentclass)
       parentclassname = Getattr(parentclass, "name");
-    Replaceall(code, "$parentclassname", parentclassname ? SwigType_str(parentclassname, "") : "");
+    Replaceall(code, "$parentclassname", parentclassname ? SwigType_str(parentclassname, NULL) : "");
   }
 }
 
@@ -887,7 +893,7 @@
   String *rt_sig = SwigType_str(return_type, sig);
   String *body = NewStringf("SWIGINTERN %s", rt_sig);
   Printv(body, code, "\n", NIL);
-  if (Strstr(body, "$")) {
+  if (Strchr(body, '$')) {
     Swig_replace_special_variables(n, parentNode(parentNode(n)), body);
     if (self)
       Replaceall(body, "$self", self);
@@ -1069,16 +1075,25 @@
     String *code = Getattr(n, "code");
     String *cname = Getattr(n, "extendsmartclassname") ? Getattr(n, "extendsmartclassname") : classname;
     String *membername = Swig_name_member(nspace, cname, name);
-    String *mangled = Swig_name_mangle(membername);
+    String *mangled = Swig_name_mangle_string(membername);
     int is_smart_pointer = flags & CWRAP_SMART_POINTER;
 
     type = Getattr(n, "type");
 
     /* Check if the method is overloaded.   If so, and it has code attached, we append an extra suffix
        to avoid a name-clash in the generated wrappers.  This allows overloaded methods to be defined
-       in C. */
-    if (Getattr(n, "sym:overloaded") && code) {
-      Append(mangled, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
+       in C.
+
+       But when not using the suffix used for overloaded functions, we still need to ensure that the
+       wrapper name doesn't conflict with any wrapper functions for some languages, so optionally make
+       it sufficiently unique by appending a suffix similar to the one used for overloaded functions to it.
+     */
+    if (code) {
+      if (Getattr(n, "sym:overloaded")) {
+	Append(mangled, Getattr(defaultargs ? defaultargs : n, "sym:overname"));
+      } else if (UseWrapperSuffix) {
+	Append(mangled, "__SWIG");
+      }
     }
 
     /* See if there is any code that we need to emit */
@@ -1157,8 +1172,7 @@
  * ----------------------------------------------------------------------------- */
 
 Node *Swig_methodclass(Node *n) {
-  Node *nodetype = nodeType(n);
-  if (Cmp(nodetype, "class") == 0)
+  if (Equal(nodeType(n), "class"))
     return n;
   return GetFlag(n, "feature:extend") ? parentNode(parentNode(n)) : parentNode(n);
 }
@@ -1223,7 +1237,7 @@
     String *defaultargs = Getattr(n, "defaultargs");
     String *code = Getattr(n, "code");
     String *membername = Swig_name_construct(nspace, classname);
-    String *mangled = Swig_name_mangle(membername);
+    String *mangled = Swig_name_mangle_string(membername);
 
     /* Check if the constructor is overloaded.   If so, and it has code attached, we append an extra suffix
        to avoid a name-clash in the generated wrappers.  This allows overloaded constructors to be defined
@@ -1341,7 +1355,7 @@
     String *call;
     String *membername, *mangled, *code;
     membername = Swig_name_destroy(nspace, classname);
-    mangled = Swig_name_mangle(membername);
+    mangled = Swig_name_mangle_string(membername);
     code = Getattr(n, "code");
     if (code) {
       Swig_add_extension_code(n, mangled, p, type, code, cparse_cplusplus, "self");
@@ -1428,7 +1442,7 @@
 
     String *sname = Swig_name_set(0, name);
     String *membername = Swig_name_member(0, classname, sname);
-    String *mangled = Swig_name_mangle(membername);
+    String *mangled = Swig_name_mangle_string(membername);
 
     if (code) {
       /* I don't think this ever gets run - WSF */
@@ -1510,7 +1524,7 @@
 
     String *gname = Swig_name_get(0, name);
     String *membername = Swig_name_member(0, classname, gname);
-    String *mangled = Swig_name_mangle(membername);
+    String *mangled = Swig_name_mangle_string(membername);
 
     if (code) {
       /* I don't think this ever gets run - WSF */
@@ -1562,7 +1576,7 @@
 
   if (flags & CWRAP_EXTEND) {
     String *sname = Swig_name_set(0, name);
-    String *mangled = Swig_name_mangle(sname);
+    String *mangled = Swig_name_mangle_string(sname);
     String *call = Swig_cfunction_call(mangled, parms);
     String *cres = NewStringf("%s;", call);
     Setattr(n, "wrap:action", cres);
@@ -1616,7 +1630,7 @@
 
   if (flags & CWRAP_EXTEND) {
     String *sname = Swig_name_get(0, name);
-    String *mangled = Swig_name_mangle(sname);
+    String *mangled = Swig_name_mangle_string(sname);
     call = Swig_cfunction_call(mangled, 0);
     cres = Swig_cresult(ty, Swig_cresult_name(), call);
     Setattr(n, "wrap:action", cres);
diff --git a/Source/Swig/deprecate.c b/Source/Swig/deprecate.c
index 08dc06a..5783455 100644
--- a/Source/Swig/deprecate.c
+++ b/Source/Swig/deprecate.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * deprecate.c
  *
diff --git a/Source/Swig/error.c b/Source/Swig/error.c
index 1dde066..c85f16d 100644
--- a/Source/Swig/error.c
+++ b/Source/Swig/error.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * error.c
  *
@@ -189,7 +189,6 @@
     filter = NewStringEmpty();
 
   s = NewString("");
-  Clear(s);
   cw = Char(wlist);
   while (*cw != '\0') {
     if (*cw != ' ') {
@@ -209,14 +208,14 @@
 	  Insert(filter, 0, "-");
 	}
       } else {
-	char *temp = (char *)malloc(sizeof(char)*strlen(c) + 2);
+	char *temp = (char *)Malloc(sizeof(char)*strlen(c) + 2);
 	if (isdigit((int) *c)) {
 	  sprintf(temp, "-%s", c);
 	} else {
 	  strcpy(temp, c);
 	}
 	Replace(filter, temp, "", DOH_REPLACE_FIRST);
-        free(temp);
+	Free(temp);
       }
     }
     c = strtok(NULL, ", ");
diff --git a/Source/Swig/extend.c b/Source/Swig/extend.c
index 70355a2..4e430ed 100644
--- a/Source/Swig/extend.c
+++ b/Source/Swig/extend.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * extend.c
  *
@@ -38,7 +38,6 @@
 
 void Swig_extend_merge(Node *cls, Node *am) {
   Node *n;
-  Node *csym;
 
   n = firstChild(am);
   while (n) {
@@ -61,28 +60,28 @@
     symname = Getattr(n,"sym:name");
     DohIncref(symname);
     if ((symname) && (!Getattr(n,"error"))) {
+      Node *c;
       /* Remove node from its symbol table */
       Swig_symbol_remove(n);
-      csym = Swig_symbol_add(symname,n);
-      if (csym != n) {
+      c = Swig_symbol_add(symname,n);
+      if (c != n) {
 	/* Conflict with previous definition.  Nuke previous definition */
 	String *e = NewStringEmpty();
 	String *en = NewStringEmpty();
 	String *ec = NewStringEmpty();
-	Printf(ec,"Identifier '%s' redefined by %%extend (ignored),",symname);
-	Printf(en,"%%extend definition of '%s'.",symname);
+	Printf(ec, "Redefinition of identifier '%s' by %%extend ignored,", symname);
+	Printf(en, "%%extend definition of '%s'.", symname);
 	SWIG_WARN_NODE_BEGIN(n);
-	Swig_warning(WARN_PARSE_REDEFINED,Getfile(csym),Getline(csym),"%s\n",ec);
-	Swig_warning(WARN_PARSE_REDEFINED,Getfile(n),Getline(n),"%s\n",en);
+	Swig_warning(WARN_PARSE_REDEFINED, Getfile(c), Getline(c), "%s\n", ec);
+	Swig_warning(WARN_PARSE_REDEFINED, Getfile(n), Getline(n), "%s\n", en);
 	SWIG_WARN_NODE_END(n);
-	Printf(e,"%s:%d:%s\n%s:%d:%s\n",Getfile(csym),Getline(csym),ec, 
-	       Getfile(n),Getline(n),en);
-	Setattr(csym,"error",e);
+	Printf(e, "%s:%d:%s\n%s:%d:%s\n", Getfile(c), Getline(c), ec, Getfile(n),Getline(n),en);
+	Setattr(c, "error", e);
 	Delete(e);
 	Delete(en);
 	Delete(ec);
-	Swig_symbol_remove(csym);              /* Remove class definition */
-	Swig_symbol_add(symname,n);            /* Insert extend definition */
+	Swig_symbol_remove(c);                /* Remove class definition */
+	Swig_symbol_add(symname, n);          /* Insert extend definition */
       }
     }
     n = nextSibling(n);
diff --git a/Source/Swig/fragment.c b/Source/Swig/fragment.c
index 5b30e86..84731f5 100644
--- a/Source/Swig/fragment.c
+++ b/Source/Swig/fragment.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * fragment.c
  *
@@ -29,7 +29,7 @@
  * Swig_fragment_register()
  *
  * Add a fragment. Use the original Node*, so, if something needs to be
- * changed, lang.cxx doesn't nedd to be touched again.
+ * changed, lang.cxx doesn't need to be touched again.
  * ----------------------------------------------------------------------------- */
 
 void Swig_fragment_register(Node *fragment) {
@@ -41,7 +41,7 @@
     String *type = Getattr(fragment, "type");
     if (type) {
       SwigType *rtype = SwigType_typedef_resolve_all(type);
-      String *mangle = Swig_string_mangle(type);
+      String *mangle = Swig_name_mangle_type(type);
       Append(name, mangle);
       Delete(mangle);
       Delete(rtype);
@@ -106,7 +106,7 @@
 
   type = Getattr(n, "type");
   if (type) {
-    mangle = Swig_string_mangle(type);
+    mangle = Swig_name_mangle_type(type);
   }
 
   if (debug)
@@ -162,7 +162,7 @@
       SwigType *rtype = SwigType_typedef_resolve_all(type);
       if (!Equal(type, rtype)) {
 	String *name = Copy(Getattr(n, "value"));
-	String *mangle = Swig_string_mangle(type);
+	String *mangle = Swig_name_mangle_type(type);
 	Append(name, mangle);
 	Setfile(name, Getfile(n));
 	Setline(name, Getline(n));
diff --git a/Source/Swig/getopt.c b/Source/Swig/getopt.c
index 6970dc1..7791d13 100644
--- a/Source/Swig/getopt.c
+++ b/Source/Swig/getopt.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * getopt.c
  *
@@ -32,16 +32,12 @@
  * ----------------------------------------------------------------------------- */
 
 void Swig_init_args(int argc, char **argv) {
-  int i;
   assert(argc > 0);
   assert(argv);
 
   numargs = argc;
   args = argv;
-  marked = (int *) malloc(numargs * sizeof(int));
-  for (i = 0; i < argc; i++) {
-    marked[i] = 0;
-  }
+  marked = (int *) Calloc(numargs, sizeof(int));
   marked[0] = 1;
 }
 
@@ -87,11 +83,11 @@
   }
   if (error) {
     Printf(stderr, "Use 'swig -help' for available options.\n");
-    SWIG_exit(EXIT_FAILURE);
+    Exit(EXIT_FAILURE);
   }
   if (check_input && marked[numargs - 1]) {
     Printf(stderr, "Must specify an input file. Use -help for available options.\n");
-    SWIG_exit(EXIT_FAILURE);
+    Exit(EXIT_FAILURE);
   }
 }
 
@@ -104,5 +100,5 @@
 void Swig_arg_error(void) {
   Printf(stderr, "SWIG : Unable to parse command line options.\n");
   Printf(stderr, "Use 'swig -help' for available options.\n");
-  SWIG_exit(EXIT_FAILURE);
+  Exit(EXIT_FAILURE);
 }
diff --git a/Source/Swig/include.c b/Source/Swig/include.c
index 94df338..c153ac9 100644
--- a/Source/Swig/include.c
+++ b/Source/Swig/include.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * include.c
  *
@@ -110,11 +110,7 @@
   assert(slist);
   filename = NewStringEmpty();
   assert(filename);
-#ifdef MACSWIG
-  Printf(filename, "%s", SWIG_FILE_DELIMITER);
-#else
   Printf(filename, ".%s", SWIG_FILE_DELIMITER);
-#endif
   Append(slist, filename);
   Delete(filename);
   
@@ -145,7 +141,7 @@
   return slist;
 }
 
-List *Swig_search_path() {
+List *Swig_search_path(void) {
   return Swig_search_path_any(0);
 }
 
@@ -376,6 +372,6 @@
 /*
  * Swig_file_debug()
  */
-void Swig_file_debug_set() {
+void Swig_file_debug_set(void) {
   file_debug = 1;
 }
diff --git a/Source/Swig/misc.c b/Source/Swig/misc.c
index 7b81847..3cd1675 100644
--- a/Source/Swig/misc.c
+++ b/Source/Swig/misc.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * misc.c
  *
@@ -36,7 +36,7 @@
 char *Swig_copy_string(const char *s) {
   char *c = 0;
   if (s) {
-    c = (char *) malloc(strlen(s) + 1);
+    c = (char *) Malloc(strlen(s) + 1);
     strcpy(c, s);
   }
   return c;
@@ -63,21 +63,52 @@
 }
 
 /* -----------------------------------------------------------------------------
+ * Swig_package_version_hex()
+ *
+ * Return the package version in hex format "0xAABBCC" such as "0x040200" for 4.2.0
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_package_version_hex(void) {
+  String *package_version = NewString(Swig_package_version());
+  char *token = strtok(Char(package_version), ".");
+  String *vers = NewString("SWIG_VERSION 0x");
+  int count = 0;
+  while (token) {
+    int len = (int)strlen(token);
+    assert(len == 1 || len == 2);
+    Printf(vers, "%s%s", (len == 1) ? "0" : "", token);
+    token = strtok(NULL, ".");
+    count++;
+  }
+  Delete(package_version);
+  assert(count == 3); /* Check version format is correct */
+  return vers;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_obligatory_macros()
+ *
+ * Generates the SWIG_VERSION and SWIGXXX macros where XXX is the target language
+ * name (must be provided uppercase).
+ * ----------------------------------------------------------------------------- */
+
+void Swig_obligatory_macros(String *f_runtime, const char *language) {
+  String *version_hex = Swig_package_version_hex();
+  Printf(f_runtime, "\n\n");
+  Printf(f_runtime, "#define %s\n", version_hex);
+  Printf(f_runtime, "#define SWIG%s\n", language);
+  Delete(version_hex);
+}
+
+/* -----------------------------------------------------------------------------
  * Swig_banner()
  *
  * Emits the SWIG identifying banner for the C/C++ wrapper file.
  * ----------------------------------------------------------------------------- */
 
 void Swig_banner(File *f) {
-  Printf(f, "/* ----------------------------------------------------------------------------\n\
- * This file was automatically generated by SWIG (http://www.swig.org).\n\
- * Version %s\n\
- *\n\
- * This file is not intended to be easily readable and contains a number of\n\
- * coding conventions designed to improve portability and efficiency. Do not make\n\
- * changes to this file unless you know what you are doing--modify the SWIG\n\
- * interface file instead.\n", Swig_package_version());
-  /* String too long for ISO compliance */
+  Printf(f, "/* ----------------------------------------------------------------------------\n");
+  Swig_banner_target_lang(f, " *");
   Printf(f, " * ----------------------------------------------------------------------------- */\n");
 
 }
@@ -89,10 +120,10 @@
  * ----------------------------------------------------------------------------- */
 
 void Swig_banner_target_lang(File *f, const_String_or_char_ptr commentchar) {
-  Printf(f, "%s This file was automatically generated by SWIG (http://www.swig.org).\n", commentchar);
+  Printf(f, "%s This file was automatically generated by SWIG (https://www.swig.org).\n", commentchar);
   Printf(f, "%s Version %s\n", commentchar, Swig_package_version());
   Printf(f, "%s\n", commentchar);
-  Printf(f, "%s Do not make changes to this file unless you know what you are doing--modify\n", commentchar);
+  Printf(f, "%s Do not make changes to this file unless you know what you are doing - modify\n", commentchar);
   Printf(f, "%s the SWIG interface file instead.\n", commentchar);
 }
 
@@ -218,7 +249,7 @@
     if (fname[0] == '/' && fname[1] == '/')
       network_path = 1;
   }
-#if defined(_WIN32) || defined(MACSWIG)
+#if defined(_WIN32)
   /* accept Unix path separator on non-Unix systems */
   Replaceall(filename, "/", SWIG_FILE_DELIMITER);
 #endif
@@ -250,6 +281,19 @@
 }
 
 /* -----------------------------------------------------------------------------
+ * Swig_filename_escape()
+ *
+ * Escapes spaces in filename - for Makefiles
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_filename_escape_space(String *filename) {
+  String *adjusted_filename = Copy(filename);
+  Swig_filename_correct(adjusted_filename);
+  Replaceall(adjusted_filename, " ", "\\ ");
+  return adjusted_filename;
+}
+
+/* -----------------------------------------------------------------------------
  * Swig_filename_unescape()
  *
  * Remove double backslash escaping in filename - for Windows
@@ -658,167 +702,8 @@
   return ns;
 }
 
-/* -----------------------------------------------------------------------------
- * Swig_string_mangle()
- * 
- * Take a string and mangle it by stripping all non-valid C identifier
- * characters.
- *
- * This routine skips unnecessary blank spaces, therefore mangling
- * 'char *' and 'char*', 'std::pair<int, int >' and
- * 'std::pair<int,int>', produce the same result.
- *
- * However, note that 'long long' and 'long_long' produce different
- * mangled strings.
- *
- * The mangling method still is not 'perfect', for example std::pair and
- * std_pair return the same mangling. This is just a little better
- * than before, but it seems to be enough for most of the purposes.
- *
- * Having a perfect mangling will break some examples and code which
- * assume, for example, that A::get_value will be mangled as
- * A_get_value. 
- * ----------------------------------------------------------------------------- */
-
-String *Swig_string_mangle(const String *s) {
-#if 0
-  /* old mangling, not suitable for using in macros */
-  String *t = Copy(s);
-  char *c = Char(t);
-  while (*c) {
-    if (!isalnum(*c))
-      *c = '_';
-    c++;
-  }
-  return t;
-#else
-  String *result = NewStringEmpty();
-  int space = 0;
-  int state = 0;
-  char *pc, *cb;
-  String *b = Copy(s);
-  if (SwigType_istemplate(b)) {
-    String *st = Swig_symbol_template_deftype(b, 0);
-    String *sq = Swig_symbol_type_qualify(st, 0);
-    String *t = SwigType_namestr(sq);
-    Delete(st);
-    Delete(sq);
-    Delete(b);
-    b = t;
-  }
-  pc = cb = Char(b);
-  while (*pc) {
-    char c = *pc;
-    if (isalnum((int) c) || (c == '_')) {
-      state = 1;
-      if (space && (space == state)) {
-	Append(result, "_SS_");
-      }
-      space = 0;
-      Printf(result, "%c", (int) c);
-
-    } else {
-      if (isspace((int) c)) {
-	space = state;
-	++pc;
-	continue;
-      } else {
-	state = 3;
-	space = 0;
-      }
-      switch (c) {
-      case '.':
-	if ((cb != pc) && (*(pc - 1) == 'p')) {
-	  Append(result, "_");
-	  ++pc;
-	  continue;
-	} else {
-	  c = 'f';
-	}
-	break;
-      case ':':
-	if (*(pc + 1) == ':') {
-	  Append(result, "_");
-	  ++pc;
-	  ++pc;
-	  continue;
-	}
-	break;
-      case '*':
-	c = 'm';
-	break;
-      case '&':
-	c = 'A';
-	break;
-      case '<':
-	c = 'l';
-	break;
-      case '>':
-	c = 'g';
-	break;
-      case '=':
-	c = 'e';
-	break;
-      case ',':
-	c = 'c';
-	break;
-      case '(':
-	c = 'p';
-	break;
-      case ')':
-	c = 'P';
-	break;
-      case '[':
-	c = 'b';
-	break;
-      case ']':
-	c = 'B';
-	break;
-      case '^':
-	c = 'x';
-	break;
-      case '|':
-	c = 'o';
-	break;
-      case '~':
-	c = 'n';
-	break;
-      case '!':
-	c = 'N';
-	break;
-      case '%':
-	c = 'M';
-	break;
-      case '?':
-	c = 'q';
-	break;
-      case '+':
-	c = 'a';
-	break;
-      case '-':
-	c = 's';
-	break;
-      case '/':
-	c = 'd';
-	break;
-      default:
-	break;
-      }
-      if (isalpha((int) c)) {
-	Printf(result, "_S%c_", (int) c);
-      } else {
-	Printf(result, "_S%02X_", (int) c);
-      }
-    }
-    ++pc;
-  }
-  Delete(b);
-  return result;
-#endif
-}
-
-String *Swig_string_emangle(String *s) {
-  return Swig_string_mangle(s);
+static String *string_mangle(String *s) {
+  return Swig_name_mangle_string(s);
 }
 
 
@@ -1144,47 +1029,15 @@
 /* -----------------------------------------------------------------------------
  * Swig_string_command()
  *
- * Executes a external command via popen with the string as a command
- * line parameter. For example:
- *
- *  Printf(stderr,"%(command:sed 's/[a-z]/\U\\1/' <<<)s","hello") -> Hello
+ * Feature removed in SWIG 4.1.0.
  * ----------------------------------------------------------------------------- */
-#if defined(_MSC_VER)
-#  define popen _popen
-#  define pclose _pclose
-#  if !defined(HAVE_POPEN)
-#    define HAVE_POPEN 1
-#  endif
-#else
-#  if !defined(_WIN32)
-/* These Posix functions are not ISO C and so are not always defined in stdio.h */
-extern FILE *popen(const char *command, const char *type);
-extern int pclose(FILE *stream);
-#  endif
-#endif
 
 String *Swig_string_command(String *s) {
-  String *res = NewStringEmpty();
-#if defined(HAVE_POPEN)
-  if (Len(s)) {
-    char *command = Char(s);
-    FILE *fp = popen(command, "r");
-    if (fp) {
-      char buffer[1025];
-      while (fscanf(fp, "%1024s", buffer) != EOF) {
-	Append(res, buffer);
-      }
-      pclose(fp);
-    } else {
-      Swig_error("SWIG", Getline(s), "Command encoder fails attempting '%s'.\n", s);
-      SWIG_exit(EXIT_FAILURE);
-    }
-  }
-#endif
-  return res;
+  Swig_error("SWIG", Getline(s), "Command encoder no longer supported - use regex encoder instead, command:%s\n", s);
+  Exit(EXIT_FAILURE);
+  return 0;
 }
 
-
 /* -----------------------------------------------------------------------------
  * Swig_string_strip()
  *
@@ -1270,7 +1123,7 @@
   if ((Char(s))[len-1] == '\n')
     --lines;
   /* allocate a temporary storage for a padded string */
-  res = (char*)malloc(len + lines * number * 2 + 1);
+  res = (char*)Malloc(len + lines * number * 2 + 1);
   res[len + lines * number * 2] = 0;
 
   /* copy lines to res, prepending tabs to each line */
@@ -1294,12 +1147,13 @@
   /* replace 's' contents with 'res' */
   Clear(s);
   Append(s, res);
-  free(res);
+  Free(res);
 }
 
 
 #ifdef HAVE_PCRE
-#include <pcre.h>
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
 
 static int split_regex_pattern_subst(String *s, String **pattern, String **subst, const char **input)
 {
@@ -1327,7 +1181,7 @@
 
 err_out:
   Swig_error("SWIG", Getline(s), "Invalid regex substitution: '%s'.\n", s);
-  SWIG_exit(EXIT_FAILURE);
+  Exit(EXIT_FAILURE);
   return 0;
 }
 
@@ -1362,7 +1216,7 @@
   }
 }
 
-String *replace_captures(int num_captures, const char *input, String *subst, int captures[], String *pattern, String *s)
+String *replace_captures(int num_captures, const char *input, String *subst, size_t captures[], String *pattern, String *s)
 {
   int convertCase = 0, convertNextOnly = 0;
   String *result = NewStringEmpty();
@@ -1384,7 +1238,7 @@
     } else if (isdigit((unsigned char)*p)) {
       int group = *p++ - '0';
       if (group < num_captures) {
-	int l = captures[group*2], r = captures[group*2 + 1];
+	int l = (int)captures[group*2], r = (int)captures[group*2 + 1];
 	if (l != -1) {
 	  copy_with_maybe_case_conversion(result, input + l, r - l, &convertCase, convertNextOnly);
 	}
@@ -1436,47 +1290,59 @@
   const int pcre_options = 0;
 
   String *res = 0;
-  pcre *compiled_pat = 0;
-  const char *pcre_error, *input;
-  int pcre_errorpos;
+  pcre2_code *compiled_pat = 0;
+  const char *input;
+  PCRE2_UCHAR pcre_error[256];
+  int pcre_errornum;
+  size_t pcre_errorpos;
   String *pattern = 0, *subst = 0;
-  int captures[30];
-
+  size_t *captures = 0;
+  pcre2_match_data *match_data = 0;
   if (split_regex_pattern_subst(s, &pattern, &subst, &input)) {
     int rc;
 
-    compiled_pat = pcre_compile(
-          Char(pattern), pcre_options, &pcre_error, &pcre_errorpos, NULL);
+    compiled_pat = pcre2_compile(
+          (PCRE2_SPTR8)Char(pattern), PCRE2_ZERO_TERMINATED, pcre_options, &pcre_errornum, &pcre_errorpos, NULL);
     if (!compiled_pat) {
+      pcre2_get_error_message (pcre_errornum, pcre_error, sizeof pcre_error);
       Swig_error("SWIG", Getline(s), "PCRE compilation failed: '%s' in '%s':%i.\n",
           pcre_error, Char(pattern), pcre_errorpos);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
-    rc = pcre_exec(compiled_pat, NULL, input, (int)strlen(input), 0, 0, captures, 30);
+    match_data = pcre2_match_data_create_from_pattern (compiled_pat, NULL);
+    rc = pcre2_match(compiled_pat, (PCRE2_SPTR8)input, PCRE2_ZERO_TERMINATED, 0, 0, match_data, NULL);
+    captures = pcre2_get_ovector_pointer (match_data);
     if (rc >= 0) {
       res = replace_captures(rc, input, subst, captures, pattern, s);
-    } else if (rc != PCRE_ERROR_NOMATCH) {
+    } else if (rc != PCRE2_ERROR_NOMATCH) {
       Swig_error("SWIG", Getline(s), "PCRE execution failed: error %d while matching \"%s\" using \"%s\".\n",
 	rc, Char(pattern), input);
-      SWIG_exit(EXIT_FAILURE);
+      Exit(EXIT_FAILURE);
     }
   }
 
-  DohDelete(pattern);
-  DohDelete(subst);
-  pcre_free(compiled_pat);
+  Delete(pattern);
+  Delete(subst);
+  pcre2_code_free(compiled_pat);
+  pcre2_match_data_free(match_data);
   return res ? res : NewStringEmpty();
 }
 
 String *Swig_pcre_version(void) {
-  return NewStringf("PCRE Version: %s", pcre_version());
+  int len = pcre2_config(PCRE2_CONFIG_VERSION, NULL);
+  char *buf = Malloc(len);
+  String *result;
+  pcre2_config(PCRE2_CONFIG_VERSION, buf);
+  result = NewStringf("PCRE2 Version: %s", buf);
+  Free(buf);
+  return result;
 }
 
 #else
 
 String *Swig_string_regex(String *s) {
   Swig_error("SWIG", Getline(s), "PCRE regex support not enabled in this SWIG build.\n");
-  SWIG_exit(EXIT_FAILURE);
+  Exit(EXIT_FAILURE);
   return 0;
 }
 
@@ -1491,6 +1357,7 @@
  * Check if the function is an automatically generated
  * overload created because a method has default parameters. 
  * ------------------------------------------------------------ */
+
 int Swig_is_generated_overload(Node *n) {
   Node *base_method = Getattr(n, "sym:overloaded");
   Node *default_args = Getattr(n, "defaultargs");
@@ -1498,12 +1365,32 @@
 }
 
 /* -----------------------------------------------------------------------------
+ * Swig_item_in_list()
+ *
+ * If the input name is the name of an item in the list, return the item
+ * ----------------------------------------------------------------------------- */
+
+Node *Swig_item_in_list(List *list, const_String_or_char_ptr name) {
+  Node *item = 0;
+  if (list) {
+    Iterator it;
+    for (it = First(list); it.item; it = Next(it)) {
+      if (Strcmp(name, it.item) == 0) {
+	item = it.item;
+	break;
+      }
+    }
+  }
+  return item;
+}
+
+/* -----------------------------------------------------------------------------
  * Swig_init()
  *
  * Initialize the SWIG core
  * ----------------------------------------------------------------------------- */
 
-void Swig_init() {
+void Swig_init(void) {
   /* Set some useful string encoding methods */
   DohEncoding("escape", Swig_string_escape);
   DohEncoding("hexescape", Swig_string_hexescape);
@@ -1514,7 +1401,7 @@
   DohEncoding("lctitle", Swig_string_lccase);
   DohEncoding("utitle", Swig_string_ucase);
   DohEncoding("typecode", Swig_string_typecode);
-  DohEncoding("mangle", Swig_string_emangle);
+  DohEncoding("mangle", string_mangle);
   DohEncoding("command", Swig_string_command);
   DohEncoding("schemify", Swig_string_schemify);
   DohEncoding("strip", Swig_string_strip);
diff --git a/Source/Swig/naming.c b/Source/Swig/naming.c
index 6689ceb..6f557a2 100644
--- a/Source/Swig/naming.c
+++ b/Source/Swig/naming.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * naming.c
  *
@@ -157,22 +157,169 @@
 }
 
 /* -----------------------------------------------------------------------------
- * Swig_name_mangle()
- *
- * Converts all of the non-identifier characters of a string to underscores.
+ * Swig_name_mangle_type()
+ * 
+ * Same as Swig_name_mangle_string, but converting internal SwigType * to a human
+ * readable string of the type (for templates). Simplifies a type that is a
+ * template to the default template if possible.
  * ----------------------------------------------------------------------------- */
 
-String *Swig_name_mangle(const_String_or_char_ptr s) {
-#if 0
-  String *r = NewString(s);
-  name_mangle(r);
-  return r;
-#else
-  return Swig_string_mangle(s);
-#endif
+String *Swig_name_mangle_type(const SwigType *s) {
+  String *mangled = 0;
+  String *b = Copy(s);
+  if (SwigType_istemplate(b)) {
+    String *st = Swig_symbol_template_deftype(b, 0);
+    String *sq = Swig_symbol_type_qualify(st, 0);
+    String *t = SwigType_namestr(sq);
+    Delete(st);
+    Delete(sq);
+    Delete(b);
+    b = t;
+  }
+  mangled = Swig_name_mangle_string(b);
+  Delete(b);
+  return mangled;
 }
 
 /* -----------------------------------------------------------------------------
+ * Swig_name_mangle_string()
+ * 
+ * Take a string and mangle it by stripping all non-valid C identifier
+ * characters.
+ *
+ * This routine skips unnecessary blank spaces, therefore mangling
+ * 'char *' and 'char*', 'std::pair<int, int >' and
+ * 'std::pair<int,int>', produce the same result.
+ *
+ * However, note that 'long long' and 'long_long' produce different
+ * mangled strings.
+ *
+ * The mangling method still is not 'perfect', for example std::pair and
+ * std_pair return the same mangling. This is just a little better
+ * than before, but it seems to be enough for most of the purposes.
+ *
+ * Having a perfect mangling will break some examples and code which
+ * assume, for example, that A::get_value will be mangled as
+ * A_get_value. 
+ * ----------------------------------------------------------------------------- */
+
+String *Swig_name_mangle_string(const String *s) {
+  String *result = NewStringEmpty();
+  int space = 0;
+  int state = 0;
+  char *pc, *cb;
+
+  pc = cb = Char(s);
+  while (*pc) {
+    char c = *pc;
+    if (isalnum((int) c) || (c == '_')) {
+      state = 1;
+      if (space && (space == state)) {
+	Append(result, "_SS_");
+      }
+      space = 0;
+      Printf(result, "%c", (int) c);
+
+    } else {
+      if (isspace((int) c)) {
+	space = state;
+	++pc;
+	continue;
+      } else {
+	state = 3;
+	space = 0;
+      }
+      switch (c) {
+      case '.':
+	if ((cb != pc) && (*(pc - 1) == 'p')) {
+	  Append(result, "_");
+	  ++pc;
+	  continue;
+	} else {
+	  c = 'f';
+	}
+	break;
+      case ':':
+	if (*(pc + 1) == ':') {
+	  Append(result, "_");
+	  ++pc;
+	  ++pc;
+	  continue;
+	}
+	break;
+      case '*':
+	c = 'm';
+	break;
+      case '&':
+	c = 'A';
+	break;
+      case '<':
+	c = 'l';
+	break;
+      case '>':
+	c = 'g';
+	break;
+      case '=':
+	c = 'e';
+	break;
+      case ',':
+	c = 'c';
+	break;
+      case '(':
+	c = 'p';
+	break;
+      case ')':
+	c = 'P';
+	break;
+      case '[':
+	c = 'b';
+	break;
+      case ']':
+	c = 'B';
+	break;
+      case '^':
+	c = 'x';
+	break;
+      case '|':
+	c = 'o';
+	break;
+      case '~':
+	c = 'n';
+	break;
+      case '!':
+	c = 'N';
+	break;
+      case '%':
+	c = 'M';
+	break;
+      case '?':
+	c = 'q';
+	break;
+      case '+':
+	c = 'a';
+	break;
+      case '-':
+	c = 's';
+	break;
+      case '/':
+	c = 'd';
+	break;
+      default:
+	break;
+      }
+      if (isalpha((int) c)) {
+	Printf(result, "_S%c_", (int) c);
+      } else {
+	Printf(result, "_S%02X_", (int) c);
+      }
+    }
+    ++pc;
+  }
+  return result;
+}
+
+
+/* -----------------------------------------------------------------------------
  * Swig_name_wrapper()
  *
  * Returns the name of a wrapper function.
@@ -196,9 +343,11 @@
 String *Swig_name_member(const_String_or_char_ptr nspace, const_String_or_char_ptr classname, const_String_or_char_ptr membername) {
   String *r;
   String *rclassname;
+  String *rmembername;
   char *cname;
 
   rclassname = SwigType_namestr(classname);
+  rmembername = SwigType_namestr(membername);
   r = get_naming_format_for("member", "%n%c_%m");
   cname = Char(rclassname);
   if ((strncmp(cname, "struct ", 7) == 0) || ((strncmp(cname, "class ", 6) == 0)) || ((strncmp(cname, "union ", 6) == 0))) {
@@ -206,9 +355,10 @@
   }
   replace_nspace(r, nspace);
   Replace(r, "%c", cname, DOH_REPLACE_ANY);
-  Replace(r, "%m", membername, DOH_REPLACE_ANY);
+  Replace(r, "%m", rmembername, DOH_REPLACE_ANY);
   /*  name_mangle(r); */
   Delete(rclassname);
+  Delete(rmembername);
   return r;
 }
 
@@ -744,28 +894,28 @@
  * ----------------------------------------------------------------------------- */
 
 static Hash *namewarn_hash = 0;
-static Hash *name_namewarn_hash() {
+static Hash *name_namewarn_hash(void) {
   if (!namewarn_hash)
     namewarn_hash = NewHash();
   return namewarn_hash;
 }
 
 static Hash *rename_hash = 0;
-static Hash *name_rename_hash() {
+static Hash *name_rename_hash(void) {
   if (!rename_hash)
     rename_hash = NewHash();
   return rename_hash;
 }
 
 static List *namewarn_list = 0;
-static List *name_namewarn_list() {
+static List *name_namewarn_list(void) {
   if (!namewarn_list)
     namewarn_list = NewList();
   return namewarn_list;
 }
 
 static List *rename_list = 0;
-static List *name_rename_list() {
+static List *name_rename_list(void) {
   if (!rename_list)
     rename_list = NewList();
   return rename_list;
@@ -822,8 +972,8 @@
     }
   }
 
-  if (Cmp(ta, "cdecl") == 0) {
-    /* both cdecl case */
+  if (Equal(ta, "cdecl") || Equal(ta, "constructor")) {
+    /* both cdecl or constructor case */
     /* typedef */
     String *a_storage = Getattr(a, "storage");
     String *b_storage = Getattr(b, "storage");
@@ -847,7 +997,7 @@
 
     /* friend methods */
 
-    if (!a_inclass || (Cmp(a_storage, "friend") == 0)) {
+    if (!a_inclass || Strstr(a_storage, "friend")) {
       /* check declaration */
 
       String *a_decl = (Getattr(a, "decl"));
@@ -906,7 +1056,7 @@
       return 0;
     }
     if (Equal(ta, "template") && Equal(tb, "template")) {
-      if (Cmp(a_storage, "friend") == 0 || Cmp(b_storage, "friend") == 0)
+      if (Strstr(a_storage, "friend") || Strstr(b_storage, "friend"))
 	return 1;
     }
   }
@@ -1092,33 +1242,39 @@
 }
 
 #ifdef HAVE_PCRE
-#include <pcre.h>
+#define PCRE2_CODE_UNIT_WIDTH 8
+#include <pcre2.h>
 
 static int name_regexmatch_value(Node *n, String *pattern, String *s) {
-  pcre *compiled_pat;
-  const char *err;
-  int errpos;
+  pcre2_code *compiled_pat;
+  PCRE2_UCHAR err[256];
+  int errornum;
+  size_t errpos;
   int rc;
+  pcre2_match_data *match_data = 0;
 
-  compiled_pat = pcre_compile(Char(pattern), 0, &err, &errpos, NULL);
+  compiled_pat = pcre2_compile((PCRE2_SPTR8)Char(pattern), PCRE2_ZERO_TERMINATED, 0, &errornum, &errpos, NULL);
   if (!compiled_pat) {
+    pcre2_get_error_message (errornum, err, sizeof err);
     Swig_error("SWIG", Getline(n),
                "Invalid regex \"%s\": compilation failed at %d: %s\n",
                Char(pattern), errpos, err);
-    SWIG_exit(EXIT_FAILURE);
+    Exit(EXIT_FAILURE);
   }
 
-  rc = pcre_exec(compiled_pat, NULL, Char(s), Len(s), 0, 0, NULL, 0);
-  pcre_free(compiled_pat);
+  match_data = pcre2_match_data_create_from_pattern (compiled_pat, NULL);
+  rc = pcre2_match(compiled_pat, (PCRE2_SPTR8)Char(s), PCRE2_ZERO_TERMINATED, 0, 0, match_data, 0);
+  pcre2_code_free(compiled_pat);
+  pcre2_match_data_free(match_data);
 
-  if (rc == PCRE_ERROR_NOMATCH)
+  if (rc == PCRE2_ERROR_NOMATCH)
     return 0;
 
   if (rc < 0 ) {
     Swig_error("SWIG", Getline(n),
                "Matching \"%s\" against regex \"%s\" failed: %d\n",
                Char(s), Char(pattern), rc);
-    SWIG_exit(EXIT_FAILURE);
+    Exit(EXIT_FAILURE);
   }
 
   return 1;
@@ -1131,7 +1287,8 @@
   (void)s;
   Swig_error("SWIG", Getline(n),
              "PCRE regex matching is not available in this SWIG build.\n");
-  SWIG_exit(EXIT_FAILURE);
+  Exit(EXIT_FAILURE);
+  return 0;
 }
 
 #endif /* HAVE_PCRE/!HAVE_PCRE */
@@ -1510,20 +1667,30 @@
 	result = apply_rename(n, rename, fullname, prefix, name);
 	if ((msg) && (Len(msg))) {
 	  if (!Getmeta(nname, "already_warned")) {
+	    String* suffix = 0;
+	    if (Strcmp(result, "$ignore") == 0) {
+	      suffix = NewStringf(": ignoring '%s'\n", name);
+	    } else if (Strcmp(result, name) != 0) {
+	      suffix = NewStringf(", renaming to '%s'\n", result);
+	    } else {
+	      /* No rename was performed */
+	      suffix = NewString("\n");
+	    }
 	    if (n) {
 	      /* Parameter renaming is not fully implemented. Mainly because there is no C/C++ syntax to
 	       * for %rename to fully qualify a function's parameter name from outside the function. Hence it
-	       * is not possible to implemented targetted warning suppression on one parameter in one function. */
+	       * is not possible to implemented targeted warning suppression on one parameter in one function. */
 	      int suppress_parameter_rename_warning = Equal(nodeType(n), "parm");
 	      if (!suppress_parameter_rename_warning) {
 		SWIG_WARN_NODE_BEGIN(n);
-		Swig_warning(0, Getfile(n), Getline(n), "%s\n", msg);
+	      Swig_warning(0, Getfile(n), Getline(n), "%s%s", msg, suffix);
 		SWIG_WARN_NODE_END(n);
 	      }
 	    } else {
-	      Swig_warning(0, Getfile(name), Getline(name), "%s\n", msg);
+	      Swig_warning(0, Getfile(name), Getline(name), "%s%s", msg, suffix);
 	    }
 	    Setmeta(nname, "already_warned", "1");
+	    Delete(suffix);
 	  }
 	}
       }
@@ -1686,29 +1853,31 @@
  * void Swig_name_decl()
  *
  * Return a stringified version of a C/C++ declaration without the return type.
- * The node passed in is expected to be a function, constructor, destructor or
- * variable. Some example return values:
+ * The node passed in is usually a function, constructor, destructor.
+ * Other nodes result in a simple fully qualified string of the symbol.
+ * Some example return values:
  *   "MyNameSpace::MyTemplate<MyNameSpace::ABC >::~MyTemplate()"
  *   "MyNameSpace::ABC::ABC(int,double)"
  *   "MyNameSpace::ABC::constmethod(int) const"
  *   "MyNameSpace::ABC::refqualifiermethod(int) const &"
  *   "MyNameSpace::ABC::variablename"
- * 
+ *   "MyNameSpace::ABC::MyClass"
  * ----------------------------------------------------------------------------- */
 
 String *Swig_name_decl(Node *n) {
   String *qname;
   String *decl;
+  String *nodetype = nodeType(n);
 
   qname = Swig_name_str(n);
   decl = NewStringf("%s", qname);
 
-  if (!checkAttribute(n, "kind", "variable")) {
+  if (nodetype && (Equal(nodetype, "constructor") || Equal(nodetype, "destructor") || Equal(nodetype, "cdecl"))) {
     String *d = Getattr(n, "decl");
-    Printv(decl, "(", ParmList_errorstr(Getattr(n, "parms")), ")", NIL);
     if (SwigType_isfunction(d)) {
       SwigType *decl_temp = Copy(d);
       SwigType *qualifiers = SwigType_pop_function_qualifiers(decl_temp);
+      Printv(decl, "(", ParmList_errorstr(Getattr(n, "parms")), ")", NIL);
       if (qualifiers) {
 	String *qualifiers_string = SwigType_str(qualifiers, 0);
 	Printv(decl, " ", qualifiers_string, NIL);
diff --git a/Source/Swig/parms.c b/Source/Swig/parms.c
index 3e832c3..c1dffb5 100644
--- a/Source/Swig/parms.c
+++ b/Source/Swig/parms.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * parms.c
  *
@@ -113,7 +113,85 @@
 }
 
 /* -----------------------------------------------------------------------------
- * int ParmList_numrequired().  Return number of required arguments
+ * ParmList_join()
+ *
+ * Join two parameter lists. Appends p2 to the end of p.
+ * No copies are made.
+ * Returns start of joined parameter list.
+ * ----------------------------------------------------------------------------- */
+
+ParmList *ParmList_join(ParmList *p, ParmList *p2) {
+  Parm *firstparm = p ? p : p2;
+  Parm *lastparm = 0;
+  while (p) {
+    lastparm = p;
+    p = nextSibling(p);
+  }
+  if (lastparm)
+    set_nextSibling(lastparm, p2);
+
+  return firstparm;
+}
+
+/* -----------------------------------------------------------------------------
+ * ParmList_replace_last()
+ *
+ * Delete last parameter in p and replace it with parameter list p2.
+ * p must have at least one element, that is, must not be NULL.
+ * Return beginning of modified parameter list.
+ * ----------------------------------------------------------------------------- */
+
+ParmList *ParmList_replace_last(ParmList *p, ParmList *p2) {
+  ParmList *start = p;
+  int len = ParmList_len(p);
+  assert(p);
+  if (len == 1) {
+    start = p2;
+  } else if (len > 1) {
+    Parm *secondlastparm = ParmList_nth_parm(p, len - 2);
+    set_nextSibling(secondlastparm, p2);
+  }
+  return start;
+}
+
+/* -----------------------------------------------------------------------------
+ * ParmList_nth_parm()
+ *
+ * return the nth parameter (0 based) in the parameter list
+ * return NULL if there are not enough parameters in the list
+ * ----------------------------------------------------------------------------- */
+
+Parm *ParmList_nth_parm(ParmList *p, unsigned int n) {
+  while (p) {
+    if (n == 0) {
+      break;
+    }
+    n--;
+    p = nextSibling(p);
+  }
+  return p;
+}
+
+/* -----------------------------------------------------------------------------
+ * ParmList_variadic_parm()
+ *
+ * Return the variadic parm (last in list if it is variadic), NULL otherwise
+ * ----------------------------------------------------------------------------- */
+
+Parm *ParmList_variadic_parm(ParmList *p) {
+  Parm *lastparm = 0;
+  while (p) {
+    lastparm = p;
+    p = nextSibling(p);
+  }
+  return lastparm && SwigType_isvariadic(Getattr(lastparm, "type")) ? lastparm : 0;
+}
+
+/* -----------------------------------------------------------------------------
+ * ParmList_numrequired()
+ *
+ * Return number of required arguments - the number of arguments excluding
+ * default arguments
  * ----------------------------------------------------------------------------- */
 
 int ParmList_numrequired(ParmList *p) {
@@ -149,7 +227,7 @@
  * get_empty_type()
  * ---------------------------------------------------------------------- */
 
-static SwigType *get_empty_type() {
+static SwigType *get_empty_type(void) {
   return NewStringEmpty();
 }
 
@@ -263,10 +341,10 @@
  * ---------------------------------------------------------------------- */
 
 int ParmList_has_varargs(ParmList *p) {
-  Parm *lp = 0;
+  Parm *lastparm = 0;
   while (p) {
-    lp = p;
+    lastparm = p;
     p = nextSibling(p);
   }
-  return lp ? SwigType_isvarargs(Getattr(lp, "type")) : 0;
+  return lastparm ? SwigType_isvarargs(Getattr(lastparm, "type")) : 0;
 }
diff --git a/Source/Swig/scanner.c b/Source/Swig/scanner.c
index e5a267a..9348f65 100644
--- a/Source/Swig/scanner.c
+++ b/Source/Swig/scanner.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * scanner.c
  *
@@ -56,7 +56,7 @@
 
 Scanner *NewScanner(void) {
   Scanner *s;
-  s = (Scanner *) malloc(sizeof(Scanner));
+  s = (Scanner *) Malloc(sizeof(Scanner));
   s->line = 1;
   s->file = 0;
   s->nexttoken = -1;
@@ -88,8 +88,8 @@
   Delete(s->file);
   Delete(s->error);
   Delete(s->str);
-  free(s->idstart);
-  free(s); 
+  Free(s->idstart);
+  Free(s);
 }
 
 /* -----------------------------------------------------------------------------
@@ -202,7 +202,7 @@
  * ----------------------------------------------------------------------------- */
 
 void Scanner_idstart(Scanner *s, const char *id) {
-  free(s->idstart);
+  Free(s->idstart);
   s->idstart = Swig_copy_string(id);
 }
 
@@ -336,9 +336,9 @@
  * Usually called when '(' is found.
  * ----------------------------------------------------------------------------- */
 static void brackets_push(Scanner *s) {
-  int *newInt = (int *)malloc(sizeof(int));
+  int *newInt = (int *)Malloc(sizeof(int));
   *newInt = 0;
-  Push(s->brackets, NewVoid(newInt, free));
+  Push(s->brackets, NewVoid(newInt, Free));
 }
 
 /* -----------------------------------------------------------------------------
@@ -468,12 +468,9 @@
 	state = 20;
 	Delitem(s->text, DOH_END);
       } else {
-	char tmp[3];
-	tmp[0] = '\\';
-	tmp[1] = (char)c;
-	tmp[2] = 0;
 	Delitem(s->text, DOH_END);
-	Append(s->text, tmp);
+	Putc('\\',s->text);
+	Putc((char)c,s->text);
 	return;
       }
       break;
@@ -596,10 +593,6 @@
 	state = 3;
       else if (c == '\\')
 	return SWIG_TOKEN_BACKSLASH;
-      else if (c == '[')
-	return SWIG_TOKEN_LBRACKET;
-      else if (c == ']')
-	return SWIG_TOKEN_RBRACKET;
       else if (c == '@')
 	return SWIG_TOKEN_AT;
       else if (c == '$')
@@ -636,7 +629,11 @@
       }
 
       else if (c == '.')
-	state = 100;		/* Maybe a number, maybe just a period */
+	state = 100;		/* Maybe a number, maybe ellipsis, just a period */
+      else if (c == '[')
+        state = 102;            /* Maybe a bracket or a double bracket */
+      else if (c == ']')
+        state = 103;            /* Maybe a bracket or a double bracket */
       else if (isdigit(c))
 	state = 8;		/* A numerical value */
       else
@@ -716,9 +713,7 @@
 	state = 20;
       }
       else {
-	char temp[2] = { 0, 0 };
-	temp[0] = c;
-	Append( str_delimiter, temp );
+	Putc( (char)c, str_delimiter );
       }
     
       break;
@@ -742,9 +737,7 @@
 	  int i=0;
 	  String *end_delimiter = NewStringEmpty();
 	  while ((c = nextchar(s)) != 0 && c!='\"') {
-	    char temp[2] = { 0, 0 };
-	    temp[0] = c;
-	    Append( end_delimiter, temp );
+	    Putc( (char)c, end_delimiter );
 	    i++;
 	  }
 	  
@@ -833,7 +826,7 @@
 	return SWIG_TOKEN_MODEQUAL;
       } else if (c == '}') {
 	Swig_error(cparse_file, cparse_line, "Syntax error. Extraneous '%%}'\n");
-	SWIG_exit(EXIT_FAILURE);
+	Exit(EXIT_FAILURE);
       } else {
 	retract(s, 1);
 	return SWIG_TOKEN_PERCENT;
@@ -893,9 +886,16 @@
       }
       if (c == '<')
 	state = 240;
-      else if (c == '=')
-	return SWIG_TOKEN_LTEQUAL;
-      else {
+      else if (c == '=') {
+	if ((c = nextchar(s)) == 0) {
+	  return SWIG_TOKEN_LTEQUAL;
+	} else if (c == '>' && cparse_cplusplus) { /* Spaceship operator */
+	  return SWIG_TOKEN_LTEQUALGT;
+	} else {
+	  retract(s, 1);
+	  return SWIG_TOKEN_LTEQUAL;
+	}
+      } else {
 	retract(s, 1);
 	brackets_increment(s);
 	return SWIG_TOKEN_LESSTHAN;
@@ -1031,9 +1031,8 @@
 	  return SWIG_TOKEN_BOOL;
 	else if (Strcmp(s->text, "false") == 0)
 	  return SWIG_TOKEN_BOOL;
-	}
+      }
       return SWIG_TOKEN_ID;
-      break;
 
     case 77: /*identifier or wide string literal*/
       if ((c = nextchar(s)) == 0)
@@ -1121,7 +1120,7 @@
 	return SWIG_TOKEN_FLOAT;
       } else if ((c == 'l') || (c == 'L')) {
 	Delitem(s->text, DOH_END);
-	return SWIG_TOKEN_DOUBLE;
+	return SWIG_TOKEN_LONGDOUBLE;
       } else {
 	retract(s, 1);
 	return (SWIG_TOKEN_DOUBLE);
@@ -1258,7 +1257,7 @@
 	return SWIG_TOKEN_FLOAT;
       } else if ((c == 'l') || (c == 'L')) {
 	Delitem(s->text, DOH_END);
-	return SWIG_TOKEN_DOUBLE;
+	return SWIG_TOKEN_LONGDOUBLE;
       } else {
 	retract(s, 1);
 	return SWIG_TOKEN_DOUBLE;
@@ -1330,19 +1329,59 @@
       }
       break;
 
-      /* A period or maybe a floating point number */
+      /* A period or an ellipsis or maybe a floating point number */
 
     case 100:
       if ((c = nextchar(s)) == 0)
 	return (0);
       if (isdigit(c))
 	state = 81;
+      else if (c == '.')
+	state = 101;
       else {
 	retract(s, 1);
 	return SWIG_TOKEN_PERIOD;
       }
       break;
 
+      /* An ellipsis */
+
+    case 101:
+      if ((c = nextchar(s)) == 0)
+	return (0);
+      if (c == '.') {
+	return SWIG_TOKEN_ELLIPSIS;
+      } else {
+	retract(s, 2);
+	return SWIG_TOKEN_PERIOD;
+      }
+      break;
+
+    /* A left bracket or a double left bracket */
+    case 102:
+
+      if ((c = nextchar(s)) == 0) {
+        return SWIG_TOKEN_LBRACKET;
+      } else if (c == '[') {
+        return SWIG_TOKEN_LLBRACKET;
+      } else {
+        retract(s, 1);
+        return SWIG_TOKEN_LBRACKET;
+      }
+      break;
+
+    /* a right bracket or a double right bracket */
+    case 103:
+      if ((c = nextchar(s)) == 0) {
+        return SWIG_TOKEN_RBRACKET;
+      } else if (c == ']') {
+        return SWIG_TOKEN_RRBRACKET;
+      } else {
+        retract(s, 1);
+        return SWIG_TOKEN_RBRACKET;
+      }
+      break;
+
     case 200:			/* PLUS, PLUSPLUS, PLUSEQUAL */
       if ((c = nextchar(s)) == 0)
 	return SWIG_TOKEN_PLUS;
@@ -1427,9 +1466,6 @@
       }
       break;
 
-
-      /* An illegal character */
-
       /* Reverse string */
     case 900:
       if ((c = nextchar(s)) == 0) {
@@ -1442,6 +1478,7 @@
       }
       break;
 
+      /* An illegal character */
     default:
       return SWIG_TOKEN_ILLEGAL;
     }
@@ -1511,131 +1548,61 @@
  *
  * Skips a piece of code enclosed in begin/end symbols such as '{...}' or
  * (...).  Ignores symbols inside comments or strings.
+ *
+ * Returns 0 on success, -1 if no matching endchar could be found.
  * ----------------------------------------------------------------------------- */
 
 int Scanner_skip_balanced(Scanner *s, int startchar, int endchar) {
-  char c;
-  int num_levels = 1;
-  int state = 0;
-  char temp[2] = { 0, 0 };
-  String *locator = 0;
-  temp[0] = (char) startchar;
-  Clear(s->text);
-  Setfile(s->text, Getfile(s->str));
-  Setline(s->text, s->line);
+  int old_line = s->line;
+  long position = Tell(s->str);
 
-  Append(s->text, temp);
-  while (num_levels > 0) {
-    if ((c = nextchar(s)) == 0) {
-      Delete(locator);
-      return -1;
-    }
-    switch (state) {
-    case 0:
-      if (c == startchar)
-	num_levels++;
-      else if (c == endchar)
-	num_levels--;
-      else if (c == '/')
-	state = 10;
-      else if (c == '\"')
-	state = 20;
-      else if (c == '\'')
-	state = 30;
+  int num_levels = 1;
+  int starttok = 0;
+  int endtok = 0;
+  switch (endchar) {
+    case '}':
+      starttok = SWIG_TOKEN_LBRACE;
+      endtok = SWIG_TOKEN_RBRACE;
       break;
-    case 10:
-      if (c == '/')
-	state = 11;
-      else if (c == '*')
-	state = 12;
-      else if (c == startchar) {
-	state = 0;
-	num_levels++;
-      }
-      else
-	state = 0;
+    case ')':
+      starttok = SWIG_TOKEN_LPAREN;
+      endtok = SWIG_TOKEN_RPAREN;
       break;
-    case 11:
-      if (c == '\n')
-	state = 0;
-      else
-	state = 11;
+    case ']':
+      starttok = SWIG_TOKEN_LBRACKET;
+      endtok = SWIG_TOKEN_RBRACKET;
       break;
-    case 12: /* first character inside C comment */
-      if (c == '*')
-	state = 14;
-      else if (c == '@')
-	state = 40;
-      else
-	state = 13;
-      break;
-    case 13:
-      if (c == '*')
-	state = 14;
-      break;
-    case 14: /* possible end of C comment */
-      if (c == '*')
-	state = 14;
-      else if (c == '/')
-	state = 0;
-      else
-	state = 13;
-      break;
-    case 20:
-      if (c == '\"')
-	state = 0;
-      else if (c == '\\')
-	state = 21;
-      break;
-    case 21:
-      state = 20;
-      break;
-    case 30:
-      if (c == '\'')
-	state = 0;
-      else if (c == '\\')
-	state = 31;
-      break;
-    case 31:
-      state = 30;
-      break;
-    /* 40-45 SWIG locator checks - a C comment with contents starting: @SWIG */
-    case 40:
-      state = (c == 'S') ? 41 : (c == '*') ? 14 : 13;
-      break;
-    case 41:
-      state = (c == 'W') ? 42 : (c == '*') ? 14 : 13;
-      break;
-    case 42:
-      state = (c == 'I') ? 43 : (c == '*') ? 14 : 13;
-      break;
-    case 43:
-      state = (c == 'G') ? 44 : (c == '*') ? 14 : 13;
-      if (c == 'G') {
-	Delete(locator);
-	locator = NewString("/*@SWIG");
-      }
-      break;
-    case 44:
-      if (c == '*')
-	state = 45;
-      Putc(c, locator);
-      break;
-    case 45: /* end of SWIG locator in C comment */
-      if (c == '/') {
-	state = 0;
-	Putc(c, locator);
-	Scanner_locator(s, locator);
-      } else {
-	/* malformed locator */
-	state = (c == '*') ? 14 : 13;
-      }
+    case '>':
+      starttok = SWIG_TOKEN_LESSTHAN;
+      endtok = SWIG_TOKEN_GREATERTHAN;
       break;
     default:
-      break;
+      assert(0);
+  }
+
+  while (1) {
+    int tok = Scanner_token(s);
+    if (tok == starttok) {
+      num_levels++;
+    } else if (tok == endtok) {
+      if (--num_levels == 0) break;
+    } else if (tok == SWIG_TOKEN_COMMENT) {
+      char *loc = Char(s->text);
+      if (strncmp(loc, "/*@SWIG", 7) == 0 && loc[Len(s->text)-3] == '@') {
+	Scanner_locator(s, s->text);
+      }
+    } else if (tok == 0) {
+      return -1;
     }
   }
-  Delete(locator);
+
+  Delete(s->text);
+  s->text = NewStringWithSize(Char(s->str) + position - 1,
+			      Tell(s->str) - position + 1);
+  Char(s->text)[0] = startchar;
+  Setfile(s->text, Getfile(s->str));
+  Setline(s->text, old_line);
+
   return 0;
 }
 
@@ -1646,107 +1613,67 @@
  * ----------------------------------------------------------------------------- */
 
 String *Scanner_get_raw_text_balanced(Scanner *s, int startchar, int endchar) {
-  String *result = 0;
-  char c;
+  String *result = NULL;
   int old_line = s->line;
   String *old_text = Copy(s->text);
   long position = Tell(s->str);
 
   int num_levels = 1;
-  int state = 0;
-  char temp[2] = { 0, 0 };
-  temp[0] = (char) startchar;
-  Clear(s->text);
-  Setfile(s->text, Getfile(s->str));
-  Setline(s->text, s->line);
-  Append(s->text, temp);
-  while (num_levels > 0) {
-    if ((c = nextchar(s)) == 0) {
-      Clear(s->text);
-      Append(s->text, old_text);
-      Delete(old_text);
-      s->line = old_line;
-      return 0;
-    }
-    switch (state) {
-    case 0:
-      if (c == startchar)
-	num_levels++;
-      else if (c == endchar)
-	num_levels--;
-      else if (c == '/')
-	state = 10;
-      else if (c == '\"')
-	state = 20;
-      else if (c == '\'')
-	state = 30;
+  int starttok = 0;
+  int endtok = 0;
+  switch (endchar) {
+    case '}':
+      starttok = SWIG_TOKEN_LBRACE;
+      endtok = SWIG_TOKEN_RBRACE;
       break;
-    case 10:
-      if (c == '/')
-	state = 11;
-      else if (c == '*')
-	state = 12;
-      else if (c == startchar) {
-	state = 0;
-	num_levels++;
-      }
-      else
-	state = 0;
+    case ')':
+      starttok = SWIG_TOKEN_LPAREN;
+      endtok = SWIG_TOKEN_RPAREN;
       break;
-    case 11:
-      if (c == '\n')
-	state = 0;
-      else
-	state = 11;
+    case ']':
+      starttok = SWIG_TOKEN_LBRACKET;
+      endtok = SWIG_TOKEN_RBRACKET;
       break;
-    case 12: /* first character inside C comment */
-      if (c == '*')
-	state = 14;
-      else
-	state = 13;
-      break;
-    case 13:
-      if (c == '*')
-	state = 14;
-      break;
-    case 14: /* possible end of C comment */
-      if (c == '*')
-	state = 14;
-      else if (c == '/')
-	state = 0;
-      else
-	state = 13;
-      break;
-    case 20:
-      if (c == '\"')
-	state = 0;
-      else if (c == '\\')
-	state = 21;
-      break;
-    case 21:
-      state = 20;
-      break;
-    case 30:
-      if (c == '\'')
-	state = 0;
-      else if (c == '\\')
-	state = 31;
-      break;
-    case 31:
-      state = 30;
+    case '>':
+      starttok = SWIG_TOKEN_LESSTHAN;
+      endtok = SWIG_TOKEN_GREATERTHAN;
       break;
     default:
+      assert(0);
+  }
+
+  while (1) {
+    int tok = Scanner_token(s);
+    if (tok == starttok) {
+      num_levels++;
+    } else if (tok == endtok) {
+      if (--num_levels == 0) {
+	result = NewStringWithSize(Char(s->str) + position - 1,
+				   Tell(s->str) - position + 1);
+	Char(result)[0] = startchar;
+	Setfile(result, Getfile(s->str));
+	Setline(result, old_line);
+	break;
+      }
+    } else if (tok == SWIG_TOKEN_COMMENT) {
+      char *loc = Char(s->text);
+      if (strncmp(loc, "/*@SWIG", 7) == 0 && loc[Len(s->text)-3] == '@') {
+	Scanner_locator(s, s->text);
+      }
+    } else if (tok == 0) {
       break;
     }
   }
+
+  /* Reset the scanner state. */
   Seek(s->str, position, SEEK_SET);
-  result = Copy(s->text);
-  Clear(s->text);
-  Append(s->text, old_text);
-  Delete(old_text);
+  Delete(s->text);
+  s->text = old_text;
   s->line = old_line;
+
   return result;
 }
+
 /* -----------------------------------------------------------------------------
  * Scanner_isoperator()
  *
@@ -1796,14 +1723,14 @@
 	cparse_file = locs->filename;
 	cparse_line = locs->line_number;
 	l = locs->next;
-	free(locs);
+	Free(locs);
 	locs = l;
       }
       return;
     }
 
     /* We're going to push a new location */
-    l = (Locator *) malloc(sizeof(Locator));
+    l = (Locator *) Malloc(sizeof(Locator));
     l->filename = cparse_file;
     l->line_number = cparse_line;
     l->next = locs;
diff --git a/Source/Swig/stype.c b/Source/Swig/stype.c
index 66518f5..b0eec2f 100644
--- a/Source/Swig/stype.c
+++ b/Source/Swig/stype.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * stype.c
  *
@@ -42,6 +42,7 @@
  *  'p.'                = Pointer (*)
  *  'r.'                = Reference (&)
  *  'z.'                = Rvalue reference (&&)
+ *  'v.'                = Variadic (...)
  *  'a(n).'             = Array of size n  [n]
  *  'f(..,..).'         = Function with arguments  (args)
  *  'q(str).'           = Qualifier, such as const or volatile (cv-qualifier)
@@ -108,71 +109,59 @@
   switch (t) {
   case T_BOOL:
     return NewString("bool");
-    break;
+  case T_UNKNOWN:
+    /* Handle like T_INT since we used to just use T_INT where we now use
+     * T_UNKNOWN.
+     */
   case T_INT:
     return NewString("int");
-    break;
   case T_UINT:
     return NewString("unsigned int");
-    break;
   case T_SHORT:
     return NewString("short");
-    break;
   case T_USHORT:
     return NewString("unsigned short");
-    break;
   case T_LONG:
     return NewString("long");
-    break;
   case T_ULONG:
     return NewString("unsigned long");
-    break;
   case T_FLOAT:
     return NewString("float");
-    break;
   case T_DOUBLE:
     return NewString("double");
-    break;
+  case T_LONGDOUBLE:
+    return NewString("long double");
+  case T_FLTCPLX:
+    return NewString("float _Complex");
   case T_COMPLEX:
-    return NewString("complex");
-    break;
+    return NewString("_Complex");
   case T_CHAR:
     return NewString("char");
-    break;
   case T_SCHAR:
     return NewString("signed char");
-    break;
   case T_UCHAR:
     return NewString("unsigned char");
-    break;
   case T_STRING: {
       SwigType *t = NewString("char");
       SwigType_add_qualifier(t, "const");
       SwigType_add_pointer(t);
       return t;
-      break;
     }
   case T_WCHAR:
     return NewString("wchar_t");
-    break;
   case T_WSTRING: {
     SwigType *t = NewString("wchar_t");
     SwigType_add_pointer(t);
     return t;
-    break;
   }
   case T_LONGLONG:
     return NewString("long long");
-    break;
   case T_ULONGLONG:
     return NewString("unsigned long long");
-    break;
   case T_VOID:
     return NewString("void");
-    break;
   case T_AUTO:
     return NewString("auto");
-    break;
   default:
     break;
   }
@@ -260,8 +249,12 @@
 int SwigType_ismutable(const SwigType *t) {
   int r;
   SwigType *qt = SwigType_typedef_resolve_all(t);
-  if (SwigType_isreference(qt) || SwigType_isrvalue_reference(qt) || SwigType_isarray(qt)) {
+  if (SwigType_isreference(qt) || SwigType_isrvalue_reference(qt)) {
     Delete(SwigType_pop(qt));
+  } else {
+    while (SwigType_isarray(qt)) {
+      Delete(SwigType_pop(qt));
+    }
   }
   r = SwigType_isconst(qt);
   Delete(qt);
@@ -549,7 +542,7 @@
   int nelements, i;
 
   if (id) {
-    /* stringify the id expanding templates, for example when the id is a fully qualified templated class name */
+    /* Stringify the id expanding templates, for example when the id is a fully qualified class template name */
     String *id_str = NewString(id); /* unfortunate copy due to current const limitations */
     result = SwigType_str(id_str, 0);
     Delete(id_str);
@@ -624,6 +617,12 @@
 	Insert(result, 0, "(");
 	Append(result, ")");
       }
+    } else if (SwigType_isvariadic(element)) {
+      Insert(result, 0, "...");
+      if ((forwardelement) && ((SwigType_isfunction(forwardelement) || (SwigType_isarray(forwardelement))))) {
+	Insert(result, 0, "(");
+	Append(result, ")");
+      }
     } else if (SwigType_isarray(element)) {
       DOH *size;
       Append(result, "[");
@@ -1190,7 +1189,9 @@
   SwigType *type = ss;
 
   if (SwigType_istemplate(ss)) {
-    SwigType *ty = Swig_symbol_template_deftype(ss, 0);
+    SwigType *dt = Swig_symbol_template_deftype(ss, 0);
+    String *ty = Swig_symbol_type_qualify(dt, 0);
+    Delete(dt);
     Delete(ss);
     ss = ty;
     type = ss;
@@ -1253,10 +1254,10 @@
 String *SwigType_manglestr(const SwigType *s) {
 #if 0
   /* Debugging checks to ensure a proper SwigType is passed in and not a stringified type */
-  String *angle = Strstr(s, "<");
+  String *angle = Strchr(s, '<');
   if (angle && Strncmp(angle, "<(", 2) != 0)
     Printf(stderr, "SwigType_manglestr error: %s\n", s);
-  else if (Strstr(s, "*") || Strstr(s, "&") || Strstr(s, "["))
+  else if (Strchr(s, '*') || Strchr(s, '&') || Strchr(s, '['))
     Printf(stderr, "SwigType_manglestr error: %s\n", s);
 #endif
   return manglestr_default(s);
@@ -1266,6 +1267,11 @@
  * SwigType_typename_replace()
  *
  * Replaces a typename in a type with something else.  Needed for templates.
+ * Collapses duplicate const into a single const.
+ * Reference collapsing probably should be implemented here.
+ * Example:
+ *   t=r.q(const).T pat=T rep=int           =>  r.q(const).int
+ *   t=r.q(const).T pat=T rep=q(const).int  =>  r.q(const).int  (duplicate const removed)
  * ----------------------------------------------------------------------------- */
 
 void SwigType_typename_replace(SwigType *t, String *pat, String *rep) {
@@ -1288,14 +1294,40 @@
     if (SwigType_issimple(e)) {
       if (Equal(e, pat)) {
 	/* Replaces a type of the form 'pat' with 'rep<args>' */
-	Replace(e, pat, rep, DOH_REPLACE_ANY);
+	if (SwigType_isconst(rep) && i > 0 && SwigType_isconst(Getitem(elem, i - 1))) {
+	  /* Collapse duplicate const into a single const */
+	  SwigType *rep_without_const = Copy(rep);
+	  Delete(SwigType_pop(rep_without_const));
+	  Replace(e, pat, rep_without_const, DOH_REPLACE_ANY);
+	  Delete(rep_without_const);
+	} else {
+	  Replace(e, pat, rep, DOH_REPLACE_ANY);
+	}
       } else if (SwigType_istemplate(e)) {
 	/* Replaces a type of the form 'pat<args>' with 'rep' */
-	if (Equal(e, pat)) {
-	  String *repbase = SwigType_templateprefix(rep);
-	  Replace(e, pat, repbase, DOH_REPLACE_ID | DOH_REPLACE_FIRST);
-	  Delete(repbase);
+	{
+	  /* To match "e=TemplateTemplateT<(float)>"
+	   * with "pat=TemplateTemplateT"
+	   * we need to compare only the first part of the string e.
+	   */
+	  int len = Len(pat);
+
+	  /* Len(e) > len, not >= (because we expect at least a
+	   * character '<' following the template typename)
+	   */
+	  if (Len(e) > len) {
+	    String *firstPartOfType = NewStringWithSize(e, len);
+	    const char* e_as_char = Char(e);
+
+	    if (Equal(firstPartOfType, pat) && e_as_char[len] == '<') {
+	      String *repbase = SwigType_templateprefix(rep);
+	      Replace(e, pat, repbase, DOH_REPLACE_ID | DOH_REPLACE_FIRST);
+	      Delete(repbase);
+	    }
+	    Delete(firstPartOfType);
+	  }
 	}
+
 	{
 	  String *tsuffix;
 	  List *tparms = SwigType_parmlist(e);
@@ -1366,6 +1398,73 @@
 }
 
 /* -----------------------------------------------------------------------------
+ * SwigType_variadic_replace()
+ *
+ * Replaces variadic parameter with a list of (zero or more) parameters.
+ * Needed for variadic templates.
+ * ----------------------------------------------------------------------------- */
+
+void SwigType_variadic_replace(SwigType *t, Parm *unexpanded_variadic_parm, ParmList *expanded_variadic_parms) {
+  String *nt;
+  int i, ilen;
+  List *elem;
+  if (!unexpanded_variadic_parm)
+    return;
+
+  if (SwigType_isvariadic(t)) {
+    /* Based on expand_variadic_parms() but input is single SwigType (t) instead of ParmList */
+    String *unexpanded_name = Getattr(unexpanded_variadic_parm, "name");
+    ParmList *expanded = CopyParmList(expanded_variadic_parms);
+    Parm *ep = expanded;
+    SwigType *fparms;
+    while (ep) {
+      SwigType *newtype = Copy(t);
+      SwigType_del_variadic(newtype);
+      Replaceid(newtype, unexpanded_name, Getattr(ep, "type"));
+      Setattr(ep, "type", newtype);
+      ep = nextSibling(ep);
+    }
+    Clear(t);
+    fparms = SwigType_function_parms_only(expanded);
+    Append(t, fparms);
+    Delete(expanded);
+
+    return;
+  }
+  nt = NewStringEmpty();
+  elem = SwigType_split(t);
+  ilen = Len(elem);
+  for (i = 0; i < ilen; i++) {
+    String *e = Getitem(elem, i);
+    if (SwigType_isfunction(e)) {
+      int j, jlen;
+      List *fparms = SwigType_parmlist(e);
+      Clear(e);
+      Append(e, "f(");
+      jlen = Len(fparms);
+      for (j = 0; j < jlen; j++) {
+	SwigType *type = Getitem(fparms, j);
+	SwigType_variadic_replace(type, unexpanded_variadic_parm, expanded_variadic_parms);
+	if (Len(type) > 0) {
+	  if (j != 0)
+	    Putc(',', e);
+	  Append(e, type);
+	} else {
+	  assert(j == jlen - 1); /* A variadic parm was replaced with zero parms, variadic parms are only changed at the end of the list */
+	}
+      }
+      Append(e, ").");
+      Delete(fparms);
+    }
+    Append(nt, e);
+  }
+  Clear(t);
+  Append(t, nt);
+  Delete(nt);
+  Delete(elem);
+}
+
+/* -----------------------------------------------------------------------------
  * SwigType_remove_global_scope_prefix()
  *
  * Removes the unary scope operator (::) prefix indicating global scope in all 
diff --git a/Source/Swig/swig.h b/Source/Swig/swig.h
index 523aef5..042b5ed 100644
--- a/Source/Swig/swig.h
+++ b/Source/Swig/swig.h
@@ -4,19 +4,17 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * swig.h
  *
  * Header file for the SWIG core.
  * ----------------------------------------------------------------------------- */
 
-#ifndef SWIGCORE_H_
-#define SWIGCORE_H_
+#ifndef SWIG_SWIG_H
+#define SWIG_SWIG_H
 
-#ifndef MACSWIG
 #include "swigconfig.h"
-#endif
 
 #include <stdio.h>
 #include <string.h>
@@ -66,7 +64,6 @@
 #define   T_UCHAR      3
 #define   T_SHORT      4
 #define   T_USHORT     5
-#define   T_ENUM       6
 #define   T_INT        7
 #define   T_UINT       8
 #define   T_LONG       9
@@ -78,7 +75,6 @@
 #define   T_LONGDOUBLE 22
 #define   T_FLTCPLX    23
 #define   T_DBLCPLX    24
-#define   T_NUMERIC    25
 #define   T_AUTO       26
 
 #define   T_COMPLEX    T_DBLCPLX
@@ -98,11 +94,7 @@
 #define   T_VARARGS    39
 #define   T_RVALUE_REFERENCE  40
 #define   T_WSTRING    41
-
-#define   T_SYMBOL     98
-#define   T_ERROR      99
-
-
+#define   T_UNKNOWN    42
 
 /* --- File interface --- */
 
@@ -131,16 +123,20 @@
   extern SwigType *SwigType_del_reference(SwigType *t);
   extern SwigType *SwigType_add_rvalue_reference(SwigType *t);
   extern SwigType *SwigType_del_rvalue_reference(SwigType *t);
+  extern SwigType *SwigType_add_variadic(SwigType *t);
+  extern SwigType *SwigType_del_variadic(SwigType *t);
   extern SwigType *SwigType_add_qualifier(SwigType *t, const_String_or_char_ptr qual);
   extern SwigType *SwigType_del_qualifier(SwigType *t);
   extern SwigType *SwigType_add_function(SwigType *t, ParmList *parms);
   extern SwigType *SwigType_add_template(SwigType *t, ParmList *parms);
   extern SwigType *SwigType_pop_function(SwigType *t);
   extern SwigType *SwigType_pop_function_qualifiers(SwigType *t);
+  extern SwigType *SwigType_function_parms_only(ParmList *parms);
   extern ParmList *SwigType_function_parms(const SwigType *t, Node *file_line_node);
   extern List *SwigType_split(const SwigType *t);
   extern String *SwigType_pop(SwigType *t);
   extern void SwigType_push(SwigType *t, String *s);
+  extern SwigType *SwigType_last(SwigType *t);
   extern List *SwigType_parmlist(const SwigType *p);
   extern String *SwigType_parm(const SwigType *p);
   extern String *SwigType_str(const SwigType *s, const_String_or_char_ptr id);
@@ -156,6 +152,7 @@
   extern int SwigType_isreference(const SwigType *t);
   extern int SwigType_isreference_return(const SwigType *t);
   extern int SwigType_isrvalue_reference(const SwigType *t);
+  extern int SwigType_isvariadic(const SwigType *t);
   extern int SwigType_isarray(const SwigType *t);
   extern int SwigType_prefix_is_simple_1D_array(const SwigType *t);
   extern int SwigType_isfunction(const SwigType *t);
@@ -185,6 +182,7 @@
   extern SwigType *SwigType_default_create(const SwigType *ty);
   extern SwigType *SwigType_default_deduce(const SwigType *t);
   extern void SwigType_typename_replace(SwigType *t, String *pat, String *rep);
+  extern void SwigType_variadic_replace(SwigType *t, Parm *unexpanded_variadic_parm, ParmList *expanded_variadic_parms);
   extern SwigType *SwigType_remove_global_scope_prefix(const SwigType *t);
   extern SwigType *SwigType_alttype(const SwigType *t, int ltmap);
 
@@ -232,17 +230,19 @@
   extern Symtab *Swig_symbol_global_scope(void);
   extern Symtab *Swig_symbol_current(void);
   extern Symtab *Swig_symbol_popscope(void);
-  extern Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *node);
-  extern void Swig_symbol_cadd(const_String_or_char_ptr symname, Node *node);
+  extern Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n);
+  extern void Swig_symbol_conflict_warn(Node *n, Node *c, const String *symname, int inclass);
+  extern void Swig_symbol_cadd(const_String_or_char_ptr symname, Node *n);
   extern Node *Swig_symbol_clookup(const_String_or_char_ptr symname, Symtab *tab);
-  extern Node *Swig_symbol_clookup_check(const_String_or_char_ptr symname, Symtab *tab, int (*check) (Node *));
+  extern Node *Swig_symbol_clookup_check(const_String_or_char_ptr symname, Symtab *tab, Node *(*checkfunc) (Node *));
   extern Node *Swig_symbol_clookup_no_inherit(const_String_or_char_ptr name, Symtab *n);
   extern Symtab *Swig_symbol_cscope(const_String_or_char_ptr symname, Symtab *tab);
   extern Node *Swig_symbol_clookup_local(const_String_or_char_ptr symname, Symtab *tab);
-  extern Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr symname, Symtab *tab, int (*check) (Node *));
-  extern String *Swig_symbol_qualified(Node *node);
-  extern Node *Swig_symbol_isoverloaded(Node *node);
-  extern void Swig_symbol_remove(Node *node);
+  extern Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr symname, Symtab *tab, Node *(*checkfunc) (Node *));
+  extern String *Swig_symbol_qualified(Node *n);
+  extern Node *Swig_symbol_isoverloaded(Node *n);
+  extern void Swig_symbol_remove(Node *n);
+  extern void Swig_symbol_fix_overname(Node *n);
   extern void Swig_symbol_alias(const_String_or_char_ptr aliasname, Symtab *tab);
   extern void Swig_symbol_inherit(Symtab *tab);
   extern SwigType *Swig_symbol_type_qualify(const SwigType *ty, Symtab *tab);
@@ -272,7 +272,8 @@
 
   extern void Swig_name_register(const_String_or_char_ptr method, const_String_or_char_ptr format);
   extern void Swig_name_unregister(const_String_or_char_ptr method);
-  extern String *Swig_name_mangle(const_String_or_char_ptr s);
+  extern String *Swig_name_mangle_string(const String *s);
+  extern String *Swig_name_mangle_type(const SwigType *s);
   extern String *Swig_name_wrapper(const_String_or_char_ptr fname);
   extern String *Swig_name_member(const_String_or_char_ptr nspace, const_String_or_char_ptr classname, const_String_or_char_ptr membername);
   extern String *Swig_name_get(const_String_or_char_ptr nspace, const_String_or_char_ptr vname);
@@ -309,19 +310,21 @@
   extern char *Swig_copy_string(const char *c);
   extern void Swig_set_fakeversion(const char *version);
   extern const char *Swig_package_version(void);
+  extern String *Swig_package_version_hex(void);
+  extern void Swig_obligatory_macros(String *f_runtime, const char *language);
   extern void Swig_banner(File *f);
   extern void Swig_banner_target_lang(File *f, const_String_or_char_ptr commentchar);
   extern String *Swig_strip_c_comments(const String *s);
   extern String *Swig_new_subdirectory(String *basedirectory, String *subdirectory);
   extern void Swig_filename_correct(String *filename);
   extern String *Swig_filename_escape(String *filename);
+  extern String *Swig_filename_escape_space(String *filename);
   extern void Swig_filename_unescape(String *filename);
   extern int Swig_storage_isextern(Node *n);
   extern int Swig_storage_isexternc(Node *n);
   extern int Swig_storage_isstatic_custom(Node *n, const_String_or_char_ptr storage);
   extern int Swig_storage_isstatic(Node *n);
   extern String *Swig_string_escape(String *s);
-  extern String *Swig_string_mangle(const String *s);
   extern void Swig_scopename_split(const String *s, String **prefix, String **last);
   extern String *Swig_scopename_prefix(const String *s);
   extern String *Swig_scopename_last(const String *s);
@@ -338,6 +341,7 @@
 
   extern int Swig_value_wrapper_mode(int mode);
   extern int Swig_is_generated_overload(Node *n);
+  extern Node *Swig_item_in_list(List *list, const String *name);
 
   typedef enum { EMF_STANDARD, EMF_MICROSOFT } ErrorMessageFormat;
 
@@ -438,8 +442,6 @@
   extern void Language_replace_special_variables(String *method, String *tm, Parm *parm);
   extern void Swig_print(DOH *object, int count);
   extern void Swig_print_with_location(DOH *object, int count);
-  extern void SWIG_exit(int exit_code) __attribute__((noreturn));
-
 
 /* -- template init -- */
   extern void SwigType_template_init(void);
diff --git a/Source/Swig/swigfile.h b/Source/Swig/swigfile.h
index f12b330..009599a 100644
--- a/Source/Swig/swigfile.h
+++ b/Source/Swig/swigfile.h
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * swigfile.h
  *
@@ -30,13 +30,11 @@
 extern String *Swig_file_basename(const_String_or_char_ptr filename);
 extern String *Swig_file_filename(const_String_or_char_ptr filename);
 extern String *Swig_file_dirname(const_String_or_char_ptr filename);
-extern void   Swig_file_debug_set();
+extern void   Swig_file_debug_set(void);
 
 /* Delimiter used in accessing files and directories */
 
-#if defined(MACSWIG)
-#  define SWIG_FILE_DELIMITER ":"
-#elif defined(_WIN32)
+#if defined(_WIN32)
 #  define SWIG_FILE_DELIMITER "\\"
 #else
 #  define SWIG_FILE_DELIMITER "/"
diff --git a/Source/Swig/swigopt.h b/Source/Swig/swigopt.h
index 543bfb8..86a477b 100644
--- a/Source/Swig/swigopt.h
+++ b/Source/Swig/swigopt.h
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * swigopt.h
  *
diff --git a/Source/Swig/swigparm.h b/Source/Swig/swigparm.h
index 7b27df5..2d4cfb8 100644
--- a/Source/Swig/swigparm.h
+++ b/Source/Swig/swigparm.h
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * swigparm.h
  *
@@ -19,10 +19,15 @@
 extern Parm      *CopyParm(Parm *p);
 
 /* Parameter lists */
-extern ParmList  *CopyParmList(ParmList *);
-extern ParmList  *CopyParmListMax(ParmList *, int count);
-extern int        ParmList_len(ParmList *);
+extern ParmList  *CopyParmList(ParmList *p);
+extern ParmList  *CopyParmListMax(ParmList *p, int count);
+extern ParmList  *ParmList_join(ParmList *p, ParmList *p2);
+extern ParmList  *ParmList_replace_last(ParmList *p, ParmList *p2);
+extern Parm      *ParmList_nth_parm(ParmList *p, unsigned int n);
+extern Parm      *ParmList_variadic_parm(ParmList *p);
+extern Parm      *ParmList_add_parm(ParmList *p, Parm *newparm);
 extern int        ParmList_numrequired(ParmList *);
+extern int        ParmList_len(ParmList *);
 extern int        ParmList_has_defaultargs(ParmList *p);
 extern int        ParmList_has_varargs(ParmList *p);
 
diff --git a/Source/Swig/swigscan.h b/Source/Swig/swigscan.h
index 740a936..edb7dfb 100644
--- a/Source/Swig/swigscan.h
+++ b/Source/Swig/swigscan.h
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * swigscan.h
  *
@@ -53,30 +53,33 @@
 #define   SWIG_TOKEN_ID           15       /* identifier */
 #define   SWIG_TOKEN_FLOAT        16       /* 3.1415F */
 #define   SWIG_TOKEN_DOUBLE       17       /* 3.1415 */
-#define   SWIG_TOKEN_INT          18       /* 314 */
-#define   SWIG_TOKEN_UINT         19       /* 314U */
-#define   SWIG_TOKEN_LONG         20       /* 314L */
-#define   SWIG_TOKEN_ULONG        21       /* 314UL */
-#define   SWIG_TOKEN_CHAR         22       /* 'charconst' */
-#define   SWIG_TOKEN_PERIOD       23       /* . */
-#define   SWIG_TOKEN_AT           24       /* @ */
-#define   SWIG_TOKEN_DOLLAR       25       /* $ */
-#define   SWIG_TOKEN_CODEBLOCK    26       /* %{ ... %} ... */
-#define   SWIG_TOKEN_RSTRING      27       /* `charconst` */
-#define   SWIG_TOKEN_LONGLONG     28       /* 314LL */
-#define   SWIG_TOKEN_ULONGLONG    29       /* 314ULL */
-#define   SWIG_TOKEN_QUESTION     30       /* ? */
-#define   SWIG_TOKEN_COMMENT      31       /* C or C++ comment */
-#define   SWIG_TOKEN_BOOL         32       /* true or false */
-#define   SWIG_TOKEN_WSTRING      33       /* L"str" */
-#define   SWIG_TOKEN_WCHAR        34       /* L'c' */
+#define   SWIG_TOKEN_LONGDOUBLE   18       /* 3.1415L */
+#define   SWIG_TOKEN_INT          19       /* 314 */
+#define   SWIG_TOKEN_UINT         20       /* 314U */
+#define   SWIG_TOKEN_LONG         21       /* 314L */
+#define   SWIG_TOKEN_ULONG        22       /* 314UL */
+#define   SWIG_TOKEN_CHAR         23       /* 'charconst' */
+#define   SWIG_TOKEN_PERIOD       24       /* . */
+#define   SWIG_TOKEN_AT           25       /* @ */
+#define   SWIG_TOKEN_DOLLAR       26       /* $ */
+#define   SWIG_TOKEN_CODEBLOCK    27       /* %{ ... %} ... */
+#define   SWIG_TOKEN_RSTRING      28       /* `charconst` */
+#define   SWIG_TOKEN_LONGLONG     29       /* 314LL */
+#define   SWIG_TOKEN_ULONGLONG    30       /* 314ULL */
+#define   SWIG_TOKEN_QUESTION     31       /* ? */
+#define   SWIG_TOKEN_COMMENT      32       /* C or C++ comment */
+#define   SWIG_TOKEN_BOOL         33       /* true or false */
+#define   SWIG_TOKEN_WSTRING      34       /* L"str" */
+#define   SWIG_TOKEN_WCHAR        35       /* L'c' */
+#define   SWIG_TOKEN_ELLIPSIS     36       /* ... */
+#define   SWIG_TOKEN_LLBRACKET    37       /* [[ */
+#define   SWIG_TOKEN_RRBRACKET    38       /* ]] */
 
 #define   SWIG_TOKEN_ILLEGAL      99
 #define   SWIG_TOKEN_ERROR        -1
 
 #define   SWIG_TOKEN_COMMA        101      /* , */
 #define   SWIG_TOKEN_STAR         102      /* * */
-#define   SWIG_TOKEN_TIMES        102      /* * */
 #define   SWIG_TOKEN_EQUAL        103      /* = */
 #define   SWIG_TOKEN_EQUALTO      104      /* == */
 #define   SWIG_TOKEN_NOTEQUAL     105      /* != */
@@ -94,9 +97,7 @@
 #define   SWIG_TOKEN_NOT          117      /* ~ */
 #define   SWIG_TOKEN_LNOT         118      /* ! */
 #define   SWIG_TOKEN_SLASH        119      /* / */
-#define   SWIG_TOKEN_DIVIDE       119      /* / */
 #define   SWIG_TOKEN_PERCENT      120      /* % */
-#define   SWIG_TOKEN_MODULO       120      /* % */
 #define   SWIG_TOKEN_LSHIFT       121      /* << */
 #define   SWIG_TOKEN_RSHIFT       122      /* >> */
 #define   SWIG_TOKEN_PLUSPLUS     123      /* ++ */
@@ -113,3 +114,4 @@
 #define   SWIG_TOKEN_MODEQUAL     134      /* %= */
 #define   SWIG_TOKEN_ARROW        135      /* -> */
 #define   SWIG_TOKEN_ARROWSTAR    136      /* ->* */
+#define   SWIG_TOKEN_LTEQUALGT    137      /* <=> */
diff --git a/Source/Swig/swigtree.h b/Source/Swig/swigtree.h
index acd0e5e..8d63d8f 100644
--- a/Source/Swig/swigtree.h
+++ b/Source/Swig/swigtree.h
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * swigtree.h
  *
@@ -51,3 +51,4 @@
 extern void Swig_print_tags(File *obj, Node *root);
 extern void Swig_print_tree(Node *obj);
 extern void Swig_print_node(Node *obj);
+extern int Swig_print_quiet(int quiet);
diff --git a/Source/Swig/swigwrap.h b/Source/Swig/swigwrap.h
index e44cb53..b584ca4 100644
--- a/Source/Swig/swigwrap.h
+++ b/Source/Swig/swigwrap.h
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * swigwrap.h
  *
diff --git a/Source/Swig/symbol.c b/Source/Swig/symbol.c
index aacaf24..165efbd 100644
--- a/Source/Swig/symbol.c
+++ b/Source/Swig/symbol.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * symbol.c
  *
@@ -12,7 +12,7 @@
  * ----------------------------------------------------------------------------- */
 
 #include "swig.h"
-#include "swigwarn.h"
+#include "cparse.h"
 #include <ctype.h>
 
 /* #define SWIG_DEBUG*/
@@ -495,7 +495,7 @@
  *
  * Inherit symbols from another scope. Primarily for C++ inheritance and
  * for using directives, such as 'using namespace X;'
- * but not for using declarations, such as 'using A;'.
+ * but not for using declarations, such as 'using X::A;'.
  * ----------------------------------------------------------------------------- */
 
 void Swig_symbol_inherit(Symtab *s) {
@@ -553,6 +553,12 @@
     String *cname = NewString(name);
     String *dname = Swig_symbol_template_deftype(cname, 0);
     if (!Equal(dname, name)) {
+      /* Add another symbol with all template default arguments expanded, eg
+       *
+       * template <typename T1, typename T2 = short> struct X {};
+       * %template(XInt) X<int>;
+       *
+       * then name=X<int>, and dname=X<int,short> so add X<int,short> here too. */
       Swig_symbol_cadd(dname, n);
     }
     Delete(dname);
@@ -641,10 +647,11 @@
 
   {
     Node *td = n;
-    while (td && Checkattr(td, "nodeType", "cdecl") && Checkattr(td, "storage", "typedef")) {
+    while (td && ((Equal(nodeType(td), "cdecl") && Checkattr(td, "storage", "typedef")) || (Equal(nodeType(td), "using") && !Getattr(n, "namespace")))) {
       SwigType *type;
       Node *td1;
-      type = Copy(Getattr(td, "type"));
+      int using_not_typedef = Equal(nodeType(td), "using");
+      type = Copy(Getattr(td, using_not_typedef ? "uname" : "type"));
       SwigType_push(type, Getattr(td, "decl"));
       td1 = Swig_symbol_clookup(type, 0);
 
@@ -665,9 +672,13 @@
          ie, when Foo -> FooBar -> Foo, jump one scope up when possible.
 
        */
-      if (td1 && Checkattr(td1, "storage", "typedef")) {
-	String *st = Getattr(td1, "type");
+      if (td1) {
+	String *st = 0;
 	String *sn = Getattr(td, "name");
+	if (Equal(nodeType(td1), "cdecl") && Checkattr(td1, "storage", "typedef"))
+	  st = Getattr(td1, "type");
+	else if (Equal(nodeType(td1), "using") && !Getattr(td1, "namespace"))
+	  st = Getattr(td1, "uname");
 	if (st && sn && Equal(st, sn)) {
 	  Symtab *sc = Getattr(current_symtab, "parentNode");
 	  if (sc)
@@ -700,7 +711,7 @@
  * for namespace support, type resolution, and other issues.
  * ----------------------------------------------------------------------------- */
 
-Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) {
+static Node *symbol_add(const_String_or_char_ptr symname, Node *n) {
   Hash *c, *cl = 0;
   SwigType *decl, *ndecl;
   String *cstorage, *nstorage;
@@ -739,7 +750,6 @@
 
   /* No symbol name defined.  We return. */
   if (!symname) {
-    Setattr(n, "sym:symtab", current_symtab);
     return n;
   }
 
@@ -834,10 +844,10 @@
 
       /* Hmmm.  This appears to be okay.  Make sure the symbol table refers to the allow_type node */
 
-      if (td != c) {
+      Setattr(n, "sym:symtab", current_symtab);
+      Setattr(n, "sym:name", symname);
+      if (td == n) {
 	Setattr(current, symname, td);
-	Setattr(td, "sym:symtab", current_symtab);
-	Setattr(td, "sym:name", symname);
       }
       return n;
     }
@@ -937,6 +947,69 @@
   return n;
 }
 
+Node *Swig_symbol_add(const_String_or_char_ptr symname, Node *n) {
+  Node *nn = symbol_add(symname, n);
+  /* Always set the symtab to have correct scope in case of error reporting */
+  if (!Getattr(n, "sym:symtab"))
+    Setattr(n, "sym:symtab", current_symtab);
+  return nn;
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_conflict_warn()
+ *
+ * Issue warnings for node n if it conflicts with node c after calling
+ * Swig_symbol_add().
+ * ----------------------------------------------------------------------------- */
+
+void Swig_symbol_conflict_warn(Node *n, Node *c, const String *symname, int inclass) {
+  String *e = NewStringEmpty();
+  String *en = NewStringEmpty();
+  String *ec = NewStringEmpty();
+  String *symname_stripped = SwigType_templateprefix(symname);
+  String *n_name_stripped = SwigType_templateprefix(Getattr(n, "name"));
+  String *c_name_stripped = SwigType_templateprefix(Getattr(c, "name"));
+  int redefined = Swig_need_redefined_warn(n, c, inclass);
+  String *n_name_decl = Swig_name_decl(n);
+  String *c_name_decl = Swig_name_decl(c);
+  if (redefined) {
+    Printf(en, "Redefinition of identifier '%s'", symname_stripped);
+    Printf(ec, "previous definition of '%s'", symname_stripped);
+  } else {
+    Printf(en, "Redundant redeclaration of identifier '%s'", symname_stripped);
+    Printf(ec, "previous declaration of '%s'", symname_stripped);
+  }
+  if (!Equal(symname_stripped, n_name_stripped))
+    Printf(en, " (Renamed from '%s')", SwigType_namestr(n_name_stripped));
+  if (!Equal(symname_stripped, c_name_stripped))
+    Printf(ec, " (Renamed from '%s')", SwigType_namestr(c_name_stripped));
+  if (!Equal(n_name_stripped, n_name_decl))
+    Printf(en, " as %s", n_name_decl);
+  if (!Equal(c_name_stripped, c_name_decl))
+    Printf(ec, " as %s", c_name_decl);
+  Printf(en, " ignored,");
+  Printf(ec, ".");
+  SWIG_WARN_NODE_BEGIN(n);
+  if (redefined) {
+    Swig_warning(WARN_PARSE_REDEFINED, Getfile(n), Getline(n), "%s\n", en);
+    Swig_warning(WARN_PARSE_REDEFINED, Getfile(c), Getline(c), "%s\n", ec);
+  } else if (!Checkattr(n, "storage", "friend") && !Checkattr(c, "storage", "friend")) {
+    Swig_warning(WARN_PARSE_REDUNDANT, Getfile(n), Getline(n), "%s\n", en);
+    Swig_warning(WARN_PARSE_REDUNDANT, Getfile(c), Getline(c), "%s\n", ec);
+  }
+  SWIG_WARN_NODE_END(n);
+  Printf(e, "%s:%d:%s\n%s:%d:%s\n", Getfile(n), Getline(n), en, Getfile(c), Getline(c), ec);
+  Setattr(n, "error", e);
+  Delete(c_name_decl);
+  Delete(n_name_decl);
+  Delete(symname_stripped);
+  Delete(c_name_stripped);
+  Delete(n_name_stripped);
+  Delete(e);
+  Delete(en);
+  Delete(ec);
+}
+
 /* -----------------------------------------------------------------------------
  * symbol_lookup()
  *
@@ -946,12 +1019,12 @@
  *
  * This function operates in the C namespace, not the target namespace.
  *
- * The check function is an optional callback that can be used to verify a particular
+ * The checkfunc function is an optional callback that can be used to verify a particular
  * symbol match.   This is only used in some of the more exotic parts of SWIG. For instance,
  * verifying that a class hierarchy implements all pure virtual methods.
  * ----------------------------------------------------------------------------- */
 
-static Node *_symbol_lookup(const String *name, Symtab *symtab, int (*check) (Node *n)) {
+static Node *_symbol_lookup(const String *name, Symtab *symtab, Node *(*checkfunc) (Node *n)) {
   Node *n;
   List *inherit;
   Hash *sym = Getattr(symtab, "csymtab");
@@ -966,17 +1039,13 @@
 #endif
 
   if (n) {
-    /* if a check-function is defined.  Call it to determine a match */
-    if (check) {
-      int c = check(n);
-      if (c == 1) {
+    /* if checkfunc is defined.  Call it to determine a match */
+    if (checkfunc) {
+      Node *cn = checkfunc(n);
+      if (cn) {
 	Setmark(symtab, 0);
-	return n;
-      }
-      if (c < 0) {
-	/* Terminate the search right away */
-	Setmark(symtab, 0);
-	return 0;
+	/* Note that checkfunc can return n != cn, where cn could be a node further down the csym linked list starting at n */
+	return cn;
       }
     } else {
       Setmark(symtab, 0);
@@ -989,7 +1058,7 @@
     Setmark(symtab, 0);
     dname = Swig_symbol_template_deftype(name, symtab);
     if (!Equal(dname, name)) {
-      n = _symbol_lookup(dname, symtab, check);
+      n = _symbol_lookup(dname, symtab, checkfunc);
     }
     Delete(dname);
     if (n)
@@ -1002,7 +1071,7 @@
     int i, len;
     len = Len(inherit);
     for (i = 0; i < len; i++) {
-      n = _symbol_lookup(name, Getitem(inherit, i), check);
+      n = _symbol_lookup(name, Getitem(inherit, i), checkfunc);
       if (n) {
 	Setmark(symtab, 0);
 	return n;
@@ -1014,13 +1083,13 @@
   return 0;
 }
 
-static Node *symbol_lookup(const_String_or_char_ptr name, Symtab *symtab, int (*check) (Node *n)) {
+static Node *symbol_lookup(const_String_or_char_ptr name, Symtab *symtab, Node *(*checkfunc) (Node *n)) {
   Node *n = 0;
   if (DohCheck(name)) {
-    n = _symbol_lookup(name, symtab, check);
+    n = _symbol_lookup(name, symtab, checkfunc);
   } else {
     String *sname = NewString(name);
-    n = _symbol_lookup(sname, symtab, check);
+    n = _symbol_lookup(sname, symtab, checkfunc);
     Delete(sname);
   }
   return n;
@@ -1032,7 +1101,7 @@
  * symbol_lookup_qualified()
  * ----------------------------------------------------------------------------- */
 
-static Node *symbol_lookup_qualified(const_String_or_char_ptr name, Symtab *symtab, const String *prefix, int local, int (*checkfunc) (Node *n)) {
+static Node *symbol_lookup_qualified(const_String_or_char_ptr name, Symtab *symtab, const String *prefix, int local, Node *(*checkfunc) (Node *n)) {
   /* This is a little funky, we search by fully qualified names */
 
   if (!symtab)
@@ -1168,18 +1237,22 @@
     }
   }
 
-  if (!s) {
-    return 0;
-  }
   /* Check if s is a 'using' node */
   while (s && Checkattr(s, "nodeType", "using")) {
-    String *uname = Getattr(s, "uname");
-    Symtab *un = Getattr(s, "sym:symtab");
-    Node *ss = (!Equal(name, uname) || (un != n)) ? Swig_symbol_clookup(uname, un) : 0;	/* avoid infinity loop */
-    if (!ss) {
-      Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname")));
+    if (Getattr(s, "csym:nextSibling")) {
+      /* overloaded using declarations and method declarations - don't chase the using declarations up the inheritance hierarchy  */
+      break;
+    } else {
+      String *uname = Getattr(s, "uname");
+      Symtab *un = Getattr(s, "sym:symtab");
+      Node *ss = (!Equal(name, uname) || (un != n)) ? Swig_symbol_clookup(uname, un) : 0;	/* avoid infinity loop */
+      if (!ss) {
+	SWIG_WARN_NODE_BEGIN(s);
+	Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(uname));
+	SWIG_WARN_NODE_END(s);
+      }
+      s = ss;
     }
-    s = ss;
   }
   return s;
 }
@@ -1194,7 +1267,7 @@
  * inheritance hierarchy. 
  * ----------------------------------------------------------------------------- */
 
-Node *Swig_symbol_clookup_check(const_String_or_char_ptr name, Symtab *n, int (*checkfunc) (Node *n)) {
+Node *Swig_symbol_clookup_check(const_String_or_char_ptr name, Symtab *n, Node *(*checkfunc) (Node *n)) {
   Hash *hsym = 0;
   Node *s = 0;
 
@@ -1241,17 +1314,23 @@
 	break;
     }
   }
-  if (!s) {
-    return 0;
-  }
+
   /* Check if s is a 'using' node */
   while (s && Checkattr(s, "nodeType", "using")) {
-    Node *ss;
-    ss = Swig_symbol_clookup(Getattr(s, "uname"), Getattr(s, "sym:symtab"));
-    if (!ss && !checkfunc) {
-      Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname")));
+    if (Getattr(s, "csym:nextSibling")) {
+      /* overloaded using declarations and method declarations - don't chase the using declarations up the inheritance hierarchy  */
+      break;
+    } else {
+      String *uname = Getattr(s, "uname");
+      Symtab *un = Getattr(s, "sym:symtab");
+      Node *ss = Swig_symbol_clookup_check(uname, un, checkfunc);
+      if (!ss && !checkfunc) {
+	SWIG_WARN_NODE_BEGIN(s);
+	Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(uname));
+	SWIG_WARN_NODE_END(s);
+      }
+      s = ss;
     }
-    s = ss;
   }
   return s;
 }
@@ -1294,15 +1373,23 @@
   if (!s) {
     s = symbol_lookup(name, hsym, 0);
   }
-  if (!s)
-    return 0;
+
   /* Check if s is a 'using' node */
   while (s && Checkattr(s, "nodeType", "using")) {
-    Node *ss = Swig_symbol_clookup_local(Getattr(s, "uname"), Getattr(s, "sym:symtab"));
-    if (!ss) {
-      Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname")));
+    if (Getattr(s, "csym:nextSibling")) {
+      /* overloaded using declarations and method declarations - don't chase the using declarations up the inheritance hierarchy  */
+      break;
+    } else {
+      String *uname = Getattr(s, "uname");
+      Symtab *un = Getattr(s, "sym:symtab");
+      Node *ss = Swig_symbol_clookup_local(uname, un);
+      if (!ss) {
+	SWIG_WARN_NODE_BEGIN(s);
+	Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(uname));
+	SWIG_WARN_NODE_END(s);
+      }
+      s = ss;
     }
-    s = ss;
   }
   return s;
 }
@@ -1311,7 +1398,7 @@
  * Swig_symbol_clookup_local_check()
  * ----------------------------------------------------------------------------- */
 
-Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr name, Symtab *n, int (*checkfunc) (Node *)) {
+Node *Swig_symbol_clookup_local_check(const_String_or_char_ptr name, Symtab *n, Node *(*checkfunc) (Node *)) {
   Hash *hsym;
   Node *s = 0;
 
@@ -1342,15 +1429,23 @@
   if (!s) {
     s = symbol_lookup(name, hsym, checkfunc);
   }
-  if (!s)
-    return 0;
+
   /* Check if s is a 'using' node */
   while (s && Checkattr(s, "nodeType", "using")) {
-    Node *ss = Swig_symbol_clookup_local_check(Getattr(s, "uname"), Getattr(s, "sym:symtab"), checkfunc);
-    if (!ss && !checkfunc) {
-      Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(Getattr(s, "uname")));
+    if (Getattr(s, "csym:nextSibling")) {
+      /* overloaded using declarations and method declarations - don't chase the using declarations up the inheritance hierarchy  */
+      break;
+    } else {
+      String *uname = Getattr(s, "uname");
+      Symtab *un = Getattr(s, "sym:symtab");
+      Node *ss = Swig_symbol_clookup_local_check(uname, un, checkfunc);
+      if (!ss && !checkfunc) {
+	SWIG_WARN_NODE_BEGIN(s);
+	Swig_warning(WARN_PARSE_USING_UNDEF, Getfile(s), Getline(s), "Nothing known about '%s'.\n", SwigType_namestr(uname));
+	SWIG_WARN_NODE_END(s);
+      }
+      s = ss;
     }
-    s = ss;
   }
   return s;
 }
@@ -1358,7 +1453,8 @@
 /* -----------------------------------------------------------------------------
  * Swig_symbol_clookup_no_inherit()
  *
- * Symbol lookup like Swig_symbol_clookup but does not follow using declarations.
+ * Symbol lookup like Swig_symbol_clookup but does not follow using directives.
+ * Using declarations are followed.
  * ----------------------------------------------------------------------------- */
 
 Node *Swig_symbol_clookup_no_inherit(const_String_or_char_ptr name, Symtab *n) {
@@ -1394,7 +1490,6 @@
 void Swig_symbol_remove(Node *n) {
   Symtab *symtab;
   String *symname;
-  String *overname;
   Node *symprev;
   Node *symnext;
   Node *fixovername = 0;
@@ -1436,11 +1531,22 @@
   Delattr(n, "sym:overname");
   Delattr(n, "csym:previousSibling");
   Delattr(n, "sym:overloaded");
-  n = 0;
 
-  if (fixovername) {
-    Node *nn = fixovername;
-    Node *head = fixovername;
+  Swig_symbol_fix_overname(fixovername);
+}
+
+/* -----------------------------------------------------------------------------
+ * Swig_symbol_fix_overname()
+ *
+ * Fix/update the sym:overname attribute for all the overloaded names.
+ * The sym:overname attributes are changed to start from zero, eg __SWIG_0.
+ * Call this when the linked lists for overloaded methods are modified.
+ * ----------------------------------------------------------------------------- */
+
+void Swig_symbol_fix_overname(Node *n) {
+  if (n) {
+    Node *nn = n;
+    Node *head = n;
     int pn = 0;
 
     /* find head of linked list */
@@ -1452,9 +1558,8 @@
     /* adjust all the sym:overname strings to start from 0 and increment by one */
     nn = head;
     while (nn) {
-      assert(Getattr(nn, "sym:overname"));
+      String *overname = NewStringf("__SWIG_%d", pn);
       Delattr(nn, "sym:overname");
-      overname = NewStringf("__SWIG_%d", pn);
       Setattr(nn, "sym:overname", overname);
       Delete(overname);
       pn++;
@@ -1505,7 +1610,8 @@
 static SwigType *symbol_template_qualify(const SwigType *e, Symtab *st) {
   String *tprefix, *tsuffix;
   SwigType *qprefix;
-  List *targs;
+  String *targs;
+  List *targslist;
   Node *tempn;
   Symtab *tscope;
   Iterator ti;
@@ -1528,12 +1634,15 @@
   tprefix = SwigType_templateprefix(e);
   tsuffix = SwigType_templatesuffix(e);
   qprefix = Swig_symbol_type_qualify(tprefix, st);
-  targs = SwigType_parmlist(e);
+  targs = SwigType_templateargs(e);
+  targslist = SwigType_parmlist(targs);
   tempn = Swig_symbol_clookup_local(tprefix, st);
   tscope = tempn ? Getattr(tempn, "sym:symtab") : 0;
   Append(qprefix, "<(");
-  for (ti = First(targs); ti.item;) {
+  for (ti = First(targslist); ti.item;) {
     String *vparm;
+    /* TODO: the logic here should be synchronised with that in SwigType_typedef_qualified() */
+    /* TODO: ti.item might be a non-type parameter possibly within (), eg: (std::is_integral_v<(A)>||std::is_same_v<(A,node_t)>) */
     String *qparm = Swig_symbol_type_qualify(ti.item, st);
     if (tscope && (tscope != st)) {
       String *ty = Swig_symbol_type_qualify(qparm, tscope);
@@ -1555,6 +1664,7 @@
   Delete(tprefix);
   Delete(tsuffix);
   Delete(targs);
+  Delete(targslist);
 #ifdef SWIG_DEBUG
   Printf(stderr, "symbol_temp_qual %s %s\n", e, qprefix);
 #endif
@@ -1567,8 +1677,12 @@
 }
 
 
-static int symbol_no_constructor(Node *n) {
-  return !Checkattr(n, "nodeType", "constructor");
+static Node *symbol_no_constructor(Node *n) {
+  return Checkattr(n, "nodeType", "constructor") ? 0 : n;
+}
+
+static Node *symbol_is_template(Node *n) {
+  return Checkattr(n, "nodeType", "template") ? n : 0;
 }
 
 /* -----------------------------------------------------------------------------
@@ -1728,7 +1842,7 @@
 
   n = Swig_symbol_clookup(base, tab);
   if (!n) {
-    if (SwigType_istemplate(ty)) {
+    if (SwigType_istemplate(base)) {
       SwigType *qt = Swig_symbol_template_reduce(base, tab);
       Append(prefix, qt);
       Delete(qt);
@@ -1926,6 +2040,7 @@
  * Swig_symbol_template_deftype()
  *
  * Apply default args to generic template type
+ * Return input type with template args expanded to include default template args
  * ----------------------------------------------------------------------------- */
 
 #define SWIG_TEMPLATE_DEFTYPE_CACHE
@@ -2000,9 +2115,9 @@
       String *targs = SwigType_templateargs(base);
       String *tsuffix = SwigType_templatesuffix(base);
       ParmList *tparms = SwigType_function_parms(targs, 0);
-      Node *tempn = Swig_symbol_clookup_local(tprefix, tscope);
+      Node *tempn = Swig_symbol_clookup_local_check(tprefix, tscope, symbol_is_template);
       if (!tempn && tsuffix && Len(tsuffix)) {
-	tempn = Swig_symbol_clookup(tprefix, 0);
+	tempn = Swig_symbol_clookup_check(tprefix, 0, symbol_is_template);
       }
 #ifdef SWIG_DEBUG
       Printf(stderr, "deftype type %s %s %d\n", e, tprefix, (long) tempn);
diff --git a/Source/Swig/tree.c b/Source/Swig/tree.c
index 46571fc..1573bd1 100644
--- a/Source/Swig/tree.c
+++ b/Source/Swig/tree.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * tree.c
  *
@@ -16,6 +16,20 @@
 #include <stdarg.h>
 #include <assert.h>
 
+static int debug_quiet = 0;
+
+/* -----------------------------------------------------------------------------
+ * Swig_print_quiet()
+ *
+ * Set quiet mode when printing a parse tree node
+ * ----------------------------------------------------------------------------- */
+
+int Swig_print_quiet(int quiet) {
+  int previous_quiet = debug_quiet;
+  debug_quiet = quiet;
+  return previous_quiet;
+}
+
 /* -----------------------------------------------------------------------------
  * Swig_print_tags()
  *
@@ -66,33 +80,46 @@
 void Swig_print_node(Node *obj) {
   Iterator ki;
   Node *cobj;
+  List *keys = Keys(obj);
 
   print_indent(0);
-  Printf(stdout, "+++ %s - %p ----------------------------------------\n", nodeType(obj), obj);
-  ki = First(obj);
-  while (ki.key) {
-    String *k = ki.key;
-    if ((Cmp(k, "nodeType") == 0) || (Cmp(k, "firstChild") == 0) || (Cmp(k, "lastChild") == 0) ||
-	(Cmp(k, "parentNode") == 0) || (Cmp(k, "nextSibling") == 0) || (Cmp(k, "previousSibling") == 0) || (*(Char(k)) == '$')) {
+  if (debug_quiet)
+    Printf(stdout, "+++ %s ----------------------------------------\n", nodeType(obj));
+  else
+    Printf(stdout, "+++ %s - %p ----------------------------------------\n", nodeType(obj), obj);
+
+  SortList(keys, 0);
+  ki = First(keys);
+  while (ki.item) {
+    String *k = ki.item;
+    DOH *value = Getattr(obj, k);
+    if (Equal(k, "nodeType") || (*(Char(k)) == '$')) {
       /* Do nothing */
-    } else if (Cmp(k, "kwargs") == 0 || Cmp(k, "parms") == 0 || Cmp(k, "wrap:parms") == 0 ||
-	       Cmp(k, "pattern") == 0 || Cmp(k, "templateparms") == 0 || Cmp(k, "throws") == 0) {
+    } else if (debug_quiet && (Equal(k, "firstChild") || Equal(k, "lastChild") || Equal(k, "parentNode") || Equal(k, "nextSibling") ||
+	Equal(k, "previousSibling") || Equal(k, "symtab") || Equal(k, "csymtab") || Equal(k, "sym:symtab") || Equal(k, "sym:nextSibling") ||
+	Equal(k, "sym:previousSibling") || Equal(k, "csym:nextSibling") || Equal(k, "csym:previousSibling"))) {
+      /* Do nothing */
+    } else if (Equal(k, "kwargs") || Equal(k, "parms") || Equal(k, "wrap:parms") || Equal(k, "pattern") || Equal(k, "templateparms") || Equal(k, "throws")) {
       print_indent(2);
       /* Differentiate parameter lists by displaying within single quotes */
-      Printf(stdout, "%-12s - \'%s\'\n", k, ParmList_str_defaultargs(Getattr(obj, k)));
+      Printf(stdout, "%-12s - \'%s\'\n", k, ParmList_str_defaultargs(value));
     } else {
       DOH *o;
       const char *trunc = "";
       print_indent(2);
-      if (DohIsString(Getattr(obj, k))) {
-	o = Str(Getattr(obj, k));
+      if (DohIsString(value)) {
+	o = Str(value);
 	if (Len(o) > 80) {
 	  trunc = "...";
 	}
 	Printf(stdout, "%-12s - \"%(escape)-0.80s%s\"\n", k, o, trunc);
 	Delete(o);
+/*
+      } else if (DohIsSequence(value)) {
+	Printf(stdout, "%-12s - %s\n", k, value);
+*/
       } else {
-	Printf(stdout, "%-12s - %p\n", k, Getattr(obj, k));
+	Printf(stdout, "%-12s - %p\n", k, value);
       }
     }
     ki = Next(ki);
@@ -107,6 +134,7 @@
     print_indent(1);
     Printf(stdout, "\n");
   }
+  Delete(keys);
 }
 
 /* -----------------------------------------------------------------------------
@@ -225,7 +253,7 @@
   /* Delete attributes */
   Delattr(n,"parentNode");
   Delattr(n,"nextSibling");
-  Delattr(n,"prevSibling");
+  Delattr(n,"previousSibling");
 }
 
 /* -----------------------------------------------------------------------------
@@ -261,12 +289,16 @@
  * ns   - namespace for the view name for saving any attributes under
  * n    - node
  * ...  - list of attribute names of type char*
- * This method checks that the attribute names exist in the node n and asserts if
- * not. Assert will only occur unless the attribute is optional. An attribute is
- * optional if it is prefixed by ?, eg "?value". If the attribute name is prefixed
- * by * or ?, eg "*value" then a copy of the attribute is saved. The saved
- * attributes will be restored on a subsequent call to Swig_restore(). All the
- * saved attributes are saved in the view namespace (prefixed by ns).
+ *
+ * An attribute is optional if it is prefixed by ?, eg "?value".  All
+ * non-optional attributes are checked for on node n and if any do not exist
+ * SWIG exits with a fatal error.
+ *
+ * If the attribute name is prefixed by * or ?, eg "*value" then a copy of the
+ * attribute is saved. The saved attributes will be restored on a subsequent
+ * call to Swig_restore(). All the saved attributes are saved in the view
+ * namespace (prefixed by ns).
+ *
  * This function can be called more than once with different namespaces.
  * ----------------------------------------------------------------------------- */
 
@@ -291,10 +323,10 @@
     obj = Getattr(n, name);
     if (!opt && !obj) {
       Swig_error(Getfile(n), Getline(n), "Fatal error (Swig_require).  Missing attribute '%s' in node '%s'.\n", name, nodeType(n));
-      assert(obj);
+      Exit(EXIT_FAILURE);
     }
     if (!obj)
-      obj = DohNone;
+      obj = None;
     if (newref) {
       /* Save a copy of the attribute */
       Setattr(n, NewStringf("%s:%s", ns, name), obj);
@@ -339,7 +371,7 @@
     }
     obj = Getattr(n, name);
     if (!obj)
-      obj = DohNone;
+      obj = None;
 
     /* Save a copy of the attribute */
     if (Setattr(n, NewStringf("%s:%s", ns, name), obj)) {
diff --git a/Source/Swig/typemap.c b/Source/Swig/typemap.c
index c0f5397..3294bdf 100644
--- a/Source/Swig/typemap.c
+++ b/Source/Swig/typemap.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * typemap.c
  *
@@ -102,6 +102,7 @@
     dtype = Swig_symbol_type_qualify(ty, 0);
     type = dtype;
     Delete(ty);
+    Delete(rty);
   }
 
   /* remove unary scope operator (::) prefix indicating global scope for looking up in the hashmap */
@@ -151,7 +152,7 @@
  * Initialize the typemap system
  * ----------------------------------------------------------------------------- */
 
-void Swig_typemap_init() {
+void Swig_typemap_init(void) {
   typemaps = NewHash();
 }
 
@@ -511,7 +512,12 @@
   if (sm) {
     /* Got a typemap.  Need to only merge attributes for methods that match our signature */
     Iterator ki;
+    Hash *deferred_add;
     match = 1;
+
+    /* Since typemap_register can modify the `sm` hash, we *cannot* call typemap_register while iterating over sm. 
+     * Create a temporary hash of typemaps to add immediately after. */
+    deferred_add = NewHash();
     for (ki = First(sm); ki.key; ki = Next(ki)) {
       /* Check for a signature match with the source signature */
       if ((count_args(ki.key) == narg) && (Strstr(ki.key, ssig))) {
@@ -521,34 +527,36 @@
 	Replace(nkey, ssig, dsig, DOH_REPLACE_ANY);
 
 	/* Make sure the typemap doesn't already exist in the target map */
-
 	oldm = Getattr(tm, nkey);
 	if (!oldm || (!Getattr(tm, "code"))) {
 	  String *code;
-	  ParmList *locals;
-	  ParmList *kwargs;
 	  Hash *sm1 = ki.item;
 
 	  code = Getattr(sm1, "code");
-	  locals = Getattr(sm1, "locals");
-	  kwargs = Getattr(sm1, "kwargs");
 	  if (code) {
-	    String *src_str = ParmList_str_multibrackets(src);
-	    String *dest_str = ParmList_str_multibrackets(dest);
-	    String *source_directive = NewStringf("apply %s { %s }", src_str, dest_str);
-
 	    Replace(nkey, dsig, "", DOH_REPLACE_ANY);
 	    Replace(nkey, "tmap:", "", DOH_REPLACE_ANY);
-	    typemap_register(nkey, dest, code, locals, kwargs, source_directive);
-
-	    Delete(source_directive);
-	    Delete(dest_str);
-	    Delete(src_str);
+	    Setattr(deferred_add, nkey, sm1);
 	  }
 	}
 	Delete(nkey);
       }
     }
+
+    /* After assembling the key/item pairs, add the resulting typemaps */
+    for (ki = First(deferred_add); ki.key; ki = Next(ki)) {
+      Hash *sm1 = ki.item;
+      String *src_str = ParmList_str_multibrackets(src);
+      String *dest_str = ParmList_str_multibrackets(dest);
+      String *source_directive = NewStringf("apply %s { %s }", src_str, dest_str);
+
+      typemap_register(ki.key, dest, Getattr(sm1, "code"), Getattr(sm1, "locals"), Getattr(sm1, "kwargs"), source_directive);
+
+      Delete(source_directive);
+      Delete(dest_str);
+      Delete(src_str);
+    }
+    Delete(deferred_add);
   }
   Delete(ssig);
   Delete(dsig);
@@ -858,13 +866,6 @@
 }
 
 
-/* -----------------------------------------------------------------------------
- * typemap_replace_vars()
- *
- * Replaces typemap variables on a string.  index is the $n variable.
- * type and pname are the type and parameter name.
- * ----------------------------------------------------------------------------- */
-
 static void replace_local_types(ParmList *p, const String *name, const String *rep) {
   SwigType *t;
   while (p) {
@@ -884,7 +885,23 @@
   return 0;
 }
 
-static int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, SwigType *rtype, String *pname, String *lname, int index) {
+static int replace_with_override(String *src, const DOHString_or_char *token, const DOHString_or_char *rep, int flags, Hash *override_vars) {
+  String *override_replace = override_vars ? Getattr(override_vars, token) : NULL;
+  if (override_replace)
+    return Replace(src, token, override_replace, flags);
+  return Replace(src, token, rep, flags);
+}
+
+/* -----------------------------------------------------------------------------
+ * typemap_replace_vars()
+ *
+ * Replaces typemap variables in a string.  index is the $n variable.
+ * type and pname are the type and parameter name.
+ * override_vars are only used to replace variable names (NOT types), so is only
+ * used for $n, but not the various ways of representing types: $n_ltype, $n_type etc
+ * ----------------------------------------------------------------------------- */
+
+static int typemap_replace_vars(String *s, ParmList *locals, SwigType *type, SwigType *rtype, String *pname, String *lname, int index, Hash *override_vars) {
   char var[512];
   char *varname;
   SwigType *ftype;
@@ -1159,7 +1176,7 @@
     Delete(lex_type);
   }
 
-  /* Replace any $n. with (&n)-> */
+  /* Replace variable usage $n. with (&$n)-> */
   {
     char temp[64];
     sprintf(var, "$%d.", index);
@@ -1169,7 +1186,7 @@
 
   /* Replace the bare $n variable */
   sprintf(var, "$%d", index);
-  bare_substitution_count = Replace(s, var, lname, DOH_REPLACE_NUMBER_END);
+  bare_substitution_count = replace_with_override(s, var, lname, DOH_REPLACE_NUMBER_END, override_vars);
   Delete(ftype);
   return bare_substitution_count;
 }
@@ -1257,6 +1274,59 @@
 }
 
 /* -----------------------------------------------------------------------------
+ * typemap_merge_fragment_kwargs()
+ *
+ * If multiple 'fragment' attributes are provided to a typemap, combine them by
+ * concatenating with commas.
+ * ----------------------------------------------------------------------------- */
+
+static void typemap_merge_fragment_kwargs(Parm *kw) {
+  Parm *reattach_kw = NULL;
+  Parm *prev_kw = NULL;
+  Parm *next_kw = NULL;
+  String *fragment = NULL;
+  while (kw) {
+    next_kw = nextSibling(kw);
+    if (Strcmp(Getattr(kw, "name"), "fragment") == 0) {
+      String *thisfragment = Getattr(kw, "value");
+      String *kwtype = Getattr(kw, "type");
+      if (!fragment) {
+	/* First fragment found; it should remain in the list */
+	fragment = thisfragment;
+	prev_kw = kw;
+      } else {
+	/* Concatenate to previously found fragment */
+	Printv(fragment, ",", thisfragment, NULL);
+	reattach_kw = prev_kw;
+      }
+      if (kwtype) {
+        String *mangle = Swig_name_mangle_type(kwtype);
+        Append(fragment, mangle);
+        Delete(mangle);
+        /* Remove 'type' from kwargs so it's not duplicated later */
+        Setattr(kw, "type", NULL);
+      }
+    } else {
+      /* Not a fragment */
+      if (reattach_kw) {
+	/* Update linked list to remove duplicate fragment */
+	DohIncref(kw);
+	set_nextSibling(reattach_kw, kw);
+	set_previousSibling(kw, reattach_kw);
+	Delete(reattach_kw);
+	reattach_kw = NULL;
+      }
+      prev_kw = kw;
+    }
+    kw = next_kw;
+  }
+  if (reattach_kw) {
+    /* Update linked list to remove duplicate fragment */
+    set_nextSibling(reattach_kw, kw);
+  }
+}
+
+/* -----------------------------------------------------------------------------
  * Swig_typemap_lookup()
  *
  * Attach one or more typemaps to a node and optionally generate the typemap contents
@@ -1390,7 +1460,6 @@
      * ie, not use the typemap code, otherwise both f and actioncode must be non null. */
     if (actioncode) {
       const String *result_equals = NewStringf("%s = ", Swig_cresult_name());
-      clname = Copy(actioncode);
       /* check that the code in the typemap can be used in this optimal way.
        * The code should be in the form "result = ...;\n". We need to extract
        * the "..." part. This may not be possible for various reasons, eg
@@ -1398,22 +1467,17 @@
        * hack and circumvents the normal requirement for a temporary variable 
        * to hold the result returned from a wrapped function call.
        */
-      if (Strncmp(clname, result_equals, 9) == 0) {
-        int numreplacements = Replace(clname, result_equals, "", DOH_REPLACE_ID_BEGIN);
-        if (numreplacements == 1) {
-          numreplacements = Replace(clname, ";\n", "", DOH_REPLACE_ID_END);
-          if (numreplacements == 1) {
-            if (Strchr(clname, ';') == 0) {
-              lname = clname;
-              actioncode = 0;
-              optimal_substitution = 1;
-            }
-          }
-        }
-      }
-      if (!optimal_substitution) {
+      if (Strncmp(actioncode, result_equals, Len(result_equals)) == 0 &&
+	  Strchr(actioncode, ';') == Char(actioncode) + Len(actioncode) - 2 &&
+	  Char(actioncode)[Len(actioncode) - 1] == '\n') {
+	clname = NewStringWithSize(Char(actioncode) + Len(result_equals),
+				   Len(actioncode) - Len(result_equals) - 2);
+	lname = clname;
+	actioncode = 0;
+	optimal_substitution = 1;
+      } else {
 	Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(node), Getline(node), "Method %s usage of the optimal attribute ignored\n", Swig_name_decl(node));
-	Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(s), Getline(s), "in the out typemap as the following cannot be used to generate optimal code: %s\n", clname);
+	Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_IGNORED, Getfile(s), Getline(s), "in the out typemap as the following cannot be used to generate optimal code: %s\n", actioncode);
 	delete_optimal_attribute = 1;
       }
     } else {
@@ -1444,7 +1508,7 @@
   }
 
   matchtype = mtype && SwigType_isarray(mtype) ? mtype : type;
-  num_substitutions = typemap_replace_vars(s, locals, matchtype, type, pname, (char *) lname, 1);
+  num_substitutions = typemap_replace_vars(s, locals, matchtype, type, pname, (char *) lname, 1, NULL);
   if (optimal_substitution && num_substitutions > 1) {
     Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE, Getfile(node), Getline(node), "Multiple calls to %s might be generated due to\n", Swig_name_decl(node));
     Swig_warning(WARN_TYPEMAP_OUT_OPTIMAL_MULTIPLE, Getfile(s), Getline(s), "optimal attribute usage in the out typemap.\n");
@@ -1463,6 +1527,7 @@
 
   /* Attach kwargs - ie the typemap attributes */
   kw = Getattr(tm, "kwargs");
+  typemap_merge_fragment_kwargs(kw);
   while (kw) {
     String *value = Copy(Getattr(kw, "value"));
     String *kwtype = Getattr(kw, "type");
@@ -1474,7 +1539,7 @@
       SwigType *mtype = Getattr(node, "tmap:match");
       SwigType *matchtype = mtype ? mtype : ptype;
       ParmList *parm_sublist;
-      typemap_replace_vars(value, NULL, matchtype, ptype, pname, (char *)lname, 1);
+      typemap_replace_vars(value, NULL, matchtype, ptype, pname, (char *)lname, 1, NULL);
 
       /* Expand special variable macros (embedded typemaps) in typemap attributes. */
       parm_sublist = NewParmWithoutFileLineInfo(ptype, pname);
@@ -1483,7 +1548,7 @@
       Delete(parm_sublist);
     }
     if (kwtype) {
-      String *mangle = Swig_string_mangle(kwtype);
+      String *mangle = Swig_name_mangle_type(kwtype);
       Append(value, mangle);
       Delete(mangle);
     }
@@ -1517,7 +1582,7 @@
   /* Print warnings, if any */
   warning = typemap_warn(cmethod, node);
   if (warning) {
-    typemap_replace_vars(warning, 0, matchtype, type, pname, (char *) lname, 1);
+    typemap_replace_vars(warning, 0, matchtype, type, pname, (char *) lname, 1, NULL);
     Replace(warning, "$name", pname, DOH_REPLACE_ANY);
     if (symname)
       Replace(warning, "$symname", symname, DOH_REPLACE_ANY);
@@ -1577,6 +1642,7 @@
 static void typemap_attach_kwargs(Hash *tm, const_String_or_char_ptr tmap_method, Parm *firstp, int nmatch) {
   String *temp = NewStringEmpty();
   Parm *kw = Getattr(tm, "kwargs");
+  typemap_merge_fragment_kwargs(kw);
   while (kw) {
     String *value = Copy(Getattr(kw, "value"));
     String *type = Getattr(kw, "type");
@@ -1589,7 +1655,7 @@
       String *lname = Getattr(p, "lname");
       SwigType *mtype = Getattr(p, "tmap:match");
       SwigType *matchtype = mtype ? mtype : type;
-      typemap_replace_vars(value, NULL, matchtype, type, pname, lname, i + 1);
+      typemap_replace_vars(value, NULL, matchtype, type, pname, lname, i + 1, NULL);
       p = nextSibling(p);
     }
 
@@ -1661,12 +1727,13 @@
  * code can be retrieved for the first parameter with a call to Getattr(parm, "tmap:in")
  * and the "numinputs" attribute can be retrieved with a call to Getattr(parm, "tmap:in:numinputs").
  *
- * tmap_method - typemap method, eg "in", "out", "newfree"
- * parms       - parameter list to attach each typemap and all typemap attributes
- * f           - wrapper code to generate into if non null
+ * tmap_method   - typemap method, eg "in", "out", "newfree"
+ * parms         - parameter list to attach each typemap and all typemap attributes
+ * f             - wrapper code to generate into if non null
+ * override_vars - Hash of variables from $typemap(...) that will override special variable replacements
  * ----------------------------------------------------------------------------- */
 
-void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *parms, Wrapper *f) {
+static void typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *parms, Wrapper *f, Hash *override_vars) {
   Parm *p, *firstp;
   Hash *tm;
   int nmatch = 0;
@@ -1782,7 +1849,7 @@
       SwigType *mtype = Getattr(p, "tmap:match");
       SwigType *matchtype = mtype ? mtype : type;
 
-      typemap_replace_vars(s, locals, matchtype, type, pname, lname, i + 1);
+      typemap_replace_vars(s, locals, matchtype, type, pname, lname, i + 1, override_vars);
       if (mtype)
 	Delattr(p, "tmap:match");
 
@@ -1830,7 +1897,7 @@
       String *lname = Getattr(firstp, "lname");
       SwigType *mtype = Getattr(firstp, "tmap:match");
       SwigType *matchtype = mtype ? mtype : type;
-      typemap_replace_vars(warning, 0, matchtype, type, pname, lname, 1);
+      typemap_replace_vars(warning, 0, matchtype, type, pname, lname, 1, override_vars);
       Replace(warning, "$argnum", temp, DOH_REPLACE_ANY);
       Swig_warning(0, Getfile(firstp), Getline(firstp), "%s\n", warning);
       Delete(warning);
@@ -1853,6 +1920,10 @@
 
 }
 
+void Swig_typemap_attach_parms(const_String_or_char_ptr tmap_method, ParmList *parms, Wrapper *f) {
+  typemap_attach_parms(tmap_method, parms, f, NULL);
+}
+
 /* Splits the arguments of an embedded typemap */
 static List *split_embedded_typemap(String *s) {
   List *args = 0;
@@ -1897,7 +1968,7 @@
       level--;
     if (*c == '<')
       angle_level++;
-    if (*c == '>')
+    if (*c == '>' && *(c - 1) != '-')
       angle_level--;
     if (isspace((int) *c) && leading)
       start++;
@@ -1931,7 +2002,9 @@
  *
  *   $typemap(method, typelist, var1=value, var2=value, ...)
  *
- * where varx parameters are optional and undocumented; they were used in an earlier version of $typemap.
+ * where varx parameters are optional and undocumented; they were initially an experiment in the first implementation of $typemap.
+ * They allow one to override known special variable replacements or even add in new special variables for replacement
+ * from the calling typemap to the called typemap.
  * A search is made using the typemap matching rules of form:
  *
  *   %typemap(method) typelist {...}
@@ -1976,7 +2049,7 @@
     if (!syntax_error) {
       List *l;
       String *tmap_method;
-      Hash *vars;
+      Hash *override_vars;
       syntax_error = 1;
 
       /* Split apart each parameter in $typemap(...) */
@@ -2005,8 +2078,8 @@
 	  Delete(empty_string);
 	}
 
-	/* process optional extra parameters - the variable replacements (undocumented) */
-	vars = NewHash();
+	/* process optional extra parameters - the override variable replacements (undocumented) */
+	override_vars = NewHash();
 	{
 	  int i, ilen;
 	  ilen = Len(l);
@@ -2018,7 +2091,7 @@
 	      String *name = NewStringWithSize(c, (int)(eq - c));
 	      String *value = NewString(eq + 1);
 	      Insert(name, 0, "$");
-	      Setattr(vars, name, value);
+	      Setattr(override_vars, name, value);
 	    } else {
 	      to_match_parms = 0; /* error - variable replacement parameters must be of form varname=value */
 	    }
@@ -2035,6 +2108,7 @@
 	  Printf(stdout, "Swig_typemap_attach_parms:  embedded\n");
 #endif
 	  if (already_substituting < 10) {
+	    char* found_colon;
 	    already_substituting++;
 	    if ((in_typemap_search_multi == 0) && typemap_search_debug) {
 	      String *dtypemap = NewString(dollar_typemap);
@@ -2042,7 +2116,15 @@
 	      Printf(stdout, "  Containing: %s\n", dtypemap);
 	      Delete(dtypemap);
 	    }
-	    Swig_typemap_attach_parms(tmap_method, to_match_parms, f);
+	    found_colon = Strchr(tmap_method, ':');
+	    if (found_colon) {
+	      /* Substitute from a keyword argument to a typemap. Avoid emitting local variables from the attached typemap by passing NULL for the file. */
+	      String *temp_tmap_method = NewStringWithSize(Char(tmap_method), (int)(found_colon - Char(tmap_method)));
+	      typemap_attach_parms(temp_tmap_method, to_match_parms, NULL, override_vars);
+	      Delete(temp_tmap_method);
+	    } else {
+	      typemap_attach_parms(tmap_method, to_match_parms, f, override_vars);
+	    }
 	    already_substituting--;
 
 	    /* Look for the typemap code */
@@ -2054,7 +2136,7 @@
 	      if (!Getattr(to_match_parms, attr)) {
 		/* Replace parameter variables */
 		Iterator ki;
-		for (ki = First(vars); ki.key; ki = Next(ki)) {
+		for (ki = First(override_vars); ki.key; ki = Next(ki)) {
 		  Replace(tm, ki.key, ki.item, DOH_REPLACE_ANY);
 		}
 		/* offer the target language module the chance to make special variable substitutions */
@@ -2083,7 +2165,7 @@
 	  }
 	  syntax_error = 0;
 	}
-	Delete(vars);
+	Delete(override_vars);
       }
       Delete(l);
     }
@@ -2105,7 +2187,7 @@
  * Display all typemaps
  * ----------------------------------------------------------------------------- */
 
-void Swig_typemap_debug() {
+void Swig_typemap_debug(void) {
   int nesting_level = 2;
   Printf(stdout, "---[ typemaps ]--------------------------------------------------------------\n");
   Swig_print(typemaps, nesting_level);
diff --git a/Source/Swig/typeobj.c b/Source/Swig/typeobj.c
index 69fb666..fc443d8 100644
--- a/Source/Swig/typeobj.c
+++ b/Source/Swig/typeobj.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * typeobj.c
  *
@@ -45,6 +45,7 @@
  *  'p.'                = Pointer (*)
  *  'r.'                = Reference or ref-qualifier (&)
  *  'z.'                = Rvalue reference or ref-qualifier (&&)
+ *  'v.'                = Variadic (...)
  *  'a(n).'             = Array of size n  [n]
  *  'f(..,..).'         = Function with arguments  (args)
  *  'q(str).'           = Qualifier, such as const or volatile (cv-qualifier)
@@ -79,6 +80,7 @@
  *       SwigType_add_pointer()
  *       SwigType_add_reference()
  *       SwigType_add_rvalue_reference()
+ *       SwigType_add_variadic()
  *       SwigType_add_array()
  *
  * These are used to build new types.  There are also functions to undo these
@@ -87,6 +89,7 @@
  *       SwigType_del_pointer()
  *       SwigType_del_reference()
  *       SwigType_del_rvalue_reference()
+ *       SwigType_del_variadic()
  *       SwigType_del_array()
  *
  * In addition, there are query functions
@@ -94,6 +97,7 @@
  *       SwigType_ispointer()
  *       SwigType_isreference()
  *       SwigType_isrvalue_reference()
+ *       SwigType_isvariadic()
  *       SwigType_isarray()
  *
  * Finally, there are some data extraction functions that can be used to
@@ -111,21 +115,6 @@
  * reliable manner.
  * ----------------------------------------------------------------------------- */
 
-
-/* -----------------------------------------------------------------------------
- * NewSwigType()
- *
- * Constructs a new type object.   Eventually, it would be nice for this function
- * to accept an initial value in the form a C/C++ abstract type (currently unimplemented).
- * ----------------------------------------------------------------------------- */
-
-#ifdef NEW
-SwigType *NewSwigType(const_String_or_char_ptr initial) {
-  return NewString(initial);
-}
-
-#endif
-
 /* The next few functions are utility functions used in the construction and 
    management of types */
 
@@ -209,6 +198,47 @@
 }
 
 /* -----------------------------------------------------------------------------
+ * SwigType_last()
+ * 
+ * Return the last element of the given (partial) type.
+ * For example:
+ *   t:      q(const).p.
+ *   result: p.
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_last(SwigType *t) {
+  SwigType *result;
+  char *c;
+  char *last;
+  int sz = 0;
+
+  if (!t)
+    return 0;
+
+  /* Find the last element */
+  c = Char(t);
+  last = 0;
+  while (*c) {
+    last = c;
+    sz = element_size(c);
+    c = c + sz;
+    if (*c == '.') {
+      c++;
+      sz++;
+    }
+  }
+
+  /* Extract the last element */
+  if (last) {
+    result = NewStringWithSize(last, sz);
+  } else {
+    result = 0;
+  }
+
+  return result;
+}
+
+/* -----------------------------------------------------------------------------
  * SwigType_parm()
  *
  * Returns the parameter of an operator as a string
@@ -242,6 +272,7 @@
  * SwigType_split()
  *
  * Splits a type into its component parts and returns a list of string.
+ * The component parts of SwigType are split by '.'.
  * ----------------------------------------------------------------------------- */
 
 List *SwigType_split(const SwigType *t) {
@@ -267,7 +298,7 @@
 /* -----------------------------------------------------------------------------
  * SwigType_parmlist()
  *
- * Splits a comma separated list of parameters into its component parts
+ * Splits a comma separated list of SwigType * parameters into its component parts
  * The input is expected to contain the parameter list within () brackets
  * Returns 0 if no argument list in the input, ie there are no round brackets ()
  * Returns an empty List if there are no parameters in the () brackets
@@ -275,12 +306,12 @@
  *
  *     Foo(std::string,p.f().Bar<(int,double)>)
  *
- * returns 2 elements in the list:
+ * returns 2 SwigType * elements in the list:
  *    std::string
  *    p.f().Bar<(int,double)>
  * ----------------------------------------------------------------------------- */
  
-List *SwigType_parmlist(const String *p) {
+List *SwigType_parmlist(const SwigType *p) {
   String *item = 0;
   List *list;
   char *c;
@@ -359,8 +390,8 @@
     c++;
   }
   if (strncmp(c, "p.", 2)) {
-    printf("Fatal error. SwigType_del_pointer applied to non-pointer.\n");
-    abort();
+    printf("Fatal error: SwigType_del_pointer applied to non-pointer.\n");
+    Exit(EXIT_FAILURE);
   }
   Delslice(t, 0, (int)((c - s) + 2));
   return t;
@@ -402,8 +433,10 @@
 
 SwigType *SwigType_del_reference(SwigType *t) {
   char *c = Char(t);
-  int check = strncmp(c, "r.", 2);
-  assert(check == 0);
+  if (strncmp(c, "r.", 2)) {
+    printf("Fatal error: SwigType_del_reference applied to non-reference.\n");
+    Exit(EXIT_FAILURE);
+  }
   Delslice(t, 0, 2);
   return t;
 }
@@ -437,8 +470,10 @@
 
 SwigType *SwigType_del_rvalue_reference(SwigType *t) {
   char *c = Char(t);
-  int check = strncmp(c, "z.", 2);
-  assert(check == 0);
+  if (strncmp(c, "z.", 2)) {
+    fprintf(stderr, "Fatal error: SwigType_del_rvalue_reference() applied to non-rvalue-reference.\n");
+    Exit(EXIT_FAILURE);
+  }
   Delslice(t, 0, 2);
   return t;
 }
@@ -455,6 +490,43 @@
 }
 
 /* -----------------------------------------------------------------------------
+ *                                 Variadic
+ *
+ * SwigType_add_variadic()
+ * SwigType_del_variadic()
+ * SwigType_isvariadic()
+ *
+ * Add, remove, and test if a type is a variadic.  The deletion and query
+ * functions take into account qualifiers (if any).
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_add_variadic(SwigType *t) {
+  Insert(t, 0, "v.");
+  return t;
+}
+
+SwigType *SwigType_del_variadic(SwigType *t) {
+  char *c = Char(t);
+  if (strncmp(c, "v.", 2)) {
+    printf("Fatal error: SwigType_del_variadic applied to non-variadic.\n");
+    Exit(EXIT_FAILURE);
+  }
+  Delslice(t, 0, 2);
+  return t;
+}
+
+int SwigType_isvariadic(const SwigType *t) {
+  char *c;
+  if (!t)
+    return 0;
+  c = Char(t);
+  if (strncmp(c, "v.", 2) == 0) {
+    return 1;
+  }
+  return 0;
+}
+
+/* -----------------------------------------------------------------------------
  *                                  Qualifiers
  *
  * SwigType_add_qualifier()
@@ -478,7 +550,7 @@
   const char *cqual = Char(qual);
 
   /* if 't' has no qualifiers and 'qual' is a single qualifier, simply add it */
-  if ((strncmp(c, "q(", 2) != 0) && (strstr(cqual, " ") == 0)) {
+  if ((strncmp(c, "q(", 2) != 0) && (strchr(cqual, ' ') == 0)) {
     String *temp = NewStringf("q(%s).", cqual);
     Insert(t, 0, temp);
     Delete(temp);
@@ -529,6 +601,7 @@
   char *c = Char(t);
   int check = strncmp(c, "q(", 2);
   assert(check == 0);
+  (void)check;
   Delslice(t, 0, element_size(c));
   return t;
 }
@@ -597,6 +670,7 @@
   char *c = Char(t);
   int check = strncmp(c, "m(", 2);
   assert(check == 0);
+  (void)check;
   Delslice(t, 0, element_size(c));
   return t;
 }
@@ -639,8 +713,10 @@
 
 SwigType *SwigType_del_array(SwigType *t) {
   char *c = Char(t);
-  int check = strncmp(c, "a(", 2);
-  assert(check == 0);
+  if (strncmp(c, "a(", 2)) {
+    fprintf(stderr, "Fatal error: SwigType_del_array() applied to non-array.\n");
+    Exit(EXIT_FAILURE);
+  }
   Delslice(t, 0, element_size(c));
   return t;
 }
@@ -733,8 +809,10 @@
   char *c = Char(t);
 
   start = c;
-  if (strncmp(c, "a(", 2))
-    abort();
+  if (strncmp(c, "a(", 2)) {
+    fprintf(stderr, "Fatal error: SwigType_array_type applied to non-array.\n");
+    Exit(EXIT_FAILURE);
+  }
 
   while (c && (strncmp(c, "a(", 2) == 0) && (n > 0)) {
     c = strchr(c, '.');
@@ -772,26 +850,42 @@
  *                                    Functions
  *
  * SwigType_add_function()
+ * SwigType_function_parms_only()
  * SwigType_isfunction()
  * SwigType_pop_function()
  *
  * Add, remove, and test for function types.
  * ----------------------------------------------------------------------------- */
 
-/* Returns the function type, t, constructed from the parameters, parms */
-SwigType *SwigType_add_function(SwigType *t, ParmList *parms) {
-  String *pstr;
-  Parm *p;
+/* -----------------------------------------------------------------------------
+ * SwigType_function_parms_only()
+ *
+ * Creates a comma separated list of SwigType strings from parms
+ * ----------------------------------------------------------------------------- */
 
-  Insert(t, 0, ").");
-  pstr = NewString("f(");
+SwigType *SwigType_function_parms_only(ParmList *parms) {
+  Parm *p;
+  SwigType *t = NewString("");
   for (p = parms; p; p = nextSibling(p)) {
     if (p != parms)
-      Putc(',', pstr);
-    Append(pstr, Getattr(p, "type"));
+      Putc(',', t);
+    Append(t, Getattr(p, "type"));
   }
-  Insert(t, 0, pstr);
-  Delete(pstr);
+  return t;
+}
+
+/* -----------------------------------------------------------------------------
+ * SwigType_add_function()
+ *
+ * Returns the function type, t, constructed from the parameters, parms
+ * ----------------------------------------------------------------------------- */
+
+SwigType *SwigType_add_function(SwigType *t, ParmList *parms) {
+  SwigType *fparms = SwigType_function_parms_only(parms);
+  Insert(fparms, 0, "f(");
+  Append(fparms, ").");
+  Insert(t, 0, fparms);
+  Delete(fparms);
   return t;
 }
 
@@ -826,8 +920,8 @@
     c = Char(t);
   }
   if (strncmp(c, "f(", 2)) {
-    printf("Fatal error. SwigType_pop_function applied to non-function.\n");
-    abort();
+    fprintf(stderr, "Fatal error. SwigType_pop_function applied to non-function.\n");
+    Exit(EXIT_FAILURE);
   }
   g = SwigType_pop(t);
   if (f)
@@ -992,16 +1086,17 @@
  * ----------------------------------------------------------------------------- */
 
 String *SwigType_templatesuffix(const SwigType *t) {
-  const char *c;
+  const char *c, *d;
   c = Char(t);
-  while (*c) {
+  d = c + strlen(c);
+  while (d > c) {
     if ((*c == '<') && (*(c + 1) == '(')) {
       int nest = 1;
       c++;
-      while (*c && nest) {
-	if (*c == '<')
+      while ((d > c) && nest) {
+	if (*c == '<' && *(c + 1) == '(')
 	  nest++;
-	if (*c == '>')
+	if (*c == '>' && *(c - 1) == ')')
 	  nest--;
 	c++;
       }
@@ -1069,18 +1164,19 @@
  * ----------------------------------------------------------------------------- */
 
 String *SwigType_templateargs(const SwigType *t) {
-  const char *c;
+  const char *c, *d;
   const char *start;
   c = Char(t);
-  while (*c) {
+  d = c + strlen(c);
+  while (d > c) {
     if ((*c == '<') && (*(c + 1) == '(')) {
       int nest = 1;
       start = c;
       c++;
-      while (*c && nest) {
-	if (*c == '<')
+      while ((d > c) && nest) {
+	if (*c == '<' && *(c + 1) == '(')
 	  nest++;
-	if (*c == '>')
+	if (*c == '>' && *(c - 1) == ')')
 	  nest--;
 	c++;
       }
@@ -1128,20 +1224,9 @@
       c++;
       continue;
     }
-    if (*c == '<') {
-      /* Skip over template---it's part of the base name */
-      int ntemp = 1;
-      c++;
-      while ((*c) && (ntemp > 0)) {
-	if (*c == '>')
-	  ntemp--;
-	else if (*c == '<')
-	  ntemp++;
-	c++;
-      }
-      if (ntemp)
-	break;
-      continue;
+    if (*c == '<' && *(c + 1) == '(') {
+      /* start of template parameters --- the remainder is part of the base */
+      break;
     }
     if (*c == '(') {
       /* Skip over params */
@@ -1183,17 +1268,20 @@
 
   while (d > c) {
     d--;
-    if (*d == '>') {
+    if (*d == '>' && (d > c) && *(d - 1) == ')') {
+      /* skip over template parameters */
       int nest = 1;
       d--;
+      d--;
       while ((d > c) && (nest)) {
-	if (*d == '>')
+	if (*d == '>' && *(d - 1) == ')')
 	  nest++;
-	if (*d == '<')
+	if (*d == '<' && *(d + 1) == '(')
 	  nest--;
 	d--;
       }
     }
+
     if (*d == ')') {
       /* Skip over params */
       int nparen = 1;
@@ -1208,10 +1296,10 @@
     }
 
     if (*d == '.') {
-      char t = *(d + 1);
+      char x = *(d + 1);
       *(d + 1) = 0;
       r = NewString(c);
-      *(d + 1) = t;
+      *(d + 1) = x;
       return r;
     }
   }
diff --git a/Source/Swig/typesys.c b/Source/Swig/typesys.c
index 7564db1..dacc125 100644
--- a/Source/Swig/typesys.c
+++ b/Source/Swig/typesys.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * typesys.c
  *
@@ -180,7 +180,7 @@
 }
 
 
-static void flush_cache() {
+static void flush_cache(void) {
   typedef_resolve_cache = 0;
   typedef_all_cache = 0;
   typedef_qualified_cache = 0;
@@ -188,7 +188,7 @@
 
 /* Initialize the scoping system */
 
-void SwigType_typesystem_init() {
+void SwigType_typesystem_init(void) {
   if (global_scope)
     Delete(global_scope);
   if (scopes)
@@ -407,7 +407,7 @@
  * table for the scope that was popped off.
  * ----------------------------------------------------------------------------- */
 
-Typetab *SwigType_pop_scope() {
+Typetab *SwigType_pop_scope(void) {
   Typetab *t, *old = current_scope;
   t = Getattr(current_scope, "parent");
   if (!t)
@@ -1148,6 +1148,7 @@
 	Append(qprefix, "<(");
 	pi = First(parms);
 	while ((p = pi.item)) {
+	  /* TODO: the logic here should be synchronised with that in symbol_template_qualify() in symbol.c */
 	  String *qt = SwigType_typedef_qualified(p);
 	  if (Equal(qt, p)) {	/*  && (!Swig_scopename_check(qt))) */
 	    /* No change in value.  It is entirely possible that the parameter is an integer value.
@@ -1419,7 +1420,8 @@
       c++;
     if (*c)
       return SwigType_type(c + 1);
-    return T_ERROR;
+    Printf(stderr, "*** Internal error: Invalid type string '%s'\n", t);
+    Exit(EXIT_FAILURE);
   }
   if (strncmp(c, "f(", 2) == 0)
     return T_FUNCTION;
@@ -1453,11 +1455,11 @@
     return T_DOUBLE;
   if (strcmp(c, "long double") == 0)
     return T_LONGDOUBLE;
-  if (!cparse_cplusplus && (strcmp(c, "float complex") == 0))
+  if (!cparse_cplusplus && (strcmp(c, "float _Complex") == 0))
     return T_FLTCPLX;
-  if (!cparse_cplusplus && (strcmp(c, "double complex") == 0))
+  if (!cparse_cplusplus && (strcmp(c, "double _Complex") == 0))
     return T_DBLCPLX;
-  if (!cparse_cplusplus && (strcmp(c, "complex") == 0))
+  if (!cparse_cplusplus && (strcmp(c, "_Complex") == 0))
     return T_COMPLEX;
   if (strcmp(c, "void") == 0)
     return T_VOID;
@@ -1491,11 +1493,11 @@
  * Returns the alternative value type needed in C++ for class value
  * types. When swig is not sure about using a plain $ltype value,
  * since the class doesn't have a default constructor, or it can't be
- * assigned, you will get back 'SwigValueWrapper<type >'.
+ * assigned, you will get back 'SwigValueWrapper<(type)>'.
  *
  * This is the default behavior unless:
  *
- *  1.- swig detects a default_constructor and 'setallocate:default_constructor'
+ *  1.- swig detects a default_constructor and 'allocate:default_constructor'
  *      attribute.
  *
  *  2.- swig doesn't mark 'type' as non-assignable.
@@ -1564,11 +1566,7 @@
   }
 
   if (use_wrapper) {
-    /* Need a space before the type in case it starts "::" (since the <:
-     * token is a digraph for [ in C++.  Also need a space after the
-     * type in case it ends with ">" since then we form the token ">>".
-     */
-    w = NewStringf("SwigValueWrapper< %s >", td);
+    w = NewStringf("SwigValueWrapper<(%s)>", td);
   }
   Delete(td);
   return w;
@@ -1700,14 +1698,6 @@
   /*Printf(stdout,"t = '%s'\n", t);
      Printf(stdout,"fr= '%s'\n\n", fr); */
 
-  if (t) {
-    char *ct = Char(t);
-    if (strchr(ct, '<') && !(strstr(ct, "<("))) {
-      Printf(stdout, "Bad template type passed to SwigType_remember: %s\n", t);
-      assert(0);
-    }
-  }
-
   h = Getattr(r_mangled, mt);
   if (!h) {
     h = NewHash();
@@ -1974,6 +1964,7 @@
   Hash *sub;
   Hash *rh;
   List *rlist;
+  List *r_resolved_sorted_keys;
   Iterator rk, bk, ck;
 
   if (!conversions)
@@ -1981,10 +1972,12 @@
   if (!subclass)
     subclass = NewHash();
 
-  rk = First(r_resolved);
-  while (rk.key) {
+  r_resolved_sorted_keys = SortedKeys(r_resolved, Strcmp);
+  rk = First(r_resolved_sorted_keys);
+  while (rk.item) {
+    List *sub_sorted_keys;
     /* rkey is a fully qualified type.  We strip all of the type constructors off of it just to get the base */
-    base = SwigType_base(rk.key);
+    base = SwigType_base(rk.item);
     /* Check to see whether the base is recorded in the subclass table */
     sub = Getattr(subclass, base);
     Delete(base);
@@ -1995,28 +1988,29 @@
 
     /* This type has subclasses.  We now need to walk through these subtypes and generate pointer conversion functions */
 
-    rh = Getattr(r_resolved, rk.key);
+    rh = Getattr(r_resolved, rk.item);
     rlist = NewList();
     for (ck = First(rh); ck.key; ck = Next(ck)) {
       Append(rlist, ck.key);
     }
-    /*    Printf(stdout,"rk.key = '%s'\n", rk.key);
+    /*    Printf(stdout,"rk.item = '%s'\n", rk.item);
        Printf(stdout,"rh = %p '%s'\n", rh,rh); */
 
-    bk = First(sub);
-    while (bk.key) {
-      prefix = SwigType_prefix(rk.key);
-      Append(prefix, bk.key);
+    sub_sorted_keys = SortedKeys(sub, Strcmp);
+    bk = First(sub_sorted_keys);
+    while (bk.item) {
+      prefix = SwigType_prefix(rk.item);
+      Append(prefix, bk.item);
       /*      Printf(stdout,"set %p = '%s' : '%s'\n", rh, SwigType_manglestr(prefix),prefix); */
       mprefix = SwigType_manglestr(prefix);
       Setattr(rh, mprefix, prefix);
-      mkey = SwigType_manglestr(rk.key);
+      mkey = SwigType_manglestr(rk.item);
       ckey = NewStringf("%s+%s", mprefix, mkey);
       if (!Getattr(conversions, ckey)) {
 	String *convname = NewStringf("%sTo%s", mprefix, mkey);
-	String *lkey = SwigType_lstr(rk.key, 0);
+	String *lkey = SwigType_lstr(rk.item, 0);
 	String *lprefix = SwigType_lstr(prefix, 0);
-        Hash *subhash = Getattr(sub, bk.key);
+        Hash *subhash = Getattr(sub, bk.item);
         String *convcode = Getattr(subhash, "convcode");
         if (convcode) {
           char *newmemoryused = Strstr(convcode, "newmemory"); /* see if newmemory parameter is used in order to avoid unused parameter warnings */
@@ -2077,29 +2071,13 @@
       Delete(mkey);
       bk = Next(bk);
     }
+    Delete(sub_sorted_keys);
     rk = Next(rk);
     Delete(rlist);
   }
+  Delete(r_resolved_sorted_keys);
 }
 
-/* Helper function to sort the mangled list */
-static int SwigType_compare_mangled(const DOH *a, const DOH *b) {
-  return strcmp((char *) Data(a), (char *) Data(b));
-}
-
-/* -----------------------------------------------------------------------------
- * SwigType_get_sorted_mangled_list()
- *
- * Returns the sorted list of mangled type names that should be exported into the
- * wrapper file.
- * ----------------------------------------------------------------------------- */
-List *SwigType_get_sorted_mangled_list() {
-  List *l = Keys(r_mangled);
-  SortList(l, SwigType_compare_mangled);
-  return l;
-}
-
-
 /* -----------------------------------------------------------------------------
  * SwigType_type_table()
  *
@@ -2126,22 +2104,22 @@
    /*#define DEBUG 1*/
 #ifdef DEBUG
   Printf(stdout, "---r_mangled---\n");
-  Printf(stdout, "%s\n", r_mangled);
+  Swig_print(r_mangled, 2);
 
   Printf(stdout, "---r_resolved---\n");
-  Printf(stdout, "%s\n", r_resolved);
+  Swig_print(r_resolved, 2);
 
   Printf(stdout, "---r_ltype---\n");
-  Printf(stdout, "%s\n", r_ltype);
+  Swig_print(r_ltype, 2);
 
   Printf(stdout, "---subclass---\n");
-  Printf(stdout, "%s\n", subclass);
+  Swig_print(subclass, 2);
 
   Printf(stdout, "---conversions---\n");
-  Printf(stdout, "%s\n", conversions);
+  Swig_print(conversions, 2);
 
   Printf(stdout, "---r_clientdata---\n");
-  Printf(stdout, "%s\n", r_clientdata);
+  Swig_print(r_clientdata, 2);
 
 #endif
   table = NewStringEmpty();
@@ -2155,12 +2133,10 @@
 
   Printf(f_forward, "\n/* -------- TYPES TABLE (BEGIN) -------- */\n\n");
 
-  mangled_list = SwigType_get_sorted_mangled_list();
+  mangled_list = SortedKeys(r_mangled, Strcmp);
   for (ki = First(mangled_list); ki.item; ki = Next(ki)) {
     List *el;
     Iterator ei;
-    SwigType *lt;
-    SwigType *rt = 0;
     String *nt;
     String *ln;
     String *rn;
@@ -2168,8 +2144,12 @@
     Hash *lthash;
     Iterator ltiter;
     Hash *nthash;
+    String *cast_temp_conv;
+    String *resolved_lstr = 0;
+    List *ntlist;
 
     cast_temp = NewStringEmpty();
+    cast_temp_conv = NewStringEmpty();
 
     Printv(types, "static swig_type_info _swigt_", ki.item, " = {", NIL);
     Append(table_list, ki.item);
@@ -2185,8 +2165,8 @@
     nthash = NewHash();
     ltiter = First(lthash);
     while (ltiter.key) {
-      lt = ltiter.key;
-      rt = SwigType_typedef_resolve_all(lt);
+      SwigType *lt = ltiter.key;
+      SwigType *rt = SwigType_typedef_resolve_all(lt);
       /* we save the original type and the fully resolved version */
       ln = SwigType_lstr(lt, 0);
       rn = SwigType_lstr(rt, 0);
@@ -2196,6 +2176,12 @@
 	Setattr(nthash, rn, "1");
 	Setattr(nthash, ln, "1");
       }
+      if (!resolved_lstr) {
+	resolved_lstr = Copy(rn);
+      } else if (Len(rn) < Len(resolved_lstr)) {
+	Delete(resolved_lstr);
+	resolved_lstr = Copy(rn);
+      }
       if (SwigType_istemplate(rt)) {
         String *dt = Swig_symbol_template_deftype(rt, 0);
         String *dn = SwigType_lstr(dt, 0);
@@ -2205,33 +2191,50 @@
         Delete(dt);
         Delete(dn);
       }
+      Delete(rt);
+      Delete(rn);
+      Delete(ln);
 
       ltiter = Next(ltiter);
     }
 
     /* now build nt */
-    ltiter = First(nthash);
+    ntlist = SortedKeys(nthash, Strcmp);
+    ltiter = First(ntlist);
     nt = 0;
-    while (ltiter.key) {
-      if (nt) {
-	 Printf(nt, "|%s", ltiter.key);
-      } else {
-	 nt = NewString(ltiter.key);
+    while (ltiter.item) {
+      if (!Equal(resolved_lstr, ltiter.item)) {
+	if (nt) {
+	   Printf(nt, "|%s", ltiter.item);
+	} else {
+	   nt = NewString(ltiter.item);
+	}
       }
       ltiter = Next(ltiter);
     }
+    /* Last in list is a resolved type used by SWIG_TypePrettyName.
+     * There can be more than one resolved type and the chosen one is simply the
+     * shortest in length, arguably the most user friendly/readable. */
+    if (nt) {
+       Printf(nt, "|%s", resolved_lstr);
+    } else {
+       nt = NewString(resolved_lstr);
+    }
+    Delete(ntlist);
     Delete(nthash);
+    Delete(resolved_lstr);
 
     Printf(types, "\"%s\", \"%s\", 0, 0, (void*)%s, 0};\n", ki.item, nt, cd);
 
     el = SwigType_equivalent_mangle(ki.item, 0, 0);
+    SortList(el, Strcmp);
     for (ei = First(el); ei.item; ei = Next(ei)) {
       String *ckey;
       String *conv;
       ckey = NewStringf("%s+%s", ei.item, ki.item);
       conv = Getattr(conversions, ckey);
       if (conv) {
-	Printf(cast_temp, "  {&_swigt_%s, %s, 0, 0},", ei.item, conv);
+	Printf(cast_temp_conv, "  {&_swigt_%s, %s, 0, 0},", ei.item, conv);
       } else {
 	Printf(cast_temp, "  {&_swigt_%s, 0, 0, 0},", ei.item);
       }
@@ -2248,13 +2251,13 @@
       }
     }
     Delete(el);
-    Printf(cast, "%s{0, 0, 0, 0}};\n", cast_temp);
+    Printf(cast, "%s%s{0, 0, 0, 0}};\n", cast_temp, cast_temp_conv);
+    Delete(cast_temp_conv);
     Delete(cast_temp);
     Delete(nt);
-    Delete(rt);
   }
   /* print the tables in the proper order */
-  SortList(table_list, SwigType_compare_mangled);
+  SortList(table_list, Strcmp);
   i = 0;
   for (ki = First(table_list); ki.item; ki = Next(ki)) {
     Printf(f_forward, "#define SWIGTYPE%s swig_types[%d]\n", ki.item, i++);
diff --git a/Source/Swig/wrapfunc.c b/Source/Swig/wrapfunc.c
index 29a59cc..6d82372 100644
--- a/Source/Swig/wrapfunc.c
+++ b/Source/Swig/wrapfunc.c
@@ -4,7 +4,7 @@
  * terms also apply to certain portions of SWIG. The full details of the SWIG
  * license and copyrights can be found in the LICENSE and COPYRIGHT files
  * included with the SWIG source code as distributed by the SWIG developers
- * and at http://www.swig.org/legal.html.
+ * and at https://www.swig.org/legal.html.
  *
  * wrapfunc.c
  *
@@ -27,7 +27,7 @@
 
 Wrapper *NewWrapper(void) {
   Wrapper *w;
-  w = (Wrapper *) malloc(sizeof(Wrapper));
+  w = (Wrapper *) Malloc(sizeof(Wrapper));
   w->localh = NewHash();
   w->locals = NewStringEmpty();
   w->code = NewStringEmpty();
@@ -46,7 +46,7 @@
   Delete(w->locals);
   Delete(w->code);
   Delete(w->def);
-  free(w);
+  Free(w);
 }
 
 /* -----------------------------------------------------------------------------
diff --git a/TODO b/TODO
index 38ab460..2182ef8 100644
--- a/TODO
+++ b/TODO
@@ -26,80 +26,6 @@
        This is one of the last remaining "hard" problems in the SWIG
        core, but it is important that we solve it.
 
-***    "Nested" typemaps. The basic idea is similar to allowing one to 
-       use $descriptor(T) for any T, rather than just $descriptor
-       for the type currently being typemapped.
-
-       In short (ha!), given a previously defined typemap:
-
-       %typemap(in) Foo {
-           // whatever it takes to initialize $1 from $input
-       }
-
-       it would be possible to inline its code inside another typemap. 
-       While the syntax is still to be defined, the use would be
-       along the lines of:
-
-       template <class T> class vector {
-           %typemap(in) vector<T> {
-               ...
-               for (int i=0; i<N; i++) {
-                   PyObject* x = ... // i-th element
-                   $typemap(in, T, x, $1[i]);
-               }
-               ...
-           }
-           ...
-       }
-
-       i.e., when $typemap(in,Foo,x,y) is encountered, it will
-       be replaced by the code for %typemap(in) Foo; in the latter,
-       x will be replaced for $input and y will be replaced for $1. 
-       As in the case above, x and y themselves might need to be 
-       expanded before or after being substituted in the typemap code.
-       Also, $typemap(what,Foo,x,y,z,...) will be used in case of 
-       multi-arguments typemaps. The same will hold for "out" typemaps
-       and all the others.
-
-       Comment by mkoeppe:  
-
-	  I think we need to be careful to keep the syntax readable.
-	  I would like to get a syntax that is close to that of
-	  typemap definitions.  So consider this typemap:
-
-		 %typemap(in) int { ... }
-
-	  I would like to refer to this typemap like this:
-
-		 $typemap(in, input=x) int = foo;
-
-	  Here $input would be replaced by the given keyword argument
-	  x, and $1 would be replaced by foo.
-
-	  This syntax would extend easily to multi-typemaps:
-
-		 %typemap(in) ( int FIRST, double SECOND ) { ... }
-
-	      -> $typemap(in, input=x) 
-	      	    ( int FIRST = foo, double SECOND = bar );
-
-	  The advantage of this syntax would be that the formal
-	  arguments (int FIRST, double SECOND) are close to the
-	  actual arguments (foo, bar).
-
-	Comment by beazley
-
-               $typemap(in, input=x) int = foo;
-
-        is a little bit hard to parse in terms of variable substitution.
-        I'm considering something like this:
-
-               $typemap(in,1=int foo, input=x)
-
-       Note: This is partially implemented in the new Unified Typemap
-       Library(python,tcl,ruby and perl) via %fragments and the
-       SWIG_From/SWIG_AsVal methdos.
-
 ***    Implement $fail special variable substitution in wrappers. Used
        to properly transfer control out of a wrapper function while
        reclaiming resources.
@@ -201,12 +127,7 @@
 **     When returning wrapped objects via alternate constructors if that
        pointer value already exists "out there" as a resource we should
        use the same resource, we can't have multiple ref-counted resources
-       mapping to the same object in case it gets twice destroyed.  And check
-       if ref count destroying is even working, see smart_pointer_rename
-
-*      Work out how classes without even inherited constructors should
-       interact with the php "new <class>" notation.
-       See: abstract_inherit_wrap.cpptest
+       mapping to the same object in case it gets twice destroyed.
 
 **     Look at pass by point and passby ref,
        Make sometype** to be auto allocated
diff --git a/Tools/CI-linux-environment.sh b/Tools/CI-linux-environment.sh
new file mode 100644
index 0000000..1b68635
--- /dev/null
+++ b/Tools/CI-linux-environment.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+# Expected to be called from elsewhere with same variables set as CI-linux-install.sh
+# e.g. RETRY=travis-retry SWIGLANG=python
+# Sets up environment for using various target languages
+# For Github Actions where the environment is not preserved between steps
+set -e # exit on failure (same as -o errexit)
+
+case "$SWIGLANG" in
+	"go")
+		if [[ "$VER" ]]; then
+		  eval "$($HOME/bin/gimme ${VER}.x)"
+		  $HOME/bin/gimme --list
+		fi
+		;;
+	"javascript")
+		case "$ENGINE" in
+			"node"|"napi")
+				export NVM_DIR="$HOME/.nvm"
+				[ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh"
+				nvm use ${VER}
+				;;
+			*)      ;;
+		esac
+		;;
+	"ruby")
+		if ! command -v rvm; then
+			set +x
+			if [ -f /etc/profile.d/rvm.sh ] ; then
+				source /etc/profile.d/rvm.sh
+			elif [ -f $HOME/.rvm/scripts/rvm ] ; then
+				source $HOME/.rvm/scripts/rvm
+			fi
+			set -x
+		fi
+		;;
+	*)	;;
+esac
diff --git a/Tools/CI-linux-install.sh b/Tools/CI-linux-install.sh
new file mode 100644
index 0000000..c16eb95
--- /dev/null
+++ b/Tools/CI-linux-install.sh
@@ -0,0 +1,176 @@
+#!/bin/bash
+# Expected to be called from elsewhere with certain variables set
+# e.g. RETRY=travis-retry SWIGLANG=python GCC=7
+set -e # exit on failure (same as -o errexit)
+
+if [[ -n "$GCC" ]]; then
+	$RETRY sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
+	$RETRY sudo apt-get -qq update
+	$RETRY sudo apt-get install -qq g++-$GCC
+else
+	$RETRY sudo apt-get -qq update
+fi
+
+$RETRY sudo apt-get -qq install libboost-dev libpcre3-dev
+# Note: testflags.py needs python, but python is pre-installed
+
+WITHLANG=$SWIGLANG
+
+case "$SWIGLANG" in
+	"")     ;;
+	"csharp")
+		$RETRY sudo apt-get -qq install mono-devel
+		;;
+	"d")
+		if [[ $VER =~ ^2\. ]]; then
+			$RETRY wget http://downloads.dlang.org/releases/2.x/${VER}/dmd_${VER}-0_amd64.deb
+			$RETRY sudo dpkg -i dmd_${VER}-0_amd64.deb
+		else
+			$RETRY sudo apt-get -qq install "$VER"
+		fi
+		;;
+	"go")
+		if [[ "$VER" ]]; then
+		  mkdir -p $HOME/bin
+		  curl -sL -o $HOME/bin/gimme https://raw.githubusercontent.com/travis-ci/gimme/master/gimme
+		  chmod +x $HOME/bin/gimme
+		  eval "$($HOME/bin/gimme ${VER}.x)"
+		  $HOME/bin/gimme --list
+		fi
+		;;
+	"javascript")
+		case "$ENGINE" in
+			"node"|"napi")
+				$RETRY wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.10/install.sh | bash
+				export NVM_DIR="$HOME/.nvm"
+				[ -s "$NVM_DIR/nvm.sh" ] && source "$NVM_DIR/nvm.sh"
+				$RETRY nvm install ${VER}
+				nvm use ${VER}
+				if [ "$VER" == "0.10" ] || [ "$VER" == "0.12" ] || [ "$VER" == "4" ] || [ "$VER" == "6" ] ; then
+#					$RETRY sudo apt-get install -qq nodejs node-gyp
+					$RETRY npm install -g node-gyp@$VER
+				elif [ "$VER" == "8" ] ; then
+					$RETRY npm install -g node-gyp@6
+				elif [ "$VER" == "10" ] || [ "$VER" == "12" ] || [ "$VER" == "14" ]  || [ "$VER" == "16" ]; then
+					$RETRY npm install -g node-gyp@7
+				else
+					$RETRY npm install -g node-gyp
+				fi
+				$RETRY npm install -g node-addon-api
+				;;
+			"jsc")
+				$RETRY sudo apt-get install -qq libjavascriptcoregtk-${VER}-dev
+				;;
+			"v8")
+				$RETRY sudo apt-get install -qq libnode-dev
+				;;
+		esac
+		;;
+	"guile")
+		$RETRY sudo apt-get -qq install guile-${VER:-2.0}-dev
+		;;
+	"lua")
+		if [[ -z "$VER" ]]; then
+			$RETRY sudo apt-get -qq install lua5.2 liblua5.2-dev
+		else
+			$RETRY sudo apt-get -qq install lua${VER} liblua${VER}-dev
+		fi
+		;;
+	"mzscheme")
+		$RETRY sudo apt-get -qq install racket
+		;;
+	"ocaml")
+		$RETRY sudo apt-get -qq install ocaml camlp4
+		;;
+	"octave")
+		if [[ "$VER" ]]; then
+			$RETRY sudo add-apt-repository -y ppa:devacom/science
+			$RETRY sudo apt-get -qq update
+			$RETRY sudo apt-get -qq install "liboctave-dev=$VER.*"
+		else
+			$RETRY sudo apt-get -qq update
+			$RETRY sudo apt-get -qq install liboctave-dev
+		fi
+		;;
+	"php")
+		if [[ "$VER" ]]; then
+			$RETRY sudo apt-get -qq remove "php*-cli" "php*-dev" # Multiple versions are pre-installed
+			$RETRY sudo add-apt-repository -y ppa:ondrej/php
+			$RETRY sudo apt-get -qq update
+			$RETRY sudo apt-get -qq install php$VER-cli php$VER-dev
+		fi
+		;;
+	"python")
+		pip install --user pycodestyle
+		if [[ "$PY2" ]]; then
+			WITHLANG=$SWIGLANG
+		else
+			WITHLANG=${SWIGLANG}3
+		fi
+		if [[ "$VER" ]]; then
+			$RETRY sudo add-apt-repository -y ppa:deadsnakes/ppa
+			$RETRY sudo apt-get -qq update
+			$RETRY sudo apt-get -qq install python${VER}-dev
+			WITHLANG=$WITHLANG=$SWIGLANG$VER
+		elif [[ "$PY2" ]]; then
+			$RETRY sudo apt-get install -qq python-dev
+		else
+			$RETRY sudo apt-get install -qq python3-dev
+		fi
+		;;
+	"r")
+		$RETRY sudo apt-get -qq install r-base
+		;;
+	"ruby")
+		if [[ "$VER" ]]; then
+			case "$VER" in
+				3.1 | 3.2 | 3.2.2 | 3.3 )
+					# Ruby 3.1+ support is currently only rvm master (2023-04-19)
+					# YOLO
+					curl -sSL https://rvm.io/mpapis.asc | gpg --import -
+					curl -sSL https://rvm.io/pkuczynski.asc | gpg --import -
+					curl -sSL https://get.rvm.io | bash -s stable
+					set +x
+					source $HOME/.rvm/scripts/rvm
+					$RETRY rvm get master
+					rvm reload
+					rvm list known
+					set -x
+					;;
+				* )
+					# Install from PPA as that also contains packages needed for the build.
+					sudo apt-add-repository -y ppa:rael-gc/rvm
+					sudo apt-get update
+					sudo apt-get install rvm
+					sudo usermod -a -G rvm $USER
+					set +x
+					source /etc/profile.d/rvm.sh
+					set -x
+					;;
+			esac
+			set +x
+			$RETRY rvm install $VER
+			set -x
+		fi
+		;;
+	"scilab")
+		if [[ -z "$VER" ]]; then
+			$RETRY sudo apt-get -qq install scilab
+		else
+			# Starting with version 2023.0.0 the download filename format changed.
+			case $VER in
+				20*) scilab_tarball=scilab-$VER.bin.x86_64-pc-linux-gnu.tar.xz ;;
+				*)   scilab_tarball=scilab-$VER.bin.linux-x86_64.tar.gz ;;
+			esac
+			$RETRY wget --progress=dot:giga "https://www.scilab.org/download/$VER/$scilab_tarball"
+			# $HOME/.local/bin is in PATH and writeable
+			mkdir -p "$HOME/.local"
+			tar -xf "$scilab_tarball" --strip-components=1 -C "$HOME/.local"
+		fi	
+		;;
+	"tcl")
+		$RETRY sudo apt-get -qq install tcl-dev
+		;;
+esac
+
+set +e # turn off exit on failure (same as +o errexit)
diff --git a/Tools/GHA-linux-install.sh b/Tools/GHA-linux-install.sh
new file mode 100644
index 0000000..ea2108f
--- /dev/null
+++ b/Tools/GHA-linux-install.sh
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+#lsb_release -a
+# find location of current script (only works in bash)
+script_dir="$( dirname "${BASH_SOURCE[0]}")"
+
+# run generic script
+RETRY=
+source "$script_dir"/CI-linux-install.sh
diff --git a/Tools/brew-install b/Tools/brew-install
deleted file mode 100755
index 408ae13..0000000
--- a/Tools/brew-install
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-# Wrapper around 'brew install' emitting a message every minute if the command is still running.
-# This is used on Travis to ensure the install isn't killed when there is no output over a long period (10 minutes).
-# Usage: brew-install package, where package is the name of the package for brew to install.
-
-seconds=0
-minutes=0
-brew install $1 &
-while true; do
-  ps -p$! 2>& 1>/dev/null
-  if [ $? = 0 ]; then
-    if [ $seconds = 60 ]; then
-      let seconds=0
-      let minutes=minutes+1
-      echo "brew install $1 still running ($minutes min)"
-    fi
-    sleep 1
-    let seconds=seconds+1
-  else
-    break
-  fi
-done
-wait $!
-exit $?
diff --git a/Tools/check-include-path.pike b/Tools/check-include-path.pike
deleted file mode 100644
index 2bfb2b9..0000000
--- a/Tools/check-include-path.pike
+++ /dev/null
@@ -1,20 +0,0 @@
-/**
- * This is a helper script to identify the proper include path
- * for Pike header files. It should be run with the full path
- * to the Pike executable as its single argument, e.g.
- *
- *     pike check-include-path.pike /usr/local/bin/pike
- *
- * and its output should be the correct path to the header
- * files, e.g.
- *
- *     /usr/local/pike/7.2.239/include/pike
- *
- */
-
-int main(int argc, array(string) argv)
-{
-    string prefix = replace(argv[1], "/bin/pike", "");
-    write(prefix + "/pike/" + __MAJOR__ + "." + __MINOR__ + "." + __BUILD__ + "/include/pike");
-    return 0;
-}
diff --git a/Tools/cmake/FindPCRE2.cmake b/Tools/cmake/FindPCRE2.cmake
new file mode 100644
index 0000000..08c2163
--- /dev/null
+++ b/Tools/cmake/FindPCRE2.cmake
@@ -0,0 +1,21 @@
+# - Find PCRE2
+# Perl Compatible Regular Expressions
+# https://www.pcre.org/
+
+# The following variables are set:
+# PCRE2_FOUND - System has the PCRE library
+# PCRE2_LIBRARIES - The PCRE library file
+# PCRE2_INCLUDE_DIRS - The folder with the PCRE headers
+
+find_library(PCRE2_LIBRARY NAMES pcre2 pcre2-8)
+find_path(PCRE2_INCLUDE_DIR pcre2.h)
+
+set (PCRE2_LIBRARIES ${PCRE2_LIBRARY})
+set (PCRE2_INCLUDE_DIRS ${PCRE2_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(PCRE2 DEFAULT_MSG PCRE2_LIBRARIES PCRE2_INCLUDE_DIRS)
+
+mark_as_advanced (
+  PCRE2_LIBRARY
+  PCRE2_INCLUDE_DIR)
diff --git a/Tools/cmake/swigconfig.h.in b/Tools/cmake/swigconfig.h.in
new file mode 100644
index 0000000..1cf58e5
--- /dev/null
+++ b/Tools/cmake/swigconfig.h.in
@@ -0,0 +1,95 @@
+/* swigconfig.h. Generated by cmake from Tools/cmake/swigconfig.h.in */
+
+/* define if the Boost library is available */
+#cmakedefine HAVE_BOOST 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#cmakedefine HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `dl' library (-ldl). */
+#cmakedefine HAVE_LIBDL 1
+
+/* Define to 1 if you have the `dld' library (-ldld). */
+#cmakedefine HAVE_LIBDLD 1
+
+/* Define if you have PCRE library */
+#cmakedefine HAVE_PCRE 1
+
+/* Define if popen is available */
+#cmakedefine HAVE_POPEN 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#cmakedefine HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdio.h> header file. */
+#cmakedefine HAVE_STDIO_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#cmakedefine HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#cmakedefine HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#cmakedefine HAVE_STRING_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#cmakedefine HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#cmakedefine HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#cmakedefine HAVE_UNISTD_H 1
+
+/* Name of package */
+#define PACKAGE "swig"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "https://www.swig.org"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "swig"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "swig @SWIG_VERSION@"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "swig"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "@SWIG_VERSION@"
+
+/* The size of `void *', as computed by sizeof. */
+/* #undef SIZEOF_VOID_P */
+
+/* Define to 1 if all of the C90 standard headers exist (not just the ones
+   required in a freestanding environment). This macro is provided for
+   backward compatibility; new code need not use it. */
+#cmakedefine STDC_HEADERS 1
+
+/* Compiler that built SWIG */
+#define SWIG_CXX "@CMAKE_CXX_COMPILER@"
+
+/* Directory for SWIG system-independent libraries */
+#define SWIG_LIB "@CMAKE_INSTALL_PREFIX@/@SWIG_LIB@"
+
+/* Directory for SWIG system-independent libraries (Unix install on native
+   Windows) */
+#define SWIG_LIB_WIN_UNIX "@SWIG_LIB_WIN_UNIX@"
+
+/* Platform that SWIG is built for */
+#define SWIG_PLATFORM "@CMAKE_SYSTEM_NAME@"
+
+/* Version number of package */
+#define VERSION "@SWIG_VERSION@"
+
+
+/* Deal with attempt by Microsoft to deprecate C standard runtime functions */
+#if defined(_MSC_VER)
+# define _CRT_SECURE_NO_DEPRECATE
+#endif
+
diff --git a/Tools/config/ac_compile_warnings.m4 b/Tools/config/ac_compile_warnings.m4
index 7e4239a..04f1463 100644
--- a/Tools/config/ac_compile_warnings.m4
+++ b/Tools/config/ac_compile_warnings.m4
@@ -34,7 +34,7 @@
     then
       if test "$GXX" = "yes"
       then
-        ac_compile_warnings_opt='-Wall -W -ansi -pedantic'
+        ac_compile_warnings_opt='-Wall -W -pedantic'
       fi
       CXXFLAGS="$CXXFLAGS $ac_compile_warnings_opt"
       ac_compile_warnings_msg="$ac_compile_warnings_opt for C++"
@@ -44,7 +44,7 @@
   then
     if test "$GCC" = "yes"
     then
-      ac_compile_warnings_opt='-Wall -W -ansi -pedantic'
+      ac_compile_warnings_opt='-Wall -W -pedantic'
     fi
     CFLAGS="$CFLAGS $ac_compile_warnings_opt"
     ac_compile_warnings_msg="$ac_compile_warnings_msg $ac_compile_warnings_opt for C"
diff --git a/Tools/config/ax_boost_base.m4 b/Tools/config/ax_boost_base.m4
index f5a935c..94fb2a0 100644
--- a/Tools/config/ax_boost_base.m4
+++ b/Tools/config/ax_boost_base.m4
@@ -10,7 +10,7 @@
 #
 #   Test for the Boost C++ libraries of a particular version (or newer)
 #
-#   If no path to the installed boost library is given the macro searchs
+#   If no path to the installed boost library is given the macro searches
 #   under /usr, /usr/local, /opt and /opt/local and evaluates the
 #   $BOOST_ROOT environment variable. Further documentation is available at
 #   <http://randspringer.de/boost/index.html>.
diff --git a/Tools/config/ax_cxx_compile_stdcxx_11.m4 b/Tools/config/ax_cxx_compile_stdcxx_11.m4
deleted file mode 100644
index 138ca2a..0000000
--- a/Tools/config/ax_cxx_compile_stdcxx_11.m4
+++ /dev/null
@@ -1,121 +0,0 @@
-# ============================================================================
-#  http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
-# ============================================================================
-#
-# SYNOPSIS
-#
-#   AX_CXX_COMPILE_STDCXX_11([ext|noext], [nostop])
-#
-# DESCRIPTION
-#
-#   Check for baseline language coverage in the compiler for the C++11
-#   standard; if necessary, add switches to CXXFLAGS to enable support.
-#   CXX11FLAGS will also contain any necessary switches to enable support.
-#   HAVE_CXX11_COMPILER will additionally be set to yes if there is support.
-#   If the second argument is not specified, errors out if no mode that
-#   supports C++11 baseline syntax can be found. The first argument, if
-#   specified, indicates whether you insist on an extended mode
-#   (e.g. -std=gnu++11) or a strict conformance mode (e.g. -std=c++11).
-#   If neither is specified, you get whatever works, with preference for an
-#   extended mode.
-#
-# LICENSE
-#
-#   Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
-#   Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
-#   Copyright (c) 2012 William Fulton <wsf@fultondesigns.co.uk>
-#
-#   Copying and distribution of this file, with or without modification, are
-#   permitted in any medium without royalty provided the copyright notice
-#   and this notice are preserved. This file is offered as-is, without any
-#   warranty.
-
-#serial 1
-
-m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [
-  template <typename T>
-    struct check
-    {
-      static_assert(sizeof(int) <= sizeof(T), "not big enough");
-    };
-
-    typedef check<check<bool>> right_angle_brackets;
-
-    int a;
-    decltype(a) b;
-
-    typedef check<int> check_type;
-    check_type c;
-    check_type&& cr = static_cast<check_type&&>(c);
-])
-
-AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
-  m4_if([$1], [], [],
-        [$1], [ext], [],
-        [$1], [noext], [],
-        [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
-  m4_if([$2], [], [],
-        [$2], [nostop], [],
-        [m4_fatal([invalid argument `$2' to AX_CXX_COMPILE_STDCXX_11])])dnl
-  AC_LANG_ASSERT([C++])dnl
-  ac_success=no
-  CXX11FLAGS=
-  AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
-  ax_cv_cxx_compile_cxx11,
-  [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
-    [ax_cv_cxx_compile_cxx11=yes],
-    [ax_cv_cxx_compile_cxx11=no])])
-  if test x$ax_cv_cxx_compile_cxx11 = xyes; then
-    ac_success=yes
-  fi
-
-  m4_if([$1], [noext], [], [dnl
-  if test x$ac_success = xno; then
-    for switch in -std=gnu++11 -std=gnu++0x; do
-      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
-      AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
-                     $cachevar,
-        [ac_save_CXXFLAGS="$CXXFLAGS"
-         CXXFLAGS="$CXXFLAGS $switch"
-         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
-          [eval $cachevar=yes],
-          [eval $cachevar=no])
-         CXXFLAGS="$ac_save_CXXFLAGS"])
-      if eval test x\$$cachevar = xyes; then
-        CXXFLAGS="$CXXFLAGS $switch"
-        CXX11FLAGS=$switch
-        ac_success=yes
-        break
-      fi
-    done
-  fi])
-
-  m4_if([$1], [ext], [], [dnl
-  if test x$ac_success = xno; then
-    for switch in -std=c++11 -std=c++0x; do
-      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
-      AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
-                     $cachevar,
-        [ac_save_CXXFLAGS="$CXXFLAGS"
-         CXXFLAGS="$CXXFLAGS $switch"
-         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
-          [eval $cachevar=yes],
-          [eval $cachevar=no])
-         CXXFLAGS="$ac_save_CXXFLAGS"])
-      if eval test x\$$cachevar = xyes; then
-        CXXFLAGS="$CXXFLAGS $switch"
-        CXX11FLAGS=$switch
-        ac_success=yes
-        break
-      fi
-    done
-  fi])
-
-  if test x$ac_success = xno; then
-    if test x$2 != xnostop; then
-      AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
-    fi
-  else
-    HAVE_CXX11_COMPILER=yes
-  fi
-])
diff --git a/Tools/config/compile b/Tools/config/compile
index 99e5052..df363c8 100755
--- a/Tools/config/compile
+++ b/Tools/config/compile
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2021 Free Software Foundation, Inc.
 # Written by Tom Tromey <tromey@cygnus.com>.
 #
 # This program is free software; you can redistribute it and/or modify
@@ -53,7 +53,7 @@
 	  MINGW*)
 	    file_conv=mingw
 	    ;;
-	  CYGWIN*)
+	  CYGWIN* | MSYS*)
 	    file_conv=cygwin
 	    ;;
 	  *)
@@ -67,7 +67,7 @@
 	mingw/*)
 	  file=`cmd //C echo "$file " | sed -e 's/"\(.*\) " *$/\1/'`
 	  ;;
-	cygwin/*)
+	cygwin/* | msys/*)
 	  file=`cygpath -m "$file" || echo "$file"`
 	  ;;
 	wine/*)
diff --git a/Tools/config/config.guess b/Tools/config/config.guess
index f50dcdb..7f76b62 100755
--- a/Tools/config/config.guess
+++ b/Tools/config/config.guess
@@ -1,12 +1,14 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright 1992-2018 Free Software Foundation, Inc.
+#   Copyright 1992-2022 Free Software Foundation, Inc.
 
-timestamp='2018-02-24'
+# shellcheck disable=SC2006,SC2268 # see below for rationale
+
+timestamp='2022-01-09'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
+# the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 #
 # This program is distributed in the hope that it will be useful, but
@@ -27,11 +29,19 @@
 # Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
 #
 # You can get the latest version of this script from:
-# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+# https://git.savannah.gnu.org/cgit/config.git/plain/config.guess
 #
 # Please send patches to <config-patches@gnu.org>.
 
 
+# The "shellcheck disable" line above the timestamp inhibits complaints
+# about features and limitations of the classic Bourne shell that were
+# superseded or lifted in POSIX.  However, this script identifies a wide
+# variety of pre-POSIX systems that do not have POSIX shells at all, and
+# even some reasonably current systems (Solaris 10 as case-in-point) still
+# have a pre-POSIX /bin/sh.
+
+
 me=`echo "$0" | sed -e 's,.*/,,'`
 
 usage="\
@@ -50,7 +60,7 @@
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright 1992-2018 Free Software Foundation, Inc.
+Copyright 1992-2022 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -84,7 +94,8 @@
   exit 1
 fi
 
-trap 'exit 1' 1 2 15
+# Just in case it came from the environment.
+GUESS=
 
 # CC_FOR_BUILD -- compiler used by this script. Note that the use of a
 # compiler to aid in system detection is discouraged as it requires
@@ -96,73 +107,90 @@
 
 # Portable tmp directory creation inspired by the Autoconf team.
 
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,)    echo "int x;" > "$dummy.c" ;
-	for c in cc gcc c89 c99 ; do
-	  if ($c -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
-	     CC_FOR_BUILD="$c"; break ;
-	  fi ;
-	done ;
-	if test x"$CC_FOR_BUILD" = x ; then
-	  CC_FOR_BUILD=no_compiler_found ;
-	fi
-	;;
- ,,*)   CC_FOR_BUILD=$CC ;;
- ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
+tmp=
+# shellcheck disable=SC2172
+trap 'test -z "$tmp" || rm -fr "$tmp"' 0 1 2 13 15
+
+set_cc_for_build() {
+    # prevent multiple calls if $tmp is already set
+    test "$tmp" && return 0
+    : "${TMPDIR=/tmp}"
+    # shellcheck disable=SC2039,SC3028
+    { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+	{ test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir "$tmp" 2>/dev/null) ; } ||
+	{ tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir "$tmp" 2>/dev/null) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+	{ echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; }
+    dummy=$tmp/dummy
+    case ${CC_FOR_BUILD-},${HOST_CC-},${CC-} in
+	,,)    echo "int x;" > "$dummy.c"
+	       for driver in cc gcc c89 c99 ; do
+		   if ($driver -c -o "$dummy.o" "$dummy.c") >/dev/null 2>&1 ; then
+		       CC_FOR_BUILD=$driver
+		       break
+		   fi
+	       done
+	       if test x"$CC_FOR_BUILD" = x ; then
+		   CC_FOR_BUILD=no_compiler_found
+	       fi
+	       ;;
+	,,*)   CC_FOR_BUILD=$CC ;;
+	,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+    esac
+}
 
 # This is needed to find uname on a Pyramid OSx when run in the BSD universe.
 # (ghazi@noc.rutgers.edu 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+if test -f /.attbin/uname ; then
 	PATH=$PATH:/.attbin ; export PATH
 fi
 
 UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
 UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
 UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
 
-case "$UNAME_SYSTEM" in
+case $UNAME_SYSTEM in
 Linux|GNU|GNU/*)
-	# If the system lacks a compiler, then just pick glibc.
-	# We could probably try harder.
-	LIBC=gnu
+	LIBC=unknown
 
-	eval "$set_cc_for_build"
+	set_cc_for_build
 	cat <<-EOF > "$dummy.c"
 	#include <features.h>
 	#if defined(__UCLIBC__)
 	LIBC=uclibc
 	#elif defined(__dietlibc__)
 	LIBC=dietlibc
-	#else
+	#elif defined(__GLIBC__)
 	LIBC=gnu
+	#else
+	#include <stdarg.h>
+	/* First heuristic to detect musl libc.  */
+	#ifdef __DEFINED_va_list
+	LIBC=musl
+	#endif
 	#endif
 	EOF
-	eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`"
+	cc_set_libc=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+	eval "$cc_set_libc"
 
-	# If ldd exists, use it to detect musl libc.
-	if command -v ldd >/dev/null && \
-		ldd --version 2>&1 | grep -q ^musl
-	then
-	    LIBC=musl
+	# Second heuristic to detect musl libc.
+	if [ "$LIBC" = unknown ] &&
+	   command -v ldd >/dev/null &&
+	   ldd --version 2>&1 | grep -q ^musl; then
+		LIBC=musl
+	fi
+
+	# If the system lacks a compiler, then just pick glibc.
+	# We could probably try harder.
+	if [ "$LIBC" = unknown ]; then
+		LIBC=gnu
 	fi
 	;;
 esac
 
 # Note: order is significant - the case branches are not exclusive.
 
-case "$UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION" in
+case $UNAME_MACHINE:$UNAME_SYSTEM:$UNAME_RELEASE:$UNAME_VERSION in
     *:NetBSD:*:*)
 	# NetBSD (nbsd) targets should (where applicable) match one or
 	# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
@@ -174,12 +202,12 @@
 	#
 	# Note: NetBSD doesn't particularly care about the vendor
 	# portion of the name.  We always set it to "unknown".
-	sysctl="sysctl -n hw.machine_arch"
 	UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
-	    "/sbin/$sysctl" 2>/dev/null || \
-	    "/usr/sbin/$sysctl" 2>/dev/null || \
+	    /sbin/sysctl -n hw.machine_arch 2>/dev/null || \
+	    /usr/sbin/sysctl -n hw.machine_arch 2>/dev/null || \
 	    echo unknown)`
-	case "$UNAME_MACHINE_ARCH" in
+	case $UNAME_MACHINE_ARCH in
+	    aarch64eb) machine=aarch64_be-unknown ;;
 	    armeb) machine=armeb-unknown ;;
 	    arm*) machine=arm-unknown ;;
 	    sh3el) machine=shl-unknown ;;
@@ -188,18 +216,18 @@
 	    earmv*)
 		arch=`echo "$UNAME_MACHINE_ARCH" | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
 		endian=`echo "$UNAME_MACHINE_ARCH" | sed -ne 's,^.*\(eb\)$,\1,p'`
-		machine="${arch}${endian}"-unknown
+		machine=${arch}${endian}-unknown
 		;;
-	    *) machine="$UNAME_MACHINE_ARCH"-unknown ;;
+	    *) machine=$UNAME_MACHINE_ARCH-unknown ;;
 	esac
 	# The Operating System including object format, if it has switched
 	# to ELF recently (or will in the future) and ABI.
-	case "$UNAME_MACHINE_ARCH" in
+	case $UNAME_MACHINE_ARCH in
 	    earm*)
 		os=netbsdelf
 		;;
 	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
-		eval "$set_cc_for_build"
+		set_cc_for_build
 		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
 			| grep -q __ELF__
 		then
@@ -215,7 +243,7 @@
 		;;
 	esac
 	# Determine ABI tags.
-	case "$UNAME_MACHINE_ARCH" in
+	case $UNAME_MACHINE_ARCH in
 	    earm*)
 		expr='s/^earmv[0-9]/-eabi/;s/eb$//'
 		abi=`echo "$UNAME_MACHINE_ARCH" | sed -e "$expr"`
@@ -226,7 +254,7 @@
 	# thus, need a distinct triplet. However, they do not need
 	# kernel version information, so it can be replaced with a
 	# suitable tag, in the style of linux-gnu.
-	case "$UNAME_VERSION" in
+	case $UNAME_VERSION in
 	    Debian*)
 		release='-gnu'
 		;;
@@ -237,45 +265,57 @@
 	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
 	# contains redundant information, the shorter form:
 	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
-	echo "$machine-${os}${release}${abi}"
-	exit ;;
+	GUESS=$machine-${os}${release}${abi-}
+	;;
     *:Bitrig:*:*)
 	UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
-	echo "$UNAME_MACHINE_ARCH"-unknown-bitrig"$UNAME_RELEASE"
-	exit ;;
+	GUESS=$UNAME_MACHINE_ARCH-unknown-bitrig$UNAME_RELEASE
+	;;
     *:OpenBSD:*:*)
 	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
-	echo "$UNAME_MACHINE_ARCH"-unknown-openbsd"$UNAME_RELEASE"
-	exit ;;
+	GUESS=$UNAME_MACHINE_ARCH-unknown-openbsd$UNAME_RELEASE
+	;;
+    *:SecBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/SecBSD.//'`
+	GUESS=$UNAME_MACHINE_ARCH-unknown-secbsd$UNAME_RELEASE
+	;;
     *:LibertyBSD:*:*)
 	UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
-	echo "$UNAME_MACHINE_ARCH"-unknown-libertybsd"$UNAME_RELEASE"
-	exit ;;
+	GUESS=$UNAME_MACHINE_ARCH-unknown-libertybsd$UNAME_RELEASE
+	;;
     *:MidnightBSD:*:*)
-	echo "$UNAME_MACHINE"-unknown-midnightbsd"$UNAME_RELEASE"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-midnightbsd$UNAME_RELEASE
+	;;
     *:ekkoBSD:*:*)
-	echo "$UNAME_MACHINE"-unknown-ekkobsd"$UNAME_RELEASE"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-ekkobsd$UNAME_RELEASE
+	;;
     *:SolidBSD:*:*)
-	echo "$UNAME_MACHINE"-unknown-solidbsd"$UNAME_RELEASE"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-solidbsd$UNAME_RELEASE
+	;;
+    *:OS108:*:*)
+	GUESS=$UNAME_MACHINE-unknown-os108_$UNAME_RELEASE
+	;;
     macppc:MirBSD:*:*)
-	echo powerpc-unknown-mirbsd"$UNAME_RELEASE"
-	exit ;;
+	GUESS=powerpc-unknown-mirbsd$UNAME_RELEASE
+	;;
     *:MirBSD:*:*)
-	echo "$UNAME_MACHINE"-unknown-mirbsd"$UNAME_RELEASE"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-mirbsd$UNAME_RELEASE
+	;;
     *:Sortix:*:*)
-	echo "$UNAME_MACHINE"-unknown-sortix
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-sortix
+	;;
+    *:Twizzler:*:*)
+	GUESS=$UNAME_MACHINE-unknown-twizzler
+	;;
     *:Redox:*:*)
-	echo "$UNAME_MACHINE"-unknown-redox
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-redox
+	;;
     mips:OSF1:*.*)
-        echo mips-dec-osf1
-        exit ;;
+	GUESS=mips-dec-osf1
+	;;
     alpha:OSF1:*:*)
+	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+	trap '' 0
 	case $UNAME_RELEASE in
 	*4.0)
 		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
@@ -289,7 +329,7 @@
 	# covers most systems running today.  This code pipes the CPU
 	# types through head -n 1, so we only detect the type of CPU 0.
 	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
-	case "$ALPHA_CPU_TYPE" in
+	case $ALPHA_CPU_TYPE in
 	    "EV4 (21064)")
 		UNAME_MACHINE=alpha ;;
 	    "EV4.5 (21064)")
@@ -326,117 +366,121 @@
 	# A Tn.n version is a released field test version.
 	# A Xn.n version is an unreleased experimental baselevel.
 	# 1.2 uses "1.2" for uname -r.
-	echo "$UNAME_MACHINE"-dec-osf"`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`"
-	# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
-	exitcode=$?
-	trap '' 0
-	exit $exitcode ;;
+	OSF_REL=`echo "$UNAME_RELEASE" | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+	GUESS=$UNAME_MACHINE-dec-osf$OSF_REL
+	;;
     Amiga*:UNIX_System_V:4.0:*)
-	echo m68k-unknown-sysv4
-	exit ;;
+	GUESS=m68k-unknown-sysv4
+	;;
     *:[Aa]miga[Oo][Ss]:*:*)
-	echo "$UNAME_MACHINE"-unknown-amigaos
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-amigaos
+	;;
     *:[Mm]orph[Oo][Ss]:*:*)
-	echo "$UNAME_MACHINE"-unknown-morphos
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-morphos
+	;;
     *:OS/390:*:*)
-	echo i370-ibm-openedition
-	exit ;;
+	GUESS=i370-ibm-openedition
+	;;
     *:z/VM:*:*)
-	echo s390-ibm-zvmoe
-	exit ;;
+	GUESS=s390-ibm-zvmoe
+	;;
     *:OS400:*:*)
-	echo powerpc-ibm-os400
-	exit ;;
+	GUESS=powerpc-ibm-os400
+	;;
     arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
-	echo arm-acorn-riscix"$UNAME_RELEASE"
-	exit ;;
+	GUESS=arm-acorn-riscix$UNAME_RELEASE
+	;;
     arm*:riscos:*:*|arm*:RISCOS:*:*)
-	echo arm-unknown-riscos
-	exit ;;
+	GUESS=arm-unknown-riscos
+	;;
     SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
-	echo hppa1.1-hitachi-hiuxmpp
-	exit ;;
+	GUESS=hppa1.1-hitachi-hiuxmpp
+	;;
     Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
 	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
-	if test "`(/bin/universe) 2>/dev/null`" = att ; then
-		echo pyramid-pyramid-sysv3
-	else
-		echo pyramid-pyramid-bsd
-	fi
-	exit ;;
+	case `(/bin/universe) 2>/dev/null` in
+	    att) GUESS=pyramid-pyramid-sysv3 ;;
+	    *)   GUESS=pyramid-pyramid-bsd   ;;
+	esac
+	;;
     NILE*:*:*:dcosx)
-	echo pyramid-pyramid-svr4
-	exit ;;
+	GUESS=pyramid-pyramid-svr4
+	;;
     DRS?6000:unix:4.0:6*)
-	echo sparc-icl-nx6
-	exit ;;
+	GUESS=sparc-icl-nx6
+	;;
     DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
 	case `/usr/bin/uname -p` in
-	    sparc) echo sparc-icl-nx7; exit ;;
-	esac ;;
+	    sparc) GUESS=sparc-icl-nx7 ;;
+	esac
+	;;
     s390x:SunOS:*:*)
-	echo "$UNAME_MACHINE"-ibm-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
-	exit ;;
+	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+	GUESS=$UNAME_MACHINE-ibm-solaris2$SUN_REL
+	;;
     sun4H:SunOS:5.*:*)
-	echo sparc-hal-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
-	exit ;;
+	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+	GUESS=sparc-hal-solaris2$SUN_REL
+	;;
     sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
-	echo sparc-sun-solaris2"`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`"
-	exit ;;
+	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+	GUESS=sparc-sun-solaris2$SUN_REL
+	;;
     i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
-	echo i386-pc-auroraux"$UNAME_RELEASE"
-	exit ;;
+	GUESS=i386-pc-auroraux$UNAME_RELEASE
+	;;
     i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
-	eval "$set_cc_for_build"
+	set_cc_for_build
 	SUN_ARCH=i386
 	# If there is a compiler, see if it is configured for 64-bit objects.
 	# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
 	# This test works for both compilers.
-	if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
+	if test "$CC_FOR_BUILD" != no_compiler_found; then
 	    if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
-		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+		(CCOPTS="" $CC_FOR_BUILD -m64 -E - 2>/dev/null) | \
 		grep IS_64BIT_ARCH >/dev/null
 	    then
 		SUN_ARCH=x86_64
 	    fi
 	fi
-	echo "$SUN_ARCH"-pc-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
-	exit ;;
+	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+	GUESS=$SUN_ARCH-pc-solaris2$SUN_REL
+	;;
     sun4*:SunOS:6*:*)
 	# According to config.sub, this is the proper way to canonicalize
 	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
 	# it's likely to be more like Solaris than SunOS4.
-	echo sparc-sun-solaris3"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
-	exit ;;
+	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+	GUESS=sparc-sun-solaris3$SUN_REL
+	;;
     sun4*:SunOS:*:*)
-	case "`/usr/bin/arch -k`" in
+	case `/usr/bin/arch -k` in
 	    Series*|S4*)
 		UNAME_RELEASE=`uname -v`
 		;;
 	esac
 	# Japanese Language versions have a version number like `4.1.3-JL'.
-	echo sparc-sun-sunos"`echo "$UNAME_RELEASE"|sed -e 's/-/_/'`"
-	exit ;;
+	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/'`
+	GUESS=sparc-sun-sunos$SUN_REL
+	;;
     sun3*:SunOS:*:*)
-	echo m68k-sun-sunos"$UNAME_RELEASE"
-	exit ;;
+	GUESS=m68k-sun-sunos$UNAME_RELEASE
+	;;
     sun*:*:4.2BSD:*)
 	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
 	test "x$UNAME_RELEASE" = x && UNAME_RELEASE=3
-	case "`/bin/arch`" in
+	case `/bin/arch` in
 	    sun3)
-		echo m68k-sun-sunos"$UNAME_RELEASE"
+		GUESS=m68k-sun-sunos$UNAME_RELEASE
 		;;
 	    sun4)
-		echo sparc-sun-sunos"$UNAME_RELEASE"
+		GUESS=sparc-sun-sunos$UNAME_RELEASE
 		;;
 	esac
-	exit ;;
+	;;
     aushp:SunOS:*:*)
-	echo sparc-auspex-sunos"$UNAME_RELEASE"
-	exit ;;
+	GUESS=sparc-auspex-sunos$UNAME_RELEASE
+	;;
     # The situation for MiNT is a little confusing.  The machine name
     # can be virtually everything (everything which is not
     # "atarist" or "atariste" at least should have a processor
@@ -446,43 +490,43 @@
     # MiNT.  But MiNT is downward compatible to TOS, so this should
     # be no problem.
     atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
-	echo m68k-atari-mint"$UNAME_RELEASE"
-	exit ;;
+	GUESS=m68k-atari-mint$UNAME_RELEASE
+	;;
     atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
-	echo m68k-atari-mint"$UNAME_RELEASE"
-	exit ;;
+	GUESS=m68k-atari-mint$UNAME_RELEASE
+	;;
     *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
-	echo m68k-atari-mint"$UNAME_RELEASE"
-	exit ;;
+	GUESS=m68k-atari-mint$UNAME_RELEASE
+	;;
     milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
-	echo m68k-milan-mint"$UNAME_RELEASE"
-	exit ;;
+	GUESS=m68k-milan-mint$UNAME_RELEASE
+	;;
     hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
-	echo m68k-hades-mint"$UNAME_RELEASE"
-	exit ;;
+	GUESS=m68k-hades-mint$UNAME_RELEASE
+	;;
     *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
-	echo m68k-unknown-mint"$UNAME_RELEASE"
-	exit ;;
+	GUESS=m68k-unknown-mint$UNAME_RELEASE
+	;;
     m68k:machten:*:*)
-	echo m68k-apple-machten"$UNAME_RELEASE"
-	exit ;;
+	GUESS=m68k-apple-machten$UNAME_RELEASE
+	;;
     powerpc:machten:*:*)
-	echo powerpc-apple-machten"$UNAME_RELEASE"
-	exit ;;
+	GUESS=powerpc-apple-machten$UNAME_RELEASE
+	;;
     RISC*:Mach:*:*)
-	echo mips-dec-mach_bsd4.3
-	exit ;;
+	GUESS=mips-dec-mach_bsd4.3
+	;;
     RISC*:ULTRIX:*:*)
-	echo mips-dec-ultrix"$UNAME_RELEASE"
-	exit ;;
+	GUESS=mips-dec-ultrix$UNAME_RELEASE
+	;;
     VAX*:ULTRIX*:*:*)
-	echo vax-dec-ultrix"$UNAME_RELEASE"
-	exit ;;
+	GUESS=vax-dec-ultrix$UNAME_RELEASE
+	;;
     2020:CLIX:*:* | 2430:CLIX:*:*)
-	echo clipper-intergraph-clix"$UNAME_RELEASE"
-	exit ;;
+	GUESS=clipper-intergraph-clix$UNAME_RELEASE
+	;;
     mips:*:*:UMIPS | mips:*:*:RISCos)
-	eval "$set_cc_for_build"
+	set_cc_for_build
 	sed 's/^	//' << EOF > "$dummy.c"
 #ifdef __cplusplus
 #include <stdio.h>  /* for printf() prototype */
@@ -508,78 +552,79 @@
 	  dummyarg=`echo "$UNAME_RELEASE" | sed -n 's/\([0-9]*\).*/\1/p'` &&
 	  SYSTEM_NAME=`"$dummy" "$dummyarg"` &&
 	    { echo "$SYSTEM_NAME"; exit; }
-	echo mips-mips-riscos"$UNAME_RELEASE"
-	exit ;;
+	GUESS=mips-mips-riscos$UNAME_RELEASE
+	;;
     Motorola:PowerMAX_OS:*:*)
-	echo powerpc-motorola-powermax
-	exit ;;
+	GUESS=powerpc-motorola-powermax
+	;;
     Motorola:*:4.3:PL8-*)
-	echo powerpc-harris-powermax
-	exit ;;
+	GUESS=powerpc-harris-powermax
+	;;
     Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
-	echo powerpc-harris-powermax
-	exit ;;
+	GUESS=powerpc-harris-powermax
+	;;
     Night_Hawk:Power_UNIX:*:*)
-	echo powerpc-harris-powerunix
-	exit ;;
+	GUESS=powerpc-harris-powerunix
+	;;
     m88k:CX/UX:7*:*)
-	echo m88k-harris-cxux7
-	exit ;;
+	GUESS=m88k-harris-cxux7
+	;;
     m88k:*:4*:R4*)
-	echo m88k-motorola-sysv4
-	exit ;;
+	GUESS=m88k-motorola-sysv4
+	;;
     m88k:*:3*:R3*)
-	echo m88k-motorola-sysv3
-	exit ;;
+	GUESS=m88k-motorola-sysv3
+	;;
     AViiON:dgux:*:*)
 	# DG/UX returns AViiON for all architectures
 	UNAME_PROCESSOR=`/usr/bin/uname -p`
-	if [ "$UNAME_PROCESSOR" = mc88100 ] || [ "$UNAME_PROCESSOR" = mc88110 ]
+	if test "$UNAME_PROCESSOR" = mc88100 || test "$UNAME_PROCESSOR" = mc88110
 	then
-	    if [ "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx ] || \
-	       [ "$TARGET_BINARY_INTERFACE"x = x ]
+	    if test "$TARGET_BINARY_INTERFACE"x = m88kdguxelfx || \
+	       test "$TARGET_BINARY_INTERFACE"x = x
 	    then
-		echo m88k-dg-dgux"$UNAME_RELEASE"
+		GUESS=m88k-dg-dgux$UNAME_RELEASE
 	    else
-		echo m88k-dg-dguxbcs"$UNAME_RELEASE"
+		GUESS=m88k-dg-dguxbcs$UNAME_RELEASE
 	    fi
 	else
-	    echo i586-dg-dgux"$UNAME_RELEASE"
+	    GUESS=i586-dg-dgux$UNAME_RELEASE
 	fi
-	exit ;;
+	;;
     M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
-	echo m88k-dolphin-sysv3
-	exit ;;
+	GUESS=m88k-dolphin-sysv3
+	;;
     M88*:*:R3*:*)
 	# Delta 88k system running SVR3
-	echo m88k-motorola-sysv3
-	exit ;;
+	GUESS=m88k-motorola-sysv3
+	;;
     XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
-	echo m88k-tektronix-sysv3
-	exit ;;
+	GUESS=m88k-tektronix-sysv3
+	;;
     Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
-	echo m68k-tektronix-bsd
-	exit ;;
+	GUESS=m68k-tektronix-bsd
+	;;
     *:IRIX*:*:*)
-	echo mips-sgi-irix"`echo "$UNAME_RELEASE"|sed -e 's/-/_/g'`"
-	exit ;;
+	IRIX_REL=`echo "$UNAME_RELEASE" | sed -e 's/-/_/g'`
+	GUESS=mips-sgi-irix$IRIX_REL
+	;;
     ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
-	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
-	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+	GUESS=romp-ibm-aix    # uname -m gives an 8 hex-code CPU id
+	;;                    # Note that: echo "'`uname -s`'" gives 'AIX '
     i*86:AIX:*:*)
-	echo i386-ibm-aix
-	exit ;;
+	GUESS=i386-ibm-aix
+	;;
     ia64:AIX:*:*)
-	if [ -x /usr/bin/oslevel ] ; then
+	if test -x /usr/bin/oslevel ; then
 		IBM_REV=`/usr/bin/oslevel`
 	else
-		IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
+		IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
 	fi
-	echo "$UNAME_MACHINE"-ibm-aix"$IBM_REV"
-	exit ;;
+	GUESS=$UNAME_MACHINE-ibm-aix$IBM_REV
+	;;
     *:AIX:2:3)
 	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
-		eval "$set_cc_for_build"
+		set_cc_for_build
 		sed 's/^		//' << EOF > "$dummy.c"
 		#include <sys/systemcfg.h>
 
@@ -593,16 +638,16 @@
 EOF
 		if $CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"`
 		then
-			echo "$SYSTEM_NAME"
+			GUESS=$SYSTEM_NAME
 		else
-			echo rs6000-ibm-aix3.2.5
+			GUESS=rs6000-ibm-aix3.2.5
 		fi
 	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
-		echo rs6000-ibm-aix3.2.4
+		GUESS=rs6000-ibm-aix3.2.4
 	else
-		echo rs6000-ibm-aix3.2
+		GUESS=rs6000-ibm-aix3.2
 	fi
-	exit ;;
+	;;
     *:AIX:*:[4567])
 	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
 	if /usr/sbin/lsattr -El "$IBM_CPU_ID" | grep ' POWER' >/dev/null 2>&1; then
@@ -610,57 +655,57 @@
 	else
 		IBM_ARCH=powerpc
 	fi
-	if [ -x /usr/bin/lslpp ] ; then
-		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+	if test -x /usr/bin/lslpp ; then
+		IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc | \
 			   awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
 	else
-		IBM_REV="$UNAME_VERSION.$UNAME_RELEASE"
+		IBM_REV=$UNAME_VERSION.$UNAME_RELEASE
 	fi
-	echo "$IBM_ARCH"-ibm-aix"$IBM_REV"
-	exit ;;
+	GUESS=$IBM_ARCH-ibm-aix$IBM_REV
+	;;
     *:AIX:*:*)
-	echo rs6000-ibm-aix
-	exit ;;
+	GUESS=rs6000-ibm-aix
+	;;
     ibmrt:4.4BSD:*|romp-ibm:4.4BSD:*)
-	echo romp-ibm-bsd4.4
-	exit ;;
+	GUESS=romp-ibm-bsd4.4
+	;;
     ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
-	echo romp-ibm-bsd"$UNAME_RELEASE"   # 4.3 with uname added to
-	exit ;;                             # report: romp-ibm BSD 4.3
+	GUESS=romp-ibm-bsd$UNAME_RELEASE    # 4.3 with uname added to
+	;;                                  # report: romp-ibm BSD 4.3
     *:BOSX:*:*)
-	echo rs6000-bull-bosx
-	exit ;;
+	GUESS=rs6000-bull-bosx
+	;;
     DPX/2?00:B.O.S.:*:*)
-	echo m68k-bull-sysv3
-	exit ;;
+	GUESS=m68k-bull-sysv3
+	;;
     9000/[34]??:4.3bsd:1.*:*)
-	echo m68k-hp-bsd
-	exit ;;
+	GUESS=m68k-hp-bsd
+	;;
     hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
-	echo m68k-hp-bsd4.4
-	exit ;;
+	GUESS=m68k-hp-bsd4.4
+	;;
     9000/[34678]??:HP-UX:*:*)
-	HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
-	case "$UNAME_MACHINE" in
+	HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
+	case $UNAME_MACHINE in
 	    9000/31?)            HP_ARCH=m68000 ;;
 	    9000/[34]??)         HP_ARCH=m68k ;;
 	    9000/[678][0-9][0-9])
-		if [ -x /usr/bin/getconf ]; then
+		if test -x /usr/bin/getconf; then
 		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
 		    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
-		    case "$sc_cpu_version" in
+		    case $sc_cpu_version in
 		      523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
 		      528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
 		      532)                      # CPU_PA_RISC2_0
-			case "$sc_kernel_bits" in
+			case $sc_kernel_bits in
 			  32) HP_ARCH=hppa2.0n ;;
 			  64) HP_ARCH=hppa2.0w ;;
 			  '') HP_ARCH=hppa2.0 ;;   # HP-UX 10.20
 			esac ;;
 		    esac
 		fi
-		if [ "$HP_ARCH" = "" ]; then
-		    eval "$set_cc_for_build"
+		if test "$HP_ARCH" = ""; then
+		    set_cc_for_build
 		    sed 's/^		//' << EOF > "$dummy.c"
 
 		#define _HPUX_SOURCE
@@ -698,9 +743,9 @@
 		    test -z "$HP_ARCH" && HP_ARCH=hppa
 		fi ;;
 	esac
-	if [ "$HP_ARCH" = hppa2.0w ]
+	if test "$HP_ARCH" = hppa2.0w
 	then
-	    eval "$set_cc_for_build"
+	    set_cc_for_build
 
 	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
 	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
@@ -719,14 +764,14 @@
 		HP_ARCH=hppa64
 	    fi
 	fi
-	echo "$HP_ARCH"-hp-hpux"$HPUX_REV"
-	exit ;;
+	GUESS=$HP_ARCH-hp-hpux$HPUX_REV
+	;;
     ia64:HP-UX:*:*)
-	HPUX_REV=`echo "$UNAME_RELEASE"|sed -e 's/[^.]*.[0B]*//'`
-	echo ia64-hp-hpux"$HPUX_REV"
-	exit ;;
+	HPUX_REV=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*.[0B]*//'`
+	GUESS=ia64-hp-hpux$HPUX_REV
+	;;
     3050*:HI-UX:*:*)
-	eval "$set_cc_for_build"
+	set_cc_for_build
 	sed 's/^	//' << EOF > "$dummy.c"
 	#include <unistd.h>
 	int
@@ -754,36 +799,36 @@
 EOF
 	$CC_FOR_BUILD -o "$dummy" "$dummy.c" && SYSTEM_NAME=`"$dummy"` &&
 		{ echo "$SYSTEM_NAME"; exit; }
-	echo unknown-hitachi-hiuxwe2
-	exit ;;
+	GUESS=unknown-hitachi-hiuxwe2
+	;;
     9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:*)
-	echo hppa1.1-hp-bsd
-	exit ;;
+	GUESS=hppa1.1-hp-bsd
+	;;
     9000/8??:4.3bsd:*:*)
-	echo hppa1.0-hp-bsd
-	exit ;;
+	GUESS=hppa1.0-hp-bsd
+	;;
     *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
-	echo hppa1.0-hp-mpeix
-	exit ;;
+	GUESS=hppa1.0-hp-mpeix
+	;;
     hp7??:OSF1:*:* | hp8?[79]:OSF1:*:*)
-	echo hppa1.1-hp-osf
-	exit ;;
+	GUESS=hppa1.1-hp-osf
+	;;
     hp8??:OSF1:*:*)
-	echo hppa1.0-hp-osf
-	exit ;;
+	GUESS=hppa1.0-hp-osf
+	;;
     i*86:OSF1:*:*)
-	if [ -x /usr/sbin/sysversion ] ; then
-	    echo "$UNAME_MACHINE"-unknown-osf1mk
+	if test -x /usr/sbin/sysversion ; then
+	    GUESS=$UNAME_MACHINE-unknown-osf1mk
 	else
-	    echo "$UNAME_MACHINE"-unknown-osf1
+	    GUESS=$UNAME_MACHINE-unknown-osf1
 	fi
-	exit ;;
+	;;
     parisc*:Lites*:*:*)
-	echo hppa1.1-hp-lites
-	exit ;;
+	GUESS=hppa1.1-hp-lites
+	;;
     C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
-	echo c1-convex-bsd
-	exit ;;
+	GUESS=c1-convex-bsd
+	;;
     C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
 	if getsysinfo -f scalar_acc
 	then echo c32-convex-bsd
@@ -791,17 +836,18 @@
 	fi
 	exit ;;
     C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
-	echo c34-convex-bsd
-	exit ;;
+	GUESS=c34-convex-bsd
+	;;
     C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
-	echo c38-convex-bsd
-	exit ;;
+	GUESS=c38-convex-bsd
+	;;
     C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
-	echo c4-convex-bsd
-	exit ;;
+	GUESS=c4-convex-bsd
+	;;
     CRAY*Y-MP:*:*:*)
-	echo ymp-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
-	exit ;;
+	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+	GUESS=ymp-cray-unicos$CRAY_REL
+	;;
     CRAY*[A-Z]90:*:*:*)
 	echo "$UNAME_MACHINE"-cray-unicos"$UNAME_RELEASE" \
 	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
@@ -809,103 +855,129 @@
 	      -e 's/\.[^.]*$/.X/'
 	exit ;;
     CRAY*TS:*:*:*)
-	echo t90-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
-	exit ;;
+	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+	GUESS=t90-cray-unicos$CRAY_REL
+	;;
     CRAY*T3E:*:*:*)
-	echo alphaev5-cray-unicosmk"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
-	exit ;;
+	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+	GUESS=alphaev5-cray-unicosmk$CRAY_REL
+	;;
     CRAY*SV1:*:*:*)
-	echo sv1-cray-unicos"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
-	exit ;;
+	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+	GUESS=sv1-cray-unicos$CRAY_REL
+	;;
     *:UNICOS/mp:*:*)
-	echo craynv-cray-unicosmp"$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'
-	exit ;;
+	CRAY_REL=`echo "$UNAME_RELEASE" | sed -e 's/\.[^.]*$/.X/'`
+	GUESS=craynv-cray-unicosmp$CRAY_REL
+	;;
     F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
 	FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
 	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
 	FUJITSU_REL=`echo "$UNAME_RELEASE" | sed -e 's/ /_/'`
-	echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
-	exit ;;
+	GUESS=${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
+	;;
     5000:UNIX_System_V:4.*:*)
 	FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
 	FUJITSU_REL=`echo "$UNAME_RELEASE" | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
-	echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
-	exit ;;
+	GUESS=sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}
+	;;
     i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
-	echo "$UNAME_MACHINE"-pc-bsdi"$UNAME_RELEASE"
-	exit ;;
+	GUESS=$UNAME_MACHINE-pc-bsdi$UNAME_RELEASE
+	;;
     sparc*:BSD/OS:*:*)
-	echo sparc-unknown-bsdi"$UNAME_RELEASE"
-	exit ;;
+	GUESS=sparc-unknown-bsdi$UNAME_RELEASE
+	;;
     *:BSD/OS:*:*)
-	echo "$UNAME_MACHINE"-unknown-bsdi"$UNAME_RELEASE"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-bsdi$UNAME_RELEASE
+	;;
+    arm:FreeBSD:*:*)
+	UNAME_PROCESSOR=`uname -p`
+	set_cc_for_build
+	if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+	    | grep -q __ARM_PCS_VFP
+	then
+	    FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+	    GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabi
+	else
+	    FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+	    GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL-gnueabihf
+	fi
+	;;
     *:FreeBSD:*:*)
 	UNAME_PROCESSOR=`/usr/bin/uname -p`
-	case "$UNAME_PROCESSOR" in
+	case $UNAME_PROCESSOR in
 	    amd64)
 		UNAME_PROCESSOR=x86_64 ;;
 	    i386)
 		UNAME_PROCESSOR=i586 ;;
 	esac
-	echo "$UNAME_PROCESSOR"-unknown-freebsd"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
-	exit ;;
+	FREEBSD_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+	GUESS=$UNAME_PROCESSOR-unknown-freebsd$FREEBSD_REL
+	;;
     i*:CYGWIN*:*)
-	echo "$UNAME_MACHINE"-pc-cygwin
-	exit ;;
+	GUESS=$UNAME_MACHINE-pc-cygwin
+	;;
     *:MINGW64*:*)
-	echo "$UNAME_MACHINE"-pc-mingw64
-	exit ;;
+	GUESS=$UNAME_MACHINE-pc-mingw64
+	;;
     *:MINGW*:*)
-	echo "$UNAME_MACHINE"-pc-mingw32
-	exit ;;
+	GUESS=$UNAME_MACHINE-pc-mingw32
+	;;
     *:MSYS*:*)
-	echo "$UNAME_MACHINE"-pc-msys
-	exit ;;
+	GUESS=$UNAME_MACHINE-pc-msys
+	;;
     i*:PW*:*)
-	echo "$UNAME_MACHINE"-pc-pw32
-	exit ;;
+	GUESS=$UNAME_MACHINE-pc-pw32
+	;;
+    *:SerenityOS:*:*)
+        GUESS=$UNAME_MACHINE-pc-serenity
+        ;;
     *:Interix*:*)
-	case "$UNAME_MACHINE" in
+	case $UNAME_MACHINE in
 	    x86)
-		echo i586-pc-interix"$UNAME_RELEASE"
-		exit ;;
+		GUESS=i586-pc-interix$UNAME_RELEASE
+		;;
 	    authenticamd | genuineintel | EM64T)
-		echo x86_64-unknown-interix"$UNAME_RELEASE"
-		exit ;;
+		GUESS=x86_64-unknown-interix$UNAME_RELEASE
+		;;
 	    IA64)
-		echo ia64-unknown-interix"$UNAME_RELEASE"
-		exit ;;
+		GUESS=ia64-unknown-interix$UNAME_RELEASE
+		;;
 	esac ;;
     i*:UWIN*:*)
-	echo "$UNAME_MACHINE"-pc-uwin
-	exit ;;
+	GUESS=$UNAME_MACHINE-pc-uwin
+	;;
     amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
-	echo x86_64-unknown-cygwin
-	exit ;;
+	GUESS=x86_64-pc-cygwin
+	;;
     prep*:SunOS:5.*:*)
-	echo powerpcle-unknown-solaris2"`echo "$UNAME_RELEASE"|sed -e 's/[^.]*//'`"
-	exit ;;
+	SUN_REL=`echo "$UNAME_RELEASE" | sed -e 's/[^.]*//'`
+	GUESS=powerpcle-unknown-solaris2$SUN_REL
+	;;
     *:GNU:*:*)
 	# the GNU system
-	echo "`echo "$UNAME_MACHINE"|sed -e 's,[-/].*$,,'`-unknown-$LIBC`echo "$UNAME_RELEASE"|sed -e 's,/.*$,,'`"
-	exit ;;
+	GNU_ARCH=`echo "$UNAME_MACHINE" | sed -e 's,[-/].*$,,'`
+	GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's,/.*$,,'`
+	GUESS=$GNU_ARCH-unknown-$LIBC$GNU_REL
+	;;
     *:GNU/*:*:*)
 	# other systems with GNU libc and userland
-	echo "$UNAME_MACHINE-unknown-`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`-$LIBC"
-	exit ;;
-    i*86:Minix:*:*)
-	echo "$UNAME_MACHINE"-pc-minix
-	exit ;;
+	GNU_SYS=`echo "$UNAME_SYSTEM" | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"`
+	GNU_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+	GUESS=$UNAME_MACHINE-unknown-$GNU_SYS$GNU_REL-$LIBC
+	;;
+    *:Minix:*:*)
+	GUESS=$UNAME_MACHINE-unknown-minix
+	;;
     aarch64:Linux:*:*)
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     aarch64_be:Linux:*:*)
 	UNAME_MACHINE=aarch64_be
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     alpha:Linux:*:*)
-	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' /proc/cpuinfo 2>/dev/null` in
 	  EV5)   UNAME_MACHINE=alphaev5 ;;
 	  EV56)  UNAME_MACHINE=alphaev56 ;;
 	  PCA56) UNAME_MACHINE=alphapca56 ;;
@@ -916,187 +988,225 @@
 	esac
 	objdump --private-headers /bin/sh | grep -q ld.so.1
 	if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
-    arc:Linux:*:* | arceb:Linux:*:*)
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
+    arc:Linux:*:* | arceb:Linux:*:* | arc32:Linux:*:* | arc64:Linux:*:*)
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     arm*:Linux:*:*)
-	eval "$set_cc_for_build"
+	set_cc_for_build
 	if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
 	    | grep -q __ARM_EABI__
 	then
-	    echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
+	    GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
 	else
 	    if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
 		| grep -q __ARM_PCS_VFP
 	    then
-		echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabi
+		GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabi
 	    else
-		echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"eabihf
+		GUESS=$UNAME_MACHINE-unknown-linux-${LIBC}eabihf
 	    fi
 	fi
-	exit ;;
+	;;
     avr32*:Linux:*:*)
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     cris:Linux:*:*)
-	echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-axis-linux-$LIBC
+	;;
     crisv32:Linux:*:*)
-	echo "$UNAME_MACHINE"-axis-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-axis-linux-$LIBC
+	;;
     e2k:Linux:*:*)
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     frv:Linux:*:*)
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     hexagon:Linux:*:*)
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     i*86:Linux:*:*)
-	echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-pc-linux-$LIBC
+	;;
     ia64:Linux:*:*)
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     k1om:Linux:*:*)
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
+    loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*)
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     m32r*:Linux:*:*)
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     m68*:Linux:*:*)
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     mips:Linux:*:* | mips64:Linux:*:*)
-	eval "$set_cc_for_build"
+	set_cc_for_build
+	IS_GLIBC=0
+	test x"${LIBC}" = xgnu && IS_GLIBC=1
 	sed 's/^	//' << EOF > "$dummy.c"
 	#undef CPU
-	#undef ${UNAME_MACHINE}
-	#undef ${UNAME_MACHINE}el
+	#undef mips
+	#undef mipsel
+	#undef mips64
+	#undef mips64el
+	#if ${IS_GLIBC} && defined(_ABI64)
+	LIBCABI=gnuabi64
+	#else
+	#if ${IS_GLIBC} && defined(_ABIN32)
+	LIBCABI=gnuabin32
+	#else
+	LIBCABI=${LIBC}
+	#endif
+	#endif
+
+	#if ${IS_GLIBC} && defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
+	CPU=mipsisa64r6
+	#else
+	#if ${IS_GLIBC} && !defined(__mips64) && defined(__mips_isa_rev) && __mips_isa_rev>=6
+	CPU=mipsisa32r6
+	#else
+	#if defined(__mips64)
+	CPU=mips64
+	#else
+	CPU=mips
+	#endif
+	#endif
+	#endif
+
 	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
-	CPU=${UNAME_MACHINE}el
+	MIPS_ENDIAN=el
 	#else
 	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
-	CPU=${UNAME_MACHINE}
+	MIPS_ENDIAN=
 	#else
-	CPU=
+	MIPS_ENDIAN=
 	#endif
 	#endif
 EOF
-	eval "`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU'`"
-	test "x$CPU" != x && { echo "$CPU-unknown-linux-$LIBC"; exit; }
+	cc_set_vars=`$CC_FOR_BUILD -E "$dummy.c" 2>/dev/null | grep '^CPU\|^MIPS_ENDIAN\|^LIBCABI'`
+	eval "$cc_set_vars"
+	test "x$CPU" != x && { echo "$CPU${MIPS_ENDIAN}-unknown-linux-$LIBCABI"; exit; }
 	;;
     mips64el:Linux:*:*)
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     openrisc*:Linux:*:*)
-	echo or1k-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=or1k-unknown-linux-$LIBC
+	;;
     or32:Linux:*:* | or1k*:Linux:*:*)
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     padre:Linux:*:*)
-	echo sparc-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=sparc-unknown-linux-$LIBC
+	;;
     parisc64:Linux:*:* | hppa64:Linux:*:*)
-	echo hppa64-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=hppa64-unknown-linux-$LIBC
+	;;
     parisc:Linux:*:* | hppa:Linux:*:*)
 	# Look for CPU level
 	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
-	  PA7*) echo hppa1.1-unknown-linux-"$LIBC" ;;
-	  PA8*) echo hppa2.0-unknown-linux-"$LIBC" ;;
-	  *)    echo hppa-unknown-linux-"$LIBC" ;;
+	  PA7*) GUESS=hppa1.1-unknown-linux-$LIBC ;;
+	  PA8*) GUESS=hppa2.0-unknown-linux-$LIBC ;;
+	  *)    GUESS=hppa-unknown-linux-$LIBC ;;
 	esac
-	exit ;;
+	;;
     ppc64:Linux:*:*)
-	echo powerpc64-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=powerpc64-unknown-linux-$LIBC
+	;;
     ppc:Linux:*:*)
-	echo powerpc-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=powerpc-unknown-linux-$LIBC
+	;;
     ppc64le:Linux:*:*)
-	echo powerpc64le-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=powerpc64le-unknown-linux-$LIBC
+	;;
     ppcle:Linux:*:*)
-	echo powerpcle-unknown-linux-"$LIBC"
-	exit ;;
-    riscv32:Linux:*:* | riscv64:Linux:*:*)
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=powerpcle-unknown-linux-$LIBC
+	;;
+    riscv32:Linux:*:* | riscv32be:Linux:*:* | riscv64:Linux:*:* | riscv64be:Linux:*:*)
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     s390:Linux:*:* | s390x:Linux:*:*)
-	echo "$UNAME_MACHINE"-ibm-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-ibm-linux-$LIBC
+	;;
     sh64*:Linux:*:*)
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     sh*:Linux:*:*)
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     sparc:Linux:*:* | sparc64:Linux:*:*)
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     tile*:Linux:*:*)
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     vax:Linux:*:*)
-	echo "$UNAME_MACHINE"-dec-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-dec-linux-$LIBC
+	;;
     x86_64:Linux:*:*)
-	if objdump -f /bin/sh | grep -q elf32-x86-64; then
-	    echo "$UNAME_MACHINE"-pc-linux-"$LIBC"x32
-	else
-	    echo "$UNAME_MACHINE"-pc-linux-"$LIBC"
+	set_cc_for_build
+	LIBCABI=$LIBC
+	if test "$CC_FOR_BUILD" != no_compiler_found; then
+	    if (echo '#ifdef __ILP32__'; echo IS_X32; echo '#endif') | \
+		(CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+		grep IS_X32 >/dev/null
+	    then
+		LIBCABI=${LIBC}x32
+	    fi
 	fi
-	exit ;;
+	GUESS=$UNAME_MACHINE-pc-linux-$LIBCABI
+	;;
     xtensa*:Linux:*:*)
-	echo "$UNAME_MACHINE"-unknown-linux-"$LIBC"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
+	;;
     i*86:DYNIX/ptx:4*:*)
 	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
 	# earlier versions are messed up and put the nodename in both
 	# sysname and nodename.
-	echo i386-sequent-sysv4
-	exit ;;
+	GUESS=i386-sequent-sysv4
+	;;
     i*86:UNIX_SV:4.2MP:2.*)
 	# Unixware is an offshoot of SVR4, but it has its own version
 	# number series starting with 2...
 	# I am not positive that other SVR4 systems won't match this,
 	# I just have to hope.  -- rms.
 	# Use sysv4.2uw... so that sysv4* matches it.
-	echo "$UNAME_MACHINE"-pc-sysv4.2uw"$UNAME_VERSION"
-	exit ;;
+	GUESS=$UNAME_MACHINE-pc-sysv4.2uw$UNAME_VERSION
+	;;
     i*86:OS/2:*:*)
 	# If we were able to find `uname', then EMX Unix compatibility
 	# is probably installed.
-	echo "$UNAME_MACHINE"-pc-os2-emx
-	exit ;;
+	GUESS=$UNAME_MACHINE-pc-os2-emx
+	;;
     i*86:XTS-300:*:STOP)
-	echo "$UNAME_MACHINE"-unknown-stop
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-stop
+	;;
     i*86:atheos:*:*)
-	echo "$UNAME_MACHINE"-unknown-atheos
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-atheos
+	;;
     i*86:syllable:*:*)
-	echo "$UNAME_MACHINE"-pc-syllable
-	exit ;;
+	GUESS=$UNAME_MACHINE-pc-syllable
+	;;
     i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
-	echo i386-unknown-lynxos"$UNAME_RELEASE"
-	exit ;;
+	GUESS=i386-unknown-lynxos$UNAME_RELEASE
+	;;
     i*86:*DOS:*:*)
-	echo "$UNAME_MACHINE"-pc-msdosdjgpp
-	exit ;;
+	GUESS=$UNAME_MACHINE-pc-msdosdjgpp
+	;;
     i*86:*:4.*:*)
 	UNAME_REL=`echo "$UNAME_RELEASE" | sed 's/\/MP$//'`
 	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
-		echo "$UNAME_MACHINE"-univel-sysv"$UNAME_REL"
+		GUESS=$UNAME_MACHINE-univel-sysv$UNAME_REL
 	else
-		echo "$UNAME_MACHINE"-pc-sysv"$UNAME_REL"
+		GUESS=$UNAME_MACHINE-pc-sysv$UNAME_REL
 	fi
-	exit ;;
+	;;
     i*86:*:5:[678]*)
 	# UnixWare 7.x, OpenUNIX and OpenServer 6.
 	case `/bin/uname -X | grep "^Machine"` in
@@ -1104,12 +1214,12 @@
 	    *Pentium)	     UNAME_MACHINE=i586 ;;
 	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
 	esac
-	echo "$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}{$UNAME_VERSION}"
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	;;
     i*86:*:3.2:*)
 	if test -f /usr/options/cb.name; then
 		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
-		echo "$UNAME_MACHINE"-pc-isc"$UNAME_REL"
+		GUESS=$UNAME_MACHINE-pc-isc$UNAME_REL
 	elif /bin/uname -X 2>/dev/null >/dev/null ; then
 		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
 		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
@@ -1119,11 +1229,11 @@
 			&& UNAME_MACHINE=i686
 		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
 			&& UNAME_MACHINE=i686
-		echo "$UNAME_MACHINE"-pc-sco"$UNAME_REL"
+		GUESS=$UNAME_MACHINE-pc-sco$UNAME_REL
 	else
-		echo "$UNAME_MACHINE"-pc-sysv32
+		GUESS=$UNAME_MACHINE-pc-sysv32
 	fi
-	exit ;;
+	;;
     pc:*:*:*)
 	# Left here for compatibility:
 	# uname -m prints for DJGPP always 'pc', but it prints nothing about
@@ -1131,31 +1241,31 @@
 	# Note: whatever this is, it MUST be the same as what config.sub
 	# prints for the "djgpp" host, or else GDB configure will decide that
 	# this is a cross-build.
-	echo i586-pc-msdosdjgpp
-	exit ;;
+	GUESS=i586-pc-msdosdjgpp
+	;;
     Intel:Mach:3*:*)
-	echo i386-pc-mach3
-	exit ;;
+	GUESS=i386-pc-mach3
+	;;
     paragon:*:*:*)
-	echo i860-intel-osf1
-	exit ;;
+	GUESS=i860-intel-osf1
+	;;
     i860:*:4.*:*) # i860-SVR4
 	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
-	  echo i860-stardent-sysv"$UNAME_RELEASE" # Stardent Vistra i860-SVR4
+	  GUESS=i860-stardent-sysv$UNAME_RELEASE    # Stardent Vistra i860-SVR4
 	else # Add other i860-SVR4 vendors below as they are discovered.
-	  echo i860-unknown-sysv"$UNAME_RELEASE"  # Unknown i860-SVR4
+	  GUESS=i860-unknown-sysv$UNAME_RELEASE     # Unknown i860-SVR4
 	fi
-	exit ;;
+	;;
     mini*:CTIX:SYS*5:*)
 	# "miniframe"
-	echo m68010-convergent-sysv
-	exit ;;
+	GUESS=m68010-convergent-sysv
+	;;
     mc68k:UNIX:SYSTEM5:3.51m)
-	echo m68k-convergent-sysv
-	exit ;;
+	GUESS=m68k-convergent-sysv
+	;;
     M680?0:D-NIX:5.3:*)
-	echo m68k-diab-dnix
-	exit ;;
+	GUESS=m68k-diab-dnix
+	;;
     M68*:*:R3V[5678]*:*)
 	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
     3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
@@ -1180,249 +1290,404 @@
 	/bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
 	    && { echo i586-ncr-sysv4.3"$OS_REL"; exit; } ;;
     m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
-	echo m68k-unknown-lynxos"$UNAME_RELEASE"
-	exit ;;
+	GUESS=m68k-unknown-lynxos$UNAME_RELEASE
+	;;
     mc68030:UNIX_System_V:4.*:*)
-	echo m68k-atari-sysv4
-	exit ;;
+	GUESS=m68k-atari-sysv4
+	;;
     TSUNAMI:LynxOS:2.*:*)
-	echo sparc-unknown-lynxos"$UNAME_RELEASE"
-	exit ;;
+	GUESS=sparc-unknown-lynxos$UNAME_RELEASE
+	;;
     rs6000:LynxOS:2.*:*)
-	echo rs6000-unknown-lynxos"$UNAME_RELEASE"
-	exit ;;
+	GUESS=rs6000-unknown-lynxos$UNAME_RELEASE
+	;;
     PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
-	echo powerpc-unknown-lynxos"$UNAME_RELEASE"
-	exit ;;
+	GUESS=powerpc-unknown-lynxos$UNAME_RELEASE
+	;;
     SM[BE]S:UNIX_SV:*:*)
-	echo mips-dde-sysv"$UNAME_RELEASE"
-	exit ;;
+	GUESS=mips-dde-sysv$UNAME_RELEASE
+	;;
     RM*:ReliantUNIX-*:*:*)
-	echo mips-sni-sysv4
-	exit ;;
+	GUESS=mips-sni-sysv4
+	;;
     RM*:SINIX-*:*:*)
-	echo mips-sni-sysv4
-	exit ;;
+	GUESS=mips-sni-sysv4
+	;;
     *:SINIX-*:*:*)
 	if uname -p 2>/dev/null >/dev/null ; then
 		UNAME_MACHINE=`(uname -p) 2>/dev/null`
-		echo "$UNAME_MACHINE"-sni-sysv4
+		GUESS=$UNAME_MACHINE-sni-sysv4
 	else
-		echo ns32k-sni-sysv
+		GUESS=ns32k-sni-sysv
 	fi
-	exit ;;
+	;;
     PENTIUM:*:4.0*:*)	# Unisys `ClearPath HMP IX 4000' SVR4/MP effort
 			# says <Richard.M.Bartel@ccMail.Census.GOV>
-	echo i586-unisys-sysv4
-	exit ;;
+	GUESS=i586-unisys-sysv4
+	;;
     *:UNIX_System_V:4*:FTX*)
 	# From Gerald Hewes <hewes@openmarket.com>.
 	# How about differentiating between stratus architectures? -djm
-	echo hppa1.1-stratus-sysv4
-	exit ;;
+	GUESS=hppa1.1-stratus-sysv4
+	;;
     *:*:*:FTX*)
 	# From seanf@swdc.stratus.com.
-	echo i860-stratus-sysv4
-	exit ;;
+	GUESS=i860-stratus-sysv4
+	;;
     i*86:VOS:*:*)
 	# From Paul.Green@stratus.com.
-	echo "$UNAME_MACHINE"-stratus-vos
-	exit ;;
+	GUESS=$UNAME_MACHINE-stratus-vos
+	;;
     *:VOS:*:*)
 	# From Paul.Green@stratus.com.
-	echo hppa1.1-stratus-vos
-	exit ;;
+	GUESS=hppa1.1-stratus-vos
+	;;
     mc68*:A/UX:*:*)
-	echo m68k-apple-aux"$UNAME_RELEASE"
-	exit ;;
+	GUESS=m68k-apple-aux$UNAME_RELEASE
+	;;
     news*:NEWS-OS:6*:*)
-	echo mips-sony-newsos6
-	exit ;;
+	GUESS=mips-sony-newsos6
+	;;
     R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
-	if [ -d /usr/nec ]; then
-		echo mips-nec-sysv"$UNAME_RELEASE"
+	if test -d /usr/nec; then
+		GUESS=mips-nec-sysv$UNAME_RELEASE
 	else
-		echo mips-unknown-sysv"$UNAME_RELEASE"
+		GUESS=mips-unknown-sysv$UNAME_RELEASE
 	fi
-	exit ;;
+	;;
     BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
-	echo powerpc-be-beos
-	exit ;;
+	GUESS=powerpc-be-beos
+	;;
     BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
-	echo powerpc-apple-beos
-	exit ;;
+	GUESS=powerpc-apple-beos
+	;;
     BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
-	echo i586-pc-beos
-	exit ;;
+	GUESS=i586-pc-beos
+	;;
     BePC:Haiku:*:*)	# Haiku running on Intel PC compatible.
-	echo i586-pc-haiku
-	exit ;;
+	GUESS=i586-pc-haiku
+	;;
     x86_64:Haiku:*:*)
-	echo x86_64-unknown-haiku
-	exit ;;
+	GUESS=x86_64-unknown-haiku
+	;;
     SX-4:SUPER-UX:*:*)
-	echo sx4-nec-superux"$UNAME_RELEASE"
-	exit ;;
+	GUESS=sx4-nec-superux$UNAME_RELEASE
+	;;
     SX-5:SUPER-UX:*:*)
-	echo sx5-nec-superux"$UNAME_RELEASE"
-	exit ;;
+	GUESS=sx5-nec-superux$UNAME_RELEASE
+	;;
     SX-6:SUPER-UX:*:*)
-	echo sx6-nec-superux"$UNAME_RELEASE"
-	exit ;;
+	GUESS=sx6-nec-superux$UNAME_RELEASE
+	;;
     SX-7:SUPER-UX:*:*)
-	echo sx7-nec-superux"$UNAME_RELEASE"
-	exit ;;
+	GUESS=sx7-nec-superux$UNAME_RELEASE
+	;;
     SX-8:SUPER-UX:*:*)
-	echo sx8-nec-superux"$UNAME_RELEASE"
-	exit ;;
+	GUESS=sx8-nec-superux$UNAME_RELEASE
+	;;
     SX-8R:SUPER-UX:*:*)
-	echo sx8r-nec-superux"$UNAME_RELEASE"
-	exit ;;
+	GUESS=sx8r-nec-superux$UNAME_RELEASE
+	;;
     SX-ACE:SUPER-UX:*:*)
-	echo sxace-nec-superux"$UNAME_RELEASE"
-	exit ;;
+	GUESS=sxace-nec-superux$UNAME_RELEASE
+	;;
     Power*:Rhapsody:*:*)
-	echo powerpc-apple-rhapsody"$UNAME_RELEASE"
-	exit ;;
+	GUESS=powerpc-apple-rhapsody$UNAME_RELEASE
+	;;
     *:Rhapsody:*:*)
-	echo "$UNAME_MACHINE"-apple-rhapsody"$UNAME_RELEASE"
-	exit ;;
+	GUESS=$UNAME_MACHINE-apple-rhapsody$UNAME_RELEASE
+	;;
+    arm64:Darwin:*:*)
+	GUESS=aarch64-apple-darwin$UNAME_RELEASE
+	;;
     *:Darwin:*:*)
-	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
-	eval "$set_cc_for_build"
-	if test "$UNAME_PROCESSOR" = unknown ; then
-	    UNAME_PROCESSOR=powerpc
+	UNAME_PROCESSOR=`uname -p`
+	case $UNAME_PROCESSOR in
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	if command -v xcode-select > /dev/null 2> /dev/null && \
+		! xcode-select --print-path > /dev/null 2> /dev/null ; then
+	    # Avoid executing cc if there is no toolchain installed as
+	    # cc will be a stub that puts up a graphical alert
+	    # prompting the user to install developer tools.
+	    CC_FOR_BUILD=no_compiler_found
+	else
+	    set_cc_for_build
 	fi
-	if test "`echo "$UNAME_RELEASE" | sed -e 's/\..*//'`" -le 10 ; then
-	    if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
-		if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-		       (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
-		       grep IS_64BIT_ARCH >/dev/null
-		then
-		    case $UNAME_PROCESSOR in
-			i386) UNAME_PROCESSOR=x86_64 ;;
-			powerpc) UNAME_PROCESSOR=powerpc64 ;;
-		    esac
-		fi
-		# On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
-		if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
-		       (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
-		       grep IS_PPC >/dev/null
-		then
-		    UNAME_PROCESSOR=powerpc
-		fi
+	if test "$CC_FOR_BUILD" != no_compiler_found; then
+	    if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+		   (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+		   grep IS_64BIT_ARCH >/dev/null
+	    then
+		case $UNAME_PROCESSOR in
+		    i386) UNAME_PROCESSOR=x86_64 ;;
+		    powerpc) UNAME_PROCESSOR=powerpc64 ;;
+		esac
+	    fi
+	    # On 10.4-10.6 one might compile for PowerPC via gcc -arch ppc
+	    if (echo '#ifdef __POWERPC__'; echo IS_PPC; echo '#endif') | \
+		   (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
+		   grep IS_PPC >/dev/null
+	    then
+		UNAME_PROCESSOR=powerpc
 	    fi
 	elif test "$UNAME_PROCESSOR" = i386 ; then
-	    # Avoid executing cc on OS X 10.9, as it ships with a stub
-	    # that puts up a graphical alert prompting to install
-	    # developer tools.  Any system running Mac OS X 10.7 or
-	    # later (Darwin 11 and later) is required to have a 64-bit
-	    # processor. This is not true of the ARM version of Darwin
-	    # that Apple uses in portable devices.
-	    UNAME_PROCESSOR=x86_64
+	    # uname -m returns i386 or x86_64
+	    UNAME_PROCESSOR=$UNAME_MACHINE
 	fi
-	echo "$UNAME_PROCESSOR"-apple-darwin"$UNAME_RELEASE"
-	exit ;;
+	GUESS=$UNAME_PROCESSOR-apple-darwin$UNAME_RELEASE
+	;;
     *:procnto*:*:* | *:QNX:[0123456789]*:*)
 	UNAME_PROCESSOR=`uname -p`
 	if test "$UNAME_PROCESSOR" = x86; then
 		UNAME_PROCESSOR=i386
 		UNAME_MACHINE=pc
 	fi
-	echo "$UNAME_PROCESSOR"-"$UNAME_MACHINE"-nto-qnx"$UNAME_RELEASE"
-	exit ;;
+	GUESS=$UNAME_PROCESSOR-$UNAME_MACHINE-nto-qnx$UNAME_RELEASE
+	;;
     *:QNX:*:4*)
-	echo i386-pc-qnx
-	exit ;;
+	GUESS=i386-pc-qnx
+	;;
     NEO-*:NONSTOP_KERNEL:*:*)
-	echo neo-tandem-nsk"$UNAME_RELEASE"
-	exit ;;
+	GUESS=neo-tandem-nsk$UNAME_RELEASE
+	;;
     NSE-*:NONSTOP_KERNEL:*:*)
-	echo nse-tandem-nsk"$UNAME_RELEASE"
-	exit ;;
+	GUESS=nse-tandem-nsk$UNAME_RELEASE
+	;;
     NSR-*:NONSTOP_KERNEL:*:*)
-	echo nsr-tandem-nsk"$UNAME_RELEASE"
-	exit ;;
+	GUESS=nsr-tandem-nsk$UNAME_RELEASE
+	;;
     NSV-*:NONSTOP_KERNEL:*:*)
-	echo nsv-tandem-nsk"$UNAME_RELEASE"
-	exit ;;
+	GUESS=nsv-tandem-nsk$UNAME_RELEASE
+	;;
     NSX-*:NONSTOP_KERNEL:*:*)
-	echo nsx-tandem-nsk"$UNAME_RELEASE"
-	exit ;;
+	GUESS=nsx-tandem-nsk$UNAME_RELEASE
+	;;
     *:NonStop-UX:*:*)
-	echo mips-compaq-nonstopux
-	exit ;;
+	GUESS=mips-compaq-nonstopux
+	;;
     BS2000:POSIX*:*:*)
-	echo bs2000-siemens-sysv
-	exit ;;
+	GUESS=bs2000-siemens-sysv
+	;;
     DS/*:UNIX_System_V:*:*)
-	echo "$UNAME_MACHINE"-"$UNAME_SYSTEM"-"$UNAME_RELEASE"
-	exit ;;
+	GUESS=$UNAME_MACHINE-$UNAME_SYSTEM-$UNAME_RELEASE
+	;;
     *:Plan9:*:*)
 	# "uname -m" is not consistent, so use $cputype instead. 386
 	# is converted to i386 for consistency with other x86
 	# operating systems.
-	if test "$cputype" = 386; then
+	if test "${cputype-}" = 386; then
 	    UNAME_MACHINE=i386
-	else
-	    UNAME_MACHINE="$cputype"
+	elif test "x${cputype-}" != x; then
+	    UNAME_MACHINE=$cputype
 	fi
-	echo "$UNAME_MACHINE"-unknown-plan9
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-plan9
+	;;
     *:TOPS-10:*:*)
-	echo pdp10-unknown-tops10
-	exit ;;
+	GUESS=pdp10-unknown-tops10
+	;;
     *:TENEX:*:*)
-	echo pdp10-unknown-tenex
-	exit ;;
+	GUESS=pdp10-unknown-tenex
+	;;
     KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
-	echo pdp10-dec-tops20
-	exit ;;
+	GUESS=pdp10-dec-tops20
+	;;
     XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
-	echo pdp10-xkl-tops20
-	exit ;;
+	GUESS=pdp10-xkl-tops20
+	;;
     *:TOPS-20:*:*)
-	echo pdp10-unknown-tops20
-	exit ;;
+	GUESS=pdp10-unknown-tops20
+	;;
     *:ITS:*:*)
-	echo pdp10-unknown-its
-	exit ;;
+	GUESS=pdp10-unknown-its
+	;;
     SEI:*:*:SEIUX)
-	echo mips-sei-seiux"$UNAME_RELEASE"
-	exit ;;
+	GUESS=mips-sei-seiux$UNAME_RELEASE
+	;;
     *:DragonFly:*:*)
-	echo "$UNAME_MACHINE"-unknown-dragonfly"`echo "$UNAME_RELEASE"|sed -e 's/[-(].*//'`"
-	exit ;;
+	DRAGONFLY_REL=`echo "$UNAME_RELEASE" | sed -e 's/[-(].*//'`
+	GUESS=$UNAME_MACHINE-unknown-dragonfly$DRAGONFLY_REL
+	;;
     *:*VMS:*:*)
 	UNAME_MACHINE=`(uname -p) 2>/dev/null`
-	case "$UNAME_MACHINE" in
-	    A*) echo alpha-dec-vms ; exit ;;
-	    I*) echo ia64-dec-vms ; exit ;;
-	    V*) echo vax-dec-vms ; exit ;;
+	case $UNAME_MACHINE in
+	    A*) GUESS=alpha-dec-vms ;;
+	    I*) GUESS=ia64-dec-vms ;;
+	    V*) GUESS=vax-dec-vms ;;
 	esac ;;
     *:XENIX:*:SysV)
-	echo i386-pc-xenix
-	exit ;;
+	GUESS=i386-pc-xenix
+	;;
     i*86:skyos:*:*)
-	echo "$UNAME_MACHINE"-pc-skyos"`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`"
-	exit ;;
+	SKYOS_REL=`echo "$UNAME_RELEASE" | sed -e 's/ .*$//'`
+	GUESS=$UNAME_MACHINE-pc-skyos$SKYOS_REL
+	;;
     i*86:rdos:*:*)
-	echo "$UNAME_MACHINE"-pc-rdos
-	exit ;;
-    i*86:AROS:*:*)
-	echo "$UNAME_MACHINE"-pc-aros
-	exit ;;
+	GUESS=$UNAME_MACHINE-pc-rdos
+	;;
+    i*86:Fiwix:*:*)
+	GUESS=$UNAME_MACHINE-pc-fiwix
+	;;
+    *:AROS:*:*)
+	GUESS=$UNAME_MACHINE-unknown-aros
+	;;
     x86_64:VMkernel:*:*)
-	echo "$UNAME_MACHINE"-unknown-esx
-	exit ;;
+	GUESS=$UNAME_MACHINE-unknown-esx
+	;;
     amd64:Isilon\ OneFS:*:*)
-	echo x86_64-unknown-onefs
-	exit ;;
+	GUESS=x86_64-unknown-onefs
+	;;
+    *:Unleashed:*:*)
+	GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
+	;;
 esac
 
+# Do we have a guess based on uname results?
+if test "x$GUESS" != x; then
+    echo "$GUESS"
+    exit
+fi
+
+# No uname command or uname output not recognized.
+set_cc_for_build
+cat > "$dummy.c" <<EOF
+#ifdef _SEQUENT_
+#include <sys/types.h>
+#include <sys/utsname.h>
+#endif
+#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
+#if defined (vax) || defined (__vax) || defined (__vax__) || defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
+#include <signal.h>
+#if defined(_SIZE_T_) || defined(SIGLOST)
+#include <sys/utsname.h>
+#endif
+#endif
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+  "4"
+#else
+  ""
+#endif
+  ); exit (0);
+#endif
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+  struct utsname un;
+
+  uname(&un);
+  if (strncmp(un.version, "V2", 2) == 0) {
+    printf ("i386-sequent-ptx2\n"); exit (0);
+  }
+  if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+    printf ("i386-sequent-ptx1\n"); exit (0);
+  }
+  printf ("i386-sequent-ptx\n"); exit (0);
+#endif
+
+#if defined (vax)
+#if !defined (ultrix)
+#include <sys/param.h>
+#if defined (BSD)
+#if BSD == 43
+  printf ("vax-dec-bsd4.3\n"); exit (0);
+#else
+#if BSD == 199006
+  printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#else
+  printf ("vax-dec-bsd\n"); exit (0);
+#endif
+#endif
+#else
+  printf ("vax-dec-bsd\n"); exit (0);
+#endif
+#else
+#if defined(_SIZE_T_) || defined(SIGLOST)
+  struct utsname un;
+  uname (&un);
+  printf ("vax-dec-ultrix%s\n", un.release); exit (0);
+#else
+  printf ("vax-dec-ultrix\n"); exit (0);
+#endif
+#endif
+#endif
+#if defined(ultrix) || defined(_ultrix) || defined(__ultrix) || defined(__ultrix__)
+#if defined(mips) || defined(__mips) || defined(__mips__) || defined(MIPS) || defined(__MIPS__)
+#if defined(_SIZE_T_) || defined(SIGLOST)
+  struct utsname *un;
+  uname (&un);
+  printf ("mips-dec-ultrix%s\n", un.release); exit (0);
+#else
+  printf ("mips-dec-ultrix\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o "$dummy" "$dummy.c" 2>/dev/null && SYSTEM_NAME=`"$dummy"` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+test -d /usr/apollo && { echo "$ISP-apollo-$SYSTYPE"; exit; }
+
 echo "$0: unable to guess system type" >&2
 
-case "$UNAME_MACHINE:$UNAME_SYSTEM" in
+case $UNAME_MACHINE:$UNAME_SYSTEM in
     mips:Linux | mips64:Linux)
 	# If we got here on MIPS GNU/Linux, output extra information.
 	cat >&2 <<EOF
@@ -1439,9 +1704,17 @@
 operating system you are using. If your script is old, overwrite *all*
 copies of config.guess and config.sub with the latest versions from:
 
-  https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess
+  https://git.savannah.gnu.org/cgit/config.git/plain/config.guess
 and
-  https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+  https://git.savannah.gnu.org/cgit/config.git/plain/config.sub
+EOF
+
+our_year=`echo $timestamp | sed 's,-.*,,'`
+thisyear=`date +%Y`
+# shellcheck disable=SC2003
+script_age=`expr "$thisyear" - "$our_year"`
+if test "$script_age" -lt 3 ; then
+   cat >&2 <<EOF
 
 If $0 has already been updated, send the following data and any
 information you think might be pertinent to config-patches@gnu.org to
@@ -1469,11 +1742,12 @@
 UNAME_SYSTEM  = "$UNAME_SYSTEM"
 UNAME_VERSION = "$UNAME_VERSION"
 EOF
+fi
 
 exit 1
 
 # Local variables:
-# eval: (add-hook 'write-file-functions 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "timestamp='"
 # time-stamp-format: "%:y-%02m-%02d"
 # time-stamp-end: "'"
diff --git a/Tools/config/config.sub b/Tools/config/config.sub
index 1d8e98b..dba16e8 100755
--- a/Tools/config/config.sub
+++ b/Tools/config/config.sub
@@ -1,12 +1,14 @@
 #! /bin/sh
 # Configuration validation subroutine script.
-#   Copyright 1992-2018 Free Software Foundation, Inc.
+#   Copyright 1992-2022 Free Software Foundation, Inc.
 
-timestamp='2018-02-22'
+# shellcheck disable=SC2006,SC2268 # see below for rationale
+
+timestamp='2022-01-03'
 
 # This file is free software; you can redistribute it and/or modify it
 # under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 3 of the License, or
+# the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 #
 # This program is distributed in the hope that it will be useful, but
@@ -33,7 +35,7 @@
 # Otherwise, we print the canonical config type on stdout and succeed.
 
 # You can get the latest version of this script from:
-# https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub
+# https://git.savannah.gnu.org/cgit/config.git/plain/config.sub
 
 # This file is supposed to be the same for all GNU packages
 # and recognize all the CPU types, system types and aliases
@@ -50,6 +52,13 @@
 #	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
 # It is wrong to echo any other type of specification.
 
+# The "shellcheck disable" line above the timestamp inhibits complaints
+# about features and limitations of the classic Bourne shell that were
+# superseded or lifted in POSIX.  However, this script identifies a wide
+# variety of pre-POSIX systems that do not have POSIX shells at all, and
+# even some reasonably current systems (Solaris 10 as case-in-point) still
+# have a pre-POSIX /bin/sh.
+
 me=`echo "$0" | sed -e 's,.*/,,'`
 
 usage="\
@@ -67,7 +76,7 @@
 version="\
 GNU config.sub ($timestamp)
 
-Copyright 1992-2018 Free Software Foundation, Inc.
+Copyright 1992-2022 Free Software Foundation, Inc.
 
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -89,7 +98,7 @@
     - )	# Use stdin as input.
        break ;;
     -* )
-       echo "$me: invalid option $1$help"
+       echo "$me: invalid option $1$help" >&2
        exit 1 ;;
 
     *local*)
@@ -110,1223 +119,1186 @@
     exit 1;;
 esac
 
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
-  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
-  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
-  knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
-  kopensolaris*-gnu* | cloudabi*-eabi* | \
-  storm-chaos* | os2-emx* | rtmk-nova*)
-    os=-$maybe_os
-    basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
-    ;;
-  android-linux)
-    os=-linux-android
-    basic_machine=`echo "$1" | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
-    ;;
-  *)
-    basic_machine=`echo "$1" | sed 's/-[^-]*$//'`
-    if [ "$basic_machine" != "$1" ]
-    then os=`echo "$1" | sed 's/.*-/-/'`
-    else os=; fi
-    ;;
-esac
+# Split fields of configuration type
+# shellcheck disable=SC2162
+saved_IFS=$IFS
+IFS="-" read field1 field2 field3 field4 <<EOF
+$1
+EOF
+IFS=$saved_IFS
 
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work.  We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
-	-sun*os*)
-		# Prevent following clause from handling this invalid input.
+# Separate into logical components for further validation
+case $1 in
+	*-*-*-*-*)
+		echo Invalid configuration \`"$1"\': more than four components >&2
+		exit 1
 		;;
-	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
-	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
-	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-	-apple | -axis | -knuth | -cray | -microblaze*)
-		os=
-		basic_machine=$1
+	*-*-*-*)
+		basic_machine=$field1-$field2
+		basic_os=$field3-$field4
 		;;
-	-bluegene*)
-		os=-cnk
+	*-*-*)
+		# Ambiguous whether COMPANY is present, or skipped and KERNEL-OS is two
+		# parts
+		maybe_os=$field2-$field3
+		case $maybe_os in
+			nto-qnx* | linux-* | uclinux-uclibc* \
+			| uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* \
+			| netbsd*-eabi* | kopensolaris*-gnu* | cloudabi*-eabi* \
+			| storm-chaos* | os2-emx* | rtmk-nova*)
+				basic_machine=$field1
+				basic_os=$maybe_os
+				;;
+			android-linux)
+				basic_machine=$field1-unknown
+				basic_os=linux-android
+				;;
+			*)
+				basic_machine=$field1-$field2
+				basic_os=$field3
+				;;
+		esac
 		;;
-	-sim | -cisco | -oki | -wec | -winbond)
-		os=
-		basic_machine=$1
+	*-*)
+		# A lone config we happen to match not fitting any pattern
+		case $field1-$field2 in
+			decstation-3100)
+				basic_machine=mips-dec
+				basic_os=
+				;;
+			*-*)
+				# Second component is usually, but not always the OS
+				case $field2 in
+					# Prevent following clause from handling this valid os
+					sun*os*)
+						basic_machine=$field1
+						basic_os=$field2
+						;;
+					zephyr*)
+						basic_machine=$field1-unknown
+						basic_os=$field2
+						;;
+					# Manufacturers
+					dec* | mips* | sequent* | encore* | pc533* | sgi* | sony* \
+					| att* | 7300* | 3300* | delta* | motorola* | sun[234]* \
+					| unicom* | ibm* | next | hp | isi* | apollo | altos* \
+					| convergent* | ncr* | news | 32* | 3600* | 3100* \
+					| hitachi* | c[123]* | convex* | sun | crds | omron* | dg \
+					| ultra | tti* | harris | dolphin | highlevel | gould \
+					| cbm | ns | masscomp | apple | axis | knuth | cray \
+					| microblaze* | sim | cisco \
+					| oki | wec | wrs | winbond)
+						basic_machine=$field1-$field2
+						basic_os=
+						;;
+					*)
+						basic_machine=$field1
+						basic_os=$field2
+						;;
+				esac
+			;;
+		esac
 		;;
-	-scout)
-		;;
-	-wrs)
-		os=-vxworks
-		basic_machine=$1
-		;;
-	-chorusos*)
-		os=-chorusos
-		basic_machine=$1
-		;;
-	-chorusrdb)
-		os=-chorusrdb
-		basic_machine=$1
-		;;
-	-hiux*)
-		os=-hiuxwe2
-		;;
-	-sco6)
-		os=-sco5v6
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco5)
-		os=-sco3.2v5
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco4)
-		os=-sco3.2v4
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco3.2.[4-9]*)
-		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco3.2v[4-9]*)
-		# Don't forget version if it is 3.2v4 or newer.
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco5v6*)
-		# Don't forget version if it is 3.2v4 or newer.
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-sco*)
-		os=-sco3.2v2
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-udk*)
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-isc)
-		os=-isc2.2
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-clix*)
-		basic_machine=clipper-intergraph
-		;;
-	-isc*)
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-pc/'`
-		;;
-	-lynx*178)
-		os=-lynxos178
-		;;
-	-lynx*5)
-		os=-lynxos5
-		;;
-	-lynx*)
-		os=-lynxos
-		;;
-	-ptx*)
-		basic_machine=`echo "$1" | sed -e 's/86-.*/86-sequent/'`
-		;;
-	-psos*)
-		os=-psos
-		;;
-	-mint | -mint[0-9]*)
-		basic_machine=m68k-atari
-		os=-mint
+	*)
+		# Convert single-component short-hands not valid as part of
+		# multi-component configurations.
+		case $field1 in
+			386bsd)
+				basic_machine=i386-pc
+				basic_os=bsd
+				;;
+			a29khif)
+				basic_machine=a29k-amd
+				basic_os=udi
+				;;
+			adobe68k)
+				basic_machine=m68010-adobe
+				basic_os=scout
+				;;
+			alliant)
+				basic_machine=fx80-alliant
+				basic_os=
+				;;
+			altos | altos3068)
+				basic_machine=m68k-altos
+				basic_os=
+				;;
+			am29k)
+				basic_machine=a29k-none
+				basic_os=bsd
+				;;
+			amdahl)
+				basic_machine=580-amdahl
+				basic_os=sysv
+				;;
+			amiga)
+				basic_machine=m68k-unknown
+				basic_os=
+				;;
+			amigaos | amigados)
+				basic_machine=m68k-unknown
+				basic_os=amigaos
+				;;
+			amigaunix | amix)
+				basic_machine=m68k-unknown
+				basic_os=sysv4
+				;;
+			apollo68)
+				basic_machine=m68k-apollo
+				basic_os=sysv
+				;;
+			apollo68bsd)
+				basic_machine=m68k-apollo
+				basic_os=bsd
+				;;
+			aros)
+				basic_machine=i386-pc
+				basic_os=aros
+				;;
+			aux)
+				basic_machine=m68k-apple
+				basic_os=aux
+				;;
+			balance)
+				basic_machine=ns32k-sequent
+				basic_os=dynix
+				;;
+			blackfin)
+				basic_machine=bfin-unknown
+				basic_os=linux
+				;;
+			cegcc)
+				basic_machine=arm-unknown
+				basic_os=cegcc
+				;;
+			convex-c1)
+				basic_machine=c1-convex
+				basic_os=bsd
+				;;
+			convex-c2)
+				basic_machine=c2-convex
+				basic_os=bsd
+				;;
+			convex-c32)
+				basic_machine=c32-convex
+				basic_os=bsd
+				;;
+			convex-c34)
+				basic_machine=c34-convex
+				basic_os=bsd
+				;;
+			convex-c38)
+				basic_machine=c38-convex
+				basic_os=bsd
+				;;
+			cray)
+				basic_machine=j90-cray
+				basic_os=unicos
+				;;
+			crds | unos)
+				basic_machine=m68k-crds
+				basic_os=
+				;;
+			da30)
+				basic_machine=m68k-da30
+				basic_os=
+				;;
+			decstation | pmax | pmin | dec3100 | decstatn)
+				basic_machine=mips-dec
+				basic_os=
+				;;
+			delta88)
+				basic_machine=m88k-motorola
+				basic_os=sysv3
+				;;
+			dicos)
+				basic_machine=i686-pc
+				basic_os=dicos
+				;;
+			djgpp)
+				basic_machine=i586-pc
+				basic_os=msdosdjgpp
+				;;
+			ebmon29k)
+				basic_machine=a29k-amd
+				basic_os=ebmon
+				;;
+			es1800 | OSE68k | ose68k | ose | OSE)
+				basic_machine=m68k-ericsson
+				basic_os=ose
+				;;
+			gmicro)
+				basic_machine=tron-gmicro
+				basic_os=sysv
+				;;
+			go32)
+				basic_machine=i386-pc
+				basic_os=go32
+				;;
+			h8300hms)
+				basic_machine=h8300-hitachi
+				basic_os=hms
+				;;
+			h8300xray)
+				basic_machine=h8300-hitachi
+				basic_os=xray
+				;;
+			h8500hms)
+				basic_machine=h8500-hitachi
+				basic_os=hms
+				;;
+			harris)
+				basic_machine=m88k-harris
+				basic_os=sysv3
+				;;
+			hp300 | hp300hpux)
+				basic_machine=m68k-hp
+				basic_os=hpux
+				;;
+			hp300bsd)
+				basic_machine=m68k-hp
+				basic_os=bsd
+				;;
+			hppaosf)
+				basic_machine=hppa1.1-hp
+				basic_os=osf
+				;;
+			hppro)
+				basic_machine=hppa1.1-hp
+				basic_os=proelf
+				;;
+			i386mach)
+				basic_machine=i386-mach
+				basic_os=mach
+				;;
+			isi68 | isi)
+				basic_machine=m68k-isi
+				basic_os=sysv
+				;;
+			m68knommu)
+				basic_machine=m68k-unknown
+				basic_os=linux
+				;;
+			magnum | m3230)
+				basic_machine=mips-mips
+				basic_os=sysv
+				;;
+			merlin)
+				basic_machine=ns32k-utek
+				basic_os=sysv
+				;;
+			mingw64)
+				basic_machine=x86_64-pc
+				basic_os=mingw64
+				;;
+			mingw32)
+				basic_machine=i686-pc
+				basic_os=mingw32
+				;;
+			mingw32ce)
+				basic_machine=arm-unknown
+				basic_os=mingw32ce
+				;;
+			monitor)
+				basic_machine=m68k-rom68k
+				basic_os=coff
+				;;
+			morphos)
+				basic_machine=powerpc-unknown
+				basic_os=morphos
+				;;
+			moxiebox)
+				basic_machine=moxie-unknown
+				basic_os=moxiebox
+				;;
+			msdos)
+				basic_machine=i386-pc
+				basic_os=msdos
+				;;
+			msys)
+				basic_machine=i686-pc
+				basic_os=msys
+				;;
+			mvs)
+				basic_machine=i370-ibm
+				basic_os=mvs
+				;;
+			nacl)
+				basic_machine=le32-unknown
+				basic_os=nacl
+				;;
+			ncr3000)
+				basic_machine=i486-ncr
+				basic_os=sysv4
+				;;
+			netbsd386)
+				basic_machine=i386-pc
+				basic_os=netbsd
+				;;
+			netwinder)
+				basic_machine=armv4l-rebel
+				basic_os=linux
+				;;
+			news | news700 | news800 | news900)
+				basic_machine=m68k-sony
+				basic_os=newsos
+				;;
+			news1000)
+				basic_machine=m68030-sony
+				basic_os=newsos
+				;;
+			necv70)
+				basic_machine=v70-nec
+				basic_os=sysv
+				;;
+			nh3000)
+				basic_machine=m68k-harris
+				basic_os=cxux
+				;;
+			nh[45]000)
+				basic_machine=m88k-harris
+				basic_os=cxux
+				;;
+			nindy960)
+				basic_machine=i960-intel
+				basic_os=nindy
+				;;
+			mon960)
+				basic_machine=i960-intel
+				basic_os=mon960
+				;;
+			nonstopux)
+				basic_machine=mips-compaq
+				basic_os=nonstopux
+				;;
+			os400)
+				basic_machine=powerpc-ibm
+				basic_os=os400
+				;;
+			OSE68000 | ose68000)
+				basic_machine=m68000-ericsson
+				basic_os=ose
+				;;
+			os68k)
+				basic_machine=m68k-none
+				basic_os=os68k
+				;;
+			paragon)
+				basic_machine=i860-intel
+				basic_os=osf
+				;;
+			parisc)
+				basic_machine=hppa-unknown
+				basic_os=linux
+				;;
+			psp)
+				basic_machine=mipsallegrexel-sony
+				basic_os=psp
+				;;
+			pw32)
+				basic_machine=i586-unknown
+				basic_os=pw32
+				;;
+			rdos | rdos64)
+				basic_machine=x86_64-pc
+				basic_os=rdos
+				;;
+			rdos32)
+				basic_machine=i386-pc
+				basic_os=rdos
+				;;
+			rom68k)
+				basic_machine=m68k-rom68k
+				basic_os=coff
+				;;
+			sa29200)
+				basic_machine=a29k-amd
+				basic_os=udi
+				;;
+			sei)
+				basic_machine=mips-sei
+				basic_os=seiux
+				;;
+			sequent)
+				basic_machine=i386-sequent
+				basic_os=
+				;;
+			sps7)
+				basic_machine=m68k-bull
+				basic_os=sysv2
+				;;
+			st2000)
+				basic_machine=m68k-tandem
+				basic_os=
+				;;
+			stratus)
+				basic_machine=i860-stratus
+				basic_os=sysv4
+				;;
+			sun2)
+				basic_machine=m68000-sun
+				basic_os=
+				;;
+			sun2os3)
+				basic_machine=m68000-sun
+				basic_os=sunos3
+				;;
+			sun2os4)
+				basic_machine=m68000-sun
+				basic_os=sunos4
+				;;
+			sun3)
+				basic_machine=m68k-sun
+				basic_os=
+				;;
+			sun3os3)
+				basic_machine=m68k-sun
+				basic_os=sunos3
+				;;
+			sun3os4)
+				basic_machine=m68k-sun
+				basic_os=sunos4
+				;;
+			sun4)
+				basic_machine=sparc-sun
+				basic_os=
+				;;
+			sun4os3)
+				basic_machine=sparc-sun
+				basic_os=sunos3
+				;;
+			sun4os4)
+				basic_machine=sparc-sun
+				basic_os=sunos4
+				;;
+			sun4sol2)
+				basic_machine=sparc-sun
+				basic_os=solaris2
+				;;
+			sun386 | sun386i | roadrunner)
+				basic_machine=i386-sun
+				basic_os=
+				;;
+			sv1)
+				basic_machine=sv1-cray
+				basic_os=unicos
+				;;
+			symmetry)
+				basic_machine=i386-sequent
+				basic_os=dynix
+				;;
+			t3e)
+				basic_machine=alphaev5-cray
+				basic_os=unicos
+				;;
+			t90)
+				basic_machine=t90-cray
+				basic_os=unicos
+				;;
+			toad1)
+				basic_machine=pdp10-xkl
+				basic_os=tops20
+				;;
+			tpf)
+				basic_machine=s390x-ibm
+				basic_os=tpf
+				;;
+			udi29k)
+				basic_machine=a29k-amd
+				basic_os=udi
+				;;
+			ultra3)
+				basic_machine=a29k-nyu
+				basic_os=sym1
+				;;
+			v810 | necv810)
+				basic_machine=v810-nec
+				basic_os=none
+				;;
+			vaxv)
+				basic_machine=vax-dec
+				basic_os=sysv
+				;;
+			vms)
+				basic_machine=vax-dec
+				basic_os=vms
+				;;
+			vsta)
+				basic_machine=i386-pc
+				basic_os=vsta
+				;;
+			vxworks960)
+				basic_machine=i960-wrs
+				basic_os=vxworks
+				;;
+			vxworks68)
+				basic_machine=m68k-wrs
+				basic_os=vxworks
+				;;
+			vxworks29k)
+				basic_machine=a29k-wrs
+				basic_os=vxworks
+				;;
+			xbox)
+				basic_machine=i686-pc
+				basic_os=mingw32
+				;;
+			ymp)
+				basic_machine=ymp-cray
+				basic_os=unicos
+				;;
+			*)
+				basic_machine=$1
+				basic_os=
+				;;
+		esac
 		;;
 esac
 
-# Decode aliases for certain CPU-COMPANY combinations.
+# Decode 1-component or ad-hoc basic machines
 case $basic_machine in
-	# Recognize the basic CPU types without company name.
-	# Some are omitted here because they have special meanings below.
-	1750a | 580 \
-	| a29k \
-	| aarch64 | aarch64_be \
-	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
-	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
-	| am33_2.0 \
-	| arc | arceb \
-	| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
-	| avr | avr32 \
-	| ba \
-	| be32 | be64 \
-	| bfin \
-	| c4x | c8051 | clipper \
-	| d10v | d30v | dlx | dsp16xx \
-	| e2k | epiphany \
-	| fido | fr30 | frv | ft32 \
-	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
-	| hexagon \
-	| i370 | i860 | i960 | ia16 | ia64 \
-	| ip2k | iq2000 \
-	| k1om \
-	| le32 | le64 \
-	| lm32 \
-	| m32c | m32r | m32rle | m68000 | m68k | m88k \
-	| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
-	| mips | mipsbe | mipseb | mipsel | mipsle \
-	| mips16 \
-	| mips64 | mips64el \
-	| mips64octeon | mips64octeonel \
-	| mips64orion | mips64orionel \
-	| mips64r5900 | mips64r5900el \
-	| mips64vr | mips64vrel \
-	| mips64vr4100 | mips64vr4100el \
-	| mips64vr4300 | mips64vr4300el \
-	| mips64vr5000 | mips64vr5000el \
-	| mips64vr5900 | mips64vr5900el \
-	| mipsisa32 | mipsisa32el \
-	| mipsisa32r2 | mipsisa32r2el \
-	| mipsisa32r6 | mipsisa32r6el \
-	| mipsisa64 | mipsisa64el \
-	| mipsisa64r2 | mipsisa64r2el \
-	| mipsisa64r6 | mipsisa64r6el \
-	| mipsisa64sb1 | mipsisa64sb1el \
-	| mipsisa64sr71k | mipsisa64sr71kel \
-	| mipsr5900 | mipsr5900el \
-	| mipstx39 | mipstx39el \
-	| mn10200 | mn10300 \
-	| moxie \
-	| mt \
-	| msp430 \
-	| nds32 | nds32le | nds32be \
-	| nios | nios2 | nios2eb | nios2el \
-	| ns16k | ns32k \
-	| open8 | or1k | or1knd | or32 \
-	| pdp10 | pj | pjl \
-	| powerpc | powerpc64 | powerpc64le | powerpcle \
-	| pru \
-	| pyramid \
-	| riscv32 | riscv64 \
-	| rl78 | rx \
-	| score \
-	| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[234]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
-	| sh64 | sh64le \
-	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
-	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
-	| spu \
-	| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
-	| ubicom32 \
-	| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
-	| visium \
-	| wasm32 \
-	| x86 | xc16x | xstormy16 | xtensa \
-	| z8k | z80)
-		basic_machine=$basic_machine-unknown
+	# Here we handle the default manufacturer of certain CPU types.  It is in
+	# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		cpu=hppa1.1
+		vendor=winbond
 		;;
-	c54x)
-		basic_machine=tic54x-unknown
+	op50n)
+		cpu=hppa1.1
+		vendor=oki
 		;;
-	c55x)
-		basic_machine=tic55x-unknown
+	op60c)
+		cpu=hppa1.1
+		vendor=oki
 		;;
-	c6x)
-		basic_machine=tic6x-unknown
+	ibm*)
+		cpu=i370
+		vendor=ibm
+		;;
+	orion105)
+		cpu=clipper
+		vendor=highlevel
+		;;
+	mac | mpw | mac-mpw)
+		cpu=m68k
+		vendor=apple
+		;;
+	pmac | pmac-mpw)
+		cpu=powerpc
+		vendor=apple
+		;;
+
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		cpu=m68000
+		vendor=att
+		;;
+	3b*)
+		cpu=we32k
+		vendor=att
+		;;
+	bluegene*)
+		cpu=powerpc
+		vendor=ibm
+		basic_os=cnk
+		;;
+	decsystem10* | dec10*)
+		cpu=pdp10
+		vendor=dec
+		basic_os=tops10
+		;;
+	decsystem20* | dec20*)
+		cpu=pdp10
+		vendor=dec
+		basic_os=tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		cpu=m68k
+		vendor=motorola
+		;;
+	dpx2*)
+		cpu=m68k
+		vendor=bull
+		basic_os=sysv3
+		;;
+	encore | umax | mmax)
+		cpu=ns32k
+		vendor=encore
+		;;
+	elxsi)
+		cpu=elxsi
+		vendor=elxsi
+		basic_os=${basic_os:-bsd}
+		;;
+	fx2800)
+		cpu=i860
+		vendor=alliant
+		;;
+	genix)
+		cpu=ns32k
+		vendor=ns
+		;;
+	h3050r* | hiux*)
+		cpu=hppa1.1
+		vendor=hitachi
+		basic_os=hiuxwe2
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		cpu=hppa1.0
+		vendor=hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		cpu=m68000
+		vendor=hp
+		;;
+	hp9k3[2-9][0-9])
+		cpu=m68k
+		vendor=hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		cpu=hppa1.0
+		vendor=hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		cpu=hppa1.1
+		vendor=hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		cpu=hppa1.1
+		vendor=hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		cpu=hppa1.1
+		vendor=hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		cpu=hppa1.1
+		vendor=hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		cpu=hppa1.0
+		vendor=hp
+		;;
+	i*86v32)
+		cpu=`echo "$1" | sed -e 's/86.*/86/'`
+		vendor=pc
+		basic_os=sysv32
+		;;
+	i*86v4*)
+		cpu=`echo "$1" | sed -e 's/86.*/86/'`
+		vendor=pc
+		basic_os=sysv4
+		;;
+	i*86v)
+		cpu=`echo "$1" | sed -e 's/86.*/86/'`
+		vendor=pc
+		basic_os=sysv
+		;;
+	i*86sol2)
+		cpu=`echo "$1" | sed -e 's/86.*/86/'`
+		vendor=pc
+		basic_os=solaris2
+		;;
+	j90 | j90-cray)
+		cpu=j90
+		vendor=cray
+		basic_os=${basic_os:-unicos}
+		;;
+	iris | iris4d)
+		cpu=mips
+		vendor=sgi
+		case $basic_os in
+		    irix*)
+			;;
+		    *)
+			basic_os=irix4
+			;;
+		esac
+		;;
+	miniframe)
+		cpu=m68000
+		vendor=convergent
+		;;
+	*mint | mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		cpu=m68k
+		vendor=atari
+		basic_os=mint
+		;;
+	news-3600 | risc-news)
+		cpu=mips
+		vendor=sony
+		basic_os=newsos
+		;;
+	next | m*-next)
+		cpu=m68k
+		vendor=next
+		case $basic_os in
+		    openstep*)
+		        ;;
+		    nextstep*)
+			;;
+		    ns2*)
+		      basic_os=nextstep2
+			;;
+		    *)
+		      basic_os=nextstep3
+			;;
+		esac
+		;;
+	np1)
+		cpu=np1
+		vendor=gould
+		;;
+	op50n-* | op60c-*)
+		cpu=hppa1.1
+		vendor=oki
+		basic_os=proelf
+		;;
+	pa-hitachi)
+		cpu=hppa1.1
+		vendor=hitachi
+		basic_os=hiuxwe2
+		;;
+	pbd)
+		cpu=sparc
+		vendor=tti
+		;;
+	pbb)
+		cpu=m68k
+		vendor=tti
+		;;
+	pc532)
+		cpu=ns32k
+		vendor=pc532
+		;;
+	pn)
+		cpu=pn
+		vendor=gould
+		;;
+	power)
+		cpu=power
+		vendor=ibm
+		;;
+	ps2)
+		cpu=i386
+		vendor=ibm
+		;;
+	rm[46]00)
+		cpu=mips
+		vendor=siemens
+		;;
+	rtpc | rtpc-*)
+		cpu=romp
+		vendor=ibm
+		;;
+	sde)
+		cpu=mipsisa32
+		vendor=sde
+		basic_os=${basic_os:-elf}
+		;;
+	simso-wrs)
+		cpu=sparclite
+		vendor=wrs
+		basic_os=vxworks
+		;;
+	tower | tower-32)
+		cpu=m68k
+		vendor=ncr
+		;;
+	vpp*|vx|vx-*)
+		cpu=f301
+		vendor=fujitsu
+		;;
+	w65)
+		cpu=w65
+		vendor=wdc
+		;;
+	w89k-*)
+		cpu=hppa1.1
+		vendor=winbond
+		basic_os=proelf
+		;;
+	none)
+		cpu=none
+		vendor=none
 		;;
 	leon|leon[3-9])
-		basic_machine=sparc-$basic_machine
+		cpu=sparc
+		vendor=$basic_machine
 		;;
-	m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
-		basic_machine=$basic_machine-unknown
-		os=-none
-		;;
-	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65)
-		;;
-	ms1)
-		basic_machine=mt-unknown
+	leon-*|leon[3-9]-*)
+		cpu=sparc
+		vendor=`echo "$basic_machine" | sed 's/-.*//'`
 		;;
 
-	strongarm | thumb | xscale)
-		basic_machine=arm-unknown
+	*-*)
+		# shellcheck disable=SC2162
+		saved_IFS=$IFS
+		IFS="-" read cpu vendor <<EOF
+$basic_machine
+EOF
+		IFS=$saved_IFS
 		;;
-	xgate)
-		basic_machine=$basic_machine-unknown
-		os=-none
-		;;
-	xscaleeb)
-		basic_machine=armeb-unknown
-		;;
-
-	xscaleel)
-		basic_machine=armel-unknown
-		;;
-
 	# We use `pc' rather than `unknown'
 	# because (1) that's what they normally are, and
 	# (2) the word "unknown" tends to confuse beginning users.
 	i*86 | x86_64)
-	  basic_machine=$basic_machine-pc
-	  ;;
-	# Object if more than one company name word.
-	*-*-*)
-		echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
-		exit 1
+		cpu=$basic_machine
+		vendor=pc
 		;;
-	# Recognize the basic CPU types with company name.
-	580-* \
-	| a29k-* \
-	| aarch64-* | aarch64_be-* \
-	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
-	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
-	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
-	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
-	| avr-* | avr32-* \
-	| ba-* \
-	| be32-* | be64-* \
-	| bfin-* | bs2000-* \
-	| c[123]* | c30-* | [cjt]90-* | c4x-* \
-	| c8051-* | clipper-* | craynv-* | cydra-* \
-	| d10v-* | d30v-* | dlx-* \
-	| e2k-* | elxsi-* \
-	| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
-	| h8300-* | h8500-* \
-	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
-	| hexagon-* \
-	| i*86-* | i860-* | i960-* | ia16-* | ia64-* \
-	| ip2k-* | iq2000-* \
-	| k1om-* \
-	| le32-* | le64-* \
-	| lm32-* \
-	| m32c-* | m32r-* | m32rle-* \
-	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-	| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
-	| microblaze-* | microblazeel-* \
-	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
-	| mips16-* \
-	| mips64-* | mips64el-* \
-	| mips64octeon-* | mips64octeonel-* \
-	| mips64orion-* | mips64orionel-* \
-	| mips64r5900-* | mips64r5900el-* \
-	| mips64vr-* | mips64vrel-* \
-	| mips64vr4100-* | mips64vr4100el-* \
-	| mips64vr4300-* | mips64vr4300el-* \
-	| mips64vr5000-* | mips64vr5000el-* \
-	| mips64vr5900-* | mips64vr5900el-* \
-	| mipsisa32-* | mipsisa32el-* \
-	| mipsisa32r2-* | mipsisa32r2el-* \
-	| mipsisa32r6-* | mipsisa32r6el-* \
-	| mipsisa64-* | mipsisa64el-* \
-	| mipsisa64r2-* | mipsisa64r2el-* \
-	| mipsisa64r6-* | mipsisa64r6el-* \
-	| mipsisa64sb1-* | mipsisa64sb1el-* \
-	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
-	| mipsr5900-* | mipsr5900el-* \
-	| mipstx39-* | mipstx39el-* \
-	| mmix-* \
-	| mt-* \
-	| msp430-* \
-	| nds32-* | nds32le-* | nds32be-* \
-	| nios-* | nios2-* | nios2eb-* | nios2el-* \
-	| none-* | np1-* | ns16k-* | ns32k-* \
-	| open8-* \
-	| or1k*-* \
-	| orion-* \
-	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
-	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
-	| pru-* \
-	| pyramid-* \
-	| riscv32-* | riscv64-* \
-	| rl78-* | romp-* | rs6000-* | rx-* \
-	| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
-	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
-	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
-	| sparclite-* \
-	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
-	| tahoe-* \
-	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
-	| tile*-* \
-	| tron-* \
-	| ubicom32-* \
-	| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
-	| vax-* \
-	| visium-* \
-	| wasm32-* \
-	| we32k-* \
-	| x86-* | x86_64-* | xc16x-* | xps100-* \
-	| xstormy16-* | xtensa*-* \
-	| ymp-* \
-	| z8k-* | z80-*)
-		;;
-	# Recognize the basic CPU types without company name, with glob match.
-	xtensa*)
-		basic_machine=$basic_machine-unknown
-		;;
-	# Recognize the various machine names and aliases which stand
-	# for a CPU type and a company and sometimes even an OS.
-	386bsd)
-		basic_machine=i386-pc
-		os=-bsd
-		;;
-	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
-		basic_machine=m68000-att
-		;;
-	3b*)
-		basic_machine=we32k-att
-		;;
-	a29khif)
-		basic_machine=a29k-amd
-		os=-udi
-		;;
-	abacus)
-		basic_machine=abacus-unknown
-		;;
-	adobe68k)
-		basic_machine=m68010-adobe
-		os=-scout
-		;;
-	alliant | fx80)
-		basic_machine=fx80-alliant
-		;;
-	altos | altos3068)
-		basic_machine=m68k-altos
-		;;
-	am29k)
-		basic_machine=a29k-none
-		os=-bsd
-		;;
-	amd64)
-		basic_machine=x86_64-pc
-		;;
-	amd64-*)
-		basic_machine=x86_64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	amdahl)
-		basic_machine=580-amdahl
-		os=-sysv
-		;;
-	amiga | amiga-*)
-		basic_machine=m68k-unknown
-		;;
-	amigaos | amigados)
-		basic_machine=m68k-unknown
-		os=-amigaos
-		;;
-	amigaunix | amix)
-		basic_machine=m68k-unknown
-		os=-sysv4
-		;;
-	apollo68)
-		basic_machine=m68k-apollo
-		os=-sysv
-		;;
-	apollo68bsd)
-		basic_machine=m68k-apollo
-		os=-bsd
-		;;
-	aros)
-		basic_machine=i386-pc
-		os=-aros
-		;;
-	asmjs)
-		basic_machine=asmjs-unknown
-		;;
-	aux)
-		basic_machine=m68k-apple
-		os=-aux
-		;;
-	balance)
-		basic_machine=ns32k-sequent
-		os=-dynix
-		;;
-	blackfin)
-		basic_machine=bfin-unknown
-		os=-linux
-		;;
-	blackfin-*)
-		basic_machine=bfin-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
-	bluegene*)
-		basic_machine=powerpc-ibm
-		os=-cnk
-		;;
-	c54x-*)
-		basic_machine=tic54x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	c55x-*)
-		basic_machine=tic55x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	c6x-*)
-		basic_machine=tic6x-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	c90)
-		basic_machine=c90-cray
-		os=-unicos
-		;;
-	cegcc)
-		basic_machine=arm-unknown
-		os=-cegcc
-		;;
-	convex-c1)
-		basic_machine=c1-convex
-		os=-bsd
-		;;
-	convex-c2)
-		basic_machine=c2-convex
-		os=-bsd
-		;;
-	convex-c32)
-		basic_machine=c32-convex
-		os=-bsd
-		;;
-	convex-c34)
-		basic_machine=c34-convex
-		os=-bsd
-		;;
-	convex-c38)
-		basic_machine=c38-convex
-		os=-bsd
-		;;
-	cray | j90)
-		basic_machine=j90-cray
-		os=-unicos
-		;;
-	craynv)
-		basic_machine=craynv-cray
-		os=-unicosmp
-		;;
-	cr16 | cr16-*)
-		basic_machine=cr16-unknown
-		os=-elf
-		;;
-	crds | unos)
-		basic_machine=m68k-crds
-		;;
-	crisv32 | crisv32-* | etraxfs*)
-		basic_machine=crisv32-axis
-		;;
-	cris | cris-* | etrax*)
-		basic_machine=cris-axis
-		;;
-	crx)
-		basic_machine=crx-unknown
-		os=-elf
-		;;
-	da30 | da30-*)
-		basic_machine=m68k-da30
-		;;
-	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
-		basic_machine=mips-dec
-		;;
-	decsystem10* | dec10*)
-		basic_machine=pdp10-dec
-		os=-tops10
-		;;
-	decsystem20* | dec20*)
-		basic_machine=pdp10-dec
-		os=-tops20
-		;;
-	delta | 3300 | motorola-3300 | motorola-delta \
-	      | 3300-motorola | delta-motorola)
-		basic_machine=m68k-motorola
-		;;
-	delta88)
-		basic_machine=m88k-motorola
-		os=-sysv3
-		;;
-	dicos)
-		basic_machine=i686-pc
-		os=-dicos
-		;;
-	djgpp)
-		basic_machine=i586-pc
-		os=-msdosdjgpp
-		;;
-	dpx20 | dpx20-*)
-		basic_machine=rs6000-bull
-		os=-bosx
-		;;
-	dpx2*)
-		basic_machine=m68k-bull
-		os=-sysv3
-		;;
-	e500v[12])
-		basic_machine=powerpc-unknown
-		os=$os"spe"
-		;;
-	e500v[12]-*)
-		basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=$os"spe"
-		;;
-	ebmon29k)
-		basic_machine=a29k-amd
-		os=-ebmon
-		;;
-	elxsi)
-		basic_machine=elxsi-elxsi
-		os=-bsd
-		;;
-	encore | umax | mmax)
-		basic_machine=ns32k-encore
-		;;
-	es1800 | OSE68k | ose68k | ose | OSE)
-		basic_machine=m68k-ericsson
-		os=-ose
-		;;
-	fx2800)
-		basic_machine=i860-alliant
-		;;
-	genix)
-		basic_machine=ns32k-ns
-		;;
-	gmicro)
-		basic_machine=tron-gmicro
-		os=-sysv
-		;;
-	go32)
-		basic_machine=i386-pc
-		os=-go32
-		;;
-	h3050r* | hiux*)
-		basic_machine=hppa1.1-hitachi
-		os=-hiuxwe2
-		;;
-	h8300hms)
-		basic_machine=h8300-hitachi
-		os=-hms
-		;;
-	h8300xray)
-		basic_machine=h8300-hitachi
-		os=-xray
-		;;
-	h8500hms)
-		basic_machine=h8500-hitachi
-		os=-hms
-		;;
-	harris)
-		basic_machine=m88k-harris
-		os=-sysv3
-		;;
-	hp300-*)
-		basic_machine=m68k-hp
-		;;
-	hp300bsd)
-		basic_machine=m68k-hp
-		os=-bsd
-		;;
-	hp300hpux)
-		basic_machine=m68k-hp
-		os=-hpux
-		;;
-	hp3k9[0-9][0-9] | hp9[0-9][0-9])
-		basic_machine=hppa1.0-hp
-		;;
-	hp9k2[0-9][0-9] | hp9k31[0-9])
-		basic_machine=m68000-hp
-		;;
-	hp9k3[2-9][0-9])
-		basic_machine=m68k-hp
-		;;
-	hp9k6[0-9][0-9] | hp6[0-9][0-9])
-		basic_machine=hppa1.0-hp
-		;;
-	hp9k7[0-79][0-9] | hp7[0-79][0-9])
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k78[0-9] | hp78[0-9])
-		# FIXME: really hppa2.0-hp
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
-		# FIXME: really hppa2.0-hp
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k8[0-9][13679] | hp8[0-9][13679])
-		basic_machine=hppa1.1-hp
-		;;
-	hp9k8[0-9][0-9] | hp8[0-9][0-9])
-		basic_machine=hppa1.0-hp
-		;;
-	hppaosf)
-		basic_machine=hppa1.1-hp
-		os=-osf
-		;;
-	hppro)
-		basic_machine=hppa1.1-hp
-		os=-proelf
-		;;
-	i370-ibm* | ibm*)
-		basic_machine=i370-ibm
-		;;
-	i*86v32)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-sysv32
-		;;
-	i*86v4*)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-sysv4
-		;;
-	i*86v)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-sysv
-		;;
-	i*86sol2)
-		basic_machine=`echo "$1" | sed -e 's/86.*/86-pc/'`
-		os=-solaris2
-		;;
-	i386mach)
-		basic_machine=i386-mach
-		os=-mach
-		;;
-	vsta)
-		basic_machine=i386-unknown
-		os=-vsta
-		;;
-	iris | iris4d)
-		basic_machine=mips-sgi
-		case $os in
-		    -irix*)
-			;;
-		    *)
-			os=-irix4
-			;;
-		esac
-		;;
-	isi68 | isi)
-		basic_machine=m68k-isi
-		os=-sysv
-		;;
-	leon-*|leon[3-9]-*)
-		basic_machine=sparc-`echo "$basic_machine" | sed 's/-.*//'`
-		;;
-	m68knommu)
-		basic_machine=m68k-unknown
-		os=-linux
-		;;
-	m68knommu-*)
-		basic_machine=m68k-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
-	magnum | m3230)
-		basic_machine=mips-mips
-		os=-sysv
-		;;
-	merlin)
-		basic_machine=ns32k-utek
-		os=-sysv
-		;;
-	microblaze*)
-		basic_machine=microblaze-xilinx
-		;;
-	mingw64)
-		basic_machine=x86_64-pc
-		os=-mingw64
-		;;
-	mingw32)
-		basic_machine=i686-pc
-		os=-mingw32
-		;;
-	mingw32ce)
-		basic_machine=arm-unknown
-		os=-mingw32ce
-		;;
-	miniframe)
-		basic_machine=m68000-convergent
-		;;
-	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
-		basic_machine=m68k-atari
-		os=-mint
-		;;
-	mips3*-*)
-		basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`
-		;;
-	mips3*)
-		basic_machine=`echo "$basic_machine" | sed -e 's/mips3/mips64/'`-unknown
-		;;
-	monitor)
-		basic_machine=m68k-rom68k
-		os=-coff
-		;;
-	morphos)
-		basic_machine=powerpc-unknown
-		os=-morphos
-		;;
-	moxiebox)
-		basic_machine=moxie-unknown
-		os=-moxiebox
-		;;
-	msdos)
-		basic_machine=i386-pc
-		os=-msdos
-		;;
-	ms1-*)
-		basic_machine=`echo "$basic_machine" | sed -e 's/ms1-/mt-/'`
-		;;
-	msys)
-		basic_machine=i686-pc
-		os=-msys
-		;;
-	mvs)
-		basic_machine=i370-ibm
-		os=-mvs
-		;;
-	nacl)
-		basic_machine=le32-unknown
-		os=-nacl
-		;;
-	ncr3000)
-		basic_machine=i486-ncr
-		os=-sysv4
-		;;
-	netbsd386)
-		basic_machine=i386-unknown
-		os=-netbsd
-		;;
-	netwinder)
-		basic_machine=armv4l-rebel
-		os=-linux
-		;;
-	news | news700 | news800 | news900)
-		basic_machine=m68k-sony
-		os=-newsos
-		;;
-	news1000)
-		basic_machine=m68030-sony
-		os=-newsos
-		;;
-	news-3600 | risc-news)
-		basic_machine=mips-sony
-		os=-newsos
-		;;
-	necv70)
-		basic_machine=v70-nec
-		os=-sysv
-		;;
-	next | m*-next)
-		basic_machine=m68k-next
-		case $os in
-		    -nextstep* )
-			;;
-		    -ns2*)
-		      os=-nextstep2
-			;;
-		    *)
-		      os=-nextstep3
-			;;
-		esac
-		;;
-	nh3000)
-		basic_machine=m68k-harris
-		os=-cxux
-		;;
-	nh[45]000)
-		basic_machine=m88k-harris
-		os=-cxux
-		;;
-	nindy960)
-		basic_machine=i960-intel
-		os=-nindy
-		;;
-	mon960)
-		basic_machine=i960-intel
-		os=-mon960
-		;;
-	nonstopux)
-		basic_machine=mips-compaq
-		os=-nonstopux
-		;;
-	np1)
-		basic_machine=np1-gould
-		;;
-	neo-tandem)
-		basic_machine=neo-tandem
-		;;
-	nse-tandem)
-		basic_machine=nse-tandem
-		;;
-	nsr-tandem)
-		basic_machine=nsr-tandem
-		;;
-	nsv-tandem)
-		basic_machine=nsv-tandem
-		;;
-	nsx-tandem)
-		basic_machine=nsx-tandem
-		;;
-	op50n-* | op60c-*)
-		basic_machine=hppa1.1-oki
-		os=-proelf
-		;;
-	openrisc | openrisc-*)
-		basic_machine=or32-unknown
-		;;
-	os400)
-		basic_machine=powerpc-ibm
-		os=-os400
-		;;
-	OSE68000 | ose68000)
-		basic_machine=m68000-ericsson
-		os=-ose
-		;;
-	os68k)
-		basic_machine=m68k-none
-		os=-os68k
-		;;
-	pa-hitachi)
-		basic_machine=hppa1.1-hitachi
-		os=-hiuxwe2
-		;;
-	paragon)
-		basic_machine=i860-intel
-		os=-osf
-		;;
-	parisc)
-		basic_machine=hppa-unknown
-		os=-linux
-		;;
-	parisc-*)
-		basic_machine=hppa-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		os=-linux
-		;;
-	pbd)
-		basic_machine=sparc-tti
-		;;
-	pbb)
-		basic_machine=m68k-tti
-		;;
-	pc532 | pc532-*)
-		basic_machine=ns32k-pc532
-		;;
+	# These rules are duplicated from below for sake of the special case above;
+	# i.e. things that normalized to x86 arches should also default to "pc"
 	pc98)
-		basic_machine=i386-pc
+		cpu=i386
+		vendor=pc
 		;;
-	pc98-*)
-		basic_machine=i386-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	x64 | amd64)
+		cpu=x86_64
+		vendor=pc
 		;;
-	pentium | p5 | k5 | k6 | nexgen | viac3)
-		basic_machine=i586-pc
+	# Recognize the basic CPU types without company name.
+	*)
+		cpu=$basic_machine
+		vendor=unknown
 		;;
-	pentiumpro | p6 | 6x86 | athlon | athlon_*)
-		basic_machine=i686-pc
+esac
+
+unset -v basic_machine
+
+# Decode basic machines in the full and proper CPU-Company form.
+case $cpu-$vendor in
+	# Here we handle the default manufacturer of certain CPU types in canonical form. It is in
+	# some cases the only manufacturer, in others, it is the most popular.
+	craynv-unknown)
+		vendor=cray
+		basic_os=${basic_os:-unicosmp}
 		;;
-	pentiumii | pentium2 | pentiumiii | pentium3)
-		basic_machine=i686-pc
+	c90-unknown | c90-cray)
+		vendor=cray
+		basic_os=${Basic_os:-unicos}
 		;;
-	pentium4)
-		basic_machine=i786-pc
+	fx80-unknown)
+		vendor=alliant
 		;;
-	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
-		basic_machine=i586-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	romp-unknown)
+		vendor=ibm
 		;;
-	pentiumpro-* | p6-* | 6x86-* | athlon-*)
-		basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	mmix-unknown)
+		vendor=knuth
 		;;
-	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
-		basic_machine=i686-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	microblaze-unknown | microblazeel-unknown)
+		vendor=xilinx
 		;;
-	pentium4-*)
-		basic_machine=i786-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	rs6000-unknown)
+		vendor=ibm
 		;;
-	pn)
-		basic_machine=pn-gould
+	vax-unknown)
+		vendor=dec
 		;;
-	power)	basic_machine=power-ibm
+	pdp11-unknown)
+		vendor=dec
 		;;
-	ppc | ppcbe)	basic_machine=powerpc-unknown
+	we32k-unknown)
+		vendor=att
 		;;
-	ppc-* | ppcbe-*)
-		basic_machine=powerpc-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	cydra-unknown)
+		vendor=cydrome
 		;;
-	ppcle | powerpclittle)
-		basic_machine=powerpcle-unknown
+	i370-ibm*)
+		vendor=ibm
 		;;
-	ppcle-* | powerpclittle-*)
-		basic_machine=powerpcle-`echo "$basic_machine" | sed 's/^[^-]*-//'`
+	orion-unknown)
+		vendor=highlevel
 		;;
-	ppc64)	basic_machine=powerpc64-unknown
-		;;
-	ppc64-*) basic_machine=powerpc64-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	ppc64le | powerpc64little)
-		basic_machine=powerpc64le-unknown
-		;;
-	ppc64le-* | powerpc64little-*)
-		basic_machine=powerpc64le-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	ps2)
-		basic_machine=i386-ibm
-		;;
-	pw32)
-		basic_machine=i586-unknown
-		os=-pw32
-		;;
-	rdos | rdos64)
-		basic_machine=x86_64-pc
-		os=-rdos
-		;;
-	rdos32)
-		basic_machine=i386-pc
-		os=-rdos
-		;;
-	rom68k)
-		basic_machine=m68k-rom68k
-		os=-coff
-		;;
-	rm[46]00)
-		basic_machine=mips-siemens
-		;;
-	rtpc | rtpc-*)
-		basic_machine=romp-ibm
-		;;
-	s390 | s390-*)
-		basic_machine=s390-ibm
-		;;
-	s390x | s390x-*)
-		basic_machine=s390x-ibm
-		;;
-	sa29200)
-		basic_machine=a29k-amd
-		os=-udi
-		;;
-	sb1)
-		basic_machine=mipsisa64sb1-unknown
-		;;
-	sb1el)
-		basic_machine=mipsisa64sb1el-unknown
-		;;
-	sde)
-		basic_machine=mipsisa32-sde
-		os=-elf
-		;;
-	sei)
-		basic_machine=mips-sei
-		os=-seiux
-		;;
-	sequent)
-		basic_machine=i386-sequent
-		;;
-	sh5el)
-		basic_machine=sh5le-unknown
-		;;
-	simso-wrs)
-		basic_machine=sparclite-wrs
-		os=-vxworks
-		;;
-	sps7)
-		basic_machine=m68k-bull
-		os=-sysv2
-		;;
-	spur)
-		basic_machine=spur-unknown
-		;;
-	st2000)
-		basic_machine=m68k-tandem
-		;;
-	stratus)
-		basic_machine=i860-stratus
-		os=-sysv4
-		;;
-	strongarm-* | thumb-*)
-		basic_machine=arm-`echo "$basic_machine" | sed 's/^[^-]*-//'`
-		;;
-	sun2)
-		basic_machine=m68000-sun
-		;;
-	sun2os3)
-		basic_machine=m68000-sun
-		os=-sunos3
-		;;
-	sun2os4)
-		basic_machine=m68000-sun
-		os=-sunos4
-		;;
-	sun3os3)
-		basic_machine=m68k-sun
-		os=-sunos3
-		;;
-	sun3os4)
-		basic_machine=m68k-sun
-		os=-sunos4
-		;;
-	sun4os3)
-		basic_machine=sparc-sun
-		os=-sunos3
-		;;
-	sun4os4)
-		basic_machine=sparc-sun
-		os=-sunos4
-		;;
-	sun4sol2)
-		basic_machine=sparc-sun
-		os=-solaris2
-		;;
-	sun3 | sun3-*)
-		basic_machine=m68k-sun
-		;;
-	sun4)
-		basic_machine=sparc-sun
-		;;
-	sun386 | sun386i | roadrunner)
-		basic_machine=i386-sun
-		;;
-	sv1)
-		basic_machine=sv1-cray
-		os=-unicos
-		;;
-	symmetry)
-		basic_machine=i386-sequent
-		os=-dynix
-		;;
-	t3e)
-		basic_machine=alphaev5-cray
-		os=-unicos
-		;;
-	t90)
-		basic_machine=t90-cray
-		os=-unicos
-		;;
-	tile*)
-		basic_machine=$basic_machine-unknown
-		os=-linux-gnu
-		;;
-	tx39)
-		basic_machine=mipstx39-unknown
-		;;
-	tx39el)
-		basic_machine=mipstx39el-unknown
-		;;
-	toad1)
-		basic_machine=pdp10-xkl
-		os=-tops20
-		;;
-	tower | tower-32)
-		basic_machine=m68k-ncr
-		;;
-	tpf)
-		basic_machine=s390x-ibm
-		os=-tpf
-		;;
-	udi29k)
-		basic_machine=a29k-amd
-		os=-udi
-		;;
-	ultra3)
-		basic_machine=a29k-nyu
-		os=-sym1
-		;;
-	v810 | necv810)
-		basic_machine=v810-nec
-		os=-none
-		;;
-	vaxv)
-		basic_machine=vax-dec
-		os=-sysv
-		;;
-	vms)
-		basic_machine=vax-dec
-		os=-vms
-		;;
-	vpp*|vx|vx-*)
-		basic_machine=f301-fujitsu
-		;;
-	vxworks960)
-		basic_machine=i960-wrs
-		os=-vxworks
-		;;
-	vxworks68)
-		basic_machine=m68k-wrs
-		os=-vxworks
-		;;
-	vxworks29k)
-		basic_machine=a29k-wrs
-		os=-vxworks
-		;;
-	w65*)
-		basic_machine=w65-wdc
-		os=-none
-		;;
-	w89k-*)
-		basic_machine=hppa1.1-winbond
-		os=-proelf
-		;;
-	x64)
-		basic_machine=x86_64-pc
-		;;
-	xbox)
-		basic_machine=i686-pc
-		os=-mingw32
-		;;
-	xps | xps100)
-		basic_machine=xps100-honeywell
-		;;
-	xscale-* | xscalee[bl]-*)
-		basic_machine=`echo "$basic_machine" | sed 's/^xscale/arm/'`
-		;;
-	ymp)
-		basic_machine=ymp-cray
-		os=-unicos
-		;;
-	none)
-		basic_machine=none-none
-		os=-none
+	xps-unknown | xps100-unknown)
+		cpu=xps100
+		vendor=honeywell
 		;;
 
-# Here we handle the default manufacturer of certain CPU types.  It is in
-# some cases the only manufacturer, in others, it is the most popular.
-	w89k)
-		basic_machine=hppa1.1-winbond
+	# Here we normalize CPU types with a missing or matching vendor
+	armh-unknown | armh-alt)
+		cpu=armv7l
+		vendor=alt
+		basic_os=${basic_os:-linux-gnueabihf}
 		;;
-	op50n)
-		basic_machine=hppa1.1-oki
+	dpx20-unknown | dpx20-bull)
+		cpu=rs6000
+		vendor=bull
+		basic_os=${basic_os:-bosx}
 		;;
-	op60c)
-		basic_machine=hppa1.1-oki
+
+	# Here we normalize CPU types irrespective of the vendor
+	amd64-*)
+		cpu=x86_64
 		;;
-	romp)
-		basic_machine=romp-ibm
+	blackfin-*)
+		cpu=bfin
+		basic_os=linux
 		;;
-	mmix)
-		basic_machine=mmix-knuth
+	c54x-*)
+		cpu=tic54x
 		;;
-	rs6000)
-		basic_machine=rs6000-ibm
+	c55x-*)
+		cpu=tic55x
 		;;
-	vax)
-		basic_machine=vax-dec
+	c6x-*)
+		cpu=tic6x
 		;;
-	pdp11)
-		basic_machine=pdp11-dec
+	e500v[12]-*)
+		cpu=powerpc
+		basic_os=${basic_os}"spe"
 		;;
-	we32k)
-		basic_machine=we32k-att
+	mips3*-*)
+		cpu=mips64
 		;;
-	sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
-		basic_machine=sh-unknown
+	ms1-*)
+		cpu=mt
 		;;
-	cydra)
-		basic_machine=cydra-cydrome
+	m68knommu-*)
+		cpu=m68k
+		basic_os=linux
 		;;
-	orion)
-		basic_machine=orion-highlevel
+	m9s12z-* | m68hcs12z-* | hcs12z-* | s12z-*)
+		cpu=s12z
 		;;
-	orion105)
-		basic_machine=clipper-highlevel
+	openrisc-*)
+		cpu=or32
 		;;
-	mac | mpw | mac-mpw)
-		basic_machine=m68k-apple
+	parisc-*)
+		cpu=hppa
+		basic_os=linux
 		;;
-	pmac | pmac-mpw)
-		basic_machine=powerpc-apple
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		cpu=i586
 		;;
-	*-unknown)
-		# Make sure to match an already-canonicalized machine name.
+	pentiumpro-* | p6-* | 6x86-* | athlon-* | athalon_*-*)
+		cpu=i686
 		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		cpu=i686
+		;;
+	pentium4-*)
+		cpu=i786
+		;;
+	pc98-*)
+		cpu=i386
+		;;
+	ppc-* | ppcbe-*)
+		cpu=powerpc
+		;;
+	ppcle-* | powerpclittle-*)
+		cpu=powerpcle
+		;;
+	ppc64-*)
+		cpu=powerpc64
+		;;
+	ppc64le-* | powerpc64little-*)
+		cpu=powerpc64le
+		;;
+	sb1-*)
+		cpu=mipsisa64sb1
+		;;
+	sb1el-*)
+		cpu=mipsisa64sb1el
+		;;
+	sh5e[lb]-*)
+		cpu=`echo "$cpu" | sed 's/^\(sh.\)e\(.\)$/\1\2e/'`
+		;;
+	spur-*)
+		cpu=spur
+		;;
+	strongarm-* | thumb-*)
+		cpu=arm
+		;;
+	tx39-*)
+		cpu=mipstx39
+		;;
+	tx39el-*)
+		cpu=mipstx39el
+		;;
+	x64-*)
+		cpu=x86_64
+		;;
+	xscale-* | xscalee[bl]-*)
+		cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
+		;;
+	arm64-* | aarch64le-*)
+		cpu=aarch64
+		;;
+
+	# Recognize the canonical CPU Types that limit and/or modify the
+	# company names they are paired with.
+	cr16-*)
+		basic_os=${basic_os:-elf}
+		;;
+	crisv32-* | etraxfs*-*)
+		cpu=crisv32
+		vendor=axis
+		;;
+	cris-* | etrax*-*)
+		cpu=cris
+		vendor=axis
+		;;
+	crx-*)
+		basic_os=${basic_os:-elf}
+		;;
+	neo-tandem)
+		cpu=neo
+		vendor=tandem
+		;;
+	nse-tandem)
+		cpu=nse
+		vendor=tandem
+		;;
+	nsr-tandem)
+		cpu=nsr
+		vendor=tandem
+		;;
+	nsv-tandem)
+		cpu=nsv
+		vendor=tandem
+		;;
+	nsx-tandem)
+		cpu=nsx
+		vendor=tandem
+		;;
+	mipsallegrexel-sony)
+		cpu=mipsallegrexel
+		vendor=sony
+		;;
+	tile*-*)
+		basic_os=${basic_os:-linux-gnu}
+		;;
+
 	*)
-		echo Invalid configuration \`"$1"\': machine \`"$basic_machine"\' not recognized 1>&2
-		exit 1
+		# Recognize the canonical CPU types that are allowed with any
+		# company name.
+		case $cpu in
+			1750a | 580 \
+			| a29k \
+			| aarch64 | aarch64_be \
+			| abacus \
+			| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] \
+			| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] \
+			| alphapca5[67] | alpha64pca5[67] \
+			| am33_2.0 \
+			| amdgcn \
+			| arc | arceb | arc32 | arc64 \
+			| arm | arm[lb]e | arme[lb] | armv* \
+			| avr | avr32 \
+			| asmjs \
+			| ba \
+			| be32 | be64 \
+			| bfin | bpf | bs2000 \
+			| c[123]* | c30 | [cjt]90 | c4x \
+			| c8051 | clipper | craynv | csky | cydra \
+			| d10v | d30v | dlx | dsp16xx \
+			| e2k | elxsi | epiphany \
+			| f30[01] | f700 | fido | fr30 | frv | ft32 | fx80 \
+			| h8300 | h8500 \
+			| hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+			| hexagon \
+			| i370 | i*86 | i860 | i960 | ia16 | ia64 \
+			| ip2k | iq2000 \
+			| k1om \
+			| le32 | le64 \
+			| lm32 \
+			| loongarch32 | loongarch64 | loongarchx32 \
+			| m32c | m32r | m32rle \
+			| m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k \
+			| m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x \
+			| m88110 | m88k | maxq | mb | mcore | mep | metag \
+			| microblaze | microblazeel \
+			| mips | mipsbe | mipseb | mipsel | mipsle \
+			| mips16 \
+			| mips64 | mips64eb | mips64el \
+			| mips64octeon | mips64octeonel \
+			| mips64orion | mips64orionel \
+			| mips64r5900 | mips64r5900el \
+			| mips64vr | mips64vrel \
+			| mips64vr4100 | mips64vr4100el \
+			| mips64vr4300 | mips64vr4300el \
+			| mips64vr5000 | mips64vr5000el \
+			| mips64vr5900 | mips64vr5900el \
+			| mipsisa32 | mipsisa32el \
+			| mipsisa32r2 | mipsisa32r2el \
+			| mipsisa32r3 | mipsisa32r3el \
+			| mipsisa32r5 | mipsisa32r5el \
+			| mipsisa32r6 | mipsisa32r6el \
+			| mipsisa64 | mipsisa64el \
+			| mipsisa64r2 | mipsisa64r2el \
+			| mipsisa64r3 | mipsisa64r3el \
+			| mipsisa64r5 | mipsisa64r5el \
+			| mipsisa64r6 | mipsisa64r6el \
+			| mipsisa64sb1 | mipsisa64sb1el \
+			| mipsisa64sr71k | mipsisa64sr71kel \
+			| mipsr5900 | mipsr5900el \
+			| mipstx39 | mipstx39el \
+			| mmix \
+			| mn10200 | mn10300 \
+			| moxie \
+			| mt \
+			| msp430 \
+			| nds32 | nds32le | nds32be \
+			| nfp \
+			| nios | nios2 | nios2eb | nios2el \
+			| none | np1 | ns16k | ns32k | nvptx \
+			| open8 \
+			| or1k* \
+			| or32 \
+			| orion \
+			| picochip \
+			| pdp10 | pdp11 | pj | pjl | pn | power \
+			| powerpc | powerpc64 | powerpc64le | powerpcle | powerpcspe \
+			| pru \
+			| pyramid \
+			| riscv | riscv32 | riscv32be | riscv64 | riscv64be \
+			| rl78 | romp | rs6000 | rx \
+			| s390 | s390x \
+			| score \
+			| sh | shl \
+			| sh[1234] | sh[24]a | sh[24]ae[lb] | sh[23]e | she[lb] | sh[lb]e \
+			| sh[1234]e[lb] |  sh[12345][lb]e | sh[23]ele | sh64 | sh64le \
+			| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet \
+			| sparclite \
+			| sparcv8 | sparcv9 | sparcv9b | sparcv9v | sv1 | sx* \
+			| spu \
+			| tahoe \
+			| thumbv7* \
+			| tic30 | tic4x | tic54x | tic55x | tic6x | tic80 \
+			| tron \
+			| ubicom32 \
+			| v70 | v850 | v850e | v850e1 | v850es | v850e2 | v850e2v3 \
+			| vax \
+			| visium \
+			| w65 \
+			| wasm32 | wasm64 \
+			| we32k \
+			| x86 | x86_64 | xc16x | xgate | xps100 \
+			| xstormy16 | xtensa* \
+			| ymp \
+			| z8k | z80)
+				;;
+
+			*)
+				echo Invalid configuration \`"$1"\': machine \`"$cpu-$vendor"\' not recognized 1>&2
+				exit 1
+				;;
+		esac
 		;;
 esac
 
 # Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
-	*-digital*)
-		basic_machine=`echo "$basic_machine" | sed 's/digital.*/dec/'`
+case $vendor in
+	digital*)
+		vendor=dec
 		;;
-	*-commodore*)
-		basic_machine=`echo "$basic_machine" | sed 's/commodore.*/cbm/'`
+	commodore*)
+		vendor=cbm
 		;;
 	*)
 		;;
@@ -1334,203 +1306,215 @@
 
 # Decode manufacturer-specific aliases for certain operating systems.
 
-if [ x"$os" != x"" ]
+if test x$basic_os != x
 then
+
+# First recognize some ad-hoc cases, or perhaps split kernel-os, or else just
+# set os.
+case $basic_os in
+	gnu/linux*)
+		kernel=linux
+		os=`echo "$basic_os" | sed -e 's|gnu/linux|gnu|'`
+		;;
+	os2-emx)
+		kernel=os2
+		os=`echo "$basic_os" | sed -e 's|os2-emx|emx|'`
+		;;
+	nto-qnx*)
+		kernel=nto
+		os=`echo "$basic_os" | sed -e 's|nto-qnx|qnx|'`
+		;;
+	*-*)
+		# shellcheck disable=SC2162
+		saved_IFS=$IFS
+		IFS="-" read kernel os <<EOF
+$basic_os
+EOF
+		IFS=$saved_IFS
+		;;
+	# Default OS when just kernel was specified
+	nto*)
+		kernel=nto
+		os=`echo "$basic_os" | sed -e 's|nto|qnx|'`
+		;;
+	linux*)
+		kernel=linux
+		os=`echo "$basic_os" | sed -e 's|linux|gnu|'`
+		;;
+	*)
+		kernel=
+		os=$basic_os
+		;;
+esac
+
+# Now, normalize the OS (knowing we just have one component, it's not a kernel,
+# etc.)
 case $os in
 	# First match some system type aliases that might get confused
 	# with valid system types.
-	# -solaris* is a basic system type, with this one exception.
-	-auroraux)
-		os=-auroraux
+	# solaris* is a basic system type, with this one exception.
+	auroraux)
+		os=auroraux
 		;;
-	-solaris1 | -solaris1.*)
-		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+	bluegene*)
+		os=cnk
 		;;
-	-solaris)
-		os=-solaris2
+	solaris1 | solaris1.*)
+		os=`echo "$os" | sed -e 's|solaris1|sunos4|'`
 		;;
-	-unixware*)
-		os=-sysv4.2uw
+	solaris)
+		os=solaris2
 		;;
-	-gnu/linux*)
-		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+	unixware*)
+		os=sysv4.2uw
 		;;
 	# es1800 is here to avoid being matched by es* (a different OS)
-	-es1800*)
-		os=-ose
+	es1800*)
+		os=ose
 		;;
-	# Now accept the basic system types.
-	# The portable systems comes first.
-	# Each alternative MUST end in a * to match a version number.
-	# -sysv* is not here because it comes later, after sysvr4.
-	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
-	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
-	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
-	      | -sym* | -kopensolaris* | -plan9* \
-	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
-	      | -aos* | -aros* | -cloudabi* | -sortix* \
-	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
-	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
-	      | -hiux* | -knetbsd* | -mirbsd* | -netbsd* \
-	      | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
-	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
-	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
-	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
-	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
-	      | -chorusos* | -chorusrdb* | -cegcc* | -glidix* \
-	      | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-	      | -midipix* | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
-	      | -linux-newlib* | -linux-musl* | -linux-uclibc* \
-	      | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
-	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* \
-	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
-	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
-	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
-	      | -morphos* | -superux* | -rtmk* | -windiss* \
-	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
-	      | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
-	      | -onefs* | -tirtos* | -phoenix* | -fuchsia* | -redox* | -bme* \
-	      | -midnightbsd*)
-	# Remember, each alternative MUST END IN *, to match a version number.
+	# Some version numbers need modification
+	chorusos*)
+		os=chorusos
 		;;
-	-qnx*)
-		case $basic_machine in
-		    x86-* | i*86-*)
-			;;
-		    *)
-			os=-nto$os
-			;;
-		esac
+	isc)
+		os=isc2.2
 		;;
-	-nto-qnx*)
+	sco6)
+		os=sco5v6
 		;;
-	-nto*)
-		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+	sco5)
+		os=sco3.2v5
 		;;
-	-sim | -xray | -os68k* | -v88r* \
-	      | -windows* | -osx | -abug | -netware* | -os9* \
-	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+	sco4)
+		os=sco3.2v4
 		;;
-	-mac*)
+	sco3.2.[4-9]*)
+		os=`echo "$os" | sed -e 's/sco3.2./sco3.2v/'`
+		;;
+	sco*v* | scout)
+		# Don't match below
+		;;
+	sco*)
+		os=sco3.2v2
+		;;
+	psos*)
+		os=psos
+		;;
+	qnx*)
+		os=qnx
+		;;
+	hiux*)
+		os=hiuxwe2
+		;;
+	lynx*178)
+		os=lynxos178
+		;;
+	lynx*5)
+		os=lynxos5
+		;;
+	lynxos*)
+		# don't get caught up in next wildcard
+		;;
+	lynx*)
+		os=lynxos
+		;;
+	mac[0-9]*)
 		os=`echo "$os" | sed -e 's|mac|macos|'`
 		;;
-	-linux-dietlibc)
-		os=-linux-dietlibc
+	opened*)
+		os=openedition
 		;;
-	-linux*)
-		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+	os400*)
+		os=os400
 		;;
-	-sunos5*)
+	sunos5*)
 		os=`echo "$os" | sed -e 's|sunos5|solaris2|'`
 		;;
-	-sunos6*)
+	sunos6*)
 		os=`echo "$os" | sed -e 's|sunos6|solaris3|'`
 		;;
-	-opened*)
-		os=-openedition
+	wince*)
+		os=wince
 		;;
-	-os400*)
-		os=-os400
+	utek*)
+		os=bsd
 		;;
-	-wince*)
-		os=-wince
+	dynix*)
+		os=bsd
 		;;
-	-utek*)
-		os=-bsd
+	acis*)
+		os=aos
 		;;
-	-dynix*)
-		os=-bsd
+	atheos*)
+		os=atheos
 		;;
-	-acis*)
-		os=-aos
+	syllable*)
+		os=syllable
 		;;
-	-atheos*)
-		os=-atheos
+	386bsd)
+		os=bsd
 		;;
-	-syllable*)
-		os=-syllable
+	ctix* | uts*)
+		os=sysv
 		;;
-	-386bsd)
-		os=-bsd
+	nova*)
+		os=rtmk-nova
 		;;
-	-ctix* | -uts*)
-		os=-sysv
-		;;
-	-nova*)
-		os=-rtmk-nova
-		;;
-	-ns2)
-		os=-nextstep2
-		;;
-	-nsk*)
-		os=-nsk
+	ns2)
+		os=nextstep2
 		;;
 	# Preserve the version number of sinix5.
-	-sinix5.*)
-		os=`echo $os | sed -e 's|sinix|sysv|'`
+	sinix5.*)
+		os=`echo "$os" | sed -e 's|sinix|sysv|'`
 		;;
-	-sinix*)
-		os=-sysv4
+	sinix*)
+		os=sysv4
 		;;
-	-tpf*)
-		os=-tpf
+	tpf*)
+		os=tpf
 		;;
-	-triton*)
-		os=-sysv3
+	triton*)
+		os=sysv3
 		;;
-	-oss*)
-		os=-sysv3
+	oss*)
+		os=sysv3
 		;;
-	-svr4*)
-		os=-sysv4
+	svr4*)
+		os=sysv4
 		;;
-	-svr3)
-		os=-sysv3
+	svr3)
+		os=sysv3
 		;;
-	-sysvr4)
-		os=-sysv4
+	sysvr4)
+		os=sysv4
 		;;
-	# This must come after -sysvr4.
-	-sysv*)
+	ose*)
+		os=ose
 		;;
-	-ose*)
-		os=-ose
+	*mint | mint[0-9]* | *MiNT | MiNT[0-9]*)
+		os=mint
 		;;
-	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
-		os=-mint
+	dicos*)
+		os=dicos
 		;;
-	-zvmoe)
-		os=-zvmoe
-		;;
-	-dicos*)
-		os=-dicos
-		;;
-	-pikeos*)
+	pikeos*)
 		# Until real need of OS specific support for
 		# particular features comes up, bare metal
 		# configurations are quite functional.
-		case $basic_machine in
+		case $cpu in
 		    arm*)
-			os=-eabi
+			os=eabi
 			;;
 		    *)
-			os=-elf
+			os=elf
 			;;
 		esac
 		;;
-	-nacl*)
-		;;
-	-ios)
-		;;
-	-none)
-		;;
 	*)
-		# Get rid of the `-' at the beginning of $os.
-		os=`echo $os | sed 's/[^-]*-//'`
-		echo Invalid configuration \`"$1"\': system \`"$os"\' not recognized 1>&2
-		exit 1
+		# No normalization, but not necessarily accepted, that comes below.
 		;;
 esac
+
 else
 
 # Here we handle the default operating systems that come with various machines.
@@ -1543,258 +1527,363 @@
 # will signal an error saying that MANUFACTURER isn't an operating
 # system, and we'll never get to this point.
 
-case $basic_machine in
+kernel=
+case $cpu-$vendor in
 	score-*)
-		os=-elf
+		os=elf
 		;;
 	spu-*)
-		os=-elf
+		os=elf
 		;;
 	*-acorn)
-		os=-riscix1.2
+		os=riscix1.2
 		;;
 	arm*-rebel)
-		os=-linux
+		kernel=linux
+		os=gnu
 		;;
 	arm*-semi)
-		os=-aout
+		os=aout
 		;;
 	c4x-* | tic4x-*)
-		os=-coff
+		os=coff
 		;;
 	c8051-*)
-		os=-elf
+		os=elf
+		;;
+	clipper-intergraph)
+		os=clix
 		;;
 	hexagon-*)
-		os=-elf
+		os=elf
 		;;
 	tic54x-*)
-		os=-coff
+		os=coff
 		;;
 	tic55x-*)
-		os=-coff
+		os=coff
 		;;
 	tic6x-*)
-		os=-coff
+		os=coff
 		;;
 	# This must come before the *-dec entry.
 	pdp10-*)
-		os=-tops20
+		os=tops20
 		;;
 	pdp11-*)
-		os=-none
+		os=none
 		;;
 	*-dec | vax-*)
-		os=-ultrix4.2
+		os=ultrix4.2
 		;;
 	m68*-apollo)
-		os=-domain
+		os=domain
 		;;
 	i386-sun)
-		os=-sunos4.0.2
+		os=sunos4.0.2
 		;;
 	m68000-sun)
-		os=-sunos3
+		os=sunos3
 		;;
 	m68*-cisco)
-		os=-aout
+		os=aout
 		;;
 	mep-*)
-		os=-elf
+		os=elf
 		;;
 	mips*-cisco)
-		os=-elf
+		os=elf
 		;;
 	mips*-*)
-		os=-elf
+		os=elf
 		;;
 	or32-*)
-		os=-coff
+		os=coff
 		;;
 	*-tti)	# must be before sparc entry or we get the wrong os.
-		os=-sysv3
+		os=sysv3
 		;;
 	sparc-* | *-sun)
-		os=-sunos4.1.1
+		os=sunos4.1.1
 		;;
 	pru-*)
-		os=-elf
+		os=elf
 		;;
 	*-be)
-		os=-beos
+		os=beos
 		;;
 	*-ibm)
-		os=-aix
+		os=aix
 		;;
 	*-knuth)
-		os=-mmixware
+		os=mmixware
 		;;
 	*-wec)
-		os=-proelf
+		os=proelf
 		;;
 	*-winbond)
-		os=-proelf
+		os=proelf
 		;;
 	*-oki)
-		os=-proelf
+		os=proelf
 		;;
 	*-hp)
-		os=-hpux
+		os=hpux
 		;;
 	*-hitachi)
-		os=-hiux
+		os=hiux
 		;;
 	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
-		os=-sysv
+		os=sysv
 		;;
 	*-cbm)
-		os=-amigaos
+		os=amigaos
 		;;
 	*-dg)
-		os=-dgux
+		os=dgux
 		;;
 	*-dolphin)
-		os=-sysv3
+		os=sysv3
 		;;
 	m68k-ccur)
-		os=-rtu
+		os=rtu
 		;;
 	m88k-omron*)
-		os=-luna
+		os=luna
 		;;
 	*-next)
-		os=-nextstep
+		os=nextstep
 		;;
 	*-sequent)
-		os=-ptx
+		os=ptx
 		;;
 	*-crds)
-		os=-unos
+		os=unos
 		;;
 	*-ns)
-		os=-genix
+		os=genix
 		;;
 	i370-*)
-		os=-mvs
+		os=mvs
 		;;
 	*-gould)
-		os=-sysv
+		os=sysv
 		;;
 	*-highlevel)
-		os=-bsd
+		os=bsd
 		;;
 	*-encore)
-		os=-bsd
+		os=bsd
 		;;
 	*-sgi)
-		os=-irix
+		os=irix
 		;;
 	*-siemens)
-		os=-sysv4
+		os=sysv4
 		;;
 	*-masscomp)
-		os=-rtu
+		os=rtu
 		;;
 	f30[01]-fujitsu | f700-fujitsu)
-		os=-uxpv
+		os=uxpv
 		;;
 	*-rom68k)
-		os=-coff
+		os=coff
 		;;
 	*-*bug)
-		os=-coff
+		os=coff
 		;;
 	*-apple)
-		os=-macos
+		os=macos
 		;;
 	*-atari*)
-		os=-mint
+		os=mint
+		;;
+	*-wrs)
+		os=vxworks
 		;;
 	*)
-		os=-none
+		os=none
 		;;
 esac
+
 fi
 
+# Now, validate our (potentially fixed-up) OS.
+case $os in
+	# Sometimes we do "kernel-libc", so those need to count as OSes.
+	musl* | newlib* | relibc* | uclibc*)
+		;;
+	# Likewise for "kernel-abi"
+	eabi* | gnueabi*)
+		;;
+	# VxWorks passes extra cpu info in the 4th filed.
+	simlinux | simwindows | spe)
+		;;
+	# Now accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST end in a * to match a version number.
+	gnu* | android* | bsd* | mach* | minix* | genix* | ultrix* | irix* \
+	     | *vms* | esix* | aix* | cnk* | sunos | sunos[34]* \
+	     | hpux* | unos* | osf* | luna* | dgux* | auroraux* | solaris* \
+	     | sym* |  plan9* | psp* | sim* | xray* | os68k* | v88r* \
+	     | hiux* | abug | nacl* | netware* | windows* \
+	     | os9* | macos* | osx* | ios* \
+	     | mpw* | magic* | mmixware* | mon960* | lnews* \
+	     | amigaos* | amigados* | msdos* | newsos* | unicos* | aof* \
+	     | aos* | aros* | cloudabi* | sortix* | twizzler* \
+	     | nindy* | vxsim* | vxworks* | ebmon* | hms* | mvs* \
+	     | clix* | riscos* | uniplus* | iris* | isc* | rtu* | xenix* \
+	     | mirbsd* | netbsd* | dicos* | openedition* | ose* \
+	     | bitrig* | openbsd* | secbsd* | solidbsd* | libertybsd* | os108* \
+	     | ekkobsd* | freebsd* | riscix* | lynxos* | os400* \
+	     | bosx* | nextstep* | cxux* | aout* | elf* | oabi* \
+	     | ptx* | coff* | ecoff* | winnt* | domain* | vsta* \
+	     | udi* | lites* | ieee* | go32* | aux* | hcos* \
+	     | chorusrdb* | cegcc* | glidix* | serenity* \
+	     | cygwin* | msys* | pe* | moss* | proelf* | rtems* \
+	     | midipix* | mingw32* | mingw64* | mint* \
+	     | uxpv* | beos* | mpeix* | udk* | moxiebox* \
+	     | interix* | uwin* | mks* | rhapsody* | darwin* \
+	     | openstep* | oskit* | conix* | pw32* | nonstopux* \
+	     | storm-chaos* | tops10* | tenex* | tops20* | its* \
+	     | os2* | vos* | palmos* | uclinux* | nucleus* | morphos* \
+	     | scout* | superux* | sysv* | rtmk* | tpf* | windiss* \
+	     | powermax* | dnix* | nx6 | nx7 | sei* | dragonfly* \
+	     | skyos* | haiku* | rdos* | toppers* | drops* | es* \
+	     | onefs* | tirtos* | phoenix* | fuchsia* | redox* | bme* \
+	     | midnightbsd* | amdhsa* | unleashed* | emscripten* | wasi* \
+	     | nsk* | powerunix* | genode* | zvmoe* | qnx* | emx* | zephyr* \
+	     | fiwix* )
+		;;
+	# This one is extra strict with allowed versions
+	sco3.2v2 | sco3.2v[4-9]* | sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		;;
+	none)
+		;;
+	*)
+		echo Invalid configuration \`"$1"\': OS \`"$os"\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# As a final step for OS-related things, validate the OS-kernel combination
+# (given a valid OS), if there is a kernel.
+case $kernel-$os in
+	linux-gnu* | linux-dietlibc* | linux-android* | linux-newlib* \
+		   | linux-musl* | linux-relibc* | linux-uclibc* )
+		;;
+	uclinux-uclibc* )
+		;;
+	-dietlibc* | -newlib* | -musl* | -relibc* | -uclibc* )
+		# These are just libc implementations, not actual OSes, and thus
+		# require a kernel.
+		echo "Invalid configuration \`$1': libc \`$os' needs explicit kernel." 1>&2
+		exit 1
+		;;
+	kfreebsd*-gnu* | kopensolaris*-gnu*)
+		;;
+	vxworks-simlinux | vxworks-simwindows | vxworks-spe)
+		;;
+	nto-qnx*)
+		;;
+	os2-emx)
+		;;
+	*-eabi* | *-gnueabi*)
+		;;
+	-*)
+		# Blank kernel with real OS is always fine.
+		;;
+	*-*)
+		echo "Invalid configuration \`$1': Kernel \`$kernel' not known to work with OS \`$os'." 1>&2
+		exit 1
+		;;
+esac
+
 # Here we handle the case where we know the os, and the CPU type, but not the
 # manufacturer.  We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
-	*-unknown)
-		case $os in
-			-riscix*)
+case $vendor in
+	unknown)
+		case $cpu-$os in
+			*-riscix*)
 				vendor=acorn
 				;;
-			-sunos*)
+			*-sunos*)
 				vendor=sun
 				;;
-			-cnk*|-aix*)
+			*-cnk* | *-aix*)
 				vendor=ibm
 				;;
-			-beos*)
+			*-beos*)
 				vendor=be
 				;;
-			-hpux*)
+			*-hpux*)
 				vendor=hp
 				;;
-			-mpeix*)
+			*-mpeix*)
 				vendor=hp
 				;;
-			-hiux*)
+			*-hiux*)
 				vendor=hitachi
 				;;
-			-unos*)
+			*-unos*)
 				vendor=crds
 				;;
-			-dgux*)
+			*-dgux*)
 				vendor=dg
 				;;
-			-luna*)
+			*-luna*)
 				vendor=omron
 				;;
-			-genix*)
+			*-genix*)
 				vendor=ns
 				;;
-			-mvs* | -opened*)
+			*-clix*)
+				vendor=intergraph
+				;;
+			*-mvs* | *-opened*)
 				vendor=ibm
 				;;
-			-os400*)
+			*-os400*)
 				vendor=ibm
 				;;
-			-ptx*)
+			s390-* | s390x-*)
+				vendor=ibm
+				;;
+			*-ptx*)
 				vendor=sequent
 				;;
-			-tpf*)
+			*-tpf*)
 				vendor=ibm
 				;;
-			-vxsim* | -vxworks* | -windiss*)
+			*-vxsim* | *-vxworks* | *-windiss*)
 				vendor=wrs
 				;;
-			-aux*)
+			*-aux*)
 				vendor=apple
 				;;
-			-hms*)
+			*-hms*)
 				vendor=hitachi
 				;;
-			-mpw* | -macos*)
+			*-mpw* | *-macos*)
 				vendor=apple
 				;;
-			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+			*-*mint | *-mint[0-9]* | *-*MiNT | *-MiNT[0-9]*)
 				vendor=atari
 				;;
-			-vos*)
+			*-vos*)
 				vendor=stratus
 				;;
 		esac
-		basic_machine=`echo "$basic_machine" | sed "s/unknown/$vendor/"`
 		;;
 esac
 
-echo "$basic_machine$os"
+echo "$cpu-$vendor-${kernel:+$kernel-}$os"
 exit
 
 # Local variables:
-# eval: (add-hook 'write-file-functions 'time-stamp)
+# eval: (add-hook 'before-save-hook 'time-stamp)
 # time-stamp-start: "timestamp='"
 # time-stamp-format: "%:y-%02m-%02d"
 # time-stamp-end: "'"
diff --git a/Tools/config/depcomp b/Tools/config/depcomp
index 65cbf70..715e343 100755
--- a/Tools/config/depcomp
+++ b/Tools/config/depcomp
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2021 Free Software Foundation, Inc.
 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
diff --git a/Tools/config/install-sh b/Tools/config/install-sh
index 8175c64..ec298b5 100755
--- a/Tools/config/install-sh
+++ b/Tools/config/install-sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2018-03-11.20; # UTC
+scriptversion=2020-11-14.01; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -69,6 +69,11 @@
 # Desired mode of installed file.
 mode=0755
 
+# Create dirs (including intermediate dirs) using mode 755.
+# This is like GNU 'install' as of coreutils 8.32 (2020).
+mkdir_umask=22
+
+backupsuffix=
 chgrpcmd=
 chmodcmd=$chmodprog
 chowncmd=
@@ -99,18 +104,28 @@
      --version  display version info and exit.
 
   -c            (ignored)
-  -C            install only if different (preserve the last data modification time)
+  -C            install only if different (preserve data modification time)
   -d            create directories instead of installing files.
   -g GROUP      $chgrpprog installed files to GROUP.
   -m MODE       $chmodprog installed files to MODE.
   -o USER       $chownprog installed files to USER.
+  -p            pass -p to $cpprog.
   -s            $stripprog installed files.
+  -S SUFFIX     attempt to back up existing files, with suffix SUFFIX.
   -t DIRECTORY  install into DIRECTORY.
   -T            report an error if DSTFILE is a directory.
 
 Environment variables override the default commands:
   CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
   RMPROG STRIPPROG
+
+By default, rm is invoked with -f; when overridden with RMPROG,
+it's up to you to specify -f if you want it.
+
+If -S is not specified, no backups are attempted.
+
+Email bug reports to bug-automake@gnu.org.
+Automake home page: https://www.gnu.org/software/automake/
 "
 
 while test $# -ne 0; do
@@ -137,8 +152,13 @@
     -o) chowncmd="$chownprog $2"
         shift;;
 
+    -p) cpprog="$cpprog -p";;
+
     -s) stripcmd=$stripprog;;
 
+    -S) backupsuffix="$2"
+        shift;;
+
     -t)
         is_target_a_directory=always
         dst_arg=$2
@@ -255,6 +275,10 @@
     dstdir=$dst
     test -d "$dstdir"
     dstdir_status=$?
+    # Don't chown directories that already exist.
+    if test $dstdir_status = 0; then
+      chowncmd=""
+    fi
   else
 
     # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
@@ -301,22 +325,6 @@
   if test $dstdir_status != 0; then
     case $posix_mkdir in
       '')
-        # Create intermediate dirs using mode 755 as modified by the umask.
-        # This is like FreeBSD 'install' as of 1997-10-28.
-        umask=`umask`
-        case $stripcmd.$umask in
-          # Optimize common cases.
-          *[2367][2367]) mkdir_umask=$umask;;
-          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
-
-          *[0-7])
-            mkdir_umask=`expr $umask + 22 \
-              - $umask % 100 % 40 + $umask % 20 \
-              - $umask % 10 % 4 + $umask % 2
-            `;;
-          *) mkdir_umask=$umask,go-w;;
-        esac
-
         # With -d, create the new directory with the user-specified mode.
         # Otherwise, rely on $mkdir_umask.
         if test -n "$dir_arg"; then
@@ -326,52 +334,49 @@
         fi
 
         posix_mkdir=false
-        case $umask in
-          *[123567][0-7][0-7])
-            # POSIX mkdir -p sets u+wx bits regardless of umask, which
-            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
-            ;;
-          *)
-            # Note that $RANDOM variable is not portable (e.g. dash);  Use it
-            # here however when possible just to lower collision chance.
-            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+	# The $RANDOM variable is not portable (e.g., dash).  Use it
+	# here however when possible just to lower collision chance.
+	tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
 
-            trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
+	trap '
+	  ret=$?
+	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null
+	  exit $ret
+	' 0
 
-            # Because "mkdir -p" follows existing symlinks and we likely work
-            # directly in world-writeable /tmp, make sure that the '$tmpdir'
-            # directory is successfully created first before we actually test
-            # 'mkdir -p' feature.
-            if (umask $mkdir_umask &&
-                $mkdirprog $mkdir_mode "$tmpdir" &&
-                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
-            then
-              if test -z "$dir_arg" || {
-                   # Check for POSIX incompatibilities with -m.
-                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
-                   # other-writable bit of parent directory when it shouldn't.
-                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
-                   test_tmpdir="$tmpdir/a"
-                   ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
-                   case $ls_ld_tmpdir in
-                     d????-?r-*) different_mode=700;;
-                     d????-?--*) different_mode=755;;
-                     *) false;;
-                   esac &&
-                   $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
-                     ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
-                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
-                   }
-                 }
-              then posix_mkdir=:
-              fi
-              rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
-            else
-              # Remove any dirs left behind by ancient mkdir implementations.
-              rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
-            fi
-            trap '' 0;;
-        esac;;
+	# Because "mkdir -p" follows existing symlinks and we likely work
+	# directly in world-writeable /tmp, make sure that the '$tmpdir'
+	# directory is successfully created first before we actually test
+	# 'mkdir -p'.
+	if (umask $mkdir_umask &&
+	    $mkdirprog $mkdir_mode "$tmpdir" &&
+	    exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
+	then
+	  if test -z "$dir_arg" || {
+	       # Check for POSIX incompatibilities with -m.
+	       # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+	       # other-writable bit of parent directory when it shouldn't.
+	       # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+	       test_tmpdir="$tmpdir/a"
+	       ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
+	       case $ls_ld_tmpdir in
+		 d????-?r-*) different_mode=700;;
+		 d????-?--*) different_mode=755;;
+		 *) false;;
+	       esac &&
+	       $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
+		 ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
+		 test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+	       }
+	     }
+	  then posix_mkdir=:
+	  fi
+	  rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
+	else
+	  # Remove any dirs left behind by ancient mkdir implementations.
+	  rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
+	fi
+	trap '' 0;;
     esac
 
     if
@@ -382,7 +387,7 @@
     then :
     else
 
-      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # mkdir does not conform to POSIX,
       # or it failed possibly due to a race condition.  Create the
       # directory the slow way, step by step, checking for races as we go.
 
@@ -411,7 +416,7 @@
           prefixes=
         else
           if $posix_mkdir; then
-            (umask=$mkdir_umask &&
+            (umask $mkdir_umask &&
              $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
             # Don't fail if two instances are running concurrently.
             test -d "$prefix" || exit 1
@@ -451,7 +456,18 @@
     trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
 
     # Copy the file name to the temp name.
-    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+    (umask $cp_umask &&
+     { test -z "$stripcmd" || {
+	 # Create $dsttmp read-write so that cp doesn't create it read-only,
+	 # which would cause strip to fail.
+	 if test -z "$doit"; then
+	   : >"$dsttmp" # No need to fork-exec 'touch'.
+	 else
+	   $doit touch "$dsttmp"
+	 fi
+       }
+     } &&
+     $doit_exec $cpprog "$src" "$dsttmp") &&
 
     # and set any options; do chmod last to preserve setuid bits.
     #
@@ -477,6 +493,13 @@
     then
       rm -f "$dsttmp"
     else
+      # If $backupsuffix is set, and the file being installed
+      # already exists, attempt a backup.  Don't worry if it fails,
+      # e.g., if mv doesn't support -f.
+      if test -n "$backupsuffix" && test -f "$dst"; then
+        $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null
+      fi
+
       # Rename the file to the real destination.
       $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
 
@@ -491,9 +514,9 @@
         # file should still install successfully.
         {
           test ! -f "$dst" ||
-          $doit $rmcmd -f "$dst" 2>/dev/null ||
+          $doit $rmcmd "$dst" 2>/dev/null ||
           { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
-            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+            { $doit $rmcmd "$rmtmp" 2>/dev/null; :; }
           } ||
           { echo "$0: cannot unlink or rename $dst" >&2
             (exit 1); exit 1
diff --git a/Tools/config/m4_ax_cxx_compile_stdcxx.m4 b/Tools/config/m4_ax_cxx_compile_stdcxx.m4
new file mode 100644
index 0000000..51a3505
--- /dev/null
+++ b/Tools/config/m4_ax_cxx_compile_stdcxx.m4
@@ -0,0 +1,1005 @@
+# ===========================================================================
+#  https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
+#
+# DESCRIPTION
+#
+#   Check for baseline language coverage in the compiler for the specified
+#   version of the C++ standard.  If necessary, add switches to CXX and
+#   CXXCPP to enable support.  VERSION may be '11', '14', '17', or '20' for
+#   the respective C++ standard version.
+#
+#   The second argument, if specified, indicates whether you insist on an
+#   extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
+#   -std=c++11).  If neither is specified, you get whatever works, with
+#   preference for no added switch, and then for an extended mode.
+#
+#   The third argument, if specified 'mandatory' or if left unspecified,
+#   indicates that baseline support for the specified C++ standard is
+#   required and that the macro should error out if no mode with that
+#   support is found.  If specified 'optional', then configuration proceeds
+#   regardless, after defining HAVE_CXX${VERSION} if and only if a
+#   supporting mode is found.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
+#   Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
+#   Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
+#   Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
+#   Copyright (c) 2015 Paul Norman <penorman@mac.com>
+#   Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
+#   Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
+#   Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com>
+#   Copyright (c) 2020 Jason Merrill <jason@redhat.com>
+#   Copyright (c) 2021 Jörn Heusipp <osmanx@problemloesungsmaschine.de>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved.  This file is offered as-is, without any
+#   warranty.
+
+#serial 14
+
+dnl  This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
+dnl  (serial version number 13).
+
+AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
+  m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
+        [$1], [14], [ax_cxx_compile_alternatives="14 1y"],
+        [$1], [17], [ax_cxx_compile_alternatives="17 1z"],
+        [$1], [20], [ax_cxx_compile_alternatives="20"],
+        [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
+  m4_if([$2], [], [],
+        [$2], [ext], [],
+        [$2], [noext], [],
+        [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
+  m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
+        [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
+        [$3], [optional], [ax_cxx_compile_cxx$1_required=false],
+        [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
+  AC_LANG_PUSH([C++])dnl
+  ac_success=no
+
+  m4_if([$2], [], [dnl
+    AC_CACHE_CHECK(whether $CXX supports C++$1 features by default,
+		   ax_cv_cxx_compile_cxx$1,
+      [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
+        [ax_cv_cxx_compile_cxx$1=yes],
+        [ax_cv_cxx_compile_cxx$1=no])])
+    if test x$ax_cv_cxx_compile_cxx$1 = xyes; then
+      ac_success=yes
+    fi])
+
+  m4_if([$2], [noext], [], [dnl
+  if test x$ac_success = xno; then
+    for alternative in ${ax_cxx_compile_alternatives}; do
+      switch="-std=gnu++${alternative}"
+      cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
+      AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
+                     $cachevar,
+        [ac_save_CXX="$CXX"
+         CXX="$CXX $switch"
+         AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
+          [eval $cachevar=yes],
+          [eval $cachevar=no])
+         CXX="$ac_save_CXX"])
+      if eval test x\$$cachevar = xyes; then
+        CXX="$CXX $switch"
+        if test -n "$CXXCPP" ; then
+          CXXCPP="$CXXCPP $switch"
+        fi
+        ac_success=yes
+        break
+      fi
+    done
+  fi])
+
+  m4_if([$2], [ext], [], [dnl
+  if test x$ac_success = xno; then
+    dnl HP's aCC needs +std=c++11 according to:
+    dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
+    dnl Cray's crayCC needs "-h std=c++11"
+    for alternative in ${ax_cxx_compile_alternatives}; do
+      for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
+        cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
+        AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
+                       $cachevar,
+          [ac_save_CXX="$CXX"
+           CXX="$CXX $switch"
+           AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
+            [eval $cachevar=yes],
+            [eval $cachevar=no])
+           CXX="$ac_save_CXX"])
+        if eval test x\$$cachevar = xyes; then
+          CXX="$CXX $switch"
+          if test -n "$CXXCPP" ; then
+            CXXCPP="$CXXCPP $switch"
+          fi
+          ac_success=yes
+          break
+        fi
+      done
+      if test x$ac_success = xyes; then
+        break
+      fi
+    done
+  fi])
+  AC_LANG_POP([C++])
+  if test x$ax_cxx_compile_cxx$1_required = xtrue; then
+    if test x$ac_success = xno; then
+      AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
+    fi
+  fi
+  if test x$ac_success = xno; then
+    HAVE_CXX$1=0
+    AC_MSG_NOTICE([No compiler with C++$1 support was found])
+  else
+    HAVE_CXX$1=1
+    AC_DEFINE(HAVE_CXX$1,1,
+              [define if the compiler supports basic C++$1 syntax])
+  fi
+  AC_SUBST(HAVE_CXX$1)
+])
+
+
+dnl  Test body for checking C++11 support
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
+  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
+)
+
+dnl  Test body for checking C++14 support
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
+  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
+  _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
+)
+
+dnl  Test body for checking C++17 support
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
+  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
+  _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
+  _AX_CXX_COMPILE_STDCXX_testbody_new_in_17
+)
+
+dnl  Test body for checking C++20 support
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_20],
+  _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
+  _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
+  _AX_CXX_COMPILE_STDCXX_testbody_new_in_17
+  _AX_CXX_COMPILE_STDCXX_testbody_new_in_20
+)
+
+
+dnl  Tests for new features in C++11
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
+
+// If the compiler admits that it is not ready for C++11, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201103L
+
+#error "This is not a C++11 compiler"
+
+#else
+
+namespace cxx11
+{
+
+  namespace test_static_assert
+  {
+
+    template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+  }
+
+  namespace test_final_override
+  {
+
+    struct Base
+    {
+      virtual ~Base() {}
+      virtual void f() {}
+    };
+
+    struct Derived : public Base
+    {
+      virtual ~Derived() override {}
+      virtual void f() override {}
+    };
+
+  }
+
+  namespace test_double_right_angle_brackets
+  {
+
+    template < typename T >
+    struct check {};
+
+    typedef check<void> single_type;
+    typedef check<check<void>> double_type;
+    typedef check<check<check<void>>> triple_type;
+    typedef check<check<check<check<void>>>> quadruple_type;
+
+  }
+
+  namespace test_decltype
+  {
+
+    int
+    f()
+    {
+      int a = 1;
+      decltype(a) b = 2;
+      return a + b;
+    }
+
+  }
+
+  namespace test_type_deduction
+  {
+
+    template < typename T1, typename T2 >
+    struct is_same
+    {
+      static const bool value = false;
+    };
+
+    template < typename T >
+    struct is_same<T, T>
+    {
+      static const bool value = true;
+    };
+
+    template < typename T1, typename T2 >
+    auto
+    add(T1 a1, T2 a2) -> decltype(a1 + a2)
+    {
+      return a1 + a2;
+    }
+
+    int
+    test(const int c, volatile int v)
+    {
+      static_assert(is_same<int, decltype(0)>::value == true, "");
+      static_assert(is_same<int, decltype(c)>::value == false, "");
+      static_assert(is_same<int, decltype(v)>::value == false, "");
+      auto ac = c;
+      auto av = v;
+      auto sumi = ac + av + 'x';
+      auto sumf = ac + av + 1.0;
+      static_assert(is_same<int, decltype(ac)>::value == true, "");
+      static_assert(is_same<int, decltype(av)>::value == true, "");
+      static_assert(is_same<int, decltype(sumi)>::value == true, "");
+      static_assert(is_same<int, decltype(sumf)>::value == false, "");
+      static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
+      return (sumf > 0.0) ? sumi : add(c, v);
+    }
+
+  }
+
+  namespace test_noexcept
+  {
+
+    int f() { return 0; }
+    int g() noexcept { return 0; }
+
+    static_assert(noexcept(f()) == false, "");
+    static_assert(noexcept(g()) == true, "");
+
+  }
+
+  namespace test_constexpr
+  {
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
+    {
+      return *s ? strlen_c_r(s + 1, acc + 1) : acc;
+    }
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c(const CharT *const s) noexcept
+    {
+      return strlen_c_r(s, 0UL);
+    }
+
+    static_assert(strlen_c("") == 0UL, "");
+    static_assert(strlen_c("1") == 1UL, "");
+    static_assert(strlen_c("example") == 7UL, "");
+    static_assert(strlen_c("another\0example") == 7UL, "");
+
+  }
+
+  namespace test_rvalue_references
+  {
+
+    template < int N >
+    struct answer
+    {
+      static constexpr int value = N;
+    };
+
+    answer<1> f(int&)       { return answer<1>(); }
+    answer<2> f(const int&) { return answer<2>(); }
+    answer<3> f(int&&)      { return answer<3>(); }
+
+    void
+    test()
+    {
+      int i = 0;
+      const int c = 0;
+      static_assert(decltype(f(i))::value == 1, "");
+      static_assert(decltype(f(c))::value == 2, "");
+      static_assert(decltype(f(0))::value == 3, "");
+    }
+
+  }
+
+  namespace test_uniform_initialization
+  {
+
+    struct test
+    {
+      static const int zero {};
+      static const int one {1};
+    };
+
+    static_assert(test::zero == 0, "");
+    static_assert(test::one == 1, "");
+
+  }
+
+  namespace test_lambdas
+  {
+
+    void
+    test1()
+    {
+      auto lambda1 = [](){};
+      auto lambda2 = lambda1;
+      lambda1();
+      lambda2();
+    }
+
+    int
+    test2()
+    {
+      auto a = [](int i, int j){ return i + j; }(1, 2);
+      auto b = []() -> int { return '0'; }();
+      auto c = [=](){ return a + b; }();
+      auto d = [&](){ return c; }();
+      auto e = [a, &b](int x) mutable {
+        const auto identity = [](int y){ return y; };
+        for (auto i = 0; i < a; ++i)
+          a += b--;
+        return x + identity(a + b);
+      }(0);
+      return a + b + c + d + e;
+    }
+
+    int
+    test3()
+    {
+      const auto nullary = [](){ return 0; };
+      const auto unary = [](int x){ return x; };
+      using nullary_t = decltype(nullary);
+      using unary_t = decltype(unary);
+      const auto higher1st = [](nullary_t f){ return f(); };
+      const auto higher2nd = [unary](nullary_t f1){
+        return [unary, f1](unary_t f2){ return f2(unary(f1())); };
+      };
+      return higher1st(nullary) + higher2nd(nullary)(unary);
+    }
+
+  }
+
+  namespace test_variadic_templates
+  {
+
+    template <int...>
+    struct sum;
+
+    template <int N0, int... N1toN>
+    struct sum<N0, N1toN...>
+    {
+      static constexpr auto value = N0 + sum<N1toN...>::value;
+    };
+
+    template <>
+    struct sum<>
+    {
+      static constexpr auto value = 0;
+    };
+
+    static_assert(sum<>::value == 0, "");
+    static_assert(sum<1>::value == 1, "");
+    static_assert(sum<23>::value == 23, "");
+    static_assert(sum<1, 2>::value == 3, "");
+    static_assert(sum<5, 5, 11>::value == 21, "");
+    static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
+
+  }
+
+  // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
+  // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
+  // because of this.
+  namespace test_template_alias_sfinae
+  {
+
+    struct foo {};
+
+    template<typename T>
+    using member = typename T::member_type;
+
+    template<typename T>
+    void func(...) {}
+
+    template<typename T>
+    void func(member<T>*) {}
+
+    void test();
+
+    void test() { func<foo>(0); }
+
+  }
+
+}  // namespace cxx11
+
+#endif  // __cplusplus >= 201103L
+
+]])
+
+
+dnl  Tests for new features in C++14
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
+
+// If the compiler admits that it is not ready for C++14, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201402L
+
+#error "This is not a C++14 compiler"
+
+#else
+
+namespace cxx14
+{
+
+  namespace test_polymorphic_lambdas
+  {
+
+    int
+    test()
+    {
+      const auto lambda = [](auto&&... args){
+        const auto istiny = [](auto x){
+          return (sizeof(x) == 1UL) ? 1 : 0;
+        };
+        const int aretiny[] = { istiny(args)... };
+        return aretiny[0];
+      };
+      return lambda(1, 1L, 1.0f, '1');
+    }
+
+  }
+
+  namespace test_binary_literals
+  {
+
+    constexpr auto ivii = 0b0000000000101010;
+    static_assert(ivii == 42, "wrong value");
+
+  }
+
+  namespace test_generalized_constexpr
+  {
+
+    template < typename CharT >
+    constexpr unsigned long
+    strlen_c(const CharT *const s) noexcept
+    {
+      auto length = 0UL;
+      for (auto p = s; *p; ++p)
+        ++length;
+      return length;
+    }
+
+    static_assert(strlen_c("") == 0UL, "");
+    static_assert(strlen_c("x") == 1UL, "");
+    static_assert(strlen_c("test") == 4UL, "");
+    static_assert(strlen_c("another\0test") == 7UL, "");
+
+  }
+
+  namespace test_lambda_init_capture
+  {
+
+    int
+    test()
+    {
+      auto x = 0;
+      const auto lambda1 = [a = x](int b){ return a + b; };
+      const auto lambda2 = [a = lambda1(x)](){ return a; };
+      return lambda2();
+    }
+
+  }
+
+  namespace test_digit_separators
+  {
+
+    constexpr auto ten_million = 100'000'000;
+    static_assert(ten_million == 100000000, "");
+
+  }
+
+  namespace test_return_type_deduction
+  {
+
+    auto f(int& x) { return x; }
+    decltype(auto) g(int& x) { return x; }
+
+    template < typename T1, typename T2 >
+    struct is_same
+    {
+      static constexpr auto value = false;
+    };
+
+    template < typename T >
+    struct is_same<T, T>
+    {
+      static constexpr auto value = true;
+    };
+
+    int
+    test()
+    {
+      auto x = 0;
+      static_assert(is_same<int, decltype(f(x))>::value, "");
+      static_assert(is_same<int&, decltype(g(x))>::value, "");
+      return x;
+    }
+
+  }
+
+}  // namespace cxx14
+
+#endif  // __cplusplus >= 201402L
+
+]])
+
+
+dnl  Tests for new features in C++17
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
+
+// If the compiler admits that it is not ready for C++17, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201703L
+
+#error "This is not a C++17 compiler"
+
+#else
+
+#include <initializer_list>
+#include <utility>
+#include <type_traits>
+
+namespace cxx17
+{
+
+  namespace test_constexpr_lambdas
+  {
+
+    constexpr int foo = [](){return 42;}();
+
+  }
+
+  namespace test::nested_namespace::definitions
+  {
+
+  }
+
+  namespace test_fold_expression
+  {
+
+    template<typename... Args>
+    int multiply(Args... args)
+    {
+      return (args * ... * 1);
+    }
+
+    template<typename... Args>
+    bool all(Args... args)
+    {
+      return (args && ...);
+    }
+
+  }
+
+  namespace test_extended_static_assert
+  {
+
+    static_assert (true);
+
+  }
+
+  namespace test_auto_brace_init_list
+  {
+
+    auto foo = {5};
+    auto bar {5};
+
+    static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
+    static_assert(std::is_same<int, decltype(bar)>::value);
+  }
+
+  namespace test_typename_in_template_template_parameter
+  {
+
+    template<template<typename> typename X> struct D;
+
+  }
+
+  namespace test_fallthrough_nodiscard_maybe_unused_attributes
+  {
+
+    int f1()
+    {
+      return 42;
+    }
+
+    [[nodiscard]] int f2()
+    {
+      [[maybe_unused]] auto unused = f1();
+
+      switch (f1())
+      {
+      case 17:
+        f1();
+        [[fallthrough]];
+      case 42:
+        f1();
+      }
+      return f1();
+    }
+
+  }
+
+  namespace test_extended_aggregate_initialization
+  {
+
+    struct base1
+    {
+      int b1, b2 = 42;
+    };
+
+    struct base2
+    {
+      base2() {
+        b3 = 42;
+      }
+      int b3;
+    };
+
+    struct derived : base1, base2
+    {
+        int d;
+    };
+
+    derived d1 {{1, 2}, {}, 4};  // full initialization
+    derived d2 {{}, {}, 4};      // value-initialized bases
+
+  }
+
+  namespace test_general_range_based_for_loop
+  {
+
+    struct iter
+    {
+      int i;
+
+      int& operator* ()
+      {
+        return i;
+      }
+
+      const int& operator* () const
+      {
+        return i;
+      }
+
+      iter& operator++()
+      {
+        ++i;
+        return *this;
+      }
+    };
+
+    struct sentinel
+    {
+      int i;
+    };
+
+    bool operator== (const iter& i, const sentinel& s)
+    {
+      return i.i == s.i;
+    }
+
+    bool operator!= (const iter& i, const sentinel& s)
+    {
+      return !(i == s);
+    }
+
+    struct range
+    {
+      iter begin() const
+      {
+        return {0};
+      }
+
+      sentinel end() const
+      {
+        return {5};
+      }
+    };
+
+    void f()
+    {
+      range r {};
+
+      for (auto i : r)
+      {
+        [[maybe_unused]] auto v = i;
+      }
+    }
+
+  }
+
+  namespace test_lambda_capture_asterisk_this_by_value
+  {
+
+    struct t
+    {
+      int i;
+      int foo()
+      {
+        return [*this]()
+        {
+          return i;
+        }();
+      }
+    };
+
+  }
+
+  namespace test_enum_class_construction
+  {
+
+    enum class byte : unsigned char
+    {};
+
+    byte foo {42};
+
+  }
+
+  namespace test_constexpr_if
+  {
+
+    template <bool cond>
+    int f ()
+    {
+      if constexpr(cond)
+      {
+        return 13;
+      }
+      else
+      {
+        return 42;
+      }
+    }
+
+  }
+
+  namespace test_selection_statement_with_initializer
+  {
+
+    int f()
+    {
+      return 13;
+    }
+
+    int f2()
+    {
+      if (auto i = f(); i > 0)
+      {
+        return 3;
+      }
+
+      switch (auto i = f(); i + 4)
+      {
+      case 17:
+        return 2;
+
+      default:
+        return 1;
+      }
+    }
+
+  }
+
+  namespace test_template_argument_deduction_for_class_templates
+  {
+
+    template <typename T1, typename T2>
+    struct pair
+    {
+      pair (T1 p1, T2 p2)
+        : m1 {p1},
+          m2 {p2}
+      {}
+
+      T1 m1;
+      T2 m2;
+    };
+
+    void f()
+    {
+      [[maybe_unused]] auto p = pair{13, 42u};
+    }
+
+  }
+
+  namespace test_non_type_auto_template_parameters
+  {
+
+    template <auto n>
+    struct B
+    {};
+
+    B<5> b1;
+    B<'a'> b2;
+
+  }
+
+  namespace test_structured_bindings
+  {
+
+    int arr[2] = { 1, 2 };
+    std::pair<int, int> pr = { 1, 2 };
+
+    auto f1() -> int(&)[2]
+    {
+      return arr;
+    }
+
+    auto f2() -> std::pair<int, int>&
+    {
+      return pr;
+    }
+
+    struct S
+    {
+      int x1 : 2;
+      volatile double y1;
+    };
+
+    S f3()
+    {
+      return {};
+    }
+
+    auto [ x1, y1 ] = f1();
+    auto& [ xr1, yr1 ] = f1();
+    auto [ x2, y2 ] = f2();
+    auto& [ xr2, yr2 ] = f2();
+    const auto [ x3, y3 ] = f3();
+
+  }
+
+  namespace test_exception_spec_type_system
+  {
+
+    struct Good {};
+    struct Bad {};
+
+    void g1() noexcept;
+    void g2();
+
+    template<typename T>
+    Bad
+    f(T*, T*);
+
+    template<typename T1, typename T2>
+    Good
+    f(T1*, T2*);
+
+    static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
+
+  }
+
+  namespace test_inline_variables
+  {
+
+    template<class T> void f(T)
+    {}
+
+    template<class T> inline T g(T)
+    {
+      return T{};
+    }
+
+    template<> inline void f<>(int)
+    {}
+
+    template<> int g<>(int)
+    {
+      return 5;
+    }
+
+  }
+
+}  // namespace cxx17
+
+#endif  // __cplusplus < 201703L
+
+]])
+
+
+dnl  Tests for new features in C++20
+
+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_20], [[
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 202002L
+
+#error "This is not a C++20 compiler"
+
+#else
+
+#include <version>
+
+namespace cxx20
+{
+
+// As C++20 supports feature test macros in the standard, there is no
+// immediate need to actually test for feature availability on the
+// Autoconf side.
+
+}  // namespace cxx20
+
+#endif  // __cplusplus < 202002L
+
+]])
diff --git a/Tools/config/missing b/Tools/config/missing
index 625aeb1..1fe1611 100755
--- a/Tools/config/missing
+++ b/Tools/config/missing
@@ -3,7 +3,7 @@
 
 scriptversion=2018-03-07.03; # UTC
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2021 Free Software Foundation, Inc.
 # Originally written by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
 
 # This program is free software; you can redistribute it and/or modify
diff --git a/Tools/config/ylwrap b/Tools/config/ylwrap
deleted file mode 100755
index 5943168..0000000
--- a/Tools/config/ylwrap
+++ /dev/null
@@ -1,247 +0,0 @@
-#! /bin/sh
-# ylwrap - wrapper for lex/yacc invocations.
-
-scriptversion=2018-03-07.03; # UTC
-
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
-#
-# Written by Tom Tromey <tromey@cygnus.com>.
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-# This file is maintained in Automake, please report
-# bugs to <bug-automake@gnu.org> or send patches to
-# <automake-patches@gnu.org>.
-
-get_dirname ()
-{
-  case $1 in
-    */*|*\\*) printf '%s\n' "$1" | sed -e 's|\([\\/]\)[^\\/]*$|\1|';;
-    # Otherwise,  we want the empty string (not ".").
-  esac
-}
-
-# guard FILE
-# ----------
-# The CPP macro used to guard inclusion of FILE.
-guard ()
-{
-  printf '%s\n' "$1"                                                    \
-    | sed                                                               \
-        -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'   \
-        -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'                        \
-        -e 's/__*/_/g'
-}
-
-# quote_for_sed [STRING]
-# ----------------------
-# Return STRING (or stdin) quoted to be used as a sed pattern.
-quote_for_sed ()
-{
-  case $# in
-    0) cat;;
-    1) printf '%s\n' "$1";;
-  esac \
-    | sed -e 's|[][\\.*]|\\&|g'
-}
-
-case "$1" in
-  '')
-    echo "$0: No files given.  Try '$0 --help' for more information." 1>&2
-    exit 1
-    ;;
-  --basedir)
-    basedir=$2
-    shift 2
-    ;;
-  -h|--h*)
-    cat <<\EOF
-Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]...
-
-Wrapper for lex/yacc invocations, renaming files as desired.
-
-  INPUT is the input file
-  OUTPUT is one file PROG generates
-  DESIRED is the file we actually want instead of OUTPUT
-  PROGRAM is program to run
-  ARGS are passed to PROG
-
-Any number of OUTPUT,DESIRED pairs may be used.
-
-Report bugs to <bug-automake@gnu.org>.
-EOF
-    exit $?
-    ;;
-  -v|--v*)
-    echo "ylwrap $scriptversion"
-    exit $?
-    ;;
-esac
-
-
-# The input.
-input=$1
-shift
-# We'll later need for a correct munging of "#line" directives.
-input_sub_rx=`get_dirname "$input" | quote_for_sed`
-case $input in
-  [\\/]* | ?:[\\/]*)
-    # Absolute path; do nothing.
-    ;;
-  *)
-    # Relative path.  Make it absolute.
-    input=`pwd`/$input
-    ;;
-esac
-input_rx=`get_dirname "$input" | quote_for_sed`
-
-# Since DOS filename conventions don't allow two dots,
-# the DOS version of Bison writes out y_tab.c instead of y.tab.c
-# and y_tab.h instead of y.tab.h. Test to see if this is the case.
-y_tab_nodot=false
-if test -f y_tab.c || test -f y_tab.h; then
-  y_tab_nodot=true
-fi
-
-# The parser itself, the first file, is the destination of the .y.c
-# rule in the Makefile.
-parser=$1
-
-# A sed program to s/FROM/TO/g for all the FROM/TO so that, for
-# instance, we rename #include "y.tab.h" into #include "parse.h"
-# during the conversion from y.tab.c to parse.c.
-sed_fix_filenames=
-
-# Also rename header guards, as Bison 2.7 for instance uses its header
-# guard in its implementation file.
-sed_fix_header_guards=
-
-while test $# -ne 0; do
-  if test x"$1" = x"--"; then
-    shift
-    break
-  fi
-  from=$1
-  # Handle y_tab.c and y_tab.h output by DOS
-  if $y_tab_nodot; then
-    case $from in
-      "y.tab.c") from=y_tab.c;;
-      "y.tab.h") from=y_tab.h;;
-    esac
-  fi
-  shift
-  to=$1
-  shift
-  sed_fix_filenames="${sed_fix_filenames}s|"`quote_for_sed "$from"`"|$to|g;"
-  sed_fix_header_guards="${sed_fix_header_guards}s|"`guard "$from"`"|"`guard "$to"`"|g;"
-done
-
-# The program to run.
-prog=$1
-shift
-# Make any relative path in $prog absolute.
-case $prog in
-  [\\/]* | ?:[\\/]*) ;;
-  *[\\/]*) prog=`pwd`/$prog ;;
-esac
-
-dirname=ylwrap$$
-do_exit="cd '`pwd`' && rm -rf $dirname > /dev/null 2>&1;"' (exit $ret); exit $ret'
-trap "ret=129; $do_exit" 1
-trap "ret=130; $do_exit" 2
-trap "ret=141; $do_exit" 13
-trap "ret=143; $do_exit" 15
-mkdir $dirname || exit 1
-
-cd $dirname
-
-case $# in
-  0) "$prog" "$input" ;;
-  *) "$prog" "$@" "$input" ;;
-esac
-ret=$?
-
-if test $ret -eq 0; then
-  for from in *
-  do
-    to=`printf '%s\n' "$from" | sed "$sed_fix_filenames"`
-    if test -f "$from"; then
-      # If $2 is an absolute path name, then just use that,
-      # otherwise prepend '../'.
-      case $to in
-        [\\/]* | ?:[\\/]*) target=$to;;
-        *) target=../$to;;
-      esac
-
-      # Do not overwrite unchanged header files to avoid useless
-      # recompilations.  Always update the parser itself: it is the
-      # destination of the .y.c rule in the Makefile.  Divert the
-      # output of all other files to a temporary file so we can
-      # compare them to existing versions.
-      if test $from != $parser; then
-        realtarget=$target
-        target=tmp-`printf '%s\n' "$target" | sed 's|.*[\\/]||g'`
-      fi
-
-      # Munge "#line" or "#" directives.  Don't let the resulting
-      # debug information point at an absolute srcdir.  Use the real
-      # output file name, not yy.lex.c for instance.  Adjust the
-      # include guards too.
-      sed -e "/^#/!b"                           \
-          -e "s|$input_rx|$input_sub_rx|"       \
-          -e "$sed_fix_filenames"               \
-          -e "$sed_fix_header_guards"           \
-        "$from" >"$target" || ret=$?
-
-      # Check whether files must be updated.
-      if test "$from" != "$parser"; then
-        if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then
-          echo "$to is unchanged"
-          rm -f "$target"
-        else
-          echo "updating $to"
-          mv -f "$target" "$realtarget"
-        fi
-      fi
-    else
-      # A missing file is only an error for the parser.  This is a
-      # blatant hack to let us support using "yacc -d".  If -d is not
-      # specified, don't fail when the header file is "missing".
-      if test "$from" = "$parser"; then
-        ret=1
-      fi
-    fi
-  done
-fi
-
-# Remove the directory.
-cd ..
-rm -rf $dirname
-
-exit $ret
-
-# Local Variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'before-save-hook 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-time-zone: "UTC0"
-# time-stamp-end: "; # UTC"
-# End:
diff --git a/Tools/javascript/Makefile.in b/Tools/javascript/Makefile.in
index 5eeec07..6335d0a 100644
--- a/Tools/javascript/Makefile.in
+++ b/Tools/javascript/Makefile.in
@@ -32,12 +32,6 @@
 srcdir = @srcdir@
 
 
-ifneq (, $(V8_VERSION))
-    JSV8_VERSION=$(V8_VERSION)
-else
-    JSV8_VERSION=0x031110
-endif
-
 # Regenerate Makefile if Makefile.in or config.status have changed.
 Makefile: $(srcdir)/Makefile.in ../../config.status
 	cd ../.. && $(SHELL) ./config.status Tools/javascript/Makefile
@@ -45,7 +39,7 @@
 # These settings are provided by 'configure' (see '/configure.in')
 ifeq (1, $(JSV8ENABLED))
 JS_INTERPRETER_SRC_V8 = v8_shell.cxx
-JS_INTERPRETER_ENABLE_V8 = -DENABLE_V8 -DSWIG_V8_VERSION=$(JSV8_VERSION) -DV8_DEPRECATION_WARNINGS
+JS_INTERPRETER_ENABLE_V8 = -DENABLE_V8 -DV8_DEPRECATION_WARNINGS
 endif
 
 ifeq (1, $(JSCENABLED))
diff --git a/Tools/javascript/js_shell.cxx b/Tools/javascript/js_shell.cxx
index 539b83d..470d641 100644
--- a/Tools/javascript/js_shell.cxx
+++ b/Tools/javascript/js_shell.cxx
@@ -63,7 +63,7 @@
   }
 
   if(handle == 0) {
-    std::cerr << "Could not find module " << lib_path << ":"
+    std::cerr << "Could not find module " << lib_path << ':'
               << std::endl << LIBRARY_ERROR() << std::endl;
     return 0;
   }
@@ -120,7 +120,7 @@
     }
     file.close();
   } else {
-    std::cout << "Unable to open file " << fileName << "." << std::endl;
+    std::cout << "Unable to open file " << fileName << '.' << std::endl;
   }
 
   return script;
diff --git a/Tools/javascript/jsc_shell.cxx b/Tools/javascript/jsc_shell.cxx
index 292c404..fadd6be 100644
--- a/Tools/javascript/jsc_shell.cxx
+++ b/Tools/javascript/jsc_shell.cxx
@@ -18,7 +18,7 @@
 
 public:
 
-  JSCShell() {};
+  JSCShell() { context = 0; }
 
   virtual ~JSCShell();
 
@@ -225,7 +225,7 @@
   int line = (int) JSValueToNumber(ctx, jsLine, 0);
   JSStringRelease(lineKey);
 
-  std::cerr << sourceURL << ":" << line << ":" << errMsg << std::endl;
+  std::cerr << sourceURL << ':' << line << ':' << errMsg << std::endl;
 }
 
 JSShell* JSCShell_Create() {
diff --git a/Tools/javascript/v8_shell.cxx b/Tools/javascript/v8_shell.cxx
index 5001bc2..008f632 100644
--- a/Tools/javascript/v8_shell.cxx
+++ b/Tools/javascript/v8_shell.cxx
@@ -11,59 +11,26 @@
 
 typedef int (*V8ExtensionInitializer) (v8::Handle<v8::Object> module);
 
-// Note: these typedefs and defines are used to deal with  v8 API changes since version 3.19.00
+// Note: these typedefs and defines are used to deal with v8 API changes since version 3.19.00
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031903)
-typedef v8::Handle<v8::Value> SwigV8ReturnValue;
-typedef v8::Arguments SwigV8Arguments;
-typedef v8::AccessorInfo SwigV8PropertyCallbackInfo;
-#define SWIGV8_RETURN(val) return scope.Close(val)
-#define SWIGV8_RETURN_INFO(val, info) return scope.Close(val)
-#else
 typedef void SwigV8ReturnValue;
 typedef v8::FunctionCallbackInfo<v8::Value> SwigV8Arguments;
 typedef v8::PropertyCallbackInfo<v8::Value> SwigV8PropertyCallbackInfo;
 #define SWIGV8_RETURN(val) args.GetReturnValue().Set(val); return
 #define SWIGV8_RETURN_INFO(val, info) info.GetReturnValue().Set(val); return
-#endif
 
-
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032117)
-#define SWIGV8_HANDLESCOPE() v8::HandleScope scope
-#define SWIGV8_HANDLESCOPE_ESC() v8::HandleScope scope
-#define SWIGV8_ESCAPE(val) return scope.Close(val)
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032318)
-#define SWIGV8_HANDLESCOPE() v8::HandleScope scope(v8::Isolate::GetCurrent());
-#define SWIGV8_HANDLESCOPE_ESC() v8::HandleScope scope(v8::Isolate::GetCurrent());
-#define SWIGV8_ESCAPE(val) return scope.Close(val)
-#else
 #define SWIGV8_HANDLESCOPE() v8::HandleScope scope(v8::Isolate::GetCurrent());
 #define SWIGV8_HANDLESCOPE_ESC() v8::EscapableHandleScope scope(v8::Isolate::GetCurrent());
 #define SWIGV8_ESCAPE(val) return scope.Escape(val)
-#endif
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x032318)
-#define SWIGV8_CURRENT_CONTEXT() v8::Context::GetCurrent()
-#define SWIGV8_STRING_NEW(str) v8::String::New(str)
-#define SWIGV8_FUNCTEMPLATE_NEW(func) v8::FunctionTemplate::New(func)
-#define SWIGV8_OBJECT_NEW() v8::Object::New()
-#define SWIGV8_EXTERNAL_NEW(val) v8::External::New(val)
-#define SWIGV8_UNDEFINED() v8::Undefined()
-#else
 #define SWIGV8_CURRENT_CONTEXT() v8::Isolate::GetCurrent()->GetCurrentContext()
 #define SWIGV8_STRING_NEW(str) v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), str)
 #define SWIGV8_FUNCTEMPLATE_NEW(func) v8::FunctionTemplate::New(v8::Isolate::GetCurrent(), func)
 #define SWIGV8_OBJECT_NEW() v8::Object::New(v8::Isolate::GetCurrent())
 #define SWIGV8_EXTERNAL_NEW(val) v8::External::New(v8::Isolate::GetCurrent(), val)
 #define SWIGV8_UNDEFINED() v8::Undefined(v8::Isolate::GetCurrent())
-#endif
 
-
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-typedef v8::Persistent<v8::Context> SwigV8Context;
-#else
 typedef v8::Local<v8::Context> SwigV8Context;
-#endif
 
 class V8Shell: public JSShell {
 
@@ -149,13 +116,7 @@
 
   context->Exit();
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-    context.Dispose();
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-    context.Dispose(v8::Isolate::GetCurrent());
-#else
 //    context.Dispose();
-#endif
 
 //  v8::V8::Dispose();
 
@@ -193,13 +154,7 @@
 
   context->Exit();
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031710)
-    context.Dispose();
-#elif (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-    context.Dispose(v8::Isolate::GetCurrent());
-#else
 //    context.Dispose();
-#endif
 
 //  v8::V8::Dispose();
 
@@ -249,13 +204,8 @@
   global->Set(SWIGV8_STRING_NEW("require"), SWIGV8_FUNCTEMPLATE_NEW(V8Shell::Require));
   global->Set(SWIGV8_STRING_NEW("version"), SWIGV8_FUNCTEMPLATE_NEW(V8Shell::Version));
 
-#if (V8_MAJOR_VERSION-0) < 4 && (SWIG_V8_VERSION < 0x031900)
-  SwigV8Context context = v8::Context::New(NULL, global);
-  return context;
-#else
   SwigV8Context context = v8::Context::New(v8::Isolate::GetCurrent(), NULL, global);
   return context;
-#endif
 }
 
 v8::Handle<v8::Value> V8Shell::Import(const std::string &module_path)
@@ -307,7 +257,7 @@
 
   if (args.Length() != 1) {
     printf("Illegal arguments for `require`");
-  };
+  }
 
   v8::String::Utf8Value str(args[0]);
   const char *cstr = V8Shell::ToCString(str);
diff --git a/Tools/mkdist.py b/Tools/mkdist.py
index 47cf8e7..f008ba6 100755
--- a/Tools/mkdist.py
+++ b/Tools/mkdist.py
@@ -3,6 +3,7 @@
 import sys
 import os
 import subprocess
+from utils import *
 
 def failed():
     print("mkdist.py failed to complete")
@@ -22,6 +23,15 @@
 force_tag = args.force_tag
 skip_checks = args.skip_checks
 
+# Tools directory path $ENV/swig/Tools
+toolsdir = os.path.dirname(os.path.abspath(__file__))
+# Root directory path (swig) $ENV/swig
+rootdir = os.path.abspath(os.path.join(toolsdir, os.pardir))
+# current directory
+current_dir = os.getcwd()
+# version directory path $ENV/swig/<x.x.x>
+dirpath = os.path.join(current_dir, dirname)
+
 if sys.version_info[0:2] < (2, 7):
      print("Error: Python 2.7 or higher is required")
      sys.exit(3)
@@ -32,22 +42,27 @@
     sys.exit(3)
 
 # If directory and tarball exist, remove it
-print("Removing " + dirname)
-os.system("rm -rf " + dirname)
+if check_dir_exists(dirpath):
+    print("Removing " + dirpath)
+    run_command("rm", "-rf", dirpath)
 
-print("Removing " + dirname + ".tar if exists")
-os.system("rm -f " + dirname + ".tar.gz")
+filename = dirpath + ".tar"
+if check_file_exists(filename):
+    print("Removing " + filename)
+    run_command("rm", "-rf", filename)
 
-print("Removing " + dirname + ".tar.gz if exists")
-os.system("rm -f " + dirname + ".tar")
+filename += ".gz"
+if check_file_exists(filename):
+    print("Removing " + filename)
+    run_command("rm", "-rf", filename)
 
 # Grab the code from git
 
 print("Checking there are no local changes in git repo")
-os.system("git remote update origin") == 0 or failed()
+run_command("git", "remote", "update", "origin") == 0 or failed()
 command = ["git", "status", "--porcelain", "-uno"]
 out = subprocess.check_output(command)
-if out.strip() != "":
+if out.strip():
     print("Local git repository has modifications")
     print(" ".join(command))
     print(out)
@@ -57,7 +72,7 @@
     print("Checking git repository is in sync with remote repository")
     command = ["git", "log", "--oneline", branch + "..origin/" + branch]
     out = subprocess.check_output(command)
-    if out.strip() != "":
+    if out.strip():
         print("Remote repository has additional modifications to local repository")
         print(" ".join(command))
         print(out)
@@ -65,7 +80,7 @@
 
     command = ["git", "log", "--oneline", "origin/" + branch + ".." + branch]
     out = subprocess.check_output(command)
-    if out.strip() != "":
+    if out.strip():
         print("Local repository has modifications not pushed to the remote repository")
         print("These should be pushed and checked that they pass Continuous Integration testing before continuing")
         print(" ".join(command))
@@ -73,31 +88,48 @@
         sys.exit(3)
 
 print("Tagging release")
-tag = "'rel-" + version + "'"
-force = "-f " if force_tag else ""
-os.system("git tag -a -m " + tag + " " + force + tag) == 0 or failed()
+tag = "v" + version
+force = "-f" if force_tag else ""
+command = ["git", "tag", "-a", "-m", "'Release version " + version + "'"]
+force and command.append(force)
+command.append(tag)
+run_command(*command) == 0 or failed()
 
-outdir = os.path.basename(os.getcwd()) + "/" + dirname + "/"
+outdir = dirname + "/"
 print("Grabbing tagged release git repository using 'git archive' into " + outdir)
-os.system("(cd .. && git archive --prefix=" + outdir + " " + tag + " . | tar -xf -)") == 0 or failed()
+
+# using pipe operator without shell=True; split commands into individual ones.
+# git archive command
+command = ["git", "archive", "--prefix=" + outdir, tag, "."]
+archive_ps = subprocess.Popen(command, cwd=rootdir, stdout=subprocess.PIPE)
+# tar -xf -
+tar_ps = subprocess.Popen(("tar", "-xf", "-"), stdin=archive_ps.stdout, stdout=subprocess.PIPE)
+archive_ps.stdout.close()  # Allow archive_ps to receive a SIGPIPE if tar_ps exits.
+output = tar_ps.communicate()
 
 # Go build the system
 
 print("Building system")
-os.system("cd " + dirname + " && ./autogen.sh") == 0 or failed()
-os.system("cd " + dirname + "/Source/CParse && bison -y -d parser.y && mv y.tab.c parser.c && mv y.tab.h parser.h") == 0 or failed()
-os.system("cd " + dirname + " && make -f Makefile.in libfiles srcdir=./") == 0 or failed()
+run_command("mkdir", "-p", dirpath)
+run_command("./autogen.sh", cwd=dirpath) == 0 or failed()
 
-# Remove autoconf files
-os.system("find " + dirname + " -name autom4te.cache -exec rm -rf {} \\;")
+run_command("./configure", cwd=dirpath) == 0 or failed()
+run_command("make", "-CSource", "CParse/parser.c", cwd=dirpath) == 0 or failed()
+
+run_command("make", "libfiles", cwd=dirpath) == 0 or failed()
+
+run_command("make", "distclean", cwd=dirpath) == 0 or failed()
+
+# Remove autotools files
+run_command("find", dirname, "-name", ".deps", "-exec", "rmdir", "{}", ";", cwd=rootdir)
 
 # Build documentation
 print("Building html documentation")
-os.system("cd " + dirname + "/Doc/Manual && make all clean-baks") == 0 or failed()
+docpath = os.path.join(dirpath, "Doc", "Manual")
+run_command("make", "all", "clean-baks", cwd=docpath) == 0 or failed()
 
 # Build the tar-ball
-os.system("tar -cf " + dirname + ".tar " + dirname) == 0 or failed()
-os.system("gzip " + dirname + ".tar") == 0 or failed()
+run_command("tar", "-czf", dirname + ".tar.gz", dirname) == 0 or failed()
 
 print("Finished building " + dirname + ".tar.gz")
 
diff --git a/Tools/mkrelease.py b/Tools/mkrelease.py
index 014cef2..28dca26 100755
--- a/Tools/mkrelease.py
+++ b/Tools/mkrelease.py
@@ -2,6 +2,7 @@
 
 import sys
 import os
+from utils import *
 
 def failed(message):
   if message == "":
@@ -27,15 +28,17 @@
 username = args.username
 
 print("Looking for rsync")
-os.system("which rsync") and failed("rsync not installed/found. Please install.")
+run_command("which", "rsync") and failed("rsync not installed/found. Please install.")
 
 print("Making source tarball")
 force = "--force-tag" if force_tag else ""
 skip = "--skip-checks" if skip_checks else ""
-os.system("python ./mkdist.py {} {} --branch {} {}".format(force, skip, branch, version)) and failed("")
+toolsdir = os.path.dirname(os.path.abspath(__file__))
+cmd = "python {}/mkdist.py {} {} --branch {} {}".format(toolsdir, force, skip, branch, version).split()
+run_command(*cmd) and failed("")
 
 print("Build Windows package")
-os.system("./mkwindows.sh " + version) and failed("")
+run_command("{}/mkwindows.sh".format(toolsdir), version) and failed("")
 
 if username:
     print("Uploading to SourceForge")
@@ -45,11 +48,11 @@
 
     # If a file with 'readme' in the name exists in the same folder as the zip/tarball, it gets automatically displayed as the release notes by SF
     full_readme_file = "readme-" + version + ".txt"
-    os.system("rm -f " + full_readme_file)
-    os.system("cat swig-" + version + "/README " + "swig-" + version + "/CHANGES.current " + "swig-" + version + "/RELEASENOTES " + "> " + full_readme_file)
+    run_command("rm", "-f", full_readme_file)
+    run_command("cat", "swig-" + version + "/README", "swig-" + version + "/CHANGES.current", "swig-" + version + "/RELEASENOTES", ">", full_readme_file)
 
-    os.system("rsync --archive --verbose -P --times -e ssh " + "swig-" + version + ".tar.gz " + full_readme_file + " " + swig_dir_sf) and failed("")
-    os.system("rsync --archive --verbose -P --times -e ssh " + "swigwin-" + version + ".zip " + full_readme_file + " " + swigwin_dir_sf) and failed("")
+    run_command("rsync", "--archive", "--verbose", "-P", "--times", "-e", "ssh", "swig-" + version + ".tar.gz", full_readme_file, swig_dir_sf) and failed("")
+    run_command("rsync", "--archive", "--verbose", "-P", "--times", "-e", "ssh", "swigwin-" + version + ".zip", full_readme_file, swigwin_dir_sf) and failed("")
 
     print("Finished")
 
diff --git a/Tools/mkwindows.sh b/Tools/mkwindows.sh
index e6ae843..b2dd9d1 100755
--- a/Tools/mkwindows.sh
+++ b/Tools/mkwindows.sh
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-# Build Windows distribution (swigwin-2.0.x.zip) from source tarball (swig-2.0.x.tar.gz)
+# Build Windows distribution (swigwin-x.y.z.zip) from source tarball (swig-x.y.x.tar.gz)
 # Requires running in either:
 # - MinGW environment
 # - Linux using MinGW cross compiler
@@ -23,8 +23,8 @@
     fi
 else
     echo "Usage: mkwindows.sh version [zip]"
-    echo "       Build SWIG Windows distribution from source tarball. Works on Cygwin, MinGW or Linux"
-    echo "       version should be 2.0.x"
+    echo "       Build SWIG Windows distribution from source tarball. Works on Cygwin, MinGW or Linux."
+    echo "       version should be in format x.y.z, for example 4.1.0"
     echo "       zip is full path to zip program - default is /c/cygwin/bin/zip on MinGW, zip on Linux and Cygwin"
     exit 1
 fi
@@ -84,10 +84,10 @@
 swigbasename=swig-$version
 swigwinbasename=swigwin-$version
 tarball=$swigbasename.tar.gz
-pcre_tarball=`ls pcre-*.tar.*`
+pcre_tarball=`ls pcre2-*.tar.*`
 
 if ! test -f "$pcre_tarball"; then
-  echo "Could not find PCRE tarball. Please download a PCRE source tarball from http://www.pcre.org"
+  echo "Could not find PCRE2 tarball. Please download a PCRE2 source tarball from https://www.pcre.org"
   echo "and place in the same directory as the SWIG tarball."
   exit 1
 fi
@@ -115,8 +115,9 @@
       ./configure $extraconfigureoptions --without-alllang
       echo "Compiling (quietly)..."
       make > build.log
-      echo "Simple check to see if swig.exe runs..."
+      echo "Simple check to see if swig.exe runs and show versions..."
       env LD_LIBRARY_PATH= PATH= $wine ./swig.exe -version || exit 1
+      env LD_LIBRARY_PATH= PATH= $wine ./swig.exe -pcreversion || exit 1
       echo "Simple check to see if ccache-swig.exe runs..."
       env LD_LIBRARY_PATH= PATH= $wine ./CCache/ccache-swig.exe -V || exit 1
       echo "Creating $swigwinbasename.zip..."
diff --git a/Tools/nuget-install.cmd b/Tools/nuget-install.cmd
deleted file mode 100644
index eec7f87..0000000
--- a/Tools/nuget-install.cmd
+++ /dev/null
@@ -1,28 +0,0 @@
-rem Workaround 'nuget install' not being reliable by retrying a few times
-@echo off
-rem initiate the retry number
-set errorCode=1
-set retryNumber=0
-set maxRetries=5
-
-:RESTORE
-nuget install %*
-
-rem problem?
-IF ERRORLEVEL %errorCode% GOTO :RETRY
-
-rem everything is fine!
-@echo Installed nuget, retries: %reTryNumber%
-GOTO :EXIT
-
-:RETRY
-@echo Oops, nuget restore exited with code %errorCode% - let us try again!
-set /a retryNumber=%retryNumber%+1
-IF %reTryNumber% LSS %maxRetries% (GOTO :RESTORE)
-IF %retryNumber% EQU %maxRetries% (GOTO :ERR)
-
-:ERR
-@echo Sorry, we tried restoring nuget packages for %maxRetries% times and all attempts were unsuccessful!
-EXIT /B 1
-
-:EXIT
diff --git a/Tools/pcre-build.sh b/Tools/pcre-build.sh
index 92f645d..ff088c6 100755
--- a/Tools/pcre-build.sh
+++ b/Tools/pcre-build.sh
@@ -4,17 +4,17 @@
 pcre_install_dir=`pwd`/$pcre_subdir
 
 usage() {
-  echo "Helper script to build PCRE as a static library from a tarball just for use during the"
-  echo "SWIG build. It does not install PCRE for global use on your system."
+  echo "Helper script to build PCRE2 as a static library from a tarball just for use during the"
+  echo "SWIG build. It does not install PCRE2 for global use on your system."
   echo "Usage: pcre-build.sh [--help] [args]"
-  echo "  args   - optional additional arguments passed on to the PCRE configure script (leave out"
+  echo "  args   - optional additional arguments passed on to the PCRE2 configure script (leave out"
   echo "         unless you are an expert at configure)"
   echo "  --help - Display this help information."
   echo "Instructions:"
-  echo "  - Download the latest PCRE source tarball from http://www.pcre.org and place in the"
+  echo "  - Download the latest PCRE2 source tarball from https://www.pcre.org and place in the"
   echo "    directory that you will configure and build SWIG."
   echo "  - Run this script in the same directory that you intend to configure and build SWIG in."
-  echo "    This will configure and build PCRE as a static library."
+  echo "    This will configure and build PCRE2 as a static library."
   echo "  - Afterwards run the SWIG configure script which will then find and use the PCRE static"
   echo "    libraries in the $pcre_subdir subdirectory."
   exit 0
@@ -35,21 +35,21 @@
   usage
 fi
 
-echo "Looking for PCRE tarball..."
+echo "Looking for PCRE2 tarball..."
 rm -rf pcre
-pcre_tarball=`ls pcre-*.tar*`
-test -n "$pcre_tarball" || bail "Could not find tarball matching pattern: pcre-*.tar*"
-test -f "$pcre_tarball" || bail "Could not find a single PCRE tarball. Found: $pcre_tarball"
+pcre_tarball=`ls pcre2-*.tar*`
+test -n "$pcre_tarball" || bail "Could not find tarball matching pattern: pcre2-*.tar*"
+test -f "$pcre_tarball" || bail "Could not find a single PCRE2 tarball. Found: $pcre_tarball"
 
 echo "Extracting tarball: $pcre_tarball"
 tar -xf $pcre_tarball || bail "Could not untar $pcre_tarball"
 pcre_dir=`echo $pcre_tarball | sed -e "s/\.tar.*//"`
 echo "Configuring PCRE in directory: pcre"
 mv $pcre_dir pcre || bail "Could not create pcre directory"
-cd pcre && ./configure --prefix=$pcre_install_dir --disable-shared $* || bail "PCRE configure failed"
-echo "Building PCRE..."
-${MAKE:-make} -s || bail "Could not build PCRE"
-echo "Installing PCRE locally to $pcre_install_dir..."
-${MAKE:-make} -s install || bail "Could not install PCRE"
+cd pcre && ./configure --prefix=$pcre_install_dir --disable-shared $* || bail "PCRE2 configure failed"
+echo "Building PCRE2..."
+${MAKE:-make} -s || bail "Could not build PCRE2"
+echo "Installing PCRE2 locally to $pcre_install_dir..."
+${MAKE:-make} -s install || bail "Could not install PCRE2"
 echo ""
-echo "The SWIG configure script can now be run, whereupon PCRE will automatically be detected and used from $pcre_install_dir/bin/pcre-config."
+echo "The SWIG configure script can now be run, whereupon PCRE2 will automatically be detected and used from $pcre_install_dir/bin/pcre-config."
diff --git a/Tools/setup.py.tmpl b/Tools/setup.py.tmpl
index 0bfcde2..ab7833f 100644
--- a/Tools/setup.py.tmpl
+++ b/Tools/setup.py.tmpl
@@ -97,7 +97,6 @@
 
         if self.swig_shadow:
             swig_cmd.append('-shadow')
-## swig1.1            swig_cmd.append('-docstring')
 
         for source in swig_sources:
             target = swig_targets[source]
diff --git a/Tools/testflags.py b/Tools/testflags.py
index f3d216b..16e4d8a 100755
--- a/Tools/testflags.py
+++ b/Tools/testflags.py
@@ -3,11 +3,15 @@
 def get_cflags(language, std, compiler):
     if std == None or len(std) == 0:
         std = "gnu89"
-    c_common = "-fdiagnostics-show-option -std=" + std + " -Wno-long-long -Wreturn-type -Wdeclaration-after-statement -Wmissing-field-initializers"
+    c_common = "-fdiagnostics-show-option -std=" + std + " -Wno-long-long -Wreturn-type -Wmissing-field-initializers"
+    if std == "gnu89" or std == "gnu90":
+        # gnu89 standard allows declaration after headers
+        # use c99 or gnu99 if feature is necessary for using target language
+        c_common = c_common + " -Wdeclaration-after-statement"
     cflags = {
         "csharp":"-Werror " + c_common,
              "d":"-Werror " + c_common,
-            "go":"-Werror " + c_common + " -Wno-declaration-after-statement",
+            "go":"-Werror " + c_common,
          "guile":"-Werror " + c_common,
           "java":"-Werror " + c_common,
     "javascript":"-Werror " + c_common,
diff --git a/Tools/travis-linux-install.sh b/Tools/travis-linux-install.sh
deleted file mode 100755
index 37ef841..0000000
--- a/Tools/travis-linux-install.sh
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/bin/bash
-
-# Install Linux packages where the version has been overidden in .travis.yml
-
-set -e # exit on failure (same as -o errexit)
-
-lsb_release -a
-travis_retry sudo apt-get -qq update
-
-if [[ -n "$GCC" ]]; then
-	travis_retry sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
-	travis_retry sudo apt-get -qq update
-	travis_retry sudo apt-get install -qq g++-$GCC
-fi
-
-travis_retry sudo apt-get -qq install libboost-dev
-
-WITHLANG=$SWIGLANG
-
-case "$SWIGLANG" in
-	"")     ;;
-	"csharp")
-		travis_retry sudo apt-get -qq install mono-devel
-		;;
-	"d")
-		travis_retry wget http://downloads.dlang.org/releases/2014/dmd_2.066.0-0_amd64.deb
-		travis_retry sudo dpkg -i dmd_2.066.0-0_amd64.deb
-		;;
-	"go")
-		if [[ "$VER" ]]; then
-		  eval "$(gimme ${VER}.x)"
-		fi
-		;;
-	"javascript")
-		case "$ENGINE" in
-			"node")
-				travis_retry wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.10/install.sh | bash
-				export NVM_DIR="$HOME/.nvm"
-				[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
-				travis_retry nvm install ${VER}
-				nvm use ${VER}
-				if [ "$VER" == "0.10" ] || [ "$VER" == "0.12" ] || [ "$VER" == "4" ] ; then
-#					travis_retry sudo apt-get install -qq nodejs node-gyp
-					travis_retry npm install -g node-gyp@$VER
-				else
-					travis_retry npm install -g node-gyp
-				fi
-				;;
-			"jsc")
-				travis_retry sudo apt-get install -qq libwebkitgtk-dev
-				;;
-			"v8")
-				travis_retry sudo apt-get install -qq libv8-dev
-				;;
-		esac
-		;;
-	"guile")
-		travis_retry sudo apt-get -qq install guile-2.0-dev
-		;;
-	"lua")
-		if [[ -z "$VER" ]]; then
-			travis_retry sudo apt-get -qq install lua5.2 liblua5.2-dev
-		else
-			travis_retry sudo apt-get -qq install lua${VER} liblua${VER}-dev
-		fi
-		;;
-	"mzscheme")
-		travis_retry sudo apt-get -qq install racket
-		;;
-	"ocaml")
-		travis_retry sudo apt-get -qq install ocaml camlp4
-		;;
-	"octave")
-		if [[ -z "$VER" ]]; then
-			travis_retry sudo apt-get -qq install liboctave-dev
-		else
-			# Travis adds external PPAs which contain newer versions of packages
-			# than in baseline trusty. These newer packages prevent some of the
-			# Octave packages in ppa:kwwette/octave, which rely on the older
-			# packages in trusty, from installing. To prevent these kind of
-			# interactions arising, clean out all external PPAs added by Travis
-			# before installing Octave
-			sudo rm -rf /etc/apt/sources.list.d/*
-			travis_retry sudo apt-get -qq update
-			travis_retry sudo add-apt-repository -y ppa:kwwette/octaves
-			travis_retry sudo apt-get -qq update
-			travis_retry sudo apt-get -qq install liboctave${VER}-dev
-		fi
-		;;
-	"php")
-		travis_retry sudo add-apt-repository -y ppa:ondrej/php
-		travis_retry sudo apt-get -qq update
-		travis_retry sudo apt-get -qq install php$VER-cli php$VER-dev
-		;;
-	"python")
-		pip install --user pycodestyle
-		if [[ "$PY3" ]]; then
-			travis_retry sudo apt-get install -qq python3-dev
-		fi
-		WITHLANG=$SWIGLANG$PY3
-		if [[ "$VER" ]]; then
-			travis_retry sudo add-apt-repository -y ppa:deadsnakes/ppa
-			travis_retry sudo apt-get -qq update
-			travis_retry sudo apt-get -qq install python${VER}-dev
-			WITHLANG=$SWIGLANG$PY3=$SWIGLANG$VER
-		fi
-		;;
-	"r")
-		travis_retry sudo apt-get -qq install r-base
-		;;
-	"ruby")
-		if [[ "$VER" ]]; then
-			travis_retry rvm install $VER
-		fi
-		;;
-	"scilab")
-		# Travis has the wrong version of Java pre-installed resulting in error using scilab:
-		# /usr/bin/scilab-bin: error while loading shared libraries: libjava.so: cannot open shared object file: No such file or directory
-		echo "JAVA_HOME was set to $JAVA_HOME"
-		unset JAVA_HOME
-		travis_retry sudo apt-get -qq install scilab
-		;;
-	"tcl")
-		travis_retry sudo apt-get -qq install tcl-dev
-		;;
-esac
-
-set +e # turn off exit on failure (same as +o errexit)
diff --git a/Tools/travis-osx-install.sh b/Tools/travis-osx-install.sh
deleted file mode 100755
index 393d96e..0000000
--- a/Tools/travis-osx-install.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/bash
-
-# Install MacOS packages where the version has been overidden in .travis.yml
-
-set -e # exit on failure (same as -o errexit)
-
-sw_vers
-travis_retry brew update
-travis_retry brew list
-# travis_retry brew install pcre # Travis Xcode-7.3 has pcre
-# travis_retry brew install boost
-
-WITHLANG=$SWIGLANG
-
-case "$SWIGLANG" in
-	"csharp")
-		travis_retry brew install mono
-		;;
-	"guile")
-		travis_retry Tools/brew-install guile
-		;;
-	"lua")
-		travis_retry brew install lua
-		;;
-	"octave")
-		travis_retry brew install octave
-		;;
-	"python")
-		WITHLANG=$SWIGLANG$PY3
-		;;
-esac
-
-# Workaround for https://github.com/travis-ci/travis-ci/issues/6522
-set +e # turn off exit on failure (same as +o errexit)
diff --git a/Tools/utils.py b/Tools/utils.py
new file mode 100644
index 0000000..496882f
--- /dev/null
+++ b/Tools/utils.py
@@ -0,0 +1,26 @@
+import os, subprocess
+
+
+def check_file_exists(path):
+    """
+    Checks if a file exists or not.
+    """
+    return os.path.isfile(path)
+
+
+def check_dir_exists(path):
+    """
+    Checks if a folder exists or not.
+    """
+    return os.path.isdir(path)
+
+
+def run_command(*args, **kwargs):
+    """
+    Runs an os command using subprocess module.
+    """
+    redirect_out = list(map(str.strip, " ".join(args).split(" > ")))
+    if len(redirect_out) > 1:
+        args, filepath = redirect_out[0].split(), redirect_out[-1]
+        kwargs.update(stdout=open(filepath, "w"))
+    return subprocess.call(args, **kwargs)
diff --git a/aclocal.m4 b/aclocal.m4
index 7a18418..3e27536 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.5 -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2021 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -14,13 +14,13 @@
 m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.69],,
-[m4_warning([this file was generated for autoconf 2.69.
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.71],,
+[m4_warning([this file was generated for autoconf 2.71.
 You have another version of autoconf.  It may work, but is not guaranteed to.
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically 'autoreconf'.])])
 
-# Copyright (C) 2002-2018 Free Software Foundation, Inc.
+# Copyright (C) 2002-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -35,7 +35,7 @@
 [am__api_version='1.16'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.16.1], [],
+m4_if([$1], [1.16.5], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -51,14 +51,14 @@
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.16.1])dnl
+[AM_AUTOMAKE_VERSION([1.16.5])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -110,7 +110,7 @@
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2018 Free Software Foundation, Inc.
+# Copyright (C) 1997-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -141,7 +141,7 @@
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -332,7 +332,7 @@
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -371,7 +371,9 @@
   done
   if test $am_rc -ne 0; then
     AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
-    for automatic dependency tracking.  Try re-running configure with the
+    for automatic dependency tracking.  If GNU make was not used, consider
+    re-running the configure script with MAKE="gmake" (or whatever is
+    necessary).  You can also try re-running configure with the
     '--disable-dependency-tracking' option to at least be able to build
     the package (albeit without support for automatic dependency tracking).])
   fi
@@ -398,7 +400,7 @@
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -426,6 +428,10 @@
 # release and drop the old call support.
 AC_DEFUN([AM_INIT_AUTOMAKE],
 [AC_PREREQ([2.65])dnl
+m4_ifdef([_$0_ALREADY_INIT],
+  [m4_fatal([$0 expanded multiple times
+]m4_defn([_$0_ALREADY_INIT]))],
+  [m4_define([_$0_ALREADY_INIT], m4_expansion_stack)])dnl
 dnl Autoconf wants to disallow AM_ names.  We explicitly allow
 dnl the ones we care about.
 m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
@@ -462,7 +468,7 @@
 [_AM_SET_OPTIONS([$1])dnl
 dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
 m4_if(
-  m4_ifdef([AC_PACKAGE_NAME], [ok]):m4_ifdef([AC_PACKAGE_VERSION], [ok]),
+  m4_ifset([AC_PACKAGE_NAME], [ok]):m4_ifset([AC_PACKAGE_VERSION], [ok]),
   [ok:ok],,
   [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
  AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
@@ -514,6 +520,20 @@
 		  [m4_define([AC_PROG_OBJCXX],
 			     m4_defn([AC_PROG_OBJCXX])[_AM_DEPENDENCIES([OBJCXX])])])dnl
 ])
+# Variables for tags utilities; see am/tags.am
+if test -z "$CTAGS"; then
+  CTAGS=ctags
+fi
+AC_SUBST([CTAGS])
+if test -z "$ETAGS"; then
+  ETAGS=etags
+fi
+AC_SUBST([ETAGS])
+if test -z "$CSCOPE"; then
+  CSCOPE=cscope
+fi
+AC_SUBST([CSCOPE])
+
 AC_REQUIRE([AM_SILENT_RULES])dnl
 dnl The testsuite driver may need to know about EXEEXT, so add the
 dnl 'am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen.  This
@@ -595,7 +615,7 @@
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -616,7 +636,7 @@
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2018 Free Software Foundation, Inc.
+# Copyright (C) 2003-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -637,7 +657,7 @@
 
 # Check to see how 'make' treats includes.	            -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -680,7 +700,7 @@
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2018 Free Software Foundation, Inc.
+# Copyright (C) 1997-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -701,12 +721,7 @@
 [AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
 AC_REQUIRE_AUX_FILE([missing])dnl
 if test x"${MISSING+set}" != xset; then
-  case $am_aux_dir in
-  *\ * | *\	*)
-    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
-  *)
-    MISSING="\${SHELL} $am_aux_dir/missing" ;;
-  esac
+  MISSING="\${SHELL} '$am_aux_dir/missing'"
 fi
 # Use eval to expand $SHELL
 if eval "$MISSING --is-lightweight"; then
@@ -719,7 +734,7 @@
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -748,7 +763,7 @@
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -795,7 +810,7 @@
 # For backward compatibility.
 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -814,7 +829,7 @@
 
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -895,7 +910,7 @@
 rm -f conftest.file
 ])
 
-# Copyright (C) 2009-2018 Free Software Foundation, Inc.
+# Copyright (C) 2009-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -955,7 +970,7 @@
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -983,7 +998,7 @@
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2018 Free Software Foundation, Inc.
+# Copyright (C) 2006-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1002,7 +1017,7 @@
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2018 Free Software Foundation, Inc.
+# Copyright (C) 2004-2021 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1137,5 +1152,5 @@
 m4_include([Tools/config/ac_define_dir.m4])
 m4_include([Tools/config/ax_boost_base.m4])
 m4_include([Tools/config/ax_compare_version.m4])
-m4_include([Tools/config/ax_cxx_compile_stdcxx_11.m4])
 m4_include([Tools/config/ax_path_generic.m4])
+m4_include([Tools/config/m4_ax_cxx_compile_stdcxx.m4])
diff --git a/appveyor.yml b/appveyor.yml
index 42eaa36..b9ca637 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,7 +1,13 @@
 platform:
-- x86
 - x64
 
+skip_commits:
+  files:
+    - '.github/**'
+    - 'CHANGES*'
+    - 'Doc/**'
+    - 'Tools/CI-*'
+
 environment:
   global:
     MAKEJOBS: 2
@@ -11,25 +17,66 @@
     VSVER: 12
   - SWIGLANG: csharp
     VSVER: 14
-  - SWIGLANG: java
-    VSVER: 14
   - SWIGLANG: python
     VSVER: 14
     VER: 27
-  - SWIGLANG: python
+    PY2: 2
+  - BUILDSYSTEM: cmake
     VSVER: 14
-    VER: 36
-    PY3: 3
+  - SWIGLANG: python
+    VSVER: 15
+    VER: 38
+    APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
+  - SWIGLANG: python
+    VSVER: 16
+    VER: 39
+    APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
+  - SWIGLANG: csharp
+    VSVER: 17
+    APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
+  - SWIGLANG: csharp
+    VSVER: 17
+    Platform: x86
+    APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
+  - SWIGLANG: java
+    VSVER: 17
+    APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
+  - SWIGLANG: java
+    VSVER: 17
+    Platform: x86
+    APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
+  - SWIGLANG: python
+    VSVER: 17
+    VER: 310
+    APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
+  - SWIGLANG: python
+    VSVER: 17
+    VER: 310
+    Platform: x86
+    APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
   - SWIGLANG: python
     OSVARIANT: cygwin
-  - SWIGLANG: python
+    APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
+  - SWIGLANG: java
     OSVARIANT: mingw
-    VER: 27
+    APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
   - SWIGLANG: python
     OSVARIANT: mingw
     WITHLANG: python
-    VER: 37
-    PY3: 3
+    APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022
+
+#matrix:
+#  allow_failures:
+#  - SWIGLANG: python
+#    OSVARIANT: cygwin
+
+# Skip stale commits (pull requests only), see https://github.com/appveyor/ci/issues/38#issuecomment-70628826
+init:
+- ps: |
+    if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
+        https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
+        Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
+        throw "There are newer queued builds for this pull request, failing early." }
 
 install:
 - date /T & time /T
@@ -45,9 +92,10 @@
       $env:MINGWBIN="C:\msys64\mingw32\bin"
       $env:MBITS="32"
       $env:MARCH="i686"
+      $env:VSARCH=""
     } else {
       $env:PCRE_PLATFORM="x64"
-      $env:JAVA_HOME="C:/Program Files/Java/jdk1.8.0"
+      $env:JAVA_HOME="C:/Program Files/Java/jdk17"
       $env:VCVARS_PLATFORM="amd64"
       $env:LANG_PLATFORM="-x64"
       $env:CYGWINBIN="C:\cygwin64\bin"
@@ -56,14 +104,31 @@
       $env:MINGWBIN="C:\msys64\mingw64\bin"
       $env:MBITS="64"
       $env:MARCH="x86_64"
+      $env:VSARCH=" Win64"
     }
 - ps: >-
     if (!$env:OSVARIANT) {
       $env:PATH="$env:CYGWINBIN;$env:PATH"
       $env:CYGWIN="nodosfilewarning"
-      $env:VSCOMNTOOLS=(Get-Content ("env:VS" + "$env:VSVER" + "0COMNTOOLS"))
       $env:CC="cccl"
       $env:CXX="cccl"
+      if ($env:VSVER -ge 17) {
+        $env:VCVARSBAT="C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvars$env:MBITS.bat"
+        $env:BOOSTROOT="C:/Libraries/boost_1_83_0"
+      } elseif ($env:VSVER -eq 16) {
+        $env:VCVARSBAT="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars$env:MBITS.bat"
+        $env:BOOSTROOT="C:/Libraries/boost_1_83_0"
+      } elseif ($env:VSVER -eq 15) {
+        $env:VCVARSBAT="C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars$env:MBITS.bat"
+        $env:BOOSTROOT="C:/Libraries/boost_1_69_0"
+        nuget install Bison -Version 3.7.4 -OutputDirectory C:\Tools\bison
+      } else {
+        $env:VSCOMNTOOLS=(Get-Content ("env:VS" + "$env:VSVER" + "0COMNTOOLS"))
+        $env:VCVARSBAT="$env:VSCOMNTOOLS..\..\VC\vcvarsall.bat"
+        $env:VCVARSARG="$env:VCVARS_PLATFORM"
+        $env:BOOSTROOT="C:/Libraries/boost_1_69_0"
+        nuget install Bison -Version 3.7.4 -OutputDirectory C:\Tools\bison
+      }
     } elseif ($env:OSVARIANT -eq "cygwin") {
       $env:PATH="$env:CYGWINBIN;$env:PATH"
       $env:CYGWIN="nodosfilewarning"
@@ -75,24 +140,23 @@
       $env:MSYSTEM="MINGW$env:MBITS" # This is important for msys2
       $env:CC="gcc"
       $env:CXX="g++"
-      if ($env:MBITS -eq "64" -and $env:SWIGLANG -eq "python") {
-        $env:CHECK_OPTIONS2="CFLAGS+=-DMS_WIN64 CXXFLAGS+=-DMS_WIN64"
-      }
     }
-- if "%OSVARIANT%"=="" bash -c "cd /usr/bin && curl --retry 15 -s -L https://github.com/swig/cccl/archive/cccl-1.0.tar.gz | tar -xz --strip 1 cccl-cccl-1.0/cccl"
-- if "%OSVARIANT%"=="" echo Using Visual Studio %VSVER%.0 at %VSCOMNTOOLS%
-- if "%OSVARIANT%"=="" call "%VSCOMNTOOLS%\..\..\VC\vcvarsall.bat" %VCVARS_PLATFORM%
-- if "%OSVARIANT%"=="" Tools\nuget-install.cmd pcre -Verbosity quiet -Version 8.33.0.1 -OutputDirectory C:\pcre
-- if "%OSVARIANT%"=="" set PCRE_ROOT=C:/pcre/pcre.8.33.0.1/build/native
-- if not "%OSVARIANT%"=="cygwin" set PATH=C:\Python%VER%%LANG_PLATFORM%;%PATH%
+- if "%OSVARIANT%"=="" bash -c "cd /usr/bin && curl --retry 15 -s -L https://github.com/swig/cccl/archive/cccl-1.2.tar.gz | tar -xz --strip 1 cccl-cccl-1.2/cccl"
+- if "%OSVARIANT%"=="" call "%VCVARSBAT%" %VCVARSARG%
+- if "%OSVARIANT%"=="" appveyor-retry appveyor DownloadFile https://github.com/PhilipHazel/pcre2/archive/refs/tags/pcre2-10.39.zip
+- if "%OSVARIANT%"=="" 7z x pcre2-10.39.zip
+- if "%OSVARIANT%"=="" set PCRE_ROOT=C:/pcre
+- if "%OSVARIANT%"=="" set PATH=C:\Python%VER%%LANG_PLATFORM%;%PATH%
 - if "%OSVARIANT%"=="" bash -c "which cl.exe"
 - if "%OSVARIANT%"=="" bash -c "cl.exe /? 2>&1 | head -n 1"
 - if "%OSVARIANT%"=="" bash -c "which csc.exe"
 - if "%OSVARIANT%"=="" bash -c "csc.exe /? | head -n 1"
-- if "%OSVARIANT%"=="cygwin" %CYGWINSETUP% --quiet-mode --packages python2-devel,libpcre-devel,libboost-devel > cygwin-install.txt || bash -c "cat cygwin-install.txt"
-- if "%OSVARIANT%"=="mingw" bash -c "pacman --noconfirm --sync mingw%MBITS%/mingw-w64-%MARCH%-pcre mingw%MBITS%/mingw-w64-%MARCH%-boost"
+- if "%OSVARIANT%"=="cygwin" %CYGWINSETUP% --quiet-mode --packages python3-devel,libpcre2-devel,libboost-devel > cygwin-install.txt || bash -c "cat cygwin-install.txt"
+- if "%OSVARIANT%"=="mingw" bash -c "pacman --noconfirm --sync mingw%MBITS%/mingw-w64-%MARCH%-autotools mingw%MBITS%/mingw-w64-%MARCH%-pcre2 mingw%MBITS%/mingw-w64-%MARCH%-boost mingw%MBITS%/mingw-w64-%MARCH%-python"
 - if not "%WITHLANG%"=="" set SWIGWITHLANG==%WITHLANG%
 - if not "%WITHLANG%"=="" where %WITHLANG%
+- if "%SWIGLANG%"=="python" set PY3=3
+- if "%PY2%"=="2" set PY3=
 - bash -c "which $CC"
 - bash -c "which $CXX"
 - bash -c "$CC --version | head -n 1"
@@ -105,16 +169,21 @@
 - uname -a
 
 build_script:
+- set PATH=C:\Tools\bison\Bison.3.7.4\bin;%PATH%
 - set CCCL_OPTIONS=--cccl-muffle /W3 /EHsc
 - set CHECK_OPTIONS=CSHARPOPTIONS=-platform:%Platform%
+- if "%BUILDSYSTEM%"=="cmake" cd pcre2-pcre2-10.39 && cmake -G "Visual Studio 14 2015%VSARCH%" -DCMAKE_INSTALL_PREFIX="%PCRE_ROOT:\=/%" . && cmake --build . --config Release --target install && cd ..
+- if "%BUILDSYSTEM%"=="cmake" cmake --version && cmake -G "Visual Studio 14 2015%VSARCH%" -DCMAKE_INSTALL_PREFIX="%CD:\=/%/install2" -DCMAKE_C_FLAGS="/WX /DPCRE2_STATIC" -DCMAKE_CXX_FLAGS="/WX /DPCRE2_STATIC" -DPCRE2_INCLUDE_DIR=%PCRE_ROOT%/include -DPCRE2_LIBRARY=%PCRE_ROOT%/lib/pcre2-8-static.lib -DBISON_EXECUTABLE=C:/Tools/bison/Bison.3.7.4/bin/bison.exe . && cmake --build . --config Release --target install && ctest --output-on-failure -V -C Release && appveyor exit
+- if "%OSVARIANT%"=="" bash -c "exec 0</dev/null && cd pcre2-pcre2-10.39 && ./autogen.sh && ./configure CC=$CC CXX=$CXX CFLAGS='-O2' LDFLAGS='--cccl-link /LTCG' --prefix=%PCRE_ROOT% --disable-shared && time make -s -j%MAKEJOBS% LN_S=cp && make install && cd .. && cp -v %PCRE_ROOT%/lib/libpcre2-8.lib %PCRE_ROOT%/lib/pcre2-8.lib"
   # Open dummy file descriptor to fix error on cygwin: ./configure: line 560: 0: Bad file descriptor
-- if "%OSVARIANT%"=="" bash -c "exec 0</dev/null && ./autogen.sh && time ./configure --disable-dependency-tracking --disable-ccache CC=$CC CXX=$CXX CFLAGS='-O2' CXXFLAGS='-O2' LDFLAGS='--cccl-link /LTCG' PCRE_CFLAGS='-I%PCRE_ROOT%/include -DPCRE_STATIC' PCRE_LIBS='-L%PCRE_ROOT%/lib/v110/%PCRE_PLATFORM%/Release/static/utf8 -lpcre8' --without-perl5 --without-go --with-boost=C:/Libraries/boost_1_67_0 || cat config.log"
-- if not "%OSVARIANT%"=="" bash -c "exec 0</dev/null && ./autogen.sh && time ./configure CC=%CC% CXX=%CXX% --without-alllang --with-$SWIGLANG$PY3$SWIGWITHLANG --enable-cpp11-testing || cat config.log"
+- if "%OSVARIANT%"=="" bash -c "exec 0</dev/null && ./autogen.sh && time ./configure --disable-dependency-tracking --disable-ccache CC=$CC CXX=$CXX CFLAGS='-O2' CXXFLAGS='-O2' LDFLAGS='--cccl-link /LTCG' PCRE2_CFLAGS='-I%PCRE_ROOT%/include -DPCRE2_STATIC' PCRE2_LIBS='-L%PCRE_ROOT%/lib/ -lpcre2-8' --without-perl5 --without-go --with-boost=%BOOSTROOT% || cat config.log"
+- if not "%OSVARIANT%"=="" bash -c "exec 0</dev/null && ./autogen.sh && time ./configure CC=%CC% CXX=%CXX% --without-alllang --with-$SWIGLANG$PY3$SWIGWITHLANG || cat config.log"
 - bash -c "time make -s -j%MAKEJOBS%"
 
 test_script:
 - set CCCL_OPTIONS=--cccl-muffle /W3 /EHsc
 - .\swig.exe -version
+- .\swig.exe -pcreversion
 - if not "%OSVARIANT%"=="" CCache\ccache-swig -V
 - bash -c "file ./swig.exe"
 - bash -c "make check-%SWIGLANG%-version"
diff --git a/configure b/configure
index 6406776..f9123a6 100755
--- a/configure
+++ b/configure
@@ -1,11 +1,12 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for swig 4.0.1.
+# Generated by GNU Autoconf 2.71 for swig 4.2.1.
 #
-# Report bugs to <http://www.swig.org>.
+# Report bugs to <https://www.swig.org>.
 #
 #
-# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+# Copyright (C) 1992-1996, 1998-2017, 2020-2021 Free Software Foundation,
+# Inc.
 #
 #
 # This configure script is free software; the Free Software Foundation
@@ -16,14 +17,16 @@
 
 # Be more Bourne compatible
 DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+as_nop=:
+if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
   emulate sh
   NULLCMD=:
   # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
   setopt NO_GLOB_SUBST
-else
+else $as_nop
   case `(set -o) 2>/dev/null` in #(
   *posix*) :
     set -o posix ;; #(
@@ -33,46 +36,46 @@
 fi
 
 
+
+# Reset variables that may have inherited troublesome values from
+# the environment.
+
+# IFS needs to be set, to space, tab, and newline, in precisely that order.
+# (If _AS_PATH_WALK were called with IFS unset, it would have the
+# side effect of setting IFS to empty, thus disabling word splitting.)
+# Quoting is to prevent editors from complaining about space-tab.
 as_nl='
 '
 export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
-    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='print -r --'
-  as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='printf %s\n'
-  as_echo_n='printf %s'
-else
-  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
-    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
-    as_echo_n='/usr/ucb/echo -n'
-  else
-    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
-    as_echo_n_body='eval
-      arg=$1;
-      case $arg in #(
-      *"$as_nl"*)
-	expr "X$arg" : "X\\(.*\\)$as_nl";
-	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
-      esac;
-      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
-    '
-    export as_echo_n_body
-    as_echo_n='sh -c $as_echo_n_body as_echo'
-  fi
-  export as_echo_body
-  as_echo='sh -c $as_echo_body as_echo'
-fi
+IFS=" ""	$as_nl"
+
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# Ensure predictable behavior from utilities with locale-dependent output.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# We cannot yet rely on "unset" to work, but we need these variables
+# to be unset--not just set to an empty or harmless value--now, to
+# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
+# also avoids known problems related to "unset" and subshell syntax
+# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
+for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
+do eval test \${$as_var+y} \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+
+# Ensure that fds 0, 1, and 2 are open.
+if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
+if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
+if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi
 
 # The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
+if ${PATH_SEPARATOR+false} :; then
   PATH_SEPARATOR=:
   (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
     (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
@@ -81,13 +84,6 @@
 fi
 
 
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" ""	$as_nl"
-
 # Find who we are.  Look in the path if we contain no directory separator.
 as_myself=
 case $0 in #((
@@ -96,8 +92,12 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    test -r "$as_dir$0" && as_myself=$as_dir$0 && break
   done
 IFS=$as_save_IFS
 
@@ -109,30 +109,10 @@
   as_myself=$0
 fi
 if test ! -f "$as_myself"; then
-  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
   exit 1
 fi
 
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there.  '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
-  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
 # Use a proper internal environment variable to ensure we don't fall
   # into an infinite loop, continuously re-executing ourselves.
@@ -154,20 +134,22 @@
 exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
 # Admittedly, this is quite paranoid, since all the known shells bail
 # out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
-as_fn_exit 255
+printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
   fi
   # We don't want this to propagate to other subprocesses.
           { _as_can_reexec=; unset _as_can_reexec;}
 if test "x$CONFIG_SHELL" = x; then
-  as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+  as_bourne_compatible="as_nop=:
+if test \${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
   emulate sh
   NULLCMD=:
   # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '\${1+\"\$@\"}'='\"\$@\"'
   setopt NO_GLOB_SUBST
-else
+else \$as_nop
   case \`(set -o) 2>/dev/null\` in #(
   *posix*) :
     set -o posix ;; #(
@@ -187,42 +169,53 @@
 as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
 as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
 as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
-if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+if ( set x; as_fn_ret_success y && test x = \"\$1\" )
+then :
 
-else
+else \$as_nop
   exitcode=1; echo positional parameters were not saved.
 fi
 test x\$exitcode = x0 || exit 1
+blah=\$(echo \$(echo blah))
+test x\"\$blah\" = xblah || exit 1
 test -x / || exit 1"
   as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
   as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
   eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
   test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
 test \$(( 1 + 1 )) = 2 || exit 1"
-  if (eval "$as_required") 2>/dev/null; then :
+  if (eval "$as_required") 2>/dev/null
+then :
   as_have_required=yes
-else
+else $as_nop
   as_have_required=no
 fi
-  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+  if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null
+then :
 
-else
+else $as_nop
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 as_found=false
 for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
   as_found=:
   case $as_dir in #(
 	 /*)
 	   for as_base in sh bash ksh sh5; do
 	     # Try only shells that exist, to save several forks.
-	     as_shell=$as_dir/$as_base
+	     as_shell=$as_dir$as_base
 	     if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
-		    { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+		    as_run=a "$as_shell" -c "$as_bourne_compatible""$as_required" 2>/dev/null
+then :
   CONFIG_SHELL=$as_shell as_have_required=yes
-		   if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+		   if as_run=a "$as_shell" -c "$as_bourne_compatible""$as_suggested" 2>/dev/null
+then :
   break 2
 fi
 fi
@@ -230,14 +223,21 @@
        esac
   as_found=false
 done
-$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
-	      { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
-  CONFIG_SHELL=$SHELL as_have_required=yes
-fi; }
 IFS=$as_save_IFS
+if $as_found
+then :
+
+else $as_nop
+  if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+	      as_run=a "$SHELL" -c "$as_bourne_compatible""$as_required" 2>/dev/null
+then :
+  CONFIG_SHELL=$SHELL as_have_required=yes
+fi
+fi
 
 
-      if test "x$CONFIG_SHELL" != x; then :
+      if test "x$CONFIG_SHELL" != x
+then :
   export CONFIG_SHELL
              # We cannot yet assume a decent shell, so we have to provide a
 # neutralization value for shells without unset; and this also
@@ -255,19 +255,20 @@
 exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
 # Admittedly, this is quite paranoid, since all the known shells bail
 # out after a failed `exec'.
-$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+printf "%s\n" "$0: could not re-execute with $CONFIG_SHELL" >&2
 exit 255
 fi
 
-    if test x$as_have_required = xno; then :
-  $as_echo "$0: This script requires a shell more modern than all"
-  $as_echo "$0: the shells that I found on your system."
-  if test x${ZSH_VERSION+set} = xset ; then
-    $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
-    $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+    if test x$as_have_required = xno
+then :
+  printf "%s\n" "$0: This script requires a shell more modern than all"
+  printf "%s\n" "$0: the shells that I found on your system."
+  if test ${ZSH_VERSION+y} ; then
+    printf "%s\n" "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+    printf "%s\n" "$0: be upgraded to zsh 4.3.4 or later."
   else
-    $as_echo "$0: Please tell bug-autoconf@gnu.org and
-$0: http://www.swig.org about your system, including any
+    printf "%s\n" "$0: Please tell bug-autoconf@gnu.org and
+$0: https://www.swig.org about your system, including any
 $0: error possibly output before this message. Then install
 $0: a modern shell, or manually run the script under such a
 $0: shell if you do have one."
@@ -294,6 +295,7 @@
 }
 as_unset=as_fn_unset
 
+
 # as_fn_set_status STATUS
 # -----------------------
 # Set $? to STATUS, without forking.
@@ -311,6 +313,14 @@
   as_fn_set_status $1
   exit $1
 } # as_fn_exit
+# as_fn_nop
+# ---------
+# Do nothing but, unlike ":", preserve the value of $?.
+as_fn_nop ()
+{
+  return $?
+}
+as_nop=as_fn_nop
 
 # as_fn_mkdir_p
 # -------------
@@ -325,7 +335,7 @@
     as_dirs=
     while :; do
       case $as_dir in #(
-      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
       *) as_qdir=$as_dir;;
       esac
       as_dirs="'$as_qdir' $as_dirs"
@@ -334,7 +344,7 @@
 	 X"$as_dir" : 'X\(//\)[^/]' \| \
 	 X"$as_dir" : 'X\(//\)$' \| \
 	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
+printf "%s\n" X"$as_dir" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
 	    s//\1/
 	    q
@@ -373,12 +383,13 @@
 # advantage of any shell optimizations that allow amortized linear growth over
 # repeated appends, instead of the typical quadratic growth present in naive
 # implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
+then :
   eval 'as_fn_append ()
   {
     eval $1+=\$2
   }'
-else
+else $as_nop
   as_fn_append ()
   {
     eval $1=\$$1\$2
@@ -390,18 +401,27 @@
 # Perform arithmetic evaluation on the ARGs, and store the result in the
 # global $as_val. Take advantage of shells that can avoid forks. The arguments
 # must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
+then :
   eval 'as_fn_arith ()
   {
     as_val=$(( $* ))
   }'
-else
+else $as_nop
   as_fn_arith ()
   {
     as_val=`expr "$@" || test $? -eq 1`
   }
 fi # as_fn_arith
 
+# as_fn_nop
+# ---------
+# Do nothing but, unlike ":", preserve the value of $?.
+as_fn_nop ()
+{
+  return $?
+}
+as_nop=as_fn_nop
 
 # as_fn_error STATUS ERROR [LINENO LOG_FD]
 # ----------------------------------------
@@ -413,9 +433,9 @@
   as_status=$1; test $as_status -eq 0 && as_status=1
   if test "$4"; then
     as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-  $as_echo "$as_me: error: $2" >&2
+  printf "%s\n" "$as_me: error: $2" >&2
   as_fn_exit $as_status
 } # as_fn_error
 
@@ -442,7 +462,7 @@
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
 	 X"$0" : 'X\(//\)$' \| \
 	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
+printf "%s\n" X/"$0" |
     sed '/^.*\/\([^/][^/]*\)\/*$/{
 	    s//\1/
 	    q
@@ -486,7 +506,7 @@
       s/-\n.*//
     ' >$as_me.lineno &&
   chmod +x "$as_me.lineno" ||
-    { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+    { printf "%s\n" "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
 
   # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
   # already done that, so ensure we don't try to do so again and fall
@@ -500,6 +520,10 @@
   exit
 }
 
+
+# Determine whether it's possible to make 'echo' print without a newline.
+# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
+# for compatibility with existing Makefiles.
 ECHO_C= ECHO_N= ECHO_T=
 case `echo -n x` in #(((((
 -n*)
@@ -513,6 +537,13 @@
   ECHO_N='-n';;
 esac
 
+# For backward compatibility with old third-party macros, we provide
+# the shell variables $as_echo and $as_echo_n.  New code should use
+# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
+as_echo='printf %s\n'
+as_echo_n='printf %s'
+
+
 rm -f conf$$ conf$$.exe conf$$.file
 if test -d conf$$.dir; then
   rm -f conf$$.dir/conf$$.file
@@ -580,49 +611,45 @@
 # Identity of this package.
 PACKAGE_NAME='swig'
 PACKAGE_TARNAME='swig'
-PACKAGE_VERSION='4.0.1'
-PACKAGE_STRING='swig 4.0.1'
-PACKAGE_BUGREPORT='http://www.swig.org'
+PACKAGE_VERSION='4.2.1'
+PACKAGE_STRING='swig 4.2.1'
+PACKAGE_BUGREPORT='https://www.swig.org'
 PACKAGE_URL=''
 
 ac_unique_file="Source/Swig/swig.h"
 enable_option_checking=no
 # Factoring default headers for most tests.
 ac_includes_default="\
-#include <stdio.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
+#include <stddef.h>
+#ifdef HAVE_STDIO_H
+# include <stdio.h>
 #endif
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#ifdef STDC_HEADERS
+#ifdef HAVE_STDLIB_H
 # include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-#  include <stdlib.h>
-# endif
 #endif
 #ifdef HAVE_STRING_H
-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
-#  include <memory.h>
-# endif
 # include <string.h>
 #endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
 #ifdef HAVE_INTTYPES_H
 # include <inttypes.h>
 #endif
 #ifdef HAVE_STDINT_H
 # include <stdint.h>
 #endif
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
 #ifdef HAVE_UNISTD_H
 # include <unistd.h>
 #endif"
 
+ac_header_c_list=
 ac_subst_vars='am__EXEEXT_FALSE
 am__EXEEXT_TRUE
 LTLIBOBJS
@@ -635,59 +662,35 @@
 EXTRA_CLEAN
 ROOT_DIR
 SKIP_ANDROID
-SKIP_D
-SKIP_GO
+SKIP_TCL
 SKIP_SCILAB
-SKIP_R
-SKIP_LUA
-SKIP_CSHARP
-SKIP_OCAML
-SKIP_PHP
 SKIP_RUBY
-SKIP_MZSCHEME
-SKIP_GUILE
-SKIP_JAVASCRIPT
-SKIP_JAVA
+SKIP_R
 SKIP_PYTHON3
 SKIP_PYTHON
-SKIP_OCTAVE
 SKIP_PERL5
-SKIP_TCL
-DLIBPREFIX
-DDEFAULTVERSION
-D2COMPILER
-D1COMPILER
-GOVERSIONOPTION
-GCCGOOPT
-GOOPT
-GO15
-GO13
-GO12
-GO1
-GOC
-GOGCC
-GCCGO
-GO
-RBIN
-LUALINK
-LUAFLAGS
-LUADYNAMICLINKING
-LUABIN
-CSHARPSO
-CSHARPCFLAGS
-CSHARPLIBRARYPREFIX
-CSHARPDYNAMICLINKING
-CSHARPCONVERTPATH
-CSHARPCILINTERPRETER_FLAGS
-CSHARPCILINTERPRETER
-CSHARPCOMPILER
-OCAMLMKTOP
-OCAMLFIND
-OCAMLDLGEN
-CAMLP4
-OCAMLC
-PHPINC
-PHP
+SKIP_PHP
+SKIP_OCTAVE
+SKIP_OCAML
+SKIP_MZSCHEME
+SKIP_LUA
+SKIP_JAVASCRIPT
+SKIP_JAVA
+SKIP_GUILE
+SKIP_GO
+SKIP_D
+SKIP_CSHARP
+TCLLINK
+TCLCXXSHARED
+TCLLDSHARED
+TCLDYNAMICLINKING
+TCLLIB
+TCLINCLUDE
+CPP
+SCILAB_VERSION
+SCILABOPT
+SCILABINCLUDE
+SCILAB
 RUBYDYNAMICLINKING
 RUBYSO
 RUBYCCDLFLAGS
@@ -695,57 +698,7 @@
 RUBYLIB
 RUBYINCLUDE
 RUBY
-MZDYNOBJ
-MZC
-MZSCHEME
-GUILE_LIBS
-GUILE_CFLAGS
-GUILE
-GUILE_CONFIG
-NDKBUILD
-ANT
-ADB
-ANDROID
-JSV8ENABLED
-JSCENABLED
-JSV8DYNAMICLINKING
-JSV8INC
-JSCOREVERSION
-JSCOREDYNAMICLINKING
-JSCOREINC
-JSINTERPRETERLINKFLAGS
-JSINTERPRETERCXX
-NODEGYP
-NODEJS
-JAVACFLAGS
-JAVAFLAGS
-JAVACXXSHARED
-JAVALDSHARED
-JAVASO
-JAVALIBRARYPREFIX
-JAVADYNAMICLINKING
-JAVA_TOOLS_JAR
-JAVA_CLASSPATH_SEP
-JAVAINC
-JAVAC
-JAVA
-SCILABOPT
-SCILABINCLUDE
-SCILAB
-OCTAVE_LDFLAGS
-OCTAVE_CXXFLAGS
-OCTAVE_CPPFLAGS
-OCTAVE_SO
-OCTAVE
-PERL5LDFLAGS
-PERL5CCCDLFLAGS
-PERL5CCDLFLAGS
-PERL5CCFLAGS
-PERL5LIB
-PERL5DYNAMICLINKING
-PERL5EXT
-PERL
-PY2TO3
+RBIN
 PYCODESTYLE
 PYTHON3DYNAMICLINKING
 PY3LINK
@@ -758,17 +711,92 @@
 PYLIB
 PYINCLUDE
 PYTHON
-TCLCXXSHARED
-TCLLDSHARED
-TCLDYNAMICLINKING
-TCLLIB
-TCLINCLUDE
-PKGCONFIG
+PHPINC
+PHP
+PERL5LDFLAGS
+PERL5CCCDLFLAGS
+PERL5CCDLFLAGS
+PERL5CCFLAGS
+PERL5LIB
+PERL5DYNAMICLINKING
+PERL5EXT
+PERL
+OCTAVE_LDFLAGS
+OCTAVE_CXXFLAGS
+OCTAVE_CPPFLAGS
+OCTAVE_SO
+OCTAVE
+OCAMLMKTOP
+OCAMLFIND
+OCAMLDLGEN
+CAMLP4
+OCAMLC
+MZDYNOBJ
+MZC
+MZSCHEME
+LUALINK
+LUAFLAGS
+LUADYNAMICLINKING
+LUABIN
+JSV8ENABLED
+JSCENABLED
+JSV8DYNAMICLINKING
+JSV8INC
+JSCOREVERSION
+JSCOREDYNAMICLINKING
+JSCOREINC
+JSINTERPRETERLINKFLAGS
+JSINTERPRETERCXX
+JSNAPIENABLED
+NODENAPI_DIR
+NODENPM
+NODEGYP
+NODEJS
+JAVACFLAGS
+JAVAFLAGS
+JAVACXXSHARED
+JAVALDSHARED
+JAVASO
+JAVALIBRARYPREFIX
+JAVADYNAMICLINKING
+JAVA_CLASSPATH_SEP
+JAVAINC
+JAVA_SKIP_DOXYGEN_TEST_CASES
+JAVAC
+JAVA
+GUILE_LIBS
+GUILE_CFLAGS
+GUILE
+GUILE_CONFIG
+GOVERSIONOPTION
+GCCGOOPT
+GOOPT
+GO15
+GO13
+GO12
+GO1
+GOC
+GOGCC
+GCCGO
+GO
+DLIBPREFIX
+D2COMPILER
+CSHARPSO
+CSHARPCFLAGS
+CSHARPLIBRARYPREFIX
+CSHARPDYNAMICLINKING
+CSHARPCONVERTPATH
+CSHARPCILINTERPRETER_FLAGS
+CSHARPCILINTERPRETER
+CSHARPCOMPILER
+NDKBUILD
+ANT
+ADB
+ANDROID
+PKG_CONFIG
 LIBC
 LIBCRYPT
 LIBM
-SWILL
-SWIGLIBS
 LUA_SO
 MZSCHEME_SO
 PHP_SO
@@ -776,7 +804,6 @@
 TCL_SO
 PYTHON_SO
 LINKFORSHARED
-HAVE_CXX11_COMPILER
 PLATCXXFLAGS
 PLATCFLAGS
 RPATH
@@ -785,19 +812,24 @@
 CCSHARED
 LDSHARED
 SO
+PCHINCLUDEEXT
+PCHINCLUDEARG
+PCHSUPPORT
+HAVE_CXX11
+HAVE_CXX14
+HAVE_CXX17
+HAVE_CXX20
 BOOST_LDFLAGS
 BOOST_CPPFLAGS
-YFLAGS
-YACC
+BISON
 ENABLE_CCACHE
 subdirs
-PCRE_LIBS
-PCRE_CFLAGS
-PCRE_CONFIG
+PCRE2_LIBS
+PCRE2_CFLAGS
+PCRE2_CONFIG
 SED
 EGREP
 GREP
-CPP
 am__fastdepCXX_FALSE
 am__fastdepCXX_TRUE
 CXXDEPMODE
@@ -824,6 +856,9 @@
 AM_DEFAULT_VERBOSITY
 AM_DEFAULT_V
 AM_V
+CSCOPE
+ETAGS
+CTAGS
 am__untar
 am__tar
 AMTAR
@@ -901,10 +936,9 @@
 enable_silent_rules
 enable_dependency_tracking
 with_maximum_compile_warnings
-with_popen
 with_pcre
-with_pcre_prefix
-with_pcre_exec_prefix
+with_pcre2_prefix
+with_pcre2_exec_prefix
 enable_ccache
 with_boost
 with_boost_libdir
@@ -912,17 +946,20 @@
 with_libm
 with_libc
 with_alllang
-with_tclconfig
-with_tcl
-with_tclincl
-with_tcllib
-with_python
-with_python3
-with_2to3
-with_perl5
-with_octave
-with_scilab
-with_scilab_inc
+with_android
+with_adb
+with_ant
+with_ndk_build
+with_csharp
+with_cil_interpreter
+with_csharp_compiler
+with_d
+with_d2_compiler
+with_go
+with_guile_config
+with_guile
+with_guile_cflags
+with_guile_libs
 with_java
 with_javac
 with_javaincl
@@ -931,35 +968,30 @@
 with_jscorelib
 with_jsv8inc
 with_jsv8lib
-with_android
-with_adb
-with_ant
-with_ndk_build
-with_guile_config
-with_guile
-with_guile_cflags
-with_guile_libs
+with_lua
+with_luaincl
+with_lualib
 with_mzscheme
 with_mzc
-with_ruby
-with_php
 with_ocaml
 with_ocamlc
 with_ocamldlgen
 with_ocamlfind
 with_ocamlmktop
 with_camlp4
-with_csharp
-with_cil_interpreter
-with_csharp_compiler
-with_lua
-with_luaincl
-with_lualib
+with_octave
+with_perl5
+with_php
+with_python
+with_python3
 with_r
-with_go
-with_d
-with_d1_compiler
-with_d2_compiler
+with_ruby
+with_scilab
+with_scilab_inc
+with_tclconfig
+with_tcl
+with_tclincl
+with_tcllib
 with_swiglibdir
 '
       ac_precious_vars='build_alias
@@ -973,12 +1005,10 @@
 CXX
 CXXFLAGS
 CCC
-CPP
-PCRE_CONFIG
-PCRE_CFLAGS
-PCRE_LIBS
-YACC
-YFLAGS'
+PCRE2_CONFIG
+PCRE2_CFLAGS
+PCRE2_LIBS
+CPP'
 ac_subdirs_all='CCache'
 
 # Initialize some variables set by options.
@@ -1047,8 +1077,6 @@
   *)    ac_optarg=yes ;;
   esac
 
-  # Accept the important Cygnus configure options, so we can diagnose typos.
-
   case $ac_dashdash$ac_option in
   --)
     ac_dashdash=yes ;;
@@ -1089,9 +1117,9 @@
     ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid feature name: $ac_useropt"
+      as_fn_error $? "invalid feature name: \`$ac_useropt'"
     ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
       *"
 "enable_$ac_useropt"
@@ -1115,9 +1143,9 @@
     ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid feature name: $ac_useropt"
+      as_fn_error $? "invalid feature name: \`$ac_useropt'"
     ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
       *"
 "enable_$ac_useropt"
@@ -1328,9 +1356,9 @@
     ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid package name: $ac_useropt"
+      as_fn_error $? "invalid package name: \`$ac_useropt'"
     ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
       *"
 "with_$ac_useropt"
@@ -1344,9 +1372,9 @@
     ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error $? "invalid package name: $ac_useropt"
+      as_fn_error $? "invalid package name: \`$ac_useropt'"
     ac_useropt_orig=$ac_useropt
-    ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+    ac_useropt=`printf "%s\n" "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
       *"
 "with_$ac_useropt"
@@ -1390,9 +1418,9 @@
 
   *)
     # FIXME: should be removed in autoconf 3.0.
-    $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    printf "%s\n" "$as_me: WARNING: you should use --build, --host, --target" >&2
     expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
-      $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+      printf "%s\n" "$as_me: WARNING: invalid host type: $ac_option" >&2
     : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
     ;;
 
@@ -1408,7 +1436,7 @@
   case $enable_option_checking in
     no) ;;
     fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
-    *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+    *)     printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
   esac
 fi
 
@@ -1472,7 +1500,7 @@
 	 X"$as_myself" : 'X\(//\)[^/]' \| \
 	 X"$as_myself" : 'X\(//\)$' \| \
 	 X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_myself" |
+printf "%s\n" X"$as_myself" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
 	    s//\1/
 	    q
@@ -1529,7 +1557,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures swig 4.0.1 to adapt to many kinds of systems.
+\`configure' configures swig 4.2.1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1600,7 +1628,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of swig 4.0.1:";;
+     short | recursive ) echo "Configuration of swig 4.2.1:";;
    esac
   cat <<\_ACEOF
 
@@ -1616,20 +1644,19 @@
                           speeds up one-time build
   --disable-ccache        disable building and installation of ccache-swig
                           executable (default enabled)
-  --enable-cpp11-testing  enable C++11 testing if supported by compiler
-                          (default disabled)
+  --disable-cpp11-testing disable C++11 and later C++ standards testing even
+                          if supported by compiler (default enabled)
 
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
   --without-maximum-compile-warnings
                           Disable maximum warning verbosity
-  --without-popen         Disable popen
-  --without-pcre          Disable support for regular expressions using PCRE
-  --with-pcre-prefix=PREFIX
-                          Prefix where pcre is installed (optional)
-  --with-pcre-exec-prefix=EPREFIX
-                          Exec prefix where pcre is installed (optional)
+  --without-pcre          Disable support for regular expressions using PCRE2
+  --with-pcre2-prefix=PREFIX
+                          Prefix where pcre2 is installed (optional)
+  --with-pcre2-exec-prefix=EPREFIX
+                          Exec prefix where pcre2 is installed (optional)
   --with-boost[=ARG]      use Boost library from a standard location
                           (ARG=yes), from the specified location (ARG=<path>),
                           or disable it (ARG=no) [ARG=yes]
@@ -1642,70 +1669,68 @@
   --with-libm=STRING      math library
   --with-libc=STRING      C library
   --without-alllang       Disable all languages
-  --without-tcl           Disable Tcl
-  --with-tclconfig=path   Set location of tclConfig.sh
-  --with-tcl=path         Set location of Tcl package
-  --with-tclincl=path     Set location of Tcl include directory
-  --with-tcllib=path      Set location of Tcl library directory
-  --without-python        Disable Python
-  --with-python=path      Set location of Python executable
-  --without-python3       Disable Python 3.x support
-  --with-python3=path     Set location of Python 3.x executable
-  --with-2to3=path        Set location of Python 2to3 tool
-  --without-perl5         Disable Perl5
-  --with-perl5=path       Set location of Perl5 executable
-  --without-octave        Disable Octave
-  --with-octave=path      Set location of Octave executable
-  --without-scilab        Disable Scilab
-  --with-scilab=path      Set location of Scilab executable
-  --with-scilab-inc=path  Set location of Scilab include directory
-  --without-java          Disable Java
-  --with-java=path        Set location of java executable
-  --with-javac=path       Set location of javac executable
-  --with-javaincl=path    Set location of Java include directory
-  --without-javascript    Disable Javascript
-  --with-jscoreinc=path      Set location of Javascript include directory
-  --with-jscorelib=path      Set location of the JavaScriptCore/Webkit library directory
-  --with-jsv8inc=path     Set location of Javascript v8 include directory
-  --with-jsv8lib=path     Set location of V8 Javascript library directory
   --without-android       Disable Android
   --with-android=path     Set location of android executable
   --with-adb=path         Set location of adb executable - Android Debug Bridge
   --with-ant=path         Set location of ant executable for Android
   --with-ndk-build=path   Set location of Android ndk-build executable
+  --without-csharp        Disable CSharp
+  --with-cil-interpreter=path     Set location of CIL interpreter for CSharp
+  --with-csharp-compiler=path     Set location of CSharp compiler
+  --without-d             Disable D
+  --with-d2-compiler=path  Set location of D2 compiler (DMD compatible)
+  --without-go            Disable Go
+  --with-go=path          Set location of Go compiler
   --without-guile         Disable Guile
   --with-guile-config=path
                           Set location of guile-config
   --with-guile=path       Set location of Guile executable
   --with-guile-cflags=cflags   Set cflags required to compile against Guile
   --with-guile-libs=ldflags    Set ldflags needed to link with Guile
+  --without-java          Disable Java
+  --with-java=path        Set location of java executable
+  --with-javac=path       Set location of javac executable
+  --with-javaincl=path    Set location of Java include directory
+  --without-javascript    Disable Javascript
+  --with-jscoreinc=path      Set location of JavaScriptCore/Webkit include directory
+  --with-jscorelib=path      Set location of the JavaScriptCore/Webkit library directory
+  --with-jsv8inc=path     Set location of Javascript v8 include directory
+  --with-jsv8lib=path     Set location of V8 Javascript library directory
+  --without-lua           Disable Lua
+  --with-lua=path         Set location of Lua executable
+  --with-luaincl=path     Set location of Lua include directory
+  --with-lualib=path      Set location of Lua library directory
   --without-mzscheme      Disable MzScheme
   --with-mzscheme=path    Set location of MzScheme executable
   --with-mzc=path         Set location of MzScheme's mzc
-  --without-ruby          Disable Ruby
-  --with-ruby=path        Set location of Ruby executable
-  --without-php           Disable PHP
-  --with-php=path         Set location of PHP executable
   --without-ocaml         Disable OCaml
   --with-ocamlc=path      Set location of ocamlc executable
   --with-ocamldlgen=path  Set location of ocamldlgen
   --with-ocamlfind=path   Set location of ocamlfind
   --with-ocamlmktop=path  Set location of ocamlmktop executable
   --with-camlp4=path  Set location of camlp4 executable
-  --without-csharp        Disable CSharp
-  --with-cil-interpreter=path     Set location of CIL interpreter for CSharp
-  --with-csharp-compiler=path     Set location of CSharp compiler
-  --without-lua           Disable Lua
-  --with-lua=path         Set location of Lua executable
-  --with-luaincl=path     Set location of Lua include directory
-  --with-lualib=path      Set location of Lua library directory
+  --without-octave        Disable Octave
+  --with-octave=path      Set location of Octave executable
+  --without-perl5         Disable Perl5
+  --with-perl5=path       Set location of Perl5 executable
+  --without-php           Disable PHP
+  --with-php=path         Set location of PHP executable
+  --without-python        Don't probe for Python 2.x
+  --with-python=path      Set location of Python 2.x executable
+  --without-python3       Don't probe for Python 3.x
+  --with-python3=path     Set location of Python 3.x executable
   --without-r             Disable R
   --with-r=path           Set location of R executable (r)
-  --without-go            Disable Go
-  --with-go=path          Set location of Go compiler
-  --without-d             Disable D
-  --with-d1-compiler=path  Set location of D1/Tango compiler (DMD compatible)
-  --with-d2-compiler=path  Set location of D2 compiler (DMD compatible)
+  --without-ruby          Disable Ruby
+  --with-ruby=path        Set location of Ruby executable
+  --without-scilab        Disable Scilab
+  --with-scilab=path      Set location of Scilab executable
+  --with-scilab-inc=path  Set location of Scilab include directory
+  --without-tcl           Disable Tcl
+  --with-tclconfig=path   Set location of tclConfig.sh
+  --with-tcl=path         Set location of Tcl package
+  --with-tclincl=path     Set location of Tcl include directory
+  --with-tcllib=path      Set location of Tcl library directory
   --with-swiglibdir=DIR   Put SWIG system-independent libraries into DIR.
 
 Some influential environment variables:
@@ -1718,21 +1743,17 @@
               you have headers in a nonstandard directory <include dir>
   CXX         C++ compiler command
   CXXFLAGS    C++ compiler flags
+  PCRE2_CONFIG
+              config script used for pcre2
+  PCRE2_CFLAGS
+              CFLAGS used for pcre2
+  PCRE2_LIBS  LIBS used for pcre2
   CPP         C preprocessor
-  PCRE_CONFIG config script used for pcre
-  PCRE_CFLAGS CFLAGS used for pcre
-  PCRE_LIBS   LIBS used for pcre
-  YACC        The `Yet Another Compiler Compiler' implementation to use.
-              Defaults to the first program found out of: `bison -y', `byacc',
-              `yacc'.
-  YFLAGS      The list of arguments that will be passed by default to $YACC.
-              This script will default YFLAGS to the empty string to avoid a
-              default value of `-d' given by some make applications.
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
 
-Report bugs to <http://www.swig.org>.
+Report bugs to <https://www.swig.org>.
 _ACEOF
 ac_status=$?
 fi
@@ -1748,9 +1769,9 @@
 case "$ac_dir" in
 .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
 *)
-  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
   # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
   case $ac_top_builddir_sub in
   "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
   *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
@@ -1778,7 +1799,8 @@
 ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
 
     cd "$ac_dir" || { ac_status=$?; continue; }
-    # Check for guested configure.
+    # Check for configure.gnu first; this name is used for a wrapper for
+    # Metaconfig's "Configure" on case-insensitive file systems.
     if test -f "$ac_srcdir/configure.gnu"; then
       echo &&
       $SHELL "$ac_srcdir/configure.gnu" --help=recursive
@@ -1786,7 +1808,7 @@
       echo &&
       $SHELL "$ac_srcdir/configure" --help=recursive
     else
-      $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+      printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2
     fi || ac_status=$?
     cd "$ac_pwd" || { ac_status=$?; break; }
   done
@@ -1795,10 +1817,10 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-swig configure 4.0.1
-generated by GNU Autoconf 2.69
+swig configure 4.2.1
+generated by GNU Autoconf 2.71
 
-Copyright (C) 2012 Free Software Foundation, Inc.
+Copyright (C) 2021 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it.
 _ACEOF
@@ -1815,14 +1837,14 @@
 ac_fn_c_try_compile ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext
+  rm -f conftest.$ac_objext conftest.beam
   if { { ac_try="$ac_compile"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_compile") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -1830,14 +1852,15 @@
     cat conftest.er1 >&5
     mv -f conftest.er1 conftest.err
   fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } && {
 	 test -z "$ac_c_werror_flag" ||
 	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then :
+       } && test -s conftest.$ac_objext
+then :
   ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
 	ac_retval=1
@@ -1853,14 +1876,14 @@
 ac_fn_cxx_try_compile ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext
+  rm -f conftest.$ac_objext conftest.beam
   if { { ac_try="$ac_compile"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_compile") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -1868,14 +1891,15 @@
     cat conftest.er1 >&5
     mv -f conftest.er1 conftest.err
   fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } && {
 	 test -z "$ac_cxx_werror_flag" ||
 	 test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then :
+       } && test -s conftest.$ac_objext
+then :
   ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
 	ac_retval=1
@@ -1885,99 +1909,20 @@
 
 } # ac_fn_cxx_try_compile
 
-# ac_fn_c_try_cpp LINENO
-# ----------------------
-# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_cpp ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if { { ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
-  ac_status=$?
-  if test -s conftest.err; then
-    grep -v '^ *+' conftest.err >conftest.er1
-    cat conftest.er1 >&5
-    mv -f conftest.er1 conftest.err
-  fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } > conftest.i && {
-	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
-	 test ! -s conftest.err
-       }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-    ac_retval=1
-fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_cpp
-
-# ac_fn_c_try_run LINENO
-# ----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
-# that executables *can* be run.
-ac_fn_c_try_run ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if { { ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
-  { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; }; then :
-  ac_retval=0
-else
-  $as_echo "$as_me: program exited with status $ac_status" >&5
-       $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-       ac_retval=$ac_status
-fi
-  rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-  as_fn_set_status $ac_retval
-
-} # ac_fn_c_try_run
-
 # ac_fn_c_try_link LINENO
 # -----------------------
 # Try to link conftest.$ac_ext, and return whether this succeeded.
 ac_fn_c_try_link ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  rm -f conftest.$ac_objext conftest$ac_exeext
+  rm -f conftest.$ac_objext conftest.beam conftest$ac_exeext
   if { { ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_link") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -1985,17 +1930,18 @@
     cat conftest.er1 >&5
     mv -f conftest.er1 conftest.err
   fi
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } && {
 	 test -z "$ac_c_werror_flag" ||
 	 test ! -s conftest.err
        } && test -s conftest$ac_exeext && {
 	 test "$cross_compiling" = yes ||
 	 test -x conftest$ac_exeext
-       }; then :
+       }
+then :
   ac_retval=0
-else
-  $as_echo "$as_me: failed program was:" >&5
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
 	ac_retval=1
@@ -2010,164 +1956,6 @@
 
 } # ac_fn_c_try_link
 
-# ac_fn_c_check_func LINENO FUNC VAR
-# ----------------------------------
-# Tests whether FUNC exists, setting the cache variable VAR accordingly
-ac_fn_c_check_func ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define $2 innocuous_$2
-
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $2 (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $2
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $2 ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined __stub_$2 || defined __stub___$2
-choke me
-#endif
-
-int
-main ()
-{
-return $2 ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  eval "$3=yes"
-else
-  eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_func
-
-# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists, giving a warning if it cannot be compiled using
-# the include files in INCLUDES and setting the cache variable VAR
-# accordingly.
-ac_fn_c_check_header_mongrel ()
-{
-  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if eval \${$3+:} false; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-else
-  # Is the header compilable?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
-$as_echo_n "checking $2 usability... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_header_compiler=yes
-else
-  ac_header_compiler=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
-$as_echo "$ac_header_compiler" >&6; }
-
-# Is the header present?
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
-$as_echo_n "checking $2 presence... " >&6; }
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <$2>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  ac_header_preproc=yes
-else
-  ac_header_preproc=no
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
-$as_echo "$ac_header_preproc" >&6; }
-
-# So?  What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
-  yes:no: )
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
-$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-    ;;
-  no:yes:* )
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
-$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
-$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
-$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
-$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
-$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( $as_echo "## ---------------------------------- ##
-## Report this to http://www.swig.org ##
-## ---------------------------------- ##"
-     ) | sed "s/^/$as_me: WARNING:     /" >&2
-    ;;
-esac
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  eval "$3=\$ac_header_compiler"
-fi
-eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-fi
-  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
-
-} # ac_fn_c_check_header_mongrel
-
 # ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
 # -------------------------------------------------------
 # Tests whether HEADER exists and can be compiled using the include files in
@@ -2175,220 +1963,97 @@
 ac_fn_c_check_header_compile ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if eval \${$3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+printf %s "checking for $2... " >&6; }
+if eval test \${$3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 $4
 #include <$2>
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   eval "$3=yes"
-else
+else $as_nop
   eval "$3=no"
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
 eval ac_res=\$$3
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_header_compile
 
-# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES
-# --------------------------------------------
-# Tries to find the compile-time value of EXPR in a program that includes
-# INCLUDES, setting VAR accordingly. Returns whether the value could be
-# computed
-ac_fn_c_compute_int ()
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if test "$cross_compiling" = yes; then
-    # Depending upon the size, compute the lo and hi bounds.
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-static int test_array [1 - 2 * !(($2) >= 0)];
-test_array [0] = 0;
-return test_array [0];
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_lo=0 ac_mid=0
-  while :; do
-    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0;
-return test_array [0];
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_hi=$ac_mid; break
-else
-  as_fn_arith $ac_mid + 1 && ac_lo=$as_val
-			if test $ac_lo -le $ac_mid; then
-			  ac_lo= ac_hi=
-			  break
-			fi
-			as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  done
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-static int test_array [1 - 2 * !(($2) < 0)];
-test_array [0] = 0;
-return test_array [0];
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_hi=-1 ac_mid=-1
-  while :; do
-    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-static int test_array [1 - 2 * !(($2) >= $ac_mid)];
-test_array [0] = 0;
-return test_array [0];
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_lo=$ac_mid; break
-else
-  as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val
-			if test $ac_mid -le $ac_hi; then
-			  ac_lo= ac_hi=
-			  break
-			fi
-			as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-  done
-else
-  ac_lo= ac_hi=
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-# Binary search between lo and hi bounds.
-while test "x$ac_lo" != "x$ac_hi"; do
-  as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-int
-main ()
-{
-static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0;
-return test_array [0];
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_hi=$ac_mid
-else
-  as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-done
-case $ac_lo in #((
-?*) eval "$3=\$ac_lo"; ac_retval=0 ;;
-'') ac_retval=1 ;;
+  if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
 esac
-  else
-    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-$4
-static long int longval () { return $2; }
-static unsigned long int ulongval () { return $2; }
-#include <stdio.h>
-#include <stdlib.h>
-int
-main ()
-{
-
-  FILE *f = fopen ("conftest.val", "w");
-  if (! f)
-    return 1;
-  if (($2) < 0)
-    {
-      long int i = longval ();
-      if (i != ($2))
-	return 1;
-      fprintf (f, "%ld", i);
-    }
-  else
-    {
-      unsigned long int i = ulongval ();
-      if (i != ($2))
-	return 1;
-      fprintf (f, "%lu", i);
-    }
-  /* Do not output a trailing newline, as this causes \r\n confusion
-     on some platforms.  */
-  return ferror (f) || fclose (f) != 0;
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-  echo >>conftest.val; read $3 <conftest.val; ac_retval=0
-else
-  ac_retval=1
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-rm -f conftest.val
-
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+printf "%s\n" "$ac_try_echo"; } >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+  ac_status=$?
+  if test -s conftest.err; then
+    grep -v '^ *+' conftest.err >conftest.er1
+    cat conftest.er1 >&5
+    mv -f conftest.er1 conftest.err
   fi
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } > conftest.i && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }
+then :
+  ac_retval=0
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+    ac_retval=1
+fi
   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
   as_fn_set_status $ac_retval
 
-} # ac_fn_c_compute_int
+} # ac_fn_c_try_cpp
+ac_configure_args_raw=
+for ac_arg
+do
+  case $ac_arg in
+  *\'*)
+    ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+  esac
+  as_fn_append ac_configure_args_raw " '$ac_arg'"
+done
+
+case $ac_configure_args_raw in
+  *$as_nl*)
+    ac_safe_unquote= ;;
+  *)
+    ac_unsafe_z='|&;<>()$`\\"*?[ ''	' # This string ends in space, tab.
+    ac_unsafe_a="$ac_unsafe_z#~"
+    ac_safe_unquote="s/ '\\([^$ac_unsafe_a][^$ac_unsafe_z]*\\)'/ \\1/g"
+    ac_configure_args_raw=`      printf "%s\n" "$ac_configure_args_raw" | sed "$ac_safe_unquote"`;;
+esac
+
 cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by swig $as_me 4.0.1, which was
-generated by GNU Autoconf 2.69.  Invocation command line was
+It was created by swig $as_me 4.2.1, which was
+generated by GNU Autoconf 2.71.  Invocation command line was
 
-  $ $0 $@
+  $ $0$ac_configure_args_raw
 
 _ACEOF
 exec 5>>config.log
@@ -2421,8 +2086,12 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    $as_echo "PATH: $as_dir"
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    printf "%s\n" "PATH: $as_dir"
   done
 IFS=$as_save_IFS
 
@@ -2457,7 +2126,7 @@
     | -silent | --silent | --silen | --sile | --sil)
       continue ;;
     *\'*)
-      ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+      ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
     esac
     case $ac_pass in
     1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
@@ -2492,11 +2161,13 @@
 # WARNING: Use '\'' to represent an apostrophe within the trap.
 # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
 trap 'exit_status=$?
+  # Sanitize IFS.
+  IFS=" ""	$as_nl"
   # Save into config.log some information that might help in debugging.
   {
     echo
 
-    $as_echo "## ---------------- ##
+    printf "%s\n" "## ---------------- ##
 ## Cache variables. ##
 ## ---------------- ##"
     echo
@@ -2507,8 +2178,8 @@
     case $ac_val in #(
     *${as_nl}*)
       case $ac_var in #(
-      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
       esac
       case $ac_var in #(
       _ | IFS | as_nl) ;; #(
@@ -2532,7 +2203,7 @@
 )
     echo
 
-    $as_echo "## ----------------- ##
+    printf "%s\n" "## ----------------- ##
 ## Output variables. ##
 ## ----------------- ##"
     echo
@@ -2540,14 +2211,14 @@
     do
       eval ac_val=\$$ac_var
       case $ac_val in
-      *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+      *\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
       esac
-      $as_echo "$ac_var='\''$ac_val'\''"
+      printf "%s\n" "$ac_var='\''$ac_val'\''"
     done | sort
     echo
 
     if test -n "$ac_subst_files"; then
-      $as_echo "## ------------------- ##
+      printf "%s\n" "## ------------------- ##
 ## File substitutions. ##
 ## ------------------- ##"
       echo
@@ -2555,15 +2226,15 @@
       do
 	eval ac_val=\$$ac_var
 	case $ac_val in
-	*\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+	*\'\''*) ac_val=`printf "%s\n" "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
 	esac
-	$as_echo "$ac_var='\''$ac_val'\''"
+	printf "%s\n" "$ac_var='\''$ac_val'\''"
       done | sort
       echo
     fi
 
     if test -s confdefs.h; then
-      $as_echo "## ----------- ##
+      printf "%s\n" "## ----------- ##
 ## confdefs.h. ##
 ## ----------- ##"
       echo
@@ -2571,8 +2242,8 @@
       echo
     fi
     test "$ac_signal" != 0 &&
-      $as_echo "$as_me: caught signal $ac_signal"
-    $as_echo "$as_me: exit $exit_status"
+      printf "%s\n" "$as_me: caught signal $ac_signal"
+    printf "%s\n" "$as_me: exit $exit_status"
   } >&5
   rm -f core *.core core.conftest.* &&
     rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
@@ -2586,63 +2257,48 @@
 # confdefs.h avoids OS command line length limits that DEFS can exceed.
 rm -f -r conftest* confdefs.h
 
-$as_echo "/* confdefs.h */" > confdefs.h
+printf "%s\n" "/* confdefs.h */" > confdefs.h
 
 # Predefined preprocessor variables.
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_NAME "$PACKAGE_NAME"
-_ACEOF
+printf "%s\n" "#define PACKAGE_NAME \"$PACKAGE_NAME\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
-_ACEOF
+printf "%s\n" "#define PACKAGE_TARNAME \"$PACKAGE_TARNAME\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_VERSION "$PACKAGE_VERSION"
-_ACEOF
+printf "%s\n" "#define PACKAGE_VERSION \"$PACKAGE_VERSION\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_STRING "$PACKAGE_STRING"
-_ACEOF
+printf "%s\n" "#define PACKAGE_STRING \"$PACKAGE_STRING\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
-_ACEOF
+printf "%s\n" "#define PACKAGE_BUGREPORT \"$PACKAGE_BUGREPORT\"" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE_URL "$PACKAGE_URL"
-_ACEOF
+printf "%s\n" "#define PACKAGE_URL \"$PACKAGE_URL\"" >>confdefs.h
 
 
 # Let the site file select an alternate cache file if it wants to.
 # Prefer an explicitly selected file to automatically selected ones.
-ac_site_file1=NONE
-ac_site_file2=NONE
 if test -n "$CONFIG_SITE"; then
-  # We do not want a PATH search for config.site.
-  case $CONFIG_SITE in #((
-    -*)  ac_site_file1=./$CONFIG_SITE;;
-    */*) ac_site_file1=$CONFIG_SITE;;
-    *)   ac_site_file1=./$CONFIG_SITE;;
-  esac
+  ac_site_files="$CONFIG_SITE"
 elif test "x$prefix" != xNONE; then
-  ac_site_file1=$prefix/share/config.site
-  ac_site_file2=$prefix/etc/config.site
+  ac_site_files="$prefix/share/config.site $prefix/etc/config.site"
 else
-  ac_site_file1=$ac_default_prefix/share/config.site
-  ac_site_file2=$ac_default_prefix/etc/config.site
+  ac_site_files="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
 fi
-for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+
+for ac_site_file in $ac_site_files
 do
-  test "x$ac_site_file" = xNONE && continue
-  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
-$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+  case $ac_site_file in #(
+  */*) :
+     ;; #(
+  *) :
+    ac_site_file=./$ac_site_file ;;
+esac
+  if test -f "$ac_site_file" && test -r "$ac_site_file"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+printf "%s\n" "$as_me: loading site script $ac_site_file" >&6;}
     sed 's/^/| /' "$ac_site_file" >&5
     . "$ac_site_file" \
-      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+      || { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "failed to load site script $ac_site_file
 See \`config.log' for more details" "$LINENO" 5; }
   fi
@@ -2652,19 +2308,650 @@
   # Some versions of bash will fail to source /dev/null (special files
   # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
   if test /dev/null != "$cache_file" && test -f "$cache_file"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
-$as_echo "$as_me: loading cache $cache_file" >&6;}
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+printf "%s\n" "$as_me: loading cache $cache_file" >&6;}
     case $cache_file in
       [\\/]* | ?:[\\/]* ) . "$cache_file";;
       *)                      . "./$cache_file";;
     esac
   fi
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
-$as_echo "$as_me: creating cache $cache_file" >&6;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+printf "%s\n" "$as_me: creating cache $cache_file" >&6;}
   >$cache_file
 fi
 
+# Test code for whether the C compiler supports C89 (global declarations)
+ac_c_conftest_c89_globals='
+/* Does the compiler advertise C89 conformance?
+   Do not test the value of __STDC__, because some compilers set it to 0
+   while being otherwise adequately conformant. */
+#if !defined __STDC__
+# error "Compiler does not advertise C89 conformance"
+#endif
+
+#include <stddef.h>
+#include <stdarg.h>
+struct stat;
+/* Most of the following tests are stolen from RCS 5.7 src/conf.sh.  */
+struct buf { int x; };
+struct buf * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not \xHH hex character constants.
+   These do not provoke an error unfortunately, instead are silently treated
+   as an "x".  The following induces an error, until -std is added to get
+   proper ANSI mode.  Curiously \x00 != x always comes out true, for an
+   array size at least.  It is necessary to write \x00 == 0 to get something
+   that is true only with -std.  */
+int osf4_cc_array ['\''\x00'\'' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+   inside strings and character constants.  */
+#define FOO(x) '\''x'\''
+int xlc6_cc_array[FOO(a) == '\''x'\'' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, int *(*)(struct buf *, struct stat *, int),
+               int, int);'
+
+# Test code for whether the C compiler supports C89 (body of main).
+ac_c_conftest_c89_main='
+ok |= (argc == 0 || f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]);
+'
+
+# Test code for whether the C compiler supports C99 (global declarations)
+ac_c_conftest_c99_globals='
+// Does the compiler advertise C99 conformance?
+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 199901L
+# error "Compiler does not advertise C99 conformance"
+#endif
+
+#include <stdbool.h>
+extern int puts (const char *);
+extern int printf (const char *, ...);
+extern int dprintf (int, const char *, ...);
+extern void *malloc (size_t);
+
+// Check varargs macros.  These examples are taken from C99 6.10.3.5.
+// dprintf is used instead of fprintf to avoid needing to declare
+// FILE and stderr.
+#define debug(...) dprintf (2, __VA_ARGS__)
+#define showlist(...) puts (#__VA_ARGS__)
+#define report(test,...) ((test) ? puts (#test) : printf (__VA_ARGS__))
+static void
+test_varargs_macros (void)
+{
+  int x = 1234;
+  int y = 5678;
+  debug ("Flag");
+  debug ("X = %d\n", x);
+  showlist (The first, second, and third items.);
+  report (x>y, "x is %d but y is %d", x, y);
+}
+
+// Check long long types.
+#define BIG64 18446744073709551615ull
+#define BIG32 4294967295ul
+#define BIG_OK (BIG64 / BIG32 == 4294967297ull && BIG64 % BIG32 == 0)
+#if !BIG_OK
+  #error "your preprocessor is broken"
+#endif
+#if BIG_OK
+#else
+  #error "your preprocessor is broken"
+#endif
+static long long int bignum = -9223372036854775807LL;
+static unsigned long long int ubignum = BIG64;
+
+struct incomplete_array
+{
+  int datasize;
+  double data[];
+};
+
+struct named_init {
+  int number;
+  const wchar_t *name;
+  double average;
+};
+
+typedef const char *ccp;
+
+static inline int
+test_restrict (ccp restrict text)
+{
+  // See if C++-style comments work.
+  // Iterate through items via the restricted pointer.
+  // Also check for declarations in for loops.
+  for (unsigned int i = 0; *(text+i) != '\''\0'\''; ++i)
+    continue;
+  return 0;
+}
+
+// Check varargs and va_copy.
+static bool
+test_varargs (const char *format, ...)
+{
+  va_list args;
+  va_start (args, format);
+  va_list args_copy;
+  va_copy (args_copy, args);
+
+  const char *str = "";
+  int number = 0;
+  float fnumber = 0;
+
+  while (*format)
+    {
+      switch (*format++)
+	{
+	case '\''s'\'': // string
+	  str = va_arg (args_copy, const char *);
+	  break;
+	case '\''d'\'': // int
+	  number = va_arg (args_copy, int);
+	  break;
+	case '\''f'\'': // float
+	  fnumber = va_arg (args_copy, double);
+	  break;
+	default:
+	  break;
+	}
+    }
+  va_end (args_copy);
+  va_end (args);
+
+  return *str && number && fnumber;
+}
+'
+
+# Test code for whether the C compiler supports C99 (body of main).
+ac_c_conftest_c99_main='
+  // Check bool.
+  _Bool success = false;
+  success |= (argc != 0);
+
+  // Check restrict.
+  if (test_restrict ("String literal") == 0)
+    success = true;
+  char *restrict newvar = "Another string";
+
+  // Check varargs.
+  success &= test_varargs ("s, d'\'' f .", "string", 65, 34.234);
+  test_varargs_macros ();
+
+  // Check flexible array members.
+  struct incomplete_array *ia =
+    malloc (sizeof (struct incomplete_array) + (sizeof (double) * 10));
+  ia->datasize = 10;
+  for (int i = 0; i < ia->datasize; ++i)
+    ia->data[i] = i * 1.234;
+
+  // Check named initializers.
+  struct named_init ni = {
+    .number = 34,
+    .name = L"Test wide string",
+    .average = 543.34343,
+  };
+
+  ni.number = 58;
+
+  int dynamic_array[ni.number];
+  dynamic_array[0] = argv[0][0];
+  dynamic_array[ni.number - 1] = 543;
+
+  // work around unused variable warnings
+  ok |= (!success || bignum == 0LL || ubignum == 0uLL || newvar[0] == '\''x'\''
+	 || dynamic_array[ni.number - 1] != 543);
+'
+
+# Test code for whether the C compiler supports C11 (global declarations)
+ac_c_conftest_c11_globals='
+// Does the compiler advertise C11 conformance?
+#if !defined __STDC_VERSION__ || __STDC_VERSION__ < 201112L
+# error "Compiler does not advertise C11 conformance"
+#endif
+
+// Check _Alignas.
+char _Alignas (double) aligned_as_double;
+char _Alignas (0) no_special_alignment;
+extern char aligned_as_int;
+char _Alignas (0) _Alignas (int) aligned_as_int;
+
+// Check _Alignof.
+enum
+{
+  int_alignment = _Alignof (int),
+  int_array_alignment = _Alignof (int[100]),
+  char_alignment = _Alignof (char)
+};
+_Static_assert (0 < -_Alignof (int), "_Alignof is signed");
+
+// Check _Noreturn.
+int _Noreturn does_not_return (void) { for (;;) continue; }
+
+// Check _Static_assert.
+struct test_static_assert
+{
+  int x;
+  _Static_assert (sizeof (int) <= sizeof (long int),
+                  "_Static_assert does not work in struct");
+  long int y;
+};
+
+// Check UTF-8 literals.
+#define u8 syntax error!
+char const utf8_literal[] = u8"happens to be ASCII" "another string";
+
+// Check duplicate typedefs.
+typedef long *long_ptr;
+typedef long int *long_ptr;
+typedef long_ptr long_ptr;
+
+// Anonymous structures and unions -- taken from C11 6.7.2.1 Example 1.
+struct anonymous
+{
+  union {
+    struct { int i; int j; };
+    struct { int k; long int l; } w;
+  };
+  int m;
+} v1;
+'
+
+# Test code for whether the C compiler supports C11 (body of main).
+ac_c_conftest_c11_main='
+  _Static_assert ((offsetof (struct anonymous, i)
+		   == offsetof (struct anonymous, w.k)),
+		  "Anonymous union alignment botch");
+  v1.i = 2;
+  v1.w.k = 5;
+  ok |= v1.i != 5;
+'
+
+# Test code for whether the C compiler supports C11 (complete).
+ac_c_conftest_c11_program="${ac_c_conftest_c89_globals}
+${ac_c_conftest_c99_globals}
+${ac_c_conftest_c11_globals}
+
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  ${ac_c_conftest_c99_main}
+  ${ac_c_conftest_c11_main}
+  return ok;
+}
+"
+
+# Test code for whether the C compiler supports C99 (complete).
+ac_c_conftest_c99_program="${ac_c_conftest_c89_globals}
+${ac_c_conftest_c99_globals}
+
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  ${ac_c_conftest_c99_main}
+  return ok;
+}
+"
+
+# Test code for whether the C compiler supports C89 (complete).
+ac_c_conftest_c89_program="${ac_c_conftest_c89_globals}
+
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_c_conftest_c89_main}
+  return ok;
+}
+"
+
+# Test code for whether the C++ compiler supports C++98 (global declarations)
+ac_cxx_conftest_cxx98_globals='
+// Does the compiler advertise C++98 conformance?
+#if !defined __cplusplus || __cplusplus < 199711L
+# error "Compiler does not advertise C++98 conformance"
+#endif
+
+// These inclusions are to reject old compilers that
+// lack the unsuffixed header files.
+#include <cstdlib>
+#include <exception>
+
+// <cassert> and <cstring> are *not* freestanding headers in C++98.
+extern void assert (int);
+namespace std {
+  extern int strcmp (const char *, const char *);
+}
+
+// Namespaces, exceptions, and templates were all added after "C++ 2.0".
+using std::exception;
+using std::strcmp;
+
+namespace {
+
+void test_exception_syntax()
+{
+  try {
+    throw "test";
+  } catch (const char *s) {
+    // Extra parentheses suppress a warning when building autoconf itself,
+    // due to lint rules shared with more typical C programs.
+    assert (!(strcmp) (s, "test"));
+  }
+}
+
+template <typename T> struct test_template
+{
+  T const val;
+  explicit test_template(T t) : val(t) {}
+  template <typename U> T add(U u) { return static_cast<T>(u) + val; }
+};
+
+} // anonymous namespace
+'
+
+# Test code for whether the C++ compiler supports C++98 (body of main)
+ac_cxx_conftest_cxx98_main='
+  assert (argc);
+  assert (! argv[0]);
+{
+  test_exception_syntax ();
+  test_template<double> tt (2.0);
+  assert (tt.add (4) == 6.0);
+  assert (true && !false);
+}
+'
+
+# Test code for whether the C++ compiler supports C++11 (global declarations)
+ac_cxx_conftest_cxx11_globals='
+// Does the compiler advertise C++ 2011 conformance?
+#if !defined __cplusplus || __cplusplus < 201103L
+# error "Compiler does not advertise C++11 conformance"
+#endif
+
+namespace cxx11test
+{
+  constexpr int get_val() { return 20; }
+
+  struct testinit
+  {
+    int i;
+    double d;
+  };
+
+  class delegate
+  {
+  public:
+    delegate(int n) : n(n) {}
+    delegate(): delegate(2354) {}
+
+    virtual int getval() { return this->n; };
+  protected:
+    int n;
+  };
+
+  class overridden : public delegate
+  {
+  public:
+    overridden(int n): delegate(n) {}
+    virtual int getval() override final { return this->n * 2; }
+  };
+
+  class nocopy
+  {
+  public:
+    nocopy(int i): i(i) {}
+    nocopy() = default;
+    nocopy(const nocopy&) = delete;
+    nocopy & operator=(const nocopy&) = delete;
+  private:
+    int i;
+  };
+
+  // for testing lambda expressions
+  template <typename Ret, typename Fn> Ret eval(Fn f, Ret v)
+  {
+    return f(v);
+  }
+
+  // for testing variadic templates and trailing return types
+  template <typename V> auto sum(V first) -> V
+  {
+    return first;
+  }
+  template <typename V, typename... Args> auto sum(V first, Args... rest) -> V
+  {
+    return first + sum(rest...);
+  }
+}
+'
+
+# Test code for whether the C++ compiler supports C++11 (body of main)
+ac_cxx_conftest_cxx11_main='
+{
+  // Test auto and decltype
+  auto a1 = 6538;
+  auto a2 = 48573953.4;
+  auto a3 = "String literal";
+
+  int total = 0;
+  for (auto i = a3; *i; ++i) { total += *i; }
+
+  decltype(a2) a4 = 34895.034;
+}
+{
+  // Test constexpr
+  short sa[cxx11test::get_val()] = { 0 };
+}
+{
+  // Test initializer lists
+  cxx11test::testinit il = { 4323, 435234.23544 };
+}
+{
+  // Test range-based for
+  int array[] = {9, 7, 13, 15, 4, 18, 12, 10, 5, 3,
+                 14, 19, 17, 8, 6, 20, 16, 2, 11, 1};
+  for (auto &x : array) { x += 23; }
+}
+{
+  // Test lambda expressions
+  using cxx11test::eval;
+  assert (eval ([](int x) { return x*2; }, 21) == 42);
+  double d = 2.0;
+  assert (eval ([&](double x) { return d += x; }, 3.0) == 5.0);
+  assert (d == 5.0);
+  assert (eval ([=](double x) mutable { return d += x; }, 4.0) == 9.0);
+  assert (d == 5.0);
+}
+{
+  // Test use of variadic templates
+  using cxx11test::sum;
+  auto a = sum(1);
+  auto b = sum(1, 2);
+  auto c = sum(1.0, 2.0, 3.0);
+}
+{
+  // Test constructor delegation
+  cxx11test::delegate d1;
+  cxx11test::delegate d2();
+  cxx11test::delegate d3(45);
+}
+{
+  // Test override and final
+  cxx11test::overridden o1(55464);
+}
+{
+  // Test nullptr
+  char *c = nullptr;
+}
+{
+  // Test template brackets
+  test_template<::test_template<int>> v(test_template<int>(12));
+}
+{
+  // Unicode literals
+  char const *utf8 = u8"UTF-8 string \u2500";
+  char16_t const *utf16 = u"UTF-8 string \u2500";
+  char32_t const *utf32 = U"UTF-32 string \u2500";
+}
+'
+
+# Test code for whether the C compiler supports C++11 (complete).
+ac_cxx_conftest_cxx11_program="${ac_cxx_conftest_cxx98_globals}
+${ac_cxx_conftest_cxx11_globals}
+
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_cxx_conftest_cxx98_main}
+  ${ac_cxx_conftest_cxx11_main}
+  return ok;
+}
+"
+
+# Test code for whether the C compiler supports C++98 (complete).
+ac_cxx_conftest_cxx98_program="${ac_cxx_conftest_cxx98_globals}
+int
+main (int argc, char **argv)
+{
+  int ok = 0;
+  ${ac_cxx_conftest_cxx98_main}
+  return ok;
+}
+"
+
+as_fn_append ac_header_c_list " stdio.h stdio_h HAVE_STDIO_H"
+as_fn_append ac_header_c_list " stdlib.h stdlib_h HAVE_STDLIB_H"
+as_fn_append ac_header_c_list " string.h string_h HAVE_STRING_H"
+as_fn_append ac_header_c_list " inttypes.h inttypes_h HAVE_INTTYPES_H"
+as_fn_append ac_header_c_list " stdint.h stdint_h HAVE_STDINT_H"
+as_fn_append ac_header_c_list " strings.h strings_h HAVE_STRINGS_H"
+as_fn_append ac_header_c_list " sys/stat.h sys_stat_h HAVE_SYS_STAT_H"
+as_fn_append ac_header_c_list " sys/types.h sys_types_h HAVE_SYS_TYPES_H"
+as_fn_append ac_header_c_list " unistd.h unistd_h HAVE_UNISTD_H"
+
+# Auxiliary files required by this configure script.
+ac_aux_files="compile missing install-sh config.guess config.sub"
+
+# Locations in which to look for auxiliary files.
+ac_aux_dir_candidates="${srcdir}/Tools/config"
+
+# Search for a directory containing all of the required auxiliary files,
+# $ac_aux_files, from the $PATH-style list $ac_aux_dir_candidates.
+# If we don't find one directory that contains all the files we need,
+# we report the set of missing files from the *first* directory in
+# $ac_aux_dir_candidates and give up.
+ac_missing_aux_files=""
+ac_first_candidate=:
+printf "%s\n" "$as_me:${as_lineno-$LINENO}: looking for aux files: $ac_aux_files" >&5
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in $ac_aux_dir_candidates
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+  as_found=:
+
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}:  trying $as_dir" >&5
+  ac_aux_dir_found=yes
+  ac_install_sh=
+  for ac_aux in $ac_aux_files
+  do
+    # As a special case, if "install-sh" is required, that requirement
+    # can be satisfied by any of "install-sh", "install.sh", or "shtool",
+    # and $ac_install_sh is set appropriately for whichever one is found.
+    if test x"$ac_aux" = x"install-sh"
+    then
+      if test -f "${as_dir}install-sh"; then
+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}install-sh found" >&5
+        ac_install_sh="${as_dir}install-sh -c"
+      elif test -f "${as_dir}install.sh"; then
+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}install.sh found" >&5
+        ac_install_sh="${as_dir}install.sh -c"
+      elif test -f "${as_dir}shtool"; then
+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}shtool found" >&5
+        ac_install_sh="${as_dir}shtool install -c"
+      else
+        ac_aux_dir_found=no
+        if $ac_first_candidate; then
+          ac_missing_aux_files="${ac_missing_aux_files} install-sh"
+        else
+          break
+        fi
+      fi
+    else
+      if test -f "${as_dir}${ac_aux}"; then
+        printf "%s\n" "$as_me:${as_lineno-$LINENO}:   ${as_dir}${ac_aux} found" >&5
+      else
+        ac_aux_dir_found=no
+        if $ac_first_candidate; then
+          ac_missing_aux_files="${ac_missing_aux_files} ${ac_aux}"
+        else
+          break
+        fi
+      fi
+    fi
+  done
+  if test "$ac_aux_dir_found" = yes; then
+    ac_aux_dir="$as_dir"
+    break
+  fi
+  ac_first_candidate=false
+
+  as_found=false
+done
+IFS=$as_save_IFS
+if $as_found
+then :
+
+else $as_nop
+  as_fn_error $? "cannot find required auxiliary files:$ac_missing_aux_files" "$LINENO" 5
+fi
+
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+if test -f "${ac_aux_dir}config.guess"; then
+  ac_config_guess="$SHELL ${ac_aux_dir}config.guess"
+fi
+if test -f "${ac_aux_dir}config.sub"; then
+  ac_config_sub="$SHELL ${ac_aux_dir}config.sub"
+fi
+if test -f "$ac_aux_dir/configure"; then
+  ac_configure="$SHELL ${ac_aux_dir}configure"
+fi
+
 # Check that the precious variables saved in the cache have kept the same
 # value.
 ac_cache_corrupted=false
@@ -2675,12 +2962,12 @@
   eval ac_new_val=\$ac_env_${ac_var}_value
   case $ac_old_set,$ac_new_set in
     set,)
-      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
       ac_cache_corrupted=: ;;
     ,set)
-      { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
-$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
       ac_cache_corrupted=: ;;
     ,);;
     *)
@@ -2689,24 +2976,24 @@
 	ac_old_val_w=`echo x $ac_old_val`
 	ac_new_val_w=`echo x $ac_new_val`
 	if test "$ac_old_val_w" != "$ac_new_val_w"; then
-	  { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
-$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+printf "%s\n" "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
 	  ac_cache_corrupted=:
 	else
-	  { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
-$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+printf "%s\n" "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
 	  eval $ac_var=\$ac_old_val
 	fi
-	{ $as_echo "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
-$as_echo "$as_me:   former value:  \`$ac_old_val'" >&2;}
-	{ $as_echo "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
-$as_echo "$as_me:   current value: \`$ac_new_val'" >&2;}
+	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}:   former value:  \`$ac_old_val'" >&5
+printf "%s\n" "$as_me:   former value:  \`$ac_old_val'" >&2;}
+	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}:   current value: \`$ac_new_val'" >&5
+printf "%s\n" "$as_me:   current value: \`$ac_new_val'" >&2;}
       fi;;
   esac
   # Pass precious variables to config.status.
   if test "$ac_new_set" = set; then
     case $ac_new_val in
-    *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *\'*) ac_arg=$ac_var=`printf "%s\n" "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
     *) ac_arg=$ac_var=$ac_new_val ;;
     esac
     case " $ac_configure_args " in
@@ -2716,11 +3003,12 @@
   fi
 done
 if $ac_cache_corrupted; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-  { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
-$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
-  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+printf "%s\n" "$as_me: error: changes in the environment can compromise the build" >&2;}
+  as_fn_error $? "run \`${MAKE-make} distclean' and/or \`rm $cache_file'
+	    and start over" "$LINENO" 5
 fi
 ## -------------------- ##
 ## Main body of script. ##
@@ -2736,57 +3024,33 @@
 
 
 
-ac_aux_dir=
-for ac_dir in Tools/config "$srcdir"/Tools/config; do
-  if test -f "$ac_dir/install-sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install-sh -c"
-    break
-  elif test -f "$ac_dir/install.sh"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/install.sh -c"
-    break
-  elif test -f "$ac_dir/shtool"; then
-    ac_aux_dir=$ac_dir
-    ac_install_sh="$ac_aux_dir/shtool install -c"
-    break
-  fi
-done
-if test -z "$ac_aux_dir"; then
-  as_fn_error $? "cannot find install-sh, install.sh, or shtool in Tools/config \"$srcdir\"/Tools/config" "$LINENO" 5
-fi
-
-# These three variables are undocumented and unsupported,
-# and are intended to be withdrawn in a future Autoconf release.
-# They can cause serious problems if a builder's source tree is in a directory
-# whose full name contains unusual characters.
-ac_config_guess="$SHELL $ac_aux_dir/config.guess"  # Please don't use this var.
-ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
-ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
-
 
 ac_config_headers="$ac_config_headers Source/Include/swigconfig.h"
 
-# Make sure we can run config.sub.
-$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
-  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
-$as_echo_n "checking build system type... " >&6; }
-if ${ac_cv_build+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+
+
+  # Make sure we can run config.sub.
+$SHELL "${ac_aux_dir}config.sub" sun4 >/dev/null 2>&1 ||
+  as_fn_error $? "cannot run $SHELL ${ac_aux_dir}config.sub" "$LINENO" 5
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+printf %s "checking build system type... " >&6; }
+if test ${ac_cv_build+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_build_alias=$build_alias
 test "x$ac_build_alias" = x &&
-  ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+  ac_build_alias=`$SHELL "${ac_aux_dir}config.guess"`
 test "x$ac_build_alias" = x &&
   as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
-ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
-  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+ac_cv_build=`$SHELL "${ac_aux_dir}config.sub" $ac_build_alias` ||
+  as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $ac_build_alias failed" "$LINENO" 5
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
-$as_echo "$ac_cv_build" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+printf "%s\n" "$ac_cv_build" >&6; }
 case $ac_cv_build in
 *-*-*) ;;
 *) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
@@ -2805,21 +3069,22 @@
 case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
-$as_echo_n "checking host system type... " >&6; }
-if ${ac_cv_host+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+printf %s "checking host system type... " >&6; }
+if test ${ac_cv_host+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test "x$host_alias" = x; then
   ac_cv_host=$ac_cv_build
 else
-  ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
-    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+  ac_cv_host=`$SHELL "${ac_aux_dir}config.sub" $host_alias` ||
+    as_fn_error $? "$SHELL ${ac_aux_dir}config.sub $host_alias failed" "$LINENO" 5
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
-$as_echo "$ac_cv_host" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+printf "%s\n" "$ac_cv_host" >&6; }
 case $ac_cv_host in
 *-*-*) ;;
 *) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
@@ -2840,7 +3105,8 @@
 
 am__api_version='1.16'
 
-# Find a good install program.  We prefer a C program (faster),
+
+  # Find a good install program.  We prefer a C program (faster),
 # so one script is as good as another.  But avoid the broken or
 # incompatible versions:
 # SysV /etc/install, /usr/sbin/install
@@ -2854,20 +3120,25 @@
 # OS/2's system install, which has a completely different semantic
 # ./install, which can be erroneously created by make from ./install.sh.
 # Reject install programs that cannot install multiple files.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
-$as_echo_n "checking for a BSD-compatible install... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+printf %s "checking for a BSD-compatible install... " >&6; }
 if test -z "$INSTALL"; then
-if ${ac_cv_path_install+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+if test ${ac_cv_path_install+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    # Account for people who put trailing slashes in PATH elements.
-case $as_dir/ in #((
-  ./ | .// | /[cC]/* | \
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    # Account for fact that we put trailing slashes in our PATH walk.
+case $as_dir in #((
+  ./ | /[cC]/* | \
   /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
   ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
   /usr/ucb/* ) ;;
@@ -2877,13 +3148,13 @@
     # by default.
     for ac_prog in ginstall scoinst install; do
       for ac_exec_ext in '' $ac_executable_extensions; do
-	if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	if as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext"; then
 	  if test $ac_prog = install &&
-	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    grep dspmsg "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
 	    # AIX install.  It has an incompatible calling convention.
 	    :
 	  elif test $ac_prog = install &&
-	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    grep pwplus "$as_dir$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
 	    # program-specific install script used by HP pwplus--don't use.
 	    :
 	  else
@@ -2891,12 +3162,12 @@
 	    echo one > conftest.one
 	    echo two > conftest.two
 	    mkdir conftest.dir
-	    if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+	    if "$as_dir$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir/" &&
 	      test -s conftest.one && test -s conftest.two &&
 	      test -s conftest.dir/conftest.one &&
 	      test -s conftest.dir/conftest.two
 	    then
-	      ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	      ac_cv_path_install="$as_dir$ac_prog$ac_exec_ext -c"
 	      break 3
 	    fi
 	  fi
@@ -2912,7 +3183,7 @@
 rm -rf conftest.one conftest.two conftest.dir
 
 fi
-  if test "${ac_cv_path_install+set}" = set; then
+  if test ${ac_cv_path_install+y}; then
     INSTALL=$ac_cv_path_install
   else
     # As a last resort, use the slow shell script.  Don't cache a
@@ -2922,8 +3193,8 @@
     INSTALL=$ac_install_sh
   fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
-$as_echo "$INSTALL" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+printf "%s\n" "$INSTALL" >&6; }
 
 # Use test -z because SunOS4 sh mishandles braces in ${var-val}.
 # It thinks the first close brace ends the variable substitution.
@@ -2933,8 +3204,8 @@
 
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
-$as_echo_n "checking whether build environment is sane... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+printf %s "checking whether build environment is sane... " >&6; }
 # Reject unsafe characters in $srcdir or the absolute working directory
 # name.  Accept space and tab only in the latter.
 am_lf='
@@ -2988,8 +3259,8 @@
    as_fn_error $? "newly created file is older than distributed files!
 Check your system clock" "$LINENO" 5
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
 # If we didn't sleep, we still need to ensure time stamps of config.status and
 # generated files are strictly newer.
 am_sleep_pid=
@@ -3008,26 +3279,23 @@
 # Double any \ or $.
 # By default was `s,x,x', remove it if useless.
 ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
-program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+program_transform_name=`printf "%s\n" "$program_transform_name" | sed "$ac_script"`
+
 
 # Expand $ac_aux_dir to an absolute path.
 am_aux_dir=`cd "$ac_aux_dir" && pwd`
 
-if test x"${MISSING+set}" != xset; then
-  case $am_aux_dir in
-  *\ * | *\	*)
-    MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
-  *)
-    MISSING="\${SHELL} $am_aux_dir/missing" ;;
-  esac
+
+  if test x"${MISSING+set}" != xset; then
+  MISSING="\${SHELL} '$am_aux_dir/missing'"
 fi
 # Use eval to expand $SHELL
 if eval "$MISSING --is-lightweight"; then
   am_missing_run="$MISSING "
 else
   am_missing_run=
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
-$as_echo "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: 'missing' script is too old or missing" >&5
+printf "%s\n" "$as_me: WARNING: 'missing' script is too old or missing" >&2;}
 fi
 
 if test x"${install_sh+set}" != xset; then
@@ -3047,11 +3315,12 @@
   if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
 set dummy ${ac_tool_prefix}strip; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_STRIP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_STRIP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$STRIP"; then
   ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
 else
@@ -3059,11 +3328,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_STRIP="${ac_tool_prefix}strip"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -3074,11 +3347,11 @@
 fi
 STRIP=$ac_cv_prog_STRIP
 if test -n "$STRIP"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
-$as_echo "$STRIP" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+printf "%s\n" "$STRIP" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -3087,11 +3360,12 @@
   ac_ct_STRIP=$STRIP
   # Extract the first word of "strip", so it can be a program name with args.
 set dummy strip; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_STRIP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_STRIP"; then
   ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
 else
@@ -3099,11 +3373,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_STRIP="strip"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -3114,11 +3392,11 @@
 fi
 ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
 if test -n "$ac_ct_STRIP"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
-$as_echo "$ac_ct_STRIP" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+printf "%s\n" "$ac_ct_STRIP" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
   if test "x$ac_ct_STRIP" = x; then
@@ -3126,8 +3404,8 @@
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     STRIP=$ac_ct_STRIP
@@ -3139,25 +3417,31 @@
 fi
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
-$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a race-free mkdir -p" >&5
+printf %s "checking for a race-free mkdir -p... " >&6; }
 if test -z "$MKDIR_P"; then
-  if ${ac_cv_path_mkdir+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+  if test ${ac_cv_path_mkdir+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_prog in mkdir gmkdir; do
 	 for ac_exec_ext in '' $ac_executable_extensions; do
-	   as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
-	   case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
-	     'mkdir (GNU coreutils) '* | \
-	     'mkdir (coreutils) '* | \
+	   as_fn_executable_p "$as_dir$ac_prog$ac_exec_ext" || continue
+	   case `"$as_dir$ac_prog$ac_exec_ext" --version 2>&1` in #(
+	     'mkdir ('*'coreutils) '* | \
+	     'BusyBox '* | \
 	     'mkdir (fileutils) '4.1*)
-	       ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+	       ac_cv_path_mkdir=$as_dir$ac_prog$ac_exec_ext
 	       break 3;;
 	   esac
 	 done
@@ -3168,7 +3452,7 @@
 fi
 
   test -d ./--version && rmdir ./--version
-  if test "${ac_cv_path_mkdir+set}" = set; then
+  if test ${ac_cv_path_mkdir+y}; then
     MKDIR_P="$ac_cv_path_mkdir -p"
   else
     # As a last resort, use the slow shell script.  Don't cache a
@@ -3178,18 +3462,19 @@
     MKDIR_P="$ac_install_sh -d"
   fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
-$as_echo "$MKDIR_P" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+printf "%s\n" "$MKDIR_P" >&6; }
 
 for ac_prog in gawk mawk nawk awk
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_AWK+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_AWK+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$AWK"; then
   ac_cv_prog_AWK="$AWK" # Let the user override the test.
 else
@@ -3197,11 +3482,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_AWK="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -3212,24 +3501,25 @@
 fi
 AWK=$ac_cv_prog_AWK
 if test -n "$AWK"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
-$as_echo "$AWK" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+printf "%s\n" "$AWK" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
   test -n "$AWK" && break
 done
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
-$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+printf %s "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
 set x ${MAKE-make}
-ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
-if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+ac_make=`printf "%s\n" "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if eval test \${ac_cv_prog_make_${ac_make}_set+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat >conftest.make <<\_ACEOF
 SHELL = /bin/sh
 all:
@@ -3245,12 +3535,12 @@
 rm -f conftest.make
 fi
 if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
   SET_MAKE=
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
   SET_MAKE="MAKE=${MAKE-make}"
 fi
 
@@ -3264,7 +3554,8 @@
 rmdir .tst 2>/dev/null
 
 # Check whether --enable-silent-rules was given.
-if test "${enable_silent_rules+set}" = set; then :
+if test ${enable_silent_rules+y}
+then :
   enableval=$enable_silent_rules;
 fi
 
@@ -3274,12 +3565,13 @@
     *) AM_DEFAULT_VERBOSITY=1;;
 esac
 am_make=${MAKE-make}
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
-$as_echo_n "checking whether $am_make supports nested variables... " >&6; }
-if ${am_cv_make_support_nested_variables+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if $as_echo 'TRUE=$(BAR$(V))
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $am_make supports nested variables" >&5
+printf %s "checking whether $am_make supports nested variables... " >&6; }
+if test ${am_cv_make_support_nested_variables+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if printf "%s\n" 'TRUE=$(BAR$(V))
 BAR0=false
 BAR1=true
 V=1
@@ -3291,8 +3583,8 @@
   am_cv_make_support_nested_variables=no
 fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
-$as_echo "$am_cv_make_support_nested_variables" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_make_support_nested_variables" >&5
+printf "%s\n" "$am_cv_make_support_nested_variables" >&6; }
 if test $am_cv_make_support_nested_variables = yes; then
     AM_V='$(V)'
   AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
@@ -3324,17 +3616,13 @@
 
 # Define the identity of the package.
  PACKAGE='swig'
- VERSION='4.0.1'
+ VERSION='4.2.1'
 
 
-cat >>confdefs.h <<_ACEOF
-#define PACKAGE "$PACKAGE"
-_ACEOF
+printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h
 
 
-cat >>confdefs.h <<_ACEOF
-#define VERSION "$VERSION"
-_ACEOF
+printf "%s\n" "#define VERSION \"$VERSION\"" >>confdefs.h
 
 # Some tools Automake needs.
 
@@ -3374,6 +3662,20 @@
 
 
 
+# Variables for tags utilities; see am/tags.am
+if test -z "$CTAGS"; then
+  CTAGS=ctags
+fi
+
+if test -z "$ETAGS"; then
+  ETAGS=etags
+fi
+
+if test -z "$CSCOPE"; then
+  CSCOPE=cscope
+fi
+
+
 
 # POSIX will say in a future version that running "rm -f" with no argument
 # is OK; and we want to be able to make that assumption in our Makefile
@@ -3420,6 +3722,15 @@
 
 
 
+
+
+
+
+
+
+
+
+
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -3428,11 +3739,12 @@
 if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
@@ -3440,11 +3752,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -3455,11 +3771,11 @@
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -3468,11 +3784,12 @@
   ac_ct_CC=$CC
   # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_CC"; then
   ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
 else
@@ -3480,11 +3797,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="gcc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -3495,11 +3816,11 @@
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
   if test "x$ac_ct_CC" = x; then
@@ -3507,8 +3828,8 @@
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     CC=$ac_ct_CC
@@ -3521,11 +3842,12 @@
           if test -n "$ac_tool_prefix"; then
     # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
 set dummy ${ac_tool_prefix}cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
@@ -3533,11 +3855,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -3548,11 +3874,11 @@
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -3561,11 +3887,12 @@
 if test -z "$CC"; then
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
@@ -3574,15 +3901,19 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    if test "$as_dir$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
        ac_prog_rejected=yes
        continue
      fi
     ac_cv_prog_CC="cc"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -3598,18 +3929,18 @@
     # However, it has the same basename, so the bogon will be chosen
     # first if we set CC to just the basename; use the full file name.
     shift
-    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+    ac_cv_prog_CC="$as_dir$ac_word${1+' '}$@"
   fi
 fi
 fi
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -3620,11 +3951,12 @@
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$CC"; then
   ac_cv_prog_CC="$CC" # Let the user override the test.
 else
@@ -3632,11 +3964,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -3647,11 +3983,11 @@
 fi
 CC=$ac_cv_prog_CC
 if test -n "$CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
-$as_echo "$CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -3664,11 +4000,12 @@
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_CC"; then
   ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
 else
@@ -3676,11 +4013,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -3691,11 +4032,11 @@
 fi
 ac_ct_CC=$ac_cv_prog_ac_ct_CC
 if test -n "$ac_ct_CC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
-$as_echo "$ac_ct_CC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -3707,8 +4048,8 @@
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     CC=$ac_ct_CC
@@ -3716,25 +4057,129 @@
 fi
 
 fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}clang", so it can be a program name with args.
+set dummy ${ac_tool_prefix}clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}clang"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+printf "%s\n" "$CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
 
 
-test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "clang", so it can be a program name with args.
+set dummy clang; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="clang"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+printf "%s\n" "$ac_ct_CC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+  if test "x$ac_ct_CC" = x; then
+    CC=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    CC=$ac_ct_CC
+  fi
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+
+
+test -z "$CC" && { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "no acceptable C compiler found in \$PATH
 See \`config.log' for more details" "$LINENO" 5; }
 
 # Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
 set X $ac_compile
 ac_compiler=$2
-for ac_option in --version -v -V -qversion; do
+for ac_option in --version -v -V -qversion -version; do
   { { ac_try="$ac_compiler $ac_option >&5"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_compiler $ac_option >&5") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -3744,7 +4189,7 @@
     cat conftest.er1 >&5
   fi
   rm -f conftest.er1 conftest.err
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
 done
 
@@ -3752,7 +4197,7 @@
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
@@ -3764,9 +4209,9 @@
 # Try to create an executable without -o first, disregard a.out.
 # It will help us diagnose broken compilers, and finding out an intuition
 # of exeext.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
-$as_echo_n "checking whether the C compiler works... " >&6; }
-ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+printf %s "checking whether the C compiler works... " >&6; }
+ac_link_default=`printf "%s\n" "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
 
 # The possible output files:
 ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
@@ -3787,11 +4232,12 @@
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_link_default") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
   # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
 # So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
 # in a Makefile.  We should not override ac_cv_exeext if it was cached,
@@ -3808,7 +4254,7 @@
 	# certainly right.
 	break;;
     *.* )
-	if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+	if test ${ac_cv_exeext+y} && test "$ac_cv_exeext" != no;
 	then :; else
 	   ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
 	fi
@@ -3824,44 +4270,46 @@
 done
 test "$ac_cv_exeext" = no && ac_cv_exeext=
 
-else
+else $as_nop
   ac_file=''
 fi
-if test -z "$ac_file"; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-$as_echo "$as_me: failed program was:" >&5
+if test -z "$ac_file"
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error 77 "C compiler cannot create executables
 See \`config.log' for more details" "$LINENO" 5; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
-$as_echo_n "checking for C compiler default output file name... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
-$as_echo "$ac_file" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+printf %s "checking for C compiler default output file name... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+printf "%s\n" "$ac_file" >&6; }
 ac_exeext=$ac_cv_exeext
 
 rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
 ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
-$as_echo_n "checking for suffix of executables... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+printf %s "checking for suffix of executables... " >&6; }
 if { { ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_link") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
   # If both `conftest.exe' and `conftest' are `present' (well, observable)
 # catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
 # work properly (i.e., refer to `conftest.exe'), while it won't with
@@ -3875,15 +4323,15 @@
     * ) break;;
   esac
 done
-else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+else $as_nop
+  { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "cannot compute suffix of executables: cannot compile and link
 See \`config.log' for more details" "$LINENO" 5; }
 fi
 rm -f conftest conftest$ac_cv_exeext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
-$as_echo "$ac_cv_exeext" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+printf "%s\n" "$ac_cv_exeext" >&6; }
 
 rm -f conftest.$ac_ext
 EXEEXT=$ac_cv_exeext
@@ -3892,7 +4340,7 @@
 /* end confdefs.h.  */
 #include <stdio.h>
 int
-main ()
+main (void)
 {
 FILE *f = fopen ("conftest.out", "w");
  return ferror (f) || fclose (f) != 0;
@@ -3904,8 +4352,8 @@
 ac_clean_files="$ac_clean_files conftest.out"
 # Check that the compiler produces executables we can run.  If not, either
 # the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
-$as_echo_n "checking whether we are cross compiling... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+printf %s "checking whether we are cross compiling... " >&6; }
 if test "$cross_compiling" != yes; then
   { { ac_try="$ac_link"
 case "(($ac_try" in
@@ -3913,10 +4361,10 @@
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_link") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
   if { ac_try='./conftest$ac_cv_exeext'
   { { case "(($ac_try" in
@@ -3924,39 +4372,40 @@
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_try") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }; }; then
     cross_compiling=no
   else
     if test "$cross_compiling" = maybe; then
 	cross_compiling=yes
     else
-	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "cannot run C compiled programs.
+	{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "cannot run C compiled programs.
 If you meant to cross compile, use \`--host'.
 See \`config.log' for more details" "$LINENO" 5; }
     fi
   fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
-$as_echo "$cross_compiling" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+printf "%s\n" "$cross_compiling" >&6; }
 
 rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
 ac_clean_files=$ac_clean_files_save
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
-$as_echo_n "checking for suffix of object files... " >&6; }
-if ${ac_cv_objext+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+printf %s "checking for suffix of object files... " >&6; }
+if test ${ac_cv_objext+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
@@ -3970,11 +4419,12 @@
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_compile") 2>&5
   ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then :
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+then :
   for ac_file in conftest.o conftest.obj conftest.*; do
   test -f "$ac_file" || continue;
   case $ac_file in
@@ -3983,31 +4433,32 @@
        break;;
   esac
 done
-else
-  $as_echo "$as_me: failed program was:" >&5
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "cannot compute suffix of object files: cannot compile
 See \`config.log' for more details" "$LINENO" 5; }
 fi
 rm -f conftest.$ac_cv_objext conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
-$as_echo "$ac_cv_objext" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+printf "%s\n" "$ac_cv_objext" >&6; }
 OBJEXT=$ac_cv_objext
 ac_objext=$OBJEXT
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
-$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if ${ac_cv_c_compiler_gnu+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C" >&5
+printf %s "checking whether the compiler supports GNU C... " >&6; }
+if test ${ac_cv_c_compiler_gnu+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 #ifndef __GNUC__
        choke me
@@ -4017,29 +4468,33 @@
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_compiler_gnu=yes
-else
+else $as_nop
   ac_compiler_gnu=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 ac_cv_c_compiler_gnu=$ac_compiler_gnu
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
-$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+printf "%s\n" "$ac_cv_c_compiler_gnu" >&6; }
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
 if test $ac_compiler_gnu = yes; then
   GCC=yes
 else
   GCC=
 fi
-ac_test_CFLAGS=${CFLAGS+set}
+ac_test_CFLAGS=${CFLAGS+y}
 ac_save_CFLAGS=$CFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
-$as_echo_n "checking whether $CC accepts -g... " >&6; }
-if ${ac_cv_prog_cc_g+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+printf %s "checking whether $CC accepts -g... " >&6; }
+if test ${ac_cv_prog_cc_g+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_save_c_werror_flag=$ac_c_werror_flag
    ac_c_werror_flag=yes
    ac_cv_prog_cc_g=no
@@ -4048,57 +4503,60 @@
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_prog_cc_g=yes
-else
+else $as_nop
   CFLAGS=""
       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
 
-else
+else $as_nop
   ac_c_werror_flag=$ac_save_c_werror_flag
 	 CFLAGS="-g"
 	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
+if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_prog_cc_g=yes
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    ac_c_werror_flag=$ac_save_c_werror_flag
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
-$as_echo "$ac_cv_prog_cc_g" >&6; }
-if test "$ac_test_CFLAGS" = set; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+printf "%s\n" "$ac_cv_prog_cc_g" >&6; }
+if test $ac_test_CFLAGS; then
   CFLAGS=$ac_save_CFLAGS
 elif test $ac_cv_prog_cc_g = yes; then
   if test "$GCC" = yes; then
@@ -4113,94 +4571,144 @@
     CFLAGS=
   fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
-$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if ${ac_cv_prog_cc_c89+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+ac_prog_cc_stdc=no
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C11 features" >&5
+printf %s "checking for $CC option to enable C11 features... " >&6; }
+if test ${ac_cv_prog_cc_c11+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c11=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c11_program
+_ACEOF
+for ac_arg in '' -std=gnu11
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c11=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c11" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
+
+if test "x$ac_cv_prog_cc_c11" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c11" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c11" >&5
+printf "%s\n" "$ac_cv_prog_cc_c11" >&6; }
+     CC="$CC $ac_cv_prog_cc_c11"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c11
+  ac_prog_cc_stdc=c11
+fi
+fi
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C99 features" >&5
+printf %s "checking for $CC option to enable C99 features... " >&6; }
+if test ${ac_cv_prog_cc_c99+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cc_c99=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_c_conftest_c99_program
+_ACEOF
+for ac_arg in '' -std=gnu99 -std=c99 -c99 -qlanglvl=extc1x -qlanglvl=extc99 -AC99 -D_STDC_C99=
+do
+  CC="$ac_save_CC $ac_arg"
+  if ac_fn_c_try_compile "$LINENO"
+then :
+  ac_cv_prog_cc_c99=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cc_c99" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+fi
+
+if test "x$ac_cv_prog_cc_c99" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c99" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c99" >&5
+printf "%s\n" "$ac_cv_prog_cc_c99" >&6; }
+     CC="$CC $ac_cv_prog_cc_c99"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c99
+  ac_prog_cc_stdc=c99
+fi
+fi
+if test x$ac_prog_cc_stdc = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CC option to enable C89 features" >&5
+printf %s "checking for $CC option to enable C89 features... " >&6; }
+if test ${ac_cv_prog_cc_c89+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_cv_prog_cc_c89=no
 ac_save_CC=$CC
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <stdarg.h>
-#include <stdio.h>
-struct stat;
-/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
-struct buf { int x; };
-FILE * (*rcsopen) (struct buf *, struct stat *, int);
-static char *e (p, i)
-     char **p;
-     int i;
-{
-  return p[i];
-}
-static char *f (char * (*g) (char **, int), char **p, ...)
-{
-  char *s;
-  va_list v;
-  va_start (v,p);
-  s = g (p, va_arg (v,int));
-  va_end (v);
-  return s;
-}
-
-/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
-   function prototypes and stuff, but not '\xHH' hex character constants.
-   These don't provoke an error unfortunately, instead are silently treated
-   as 'x'.  The following induces an error, until -std is added to get
-   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
-   array size at least.  It's necessary to write '\x00'==0 to get something
-   that's true only with -std.  */
-int osf4_cc_array ['\x00' == 0 ? 1 : -1];
-
-/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
-   inside strings and character constants.  */
-#define FOO(x) 'x'
-int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
-
-int test (int i, double x);
-struct s1 {int (*f) (int a);};
-struct s2 {int (*f) (double a);};
-int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
-int argc;
-char **argv;
-int
-main ()
-{
-return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
-  ;
-  return 0;
-}
+$ac_c_conftest_c89_program
 _ACEOF
-for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
-	-Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
 do
   CC="$ac_save_CC $ac_arg"
-  if ac_fn_c_try_compile "$LINENO"; then :
+  if ac_fn_c_try_compile "$LINENO"
+then :
   ac_cv_prog_cc_c89=$ac_arg
 fi
-rm -f core conftest.err conftest.$ac_objext
+rm -f core conftest.err conftest.$ac_objext conftest.beam
   test "x$ac_cv_prog_cc_c89" != "xno" && break
 done
 rm -f conftest.$ac_ext
 CC=$ac_save_CC
-
 fi
-# AC_CACHE_VAL
-case "x$ac_cv_prog_cc_c89" in
-  x)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
-$as_echo "none needed" >&6; } ;;
-  xno)
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
-$as_echo "unsupported" >&6; } ;;
-  *)
-    CC="$CC $ac_cv_prog_cc_c89"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
-$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
-esac
-if test "x$ac_cv_prog_cc_c89" != xno; then :
 
+if test "x$ac_cv_prog_cc_c89" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cc_c89" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+printf "%s\n" "$ac_cv_prog_cc_c89" >&6; }
+     CC="$CC $ac_cv_prog_cc_c89"
+fi
+  ac_cv_prog_cc_stdc=$ac_cv_prog_cc_c89
+  ac_prog_cc_stdc=c89
+fi
 fi
 
 ac_ext=c
@@ -4209,21 +4717,23 @@
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-ac_ext=c
+
+  ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
-$as_echo_n "checking whether $CC understands -c and -o together... " >&6; }
-if ${am_cv_prog_cc_c_o+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CC understands -c and -o together" >&5
+printf %s "checking whether $CC understands -c and -o together... " >&6; }
+if test ${am_cv_prog_cc_c_o+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
@@ -4251,8 +4761,8 @@
   rm -f core conftest*
   unset am_i
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
-$as_echo "$am_cv_prog_cc_c_o" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_prog_cc_c_o" >&5
+printf "%s\n" "$am_cv_prog_cc_c_o" >&6; }
 if test "$am_cv_prog_cc_c_o" != yes; then
    # Losing compiler, so override with the script.
    # FIXME: It is wrong to rewrite CC.
@@ -4271,8 +4781,8 @@
 
 ac_config_commands="$ac_config_commands depfiles"
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5
-$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5
+printf %s "checking whether ${MAKE-make} supports the include directive... " >&6; }
 cat > confinc.mk << 'END'
 am__doit:
 	@echo this is the am__doit target >confinc.out
@@ -4308,11 +4818,12 @@
   fi
 done
 rm -f confinc.* confmf.*
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5
-$as_echo "${_am_result}" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5
+printf "%s\n" "${_am_result}" >&6; }
 
 # Check whether --enable-dependency-tracking was given.
-if test "${enable_dependency_tracking+set}" = set; then :
+if test ${enable_dependency_tracking+y}
+then :
   enableval=$enable_dependency_tracking;
 fi
 
@@ -4333,11 +4844,12 @@
 
 depcc="$CC"   am_compiler_list=
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
-$as_echo_n "checking dependency style of $depcc... " >&6; }
-if ${am_cv_CC_dependencies_compiler_type+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+printf %s "checking dependency style of $depcc... " >&6; }
+if test ${am_cv_CC_dependencies_compiler_type+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
   # We make a subdir and do the tests there.  Otherwise we can end up
   # making bogus files that we don't know about and never remove.  For
@@ -4444,8 +4956,8 @@
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
-$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+printf "%s\n" "$am_cv_CC_dependencies_compiler_type" >&6; }
 CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
 
  if
@@ -4459,6 +4971,12 @@
 fi
 
 
+
+
+
+
+
+
 ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -4469,15 +4987,16 @@
     CXX=$CCC
   else
     if test -n "$ac_tool_prefix"; then
-  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CXX+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CXX+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$CXX"; then
   ac_cv_prog_CXX="$CXX" # Let the user override the test.
 else
@@ -4485,11 +5004,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -4500,11 +5023,11 @@
 fi
 CXX=$ac_cv_prog_CXX
 if test -n "$CXX"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
-$as_echo "$CXX" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+printf "%s\n" "$CXX" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -4513,15 +5036,16 @@
 fi
 if test -z "$CXX"; then
   ac_ct_CXX=$CXX
-  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+  for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC clang++
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ac_ct_CXX+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ac_ct_CXX+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$ac_ct_CXX"; then
   ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
 else
@@ -4529,11 +5053,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CXX="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -4544,11 +5072,11 @@
 fi
 ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
 if test -n "$ac_ct_CXX"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
-$as_echo "$ac_ct_CXX" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+printf "%s\n" "$ac_ct_CXX" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -4560,8 +5088,8 @@
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
-$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
     CXX=$ac_ct_CXX
@@ -4571,7 +5099,7 @@
   fi
 fi
 # Provide some information about the compiler.
-$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
 set X $ac_compile
 ac_compiler=$2
 for ac_option in --version -v -V -qversion; do
@@ -4581,7 +5109,7 @@
   *) ac_try_echo=$ac_try;;
 esac
 eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
+printf "%s\n" "$ac_try_echo"; } >&5
   (eval "$ac_compiler $ac_option >&5") 2>conftest.err
   ac_status=$?
   if test -s conftest.err; then
@@ -4591,20 +5119,21 @@
     cat conftest.er1 >&5
   fi
   rm -f conftest.er1 conftest.err
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
 done
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
-$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
-if ${ac_cv_cxx_compiler_gnu+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the compiler supports GNU C++" >&5
+printf %s "checking whether the compiler supports GNU C++... " >&6; }
+if test ${ac_cv_cxx_compiler_gnu+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 #ifndef __GNUC__
        choke me
@@ -4614,29 +5143,33 @@
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
   ac_compiler_gnu=yes
-else
+else $as_nop
   ac_compiler_gnu=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 ac_cv_cxx_compiler_gnu=$ac_compiler_gnu
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
-$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+printf "%s\n" "$ac_cv_cxx_compiler_gnu" >&6; }
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
 if test $ac_compiler_gnu = yes; then
   GXX=yes
 else
   GXX=
 fi
-ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_test_CXXFLAGS=${CXXFLAGS+y}
 ac_save_CXXFLAGS=$CXXFLAGS
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
-$as_echo_n "checking whether $CXX accepts -g... " >&6; }
-if ${ac_cv_prog_cxx_g+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+printf %s "checking whether $CXX accepts -g... " >&6; }
+if test ${ac_cv_prog_cxx_g+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_save_cxx_werror_flag=$ac_cxx_werror_flag
    ac_cxx_werror_flag=yes
    ac_cv_prog_cxx_g=no
@@ -4645,57 +5178,60 @@
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
   ac_cv_prog_cxx_g=yes
-else
+else $as_nop
   CXXFLAGS=""
       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
 
-else
+else $as_nop
   ac_cxx_werror_flag=$ac_save_cxx_werror_flag
 	 CXXFLAGS="-g"
 	 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
-main ()
+main (void)
 {
 
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
   ac_cv_prog_cxx_g=yes
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
    ac_cxx_werror_flag=$ac_save_cxx_werror_flag
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
-$as_echo "$ac_cv_prog_cxx_g" >&6; }
-if test "$ac_test_CXXFLAGS" = set; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+printf "%s\n" "$ac_cv_prog_cxx_g" >&6; }
+if test $ac_test_CXXFLAGS; then
   CXXFLAGS=$ac_save_CXXFLAGS
 elif test $ac_cv_prog_cxx_g = yes; then
   if test "$GXX" = yes; then
@@ -4710,6 +5246,100 @@
     CXXFLAGS=
   fi
 fi
+ac_prog_cxx_stdcxx=no
+if test x$ac_prog_cxx_stdcxx = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++11 features" >&5
+printf %s "checking for $CXX option to enable C++11 features... " >&6; }
+if test ${ac_cv_prog_cxx_11+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cxx_11=no
+ac_save_CXX=$CXX
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_cxx_conftest_cxx11_program
+_ACEOF
+for ac_arg in '' -std=gnu++11 -std=gnu++0x -std=c++11 -std=c++0x -qlanglvl=extended0x -AA
+do
+  CXX="$ac_save_CXX $ac_arg"
+  if ac_fn_cxx_try_compile "$LINENO"
+then :
+  ac_cv_prog_cxx_cxx11=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cxx_cxx11" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CXX=$ac_save_CXX
+fi
+
+if test "x$ac_cv_prog_cxx_cxx11" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cxx_cxx11" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx11" >&5
+printf "%s\n" "$ac_cv_prog_cxx_cxx11" >&6; }
+     CXX="$CXX $ac_cv_prog_cxx_cxx11"
+fi
+  ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx11
+  ac_prog_cxx_stdcxx=cxx11
+fi
+fi
+if test x$ac_prog_cxx_stdcxx = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $CXX option to enable C++98 features" >&5
+printf %s "checking for $CXX option to enable C++98 features... " >&6; }
+if test ${ac_cv_prog_cxx_98+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_cv_prog_cxx_98=no
+ac_save_CXX=$CXX
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_cxx_conftest_cxx98_program
+_ACEOF
+for ac_arg in '' -std=gnu++98 -std=c++98 -qlanglvl=extended -AA
+do
+  CXX="$ac_save_CXX $ac_arg"
+  if ac_fn_cxx_try_compile "$LINENO"
+then :
+  ac_cv_prog_cxx_cxx98=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam
+  test "x$ac_cv_prog_cxx_cxx98" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CXX=$ac_save_CXX
+fi
+
+if test "x$ac_cv_prog_cxx_cxx98" = xno
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+printf "%s\n" "unsupported" >&6; }
+else $as_nop
+  if test "x$ac_cv_prog_cxx_cxx98" = x
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+printf "%s\n" "none needed" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_cxx98" >&5
+printf "%s\n" "$ac_cv_prog_cxx_cxx98" >&6; }
+     CXX="$CXX $ac_cv_prog_cxx_cxx98"
+fi
+  ac_cv_prog_cxx_stdcxx=$ac_cv_prog_cxx_cxx98
+  ac_prog_cxx_stdcxx=cxx98
+fi
+fi
+
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -4718,11 +5348,12 @@
 
 depcc="$CXX"  am_compiler_list=
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
-$as_echo_n "checking dependency style of $depcc... " >&6; }
-if ${am_cv_CXX_dependencies_compiler_type+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+printf %s "checking dependency style of $depcc... " >&6; }
+if test ${am_cv_CXX_dependencies_compiler_type+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
   # We make a subdir and do the tests there.  Otherwise we can end up
   # making bogus files that we don't know about and never remove.  For
@@ -4829,8 +5460,8 @@
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
-$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+printf "%s\n" "$am_cv_CXX_dependencies_compiler_type" >&6; }
 CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
 
  if
@@ -4847,16 +5478,17 @@
   # Needed for subdir-objects in AUTOMAKE_OPTIONS
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking maximum warning verbosity option" >&5
-$as_echo_n "checking maximum warning verbosity option... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking maximum warning verbosity option" >&5
+printf %s "checking maximum warning verbosity option... " >&6; }
 
 
 
 
 # Check whether --with-maximum-compile-warnings was given.
-if test "${with_maximum_compile_warnings+set}" = set; then :
+if test ${with_maximum_compile_warnings+y}
+then :
   withval=$with_maximum_compile_warnings; ac_compile_warnings_on="$withval"
-else
+else $as_nop
   ac_compile_warnings_on=""
 fi
 
@@ -4869,7 +5501,7 @@
     then
       if test "$GXX" = "yes"
       then
-        ac_compile_warnings_opt='-Wall -W -ansi -pedantic'
+        ac_compile_warnings_opt='-Wall -W -pedantic'
       fi
       CXXFLAGS="$CXXFLAGS $ac_compile_warnings_opt"
       ac_compile_warnings_msg="$ac_compile_warnings_opt for C++"
@@ -4879,173 +5511,41 @@
   then
     if test "$GCC" = "yes"
     then
-      ac_compile_warnings_opt='-Wall -W -ansi -pedantic'
+      ac_compile_warnings_opt='-Wall -W -pedantic'
     fi
     CFLAGS="$CFLAGS $ac_compile_warnings_opt"
     ac_compile_warnings_msg="$ac_compile_warnings_msg $ac_compile_warnings_opt for C"
   fi
   fi
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_compile_warnings_msg" >&5
-$as_echo "$ac_compile_warnings_msg" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_compile_warnings_msg" >&5
+printf "%s\n" "$ac_compile_warnings_msg" >&6; }
   unset ac_compile_warnings_msg
   unset ac_compile_warnings_opt
  # Increase warning levels
 
-
-cat >>confdefs.h <<_ACEOF
-#define SWIG_CXX "$CXX"
-_ACEOF
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking CFLAGS to compile SWIG executable" >&5
+printf %s "checking CFLAGS to compile SWIG executable... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CFLAGS" >&5
+printf "%s\n" "$CFLAGS" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking CXXFLAGS to compile SWIG executable" >&5
+printf %s "checking CXXFLAGS to compile SWIG executable... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXXFLAGS" >&5
+printf "%s\n" "$CXXFLAGS" >&6; }
 
 
-cat >>confdefs.h <<_ACEOF
-#define SWIG_PLATFORM "$host"
-_ACEOF
+printf "%s\n" "#define SWIG_CXX \"$CXX\"" >>confdefs.h
 
 
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
-$as_echo_n "checking how to run the C preprocessor... " >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
-  CPP=
-fi
-if test -z "$CPP"; then
-  if ${ac_cv_prog_CPP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-      # Double quotes because CPP needs to be expanded
-    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
-    do
-      ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-		     Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
-  # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  # Broken: success on invalid input.
-continue
-else
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-  break
-fi
-
-    done
-    ac_cv_prog_CPP=$CPP
-
-fi
-  CPP=$ac_cv_prog_CPP
-else
-  ac_cv_prog_CPP=$CPP
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
-$as_echo "$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
-  # Use a header file that comes with gcc, so configuring glibc
-  # with a fresh cross-compiler works.
-  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-  # <limits.h> exists even on freestanding compilers.
-  # On the NeXT, cc -E runs the code through the compiler's parser,
-  # not just through cpp. "Syntax error" is here to catch this case.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-		     Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
-  # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-  # OK, works on sane cases.  Now check whether nonexistent headers
-  # can be detected and how.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-  # Broken: success on invalid input.
-continue
-else
-  # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.i conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-
-else
-  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
+printf "%s\n" "#define SWIG_PLATFORM \"$host\"" >>confdefs.h
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
-$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if ${ac_cv_path_GREP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+# For AC_EGREP_CPP
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+printf %s "checking for grep that handles long lines and -e... " >&6; }
+if test ${ac_cv_path_GREP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -z "$GREP"; then
   ac_path_GREP_found=false
   # Loop through the user's path and test for each of PROGNAME-LIST
@@ -5053,10 +5553,15 @@
 for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in grep ggrep; do
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_prog in grep ggrep
+   do
     for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+      ac_path_GREP="$as_dir$ac_prog$ac_exec_ext"
       as_fn_executable_p "$ac_path_GREP" || continue
 # Check for GNU ac_path_GREP and select it if it is found.
   # Check for GNU $ac_path_GREP
@@ -5065,13 +5570,13 @@
   ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
 *)
   ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
+  printf %s 0123456789 >"conftest.in"
   while :
   do
     cat "conftest.in" "conftest.in" >"conftest.tmp"
     mv "conftest.tmp" "conftest.in"
     cp "conftest.in" "conftest.nl"
-    $as_echo 'GREP' >> "conftest.nl"
+    printf "%s\n" 'GREP' >> "conftest.nl"
     "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
     diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
     as_fn_arith $ac_count + 1 && ac_count=$as_val
@@ -5099,16 +5604,17 @@
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
-$as_echo "$ac_cv_path_GREP" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+printf "%s\n" "$ac_cv_path_GREP" >&6; }
  GREP="$ac_cv_path_GREP"
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
-$as_echo_n "checking for egrep... " >&6; }
-if ${ac_cv_path_EGREP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+printf %s "checking for egrep... " >&6; }
+if test ${ac_cv_path_EGREP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
    then ac_cv_path_EGREP="$GREP -E"
    else
@@ -5119,10 +5625,15 @@
 for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in egrep; do
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_prog in egrep
+   do
     for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+      ac_path_EGREP="$as_dir$ac_prog$ac_exec_ext"
       as_fn_executable_p "$ac_path_EGREP" || continue
 # Check for GNU ac_path_EGREP and select it if it is found.
   # Check for GNU $ac_path_EGREP
@@ -5131,13 +5642,13 @@
   ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
 *)
   ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
+  printf %s 0123456789 >"conftest.in"
   while :
   do
     cat "conftest.in" "conftest.in" >"conftest.tmp"
     mv "conftest.tmp" "conftest.in"
     cp "conftest.in" "conftest.nl"
-    $as_echo 'EGREP' >> "conftest.nl"
+    printf "%s\n" 'EGREP' >> "conftest.nl"
     "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
     diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
     as_fn_arith $ac_count + 1 && ac_count=$as_val
@@ -5166,178 +5677,46 @@
 
    fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
-$as_echo "$ac_cv_path_EGREP" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+printf "%s\n" "$ac_cv_path_EGREP" >&6; }
  EGREP="$ac_cv_path_EGREP"
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
-$as_echo_n "checking for ANSI C header files... " >&6; }
-if ${ac_cv_header_stdc+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-  ac_cv_header_stdc=yes
-else
-  ac_cv_header_stdc=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
-  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "memchr" >/dev/null 2>&1; then :
-
-else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "free" >/dev/null 2>&1; then :
-
-else
-  ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
-  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
-  if test "$cross_compiling" = yes; then :
-  :
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
-		   (('a' <= (c) && (c) <= 'i') \
-		     || ('j' <= (c) && (c) <= 'r') \
-		     || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
-  int i;
-  for (i = 0; i < 256; i++)
-    if (XOR (islower (i), ISLOWER (i))
-	|| toupper (i) != TOUPPER (i))
-      return 2;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-
-else
-  ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
-$as_echo "$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-$as_echo "#define STDC_HEADERS 1" >>confdefs.h
-
-fi
-
-
-
-# Check whether --with-popen was given.
-if test "${with_popen+set}" = set; then :
-  withval=$with_popen; with_popen="$withval"
-fi
-
-if test x"${with_popen}" = xno ; then
-{ $as_echo "$as_me:${as_lineno-$LINENO}: Disabling popen" >&5
-$as_echo "$as_me: Disabling popen" >&6;}
-else
-ac_fn_c_check_func "$LINENO" "popen" "ac_cv_func_popen"
-if test "x$ac_cv_func_popen" = xyes; then :
-
-$as_echo "#define HAVE_POPEN 1" >>confdefs.h
-
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: Disabling popen" >&5
-$as_echo "$as_me: Disabling popen" >&6;}
-fi
-
-fi
 
 
 # Check whether --with-pcre was given.
-if test "${with_pcre+set}" = set; then :
+if test ${with_pcre+y}
+then :
   withval=$with_pcre;
-else
+else $as_nop
   with_pcre=yes
 fi
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable PCRE support" >&5
-$as_echo_n "checking whether to enable PCRE support... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $with_pcre" >&5
-$as_echo "$with_pcre" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable PCRE2 support" >&5
+printf %s "checking whether to enable PCRE2 support... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_pcre" >&5
+printf "%s\n" "$with_pcre" >&6; }
 
 if test x"${with_pcre}" = xyes ; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use local PCRE" >&5
-$as_echo_n "checking whether to use local PCRE... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to use local PCRE2" >&5
+printf %s "checking whether to use local PCRE2... " >&6; }
   local_pcre_config=no
-  if test -z $PCRE_CONFIG; then
-    if test -f `pwd`/pcre/pcre-swig-install/bin/pcre-config; then
-      PCRE_CONFIG=`pwd`/pcre/pcre-swig-install/bin/pcre-config
-      local_pcre_config=$PCRE_CONFIG
+  if test -z "$PCRE2_CONFIG"; then
+    if test -f `pwd`/pcre/pcre-swig-install/bin/pcre2-config; then
+      PCRE2_CONFIG=`pwd`/pcre/pcre-swig-install/bin/pcre2-config
+      local_pcre_config=$PCRE2_CONFIG
     fi
   fi
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $local_pcre_config" >&5
-$as_echo "$local_pcre_config" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $local_pcre_config" >&5
+printf "%s\n" "$local_pcre_config" >&6; }
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
-$as_echo_n "checking for a sed that does not truncate output... " >&6; }
-if ${ac_cv_path_SED+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+printf %s "checking for a sed that does not truncate output... " >&6; }
+if test ${ac_cv_path_SED+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
             ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
      for ac_i in 1 2 3 4 5 6 7; do
        ac_script="$ac_script$as_nl$ac_script"
@@ -5351,10 +5730,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_prog in sed gsed; do
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_prog in sed gsed
+   do
     for ac_exec_ext in '' $ac_executable_extensions; do
-      ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+      ac_path_SED="$as_dir$ac_prog$ac_exec_ext"
       as_fn_executable_p "$ac_path_SED" || continue
 # Check for GNU ac_path_SED and select it if it is found.
   # Check for GNU $ac_path_SED
@@ -5363,13 +5747,13 @@
   ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;;
 *)
   ac_count=0
-  $as_echo_n 0123456789 >"conftest.in"
+  printf %s 0123456789 >"conftest.in"
   while :
   do
     cat "conftest.in" "conftest.in" >"conftest.tmp"
     mv "conftest.tmp" "conftest.in"
     cp "conftest.in" "conftest.nl"
-    $as_echo '' >> "conftest.nl"
+    printf "%s\n" '' >> "conftest.nl"
     "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break
     diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
     as_fn_arith $ac_count + 1 && ac_count=$as_val
@@ -5397,30 +5781,33 @@
 fi
 
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
-$as_echo "$ac_cv_path_SED" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+printf "%s\n" "$ac_cv_path_SED" >&6; }
  SED="$ac_cv_path_SED"
   rm -f conftest.sed
 
-if test "x$with_pcre" != xno; then :
+if test "x$with_pcre" != xno
+then :
 
 
 
 
 
-# Check whether --with-pcre-prefix was given.
-if test "${with_pcre_prefix+set}" = set; then :
-  withval=$with_pcre_prefix; pcre_config_prefix="$withval"
-else
-  pcre_config_prefix=""
+# Check whether --with-pcre2-prefix was given.
+if test ${with_pcre2_prefix+y}
+then :
+  withval=$with_pcre2_prefix; pcre2_config_prefix="$withval"
+else $as_nop
+  pcre2_config_prefix=""
 fi
 
 
-# Check whether --with-pcre-exec-prefix was given.
-if test "${with_pcre_exec_prefix+set}" = set; then :
-  withval=$with_pcre_exec_prefix; pcre_config_exec_prefix="$withval"
-else
-  pcre_config_exec_prefix=""
+# Check whether --with-pcre2-exec-prefix was given.
+if test ${with_pcre2_exec_prefix+y}
+then :
+  withval=$with_pcre2_exec_prefix; pcre2_config_exec_prefix="$withval"
+else $as_nop
+  pcre2_config_exec_prefix=""
 fi
 
 
@@ -5428,64 +5815,74 @@
 
 
 
-  if test x"$PCRE_CFLAGS" != x -o x"$PCRE_LIBS" != x; then :
+  if test x"$PCRE2_CFLAGS" != x -o x"$PCRE2_LIBS" != x
+then :
 
 
 
     :
 
-$as_echo "#define HAVE_PCRE 1" >>confdefs.h
+printf "%s\n" "#define HAVE_PCRE 1" >>confdefs.h
 
-     LIBS="$LIBS $PCRE_LIBS"
-     CPPFLAGS="$CPPFLAGS $PCRE_CFLAGS"
+     LIBS="$LIBS $PCRE2_LIBS"
+     CPPFLAGS="$CPPFLAGS $PCRE2_CFLAGS"
 
 
-else
+else $as_nop
 
-    if test x$pcre_config_exec_prefix != x; then :
+    if test x$pcre2_config_exec_prefix != x
+then :
 
-      pcre_config_args="$pcre_config_args --exec-prefix=$pcre_config_exec_prefix"
-      if test x${PCRE_CONFIG+set} != xset; then :
+      pcre2_config_args="$pcre2_config_args --exec-prefix=$pcre2_config_exec_prefix"
+      if test x${PCRE2_CONFIG+set} != xset
+then :
 
-	PCRE_CONFIG=$pcre_config_exec_prefix/bin/pcre-config
+	PCRE2_CONFIG=$pcre2_config_exec_prefix/bin/pcre2-config
 
 fi
 
 fi
-    if test x$pcre_config_prefix != x; then :
+    if test x$pcre2_config_prefix != x
+then :
 
-      pcre_config_args="$pcre_config_args --prefix=$pcre_config_prefix"
-      if test x${PCRE_CONFIG+set} != xset; then :
+      pcre2_config_args="$pcre2_config_args --prefix=$pcre2_config_prefix"
+      if test x${PCRE2_CONFIG+set} != xset
+then :
 
-	PCRE_CONFIG=$pcre_config_prefix/bin/pcre-config
+	PCRE2_CONFIG=$pcre2_config_prefix/bin/pcre2-config
 
 fi
 
 fi
 
-    for ac_prog in  pcre-config
+    for ac_prog in  pcre2-config
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_PCRE_CONFIG+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  case $PCRE_CONFIG in
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_PCRE2_CONFIG+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  case $PCRE2_CONFIG in
   [\\/]* | ?:[\\/]*)
-  ac_cv_path_PCRE_CONFIG="$PCRE_CONFIG" # Let the user override the test with a path.
+  ac_cv_path_PCRE2_CONFIG="$PCRE2_CONFIG" # Let the user override the test with a path.
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_PCRE_CONFIG="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_PCRE2_CONFIG="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -5495,76 +5892,81 @@
   ;;
 esac
 fi
-PCRE_CONFIG=$ac_cv_path_PCRE_CONFIG
-if test -n "$PCRE_CONFIG"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PCRE_CONFIG" >&5
-$as_echo "$PCRE_CONFIG" >&6; }
+PCRE2_CONFIG=$ac_cv_path_PCRE2_CONFIG
+if test -n "$PCRE2_CONFIG"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PCRE2_CONFIG" >&5
+printf "%s\n" "$PCRE2_CONFIG" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
-  test -n "$PCRE_CONFIG" && break
+  test -n "$PCRE2_CONFIG" && break
 done
-test -n "$PCRE_CONFIG" || PCRE_CONFIG="no"
+test -n "$PCRE2_CONFIG" || PCRE2_CONFIG="no"
 
-    if test "$PCRE_CONFIG" = "no"; then :
+    if test "$PCRE2_CONFIG" = "no"
+then :
 
       :
-      { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+      { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "
-        Cannot find pcre-config script from PCRE (Perl Compatible Regular Expressions)
+        Cannot find pcre2-config script from PCRE2 (Perl Compatible Regular Expressions)
         library package. This dependency is needed for configure to complete,
         Either:
-        - Install the PCRE developer package on your system (preferred approach).
-        - Download the PCRE source tarball, build and install on your system
+        - Install the PCRE2 developer package on your system (preferred approach).
+        - Download the PCRE2 source tarball, build and install on your system
           as you would for any package built from source distribution.
-        - Use the Tools/pcre-build.sh script to build PCRE just for SWIG to statically
+        - Use the Tools/pcre-build.sh script to build PCRE2 just for SWIG to statically
           link against. Run 'Tools/pcre-build.sh --help' for instructions.
-          (quite easy and does not require privileges to install PCRE on your system)
+          (quite easy and does not require privileges to install PCRE2 on your system)
         - Use configure --without-pcre to disable regular expressions support in SWIG
           (not recommended).
 See \`config.log' for more details" "$LINENO" 5; }
 
 
-else
+else $as_nop
 
-            if test x"" = x; then :
+            if test x"" = x
+then :
 
-	PCRE_CFLAGS="`$PCRE_CONFIG $pcre_config_args --cflags`"
+	PCRE2_CFLAGS="`$PCRE2_CONFIG $pcre2_config_args --cflags`"
 
-else
+else $as_nop
 
-	PCRE_CFLAGS="`$PCRE_CONFIG $pcre_config_args `"
+	PCRE2_CFLAGS="`$PCRE2_CONFIG $pcre2_config_args `"
 
 fi
 
-            if test x"" = x; then :
+            if test x"--libs8" = x
+then :
 
-	PCRE_LIBS="`$PCRE_CONFIG $pcre_config_args --libs`"
+	PCRE2_LIBS="`$PCRE2_CONFIG $pcre2_config_args --libs`"
 
-else
+else $as_nop
 
-	PCRE_LIBS="`$PCRE_CONFIG $pcre_config_args `"
+	PCRE2_LIBS="`$PCRE2_CONFIG $pcre2_config_args --libs8`"
 
 fi
 
-      if test x"" != x; then :
+      if test x"" != x
+then :
 
-		if test x"    " != x; then :
+		if test x"    " != x
+then :
 
-	  	  pcre_version="`$PCRE_CONFIG $pcre_config_args --version | $SED -e     `"
+	  	  pcre2_version="`$PCRE2_CONFIG $pcre2_config_args --version | $SED -e     `"
 
-else
+else $as_nop
 
-	  pcre_version="`$PCRE_CONFIG $pcre_config_args --version | $SED -e 's/^\ *\(.*\)\ *$/\1/'`"
+	  pcre2_version="`$PCRE2_CONFIG $pcre2_config_args --version | $SED -e 's/^\ *\(.*\)\ *$/\1/'`"
 
 fi
 
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pcre ($pcre_version) >= " >&5
-$as_echo_n "checking for pcre ($pcre_version) >= ... " >&6; }
+	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for pcre2 ($pcre2_version) >= " >&5
+printf %s "checking for pcre2 ($pcre2_version) >= ... " >&6; }
 
 
 
@@ -5577,7 +5979,7 @@
   # 0001001200050617.  In other words, each number is zero padded to four
   # digits, and non digits are removed.
 
-  ax_compare_version_A=`echo "$pcre_version" | sed -e 's/\([0-9]*\)/Z\1Z/g' \
+  ax_compare_version_A=`echo "$pcre2_version" | sed -e 's/\([0-9]*\)/Z\1Z/g' \
                      -e 's/Z\([0-9]\)Z/Z0\1Z/g' \
                      -e 's/Z\([0-9][0-9]\)Z/Z0\1Z/g' \
                      -e 's/Z\([0-9][0-9][0-9]\)Z/Z0\1Z/g' \
@@ -5598,35 +6000,35 @@
 
     if test "$ax_compare_version" = "true" ; then
 
-	  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
 
 
 
 	  :
 
-$as_echo "#define HAVE_PCRE 1" >>confdefs.h
+printf "%s\n" "#define HAVE_PCRE 1" >>confdefs.h
 
-     LIBS="$LIBS $PCRE_LIBS"
-     CPPFLAGS="$CPPFLAGS $PCRE_CFLAGS"
+     LIBS="$LIBS $PCRE2_LIBS"
+     CPPFLAGS="$CPPFLAGS $PCRE2_CFLAGS"
 
 
     else
-	  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+	  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 	  :
-	  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+	  { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "
-        Cannot find pcre-config script from PCRE (Perl Compatible Regular Expressions)
+        Cannot find pcre2-config script from PCRE2 (Perl Compatible Regular Expressions)
         library package. This dependency is needed for configure to complete,
         Either:
-        - Install the PCRE developer package on your system (preferred approach).
-        - Download the PCRE source tarball, build and install on your system
+        - Install the PCRE2 developer package on your system (preferred approach).
+        - Download the PCRE2 source tarball, build and install on your system
           as you would for any package built from source distribution.
-        - Use the Tools/pcre-build.sh script to build PCRE just for SWIG to statically
+        - Use the Tools/pcre-build.sh script to build PCRE2 just for SWIG to statically
           link against. Run 'Tools/pcre-build.sh --help' for instructions.
-          (quite easy and does not require privileges to install PCRE on your system)
+          (quite easy and does not require privileges to install PCRE2 on your system)
         - Use configure --without-pcre to disable regular expressions support in SWIG
           (not recommended).
 See \`config.log' for more details" "$LINENO" 5; }
@@ -5635,16 +6037,16 @@
   fi
 
 
-else
+else $as_nop
 
 
 
 	:
 
-$as_echo "#define HAVE_PCRE 1" >>confdefs.h
+printf "%s\n" "#define HAVE_PCRE 1" >>confdefs.h
 
-     LIBS="$LIBS $PCRE_LIBS"
-     CPPFLAGS="$CPPFLAGS $PCRE_CFLAGS"
+     LIBS="$LIBS $PCRE2_LIBS"
+     CPPFLAGS="$CPPFLAGS $PCRE2_CFLAGS"
 
 
 fi
@@ -5661,16 +6063,17 @@
 
 
 # Check whether --enable-ccache was given.
-if test "${enable_ccache+set}" = set; then :
+if test ${enable_ccache+y}
+then :
   enableval=$enable_ccache; enable_ccache=$enableval
-else
+else $as_nop
   enable_ccache=yes
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable ccache-swig" >&5
-$as_echo_n "checking whether to enable ccache-swig... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_ccache" >&5
-$as_echo "$enable_ccache" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to enable ccache-swig" >&5
+printf %s "checking whether to enable ccache-swig... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_ccache" >&5
+printf "%s\n" "$enable_ccache" >&6; }
 
 if test "$enable_ccache" = yes; then
 
@@ -5687,27 +6090,32 @@
 echo "Note : None of the following packages are required for users to compile and install SWIG from the distributed tarball"
 echo ""
 
-for ac_prog in 'bison -y' byacc
+for ac_prog in bison
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_YACC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$YACC"; then
-  ac_cv_prog_YACC="$YACC" # Let the user override the test.
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_BISON+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$BISON"; then
+  ac_cv_prog_BISON="$BISON" # Let the user override the test.
 else
 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_YACC="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_BISON="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -5716,19 +6124,19 @@
 
 fi
 fi
-YACC=$ac_cv_prog_YACC
-if test -n "$YACC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $YACC" >&5
-$as_echo "$YACC" >&6; }
+BISON=$ac_cv_prog_BISON
+if test -n "$BISON"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $BISON" >&5
+printf "%s\n" "$BISON" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
-  test -n "$YACC" && break
+  test -n "$BISON" && break
 done
-test -n "$YACC" || YACC="yacc"
+test -n "$BISON" || BISON="$MISSING bison"
 
 
 echo ""
@@ -5741,7 +6149,8 @@
 
 
 # Check whether --with-boost was given.
-if test "${with_boost+set}" = set; then :
+if test ${with_boost+y}
+then :
   withval=$with_boost;
      case $withval in #(
   no) :
@@ -5752,7 +6161,7 @@
     want_boost="yes";_AX_BOOST_BASE_boost_path="$withval" ;;
 esac
 
-else
+else $as_nop
   want_boost="yes"
 fi
 
@@ -5760,40 +6169,47 @@
 
 
 # Check whether --with-boost-libdir was given.
-if test "${with_boost_libdir+set}" = set; then :
+if test ${with_boost_libdir+y}
+then :
   withval=$with_boost_libdir;
-   if test -d "$withval"; then :
+   if test -d "$withval"
+then :
   _AX_BOOST_BASE_boost_lib_path="$withval"
-else
+else $as_nop
   as_fn_error $? "--with-boost-libdir expected directory name" "$LINENO" 5
 fi
 
-else
+else $as_nop
   _AX_BOOST_BASE_boost_lib_path=""
 fi
 
 
 BOOST_LDFLAGS=""
 BOOST_CPPFLAGS=""
-if test "x$want_boost" = "xyes"; then :
+if test "x$want_boost" = "xyes"
+then :
 
 
-  if test "x" = "x"; then :
+  if test "x" = "x"
+then :
   _AX_BOOST_BASE_TONUMERICVERSION_req="1.20.0"
-else
+else $as_nop
   _AX_BOOST_BASE_TONUMERICVERSION_req=""
 fi
   _AX_BOOST_BASE_TONUMERICVERSION_req_shorten=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '\([0-9]*\.[0-9]*\)'`
   _AX_BOOST_BASE_TONUMERICVERSION_req_major=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '\([0-9]*\)'`
-  if test "x$_AX_BOOST_BASE_TONUMERICVERSION_req_major" = "x"; then :
+  if test "x$_AX_BOOST_BASE_TONUMERICVERSION_req_major" = "x"
+then :
   as_fn_error $? "You should at least specify libboost major version" "$LINENO" 5
 fi
   _AX_BOOST_BASE_TONUMERICVERSION_req_minor=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '[0-9]*\.\([0-9]*\)'`
-  if test "x$_AX_BOOST_BASE_TONUMERICVERSION_req_minor" = "x"; then :
+  if test "x$_AX_BOOST_BASE_TONUMERICVERSION_req_minor" = "x"
+then :
   _AX_BOOST_BASE_TONUMERICVERSION_req_minor="0"
 fi
   _AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req : '[0-9]*\.[0-9]*\.\([0-9]*\)'`
-  if test "X$_AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor" = "X"; then :
+  if test "X$_AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor" = "X"
+then :
   _AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor="0"
 fi
   _AX_BOOST_BASE_TONUMERICVERSION_RET=`expr $_AX_BOOST_BASE_TONUMERICVERSION_req_major \* 100000 \+  $_AX_BOOST_BASE_TONUMERICVERSION_req_minor \* 100 \+ $_AX_BOOST_BASE_TONUMERICVERSION_req_sub_minor`
@@ -5821,37 +6237,40 @@
      ;;
 esac
 
-                if test "x$_AX_BOOST_BASE_boost_path" != "x"; then :
+                if test "x$_AX_BOOST_BASE_boost_path" != "x"
+then :
 
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for boostlib >=  ($WANT_BOOST_VERSION) includes in \"$_AX_BOOST_BASE_boost_path/include\"" >&5
-$as_echo_n "checking for boostlib >=  ($WANT_BOOST_VERSION) includes in \"$_AX_BOOST_BASE_boost_path/include\"... " >&6; }
-         if test -d "$_AX_BOOST_BASE_boost_path/include" && test -r "$_AX_BOOST_BASE_boost_path/include"; then :
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for boostlib >=  ($WANT_BOOST_VERSION) includes in \"$_AX_BOOST_BASE_boost_path/include\"" >&5
+printf %s "checking for boostlib >=  ($WANT_BOOST_VERSION) includes in \"$_AX_BOOST_BASE_boost_path/include\"... " >&6; }
+         if test -d "$_AX_BOOST_BASE_boost_path/include" && test -r "$_AX_BOOST_BASE_boost_path/include"
+then :
 
-           { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+           { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
            BOOST_CPPFLAGS="-I$_AX_BOOST_BASE_boost_path/include"
            for _AX_BOOST_BASE_boost_path_tmp in $multiarch_libsubdir $libsubdirs; do
-                { $as_echo "$as_me:${as_lineno-$LINENO}: checking for boostlib >=  ($WANT_BOOST_VERSION) lib path in \"$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp\"" >&5
-$as_echo_n "checking for boostlib >=  ($WANT_BOOST_VERSION) lib path in \"$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp\"... " >&6; }
-                if test -d "$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp" && test -r "$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp" ; then :
+                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for boostlib >=  ($WANT_BOOST_VERSION) lib path in \"$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp\"" >&5
+printf %s "checking for boostlib >=  ($WANT_BOOST_VERSION) lib path in \"$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp\"... " >&6; }
+                if test -d "$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp" && test -r "$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp"
+then :
 
-                        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+                        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
                         BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_path/$_AX_BOOST_BASE_boost_path_tmp";
                         break;
 
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+else $as_nop
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
            done
-else
+else $as_nop
 
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
-else
+else $as_nop
 
         if test X"$cross_compiling" = Xyes; then
             search_libsubdirs=$multiarch_libsubdir
@@ -5871,12 +6290,13 @@
 
 fi
 
-            if test "x$_AX_BOOST_BASE_boost_lib_path" != "x"; then :
+            if test "x$_AX_BOOST_BASE_boost_lib_path" != "x"
+then :
   BOOST_LDFLAGS="-L$_AX_BOOST_BASE_boost_lib_path"
 fi
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for boostlib >=  ($WANT_BOOST_VERSION)" >&5
-$as_echo_n "checking for boostlib >=  ($WANT_BOOST_VERSION)... " >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for boostlib >=  ($WANT_BOOST_VERSION)" >&5
+printf %s "checking for boostlib >=  ($WANT_BOOST_VERSION)... " >&6; }
     CPPFLAGS_SAVED="$CPPFLAGS"
     CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
     export CPPFLAGS
@@ -5898,7 +6318,7 @@
 #include <boost/version.hpp>
 
 int
-main ()
+main (void)
 {
 
 (void) ((void)sizeof(char[1 - 2*!!((BOOST_VERSION) < ($WANT_BOOST_VERSION))]));
@@ -5907,15 +6327,16 @@
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
 
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
     succeeded=yes
     found_system=yes
 
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
     ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -5991,8 +6412,8 @@
                         stage_version_shorten=`expr $stage_version : '\([0-9]*\.[0-9]*\)'`
                     V_CHECK=`expr $stage_version_shorten \>\= $_version`
                     if test "x$V_CHECK" = "x1" && test -z "$_AX_BOOST_BASE_boost_lib_path" ; then
-                        { $as_echo "$as_me:${as_lineno-$LINENO}: We will use a staged boost library from $BOOST_ROOT" >&5
-$as_echo "$as_me: We will use a staged boost library from $BOOST_ROOT" >&6;}
+                        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: We will use a staged boost library from $BOOST_ROOT" >&5
+printf "%s\n" "$as_me: We will use a staged boost library from $BOOST_ROOT" >&6;}
                         BOOST_CPPFLAGS="-I$BOOST_ROOT"
                         BOOST_LDFLAGS="-L$BOOST_ROOT/stage/$libsubdir"
                     fi
@@ -6017,7 +6438,7 @@
 #include <boost/version.hpp>
 
 int
-main ()
+main (void)
 {
 
 (void) ((void)sizeof(char[1 - 2*!!((BOOST_VERSION) < ($WANT_BOOST_VERSION))]));
@@ -6026,15 +6447,16 @@
   return 0;
 }
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
 
-            { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
         succeeded=yes
         found_system=yes
 
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
         ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -6045,17 +6467,17 @@
 
     if test "x$succeeded" != "xyes" ; then
         if test "x$_version" = "x0" ; then
-            { $as_echo "$as_me:${as_lineno-$LINENO}: We could not detect the boost libraries (version  or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option.  If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation." >&5
-$as_echo "$as_me: We could not detect the boost libraries (version  or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option.  If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation." >&6;}
+            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: We could not detect the boost libraries (version  or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option.  If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation." >&5
+printf "%s\n" "$as_me: We could not detect the boost libraries (version  or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option.  If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation." >&6;}
         else
-            { $as_echo "$as_me:${as_lineno-$LINENO}: Your boost libraries seems to old (version $_version)." >&5
-$as_echo "$as_me: Your boost libraries seems to old (version $_version)." >&6;}
+            { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Your boost libraries seems to old (version $_version)." >&5
+printf "%s\n" "$as_me: Your boost libraries seems to old (version $_version)." >&6;}
         fi
         # execute ACTION-IF-NOT-FOUND (if present):
         :
     else
 
-$as_echo "#define HAVE_BOOST /**/" >>confdefs.h
+printf "%s\n" "#define HAVE_BOOST /**/" >>confdefs.h
 
         # execute ACTION-IF-FOUND (if present):
         :
@@ -6071,19 +6493,10 @@
 
 
 
-# -I should not be used on system directories (GCC)
-if test "$GCC" = yes; then
-    ISYSTEM="-isystem "
-else
-    ISYSTEM="-I"
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: ISYSTEM: $ISYSTEM" >&5
-$as_echo "$as_me: ISYSTEM: $ISYSTEM" >&6;}
-
 
 # SO is the extension of shared libraries (including the dot!)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking SO" >&5
-$as_echo_n "checking SO... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking SO" >&5
+printf %s "checking SO... " >&6; }
 if test -z "$SO"
 then
 	case $host in
@@ -6093,29 +6506,29 @@
 	*) SO=.so;;
 	esac
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $SO" >&5
-$as_echo "$SO" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SO" >&5
+printf "%s\n" "$SO" >&6; }
 
 # LDSHARED is the ld *command* used to create shared library
 # -- "ld" on SunOS 4.x.x, "ld -G" on SunOS 5.x, "ld -shared" on IRIX 5
 # (Shared libraries in this instance are shared modules to be loaded into
 # Python, as opposed to building Python itself as a shared library.)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking LDSHARED" >&5
-$as_echo_n "checking LDSHARED... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking LDSHARED" >&5
+printf %s "checking LDSHARED... " >&6; }
 if test -z "$LDSHARED"
 then
 	case $host in
-	*-*-aix*) LDSHARED="\$(srcdir)/ld_so_aix \$(CC)";;
+	*-*-aix*) LDSHARED="$CC -shared";;
 	*-*-cygwin* | *-*-mingw*)
             if test "$GCC" = yes; then
-                LDSHARED="$CC -shared"
+                LDSHARED="\$(CC) -shared"
             else
                 if test "cl" = $CC ;  then
                     # Microsoft Visual C++ (MSVC)
-                    LDSHARED="$CC -nologo -LD"
+                    LDSHARED="\$(CC) -nologo -LD"
                 else
                     # Unknown compiler try gcc approach
-                    LDSHARED="$CC -shared"
+                    LDSHARED="\$(CC) -shared"
                 fi
             fi ;;
 	*-*-irix5*) LDSHARED="ld -shared";;
@@ -6127,75 +6540,75 @@
 	*-sequent-sysv4) LDSHARED="ld -G";;
 	*-*-next*)
 		if test "$ns_dyld"
-		then LDSHARED='$(CC) $(LDFLAGS) -bundle -prebind'
-		else LDSHARED='$(CC) $(CFLAGS) -nostdlib -r'
+		then LDSHARED="\$(CC) \$(LDFLAGS) -bundle -prebind"
+		else LDSHARED="\$(CC) \$(CFLAGS) -nostdlib -r"
 		fi
                 if test "$with_next_framework" ; then
 		    LDSHARED="$LDSHARED \$(LDLIBRARY)"
 		fi ;;
-	*-*-linux*) LDSHARED="$CC -shared";;
+	*-*-linux*) LDSHARED="\$(CC) -shared";;
 	*-*-dgux*) LDSHARED="ld -G";;
-	*-*-freebsd3*) LDSHARED="$CC -shared";;
+	*-*-freebsd3*) LDSHARED="\$(CC) -shared";;
 	*-*-freebsd* | *-*-openbsd*) LDSHARED="ld -Bshareable";;
 	*-*-netbsd*)
-		if [ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ]
+		if [ "`\$(CC) -dM -E - </dev/null | grep __ELF__`" != "" ]
 		then
-			LDSHARED="$CC -shared"
+			LDSHARED="\$(CC) -shared"
 		else
 			LDSHARED="ld -Bshareable"
 		fi;;
-	*-sco-sysv*) LDSHARED="$CC -G -KPIC -Ki486 -belf -Wl,-Bexport";;
-	*-*-darwin*) LDSHARED="$CC -bundle -undefined suppress -flat_namespace";;
+	*-sco-sysv*) LDSHARED="\$(CC) -G -KPIC -Ki486 -belf -Wl,-Bexport";;
+	*-*-darwin*) LDSHARED="\$(CC) -bundle -undefined suppress -flat_namespace";;
 	*)	LDSHARED="ld";;
 	esac
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LDSHARED" >&5
-$as_echo "$LDSHARED" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LDSHARED" >&5
+printf "%s\n" "$LDSHARED" >&6; }
 # CXXSHARED is the ld *command* used to create C++ shared library
 # -- "ld" on SunOS 4.x.x, "ld -G" on SunOS 5.x, "ld -shared" on IRIX 5
 # (Shared libraries in this instance are shared modules to be loaded into
 # Python, as opposed to building Python itself as a shared library.)
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking CXXSHARED" >&5
-$as_echo_n "checking CXXSHARED... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking CXXSHARED" >&5
+printf %s "checking CXXSHARED... " >&6; }
 if test -z "$CXXSHARED"
 then
 	CXXSHARED="$LDSHARED"
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXSHARED" >&5
-$as_echo "$CXXSHARED" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CXXSHARED" >&5
+printf "%s\n" "$CXXSHARED" >&6; }
 
 #
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking TRYLINKINGWITHCXX" >&5
-$as_echo_n "checking TRYLINKINGWITHCXX... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking TRYLINKINGWITHCXX" >&5
+printf %s "checking TRYLINKINGWITHCXX... " >&6; }
 if test -z "$TRYLINKINGWITHCXX"
 then
 	case $host in
 	*-*-solaris*) if test "$GCC" = yes
-             then TRYLINKINGWITHCXX="CXXSHARED= $CXX -Wl,-G"
-             else TRYLINKINGWITHCXX="CXXSHARED= $CXX -G -L/opt/SUNWspro/lib -lCrun -lCstd"
+             then TRYLINKINGWITHCXX="CXXSHARED= \$(CXX) -Wl,-G"
+             else TRYLINKINGWITHCXX="CXXSHARED= \$(CXX) -G -L/opt/SUNWspro/lib -lCrun -lCstd"
              fi;;
-        *-*-hp*) TRYLINKINGWITHCXX="CXXSHARED= $CXX +z ";;
-        *-*-darwin*) TRYLINKINGWITHCXX="CXXSHARED= $CXX -bundle -undefined suppress -flat_namespace";;
+        *-*-hp*) TRYLINKINGWITHCXX="CXXSHARED= \$(CXX) +z ";;
+        *-*-darwin*) TRYLINKINGWITHCXX="CXXSHARED= \$(CXX) -bundle -undefined suppress -flat_namespace";;
         *-*-cygwin* | *-*-mingw*)
             if test "$GCC" = yes; then
-                TRYLINKINGWITHCXX="CXXSHARED= $CXX -shared "
+                TRYLINKINGWITHCXX="CXXSHARED= \$(CXX) -shared "
             else
                 if test "cl" = $CXX ;  then
                     # Microsoft Visual C++ (MSVC)
-                    TRYLINKINGWITHCXX="CXXSHARED= $CXX -nologo -LD"
+                    TRYLINKINGWITHCXX="CXXSHARED= \$(CXX) -nologo -LD"
                 else
                     TRYLINKINGWITHCXX="#unknown Windows compiler"
                 fi
             fi ;;
-        *)       TRYLINKINGWITHCXX="CXXSHARED= $CXX -shared ";;
+        *)       TRYLINKINGWITHCXX="CXXSHARED= \$(CXX) -shared ";;
         esac
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $TRYLINKINGWITHCXX" >&5
-$as_echo "$TRYLINKINGWITHCXX" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $TRYLINKINGWITHCXX" >&5
+printf "%s\n" "$TRYLINKINGWITHCXX" >&6; }
 # CCSHARED are the C *flags* used to create objects to go into a shared
 # library (module) -- this is only needed for a few systems
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking CCSHARED" >&5
-$as_echo_n "checking CCSHARED... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking CCSHARED" >&5
+printf %s "checking CCSHARED... " >&6; }
 if test -z "$CCSHARED"
 then
 	case $host in
@@ -6215,12 +6628,12 @@
 		   esac;;
 	esac
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CCSHARED" >&5
-$as_echo "$CCSHARED" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CCSHARED" >&5
+printf "%s\n" "$CCSHARED" >&6; }
 
 # RPATH is the path used to look for shared library files.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking RPATH" >&5
-$as_echo_n "checking RPATH... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking RPATH" >&5
+printf %s "checking RPATH... " >&6; }
 if test -z "$RPATH"
 then
 	case $host in
@@ -6230,14 +6643,14 @@
 	*)	RPATH='';;
 	esac
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $RPATH" >&5
-$as_echo "$RPATH" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RPATH" >&5
+printf "%s\n" "$RPATH" >&6; }
 
 # LINKFORSHARED are the flags passed to the $(CC) command that links
 # a few executables -- this is only needed for a few systems
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking LINKFORSHARED" >&5
-$as_echo_n "checking LINKFORSHARED... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking LINKFORSHARED" >&5
+printf %s "checking LINKFORSHARED... " >&6; }
 if test -z "$LINKFORSHARED"
 then
 	case $host in
@@ -6250,164 +6663,2708 @@
 	*-*-irix6*) LINKFORSHARED="-all";;
 	esac
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $LINKFORSHARED" >&5
-$as_echo "$LINKFORSHARED" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LINKFORSHARED" >&5
+printf "%s\n" "$LINKFORSHARED" >&6; }
 
 # Optional CFLAGS used to silence/enhance compiler warnings on some platforms.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking PLATCFLAGS" >&5
-$as_echo_n "checking PLATCFLAGS... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking CFLAGS to use for testing (PLATCFLAGS)" >&5
+printf %s "checking CFLAGS to use for testing (PLATCFLAGS)... " >&6; }
 case $host in
   *-*-solaris*) if test "$GCC" = yes
     then PLATCFLAGS=
     else PLATCFLAGS=
       #    else PLATCFLAGS="-errtags=yes" # Need more work as C examples use ld for linking
     fi;;
+  *-*-aix*) PLATCFLAGS="$CFLAGS";;
   *) PLATCFLAGS=
 esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PLATCFLAGS" >&5
-$as_echo "$PLATCFLAGS" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PLATCFLAGS" >&5
+printf "%s\n" "$PLATCFLAGS" >&6; }
 
 # Add switch if necessary to enable C++11 support - just for tests
 # Check whether --enable-cpp11-testing was given.
-if test "${enable_cpp11_testing+set}" = set; then :
+if test ${enable_cpp11_testing+y}
+then :
   enableval=$enable_cpp11_testing; enable_cpp11_testing=$enableval
-else
-  enable_cpp11_testing=no
+else $as_nop
+  enable_cpp11_testing=yes
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable C++11 testing" >&5
-$as_echo_n "checking whether to enable C++11 testing... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_cpp11_testing" >&5
-$as_echo "$enable_cpp11_testing" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether to attempt to enable C++11 and later C++ standards testing" >&5
+printf %s "checking whether to attempt to enable C++11 and later C++ standards testing... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $enable_cpp11_testing" >&5
+printf "%s\n" "$enable_cpp11_testing" >&6; }
 
 PLATCXXFLAGS="$PLATCFLAGS"
 if test x"$enable_cpp11_testing" = xyes; then
+  CXX_SAVED=$CXX
+  CXXCPP_SAVED=$CXXCPP
+
+  # Test for c++20
+  CXXCPP=" "
+    ax_cxx_compile_alternatives="20"    ax_cxx_compile_cxx20_required=false
   ac_ext=cpp
 ac_cpp='$CXXCPP $CPPFLAGS'
 ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+  ac_success=no
 
-  CXXFLAGS_SAVED=$CXXFLAGS
-  CXXFLAGS=
-          ac_success=no
-  CXX11FLAGS=
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features by default" >&5
-$as_echo_n "checking whether $CXX supports C++11 features by default... " >&6; }
-if ${ax_cv_cxx_compile_cxx11+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
 
-  template <typename T>
-    struct check
-    {
-      static_assert(sizeof(int) <= sizeof(T), "not big enough");
-    };
-
-    typedef check<check<bool>> right_angle_brackets;
-
-    int a;
-    decltype(a) b;
-
-    typedef check<int> check_type;
-    check_type c;
-    check_type&& cr = static_cast<check_type&&>(c);
-
-_ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
-  ax_cv_cxx_compile_cxx11=yes
-else
-  ax_cv_cxx_compile_cxx11=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ax_cv_cxx_compile_cxx11" >&5
-$as_echo "$ax_cv_cxx_compile_cxx11" >&6; }
-  if test x$ax_cv_cxx_compile_cxx11 = xyes; then
-    ac_success=yes
-  fi
 
 
 
     if test x$ac_success = xno; then
-    for switch in -std=c++11 -std=c++0x; do
-      cachevar=`$as_echo "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh`
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5
-$as_echo_n "checking whether $CXX supports C++11 features with $switch... " >&6; }
-if eval \${$cachevar+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_save_CXXFLAGS="$CXXFLAGS"
-         CXXFLAGS="$CXXFLAGS $switch"
-         cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+                for alternative in ${ax_cxx_compile_alternatives}; do
+      for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
+        cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx20_$switch" | $as_tr_sh`
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++20 features with $switch" >&5
+printf %s "checking whether $CXX supports C++20 features with $switch... " >&6; }
+if eval test \${$cachevar+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_save_CXX="$CXX"
+           CXX="$CXX $switch"
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
-  template <typename T>
+
+// If the compiler admits that it is not ready for C++11, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201103L
+
+#error "This is not a C++11 compiler"
+
+#else
+
+namespace cxx11
+{
+
+  namespace test_static_assert
+  {
+
+    template <typename T>
     struct check
     {
       static_assert(sizeof(int) <= sizeof(T), "not big enough");
     };
 
-    typedef check<check<bool>> right_angle_brackets;
+  }
 
-    int a;
-    decltype(a) b;
+  namespace test_final_override
+  {
 
-    typedef check<int> check_type;
-    check_type c;
-    check_type&& cr = static_cast<check_type&&>(c);
+    struct Base
+    {
+      virtual ~Base() {}
+      virtual void f() {}
+    };
+
+    struct Derived : public Base
+    {
+      virtual ~Derived() override {}
+      virtual void f() override {}
+    };
+
+  }
+
+  namespace test_double_right_angle_brackets
+  {
+
+    template < typename T >
+    struct check {};
+
+    typedef check<void> single_type;
+    typedef check<check<void>> double_type;
+    typedef check<check<check<void>>> triple_type;
+    typedef check<check<check<check<void>>>> quadruple_type;
+
+  }
+
+  namespace test_decltype
+  {
+
+    int
+    f()
+    {
+      int a = 1;
+      decltype(a) b = 2;
+      return a + b;
+    }
+
+  }
+
+  namespace test_type_deduction
+  {
+
+    template < typename T1, typename T2 >
+    struct is_same
+    {
+      static const bool value = false;
+    };
+
+    template < typename T >
+    struct is_same<T, T>
+    {
+      static const bool value = true;
+    };
+
+    template < typename T1, typename T2 >
+    auto
+    add(T1 a1, T2 a2) -> decltype(a1 + a2)
+    {
+      return a1 + a2;
+    }
+
+    int
+    test(const int c, volatile int v)
+    {
+      static_assert(is_same<int, decltype(0)>::value == true, "");
+      static_assert(is_same<int, decltype(c)>::value == false, "");
+      static_assert(is_same<int, decltype(v)>::value == false, "");
+      auto ac = c;
+      auto av = v;
+      auto sumi = ac + av + 'x';
+      auto sumf = ac + av + 1.0;
+      static_assert(is_same<int, decltype(ac)>::value == true, "");
+      static_assert(is_same<int, decltype(av)>::value == true, "");
+      static_assert(is_same<int, decltype(sumi)>::value == true, "");
+      static_assert(is_same<int, decltype(sumf)>::value == false, "");
+      static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
+      return (sumf > 0.0) ? sumi : add(c, v);
+    }
+
+  }
+
+  namespace test_noexcept
+  {
+
+    int f() { return 0; }
+    int g() noexcept { return 0; }
+
+    static_assert(noexcept(f()) == false, "");
+    static_assert(noexcept(g()) == true, "");
+
+  }
+
+  namespace test_constexpr
+  {
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
+    {
+      return *s ? strlen_c_r(s + 1, acc + 1) : acc;
+    }
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c(const CharT *const s) noexcept
+    {
+      return strlen_c_r(s, 0UL);
+    }
+
+    static_assert(strlen_c("") == 0UL, "");
+    static_assert(strlen_c("1") == 1UL, "");
+    static_assert(strlen_c("example") == 7UL, "");
+    static_assert(strlen_c("another\0example") == 7UL, "");
+
+  }
+
+  namespace test_rvalue_references
+  {
+
+    template < int N >
+    struct answer
+    {
+      static constexpr int value = N;
+    };
+
+    answer<1> f(int&)       { return answer<1>(); }
+    answer<2> f(const int&) { return answer<2>(); }
+    answer<3> f(int&&)      { return answer<3>(); }
+
+    void
+    test()
+    {
+      int i = 0;
+      const int c = 0;
+      static_assert(decltype(f(i))::value == 1, "");
+      static_assert(decltype(f(c))::value == 2, "");
+      static_assert(decltype(f(0))::value == 3, "");
+    }
+
+  }
+
+  namespace test_uniform_initialization
+  {
+
+    struct test
+    {
+      static const int zero {};
+      static const int one {1};
+    };
+
+    static_assert(test::zero == 0, "");
+    static_assert(test::one == 1, "");
+
+  }
+
+  namespace test_lambdas
+  {
+
+    void
+    test1()
+    {
+      auto lambda1 = [](){};
+      auto lambda2 = lambda1;
+      lambda1();
+      lambda2();
+    }
+
+    int
+    test2()
+    {
+      auto a = [](int i, int j){ return i + j; }(1, 2);
+      auto b = []() -> int { return '0'; }();
+      auto c = [=](){ return a + b; }();
+      auto d = [&](){ return c; }();
+      auto e = [a, &b](int x) mutable {
+        const auto identity = [](int y){ return y; };
+        for (auto i = 0; i < a; ++i)
+          a += b--;
+        return x + identity(a + b);
+      }(0);
+      return a + b + c + d + e;
+    }
+
+    int
+    test3()
+    {
+      const auto nullary = [](){ return 0; };
+      const auto unary = [](int x){ return x; };
+      using nullary_t = decltype(nullary);
+      using unary_t = decltype(unary);
+      const auto higher1st = [](nullary_t f){ return f(); };
+      const auto higher2nd = [unary](nullary_t f1){
+        return [unary, f1](unary_t f2){ return f2(unary(f1())); };
+      };
+      return higher1st(nullary) + higher2nd(nullary)(unary);
+    }
+
+  }
+
+  namespace test_variadic_templates
+  {
+
+    template <int...>
+    struct sum;
+
+    template <int N0, int... N1toN>
+    struct sum<N0, N1toN...>
+    {
+      static constexpr auto value = N0 + sum<N1toN...>::value;
+    };
+
+    template <>
+    struct sum<>
+    {
+      static constexpr auto value = 0;
+    };
+
+    static_assert(sum<>::value == 0, "");
+    static_assert(sum<1>::value == 1, "");
+    static_assert(sum<23>::value == 23, "");
+    static_assert(sum<1, 2>::value == 3, "");
+    static_assert(sum<5, 5, 11>::value == 21, "");
+    static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
+
+  }
+
+  // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
+  // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
+  // because of this.
+  namespace test_template_alias_sfinae
+  {
+
+    struct foo {};
+
+    template<typename T>
+    using member = typename T::member_type;
+
+    template<typename T>
+    void func(...) {}
+
+    template<typename T>
+    void func(member<T>*) {}
+
+    void test();
+
+    void test() { func<foo>(0); }
+
+  }
+
+}  // namespace cxx11
+
+#endif  // __cplusplus >= 201103L
+
+
+
+
+// If the compiler admits that it is not ready for C++14, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201402L
+
+#error "This is not a C++14 compiler"
+
+#else
+
+namespace cxx14
+{
+
+  namespace test_polymorphic_lambdas
+  {
+
+    int
+    test()
+    {
+      const auto lambda = [](auto&&... args){
+        const auto istiny = [](auto x){
+          return (sizeof(x) == 1UL) ? 1 : 0;
+        };
+        const int aretiny[] = { istiny(args)... };
+        return aretiny[0];
+      };
+      return lambda(1, 1L, 1.0f, '1');
+    }
+
+  }
+
+  namespace test_binary_literals
+  {
+
+    constexpr auto ivii = 0b0000000000101010;
+    static_assert(ivii == 42, "wrong value");
+
+  }
+
+  namespace test_generalized_constexpr
+  {
+
+    template < typename CharT >
+    constexpr unsigned long
+    strlen_c(const CharT *const s) noexcept
+    {
+      auto length = 0UL;
+      for (auto p = s; *p; ++p)
+        ++length;
+      return length;
+    }
+
+    static_assert(strlen_c("") == 0UL, "");
+    static_assert(strlen_c("x") == 1UL, "");
+    static_assert(strlen_c("test") == 4UL, "");
+    static_assert(strlen_c("another\0test") == 7UL, "");
+
+  }
+
+  namespace test_lambda_init_capture
+  {
+
+    int
+    test()
+    {
+      auto x = 0;
+      const auto lambda1 = [a = x](int b){ return a + b; };
+      const auto lambda2 = [a = lambda1(x)](){ return a; };
+      return lambda2();
+    }
+
+  }
+
+  namespace test_digit_separators
+  {
+
+    constexpr auto ten_million = 100'000'000;
+    static_assert(ten_million == 100000000, "");
+
+  }
+
+  namespace test_return_type_deduction
+  {
+
+    auto f(int& x) { return x; }
+    decltype(auto) g(int& x) { return x; }
+
+    template < typename T1, typename T2 >
+    struct is_same
+    {
+      static constexpr auto value = false;
+    };
+
+    template < typename T >
+    struct is_same<T, T>
+    {
+      static constexpr auto value = true;
+    };
+
+    int
+    test()
+    {
+      auto x = 0;
+      static_assert(is_same<int, decltype(f(x))>::value, "");
+      static_assert(is_same<int&, decltype(g(x))>::value, "");
+      return x;
+    }
+
+  }
+
+}  // namespace cxx14
+
+#endif  // __cplusplus >= 201402L
+
+
+
+
+// If the compiler admits that it is not ready for C++17, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201703L
+
+#error "This is not a C++17 compiler"
+
+#else
+
+#include <initializer_list>
+#include <utility>
+#include <type_traits>
+
+namespace cxx17
+{
+
+  namespace test_constexpr_lambdas
+  {
+
+    constexpr int foo = [](){return 42;}();
+
+  }
+
+  namespace test::nested_namespace::definitions
+  {
+
+  }
+
+  namespace test_fold_expression
+  {
+
+    template<typename... Args>
+    int multiply(Args... args)
+    {
+      return (args * ... * 1);
+    }
+
+    template<typename... Args>
+    bool all(Args... args)
+    {
+      return (args && ...);
+    }
+
+  }
+
+  namespace test_extended_static_assert
+  {
+
+    static_assert (true);
+
+  }
+
+  namespace test_auto_brace_init_list
+  {
+
+    auto foo = {5};
+    auto bar {5};
+
+    static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
+    static_assert(std::is_same<int, decltype(bar)>::value);
+  }
+
+  namespace test_typename_in_template_template_parameter
+  {
+
+    template<template<typename> typename X> struct D;
+
+  }
+
+  namespace test_fallthrough_nodiscard_maybe_unused_attributes
+  {
+
+    int f1()
+    {
+      return 42;
+    }
+
+    [[nodiscard]] int f2()
+    {
+      [[maybe_unused]] auto unused = f1();
+
+      switch (f1())
+      {
+      case 17:
+        f1();
+        [[fallthrough]];
+      case 42:
+        f1();
+      }
+      return f1();
+    }
+
+  }
+
+  namespace test_extended_aggregate_initialization
+  {
+
+    struct base1
+    {
+      int b1, b2 = 42;
+    };
+
+    struct base2
+    {
+      base2() {
+        b3 = 42;
+      }
+      int b3;
+    };
+
+    struct derived : base1, base2
+    {
+        int d;
+    };
+
+    derived d1 {{1, 2}, {}, 4};  // full initialization
+    derived d2 {{}, {}, 4};      // value-initialized bases
+
+  }
+
+  namespace test_general_range_based_for_loop
+  {
+
+    struct iter
+    {
+      int i;
+
+      int& operator* ()
+      {
+        return i;
+      }
+
+      const int& operator* () const
+      {
+        return i;
+      }
+
+      iter& operator++()
+      {
+        ++i;
+        return *this;
+      }
+    };
+
+    struct sentinel
+    {
+      int i;
+    };
+
+    bool operator== (const iter& i, const sentinel& s)
+    {
+      return i.i == s.i;
+    }
+
+    bool operator!= (const iter& i, const sentinel& s)
+    {
+      return !(i == s);
+    }
+
+    struct range
+    {
+      iter begin() const
+      {
+        return {0};
+      }
+
+      sentinel end() const
+      {
+        return {5};
+      }
+    };
+
+    void f()
+    {
+      range r {};
+
+      for (auto i : r)
+      {
+        [[maybe_unused]] auto v = i;
+      }
+    }
+
+  }
+
+  namespace test_lambda_capture_asterisk_this_by_value
+  {
+
+    struct t
+    {
+      int i;
+      int foo()
+      {
+        return [*this]()
+        {
+          return i;
+        }();
+      }
+    };
+
+  }
+
+  namespace test_enum_class_construction
+  {
+
+    enum class byte : unsigned char
+    {};
+
+    byte foo {42};
+
+  }
+
+  namespace test_constexpr_if
+  {
+
+    template <bool cond>
+    int f ()
+    {
+      if constexpr(cond)
+      {
+        return 13;
+      }
+      else
+      {
+        return 42;
+      }
+    }
+
+  }
+
+  namespace test_selection_statement_with_initializer
+  {
+
+    int f()
+    {
+      return 13;
+    }
+
+    int f2()
+    {
+      if (auto i = f(); i > 0)
+      {
+        return 3;
+      }
+
+      switch (auto i = f(); i + 4)
+      {
+      case 17:
+        return 2;
+
+      default:
+        return 1;
+      }
+    }
+
+  }
+
+  namespace test_template_argument_deduction_for_class_templates
+  {
+
+    template <typename T1, typename T2>
+    struct pair
+    {
+      pair (T1 p1, T2 p2)
+        : m1 {p1},
+          m2 {p2}
+      {}
+
+      T1 m1;
+      T2 m2;
+    };
+
+    void f()
+    {
+      [[maybe_unused]] auto p = pair{13, 42u};
+    }
+
+  }
+
+  namespace test_non_type_auto_template_parameters
+  {
+
+    template <auto n>
+    struct B
+    {};
+
+    B<5> b1;
+    B<'a'> b2;
+
+  }
+
+  namespace test_structured_bindings
+  {
+
+    int arr[2] = { 1, 2 };
+    std::pair<int, int> pr = { 1, 2 };
+
+    auto f1() -> int(&)[2]
+    {
+      return arr;
+    }
+
+    auto f2() -> std::pair<int, int>&
+    {
+      return pr;
+    }
+
+    struct S
+    {
+      int x1 : 2;
+      volatile double y1;
+    };
+
+    S f3()
+    {
+      return {};
+    }
+
+    auto [ x1, y1 ] = f1();
+    auto& [ xr1, yr1 ] = f1();
+    auto [ x2, y2 ] = f2();
+    auto& [ xr2, yr2 ] = f2();
+    const auto [ x3, y3 ] = f3();
+
+  }
+
+  namespace test_exception_spec_type_system
+  {
+
+    struct Good {};
+    struct Bad {};
+
+    void g1() noexcept;
+    void g2();
+
+    template<typename T>
+    Bad
+    f(T*, T*);
+
+    template<typename T1, typename T2>
+    Good
+    f(T1*, T2*);
+
+    static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
+
+  }
+
+  namespace test_inline_variables
+  {
+
+    template<class T> void f(T)
+    {}
+
+    template<class T> inline T g(T)
+    {
+      return T{};
+    }
+
+    template<> inline void f<>(int)
+    {}
+
+    template<> int g<>(int)
+    {
+      return 5;
+    }
+
+  }
+
+}  // namespace cxx17
+
+#endif  // __cplusplus < 201703L
+
+
+
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 202002L
+
+#error "This is not a C++20 compiler"
+
+#else
+
+#include <version>
+
+namespace cxx20
+{
+
+// As C++20 supports feature test macros in the standard, there is no
+// immediate need to actually test for feature availability on the
+// Autoconf side.
+
+}  // namespace cxx20
+
+#endif  // __cplusplus < 202002L
+
+
 
 _ACEOF
-if ac_fn_cxx_try_compile "$LINENO"; then :
+if ac_fn_cxx_try_compile "$LINENO"
+then :
   eval $cachevar=yes
-else
+else $as_nop
   eval $cachevar=no
 fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-         CXXFLAGS="$ac_save_CXXFLAGS"
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+           CXX="$ac_save_CXX"
 fi
 eval ac_res=\$$cachevar
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-      if eval test x\$$cachevar = xyes; then
-        CXXFLAGS="$CXXFLAGS $switch"
-        CXX11FLAGS=$switch
-        ac_success=yes
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+        if eval test x\$$cachevar = xyes; then
+          CXX="$CXX $switch"
+          if test -n "$CXXCPP" ; then
+            CXXCPP="$CXXCPP $switch"
+          fi
+          ac_success=yes
+          break
+        fi
+      done
+      if test x$ac_success = xyes; then
         break
       fi
     done
   fi
-
-  if test x$ac_success = xno; then
-    if test xnostop != xnostop; then
-      as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5
-    fi
-  else
-    HAVE_CXX11_COMPILER=yes
-  fi
-
-  CXXFLAGS=$CXXFLAGS_SAVED
   ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-  if test x"$CXX11FLAGS" != x; then
-    PLATCXXFLAGS="$CXX11FLAGS $PLATCXXFLAGS"
+  if test x$ax_cxx_compile_cxx20_required = xtrue; then
+    if test x$ac_success = xno; then
+      as_fn_error $? "*** A compiler with support for C++20 language features is required." "$LINENO" 5
+    fi
   fi
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for C++11 enabled compiler" >&5
-$as_echo_n "checking for C++11 enabled compiler... " >&6; }
-  if test x"$HAVE_CXX11_COMPILER" = x; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  if test x$ac_success = xno; then
+    HAVE_CXX20=0
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No compiler with C++20 support was found" >&5
+printf "%s\n" "$as_me: No compiler with C++20 support was found" >&6;}
   else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_CXX11_COMPILER" >&5
-$as_echo "$HAVE_CXX11_COMPILER" >&6; }
+    HAVE_CXX20=1
+
+printf "%s\n" "#define HAVE_CXX20 1" >>confdefs.h
+
   fi
+
+
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C++11 to C++20 testing is enabled" >&5
+printf %s "checking whether C++11 to C++20 testing is enabled... " >&6; }
+  if test "$HAVE_CXX20" = "1"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+    PLATCXXFLAGS="$CXXCPP $PLATCXXFLAGS"
+    HAVE_CXX17="1"
+    HAVE_CXX14="1"
+    HAVE_CXX11="1"
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+
+    # Test for c++17
+    CXXCPP=" "
+      ax_cxx_compile_alternatives="17 1z"    ax_cxx_compile_cxx17_required=false
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+  ac_success=no
+
+
+
+
+
+    if test x$ac_success = xno; then
+                for alternative in ${ax_cxx_compile_alternatives}; do
+      for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
+        cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx17_$switch" | $as_tr_sh`
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++17 features with $switch" >&5
+printf %s "checking whether $CXX supports C++17 features with $switch... " >&6; }
+if eval test \${$cachevar+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_save_CXX="$CXX"
+           CXX="$CXX $switch"
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+// If the compiler admits that it is not ready for C++11, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201103L
+
+#error "This is not a C++11 compiler"
+
+#else
+
+namespace cxx11
+{
+
+  namespace test_static_assert
+  {
+
+    template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+  }
+
+  namespace test_final_override
+  {
+
+    struct Base
+    {
+      virtual ~Base() {}
+      virtual void f() {}
+    };
+
+    struct Derived : public Base
+    {
+      virtual ~Derived() override {}
+      virtual void f() override {}
+    };
+
+  }
+
+  namespace test_double_right_angle_brackets
+  {
+
+    template < typename T >
+    struct check {};
+
+    typedef check<void> single_type;
+    typedef check<check<void>> double_type;
+    typedef check<check<check<void>>> triple_type;
+    typedef check<check<check<check<void>>>> quadruple_type;
+
+  }
+
+  namespace test_decltype
+  {
+
+    int
+    f()
+    {
+      int a = 1;
+      decltype(a) b = 2;
+      return a + b;
+    }
+
+  }
+
+  namespace test_type_deduction
+  {
+
+    template < typename T1, typename T2 >
+    struct is_same
+    {
+      static const bool value = false;
+    };
+
+    template < typename T >
+    struct is_same<T, T>
+    {
+      static const bool value = true;
+    };
+
+    template < typename T1, typename T2 >
+    auto
+    add(T1 a1, T2 a2) -> decltype(a1 + a2)
+    {
+      return a1 + a2;
+    }
+
+    int
+    test(const int c, volatile int v)
+    {
+      static_assert(is_same<int, decltype(0)>::value == true, "");
+      static_assert(is_same<int, decltype(c)>::value == false, "");
+      static_assert(is_same<int, decltype(v)>::value == false, "");
+      auto ac = c;
+      auto av = v;
+      auto sumi = ac + av + 'x';
+      auto sumf = ac + av + 1.0;
+      static_assert(is_same<int, decltype(ac)>::value == true, "");
+      static_assert(is_same<int, decltype(av)>::value == true, "");
+      static_assert(is_same<int, decltype(sumi)>::value == true, "");
+      static_assert(is_same<int, decltype(sumf)>::value == false, "");
+      static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
+      return (sumf > 0.0) ? sumi : add(c, v);
+    }
+
+  }
+
+  namespace test_noexcept
+  {
+
+    int f() { return 0; }
+    int g() noexcept { return 0; }
+
+    static_assert(noexcept(f()) == false, "");
+    static_assert(noexcept(g()) == true, "");
+
+  }
+
+  namespace test_constexpr
+  {
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
+    {
+      return *s ? strlen_c_r(s + 1, acc + 1) : acc;
+    }
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c(const CharT *const s) noexcept
+    {
+      return strlen_c_r(s, 0UL);
+    }
+
+    static_assert(strlen_c("") == 0UL, "");
+    static_assert(strlen_c("1") == 1UL, "");
+    static_assert(strlen_c("example") == 7UL, "");
+    static_assert(strlen_c("another\0example") == 7UL, "");
+
+  }
+
+  namespace test_rvalue_references
+  {
+
+    template < int N >
+    struct answer
+    {
+      static constexpr int value = N;
+    };
+
+    answer<1> f(int&)       { return answer<1>(); }
+    answer<2> f(const int&) { return answer<2>(); }
+    answer<3> f(int&&)      { return answer<3>(); }
+
+    void
+    test()
+    {
+      int i = 0;
+      const int c = 0;
+      static_assert(decltype(f(i))::value == 1, "");
+      static_assert(decltype(f(c))::value == 2, "");
+      static_assert(decltype(f(0))::value == 3, "");
+    }
+
+  }
+
+  namespace test_uniform_initialization
+  {
+
+    struct test
+    {
+      static const int zero {};
+      static const int one {1};
+    };
+
+    static_assert(test::zero == 0, "");
+    static_assert(test::one == 1, "");
+
+  }
+
+  namespace test_lambdas
+  {
+
+    void
+    test1()
+    {
+      auto lambda1 = [](){};
+      auto lambda2 = lambda1;
+      lambda1();
+      lambda2();
+    }
+
+    int
+    test2()
+    {
+      auto a = [](int i, int j){ return i + j; }(1, 2);
+      auto b = []() -> int { return '0'; }();
+      auto c = [=](){ return a + b; }();
+      auto d = [&](){ return c; }();
+      auto e = [a, &b](int x) mutable {
+        const auto identity = [](int y){ return y; };
+        for (auto i = 0; i < a; ++i)
+          a += b--;
+        return x + identity(a + b);
+      }(0);
+      return a + b + c + d + e;
+    }
+
+    int
+    test3()
+    {
+      const auto nullary = [](){ return 0; };
+      const auto unary = [](int x){ return x; };
+      using nullary_t = decltype(nullary);
+      using unary_t = decltype(unary);
+      const auto higher1st = [](nullary_t f){ return f(); };
+      const auto higher2nd = [unary](nullary_t f1){
+        return [unary, f1](unary_t f2){ return f2(unary(f1())); };
+      };
+      return higher1st(nullary) + higher2nd(nullary)(unary);
+    }
+
+  }
+
+  namespace test_variadic_templates
+  {
+
+    template <int...>
+    struct sum;
+
+    template <int N0, int... N1toN>
+    struct sum<N0, N1toN...>
+    {
+      static constexpr auto value = N0 + sum<N1toN...>::value;
+    };
+
+    template <>
+    struct sum<>
+    {
+      static constexpr auto value = 0;
+    };
+
+    static_assert(sum<>::value == 0, "");
+    static_assert(sum<1>::value == 1, "");
+    static_assert(sum<23>::value == 23, "");
+    static_assert(sum<1, 2>::value == 3, "");
+    static_assert(sum<5, 5, 11>::value == 21, "");
+    static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
+
+  }
+
+  // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
+  // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
+  // because of this.
+  namespace test_template_alias_sfinae
+  {
+
+    struct foo {};
+
+    template<typename T>
+    using member = typename T::member_type;
+
+    template<typename T>
+    void func(...) {}
+
+    template<typename T>
+    void func(member<T>*) {}
+
+    void test();
+
+    void test() { func<foo>(0); }
+
+  }
+
+}  // namespace cxx11
+
+#endif  // __cplusplus >= 201103L
+
+
+
+
+// If the compiler admits that it is not ready for C++14, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201402L
+
+#error "This is not a C++14 compiler"
+
+#else
+
+namespace cxx14
+{
+
+  namespace test_polymorphic_lambdas
+  {
+
+    int
+    test()
+    {
+      const auto lambda = [](auto&&... args){
+        const auto istiny = [](auto x){
+          return (sizeof(x) == 1UL) ? 1 : 0;
+        };
+        const int aretiny[] = { istiny(args)... };
+        return aretiny[0];
+      };
+      return lambda(1, 1L, 1.0f, '1');
+    }
+
+  }
+
+  namespace test_binary_literals
+  {
+
+    constexpr auto ivii = 0b0000000000101010;
+    static_assert(ivii == 42, "wrong value");
+
+  }
+
+  namespace test_generalized_constexpr
+  {
+
+    template < typename CharT >
+    constexpr unsigned long
+    strlen_c(const CharT *const s) noexcept
+    {
+      auto length = 0UL;
+      for (auto p = s; *p; ++p)
+        ++length;
+      return length;
+    }
+
+    static_assert(strlen_c("") == 0UL, "");
+    static_assert(strlen_c("x") == 1UL, "");
+    static_assert(strlen_c("test") == 4UL, "");
+    static_assert(strlen_c("another\0test") == 7UL, "");
+
+  }
+
+  namespace test_lambda_init_capture
+  {
+
+    int
+    test()
+    {
+      auto x = 0;
+      const auto lambda1 = [a = x](int b){ return a + b; };
+      const auto lambda2 = [a = lambda1(x)](){ return a; };
+      return lambda2();
+    }
+
+  }
+
+  namespace test_digit_separators
+  {
+
+    constexpr auto ten_million = 100'000'000;
+    static_assert(ten_million == 100000000, "");
+
+  }
+
+  namespace test_return_type_deduction
+  {
+
+    auto f(int& x) { return x; }
+    decltype(auto) g(int& x) { return x; }
+
+    template < typename T1, typename T2 >
+    struct is_same
+    {
+      static constexpr auto value = false;
+    };
+
+    template < typename T >
+    struct is_same<T, T>
+    {
+      static constexpr auto value = true;
+    };
+
+    int
+    test()
+    {
+      auto x = 0;
+      static_assert(is_same<int, decltype(f(x))>::value, "");
+      static_assert(is_same<int&, decltype(g(x))>::value, "");
+      return x;
+    }
+
+  }
+
+}  // namespace cxx14
+
+#endif  // __cplusplus >= 201402L
+
+
+
+
+// If the compiler admits that it is not ready for C++17, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201703L
+
+#error "This is not a C++17 compiler"
+
+#else
+
+#include <initializer_list>
+#include <utility>
+#include <type_traits>
+
+namespace cxx17
+{
+
+  namespace test_constexpr_lambdas
+  {
+
+    constexpr int foo = [](){return 42;}();
+
+  }
+
+  namespace test::nested_namespace::definitions
+  {
+
+  }
+
+  namespace test_fold_expression
+  {
+
+    template<typename... Args>
+    int multiply(Args... args)
+    {
+      return (args * ... * 1);
+    }
+
+    template<typename... Args>
+    bool all(Args... args)
+    {
+      return (args && ...);
+    }
+
+  }
+
+  namespace test_extended_static_assert
+  {
+
+    static_assert (true);
+
+  }
+
+  namespace test_auto_brace_init_list
+  {
+
+    auto foo = {5};
+    auto bar {5};
+
+    static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
+    static_assert(std::is_same<int, decltype(bar)>::value);
+  }
+
+  namespace test_typename_in_template_template_parameter
+  {
+
+    template<template<typename> typename X> struct D;
+
+  }
+
+  namespace test_fallthrough_nodiscard_maybe_unused_attributes
+  {
+
+    int f1()
+    {
+      return 42;
+    }
+
+    [[nodiscard]] int f2()
+    {
+      [[maybe_unused]] auto unused = f1();
+
+      switch (f1())
+      {
+      case 17:
+        f1();
+        [[fallthrough]];
+      case 42:
+        f1();
+      }
+      return f1();
+    }
+
+  }
+
+  namespace test_extended_aggregate_initialization
+  {
+
+    struct base1
+    {
+      int b1, b2 = 42;
+    };
+
+    struct base2
+    {
+      base2() {
+        b3 = 42;
+      }
+      int b3;
+    };
+
+    struct derived : base1, base2
+    {
+        int d;
+    };
+
+    derived d1 {{1, 2}, {}, 4};  // full initialization
+    derived d2 {{}, {}, 4};      // value-initialized bases
+
+  }
+
+  namespace test_general_range_based_for_loop
+  {
+
+    struct iter
+    {
+      int i;
+
+      int& operator* ()
+      {
+        return i;
+      }
+
+      const int& operator* () const
+      {
+        return i;
+      }
+
+      iter& operator++()
+      {
+        ++i;
+        return *this;
+      }
+    };
+
+    struct sentinel
+    {
+      int i;
+    };
+
+    bool operator== (const iter& i, const sentinel& s)
+    {
+      return i.i == s.i;
+    }
+
+    bool operator!= (const iter& i, const sentinel& s)
+    {
+      return !(i == s);
+    }
+
+    struct range
+    {
+      iter begin() const
+      {
+        return {0};
+      }
+
+      sentinel end() const
+      {
+        return {5};
+      }
+    };
+
+    void f()
+    {
+      range r {};
+
+      for (auto i : r)
+      {
+        [[maybe_unused]] auto v = i;
+      }
+    }
+
+  }
+
+  namespace test_lambda_capture_asterisk_this_by_value
+  {
+
+    struct t
+    {
+      int i;
+      int foo()
+      {
+        return [*this]()
+        {
+          return i;
+        }();
+      }
+    };
+
+  }
+
+  namespace test_enum_class_construction
+  {
+
+    enum class byte : unsigned char
+    {};
+
+    byte foo {42};
+
+  }
+
+  namespace test_constexpr_if
+  {
+
+    template <bool cond>
+    int f ()
+    {
+      if constexpr(cond)
+      {
+        return 13;
+      }
+      else
+      {
+        return 42;
+      }
+    }
+
+  }
+
+  namespace test_selection_statement_with_initializer
+  {
+
+    int f()
+    {
+      return 13;
+    }
+
+    int f2()
+    {
+      if (auto i = f(); i > 0)
+      {
+        return 3;
+      }
+
+      switch (auto i = f(); i + 4)
+      {
+      case 17:
+        return 2;
+
+      default:
+        return 1;
+      }
+    }
+
+  }
+
+  namespace test_template_argument_deduction_for_class_templates
+  {
+
+    template <typename T1, typename T2>
+    struct pair
+    {
+      pair (T1 p1, T2 p2)
+        : m1 {p1},
+          m2 {p2}
+      {}
+
+      T1 m1;
+      T2 m2;
+    };
+
+    void f()
+    {
+      [[maybe_unused]] auto p = pair{13, 42u};
+    }
+
+  }
+
+  namespace test_non_type_auto_template_parameters
+  {
+
+    template <auto n>
+    struct B
+    {};
+
+    B<5> b1;
+    B<'a'> b2;
+
+  }
+
+  namespace test_structured_bindings
+  {
+
+    int arr[2] = { 1, 2 };
+    std::pair<int, int> pr = { 1, 2 };
+
+    auto f1() -> int(&)[2]
+    {
+      return arr;
+    }
+
+    auto f2() -> std::pair<int, int>&
+    {
+      return pr;
+    }
+
+    struct S
+    {
+      int x1 : 2;
+      volatile double y1;
+    };
+
+    S f3()
+    {
+      return {};
+    }
+
+    auto [ x1, y1 ] = f1();
+    auto& [ xr1, yr1 ] = f1();
+    auto [ x2, y2 ] = f2();
+    auto& [ xr2, yr2 ] = f2();
+    const auto [ x3, y3 ] = f3();
+
+  }
+
+  namespace test_exception_spec_type_system
+  {
+
+    struct Good {};
+    struct Bad {};
+
+    void g1() noexcept;
+    void g2();
+
+    template<typename T>
+    Bad
+    f(T*, T*);
+
+    template<typename T1, typename T2>
+    Good
+    f(T1*, T2*);
+
+    static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
+
+  }
+
+  namespace test_inline_variables
+  {
+
+    template<class T> void f(T)
+    {}
+
+    template<class T> inline T g(T)
+    {
+      return T{};
+    }
+
+    template<> inline void f<>(int)
+    {}
+
+    template<> int g<>(int)
+    {
+      return 5;
+    }
+
+  }
+
+}  // namespace cxx17
+
+#endif  // __cplusplus < 201703L
+
+
+
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"
+then :
+  eval $cachevar=yes
+else $as_nop
+  eval $cachevar=no
 fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+           CXX="$ac_save_CXX"
+fi
+eval ac_res=\$$cachevar
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+        if eval test x\$$cachevar = xyes; then
+          CXX="$CXX $switch"
+          if test -n "$CXXCPP" ; then
+            CXXCPP="$CXXCPP $switch"
+          fi
+          ac_success=yes
+          break
+        fi
+      done
+      if test x$ac_success = xyes; then
+        break
+      fi
+    done
+  fi
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+  if test x$ax_cxx_compile_cxx17_required = xtrue; then
+    if test x$ac_success = xno; then
+      as_fn_error $? "*** A compiler with support for C++17 language features is required." "$LINENO" 5
+    fi
+  fi
+  if test x$ac_success = xno; then
+    HAVE_CXX17=0
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No compiler with C++17 support was found" >&5
+printf "%s\n" "$as_me: No compiler with C++17 support was found" >&6;}
+  else
+    HAVE_CXX17=1
+
+printf "%s\n" "#define HAVE_CXX17 1" >>confdefs.h
+
+  fi
+
+
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C++11 to C++17 testing is enabled" >&5
+printf %s "checking whether C++11 to C++17 testing is enabled... " >&6; }
+    if test "$HAVE_CXX17" = "1"; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+      PLATCXXFLAGS="$CXXCPP $PLATCXXFLAGS"
+      HAVE_CXX14="1"
+      HAVE_CXX11="1"
+    else
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+
+      # Test for c++14
+      CXXCPP=" "
+      CXX=$CXX_SAVED
+        ax_cxx_compile_alternatives="14 1y"    ax_cxx_compile_cxx14_required=false
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+  ac_success=no
+
+
+
+
+
+    if test x$ac_success = xno; then
+                for alternative in ${ax_cxx_compile_alternatives}; do
+      for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
+        cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx14_$switch" | $as_tr_sh`
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++14 features with $switch" >&5
+printf %s "checking whether $CXX supports C++14 features with $switch... " >&6; }
+if eval test \${$cachevar+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_save_CXX="$CXX"
+           CXX="$CXX $switch"
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+// If the compiler admits that it is not ready for C++11, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201103L
+
+#error "This is not a C++11 compiler"
+
+#else
+
+namespace cxx11
+{
+
+  namespace test_static_assert
+  {
+
+    template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+  }
+
+  namespace test_final_override
+  {
+
+    struct Base
+    {
+      virtual ~Base() {}
+      virtual void f() {}
+    };
+
+    struct Derived : public Base
+    {
+      virtual ~Derived() override {}
+      virtual void f() override {}
+    };
+
+  }
+
+  namespace test_double_right_angle_brackets
+  {
+
+    template < typename T >
+    struct check {};
+
+    typedef check<void> single_type;
+    typedef check<check<void>> double_type;
+    typedef check<check<check<void>>> triple_type;
+    typedef check<check<check<check<void>>>> quadruple_type;
+
+  }
+
+  namespace test_decltype
+  {
+
+    int
+    f()
+    {
+      int a = 1;
+      decltype(a) b = 2;
+      return a + b;
+    }
+
+  }
+
+  namespace test_type_deduction
+  {
+
+    template < typename T1, typename T2 >
+    struct is_same
+    {
+      static const bool value = false;
+    };
+
+    template < typename T >
+    struct is_same<T, T>
+    {
+      static const bool value = true;
+    };
+
+    template < typename T1, typename T2 >
+    auto
+    add(T1 a1, T2 a2) -> decltype(a1 + a2)
+    {
+      return a1 + a2;
+    }
+
+    int
+    test(const int c, volatile int v)
+    {
+      static_assert(is_same<int, decltype(0)>::value == true, "");
+      static_assert(is_same<int, decltype(c)>::value == false, "");
+      static_assert(is_same<int, decltype(v)>::value == false, "");
+      auto ac = c;
+      auto av = v;
+      auto sumi = ac + av + 'x';
+      auto sumf = ac + av + 1.0;
+      static_assert(is_same<int, decltype(ac)>::value == true, "");
+      static_assert(is_same<int, decltype(av)>::value == true, "");
+      static_assert(is_same<int, decltype(sumi)>::value == true, "");
+      static_assert(is_same<int, decltype(sumf)>::value == false, "");
+      static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
+      return (sumf > 0.0) ? sumi : add(c, v);
+    }
+
+  }
+
+  namespace test_noexcept
+  {
+
+    int f() { return 0; }
+    int g() noexcept { return 0; }
+
+    static_assert(noexcept(f()) == false, "");
+    static_assert(noexcept(g()) == true, "");
+
+  }
+
+  namespace test_constexpr
+  {
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
+    {
+      return *s ? strlen_c_r(s + 1, acc + 1) : acc;
+    }
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c(const CharT *const s) noexcept
+    {
+      return strlen_c_r(s, 0UL);
+    }
+
+    static_assert(strlen_c("") == 0UL, "");
+    static_assert(strlen_c("1") == 1UL, "");
+    static_assert(strlen_c("example") == 7UL, "");
+    static_assert(strlen_c("another\0example") == 7UL, "");
+
+  }
+
+  namespace test_rvalue_references
+  {
+
+    template < int N >
+    struct answer
+    {
+      static constexpr int value = N;
+    };
+
+    answer<1> f(int&)       { return answer<1>(); }
+    answer<2> f(const int&) { return answer<2>(); }
+    answer<3> f(int&&)      { return answer<3>(); }
+
+    void
+    test()
+    {
+      int i = 0;
+      const int c = 0;
+      static_assert(decltype(f(i))::value == 1, "");
+      static_assert(decltype(f(c))::value == 2, "");
+      static_assert(decltype(f(0))::value == 3, "");
+    }
+
+  }
+
+  namespace test_uniform_initialization
+  {
+
+    struct test
+    {
+      static const int zero {};
+      static const int one {1};
+    };
+
+    static_assert(test::zero == 0, "");
+    static_assert(test::one == 1, "");
+
+  }
+
+  namespace test_lambdas
+  {
+
+    void
+    test1()
+    {
+      auto lambda1 = [](){};
+      auto lambda2 = lambda1;
+      lambda1();
+      lambda2();
+    }
+
+    int
+    test2()
+    {
+      auto a = [](int i, int j){ return i + j; }(1, 2);
+      auto b = []() -> int { return '0'; }();
+      auto c = [=](){ return a + b; }();
+      auto d = [&](){ return c; }();
+      auto e = [a, &b](int x) mutable {
+        const auto identity = [](int y){ return y; };
+        for (auto i = 0; i < a; ++i)
+          a += b--;
+        return x + identity(a + b);
+      }(0);
+      return a + b + c + d + e;
+    }
+
+    int
+    test3()
+    {
+      const auto nullary = [](){ return 0; };
+      const auto unary = [](int x){ return x; };
+      using nullary_t = decltype(nullary);
+      using unary_t = decltype(unary);
+      const auto higher1st = [](nullary_t f){ return f(); };
+      const auto higher2nd = [unary](nullary_t f1){
+        return [unary, f1](unary_t f2){ return f2(unary(f1())); };
+      };
+      return higher1st(nullary) + higher2nd(nullary)(unary);
+    }
+
+  }
+
+  namespace test_variadic_templates
+  {
+
+    template <int...>
+    struct sum;
+
+    template <int N0, int... N1toN>
+    struct sum<N0, N1toN...>
+    {
+      static constexpr auto value = N0 + sum<N1toN...>::value;
+    };
+
+    template <>
+    struct sum<>
+    {
+      static constexpr auto value = 0;
+    };
+
+    static_assert(sum<>::value == 0, "");
+    static_assert(sum<1>::value == 1, "");
+    static_assert(sum<23>::value == 23, "");
+    static_assert(sum<1, 2>::value == 3, "");
+    static_assert(sum<5, 5, 11>::value == 21, "");
+    static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
+
+  }
+
+  // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
+  // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
+  // because of this.
+  namespace test_template_alias_sfinae
+  {
+
+    struct foo {};
+
+    template<typename T>
+    using member = typename T::member_type;
+
+    template<typename T>
+    void func(...) {}
+
+    template<typename T>
+    void func(member<T>*) {}
+
+    void test();
+
+    void test() { func<foo>(0); }
+
+  }
+
+}  // namespace cxx11
+
+#endif  // __cplusplus >= 201103L
+
+
+
+
+// If the compiler admits that it is not ready for C++14, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201402L
+
+#error "This is not a C++14 compiler"
+
+#else
+
+namespace cxx14
+{
+
+  namespace test_polymorphic_lambdas
+  {
+
+    int
+    test()
+    {
+      const auto lambda = [](auto&&... args){
+        const auto istiny = [](auto x){
+          return (sizeof(x) == 1UL) ? 1 : 0;
+        };
+        const int aretiny[] = { istiny(args)... };
+        return aretiny[0];
+      };
+      return lambda(1, 1L, 1.0f, '1');
+    }
+
+  }
+
+  namespace test_binary_literals
+  {
+
+    constexpr auto ivii = 0b0000000000101010;
+    static_assert(ivii == 42, "wrong value");
+
+  }
+
+  namespace test_generalized_constexpr
+  {
+
+    template < typename CharT >
+    constexpr unsigned long
+    strlen_c(const CharT *const s) noexcept
+    {
+      auto length = 0UL;
+      for (auto p = s; *p; ++p)
+        ++length;
+      return length;
+    }
+
+    static_assert(strlen_c("") == 0UL, "");
+    static_assert(strlen_c("x") == 1UL, "");
+    static_assert(strlen_c("test") == 4UL, "");
+    static_assert(strlen_c("another\0test") == 7UL, "");
+
+  }
+
+  namespace test_lambda_init_capture
+  {
+
+    int
+    test()
+    {
+      auto x = 0;
+      const auto lambda1 = [a = x](int b){ return a + b; };
+      const auto lambda2 = [a = lambda1(x)](){ return a; };
+      return lambda2();
+    }
+
+  }
+
+  namespace test_digit_separators
+  {
+
+    constexpr auto ten_million = 100'000'000;
+    static_assert(ten_million == 100000000, "");
+
+  }
+
+  namespace test_return_type_deduction
+  {
+
+    auto f(int& x) { return x; }
+    decltype(auto) g(int& x) { return x; }
+
+    template < typename T1, typename T2 >
+    struct is_same
+    {
+      static constexpr auto value = false;
+    };
+
+    template < typename T >
+    struct is_same<T, T>
+    {
+      static constexpr auto value = true;
+    };
+
+    int
+    test()
+    {
+      auto x = 0;
+      static_assert(is_same<int, decltype(f(x))>::value, "");
+      static_assert(is_same<int&, decltype(g(x))>::value, "");
+      return x;
+    }
+
+  }
+
+}  // namespace cxx14
+
+#endif  // __cplusplus >= 201402L
+
+
+
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"
+then :
+  eval $cachevar=yes
+else $as_nop
+  eval $cachevar=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+           CXX="$ac_save_CXX"
+fi
+eval ac_res=\$$cachevar
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+        if eval test x\$$cachevar = xyes; then
+          CXX="$CXX $switch"
+          if test -n "$CXXCPP" ; then
+            CXXCPP="$CXXCPP $switch"
+          fi
+          ac_success=yes
+          break
+        fi
+      done
+      if test x$ac_success = xyes; then
+        break
+      fi
+    done
+  fi
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+  if test x$ax_cxx_compile_cxx14_required = xtrue; then
+    if test x$ac_success = xno; then
+      as_fn_error $? "*** A compiler with support for C++14 language features is required." "$LINENO" 5
+    fi
+  fi
+  if test x$ac_success = xno; then
+    HAVE_CXX14=0
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No compiler with C++14 support was found" >&5
+printf "%s\n" "$as_me: No compiler with C++14 support was found" >&6;}
+  else
+    HAVE_CXX14=1
+
+printf "%s\n" "#define HAVE_CXX14 1" >>confdefs.h
+
+  fi
+
+
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C++11 to C++14 testing is enabled" >&5
+printf %s "checking whether C++11 to C++14 testing is enabled... " >&6; }
+      if test "$HAVE_CXX14" = "1"; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+        PLATCXXFLAGS="$CXXCPP $PLATCXXFLAGS"
+        HAVE_CXX11="1"
+      else
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+
+        # Test for c++11
+        CXXCPP=" "
+        CXX=$CXX_SAVED
+          ax_cxx_compile_alternatives="11 0x"    ax_cxx_compile_cxx11_required=false
+  ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+  ac_success=no
+
+
+
+
+
+    if test x$ac_success = xno; then
+                for alternative in ${ax_cxx_compile_alternatives}; do
+      for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
+        cachevar=`printf "%s\n" "ax_cv_cxx_compile_cxx11_$switch" | $as_tr_sh`
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether $CXX supports C++11 features with $switch" >&5
+printf %s "checking whether $CXX supports C++11 features with $switch... " >&6; }
+if eval test \${$cachevar+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_save_CXX="$CXX"
+           CXX="$CXX $switch"
+           cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+// If the compiler admits that it is not ready for C++11, why torture it?
+// Hopefully, this will speed up the test.
+
+#ifndef __cplusplus
+
+#error "This is not a C++ compiler"
+
+#elif __cplusplus < 201103L
+
+#error "This is not a C++11 compiler"
+
+#else
+
+namespace cxx11
+{
+
+  namespace test_static_assert
+  {
+
+    template <typename T>
+    struct check
+    {
+      static_assert(sizeof(int) <= sizeof(T), "not big enough");
+    };
+
+  }
+
+  namespace test_final_override
+  {
+
+    struct Base
+    {
+      virtual ~Base() {}
+      virtual void f() {}
+    };
+
+    struct Derived : public Base
+    {
+      virtual ~Derived() override {}
+      virtual void f() override {}
+    };
+
+  }
+
+  namespace test_double_right_angle_brackets
+  {
+
+    template < typename T >
+    struct check {};
+
+    typedef check<void> single_type;
+    typedef check<check<void>> double_type;
+    typedef check<check<check<void>>> triple_type;
+    typedef check<check<check<check<void>>>> quadruple_type;
+
+  }
+
+  namespace test_decltype
+  {
+
+    int
+    f()
+    {
+      int a = 1;
+      decltype(a) b = 2;
+      return a + b;
+    }
+
+  }
+
+  namespace test_type_deduction
+  {
+
+    template < typename T1, typename T2 >
+    struct is_same
+    {
+      static const bool value = false;
+    };
+
+    template < typename T >
+    struct is_same<T, T>
+    {
+      static const bool value = true;
+    };
+
+    template < typename T1, typename T2 >
+    auto
+    add(T1 a1, T2 a2) -> decltype(a1 + a2)
+    {
+      return a1 + a2;
+    }
+
+    int
+    test(const int c, volatile int v)
+    {
+      static_assert(is_same<int, decltype(0)>::value == true, "");
+      static_assert(is_same<int, decltype(c)>::value == false, "");
+      static_assert(is_same<int, decltype(v)>::value == false, "");
+      auto ac = c;
+      auto av = v;
+      auto sumi = ac + av + 'x';
+      auto sumf = ac + av + 1.0;
+      static_assert(is_same<int, decltype(ac)>::value == true, "");
+      static_assert(is_same<int, decltype(av)>::value == true, "");
+      static_assert(is_same<int, decltype(sumi)>::value == true, "");
+      static_assert(is_same<int, decltype(sumf)>::value == false, "");
+      static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
+      return (sumf > 0.0) ? sumi : add(c, v);
+    }
+
+  }
+
+  namespace test_noexcept
+  {
+
+    int f() { return 0; }
+    int g() noexcept { return 0; }
+
+    static_assert(noexcept(f()) == false, "");
+    static_assert(noexcept(g()) == true, "");
+
+  }
+
+  namespace test_constexpr
+  {
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
+    {
+      return *s ? strlen_c_r(s + 1, acc + 1) : acc;
+    }
+
+    template < typename CharT >
+    unsigned long constexpr
+    strlen_c(const CharT *const s) noexcept
+    {
+      return strlen_c_r(s, 0UL);
+    }
+
+    static_assert(strlen_c("") == 0UL, "");
+    static_assert(strlen_c("1") == 1UL, "");
+    static_assert(strlen_c("example") == 7UL, "");
+    static_assert(strlen_c("another\0example") == 7UL, "");
+
+  }
+
+  namespace test_rvalue_references
+  {
+
+    template < int N >
+    struct answer
+    {
+      static constexpr int value = N;
+    };
+
+    answer<1> f(int&)       { return answer<1>(); }
+    answer<2> f(const int&) { return answer<2>(); }
+    answer<3> f(int&&)      { return answer<3>(); }
+
+    void
+    test()
+    {
+      int i = 0;
+      const int c = 0;
+      static_assert(decltype(f(i))::value == 1, "");
+      static_assert(decltype(f(c))::value == 2, "");
+      static_assert(decltype(f(0))::value == 3, "");
+    }
+
+  }
+
+  namespace test_uniform_initialization
+  {
+
+    struct test
+    {
+      static const int zero {};
+      static const int one {1};
+    };
+
+    static_assert(test::zero == 0, "");
+    static_assert(test::one == 1, "");
+
+  }
+
+  namespace test_lambdas
+  {
+
+    void
+    test1()
+    {
+      auto lambda1 = [](){};
+      auto lambda2 = lambda1;
+      lambda1();
+      lambda2();
+    }
+
+    int
+    test2()
+    {
+      auto a = [](int i, int j){ return i + j; }(1, 2);
+      auto b = []() -> int { return '0'; }();
+      auto c = [=](){ return a + b; }();
+      auto d = [&](){ return c; }();
+      auto e = [a, &b](int x) mutable {
+        const auto identity = [](int y){ return y; };
+        for (auto i = 0; i < a; ++i)
+          a += b--;
+        return x + identity(a + b);
+      }(0);
+      return a + b + c + d + e;
+    }
+
+    int
+    test3()
+    {
+      const auto nullary = [](){ return 0; };
+      const auto unary = [](int x){ return x; };
+      using nullary_t = decltype(nullary);
+      using unary_t = decltype(unary);
+      const auto higher1st = [](nullary_t f){ return f(); };
+      const auto higher2nd = [unary](nullary_t f1){
+        return [unary, f1](unary_t f2){ return f2(unary(f1())); };
+      };
+      return higher1st(nullary) + higher2nd(nullary)(unary);
+    }
+
+  }
+
+  namespace test_variadic_templates
+  {
+
+    template <int...>
+    struct sum;
+
+    template <int N0, int... N1toN>
+    struct sum<N0, N1toN...>
+    {
+      static constexpr auto value = N0 + sum<N1toN...>::value;
+    };
+
+    template <>
+    struct sum<>
+    {
+      static constexpr auto value = 0;
+    };
+
+    static_assert(sum<>::value == 0, "");
+    static_assert(sum<1>::value == 1, "");
+    static_assert(sum<23>::value == 23, "");
+    static_assert(sum<1, 2>::value == 3, "");
+    static_assert(sum<5, 5, 11>::value == 21, "");
+    static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
+
+  }
+
+  // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
+  // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
+  // because of this.
+  namespace test_template_alias_sfinae
+  {
+
+    struct foo {};
+
+    template<typename T>
+    using member = typename T::member_type;
+
+    template<typename T>
+    void func(...) {}
+
+    template<typename T>
+    void func(member<T>*) {}
+
+    void test();
+
+    void test() { func<foo>(0); }
+
+  }
+
+}  // namespace cxx11
+
+#endif  // __cplusplus >= 201103L
+
+
+
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"
+then :
+  eval $cachevar=yes
+else $as_nop
+  eval $cachevar=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+           CXX="$ac_save_CXX"
+fi
+eval ac_res=\$$cachevar
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+        if eval test x\$$cachevar = xyes; then
+          CXX="$CXX $switch"
+          if test -n "$CXXCPP" ; then
+            CXXCPP="$CXXCPP $switch"
+          fi
+          ac_success=yes
+          break
+        fi
+      done
+      if test x$ac_success = xyes; then
+        break
+      fi
+    done
+  fi
+  ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+  if test x$ax_cxx_compile_cxx11_required = xtrue; then
+    if test x$ac_success = xno; then
+      as_fn_error $? "*** A compiler with support for C++11 language features is required." "$LINENO" 5
+    fi
+  fi
+  if test x$ac_success = xno; then
+    HAVE_CXX11=0
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: No compiler with C++11 support was found" >&5
+printf "%s\n" "$as_me: No compiler with C++11 support was found" >&6;}
+  else
+    HAVE_CXX11=1
+
+printf "%s\n" "#define HAVE_CXX11 1" >>confdefs.h
+
+  fi
+
+
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether C++11 testing is enabled" >&5
+printf %s "checking whether C++11 testing is enabled... " >&6; }
+        if test "$HAVE_CXX11" = "1"; then
+          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+          PLATCXXFLAGS="$CXXCPP $PLATCXXFLAGS"
+        else
+          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+        fi
+      fi
+    fi
+  fi
+
+  CXX=$CXX_SAVED
+  CXXCPP=$CXXCPP_SAVED
+fi
+
+
+
+
 
 # On darwin 10.7,10.8,10.9 using clang++, need to ensure using
 # libc++ for tests and examples to run under mono. May affect
@@ -6422,8 +9379,58 @@
   *) ;;
 esac
 
-# Set info about shared libraries.
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking CXXFLAGS to use for testing (PLATCXXFLAGS)" >&5
+printf %s "checking CXXFLAGS to use for testing (PLATCXXFLAGS)... " >&6; }
+PLATCXXFLAGS=$(echo $PLATCXXFLAGS | xargs) # Trim whitespace
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PLATCXXFLAGS" >&5
+printf "%s\n" "$PLATCXXFLAGS" >&6; }
 
+# Check for compiler pre-compiled header support
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if compiler supports pre-compiled headers" >&5
+printf %s "checking if compiler supports pre-compiled headers... " >&6; }
+PCHSUPPORT=no
+if test "$CLANGXX" = "yes"; then
+   PCHINCLUDEARG="-include-pch"
+   PCHINCLUDEEXT=".gch"
+else
+   PCHINCLUDEARG="-include"
+   PCHINCLUDEEXT=""
+fi
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+echo '#include <cstdlib>' > conftest.hpp
+echo '#include "conftest.hpp"' > conftest.cpp
+$CXX -c conftest.hpp 2>/dev/null
+if test $? -eq 0; then
+   if test -f conftest.hpp.gch; then
+      $CXX -H -c -I. ${PCHINCLUDEARG} ./conftest.hpp${PCHINCLUDEEXT} -o conftest.o conftest.cpp >conftest.out 2>&1
+      if test $? -eq 0; then
+         if test "$CLANGXX" = "yes"; then
+            PCHSUPPORT=yes
+         elif grep -q '^!.*conftest.hpp.gch$' conftest.out; then
+            PCHSUPPORT=yes
+         fi
+      fi
+   fi
+fi
+rm -f conftest.hpp conftest.cpp conftest.out
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PCHSUPPORT" >&5
+printf "%s\n" "$PCHSUPPORT" >&6; }
+
+
+
+
+# Set info about shared libraries.
 
 
 
@@ -6474,11 +9481,13 @@
 esac
 
 # Check for specific libraries.   Used for SWIG examples
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
-$as_echo_n "checking for dlopen in -ldl... " >&6; }
-if ${ac_cv_lib_dl_dlopen+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+printf %s "checking for dlopen in -ldl... " >&6; }
+if test ${ac_cv_lib_dl_dlopen+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-ldl  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -6487,43 +9496,41 @@
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char dlopen ();
 int
-main ()
+main (void)
 {
 return dlopen ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_dl_dlopen=yes
-else
+else $as_nop
   ac_cv_lib_dl_dlopen=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
-$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
-if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBDL 1
-_ACEOF
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+printf "%s\n" "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes
+then :
+  printf "%s\n" "#define HAVE_LIBDL 1" >>confdefs.h
 
   LIBS="-ldl $LIBS"
 
 fi
 	# Dynamic linking for SunOS/Solaris and SYSV
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
-$as_echo_n "checking for shl_load in -ldld... " >&6; }
-if ${ac_cv_lib_dld_shl_load+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+printf %s "checking for shl_load in -ldld... " >&6; }
+if test ${ac_cv_lib_dld_shl_load+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-ldld  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -6532,44 +9539,42 @@
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char shl_load ();
 int
-main ()
+main (void)
 {
 return shl_load ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_dld_shl_load=yes
-else
+else $as_nop
   ac_cv_lib_dld_shl_load=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
-$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
-if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBDLD 1
-_ACEOF
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+printf "%s\n" "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes
+then :
+  printf "%s\n" "#define HAVE_LIBDLD 1" >>confdefs.h
 
   LIBS="-ldld $LIBS"
 
 fi
 	# Dynamic linking for HP-UX
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing t_open" >&5
-$as_echo_n "checking for library containing t_open... " >&6; }
-if ${ac_cv_search_t_open+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing t_open" >&5
+printf %s "checking for library containing t_open... " >&6; }
+if test ${ac_cv_search_t_open+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_func_search_save_LIBS=$LIBS
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -6577,55 +9582,58 @@
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char t_open ();
 int
-main ()
+main (void)
 {
 return t_open ();
   ;
   return 0;
 }
 _ACEOF
-for ac_lib in '' nsl; do
+for ac_lib in '' nsl
+do
   if test -z "$ac_lib"; then
     ac_res="none required"
   else
     ac_res=-l$ac_lib
     LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
   fi
-  if ac_fn_c_try_link "$LINENO"; then :
+  if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_search_t_open=$ac_res
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext
-  if ${ac_cv_search_t_open+:} false; then :
+  if test ${ac_cv_search_t_open+y}
+then :
   break
 fi
 done
-if ${ac_cv_search_t_open+:} false; then :
+if test ${ac_cv_search_t_open+y}
+then :
 
-else
+else $as_nop
   ac_cv_search_t_open=no
 fi
 rm conftest.$ac_ext
 LIBS=$ac_func_search_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_t_open" >&5
-$as_echo "$ac_cv_search_t_open" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_t_open" >&5
+printf "%s\n" "$ac_cv_search_t_open" >&6; }
 ac_res=$ac_cv_search_t_open
-if test "$ac_res" != no; then :
+if test "$ac_res" != no
+then :
   test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 
 fi
  # SVR4
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname" >&5
-$as_echo_n "checking for library containing gethostbyname... " >&6; }
-if ${ac_cv_search_gethostbyname+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing gethostbyname" >&5
+printf %s "checking for library containing gethostbyname... " >&6; }
+if test ${ac_cv_search_gethostbyname+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_func_search_save_LIBS=$LIBS
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -6633,55 +9641,58 @@
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char gethostbyname ();
 int
-main ()
+main (void)
 {
 return gethostbyname ();
   ;
   return 0;
 }
 _ACEOF
-for ac_lib in '' inet; do
+for ac_lib in '' inet
+do
   if test -z "$ac_lib"; then
     ac_res="none required"
   else
     ac_res=-l$ac_lib
     LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
   fi
-  if ac_fn_c_try_link "$LINENO"; then :
+  if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_search_gethostbyname=$ac_res
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext
-  if ${ac_cv_search_gethostbyname+:} false; then :
+  if test ${ac_cv_search_gethostbyname+y}
+then :
   break
 fi
 done
-if ${ac_cv_search_gethostbyname+:} false; then :
+if test ${ac_cv_search_gethostbyname+y}
+then :
 
-else
+else $as_nop
   ac_cv_search_gethostbyname=no
 fi
 rm conftest.$ac_ext
 LIBS=$ac_func_search_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gethostbyname" >&5
-$as_echo "$ac_cv_search_gethostbyname" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_gethostbyname" >&5
+printf "%s\n" "$ac_cv_search_gethostbyname" >&6; }
 ac_res=$ac_cv_search_gethostbyname
-if test "$ac_res" != no; then :
+if test "$ac_res" != no
+then :
   test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 
 fi
  # Sequent
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5
-$as_echo_n "checking for library containing socket... " >&6; }
-if ${ac_cv_search_socket+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing socket" >&5
+printf %s "checking for library containing socket... " >&6; }
+if test ${ac_cv_search_socket+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_func_search_save_LIBS=$LIBS
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
@@ -6689,100 +9700,60 @@
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char socket ();
 int
-main ()
+main (void)
 {
 return socket ();
   ;
   return 0;
 }
 _ACEOF
-for ac_lib in '' socket; do
+for ac_lib in '' socket
+do
   if test -z "$ac_lib"; then
     ac_res="none required"
   else
     ac_res=-l$ac_lib
     LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
   fi
-  if ac_fn_c_try_link "$LINENO"; then :
+  if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_search_socket=$ac_res
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext
-  if ${ac_cv_search_socket+:} false; then :
+  if test ${ac_cv_search_socket+y}
+then :
   break
 fi
 done
-if ${ac_cv_search_socket+:} false; then :
+if test ${ac_cv_search_socket+y}
+then :
 
-else
+else $as_nop
   ac_cv_search_socket=no
 fi
 rm conftest.$ac_ext
 LIBS=$ac_func_search_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5
-$as_echo "$ac_cv_search_socket" >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_socket" >&5
+printf "%s\n" "$ac_cv_search_socket" >&6; }
 ac_res=$ac_cv_search_socket
-if test "$ac_res" != no; then :
+if test "$ac_res" != no
+then :
   test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 
 fi
  # SVR4 sockets
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for swill_init in -lswill" >&5
-$as_echo_n "checking for swill_init in -lswill... " >&6; }
-if ${ac_cv_lib_swill_swill_init+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lswill  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char swill_init ();
-int
-main ()
-{
-return swill_init ();
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_swill_swill_init=yes
-else
-  ac_cv_lib_swill_swill_init=no
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_swill_swill_init" >&5
-$as_echo "$ac_cv_lib_swill_swill_init" >&6; }
-if test "x$ac_cv_lib_swill_swill_init" = xyes; then :
-  SWIGLIBS="-lswill $LIBS" SWILL="-DSWIG_SWILL"
-fi
-
-
-
-
 # check for --with-libm=...
 
 LIBM=-lm
 
 # Check whether --with-libm was given.
-if test "${with_libm+set}" = set; then :
+if test ${with_libm+y}
+then :
   withval=$with_libm;
 if test "$withval" != yes
 then LIBM=$withval
@@ -6790,11 +9761,12 @@
 fi
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lieee" >&5
-$as_echo_n "checking for main in -lieee... " >&6; }
-if ${ac_cv_lib_ieee_main+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for main in -lieee" >&5
+printf %s "checking for main in -lieee... " >&6; }
+if test ${ac_cv_lib_ieee_main+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lieee  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -6802,33 +9774,36 @@
 
 
 int
-main ()
+main (void)
 {
 return main ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_ieee_main=yes
-else
+else $as_nop
   ac_cv_lib_ieee_main=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ieee_main" >&5
-$as_echo "$ac_cv_lib_ieee_main" >&6; }
-if test "x$ac_cv_lib_ieee_main" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ieee_main" >&5
+printf "%s\n" "$ac_cv_lib_ieee_main" >&6; }
+if test "x$ac_cv_lib_ieee_main" = xyes
+then :
   LIBM="-lieee $LIBM"
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for crypt in -lcrypt" >&5
-$as_echo_n "checking for crypt in -lcrypt... " >&6; }
-if ${ac_cv_lib_crypt_crypt+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for crypt in -lcrypt" >&5
+printf %s "checking for crypt in -lcrypt... " >&6; }
+if test ${ac_cv_lib_crypt_crypt+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   ac_check_lib_save_LIBS=$LIBS
 LIBS="-lcrypt  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -6837,30 +9812,29 @@
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
    builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
 char crypt ();
 int
-main ()
+main (void)
 {
 return crypt ();
   ;
   return 0;
 }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
+if ac_fn_c_try_link "$LINENO"
+then :
   ac_cv_lib_crypt_crypt=yes
-else
+else $as_nop
   ac_cv_lib_crypt_crypt=no
 fi
-rm -f core conftest.err conftest.$ac_objext \
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
     conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_crypt" >&5
-$as_echo "$ac_cv_lib_crypt_crypt" >&6; }
-if test "x$ac_cv_lib_crypt_crypt" = xyes; then :
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypt_crypt" >&5
+printf "%s\n" "$ac_cv_lib_crypt_crypt" >&6; }
+if test "x$ac_cv_lib_crypt_crypt" = xyes
+then :
   LIBCRYPT="-lcrypt"
 fi
 
@@ -6870,7 +9844,8 @@
 
 
 # Check whether --with-libc was given.
-if test "${with_libc+set}" = set; then :
+if test ${with_libc+y}
+then :
   withval=$with_libc;
 if test "$withval" != yes
 then LIBC=$withval
@@ -6885,7 +9860,8 @@
 
 
 # Check whether --with-alllang was given.
-if test "${with_alllang+set}" = set; then :
+if test ${with_alllang+y}
+then :
   withval=$with_alllang; with_alllang="$withval"
 fi
 
@@ -6896,1133 +9872,33 @@
   alllang_default=yes
 fi
 
-for ac_prog in pkg-config
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_PKGCONFIG+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$PKGCONFIG"; then
-  ac_cv_prog_PKGCONFIG="$PKGCONFIG" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_PKGCONFIG="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-PKGCONFIG=$ac_cv_prog_PKGCONFIG
-if test -n "$PKGCONFIG"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PKGCONFIG" >&5
-$as_echo "$PKGCONFIG" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$PKGCONFIG" && break
-done
-
-
-#--------------------------------------------------------------------
-# Look for Tcl
-#--------------------------------------------------------------------
-
-TCLINCLUDE=
-TCLLIB=
-TCLPACKAGE=
-
-
-# Check whether --with-tclconfig was given.
-if test "${with_tclconfig+set}" = set; then :
-  withval=$with_tclconfig; with_tclconfig="$withval"
-else
-  with_tclconfig=
-fi
-
-
-# Check whether --with-tcl was given.
-if test "${with_tcl+set}" = set; then :
-  withval=$with_tcl;
-	TCLPACKAGE="$withval"
-else
-  TCLPACKAGE="$alllang_default"
-fi
-
-
-# Check whether --with-tclincl was given.
-if test "${with_tclincl+set}" = set; then :
-  withval=$with_tclincl;
-	TCLINCLUDE="$ISYSTEM$withval"
-else
-  TCLINCLUDE=
-fi
-
-
-# Check whether --with-tcllib was given.
-if test "${with_tcllib+set}" = set; then :
-  withval=$with_tcllib;
-	TCLLIB="-L$withval"
-else
-  TCLLIB=
-fi
-
-
-# First, check for "--without-tcl" or "--with-tcl=no".
-if test x"${TCLPACKAGE}" = xno; then
-{ $as_echo "$as_me:${as_lineno-$LINENO}: Disabling Tcl" >&5
-$as_echo "$as_me: Disabling Tcl" >&6;}
-else
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5
-$as_echo_n "checking for Tcl configuration... " >&6; }
-# First check to see if --with-tclconfig was specified.
-if test x"${with_tclconfig}" != x ; then
-   if test -f "${with_tclconfig}/tclConfig.sh" ; then
-      TCLCONFIG=`(cd ${with_tclconfig}; pwd)`
-   else
-      as_fn_error $? "${with_tcl} directory does not contain tclConfig.sh" "$LINENO" 5
-   fi
-fi
-# check in a few common install locations
-dirs="/usr/lib*/ /usr/lib*/tcl*/ /usr/local/lib*/ /usr/local/lib*/tcl*/"
-case $host in
-*-*-darwin*)
-  dirs="/System/Library/Frameworks/Tcl.framework/ $dirs"
-  ;;
-*)
-  ;;
-esac
-if test x"${TCLCONFIG}" = x ; then
-  for d in $dirs ; do
-    for i in `ls -d -r $d 2>/dev/null` ; do
-      if test -f $i"tclConfig.sh" ; then
-        TCLCONFIG=`(cd $i; pwd)`
-        break
-      fi
-    done
-  done
-fi
-if test x"${TCLCONFIG}" = x ; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: found $TCLCONFIG/tclConfig.sh" >&5
-$as_echo "found $TCLCONFIG/tclConfig.sh" >&6; }
-    . $TCLCONFIG/tclConfig.sh
-    if test -z "$TCLINCLUDE"; then
-        TCLINCLUDE=`echo $TCL_INCLUDE_SPEC | sed "s/-I/$ISYSTEM/"`
-    fi
-    if test -z "$TCLLIB"; then
-        TCLLIB=$TCL_LIB_SPEC
-    fi
-fi
-
-if test -z "$TCLINCLUDE"; then
-   if test "x$TCLPACKAGE" != xyes; then
-	TCLINCLUDE="$ISYSTEM$TCLPACKAGE/include"
-   fi
-fi
-
-if test -z "$TCLLIB"; then
-   if test "x$TCLPACKAGE" != xyes; then
-	TCLLIB="-L$TCLPACKAGE/lib -ltcl"
-   fi
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl header files" >&5
-$as_echo_n "checking for Tcl header files... " >&6; }
-if test -z "$TCLINCLUDE"; then
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-#include <tcl.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
-  TCLINCLUDE=""
-fi
-rm -f conftest.err conftest.i conftest.$ac_ext
-if test -z "$TCLINCLUDE"; then
-	dirs="/usr/local/include /usr/include /opt/local/include"
-	for i in $dirs ; do
-		if test -r $i/tcl.h; then
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $i" >&5
-$as_echo "$i" >&6; }
-			TCLINCLUDE="$ISYSTEM$i"
-			break
-		fi
-	done
-fi
-if test -z "$TCLINCLUDE"; then
-    	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
-fi
-else
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TCLINCLUDE" >&5
-$as_echo "$TCLINCLUDE" >&6; }
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl library" >&5
-$as_echo_n "checking for Tcl library... " >&6; }
-if test -z "$TCLLIB"; then
-dirs="/usr/local/lib /usr/lib /opt/local/lib"
-for i in $dirs ; do
-	if test -r $i/libtcl.a; then
-	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $i" >&5
-$as_echo "$i" >&6; }
-	    TCLLIB="-L$i -ltcl"
-	    break
-	fi
-done
-if test -z "$TCLLIB"; then
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
-fi
-else
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $TCLLIB" >&5
-$as_echo "$TCLLIB" >&6; }
-fi
-
-# Cygwin (Windows) needs the library for dynamic linking
-case $host in
-*-*-cygwin* | *-*-mingw*) TCLDYNAMICLINKING="$TCLLIB";;
-*)TCLDYNAMICLINKING="";;
-esac
-
-case $host in
-*-*-darwin*)
-    TCLLDSHARED='$(CC) -dynamiclib -undefined suppress -flat_namespace'
-    TCLCXXSHARED='$(CXX) -dynamiclib -undefined suppress -flat_namespace'
-    ;;
-*)
-    TCLLDSHARED='$(LDSHARED)'
-    TCLCXXSHARED='$(CXXSHARED)'
-    ;;
-esac
-
-fi
-
-
-
-
-
-
-
-#----------------------------------------------------------------
-# Look for Python
-#----------------------------------------------------------------
-
-PYINCLUDE=
-PYLIB=
-PYLINK=
-PYPACKAGE=
-
-
-# Check whether --with-python was given.
-if test "${with_python+set}" = set; then :
-  withval=$with_python;  PYBIN="$withval"
-else
-  PYBIN="$alllang_default"
-fi
-
-
-# First, check for "--without-python" or "--with-python=no".
-if test x"${PYBIN}" = xno; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: Disabling Python" >&5
-$as_echo "$as_me: Disabling Python" >&6;}
-else
-  # First figure out the name of the Python executable
-  if test "x$PYBIN" = xyes; then
-    for ac_prog in python python2.7
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_PYTHON+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$PYTHON"; then
-  ac_cv_prog_PYTHON="$PYTHON" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_PYTHON="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-PYTHON=$ac_cv_prog_PYTHON
-if test -n "$PYTHON"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5
-$as_echo "$PYTHON" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$PYTHON" && break
-done
-
-  else
-    PYTHON="$PYBIN"
-  fi
-
-  PYVER=0
-  if test -n "$PYTHON"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $PYTHON major version number" >&5
-$as_echo_n "checking for $PYTHON major version number... " >&6; }
-    PYVER=`($PYTHON -c "import sys; sys.stdout.write(sys.version[0])") 2>/dev/null`
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYVER" >&5
-$as_echo "$PYVER" >&6; }
-    if test -z "$PYVER"; then
-      PYVER=0
-    else
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python os.name" >&5
-$as_echo_n "checking for Python os.name... " >&6; }
-      PYOSNAME=`($PYTHON -c "import sys, os; sys.stdout.write(os.name)") 2>/dev/null`
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYOSNAME" >&5
-$as_echo "$PYOSNAME" >&6; }
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python path separator" >&5
-$as_echo_n "checking for Python path separator... " >&6; }
-      PYSEPARATOR=`($PYTHON -c "import sys, os; sys.stdout.write(os.sep)") 2>/dev/null`
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYSEPARATOR" >&5
-$as_echo "$PYSEPARATOR" >&6; }
-    fi
-  fi
-
-  if test $PYVER -eq 1 -o $PYVER -eq 2; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python prefix" >&5
-$as_echo_n "checking for Python prefix... " >&6; }
-    PYPREFIX=`($PYTHON -c "import sys; sys.stdout.write(sys.prefix)") 2>/dev/null`
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYPREFIX" >&5
-$as_echo "$PYPREFIX" >&6; }
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python exec-prefix" >&5
-$as_echo_n "checking for Python exec-prefix... " >&6; }
-    PYEPREFIX=`($PYTHON -c "import sys; sys.stdout.write(sys.exec_prefix)") 2>/dev/null`
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYEPREFIX" >&5
-$as_echo "$PYEPREFIX" >&6; }
-
-    if test x"$PYOSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\"; then
-      # Windows installations are quite different to posix installations (MinGW path separator is a forward slash)
-      PYPREFIX=`echo "$PYPREFIX" | sed -e 's,\\\\,/,g'` # Forward slashes are easier to use and even work on Windows most of the time
-      PYTHON_SO=.pyd
-
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python header files" >&5
-$as_echo_n "checking for Python header files... " >&6; }
-      if test -r $PYPREFIX/include/Python.h; then
-        PYINCLUDE="-I$PYPREFIX/include"
-      fi
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYINCLUDE" >&5
-$as_echo "$PYINCLUDE" >&6; }
-
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python library directory" >&5
-$as_echo_n "checking for Python library directory... " >&6; }
-      if test -d $PYPREFIX/libs; then
-        PYLIB=$PYPREFIX/libs
-        PYLINKFILE=`ls $PYLIB/python*.lib | grep "python[0-9][0-9]\.lib"`
-        if test -r "$PYLINKFILE"; then
-          PYLINK=-l`basename $PYLINKFILE | sed -e 's/\.lib$//'`
-        else
-          PYLIB=
-        fi
-      fi
-    else
-      # Note: I could not think of a standard way to get the version string from different versions.
-      # This trick pulls it out of the file location for a standard library file.
-
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python version" >&5
-$as_echo_n "checking for Python version... " >&6; }
-
-      # Need to do this hack since autoconf replaces __file__ with the name of the configure file
-      filehack="file__"
-      PYVERSION=`($PYTHON -c "import sys,string,operator,os.path; sys.stdout.write(operator.getitem(os.path.split(operator.getitem(os.path.split(string.__$filehack),0)),1))") 2>/dev/null`
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYVERSION" >&5
-$as_echo "$PYVERSION" >&6; }
-
-      # Find the directory for libraries this is necessary to deal with
-      # platforms that can have apps built for multiple archs: e.g. x86_64
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python lib dir" >&5
-$as_echo_n "checking for Python lib dir... " >&6; }
-      PYLIBDIR=`($PYTHON -c "import sys; sys.stdout.write(sys.lib)") 2>/dev/null`
-      if test -z "$PYLIBDIR"; then
-        # Fedora patch Python to add sys.lib, for other distros we assume "lib".
-        PYLIBDIR="lib"
-      fi
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYLIBDIR" >&5
-$as_echo "$PYLIBDIR" >&6; }
-
-      # Set the include directory
-
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python header files" >&5
-$as_echo_n "checking for Python header files... " >&6; }
-      if test -r $PYPREFIX/include/$PYVERSION/Python.h; then
-        PYINCLUDE="-I$PYPREFIX/include/$PYVERSION -I$PYEPREFIX/$PYLIBDIR/$PYVERSION/config"
-      fi
-      if test -z "$PYINCLUDE"; then
-        if test -r $PYPREFIX/include/Py/Python.h; then
-          PYINCLUDE="-I$PYPREFIX/include/Py -I$PYEPREFIX/$PYLIBDIR/python/lib"
-        fi
-      fi
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYINCLUDE" >&5
-$as_echo "$PYINCLUDE" >&6; }
-
-      # Set the library directory blindly.   This probably won't work with older versions
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python library directory" >&5
-$as_echo_n "checking for Python library directory... " >&6; }
-      dirs="$PYVERSION/config $PYVERSION/$PYLIBDIR python/$PYLIBDIR"
-      for i in $dirs; do
-        if test -d $PYEPREFIX/$PYLIBDIR/$i; then
-          PYLIB="$PYEPREFIX/$PYLIBDIR/$i"
-          break
-        fi
-      done
-
-      PYLINK="-l$PYVERSION"
-    fi
-
-    if test -z "$PYLIB"; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
-$as_echo "Not found" >&6; }
-    else
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYLIB" >&5
-$as_echo "$PYLIB" >&6; }
-    fi
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python library" >&5
-$as_echo_n "checking for Python library... " >&6; }
-    if test -z "$PYLINK"; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
-$as_echo "Not found" >&6; }
-    else
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYLINK" >&5
-$as_echo "$PYLINK" >&6; }
-    fi
-  fi
-
-  # Cygwin (Windows) needs the library for dynamic linking
-  case $host in
-  *-*-cygwin* | *-*-mingw*)
-    PYTHONDYNAMICLINKING="-L$PYLIB $PYLINK"
-    DEFS="-DUSE_DL_IMPORT $DEFS"
-    ;;
-  *)PYTHONDYNAMICLINKING="";;
-  esac
-fi
-
-
-
-
-
-
-
-#----------------------------------------------------------------
-# Look for Python 3.x
-#----------------------------------------------------------------
-
-PY3INCLUDE=
-PY3LIB=
-PY3LINK=
-PY3PACKAGE=
-
-
-# Check whether --with-python3 was given.
-if test "${with_python3+set}" = set; then :
-  withval=$with_python3;  PY3BIN="$withval"
-else
-  PY3BIN="$alllang_default"
-fi
-
-
-# First, check for "--without-python3" or "--with-python3=no".
-if test x"${PY3BIN}" = xno; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: Disabling Python 3.x support" >&5
-$as_echo "$as_me: Disabling Python 3.x support" >&6;}
-else
-  if test -z "$PYVER"; then
-    PYVER=0
-  fi
-  if test "x$PY3BIN" = xyes; then
-    if test x"$PYOSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\" -a $PYVER -ge 3; then
-      PYTHON3="$PYTHON"
-    else
-      for py_ver in 3 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 ""; do
-        for ac_prog in python$py_ver
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_PYTHON3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$PYTHON3"; then
-  ac_cv_prog_PYTHON3="$PYTHON3" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_PYTHON3="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-PYTHON3=$ac_cv_prog_PYTHON3
-if test -n "$PYTHON3"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON3" >&5
-$as_echo "$PYTHON3" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$PYTHON3" && break
-done
-
-        if test -n "$PYTHON3"; then
-          for ac_prog in $PYTHON3-config
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_PY3CONFIG+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$PY3CONFIG"; then
-  ac_cv_prog_PY3CONFIG="$PY3CONFIG" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_PY3CONFIG="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-PY3CONFIG=$ac_cv_prog_PY3CONFIG
-if test -n "$PY3CONFIG"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PY3CONFIG" >&5
-$as_echo "$PY3CONFIG" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$PY3CONFIG" && break
-done
-
-          if test -n "$PY3CONFIG"; then
-            break
-          fi
-        fi
-      done
-    fi
-  else
-    PYTHON3="$PY3BIN"
-    for ac_prog in $PYTHON3-config
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_PY3CONFIG+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$PY3CONFIG"; then
-  ac_cv_prog_PY3CONFIG="$PY3CONFIG" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_PY3CONFIG="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-PY3CONFIG=$ac_cv_prog_PY3CONFIG
-if test -n "$PY3CONFIG"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PY3CONFIG" >&5
-$as_echo "$PY3CONFIG" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$PY3CONFIG" && break
-done
-
-  fi
-
-  if test -n "$PYTHON3"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $PYTHON3 major version number" >&5
-$as_echo_n "checking for $PYTHON3 major version number... " >&6; }
-    PYVER=`($PYTHON3 -c "import sys; sys.stdout.write(sys.version[0])") 2>/dev/null`
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYVER" >&5
-$as_echo "$PYVER" >&6; }
-    if test -z "$PYVER"; then
-      PYVER=0
-    fi
-  fi
-
-  if test $PYVER -ge 3; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python 3.x os.name" >&5
-$as_echo_n "checking for Python 3.x os.name... " >&6; }
-    PY3OSNAME=`($PYTHON3 -c "import sys, os; sys.stdout.write(os.name)") 2>/dev/null`
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PY3OSNAME" >&5
-$as_echo "$PY3OSNAME" >&6; }
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python 3.x path separator" >&5
-$as_echo_n "checking for Python 3.x path separator... " >&6; }
-    PYSEPARATOR=`($PYTHON3 -c "import sys, os; sys.stdout.write(os.sep)") 2>/dev/null`
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYSEPARATOR" >&5
-$as_echo "$PYSEPARATOR" >&6; }
-
-    if test x"$PY3OSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\"; then
-      # Windows installations are quite different to posix installations
-      # There is no python-config to use
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python 3.x prefix" >&5
-$as_echo_n "checking for Python 3.x prefix... " >&6; }
-      PY3PREFIX=`($PYTHON3 -c "import sys; sys.stdout.write(sys.prefix)") 2>/dev/null`
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PY3PREFIX" >&5
-$as_echo "$PY3PREFIX" >&6; }
-      PY3PREFIX=`echo "$PY3PREFIX" | sed -e 's,\\\\,/,g'` # Forward slashes are easier to use and even work on Windows most of the time
-      PYTHON_SO=.pyd
-
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python 3.x header files" >&5
-$as_echo_n "checking for Python 3.x header files... " >&6; }
-      if test -r $PY3PREFIX/include/Python.h; then
-        PY3INCLUDE="-I$PY3PREFIX/include"
-      fi
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PY3INCLUDE" >&5
-$as_echo "$PY3INCLUDE" >&6; }
-
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python 3.x library directory" >&5
-$as_echo_n "checking for Python 3.x library directory... " >&6; }
-      if test -d $PY3PREFIX/libs; then
-        PY3LIB=$PY3PREFIX/libs
-        PY3LINKFILE=`ls $PY3LIB/python*.lib | grep "python[0-9][0-9]\.lib"`
-        if test -r "$PY3LINKFILE"; then
-          PY3LINK=-l`basename $PY3LINKFILE | sed -e 's/\.lib$//'`
-        else
-          PY3LIB=
-        fi
-      fi
-      if test -z "$PY3LIB"; then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
-$as_echo "Not found" >&6; }
-      else
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PY3LIB" >&5
-$as_echo "$PY3LIB" >&6; }
-      fi
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python 3.x library" >&5
-$as_echo_n "checking for Python 3.x library... " >&6; }
-      if test -z "$PY3LINK"; then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
-$as_echo "Not found" >&6; }
-      else
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PY3LINK" >&5
-$as_echo "$PY3LINK" >&6; }
-      fi
-    elif test -n "$PY3CONFIG"; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python 3.x prefix" >&5
-$as_echo_n "checking for Python 3.x prefix... " >&6; }
-      PY3PREFIX=`($PY3CONFIG --prefix) 2>/dev/null`
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PY3PREFIX" >&5
-$as_echo "$PY3PREFIX" >&6; }
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python 3.x exec-prefix" >&5
-$as_echo_n "checking for Python 3.x exec-prefix... " >&6; }
-      # Piped through xargs to strip trailing whitespace (bug in msys2 + mingw Python)
-      PY3EPREFIX=`($PY3CONFIG --exec-prefix | xargs) 2>/dev/null`
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PY3EPREFIX" >&5
-$as_echo "$PY3EPREFIX" >&6; }
-
-      # Note: I could not think of a standard way to get the version string from different versions.
-      # This trick pulls it out of the file location for a standard library file.
-
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python 3.x version" >&5
-$as_echo_n "checking for Python 3.x version... " >&6; }
-
-      # Need to do this hack since autoconf replaces __file__ with the name of the configure file
-      filehack="file__"
-      PY3VERSION=`($PYTHON3 -c "import string,operator,os.path; print(operator.getitem(os.path.split(operator.getitem(os.path.split(string.__$filehack),0)),1))") 2>/dev/null`
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PY3VERSION" >&5
-$as_echo "$PY3VERSION" >&6; }
-
-      # Find the directory for libraries this is necessary to deal with
-      # platforms that can have apps built for multiple archs: e.g. x86_64
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python 3.x lib dir" >&5
-$as_echo_n "checking for Python 3.x lib dir... " >&6; }
-      PY3LIBDIR=`($PYTHON3 -c "import sys; print(sys.lib)") 2>/dev/null`
-      if test -z "$PY3LIBDIR"; then
-        # some dists don't have sys.lib  so the best we can do is assume lib
-        PY3LIBDIR="lib"
-      fi
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PY3LIBDIR" >&5
-$as_echo "$PY3LIBDIR" >&6; }
-
-      # Set the include directory
-
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python 3.x header files" >&5
-$as_echo_n "checking for Python 3.x header files... " >&6; }
-      PY3INCLUDE=`($PY3CONFIG --includes) 2>/dev/null`
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PY3INCLUDE" >&5
-$as_echo "$PY3INCLUDE" >&6; }
-
-      # Set the library directory blindly.   This probably won't work with older versions
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python 3.x library directory" >&5
-$as_echo_n "checking for Python 3.x library directory... " >&6; }
-      dirs="$PY3VERSION/config $PY3VERSION/$PY3LIBDIR python/$PY3LIBDIR"
-      for i in $dirs; do
-        if test -d $PY3EPREFIX/$PY3LIBDIR/$i; then
-          PY3LIB="$PY3EPREFIX/$PY3LIBDIR/$i"
-          break
-        fi
-      done
-      if test -z "$PY3LIB"; then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
-$as_echo "Not found" >&6; }
-      else
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PY3LIB" >&5
-$as_echo "$PY3LIB" >&6; }
-      fi
-
-      PY3LINK="-l$PY3VERSION"
-
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Python 3.x library" >&5
-$as_echo_n "checking for Python 3.x library... " >&6; }
-      if test -z "$PY3LINK"; then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
-$as_echo "Not found" >&6; }
-      else
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PY3LINK" >&5
-$as_echo "$PY3LINK" >&6; }
-      fi
-    fi
-  fi
-
-  # Cygwin (Windows) needs the library for dynamic linking
-  case $host in
-  *-*-cygwin* | *-*-mingw*)
-    PYTHON3DYNAMICLINKING="-L$PY3LIB $PY3LINK"
-    DEFS="-DUSE_DL_IMPORT $DEFS"
-    ;;
-  *)PYTHON3DYNAMICLINKING="";;
-  esac
-
-
-
-
-
-fi
-
-if test -n "$PYINCLUDE" || test -n "$PY3INCLUDE" ; then
-  for ac_prog in pycodestyle
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_PYCODESTYLE+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$PYCODESTYLE"; then
-  ac_cv_prog_PYCODESTYLE="$PYCODESTYLE" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_PYCODESTYLE="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-PYCODESTYLE=$ac_cv_prog_PYCODESTYLE
-if test -n "$PYCODESTYLE"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYCODESTYLE" >&5
-$as_echo "$PYCODESTYLE" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$PYCODESTYLE" && break
-done
-
-  if test -n "$PYCODESTYLE"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking pycodestyle version" >&5
-$as_echo_n "checking pycodestyle version... " >&6; }
-    pycodestyle_version=`$PYCODESTYLE --version 2>/dev/null`
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $pycodestyle_version" >&5
-$as_echo "$pycodestyle_version" >&6; }
-  fi
-fi
-
-
-# Check whether --with-2to3 was given.
-if test "${with_2to3+set}" = set; then :
-  withval=$with_2to3; PY2TO3BIN="$withval"
-else
-  PY2TO3BIN="yes"
-fi
-
-if test -n "$PYTHON3"; then
-  if test "x$PY2TO3BIN" = xyes; then
-    py3to2=`echo $PYTHON3 | sed -e "s/python/2to3-/"`
-    for ac_prog in $py3to2 2to3
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_PY2TO3+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$PY2TO3"; then
-  ac_cv_prog_PY2TO3="$PY2TO3" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_PY2TO3="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-PY2TO3=$ac_cv_prog_PY2TO3
-if test -n "$PY2TO3"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PY2TO3" >&5
-$as_echo "$PY2TO3" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$PY2TO3" && break
-done
-
-    if test -z "$PY2TO3"; then
-      # Windows distributions don't always have the 2to3 executable
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 2to3.py" >&5
-$as_echo_n "checking for 2to3.py... " >&6; }
-      py2to3script="$PY3PREFIX/Tools/scripts/2to3.py"
-      if test -f "$py2to3script"; then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $py2to3script" >&5
-$as_echo "$py2to3script" >&6; }
-        PY2TO3="$PYTHON3 $py2to3script"
-      else
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
-$as_echo "Not found" >&6; }
-      fi
-    fi
-  else
-    PY2TO3="$PY2TO3BIN"
-  fi
-  if test -z "$PY2TO3"; then
-    PYTHON3=
-  fi
-fi
-
-#----------------------------------------------------------------
-# Look for Perl5
-#----------------------------------------------------------------
-
-PERLBIN=
-
-
-# Check whether --with-perl5 was given.
-if test "${with_perl5+set}" = set; then :
-  withval=$with_perl5;  PERLBIN="$withval"
-else
-  PERLBIN="$alllang_default"
-fi
-
-
-# First, check for "--without-perl5" or "--with-perl5=no".
-if test x"${PERLBIN}" = xno; then
-{ $as_echo "$as_me:${as_lineno-$LINENO}: Disabling Perl5" >&5
-$as_echo "$as_me: Disabling Perl5" >&6;}
-PERL=
-else
-
-# First figure out what the name of Perl5 is
-
-if test "x$PERLBIN" = xyes; then
-for ac_prog in perl perl5.6.1 perl5.6.0 perl5.004 perl5.003 perl5.002 perl5.001 perl5 perl
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_PERL+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$PERL"; then
-  ac_cv_prog_PERL="$PERL" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_PERL="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-PERL=$ac_cv_prog_PERL
-if test -n "$PERL"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5
-$as_echo "$PERL" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$PERL" && break
-done
-
-else
-PERL="$PERLBIN"
-fi
-
-
-# This could probably be simplified as for all platforms and all versions of Perl the following apparently should be run to get the compilation options:
-# perl -MExtUtils::Embed -e ccopts
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Perl5 header files" >&5
-$as_echo_n "checking for Perl5 header files... " >&6; }
-if test -n "$PERL"; then
-	PERL5DIR=`($PERL -MConfig -le 'print $Config{archlibexp}') 2>/dev/null`
-	if test -n "$PERL5DIR" ; then
-		dirs="$PERL5DIR $PERL5DIR/CORE"
-		PERL5EXT=none
-		for i in $dirs; do
-			if test -r $i/perl.h; then
-				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $i" >&5
-$as_echo "$i" >&6; }
-				PERL5EXT="$i"
-				break
-			fi
-		done
-		if test "$PERL5EXT" = none; then
-			PERL5EXT="$PERL5DIR/CORE"
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: could not locate perl.h...using $PERL5EXT" >&5
-$as_echo "could not locate perl.h...using $PERL5EXT" >&6; }
-		fi
-
-		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Perl5 library" >&5
-$as_echo_n "checking for Perl5 library... " >&6; }
-		PERL5LIB=`($PERL -e 'use Config; $_=$Config{libperl}; s/^lib//; s/$Config{_a}$//; s/\.$Config{so}.*//; print $_, "\n"') 2>/dev/null`
-		if test -z "$PERL5LIB" ; then
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
-		else
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL5LIB" >&5
-$as_echo "$PERL5LIB" >&6; }
-		fi
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Perl5 ccflags" >&5
-$as_echo_n "checking for Perl5 ccflags... " >&6; }
- 		PERL5CCFLAGS=`($PERL -e 'use Config; print $Config{ccflags}, "\n"' | sed "s/-Wdeclaration-after-statement//" | sed "s/-I/$ISYSTEM/") 2>/dev/null`
- 		if test -z "$PERL5CCFLAGS" ; then
- 			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
- 		else
- 			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL5CCFLAGS" >&5
-$as_echo "$PERL5CCFLAGS" >&6; }
- 		fi
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Perl5 ccdlflags" >&5
-$as_echo_n "checking for Perl5 ccdlflags... " >&6; }
-    PERL5CCDLFLAGS=`($PERL -e 'use Config; print $Config{ccdlflags}, "\n"') 2>/dev/null`
-    if test -z "$PERL5CCDLFLAGS" ; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
-      else
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL5CCDLFLAGS" >&5
-$as_echo "$PERL5CCDLFLAGS" >&6; }
-    fi
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Perl5 cccdlflags" >&5
-$as_echo_n "checking for Perl5 cccdlflags... " >&6; }
-    PERL5CCCDLFLAGS=`($PERL -e 'use Config; print $Config{cccdlflags}, "\n"') 2>/dev/null`
-    if test -z "$PERL5CCCDLFLAGS" ; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
-      else
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL5CCCDLFLAGS" >&5
-$as_echo "$PERL5CCCDLFLAGS" >&6; }
-    fi
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Perl5 ldflags" >&5
-$as_echo_n "checking for Perl5 ldflags... " >&6; }
-    PERL5LDFLAGS=`($PERL -e 'use Config; print $Config{ldflags}, "\n"') 2>/dev/null`
-    if test -z "$PERL5LDFLAGS" ; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
-      else
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PERL5LDFLAGS" >&5
-$as_echo "$PERL5LDFLAGS" >&6; }
-    fi
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Perl5 Test::More module" >&5
-$as_echo_n "checking for Perl5 Test::More module... " >&6; } # For test-suite
-    PERL5TESTMORE=`($PERL -e 'use Test::More; print "good";') 2>/dev/null`
-    if test -z "$PERL5TESTMORE" ; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
-      else
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: found" >&5
-$as_echo "found" >&6; }
-    fi
-	else
-		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: unable to determine perl5 configuration" >&5
-$as_echo "unable to determine perl5 configuration" >&6; }
-		PERL5EXT=$PERL5DIR
-	fi
-else
-       	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: could not figure out how to run perl5" >&5
-$as_echo "could not figure out how to run perl5" >&6; }
-fi
-
-# Cygwin (Windows) needs the library for dynamic linking
-case $host in
-*-*-cygwin* | *-*-mingw*) PERL5DYNAMICLINKING="-L$PERL5EXT -l$PERL5LIB";;
-*)PERL5DYNAMICLINKING="";;
-esac
-fi
-
-
-
-
-
-
-
-
-
-
-#----------------------------------------------------------------
-# Look for Octave
-#----------------------------------------------------------------
-
-OCTAVEBIN=
-OCTAVE_SO=.oct
-
-
-# Check whether --with-octave was given.
-if test "${with_octave+set}" = set; then :
-  withval=$with_octave; OCTAVEBIN="$withval"
-else
-  OCTAVEBIN="$alllang_default"
-fi
-
-
-# Check for "--without-octave" or "--with-octave=no".
-if test x"${OCTAVEBIN}" = xno; then
-   { $as_echo "$as_me:${as_lineno-$LINENO}: Disabling Octave" >&5
-$as_echo "$as_me: Disabling Octave" >&6;}
-   OCTAVE=
-
-# Check for Octave; prefer command-line program "octave-cli" to (in newer versions) GUI program "octave"
-elif test "x$OCTAVEBIN" = xyes; then
-   # Extract the first word of "octave-cli octave", so it can be a program name with args.
-set dummy octave-cli octave; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_OCTAVE+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  case $OCTAVE in
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}pkg-config", so it can be a program name with args.
+set dummy ${ac_tool_prefix}pkg-config; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_PKG_CONFIG+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  case $PKG_CONFIG in
   [\\/]* | ?:[\\/]*)
-  ac_cv_path_OCTAVE="$OCTAVE" # Let the user override the test with a path.
+  ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path.
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_OCTAVE="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -8032,216 +9908,153 @@
   ;;
 esac
 fi
-OCTAVE=$ac_cv_path_OCTAVE
-if test -n "$OCTAVE"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCTAVE" >&5
-$as_echo "$OCTAVE" >&6; }
+PKG_CONFIG=$ac_cv_path_PKG_CONFIG
+if test -n "$PKG_CONFIG"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PKG_CONFIG" >&5
+printf "%s\n" "$PKG_CONFIG" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
-
-else
-   OCTAVE="$OCTAVEBIN"
 fi
-
-# Check if Octave works
-if test -n "$OCTAVE"; then
-   { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ${OCTAVE} works" >&5
-$as_echo_n "checking if ${OCTAVE} works... " >&6; }
-   if test "x`${OCTAVE} --version 2>/dev/null | sed -n -e '1p' | sed -n -e '/Octave, version/p'`" != x; then :
-
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-
-else
-
-      { $as_echo "$as_me:${as_lineno-$LINENO}: no" >&5
-$as_echo "$as_me: no" >&6;}
-      OCTAVE=
-
-fi
-fi
-
-# Check for required Octave helper program "mkoctfile"
-if test -n "$OCTAVE"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mkoctfile" >&5
-$as_echo_n "checking for mkoctfile... " >&6; }
-  version_suffix="`echo $OCTAVE | sed -e 's|.*\(-[0-9][0-9.]*\)$|\1|'`"
-  case $version_suffix in
-    -*) ;;
-    *) version_suffix="" ;;
+if test -z "$ac_cv_path_PKG_CONFIG"; then
+  ac_pt_PKG_CONFIG=$PKG_CONFIG
+  # Extract the first word of "pkg-config", so it can be a program name with args.
+set dummy pkg-config; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_ac_pt_PKG_CONFIG+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  case $ac_pt_PKG_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_ac_pt_PKG_CONFIG="$ac_pt_PKG_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
   esac
-  octave_directory=`dirname $OCTAVE`
-  if test "$octave_directory" = "." ; then
-    mkoctfile="mkoctfile${version_suffix}"
-  else
-    mkoctfile="${octave_directory}/mkoctfile${version_suffix}"
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_ac_pt_PKG_CONFIG="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
   fi
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${mkoctfile}" >&5
-$as_echo "${mkoctfile}" >&6; }
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ${mkoctfile} works" >&5
-$as_echo_n "checking if ${mkoctfile} works... " >&6; }
-  if test "x`${mkoctfile} --version 2>/dev/null | sed -n -e '1p' | sed -n -e '/mkoctfile, version/p'`" != x; then :
+done
+  done
+IFS=$as_save_IFS
 
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-
+  ;;
+esac
+fi
+ac_pt_PKG_CONFIG=$ac_cv_path_ac_pt_PKG_CONFIG
+if test -n "$ac_pt_PKG_CONFIG"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_pt_PKG_CONFIG" >&5
+printf "%s\n" "$ac_pt_PKG_CONFIG" >&6; }
 else
-
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-      OCTAVE=
-
-fi
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
-# Check for Octave preprocessor/compiler/linker flags
-if test -n "$OCTAVE"; then
-
-   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Octave preprocessor flags" >&5
-$as_echo_n "checking for Octave preprocessor flags... " >&6; }
-   OCTAVE_CPPFLAGS=
-   for var in CPPFLAGS INCFLAGS ALL_CXXFLAGS; do
-      for flag in `env - ${mkoctfile} -p ${var}`; do
-         case ${flag} in
-            -D*|-I*) OCTAVE_CPPFLAGS="${OCTAVE_CPPFLAGS} ${flag}";;
-            *) ;;
-         esac
-      done
-   done
-   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCTAVE_CPPFLAGS" >&5
-$as_echo "$OCTAVE_CPPFLAGS" >&6; }
-
-   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Octave compiler flags" >&5
-$as_echo_n "checking for Octave compiler flags... " >&6; }
-   OCTAVE_CXXFLAGS=
-   for var in CXX ALL_CXXFLAGS; do
-      for flag in `env - ${mkoctfile} -p ${var}`; do
-         case ${flag} in
-            -std=*|-g*|-W*) OCTAVE_CXXFLAGS="${OCTAVE_CXXFLAGS} ${flag}";;
-            *) ;;
-         esac
-      done
-   done
-   save_CXXFLAGS="${CXXFLAGS}"
-   CXXFLAGS="-Werror -O0"
-   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-
-int
-main ()
-{
-
-  ;
-  return 0;
-}
-
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
-
-      OCTAVE_CXXFLAGS="${OCTAVE_CXXFLAGS} -O0"
-
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-   CXXFLAGS="${save_CXXFLAGS}"
-   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCTAVE_CXXFLAGS" >&5
-$as_echo "$OCTAVE_CXXFLAGS" >&6; }
-
-   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Octave linker flags" >&5
-$as_echo_n "checking for Octave linker flags... " >&6; }
-   OCTAVE_LDFLAGS=
-   for var in OCTLIBDIR; do
-     OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "-L`env - ${mkoctfile} -p ${var}`
-   done
-   for var in RDYNAMIC_FLAG RLD_FLAG OCTAVE_LIBS LIBS; do
-     OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "`env - ${mkoctfile} -p ${var}`
-   done
-   { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCTAVE_LDFLAGS" >&5
-$as_echo "$OCTAVE_LDFLAGS" >&6; }
-
-fi
-
-# Check for Octave options
-if test -n "$OCTAVE"; then
-   for octave_opt in --no-window-system --silent --norc --no-history; do
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Octave option '${octave_opt}' is supported" >&5
-$as_echo_n "checking if Octave option '${octave_opt}' is supported... " >&6; }
-      octave_out=`${OCTAVE} ${octave_opt} /dev/null 2>&1 | sed -n '1p' | sed -n '/unrecognized/p'`
-      if test "x${octave_out}" = x; then :
-
-         { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-         OCTAVE="${OCTAVE} ${octave_opt}"
-
+  if test "x$ac_pt_PKG_CONFIG" = x; then
+    PKG_CONFIG=""
+  else
+    case $cross_compiling:$ac_tool_warned in
+yes:)
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+    PKG_CONFIG=$ac_pt_PKG_CONFIG
+  fi
 else
-
-         { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-
+  PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
 fi
-   done
-fi
-
-
-
-
-
 
 
 #----------------------------------------------------------------
-# Look for Scilab
+# Look for Android
 #----------------------------------------------------------------
 
 
-# Check whether --with-scilab was given.
-if test "${with_scilab+set}" = set; then :
-  withval=$with_scilab; SCILABBIN="$withval"
-else
-  SCILABBIN="$alllang_default"
+# Check whether --with-android was given.
+if test ${with_android+y}
+then :
+  withval=$with_android; ANDROIDBIN="$withval"
+else $as_nop
+  ANDROIDBIN="$alllang_default"
 fi
 
 
-# Check whether --with-scilab-inc was given.
-if test "${with_scilab_inc+set}" = set; then :
-  withval=$with_scilab_inc; SCILABINCDIR="$withval"
-else
-  SCILABINCDIR=""
+# Check whether --with-adb was given.
+if test ${with_adb+y}
+then :
+  withval=$with_adb; ADBBIN="$withval"
+else $as_nop
+  ADBBIN=
 fi
 
 
-# First, check for "--without-scilab" or "--with-scilab=no".
-if test x"${SCILABBIN}" = xno; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: Disabling Scilab" >&5
-$as_echo "$as_me: Disabling Scilab" >&6;}
-  SCILAB=
+# Check whether --with-ant was given.
+if test ${with_ant+y}
+then :
+  withval=$with_ant; ANTBIN="$withval"
+else $as_nop
+  ANTBIN=
+fi
+
+
+# Check whether --with-ndk-build was given.
+if test ${with_ndk_build+y}
+then :
+  withval=$with_ndk_build; NDKBUILDBIN="$withval"
+else $as_nop
+  NDKBUILDBIN=
+fi
+
+
+# First, check for "--without-android" or "--with-android=no".
+if test x"${ANDROIDBIN}" = xno; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Disabling Android" >&5
+printf "%s\n" "$as_me: Disabling Android" >&6;}
+  ANDROID=
 else
-  # Check for Scilab executable
-  if test "x$SCILABBIN" = xyes; then
-    for ac_prog in scilab
+  if test "x$ANDROIDBIN" = xyes; then
+    for ac_prog in android
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_SCILAB+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$SCILAB"; then
-  ac_cv_prog_SCILAB="$SCILAB" # Let the user override the test.
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ANDROID+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ANDROID"; then
+  ac_cv_prog_ANDROID="$ANDROID" # Let the user override the test.
 else
 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_SCILAB="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ANDROID="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -8250,91 +10063,843 @@
 
 fi
 fi
-SCILAB=$ac_cv_prog_SCILAB
-if test -n "$SCILAB"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SCILAB" >&5
-$as_echo "$SCILAB" >&6; }
+ANDROID=$ac_cv_prog_ANDROID
+if test -n "$ANDROID"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ANDROID" >&5
+printf "%s\n" "$ANDROID" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
-  test -n "$SCILAB" && break
+  test -n "$ANDROID" && break
 done
 
   else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for scilab" >&5
-$as_echo_n "checking for scilab... " >&6; }
-    if test -f "$SCILABBIN"; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SCILABBIN" >&5
-$as_echo "$SCILABBIN" >&6; }
-      SCILAB="$SCILABBIN"
-    else
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
-    fi
+    ANDROID="$ANDROIDBIN"
   fi
 
-  if test -n "$SCILAB"; then
-    # Check for Scilab version (needs api_scilab so needs version 5.3.3 or higher)
-    SCILAB_FULL_VERSION=`$SCILAB -version | head -1 | sed -e 's|Scilab version \"\(.*\)\"|\1|g'`
+  if test -z "$ADBBIN"; then
+    for ac_prog in adb
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ADB+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ADB"; then
+  ac_cv_prog_ADB="$ADB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ADB="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
 
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking Scilab version is 5.3.3 or higher" >&5
-$as_echo_n "checking Scilab version is 5.3.3 or higher... " >&6; }
-    SCILAB_MAJOR_VERSION=`echo $SCILAB_FULL_VERSION | cut -d. -f1`
-    SCILAB_MINOR_VERSION=`echo $SCILAB_FULL_VERSION | cut -d. -f2`
-    SCILAB_MAINTENANCE_VERSION=`echo $SCILAB_FULL_VERSION | cut -d. -f3`
-    SCILAB_VERSION="$SCILAB_MAJOR_VERSION$SCILAB_MINOR_VERSION$SCILAB_MAINTENANCE_VERSION"
+fi
+fi
+ADB=$ac_cv_prog_ADB
+if test -n "$ADB"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ADB" >&5
+printf "%s\n" "$ADB" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
 
-    if test $SCILAB_VERSION -ge 533; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-    else
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-      SCILAB=
-    fi
 
-    if test -n "$SCILAB"; then
-      # Set Scilab startup options depending on version
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Scilab startup options" >&5
-$as_echo_n "checking for Scilab startup options... " >&6; }
-      SCILABOPT="-nwni -nb"
-      if test $SCILAB_VERSION -ge 540; then
-        SCILABOPT+=" -noatomsautoload"
-      fi
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SCILABOPT" >&5
-$as_echo "$SCILABOPT" >&6; }
+  test -n "$ADB" && break
+done
 
-      # Check for Scilab header files
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Scilab header files" >&5
-$as_echo_n "checking for Scilab header files... " >&6; }
-      if test "$SCILABINCDIR" != ""; then
-        dirs="$SCILABINCDIR"
-      elif test -n "$PKGCONFIG"; then
-        dirs=`$PKGCONFIG scilab --cflags-only-I | sed -e 's/-I//g'`
+  else
+    ADB="$ADBBIN"
+  fi
+
+  if test -z "$ANTBIN"; then
+    for ac_prog in ant
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_ANT+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$ANT"; then
+  ac_cv_prog_ANT="$ANT" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ANT="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+ANT=$ac_cv_prog_ANT
+if test -n "$ANT"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ANT" >&5
+printf "%s\n" "$ANT" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$ANT" && break
+done
+
+  else
+    ANT="$ANTBIN"
+  fi
+
+  if test -z "$NDKBUILDBIN"; then
+    for ac_prog in ndk-build
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_NDKBUILD+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$NDKBUILD"; then
+  ac_cv_prog_NDKBUILD="$NDKBUILD" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_NDKBUILD="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+NDKBUILD=$ac_cv_prog_NDKBUILD
+if test -n "$NDKBUILD"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NDKBUILD" >&5
+printf "%s\n" "$NDKBUILD" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$NDKBUILD" && break
+done
+
+  else
+    NDKBUILD="$NDKBUILDBIN"
+  fi
+fi
+
+
+
+
+
+
+#----------------------------------------------------------------
+# Look for C#
+#----------------------------------------------------------------
+
+
+# Check whether --with-csharp was given.
+if test ${with_csharp+y}
+then :
+  withval=$with_csharp; with_csharp="$withval"
+else $as_nop
+  with_csharp="$alllang_default"
+fi
+
+
+# Check whether --with-cil-interpreter was given.
+if test ${with_cil_interpreter+y}
+then :
+  withval=$with_cil_interpreter; CSHARPBIN="$withval"
+else $as_nop
+  CSHARPBIN=
+fi
+
+
+# Check whether --with-csharp-compiler was given.
+if test ${with_csharp_compiler+y}
+then :
+  withval=$with_csharp_compiler; CSHARPCOMPILERBIN="$withval"
+else $as_nop
+  CSHARPCOMPILERBIN=
+fi
+
+
+# First, check for "--without-csharp" or "--with-csharp=no".
+if test x"${with_csharp}" = xno; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: Disabling CSharp" >&5
+printf "%s\n" "$as_me: Disabling CSharp" >&6;}
+CSHARPCOMPILER=
+else
+
+if test -z "$CSHARPCOMPILERBIN" ; then
+  case $host in
+  *-*-cygwin* | *-*-mingw*)
+    # prefer unified Mono mcs compiler (not to be confused with the ancient .NET 1 mcs) over older/alternative names.
+    for ac_prog in csc mcs mono-csc gmcs cscc
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CSHARPCOMPILER+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CSHARPCOMPILER"; then
+  ac_cv_prog_CSHARPCOMPILER="$CSHARPCOMPILER" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CSHARPCOMPILER="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CSHARPCOMPILER=$ac_cv_prog_CSHARPCOMPILER
+if test -n "$CSHARPCOMPILER"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CSHARPCOMPILER" >&5
+printf "%s\n" "$CSHARPCOMPILER" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$CSHARPCOMPILER" && break
+done
+
+    if test -n "$CSHARPCOMPILER" && test "$CSHARPCOMPILER" = "csc" ; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether csc is the Microsoft CSharp compiler" >&5
+printf %s "checking whether csc is the Microsoft CSharp compiler... " >&6; }
+      csc 2>/dev/null | grep "C#" > /dev/null || CSHARPCOMPILER=""
+      if test -z "$CSHARPCOMPILER" ; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+        for ac_prog in mcs mono-csc gmcs cscc
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CSHARPCOMPILER+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CSHARPCOMPILER"; then
+  ac_cv_prog_CSHARPCOMPILER="$CSHARPCOMPILER" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CSHARPCOMPILER="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CSHARPCOMPILER=$ac_cv_prog_CSHARPCOMPILER
+if test -n "$CSHARPCOMPILER"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CSHARPCOMPILER" >&5
+printf "%s\n" "$CSHARPCOMPILER" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$CSHARPCOMPILER" && break
+done
+
       else
-        dirs=""
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
       fi
-      for i in $dirs; do
-        if test -r $i/api_scilab.h; then
-          { $as_echo "$as_me:${as_lineno-$LINENO}: result: $i" >&5
-$as_echo "$i" >&6; }
-          SCILABINCLUDE="-I$i"
-          break
+    fi
+    ;;
+  *)for ac_prog in mono-csc gmcs mcs cscc
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CSHARPCOMPILER+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CSHARPCOMPILER"; then
+  ac_cv_prog_CSHARPCOMPILER="$CSHARPCOMPILER" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CSHARPCOMPILER="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CSHARPCOMPILER=$ac_cv_prog_CSHARPCOMPILER
+if test -n "$CSHARPCOMPILER"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CSHARPCOMPILER" >&5
+printf "%s\n" "$CSHARPCOMPILER" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$CSHARPCOMPILER" && break
+done
+;;
+  esac
+else
+  CSHARPCOMPILER="$CSHARPCOMPILERBIN"
+fi
+
+CSHARPCONVERTPATH="Tools/convertpath -u"
+if test -z "$CSHARPBIN" ; then
+  CSHARPCILINTERPRETER=""
+  CSHARPCILINTERPRETER_FLAGS=""
+  if test "cscc" = "$CSHARPCOMPILER" ; then
+    for ac_prog in ilrun
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CSHARPCILINTERPRETER+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CSHARPCILINTERPRETER"; then
+  ac_cv_prog_CSHARPCILINTERPRETER="$CSHARPCILINTERPRETER" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CSHARPCILINTERPRETER="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CSHARPCILINTERPRETER=$ac_cv_prog_CSHARPCILINTERPRETER
+if test -n "$CSHARPCILINTERPRETER"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CSHARPCILINTERPRETER" >&5
+printf "%s\n" "$CSHARPCILINTERPRETER" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$CSHARPCILINTERPRETER" && break
+done
+
+  else
+    if test "mcs" = "$CSHARPCOMPILER"; then
+      # Check that mcs is the C# compiler and not the Unix mcs utility by examining the output of 'mcs --version'
+      # The Mono compiler should emit: Mono C# compiler version a.b.c.d
+      csharp_version_raw=`(mcs --version) 2>/dev/null`
+      csharp_version_searched=`(mcs --version | sed -e "/C#/b" -e "/Mono/b" -e d) 2>/dev/null` # return string if contains 'Mono' or 'C#'
+      CSHARPCOMPILER=""
+      if test -n "$csharp_version_raw" ; then
+        if test "$csharp_version_raw" = "$csharp_version_searched" ; then
+          CSHARPCOMPILER="mcs"
         fi
-        if test -r $i/scilab/api_scilab.h; then
-          { $as_echo "$as_me:${as_lineno-$LINENO}: result: $i/scilab" >&5
-$as_echo "$i/scilab" >&6; }
-          SCILABINCLUDE="-I$i/scilab"
-          break
+      fi
+      if test "mcs" != "$CSHARPCOMPILER" ; then
+        echo "mcs is not a working Mono C# compiler"
+      fi
+    fi
+    if test "mcs" = "$CSHARPCOMPILER" || test "gmcs" = "$CSHARPCOMPILER" || test "mono-csc" = "$CSHARPCOMPILER"; then
+        for ac_prog in mono
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CSHARPCILINTERPRETER+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CSHARPCILINTERPRETER"; then
+  ac_cv_prog_CSHARPCILINTERPRETER="$CSHARPCILINTERPRETER" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CSHARPCILINTERPRETER="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CSHARPCILINTERPRETER=$ac_cv_prog_CSHARPCILINTERPRETER
+if test -n "$CSHARPCILINTERPRETER"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CSHARPCILINTERPRETER" >&5
+printf "%s\n" "$CSHARPCILINTERPRETER" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$CSHARPCILINTERPRETER" && break
+done
+ # Mono JIT
+        CSHARPCILINTERPRETER_FLAGS="--debug"
+    else
+      if test "csc" = "$CSHARPCOMPILER"; then
+          CSHARPCONVERTPATH="Tools/convertpath -w"
+      fi
+    fi
+  fi
+else
+  CSHARPCILINTERPRETER="$CSHARPBIN"
+fi
+
+# Cygwin requires the Windows standard (Pascal) calling convention as it is a Windows executable and not a Cygwin built executable
+case $host in
+*-*-cygwin* | *-*-mingw*)
+    if test "$GCC" = yes; then
+        CSHARPDYNAMICLINKING="$GCC_MNO_CYGWIN -mthreads -Wl,--add-stdcall-alias"
+        CSHARPCFLAGS="$GCC_MNO_CYGWIN -mthreads"
+    else
+        CSHARPDYNAMICLINKING=""
+        CSHARPCFLAGS=""
+    fi ;;
+*)
+        CSHARPDYNAMICLINKING=""
+        CSHARPCFLAGS=""
+        ;;
+esac
+
+# CSharp on Windows platforms including Cygwin doesn't use libname.dll, rather name.dll when loading dlls
+case $host in
+*-*-cygwin* | *-*-mingw*) CSHARPLIBRARYPREFIX="";;
+*)CSHARPLIBRARYPREFIX="lib";;
+esac
+
+# C#/Mono on Mac OS X tweaks
+case $host in
+*-*-darwin*)
+    CSHARPSO=".so"
+    ;;
+*)
+    CSHARPSO=$SO
+    ;;
+esac
+fi
+
+
+
+
+
+
+
+
+
+
+#----------------------------------------------------------------
+# Look for D
+#----------------------------------------------------------------
+
+
+# Check whether --with-d was given.
+if test ${with_d+y}
+then :
+  withval=$with_d; with_d="$withval"
+else $as_nop
+  with_d="$alllang_default"
+fi
+
+
+# Check whether --with-d2-compiler was given.
+if test ${with_d2_compiler+y}
+then :
+  withval=$with_d2_compiler; D2COMPILERBIN="$withval"
+else $as_nop
+  D2COMPILERBIN=
+fi
+
+
+
+# First, check for "--without-d" or "--with-d=no".
+if test x"${with_d}" = xno; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Disabling D" >&5
+printf "%s\n" "$as_me: Disabling D" >&6;}
+  D2COMPILER=
+else
+
+  if test -z "$D2COMPILERBIN" ; then
+    for ac_prog in dmd ldmd2 ldc2 gdmd
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_D2COMPILER+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$D2COMPILER"; then
+  ac_cv_prog_D2COMPILER="$D2COMPILER" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_D2COMPILER="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+D2COMPILER=$ac_cv_prog_D2COMPILER
+if test -n "$D2COMPILER"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $D2COMPILER" >&5
+printf "%s\n" "$D2COMPILER" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$D2COMPILER" && break
+done
+
+    if test -n "$D2COMPILER" ; then
+      old_ac_ext=$ac_ext
+      ac_ext=d
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the D2 compiler works" >&5
+printf %s "checking whether the D2 compiler works... " >&6; }
+      cat > conftest.$ac_ext <<_ACEOF
+import std.algorithm;
+void main() {
+}
+_ACEOF
+      rm -f conftest.out
+      if $D2COMPILER conftest.$ac_ext -ofconftest.out 2>&5 && test ! -s conftest.err && test -s conftest.out
+then :
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+else $as_nop
+  printf "%s\n" "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+ { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+        D2COMPILER=
+
+fi
+      rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext conftest.out
+      ac_ext=$old_ac_ext
+    fi
+  else
+    D2COMPILER="$D2COMPILERBIN"
+  fi
+fi
+
+# Do not prefix library file names with "lib" on Windows.
+case $host in
+*-*-cygwin* | *-*-mingw*) DLIBPREFIX="";;
+*)DLIBPREFIX="lib";;
+esac
+
+
+
+
+#----------------------------------------------------------------
+# Look for Go compilers
+#----------------------------------------------------------------
+
+
+# Check whether --with-go was given.
+if test ${with_go+y}
+then :
+  withval=$with_go; GOBIN="$withval"
+else $as_nop
+  GOBIN="$alllang_default"
+fi
+
+
+if test x"${GOBIN}" = xno; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Disabling Go" >&5
+printf "%s\n" "$as_me: Disabling Go" >&6;}
+  GO=
+  GOGCC=false
+  GCCGO=
+  GOOPT=
+  GCCGOOPT=
+  GOVERSIONOPTION=
+else
+
+  if test "x$GOBIN" = xyes; then
+    for ac_prog in go
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_GO+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$GO"; then
+  ac_cv_prog_GO="$GO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_GO="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+GO=$ac_cv_prog_GO
+if test -n "$GO"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $GO" >&5
+printf "%s\n" "$GO" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$GO" && break
+done
+
+  else
+    GO="$GOBIN"
+  fi
+
+  GOGCC=false
+  GCCGO=
+  GOOPT=
+  GCCGOOPT=
+  GOVERSIONOPTION=
+
+  if test -n "$GO" ; then
+    GOVERSIONOPTION=version
+    go_version=$($GO $GOVERSIONOPTION | sed -e 's/go version //')
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether go version is too old" >&5
+printf %s "checking whether go version is too old... " >&6; }
+    case $go_version in
+    go1.012*)
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes - minimum version is 1.3" >&5
+printf "%s\n" "yes - minimum version is 1.3" >&6; }
+      GO=
+      ;;
+    *)
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+      ;;
+    esac
+  fi
+
+  for ac_prog in gccgo
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_GCCGO+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$GCCGO"; then
+  ac_cv_prog_GCCGO="$GCCGO" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_GCCGO="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+GCCGO=$ac_cv_prog_GCCGO
+if test -n "$GCCGO"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $GCCGO" >&5
+printf "%s\n" "$GCCGO" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$GCCGO" && break
+done
+
+
+  if test -n "$GCCGO" ; then
+    if $GCCGO --help 2>/dev/null | grep gccgo >/dev/null 2>&1 ; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether gccgo version is too old" >&5
+printf %s "checking whether gccgo version is too old... " >&6; }
+      go_version=`$GO $GOVERSIONOPTION | sed -n '1p' | sed -e 's/^.* \([0-9.]*\) *$/\1/' -e 's/[.]//g'`
+      if test "x$go_version" = x; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: could not determine gccgo version" >&5
+printf "%s\n" "could not determine gccgo version" >&6; }
+        GCCGO=
+      elif test "$go_version" -lt 470; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes - minimum version is 4.7.0" >&5
+printf "%s\n" "yes - minimum version is 4.7.0" >&6; }
+        GCCGO=
+      else
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+        if test "$go_version" -lt 480; then
+          GCCGOOPT="-intgosize 32"
         fi
-      done
-      if test "$SCILABINCLUDE" = "" ; then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
-        SCILAB=
       fi
     fi
   fi
@@ -8345,31 +10910,262 @@
 
 
 
+
+
+
+
+
+
+
+#----------------------------------------------------------------
+# Look for Guile
+#----------------------------------------------------------------
+
+GUILE=
+GUILE_CFLAGS=
+GUILE_LIBS=
+
+
+# Check whether --with-guile-config was given.
+if test ${with_guile_config+y}
+then :
+  withval=$with_guile_config;  GUILE_CONFIG="$withval"
+else $as_nop
+  GUILE_CONFIG=
+fi
+
+
+# Check whether --with-guile was given.
+if test ${with_guile+y}
+then :
+  withval=$with_guile;
+	GUILE="$withval"
+else $as_nop
+  GUILE="$alllang_default"
+fi
+
+
+# Check whether --with-guile-cflags was given.
+if test ${with_guile_cflags+y}
+then :
+  withval=$with_guile_cflags;
+	GUILE_CFLAGS="$withval"
+fi
+
+
+# Check whether --with-guile-libs was given.
+if test ${with_guile_libs+y}
+then :
+  withval=$with_guile_libs;
+	GUILE_LIBS="$withval"
+fi
+
+
+# First, check for "--without-guile" or "--with-guile=no".
+if test x"${GUILE}" = xno; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Disabling Guile" >&5
+printf "%s\n" "$as_me: Disabling Guile" >&6;}
+else
+  if test -z "$GUILE_CONFIG" ; then
+    # Extract the first word of "guile-config", so it can be a program name with args.
+set dummy guile-config; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_GUILE_CONFIG+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  case $GUILE_CONFIG in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GUILE_CONFIG="$GUILE_CONFIG" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_GUILE_CONFIG="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+GUILE_CONFIG=$ac_cv_path_GUILE_CONFIG
+if test -n "$GUILE_CONFIG"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $GUILE_CONFIG" >&5
+printf "%s\n" "$GUILE_CONFIG" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  fi
+  if test -n "$GUILE_CONFIG" ; then
+    if test x"$GUILE" = xyes; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for guile executable" >&5
+printf %s "checking for guile executable... " >&6; }
+      # Try extracting it via guile-config first. If it's defined there it's the most reliable result
+      GUILE="`$GUILE_CONFIG info guile 2>/dev/null`"
+      if test -n "$GUILE";  then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $GUILE" >&5
+printf "%s\n" "$GUILE" >&6; }
+      else
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found via guile-config - constructing path" >&5
+printf "%s\n" "not found via guile-config - constructing path" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for guile bindir" >&5
+printf %s "checking for guile bindir... " >&6; }
+        guile_bindir="`$GUILE_CONFIG info bindir`"
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $guile_bindir" >&5
+printf "%s\n" "$guile_bindir" >&6; }
+        GUILE="$guile_bindir/guile"
+      fi
+      if ! test -f "$GUILE" ; then
+        GUILE=
+        # Extract the first word of "guile", so it can be a program name with args.
+set dummy guile; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_GUILE+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  case $GUILE in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GUILE="$GUILE" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_GUILE="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+GUILE=$ac_cv_path_GUILE
+if test -n "$GUILE"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $GUILE" >&5
+printf "%s\n" "$GUILE" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+      fi
+      if test -z "$GUILE" ; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: no suitable guile executable found. Disabling Guile" >&5
+printf "%s\n" "$as_me: WARNING: no suitable guile executable found. Disabling Guile" >&2;}
+      fi
+    fi
+
+    if test -n "$GUILE" ; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for guile version" >&5
+printf %s "checking for guile version... " >&6; }
+      guile_version=`$GUILE -c '(display (effective-version))'`
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $guile_version" >&5
+printf "%s\n" "$guile_version" >&6; }
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for guile version >= 1.8" >&5
+printf %s "checking for guile version >= 1.8... " >&6; }
+      guile_good_version=`$GUILE -c '(if (>= (string->number (effective-version)) 1.8) (display "yes") (display "no"))'`
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $guile_good_version" >&5
+printf "%s\n" "$guile_good_version" >&6; }
+      if test x"$guile_good_version" != xyes ; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: at least guile version 1.8 is required. Disabling Guile" >&5
+printf "%s\n" "$as_me: WARNING: at least guile version 1.8 is required. Disabling Guile" >&2;}
+        GUILE=
+      fi
+    fi
+
+    if test -n "$GUILE" ; then
+      # Test if guile-config and guile versions match. They should.
+      gc_version="`$GUILE_CONFIG --version 2>&1 | sed '1 s/.* //;q'`"
+      g_version="`$GUILE --version | sed '1 s/.* //;q'`"
+      if test "$gc_version" != "$g_version"; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: different versions reported by $GUILE_CONFIG ($gc_version) and $GUILE ($g_version). Disabling Guile" >&5
+printf "%s\n" "$as_me: WARNING: different versions reported by $GUILE_CONFIG ($gc_version) and $GUILE ($g_version). Disabling Guile" >&2;}
+        GUILE=
+      fi
+    fi
+
+    if test -n "$GUILE" ; then
+      if test -z "$GUILE_CFLAGS" ; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for guile compile flags" >&5
+printf %s "checking for guile compile flags... " >&6; }
+        GUILE_CFLAGS="`$GUILE_CONFIG compile`" # Note that this can sometimes be empty
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $GUILE_CFLAGS" >&5
+printf "%s\n" "$GUILE_CFLAGS" >&6; }
+      fi
+
+      if test -z "$GUILE_LIBS" ; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for guile link flags" >&5
+printf %s "checking for guile link flags... " >&6; }
+        GUILE_LIBS="`$GUILE_CONFIG link`"
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $GUILE_LIBS" >&5
+printf "%s\n" "$GUILE_LIBS" >&6; }
+      fi
+    fi
+  fi
+fi
+
+
+
+
+
 #----------------------------------------------------------------
 # Look for java
 #----------------------------------------------------------------
 
 
 # Check whether --with-java was given.
-if test "${with_java+set}" = set; then :
+if test ${with_java+y}
+then :
   withval=$with_java; JAVABIN="$withval"
-else
+else $as_nop
   JAVABIN="$alllang_default"
 fi
 
 
 # Check whether --with-javac was given.
-if test "${with_javac+set}" = set; then :
+if test ${with_javac+y}
+then :
   withval=$with_javac; JAVACBIN="$withval"
-else
+else $as_nop
   JAVACBIN=
 fi
 
 
 # First, check for "--without-java" or "--with-java=no".
 if test x"${JAVABIN}" = xno; then
-{ $as_echo "$as_me:${as_lineno-$LINENO}: Disabling Java" >&5
-$as_echo "$as_me: Disabling Java" >&6;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: Disabling Java" >&5
+printf "%s\n" "$as_me: Disabling Java" >&6;}
 JAVA=
 else
 
@@ -8401,18 +11197,18 @@
     ;;
 esac
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for java JDK" >&5
-$as_echo_n "checking for java JDK... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for java JDK" >&5
+printf %s "checking for java JDK... " >&6; }
 if test -n "$JAVA_HOME"; then
         java_home_ok=1
   if test -z "$JAVABIN" -a ! -x "$JAVA_HOME/bin/java"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No java executable under JAVA_HOME." >&5
-$as_echo "$as_me: WARNING: No java executable under JAVA_HOME." >&2;}
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: No java executable under JAVA_HOME." >&5
+printf "%s\n" "$as_me: WARNING: No java executable under JAVA_HOME." >&2;}
     java_home_ok=0
   fi
   if test -z "$JAVACBIN" -a ! -x "$JAVA_HOME/bin/javac"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No javac executable under JAVA_HOME." >&5
-$as_echo "$as_me: WARNING: No javac executable under JAVA_HOME." >&2;}
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: No javac executable under JAVA_HOME." >&5
+printf "%s\n" "$as_me: WARNING: No javac executable under JAVA_HOME." >&2;}
     java_home_ok=0
   fi
 
@@ -8420,23 +11216,23 @@
     JAVA_HOME_INCDIR="$JAVA_HOME/include"
   fi
   if test -z "$JAVAINCDIR" -a ! -r "$JAVA_HOME_INCDIR/jni.h"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No java headers under JAVA_HOME (does it point to a JDK and not just JRE?)." >&5
-$as_echo "$as_me: WARNING: No java headers under JAVA_HOME (does it point to a JDK and not just JRE?)." >&2;}
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: No java headers under JAVA_HOME (does it point to a JDK and not just JRE?)." >&5
+printf "%s\n" "$as_me: WARNING: No java headers under JAVA_HOME (does it point to a JDK and not just JRE?)." >&2;}
     java_home_ok=0
   fi
   if test "$java_home_ok" = 1; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: found (in $JAVA_HOME)" >&5
-$as_echo "found (in $JAVA_HOME)" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found (in $JAVA_HOME)" >&5
+printf "%s\n" "found (in $JAVA_HOME)" >&6; }
   else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: JAVA_HOME ($JAVA_HOME) is defined but does not point to a complete JDK installation, ignoring it." >&5
-$as_echo "$as_me: WARNING: JAVA_HOME ($JAVA_HOME) is defined but does not point to a complete JDK installation, ignoring it." >&2;}
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: JAVA_HOME ($JAVA_HOME) is defined but does not point to a complete JDK installation, ignoring it." >&5
+printf "%s\n" "$as_me: WARNING: JAVA_HOME ($JAVA_HOME) is defined but does not point to a complete JDK installation, ignoring it." >&2;}
     JAVA_HOME=
   fi
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no (JAVA_HOME is not defined)" >&5
-$as_echo "no (JAVA_HOME is not defined)" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no (JAVA_HOME is not defined)" >&5
+printf "%s\n" "no (JAVA_HOME is not defined)" >&6; }
 fi
 
 if test "x$JAVABIN" = xyes; then
@@ -8447,11 +11243,12 @@
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_JAVA+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_JAVA+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$JAVA"; then
   ac_cv_prog_JAVA="$JAVA" # Let the user override the test.
 else
@@ -8459,11 +11256,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_JAVA="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -8474,11 +11275,11 @@
 fi
 JAVA=$ac_cv_prog_JAVA
 if test -n "$JAVA"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVA" >&5
-$as_echo "$JAVA" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $JAVA" >&5
+printf "%s\n" "$JAVA" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -8498,11 +11299,12 @@
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_JAVAC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_JAVAC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$JAVAC"; then
   ac_cv_prog_JAVAC="$JAVAC" # Let the user override the test.
 else
@@ -8510,11 +11312,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_JAVAC="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -8525,11 +11331,11 @@
 fi
 JAVAC=$ac_cv_prog_JAVAC
 if test -n "$JAVAC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVAC" >&5
-$as_echo "$JAVAC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $JAVAC" >&5
+printf "%s\n" "$JAVAC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -8541,13 +11347,44 @@
   JAVAC="$JAVACBIN"
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for java include file jni.h" >&5
-$as_echo_n "checking for java include file jni.h... " >&6; }
+# Check Java version: we require Java 9 or later for Doxygen tests.
+if test -n "$JAVAC"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if java version is 9 or greater" >&5
+printf %s "checking if java version is 9 or greater... " >&6; }
+    javac_version=`"$JAVAC" -version 2>&1`
+    java_version_num=`echo $javac_version | sed -n 's/^javac //p'`
+    if test -z "$java_version_num"; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unknown format for Java version returned by \"$JAVAC\" ($javac_version)" >&5
+printf "%s\n" "$as_me: WARNING: unknown format for Java version returned by \"$JAVAC\" ($javac_version)" >&2;}
+        JAVA_SKIP_DOXYGEN_TEST_CASES=1
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unknown" >&5
+printf "%s\n" "unknown" >&6; }
+    else
+                        case $java_version_num in
+            1.*)
+                JAVA_SKIP_DOXYGEN_TEST_CASES=1
+                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no, disabling Doxygen tests" >&5
+printf "%s\n" "no, disabling Doxygen tests" >&6; }
+                ;;
+
+            *)
+                { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+                ;;
+        esac
+    fi
+
+
+fi
+
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for java include file jni.h" >&5
+printf %s "checking for java include file jni.h... " >&6; }
 
 # Check whether --with-javaincl was given.
-if test "${with_javaincl+set}" = set; then :
+if test ${with_javaincl+y}
+then :
   withval=$with_javaincl; JAVAINCDIR="$withval"
-else
+else $as_nop
   JAVAINCDIR=
 fi
 
@@ -8583,52 +11420,40 @@
 fi
 
 if test "$JAVAINC" = "" ; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVAINC" >&5
-$as_echo "$JAVAINC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $JAVAINC" >&5
+printf "%s\n" "$JAVAINC" >&6; }
   # now look for <arch>/jni_md.h
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for java include file jni_md.h" >&5
-$as_echo_n "checking for java include file jni_md.h... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for java include file jni_md.h" >&5
+printf %s "checking for java include file jni_md.h... " >&6; }
   JAVAMDDIR=`find "$JAVAINCDIR" -follow -name jni_md.h -print`
   if test "$JAVAMDDIR" = "" ; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
   else
     JAVAMDDIR=-I\"`dirname "$JAVAMDDIR" | tail -1`\"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVAMDDIR" >&5
-$as_echo "$JAVAMDDIR" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $JAVAMDDIR" >&5
+printf "%s\n" "$JAVAMDDIR" >&6; }
     JAVAINC="${JAVAINC} ${JAVAMDDIR}"
   fi
 fi
 
 # Auto-detecting JAVA_HOME is not so easy, below will only work up to and including jdk8
 if test -z "$JAVA_HOME" && test -n "$JAVA_HOME_MAYBE" ; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for java jdk from jni include paths" >&5
-$as_echo_n "checking for java jdk from jni include paths... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for java jdk from jni include paths" >&5
+printf %s "checking for java jdk from jni include paths... " >&6; }
   if test -r "$JAVA_HOME_MAYBE/lib/tools.jar" ; then
     JAVA_HOME=$JAVA_HOME_MAYBE
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVA_HOME" >&5
-$as_echo "$JAVA_HOME" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $JAVA_HOME" >&5
+printf "%s\n" "$JAVA_HOME" >&6; }
   else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
   fi
 fi
 
-# Javadoc support required for the Java test-suite is available by default in jdk9+ and in tools.jar in earlier jdk versions
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for java tools.jar" >&5
-$as_echo_n "checking for java tools.jar... " >&6; }
-if test -n "$JAVA_HOME" && test -r "$JAVA_HOME/lib/tools.jar" ; then
-  JAVA_TOOLS_JAR="$JAVA_HOME/lib/tools.jar"
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JAVA_TOOLS_JAR" >&5
-$as_echo "$JAVA_TOOLS_JAR" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
-fi
-
 case $host in
 *-*-cygwin*)
         # TODO: Only use this flag if the compiler supports it, later versions of gcc no longer have it
@@ -8703,23 +11528,23 @@
 
 
 
-
 #----------------------------------------------------------------
 # Look for Javascript
 #----------------------------------------------------------------
 
 # Check whether --with-javascript was given.
-if test "${with_javascript+set}" = set; then :
+if test ${with_javascript+y}
+then :
   withval=$with_javascript; with_javascript="$withval"
-else
+else $as_nop
   with_javascript="$alllang_default"
 fi
 
 
 # First, check for "--without-javascript" or "--with-javascript=no".
 if test x"${with_javascript}" = xno; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: Disabling Javascript" >&5
-$as_echo "$as_me: Disabling Javascript" >&6;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Disabling Javascript" >&5
+printf "%s\n" "$as_me: Disabling Javascript" >&6;}
   JAVASCRIPT=
 else
   JAVASCRIPT=1
@@ -8746,15 +11571,16 @@
   # Look for Node.js which is the default Javascript engine
   #----------------------------------------------------------------
 
-  for ac_prog in nodejs node
+  for ac_prog in node nodejs
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_NODEJS+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_NODEJS+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$NODEJS"; then
   ac_cv_prog_NODEJS="$NODEJS" # Let the user override the test.
 else
@@ -8762,11 +11588,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_NODEJS="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -8777,11 +11607,11 @@
 fi
 NODEJS=$ac_cv_prog_NODEJS
 if test -n "$NODEJS"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NODEJS" >&5
-$as_echo "$NODEJS" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NODEJS" >&5
+printf "%s\n" "$NODEJS" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -8790,16 +11620,17 @@
 
 
   if test -n "$NODEJS"; then
-    # node-gyp is needed to run the test-suite/examples
+    # node-gyp needed to run the test-suite/examples
     for ac_prog in node-gyp
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_NODEGYP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_NODEGYP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$NODEGYP"; then
   ac_cv_prog_NODEGYP="$NODEGYP" # Let the user override the test.
 else
@@ -8807,11 +11638,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_NODEGYP="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -8822,11 +11657,11 @@
 fi
 NODEGYP=$ac_cv_prog_NODEGYP
 if test -n "$NODEGYP"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NODEGYP" >&5
-$as_echo "$NODEGYP" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NODEGYP" >&5
+printf "%s\n" "$NODEGYP" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -8836,84 +11671,158 @@
     if test -z "$NODEGYP"; then
       NODEJS=
     fi
+    for ac_prog in npm
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_NODENPM+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$NODENPM"; then
+  ac_cv_prog_NODENPM="$NODENPM" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_NODENPM="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+NODENPM=$ac_cv_prog_NODENPM
+if test -n "$NODENPM"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NODENPM" >&5
+printf "%s\n" "$NODENPM" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$NODENPM" && break
+done
+
+    JSNAPIENABLED=
+    if test -n "$NODENPM"; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Node-API (napi) header directory" >&5
+printf %s "checking for Node-API (napi) header directory... " >&6; }
+      NODENPM_PREFIX=$($NODENPM config get prefix)
+      if test -n "$NODENPM_PREFIX"; then
+        NODENAPI_DIR=$NODENPM_PREFIX/lib/node_modules/node-addon-api
+        if test -f "$NODENAPI_DIR/napi.h"; then
+          JSNAPIENABLED=1
+
+        fi
+      fi
+      if test -n "$JSNAPIENABLED"; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $NODENAPI_DIR" >&5
+printf "%s\n" "$NODENAPI_DIR" >&6; }
+      else
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
+      fi
+    fi
+
   fi
 
   #----------------------------------------------------------------
-  # Look for JavascriptCore (Webkit) settings (JSCOREINCDIR, JSCOREDYNAMICLINKING)
+  # Look for JavaScriptCore (Webkit) settings
   #----------------------------------------------------------------
 
   # check for include files
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for JavaScriptCore/JavaScript.h" >&5
-$as_echo_n "checking for JavaScriptCore/JavaScript.h... " >&6; }
 
 # Check whether --with-jscoreinc was given.
-if test "${with_jscoreinc+set}" = set; then :
+if test ${with_jscoreinc+y}
+then :
   withval=$with_jscoreinc; JSCOREINCDIR="$withval"
-else
+else $as_nop
   JSCOREINCDIR=
 fi
 
+  # check for JavaScriptCore/Webkit libraries
+
+# Check whether --with-jscorelib was given.
+if test ${with_jscorelib+y}
+then :
+  withval=$with_jscorelib; JSCORELIB="-L$withval"
+else $as_nop
+  JSCORELIB=
+fi
+
 
   JSCOREVERSION=
 
-  if test -z "$JSCOREINCDIR"; then
-    JSCOREINCDIR="/usr/include/ /usr/local/include/"
-
-    # Add in default directory for JavaScriptCore headers for Linux and Mac OS X
-    case $host in
-    *-*-linux*)
-      JSCOREINCDIR="/usr/include/webkit-1.0/ /usr/include/webkitgtk-1.0/ /usr/local/include/webkit-1.0/JavaScriptCore/ $JSCOREINCDIR"
-      ;;
-    *-*-darwin*)
-      JSCOREINCDIR="/System/Library/Frameworks/JavaScriptCore.framework/Headers/ $JSCOREINCDIR"
-      ;;
-    *)
-      ;;
-    esac
-  fi
-
-  for d in $JSCOREINCDIR ; do
-    if test -r "$d/JavaScriptCore/JavaScript.h" || test -r "$d/JavaScript.h" ; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $d" >&5
-$as_echo "$d" >&6; }
-      JSCOREINCDIR=$d
-      JSCOREINC=-I\"$d\"
-      break
+  if test -z "$JSCOREINCDIR" -a -n "$JSCORELIB"; then
+    as_fn_error $? "Either both or none of --with-jcoreinc --with-jscorelib should be specified" "$LINENO" 5
+  elif test -n "$JSCOREINCDIR" -a -z "$JSCORELIB"; then
+    as_fn_error $? "Either both or none of --with-jcoreinc --with-jscorelib should be specified" "$LINENO" 5
+  elif test -z "$JSCOREINCDIR" -a -z "$JSCORELIB"; then
+    if test -z "$JSCORELIB" -a -n "$PKG_CONFIG "; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for JavaScriptCore/Webkit" >&5
+printf %s "checking for JavaScriptCore/Webkit... " >&6; }
+      if $PKG_CONFIG  javascriptcoregtk-4.1 2>/dev/null ; then
+        JSCORELIB=`$PKG_CONFIG  --libs javascriptcoregtk-4.1`
+        JSCOREINC=`$PKG_CONFIG  --cflags-only-I javascriptcoregtk-4.1`
+        JSCOREVERSION=`$PKG_CONFIG  --modversion javascriptcoregtk-4.1`
+      elif $PKG_CONFIG  javascriptcoregtk-4.0 2>/dev/null ; then
+        JSCORELIB=`$PKG_CONFIG  --libs javascriptcoregtk-4.0`
+        JSCOREINC=`$PKG_CONFIG  --cflags-only-I javascriptcoregtk-4.0`
+        JSCOREVERSION=`$PKG_CONFIG  --modversion javascriptcoregtk-4.0`
+      elif $PKG_CONFIG  javascriptcoregtk-3.0 2>/dev/null ; then
+        JSCORELIB=`$PKG_CONFIG  --libs javascriptcoregtk-3.0`
+        JSCOREINC=`$PKG_CONFIG  --cflags-only-I javascriptcoregtk-3.0`
+        JSCOREVERSION=`$PKG_CONFIG  --modversion javascriptcoregtk-3.0`
+      elif $PKG_CONFIG  javascriptcoregtk-1.0 2>/dev/null ; then
+        JSCORELIB=`$PKG_CONFIG  --libs javascriptcoregtk-1.0`
+        JSCOREVERSION=`$PKG_CONFIG  --modversion javascriptcoregtk-1.0`
+      fi
+      if test -z "$JSCORELIB"; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
+        JSCENABLED=
+      else
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: version $JSCOREVERSION" >&5
+printf "%s\n" "version $JSCOREVERSION" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for JavaScriptCore/Webkit include flags" >&5
+printf %s "checking for JavaScriptCore/Webkit include flags... " >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $JSCOREINC" >&5
+printf "%s\n" "$JSCOREINC" >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for JavaScriptCore/Webkit link flags" >&5
+printf %s "checking for JavaScriptCore/Webkit link flags... " >&6; }
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $JSCORELIB" >&5
+printf "%s\n" "$JSCORELIB" >&6; }
+        JSCOREDYNAMICLINKING="$JSCORELIB"
+        JSCENABLED=1
+      fi
     fi
-  done
-
-  if test "$JSCOREINC" = "" ; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
-  fi
-
-  # check for JavaScriptCore/Webkit libraries
-
-# Check whether --with-jscorelib was given.
-if test "${with_jscorelib+set}" = set; then :
-  withval=$with_jscorelib; JSCORELIB="-L$withval"
-else
-  JSCORELIB=
-fi
-
-
-  if test -z "$JSCORELIB" -a -n "$PKGCONFIG"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for JavaScriptCore/Webkit library" >&5
-$as_echo_n "checking for JavaScriptCore/Webkit library... " >&6; }
-    if pkg-config javascriptcoregtk-1.0; then
-      JSCORELIB=`$PKGCONFIG --libs javascriptcoregtk-1.0`
-      JSCOREVERSION=`$PKGCONFIG --modversion javascriptcoregtk-1.0`
-    fi
-    if test -z "$JSCORELIB"; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
-      JSCENABLED=
-    else
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JSCORELIB" >&5
-$as_echo "$JSCORELIB" >&6; }
-      JSCOREDYNAMICLINKING="$JSCORELIB"
-      JSCENABLED=1
-    fi
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for JavaScriptCore/Webkit include flags" >&5
+printf %s "checking for JavaScriptCore/Webkit include flags... " >&6; }
+    JSCOREINC=-I\"$JSCOREINCDIR\"
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $JSCOREINC" >&5
+printf "%s\n" "$JSCOREINC" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for JavaScriptCore/Webkit link flags" >&5
+printf %s "checking for JavaScriptCore/Webkit link flags... " >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $JSCORELIB" >&5
+printf "%s\n" "$JSCORELIB" >&6; }
+    JSCOREDYNAMICLINKING="$JSCORELIB"
+    JSCENABLED=1
   fi
 
   #----------------------------------------------------------------
@@ -8921,13 +11830,14 @@
   #----------------------------------------------------------------
 
   # check for include files
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for V8 Javascript v8.h" >&5
-$as_echo_n "checking for V8 Javascript v8.h... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for V8 Javascript v8.h" >&5
+printf %s "checking for V8 Javascript v8.h... " >&6; }
 
 # Check whether --with-jsv8inc was given.
-if test "${with_jsv8inc+set}" = set; then :
+if test ${with_jsv8inc+y}
+then :
   withval=$with_jsv8inc; JSV8INCDIR="$withval"
-else
+else $as_nop
   JSV8INCDIR=
 fi
 
@@ -8956,21 +11866,22 @@
   done
 
   if test "$JSV8INC" = "" ; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
   else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JSV8INCDIR" >&5
-$as_echo "$JSV8INCDIR" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $JSV8INCDIR" >&5
+printf "%s\n" "$JSV8INCDIR" >&6; }
   fi
 
   # check for V8 library
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for V8 Javascript library" >&5
-$as_echo_n "checking for V8 Javascript library... " >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for V8 Javascript library" >&5
+printf %s "checking for V8 Javascript library... " >&6; }
 
 # Check whether --with-jsv8lib was given.
-if test "${with_jsv8lib+set}" = set; then :
+if test ${with_jsv8lib+y}
+then :
   withval=$with_jsv8lib; JSV8LIBDIR="$withval"
-else
+else $as_nop
   JSV8LIB=
 fi
 
@@ -8985,12 +11896,12 @@
   done
 
   if test "$JSV8LIB" = "" ; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
     JSV8ENABLED=
   else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $JSV8LIBDIR" >&5
-$as_echo "$JSV8LIBDIR" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $JSV8LIBDIR" >&5
+printf "%s\n" "$JSV8LIBDIR" >&6; }
     JSV8ENABLED=1
   fi
 
@@ -9026,309 +11937,86 @@
 
 
 #----------------------------------------------------------------
-# Look for Android
+# Look for Lua
 #----------------------------------------------------------------
 
+LUABIN=
+LUAINCLUDE=
+LUALIB=
+LUADYNAMICLOADLIB=
+LUAFLAGS=
+LUALINK=
+# note: if LUABIN is empty then lua tests will not be done
+# LUABIN will be cleared if certain dependencies cannot be found
 
-# Check whether --with-android was given.
-if test "${with_android+set}" = set; then :
-  withval=$with_android; ANDROIDBIN="$withval"
-else
-  ANDROIDBIN="$alllang_default"
+
+# Check whether --with-lua was given.
+if test ${with_lua+y}
+then :
+  withval=$with_lua;  LUABIN="$withval"
+else $as_nop
+  LUABIN="$alllang_default"
 fi
 
 
-# Check whether --with-adb was given.
-if test "${with_adb+set}" = set; then :
-  withval=$with_adb; ADBBIN="$withval"
-else
-  ADBBIN=
+# Check whether --with-luaincl was given.
+if test ${with_luaincl+y}
+then :
+  withval=$with_luaincl;
+	LUAINCLUDE="$withval"
+else $as_nop
+  LUAINCLUDE=
 fi
 
 
-# Check whether --with-ant was given.
-if test "${with_ant+set}" = set; then :
-  withval=$with_ant; ANTBIN="$withval"
-else
-  ANTBIN=
+# Check whether --with-lualib was given.
+if test ${with_lualib+y}
+then :
+  withval=$with_lualib;
+	LUALIB="$withval"
+else $as_nop
+  LUALIB=
 fi
 
 
-# Check whether --with-ndk-build was given.
-if test "${with_ndk_build+set}" = set; then :
-  withval=$with_ndk_build; NDKBUILDBIN="$withval"
+# First, check for "--without-lua" or "--with-lua=no".
+if test x"${LUABIN}" = xno; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: Disabling Lua" >&5
+printf "%s\n" "$as_me: Disabling Lua" >&6;}
 else
-  NDKBUILDBIN=
-fi
 
-
-# First, check for "--without-android" or "--with-android=no".
-if test x"${ANDROIDBIN}" = xno; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: Disabling Android" >&5
-$as_echo "$as_me: Disabling Android" >&6;}
-  ANDROID=
-else
-  if test "x$ANDROIDBIN" = xyes; then
-    for ac_prog in android
+# can we find lua?
+if test "x$LUABIN" = xyes; then
+   # We look for a versioned Lua binary first, as there can be
+   # multiple versions of Lua installed on some systems (like Debian).
+   for ac_prog in lua5.4 lua5.3 lua5.2 lua5.1 lua
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ANDROID+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ANDROID"; then
-  ac_cv_prog_ANDROID="$ANDROID" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ANDROID="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-ANDROID=$ac_cv_prog_ANDROID
-if test -n "$ANDROID"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ANDROID" >&5
-$as_echo "$ANDROID" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$ANDROID" && break
-done
-
-  else
-    ANDROID="$ANDROIDBIN"
-  fi
-
-  if test -z "$ADBBIN"; then
-    for ac_prog in adb
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ADB+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ADB"; then
-  ac_cv_prog_ADB="$ADB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ADB="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-ADB=$ac_cv_prog_ADB
-if test -n "$ADB"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ADB" >&5
-$as_echo "$ADB" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$ADB" && break
-done
-
-  else
-    ADB="$ADBBIN"
-  fi
-
-  if test -z "$ANTBIN"; then
-    for ac_prog in ant
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_ANT+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$ANT"; then
-  ac_cv_prog_ANT="$ANT" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_ANT="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-ANT=$ac_cv_prog_ANT
-if test -n "$ANT"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ANT" >&5
-$as_echo "$ANT" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$ANT" && break
-done
-
-  else
-    ANT="$ANTBIN"
-  fi
-
-  if test -z "$NDKBUILDBIN"; then
-    for ac_prog in ndk-build
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_NDKBUILD+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$NDKBUILD"; then
-  ac_cv_prog_NDKBUILD="$NDKBUILD" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_NDKBUILD="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-NDKBUILD=$ac_cv_prog_NDKBUILD
-if test -n "$NDKBUILD"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NDKBUILD" >&5
-$as_echo "$NDKBUILD" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$NDKBUILD" && break
-done
-
-  else
-    NDKBUILD="$NDKBUILDBIN"
-  fi
-fi
-
-
-
-
-
-
-#----------------------------------------------------------------
-# Look for Guile
-#----------------------------------------------------------------
-
-GUILE=
-GUILE_CFLAGS=
-GUILE_LIBS=
-
-
-# Check whether --with-guile-config was given.
-if test "${with_guile_config+set}" = set; then :
-  withval=$with_guile_config;  GUILE_CONFIG="$withval"
-else
-  GUILE_CONFIG=
-fi
-
-
-# Check whether --with-guile was given.
-if test "${with_guile+set}" = set; then :
-  withval=$with_guile;
-	GUILE="$withval"
-else
-  GUILE="$alllang_default"
-fi
-
-
-# Check whether --with-guile-cflags was given.
-if test "${with_guile_cflags+set}" = set; then :
-  withval=$with_guile_cflags;
-	GUILE_CFLAGS="$withval"
-fi
-
-
-# Check whether --with-guile-libs was given.
-if test "${with_guile_libs+set}" = set; then :
-  withval=$with_guile_libs;
-	GUILE_LIBS="$withval"
-fi
-
-
-# First, check for "--without-guile" or "--with-guile=no".
-if test x"${GUILE}" = xno; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: Disabling Guile" >&5
-$as_echo "$as_me: Disabling Guile" >&6;}
-else
-  if test -z "$GUILE_CONFIG" ; then
-    # Extract the first word of "guile-config", so it can be a program name with args.
-set dummy guile-config; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_GUILE_CONFIG+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  case $GUILE_CONFIG in
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_LUABIN+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  case $LUABIN in
   [\\/]* | ?:[\\/]*)
-  ac_cv_path_GUILE_CONFIG="$GUILE_CONFIG" # Let the user override the test with a path.
+  ac_cv_path_LUABIN="$LUABIN" # Let the user override the test with a path.
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_GUILE_CONFIG="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_LUABIN="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -9338,133 +12026,274 @@
   ;;
 esac
 fi
-GUILE_CONFIG=$ac_cv_path_GUILE_CONFIG
-if test -n "$GUILE_CONFIG"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GUILE_CONFIG" >&5
-$as_echo "$GUILE_CONFIG" >&6; }
+LUABIN=$ac_cv_path_LUABIN
+if test -n "$LUABIN"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $LUABIN" >&5
+printf "%s\n" "$LUABIN" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
+  test -n "$LUABIN" && break
+done
+
+fi
+
+# check version: we need Lua 5.x
+if test "$LUABIN"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking Lua version" >&5
+printf %s "checking Lua version... " >&6; }
+  LUA_VERSION=`$LUABIN -e 'print(string.match(_VERSION, "%d+[.]%d+"))'`
+  # For 5.0 and 5.1 header and libraries may be named using 50 or 51.
+  LUA_VERSION_NO_DOTS=
+  if test -n "$LUA_VERSION" ; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Lua $LUA_VERSION.x" >&5
+printf "%s\n" "Lua $LUA_VERSION.x" >&6; }
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+printf "%s\n" "failed" >&6; }
   fi
-  if test -n "$GUILE_CONFIG" ; then
-    if test x"$GUILE" = xyes; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for guile executable" >&5
-$as_echo_n "checking for guile executable... " >&6; }
-      # Try extracting it via guile-config first. If it's defined there it's the most reliable result
-      GUILE="`$GUILE_CONFIG info guile 2>/dev/null`"
-      if test -n "$GUILE";  then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GUILE" >&5
-$as_echo "$GUILE" >&6; }
-      else
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found via guile-config - constructing path" >&5
-$as_echo "not found via guile-config - constructing path" >&6; }
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for guile bindir" >&5
-$as_echo_n "checking for guile bindir... " >&6; }
-        guile_bindir="`$GUILE_CONFIG info bindir`"
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $guile_bindir" >&5
-$as_echo "$guile_bindir" >&6; }
-        GUILE="$guile_bindir/guile"
-      fi
-      if ! test -f "$GUILE" ; then
-        GUILE=
-        # Extract the first word of "guile", so it can be a program name with args.
-set dummy guile; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_GUILE+:} false; then :
-  $as_echo_n "(cached) " >&6
+  case $LUA_VERSION in
+    5.0) LUA_VERSION_NO_DOTS=50 ;;
+    5.1) LUA_VERSION_NO_DOTS=51 ;;
+    5.*) ;;
+    *)
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: Not Lua 5.x, SWIG does not support this version of Lua" >&5
+printf "%s\n" "$as_me: WARNING: Not Lua 5.x, SWIG does not support this version of Lua" >&2;}
+      LUABIN=""
+      ;;
+  esac
+fi
+
+if test "$LUABIN"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether Lua dynamic loading is enabled" >&5
+printf %s "checking whether Lua dynamic loading is enabled... " >&6; }
+  # using Lua to check Lua
+  # lua 5.0 & 5.1 have different fn names
+  if test "$LUA_VERSION" = "5.0"; then
+    LUADYNAMICLOADLIB=`$LUABIN -e '_,_,c=loadlib("no_such_lib","") if c~="absent" then print "1" end'`
+  else
+    LUADYNAMICLOADLIB=`$LUABIN -e '_,_,c=package.loadlib("no_such_lib","") if c~="absent" then print "1" end'`
+  fi
+
+  if test -z "$LUADYNAMICLOADLIB"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+  else
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+  fi
+
+  # look for the header files & set LUAFLAGS accordingly
+  # will clear LUABIN if not present
+  if test -n "$LUAINCLUDE"; then
+    as_ac_File=`printf "%s\n" "ac_cv_file_$LUAINCLUDE/lua.h" | $as_tr_sh`
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $LUAINCLUDE/lua.h" >&5
+printf %s "checking for $LUAINCLUDE/lua.h... " >&6; }
+if eval test \${$as_ac_File+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  test "$cross_compiling" = yes &&
+  as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
+if test -r "$LUAINCLUDE/lua.h"; then
+  eval "$as_ac_File=yes"
 else
-  case $GUILE in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_GUILE="$GUILE" # Let the user override the test with a path.
-  ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
+  eval "$as_ac_File=no"
+fi
+fi
+eval ac_res=\$$as_ac_File
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_File"\" = x"yes"
+then :
+  LUAFLAGS="-I$LUAINCLUDE"
+else $as_nop
+  LUABIN=
+fi
+
+  else
+    LUA_OK="1"
+    CFLAGS_SAVED=$CFLAGS
+    CFLAGS= # Use empty CFLAGS to avoid failure: "present but cannot be compiled"
+    ac_header= ac_cache=
+for ac_item in $ac_header_c_list
 do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_GUILE="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
+  if test $ac_cache; then
+    ac_fn_c_check_header_compile "$LINENO" $ac_header ac_cv_header_$ac_cache "$ac_includes_default"
+    if eval test \"x\$ac_cv_header_$ac_cache\" = xyes; then
+      printf "%s\n" "#define $ac_item 1" >> confdefs.h
+    fi
+    ac_header= ac_cache=
+  elif test $ac_header; then
+    ac_cache=$ac_item
+  else
+    ac_header=$ac_item
   fi
 done
-  done
-IFS=$as_save_IFS
 
-  ;;
-esac
+
+
+
+
+
+
+
+if test $ac_cv_header_stdlib_h = yes && test $ac_cv_header_string_h = yes
+then :
+
+printf "%s\n" "#define STDC_HEADERS 1" >>confdefs.h
+
 fi
-GUILE=$ac_cv_path_GUILE
-if test -n "$GUILE"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GUILE" >&5
-$as_echo "$GUILE" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+ac_fn_c_check_header_compile "$LINENO" "lua.h" "ac_cv_header_lua_h" "$ac_includes_default"
+if test "x$ac_cv_header_lua_h" = xyes
+then :
+  LUAFLAGS=""
+else $as_nop
+  LUA_OK=""
 fi
 
-
-      fi
-      if test -z "$GUILE" ; then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no suitable guile executable found. Disabling Guile" >&5
-$as_echo "$as_me: WARNING: no suitable guile executable found. Disabling Guile" >&2;}
-      fi
-    fi
-
-    if test -n "$GUILE" ; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for guile version" >&5
-$as_echo_n "checking for guile version... " >&6; }
-      guile_version=`$GUILE -c '(display (effective-version))'`
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $guile_version" >&5
-$as_echo "$guile_version" >&6; }
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for guile version >= 1.8" >&5
-$as_echo_n "checking for guile version >= 1.8... " >&6; }
-      guile_good_version=`$GUILE -c '(if (>= (string->number (effective-version)) 1.8) (display "yes") (display "no"))'`
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $guile_good_version" >&5
-$as_echo "$guile_good_version" >&6; }
-      if test x"$guile_good_version" != xyes ; then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: at least guile version 1.8 is required. Disabling Guile" >&5
-$as_echo "$as_me: WARNING: at least guile version 1.8 is required. Disabling Guile" >&2;}
-        GUILE=
-      fi
-    fi
-
-    if test -n "$GUILE" ; then
-      # Test if guile-config and guile versions match. They should.
-      gc_version="`$GUILE_CONFIG --version 2>&1 | sed '1 s/.* //;q'`"
-      g_version="`$GUILE --version | sed '1 s/.* //;q'`"
-      if test "$gc_version" != "$g_version"; then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: different versions reported by $GUILE_CONFIG ($gc_version) and $GUILE ($g_version). Disabling Guile" >&5
-$as_echo "$as_me: WARNING: different versions reported by $GUILE_CONFIG ($gc_version) and $GUILE ($g_version). Disabling Guile" >&2;}
-        GUILE=
-      fi
-    fi
-
-    if test -n "$GUILE" ; then
-      if test -z "$GUILE_CFLAGS" ; then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for guile compile flags" >&5
-$as_echo_n "checking for guile compile flags... " >&6; }
-        GUILE_CFLAGS="`$GUILE_CONFIG compile`" # Note that this can sometimes be empty
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GUILE_CFLAGS" >&5
-$as_echo "$GUILE_CFLAGS" >&6; }
-      fi
-
-      if test -z "$GUILE_LIBS" ; then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: checking for guile link flags" >&5
-$as_echo_n "checking for guile link flags... " >&6; }
-        GUILE_LIBS="`$GUILE_CONFIG link`"
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GUILE_LIBS" >&5
-$as_echo "$GUILE_LIBS" >&6; }
+    CFLAGS=$CFLAGS_SAVED
+    # if we didn't get it, going to have to look elsewhere (the hard way)
+    if test -z "$LUA_OK"; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for lua.h in other locations" >&5
+printf %s "checking for lua.h in other locations... " >&6; }
+      # note: Debian/Ubuntu seem to like /usr/include/lua5.1/lua.h
+      # The ordering of the include directories to search should match
+      # the ordering of libraries to search in the library test below.
+      inc=/usr/include
+      incloc=/usr/local/include
+      dirs="$inc/lua$LUA_VERSION"
+      test -z "$LUA_VERSION_NO_DOTS" || dirs="$dirs $inc/lua$LUA_VERSION_NO_DOTS"
+      dirs="$dirs $incloc/lua$LUA_VERSION"
+      test -z "$LUA_VERSION_NO_DOTS" || dirs="$dirs $incloc/lua$LUA_VERSION_NO_DOTS"
+      dirs="$dirs $incloc"
+      for i in $dirs; do
+        #echo "$i"
+        if test -r $i/lua.h; then
+          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $i/lua.h" >&5
+printf "%s\n" "$i/lua.h" >&6; }
+          LUAFLAGS="-I$i"
+          break
+        fi
+      done
+      if test -z "$LUAFLAGS"; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
+        LUABIN="" # clear the bin
       fi
     fi
   fi
+
+  # look for the library files & set LUALINK accordingly
+  # will clear LUABIN if not present
+  lua_save_LIBS=$LIBS # the code seems to disrupt LIBS, so saving
+
+  if test -n "$LUALIB"; then
+    as_ac_File=`printf "%s\n" "ac_cv_file_$LUALIB/liblua.a" | $as_tr_sh`
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $LUALIB/liblua.a" >&5
+printf %s "checking for $LUALIB/liblua.a... " >&6; }
+if eval test \${$as_ac_File+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  test "$cross_compiling" = yes &&
+  as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
+if test -r "$LUALIB/liblua.a"; then
+  eval "$as_ac_File=yes"
+else
+  eval "$as_ac_File=no"
 fi
+fi
+eval ac_res=\$$as_ac_File
+	       { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+printf "%s\n" "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_File"\" = x"yes"
+then :
+  LUALINK="-L$LUALIB -llua"
+else $as_nop
+  LUABIN=
+fi
+
+  else
+    libs="lua lua$LUA_VERSION"
+    test -z "$LUA_VERSION_NO_DOTS" || libs="$libs lua$LUA_VERSION_NO_DOTS"
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for library containing lua_close" >&5
+printf %s "checking for library containing lua_close... " >&6; }
+if test ${ac_cv_search_lua_close+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+char lua_close ();
+int
+main (void)
+{
+return lua_close ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' $libs
+do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"
+then :
+  ac_cv_search_lua_close=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam \
+    conftest$ac_exeext
+  if test ${ac_cv_search_lua_close+y}
+then :
+  break
+fi
+done
+if test ${ac_cv_search_lua_close+y}
+then :
+
+else $as_nop
+  ac_cv_search_lua_close=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_lua_close" >&5
+printf "%s\n" "$ac_cv_search_lua_close" >&6; }
+ac_res=$ac_cv_search_lua_close
+if test "$ac_res" != no
+then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+  LUALINK="-l$ac_lib"
+else $as_nop
+  LUABIN=
+fi
+
+  fi
+
+  # adding lualib for lua 5.0
+  if test "$LUA_VERSION" = "5.0"; then
+    LUALINK="$LUALINK -llualib"
+  fi
+  LUALINK="$LUALINK -pthread"
+
+  LIBS=$lua_save_LIBS	# restore LIBS
+fi
+
+fi # if not disabled
+
 
 
 
@@ -9476,35 +12305,38 @@
 
 
 # Check whether --with-mzscheme was given.
-if test "${with_mzscheme+set}" = set; then :
+if test ${with_mzscheme+y}
+then :
   withval=$with_mzscheme;  MZSCHEMEBIN="$withval"
-else
+else $as_nop
   MZSCHEMEBIN="$alllang_default"
 fi
 
 
 # Check whether --with-mzc was given.
-if test "${with_mzc+set}" = set; then :
+if test ${with_mzc+y}
+then :
   withval=$with_mzc;  MZCBIN="$withval"
-else
+else $as_nop
   MZCBIN=
 fi
 
 
 # First, check for "--without-mzscheme" or "--with-mzscheme=no".
 if test x"${MZSCHEMEBIN}" = xno; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: Disabling MzScheme" >&5
-$as_echo "$as_me: Disabling MzScheme" >&6;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Disabling MzScheme" >&5
+printf "%s\n" "$as_me: Disabling MzScheme" >&6;}
   MZC=
 else
   if test "x$MZSCHEMEBIN" = xyes; then
      # Extract the first word of "mzscheme", so it can be a program name with args.
 set dummy mzscheme; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_MZSCHEME+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_MZSCHEME+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   case $MZSCHEME in
   [\\/]* | ?:[\\/]*)
   ac_cv_path_MZSCHEME="$MZSCHEME" # Let the user override the test with a path.
@@ -9514,11 +12346,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_MZSCHEME="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_MZSCHEME="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -9530,11 +12366,11 @@
 fi
 MZSCHEME=$ac_cv_path_MZSCHEME
 if test -n "$MZSCHEME"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MZSCHEME" >&5
-$as_echo "$MZSCHEME" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MZSCHEME" >&5
+printf "%s\n" "$MZSCHEME" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -9545,11 +12381,12 @@
   if test -z "$MZCBIN"; then
      # Extract the first word of "mzc", so it can be a program name with args.
 set dummy mzc; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_MZC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_MZC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   case $MZC in
   [\\/]* | ?:[\\/]*)
   ac_cv_path_MZC="$MZC" # Let the user override the test with a path.
@@ -9559,11 +12396,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_MZC="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_MZC="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -9575,19 +12416,19 @@
 fi
 MZC=$ac_cv_path_MZC
 if test -n "$MZC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MZC" >&5
-$as_echo "$MZC" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MZC" >&5
+printf "%s\n" "$MZC" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
   fi
 
   if test -n "$MZSCHEME"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for MzScheme dynext object" >&5
-$as_echo_n "checking for MzScheme dynext object... " >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for MzScheme dynext object" >&5
+printf %s "checking for MzScheme dynext object... " >&6; }
     MZDYNOBJ=`$MZSCHEME --eval '(begin (require dynext/link) (with-handlers (((lambda args #t) (lambda args #f))) (for-each (lambda (x) (printf "~a" x)) (expand-for-link-variant (current-standard-link-libraries)))))' 2>/dev/null`
     if test -f "$MZDYNOBJ"; then
       :
@@ -9596,11 +12437,11 @@
       MZDYNOBJ=`$MZSCHEME --mute-banner --version --eval '(begin (require (lib "link.ss" "dynext")) (with-handlers (((lambda args #t) (lambda args #f))) (for-each (lambda (x) (display x) (display " ")) ((current-make-standard-link-libraries)))) (with-handlers (((lambda args #t) (lambda args #f))) (for-each (lambda (x) (display x)) (expand-for-link-variant (current-standard-link-libraries)))))' 2>/dev/null`
     fi
     if test -f "$MZDYNOBJ"; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MZDYNOBJ" >&5
-$as_echo "$MZDYNOBJ" >&6; }
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $MZDYNOBJ" >&5
+printf "%s\n" "$MZDYNOBJ" >&6; }
     else
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
       MZDYNOBJ=""
     fi
   fi
@@ -9608,6 +12449,1570 @@
 
 
 #----------------------------------------------------------------
+# Look for OCaml
+#----------------------------------------------------------------
+
+
+# Check whether --with-ocaml was given.
+if test ${with_ocaml+y}
+then :
+  withval=$with_ocaml; with_ocaml="$withval"
+else $as_nop
+  with_ocaml="$alllang_default"
+fi
+
+
+# Check whether --with-ocamlc was given.
+if test ${with_ocamlc+y}
+then :
+  withval=$with_ocamlc;  OCAMLC="$withval"
+else $as_nop
+  OCAMLC=
+fi
+
+
+# Check whether --with-ocamldlgen was given.
+if test ${with_ocamldlgen+y}
+then :
+  withval=$with_ocamldlgen;  OCAMLDLGEN="$withval"
+else $as_nop
+  OCAMLDLGEN=
+fi
+
+
+# Check whether --with-ocamlfind was given.
+if test ${with_ocamlfind+y}
+then :
+  withval=$with_ocamlfind; OCAMLFIND="$withval"
+else $as_nop
+  OCAMLFIND=
+fi
+
+
+# Check whether --with-ocamlmktop was given.
+if test ${with_ocamlmktop+y}
+then :
+  withval=$with_ocamlmktop;  OCAMLMKTOP="$withval"
+else $as_nop
+  OCAMLMKTOP=
+fi
+
+
+# Check whether --with-camlp4 was given.
+if test ${with_camlp4+y}
+then :
+  withval=$with_camlp4;  CAMLP4="$withval"
+else $as_nop
+  CAMLP4=
+fi
+
+
+# First, check for "--without-ocaml" or "--with-ocaml=no".
+if test x"${with_ocaml}" = xno; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Disabling OCaml" >&5
+printf "%s\n" "$as_me: Disabling OCaml" >&6;}
+    OCAMLC=
+else
+    # OCaml compiler
+    if test -z "$OCAMLC"; then
+	for ac_prog in ocamlc
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_OCAMLC+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$OCAMLC"; then
+  ac_cv_prog_OCAMLC="$OCAMLC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_OCAMLC="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OCAMLC=$ac_cv_prog_OCAMLC
+if test -n "$OCAMLC"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OCAMLC" >&5
+printf "%s\n" "$OCAMLC" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$OCAMLC" && break
+done
+
+    fi
+
+    # OCaml Pre-Processor-Pretty-Printer
+    if test -z "$CAMLP4"; then
+	for ac_prog in camlp4
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_CAMLP4+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$CAMLP4"; then
+  ac_cv_prog_CAMLP4="$CAMLP4" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CAMLP4="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+CAMLP4=$ac_cv_prog_CAMLP4
+if test -n "$CAMLP4"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CAMLP4" >&5
+printf "%s\n" "$CAMLP4" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$CAMLP4" && break
+done
+
+    fi
+
+    # OCaml DL load generator
+    if test -z "$OCAMLDLGEN"; then
+	for ac_prog in ocamldlgen
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_OCAMLDLGEN+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$OCAMLDLGEN"; then
+  ac_cv_prog_OCAMLDLGEN="$OCAMLDLGEN" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_OCAMLDLGEN="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OCAMLDLGEN=$ac_cv_prog_OCAMLDLGEN
+if test -n "$OCAMLDLGEN"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OCAMLDLGEN" >&5
+printf "%s\n" "$OCAMLDLGEN" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$OCAMLDLGEN" && break
+done
+
+    fi
+
+    # OCaml package tool
+    if test -z "$OCAMLFIND"; then
+	for ac_prog in ocamlfind
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_OCAMLFIND+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$OCAMLFIND"; then
+  ac_cv_prog_OCAMLFIND="$OCAMLFIND" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_OCAMLFIND="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OCAMLFIND=$ac_cv_prog_OCAMLFIND
+if test -n "$OCAMLFIND"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OCAMLFIND" >&5
+printf "%s\n" "$OCAMLFIND" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$OCAMLFIND" && break
+done
+
+    fi
+
+    # OCaml toplevel creator
+    if test -z "$OCAMLMKTOP"; then
+	for ac_prog in ocamlmktop
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_OCAMLMKTOP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$OCAMLMKTOP"; then
+  ac_cv_prog_OCAMLMKTOP="$OCAMLMKTOP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_OCAMLMKTOP="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+OCAMLMKTOP=$ac_cv_prog_OCAMLMKTOP
+if test -n "$OCAMLMKTOP"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OCAMLMKTOP" >&5
+printf "%s\n" "$OCAMLMKTOP" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$OCAMLMKTOP" && break
+done
+
+    fi
+fi
+
+
+
+
+
+
+
+#----------------------------------------------------------------
+# Look for Octave
+#----------------------------------------------------------------
+
+OCTAVEBIN=
+OCTAVE_SO=.oct
+
+
+# Check whether --with-octave was given.
+if test ${with_octave+y}
+then :
+  withval=$with_octave; OCTAVEBIN="$withval"
+else $as_nop
+  OCTAVEBIN="$alllang_default"
+fi
+
+
+# Check for "--without-octave" or "--with-octave=no".
+if test x"${OCTAVEBIN}" = xno; then
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Disabling Octave" >&5
+printf "%s\n" "$as_me: Disabling Octave" >&6;}
+   OCTAVE=
+
+# Check for Octave; prefer command-line program "octave-cli" to (in newer versions) GUI program "octave"
+elif test "x$OCTAVEBIN" = xyes; then
+   # Extract the first word of "octave-cli octave", so it can be a program name with args.
+set dummy octave-cli octave; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_OCTAVE+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  case $OCTAVE in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_OCTAVE="$OCTAVE" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_OCTAVE="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+OCTAVE=$ac_cv_path_OCTAVE
+if test -n "$OCTAVE"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OCTAVE" >&5
+printf "%s\n" "$OCTAVE" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+
+else
+   OCTAVE="$OCTAVEBIN"
+fi
+
+# Check if Octave works
+if test -n "$OCTAVE"; then
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if ${OCTAVE} works" >&5
+printf %s "checking if ${OCTAVE} works... " >&6; }
+   if test "x`${OCTAVE} --version 2>/dev/null | sed -n -e '1p' | sed -n -e '/Octave, version/p'`" != x
+then :
+
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+
+else $as_nop
+
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+      OCTAVE=
+
+fi
+fi
+
+# Check for required Octave helper program "mkoctfile"
+if test -n "$OCTAVE"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for mkoctfile" >&5
+printf %s "checking for mkoctfile... " >&6; }
+  version_suffix="`echo $OCTAVE | sed -e 's|.*\(-[0-9][0-9.]*\)$|\1|'`"
+  case $version_suffix in
+    -*) ;;
+    *) version_suffix="" ;;
+  esac
+  octave_directory=`dirname $OCTAVE`
+  if test "$octave_directory" = "." ; then
+    mkoctfile="mkoctfile${version_suffix}"
+  else
+    mkoctfile="${octave_directory}/mkoctfile${version_suffix}"
+  fi
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: ${mkoctfile}" >&5
+printf "%s\n" "${mkoctfile}" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if ${mkoctfile} works" >&5
+printf %s "checking if ${mkoctfile} works... " >&6; }
+  mkoctfile="env - PATH=$PATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH ${mkoctfile}"
+  if test "x`${mkoctfile} --version 2>/dev/null | sed -n -e '1p' | sed -n -e '/mkoctfile, version/p'`" != x
+then :
+
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+
+else $as_nop
+
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+      OCTAVE=
+
+fi
+fi
+
+# Check for Octave preprocessor/compiler/linker flags
+if test -n "$OCTAVE"; then
+
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Octave preprocessor flags" >&5
+printf %s "checking for Octave preprocessor flags... " >&6; }
+   OCTAVE_CPPFLAGS=
+   for var in CPPFLAGS INCFLAGS ALL_CXXFLAGS; do
+      for flag in `${mkoctfile} -p ${var}`; do
+         case ${flag} in
+            -D*|-I*) OCTAVE_CPPFLAGS="${OCTAVE_CPPFLAGS} ${flag}";;
+            *) ;;
+         esac
+      done
+   done
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OCTAVE_CPPFLAGS" >&5
+printf "%s\n" "$OCTAVE_CPPFLAGS" >&6; }
+
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Octave compiler flags" >&5
+printf %s "checking for Octave compiler flags... " >&6; }
+   OCTAVE_CXXFLAGS=
+   for var in CXX ALL_CXXFLAGS; do
+      for flag in `${mkoctfile} -p ${var}`; do
+         case ${flag} in
+            -std=*|-g*|-W*) OCTAVE_CXXFLAGS="${OCTAVE_CXXFLAGS} ${flag}";;
+            *) ;;
+         esac
+      done
+   done
+   save_CXXFLAGS="${CXXFLAGS}"
+   CXXFLAGS="-Werror -O0"
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+
+int
+main (void)
+{
+
+  ;
+  return 0;
+}
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"
+then :
+
+      OCTAVE_CXXFLAGS="${OCTAVE_CXXFLAGS} -O0"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
+   CXXFLAGS="${save_CXXFLAGS}"
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OCTAVE_CXXFLAGS" >&5
+printf "%s\n" "$OCTAVE_CXXFLAGS" >&6; }
+
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Octave linker flags" >&5
+printf %s "checking for Octave linker flags... " >&6; }
+   OCTAVE_LDFLAGS=
+   for var in OCTLIBDIR; do
+     OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "-L`${mkoctfile} -p ${var}`
+   done
+   for var in RDYNAMIC_FLAG RLD_FLAG OCTAVE_LIBS LIBS; do
+     # RLD_FLAG gives "mkoctfile: unknown variable 'RLD_FLAG'" on stderr
+     # with Octave 7.3 so just discard stderr here.  Apparently RLD_FLAG has
+     # reported an empty value since somewhere between 3.4.3 and 3.6.1 so
+     # can be removed below once we require Octave 4.
+     OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "`${mkoctfile} -p ${var} 2>/dev/null`
+   done
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $OCTAVE_LDFLAGS" >&5
+printf "%s\n" "$OCTAVE_LDFLAGS" >&6; }
+
+fi
+
+# Check for Octave options
+if test -n "$OCTAVE"; then
+   for octave_opt in --no-window-system --silent --norc --no-history; do
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if Octave option '${octave_opt}' is supported" >&5
+printf %s "checking if Octave option '${octave_opt}' is supported... " >&6; }
+      octave_out=`${OCTAVE} ${octave_opt} /dev/null 2>&1 | sed -n '1p' | sed -n '/unrecognized/p'`
+      if test "x${octave_out}" = x
+then :
+
+         { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+printf "%s\n" "yes" >&6; }
+         OCTAVE="${OCTAVE} ${octave_opt}"
+
+else $as_nop
+
+         { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+
+fi
+   done
+fi
+
+
+
+
+
+
+
+#----------------------------------------------------------------
+# Look for Perl5
+#----------------------------------------------------------------
+
+PERLBIN=
+
+
+# Check whether --with-perl5 was given.
+if test ${with_perl5+y}
+then :
+  withval=$with_perl5;  PERLBIN="$withval"
+else $as_nop
+  PERLBIN="$alllang_default"
+fi
+
+
+# First, check for "--without-perl5" or "--with-perl5=no".
+if test x"${PERLBIN}" = xno; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: Disabling Perl5" >&5
+printf "%s\n" "$as_me: Disabling Perl5" >&6;}
+PERL=
+else
+
+# First figure out what the name of Perl5 is
+
+if test "x$PERLBIN" = xyes; then
+for ac_prog in perl perl5
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_PERL+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$PERL"; then
+  ac_cv_prog_PERL="$PERL" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_PERL="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+PERL=$ac_cv_prog_PERL
+if test -n "$PERL"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PERL" >&5
+printf "%s\n" "$PERL" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$PERL" && break
+done
+
+else
+PERL="$PERLBIN"
+fi
+
+
+# This could probably be simplified as for all platforms and all versions of Perl the following apparently should be run to get the compilation options:
+# perl -MExtUtils::Embed -e ccopts
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Perl5 header files" >&5
+printf %s "checking for Perl5 header files... " >&6; }
+if test -n "$PERL"; then
+	PERL5DIR=`($PERL -MConfig -le 'print $Config{archlibexp}') 2>/dev/null`
+	if test -n "$PERL5DIR" ; then
+		dirs="$PERL5DIR $PERL5DIR/CORE"
+		PERL5EXT=none
+		for i in $dirs; do
+			if test -r $i/perl.h; then
+				{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $i" >&5
+printf "%s\n" "$i" >&6; }
+				PERL5EXT="$i"
+				break
+			fi
+		done
+		if test "$PERL5EXT" = none; then
+			PERL5EXT="$PERL5DIR/CORE"
+			{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: could not locate perl.h...using $PERL5EXT" >&5
+printf "%s\n" "could not locate perl.h...using $PERL5EXT" >&6; }
+		fi
+
+		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Perl5 library" >&5
+printf %s "checking for Perl5 library... " >&6; }
+		PERL5LIB=`($PERL -e 'use Config; $_=$Config{libperl}; s/^lib//; s/$Config{_a}$//; s/\.$Config{so}.*//; print $_, "\n"') 2>/dev/null`
+		if test -z "$PERL5LIB" ; then
+			{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
+		else
+			{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PERL5LIB" >&5
+printf "%s\n" "$PERL5LIB" >&6; }
+		fi
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Perl5 ccflags" >&5
+printf %s "checking for Perl5 ccflags... " >&6; }
+		PERL5CCFLAGS=`($PERL -e 'use Config; print $Config{ccflags}, "\n"' | sed "s/-Wdeclaration-after-statement//") 2>/dev/null`
+		if test -z "$PERL5CCFLAGS" ; then
+			{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
+		else
+			{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PERL5CCFLAGS" >&5
+printf "%s\n" "$PERL5CCFLAGS" >&6; }
+		fi
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Perl5 ccdlflags" >&5
+printf %s "checking for Perl5 ccdlflags... " >&6; }
+    PERL5CCDLFLAGS=`($PERL -e 'use Config; print $Config{ccdlflags}, "\n"') 2>/dev/null`
+    if test -z "$PERL5CCDLFLAGS" ; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
+      else
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PERL5CCDLFLAGS" >&5
+printf "%s\n" "$PERL5CCDLFLAGS" >&6; }
+    fi
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Perl5 cccdlflags" >&5
+printf %s "checking for Perl5 cccdlflags... " >&6; }
+    PERL5CCCDLFLAGS=`($PERL -e 'use Config; print $Config{cccdlflags}, "\n"') 2>/dev/null`
+    if test -z "$PERL5CCCDLFLAGS" ; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
+      else
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PERL5CCCDLFLAGS" >&5
+printf "%s\n" "$PERL5CCCDLFLAGS" >&6; }
+    fi
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Perl5 ldflags" >&5
+printf %s "checking for Perl5 ldflags... " >&6; }
+    PERL5LDFLAGS=`($PERL -e 'use Config; print $Config{ldflags}, "\n"') 2>/dev/null`
+    if test -z "$PERL5LDFLAGS" ; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
+      else
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PERL5LDFLAGS" >&5
+printf "%s\n" "$PERL5LDFLAGS" >&6; }
+    fi
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Perl5 Test::More module" >&5
+printf %s "checking for Perl5 Test::More module... " >&6; } # For test-suite
+    PERL5TESTMORE=`($PERL -e 'use Test::More; print "good";') 2>/dev/null`
+    if test -z "$PERL5TESTMORE" ; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
+      else
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found" >&5
+printf "%s\n" "found" >&6; }
+    fi
+	else
+		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unable to determine perl5 configuration" >&5
+printf "%s\n" "unable to determine perl5 configuration" >&6; }
+		PERL5EXT=$PERL5DIR
+	fi
+else
+	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: could not figure out how to run perl5" >&5
+printf "%s\n" "could not figure out how to run perl5" >&6; }
+fi
+
+# Cygwin (Windows) needs the library for dynamic linking
+case $host in
+*-*-cygwin* | *-*-mingw*) PERL5DYNAMICLINKING="-L$PERL5EXT -l$PERL5LIB";;
+*)PERL5DYNAMICLINKING="";;
+esac
+fi
+
+
+
+
+
+
+
+
+
+
+#-------------------------------------------------------------------------
+# Look for PHP
+#-------------------------------------------------------------------------
+
+PHPBIN=
+
+
+# Check whether --with-php was given.
+if test ${with_php+y}
+then :
+  withval=$with_php;  PHPBIN="$withval"
+else $as_nop
+  PHPBIN="$alllang_default"
+fi
+
+
+# First, check for "--without-php" or "--with-php=no".
+if test x"${PHPBIN}" = xno; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Disabling PHP" >&5
+printf "%s\n" "$as_me: Disabling PHP" >&6;}
+    PHP=
+else
+    if test "x$PHPBIN" = xyes; then
+      for ac_prog in php8.3 php8.2 php8.1 php8.0 php
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_PHP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$PHP"; then
+  ac_cv_prog_PHP="$PHP" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_PHP="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+PHP=$ac_cv_prog_PHP
+if test -n "$PHP"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PHP" >&5
+printf "%s\n" "$PHP" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$PHP" && break
+done
+
+    else
+      PHP=$PHPBIN
+    fi
+
+    if test -n "$PHP"; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for PHP header files" >&5
+printf %s "checking for PHP header files... " >&6; }
+            case $PHP in
+        *8.*)
+          PHPCONFIG=`echo "$PHP"|sed 's/8\...*$/-config&/'` ;;
+        *)
+          PHPCONFIG=$PHP-config ;;
+      esac
+      php_version=`$PHPCONFIG --version 2>/dev/null`
+      case $php_version in
+      8.*)
+        PHPINC=`$PHPCONFIG --includes 2>/dev/null`
+        if test -n "$PHPINC"; then
+          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PHPINC" >&5
+printf "%s\n" "$PHPINC" >&6; }
+        else
+          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
+        fi
+        ;;
+      "")
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: could not find $PHPCONFIG or obtain PHP version from it" >&5
+printf "%s\n" "could not find $PHPCONFIG or obtain PHP version from it" >&6; } ;;
+      *)
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found PHP $php_version - not PHP 8" >&5
+printf "%s\n" "found PHP $php_version - not PHP 8" >&6; } ;;
+      esac
+    fi
+fi
+
+
+
+#----------------------------------------------------------------
+# Look for Python
+#----------------------------------------------------------------
+
+PYINCLUDE=
+PYLIB=
+PYLINK=
+PYPACKAGE=
+
+
+# Check whether --with-python was given.
+if test ${with_python+y}
+then :
+  withval=$with_python; PYBIN="$withval"
+else $as_nop
+  PYBIN="$alllang_default"
+fi
+
+
+# First, check for "--without-python" or "--with-python=no".
+if test x"${PYBIN}" = xno; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Disabling Python 2.x probe" >&5
+printf "%s\n" "$as_me: Disabling Python 2.x probe" >&6;}
+else
+  # First figure out the name of the Python 2.x executable
+  if test "x$PYBIN" = xyes; then
+    for ac_prog in python python2.7
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_PYTHON+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$PYTHON"; then
+  ac_cv_prog_PYTHON="$PYTHON" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_PYTHON="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+PYTHON=$ac_cv_prog_PYTHON
+if test -n "$PYTHON"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5
+printf "%s\n" "$PYTHON" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$PYTHON" && break
+done
+
+  else
+    PYTHON="$PYBIN"
+  fi
+
+  PYVER=0
+  if test -n "$PYTHON"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $PYTHON major version number" >&5
+printf %s "checking for $PYTHON major version number... " >&6; }
+    PYVER=`($PYTHON -c "import sys; sys.stdout.write(sys.version[0])") 2>/dev/null`
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYVER" >&5
+printf "%s\n" "$PYVER" >&6; }
+    if test -z "$PYVER"; then
+      PYVER=0
+    else
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 2.x os.name" >&5
+printf %s "checking for Python 2.x os.name... " >&6; }
+      PYOSNAME=`($PYTHON -c "import sys, os; sys.stdout.write(os.name)") 2>/dev/null`
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYOSNAME" >&5
+printf "%s\n" "$PYOSNAME" >&6; }
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 2.x path separator" >&5
+printf %s "checking for Python 2.x path separator... " >&6; }
+      PYSEPARATOR=`($PYTHON -c "import sys, os; sys.stdout.write(os.sep)") 2>/dev/null`
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYSEPARATOR" >&5
+printf "%s\n" "$PYSEPARATOR" >&6; }
+    fi
+  fi
+
+  if test $PYVER -eq 1 -o $PYVER -eq 2; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 2.x prefix" >&5
+printf %s "checking for Python 2.x prefix... " >&6; }
+    PYPREFIX=`($PYTHON -c "import sys; sys.stdout.write(sys.prefix)") 2>/dev/null`
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYPREFIX" >&5
+printf "%s\n" "$PYPREFIX" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 2.x exec-prefix" >&5
+printf %s "checking for Python 2.x exec-prefix... " >&6; }
+    PYEPREFIX=`($PYTHON -c "import sys; sys.stdout.write(sys.exec_prefix)") 2>/dev/null`
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYEPREFIX" >&5
+printf "%s\n" "$PYEPREFIX" >&6; }
+
+    if test x"$PYOSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\"; then
+      # Windows installations are quite different to posix installations (MinGW path separator is a forward slash)
+      PYPREFIX=`echo "$PYPREFIX" | sed -e 's,\\\\,/,g'` # Forward slashes are easier to use and even work on Windows most of the time
+      PYTHON_SO=.pyd
+
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 2.x header files" >&5
+printf %s "checking for Python 2.x header files... " >&6; }
+      if test -r $PYPREFIX/include/Python.h; then
+        PYINCLUDE="-I$PYPREFIX/include"
+      fi
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYINCLUDE" >&5
+printf "%s\n" "$PYINCLUDE" >&6; }
+
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 2.x library directory" >&5
+printf %s "checking for Python 2.x library directory... " >&6; }
+      if test -d $PYPREFIX/libs; then
+        PYLIB=$PYPREFIX/libs
+        PYLINKFILE=`ls $PYLIB/python*.lib | grep "python[0-9][0-9]\+\.lib"`
+        if test -r "$PYLINKFILE"; then
+          PYLINK=-l`basename $PYLINKFILE | sed -e 's/\.lib$//'`
+        else
+          PYLIB=
+        fi
+      fi
+    else
+      # Note: I could not think of a standard way to get the version string from different versions.
+      # This trick pulls it out of the file location for a standard library file.
+
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 2.x version" >&5
+printf %s "checking for Python 2.x version... " >&6; }
+
+      # Need to do this hack since autoconf replaces __file__ with the name of the configure file
+      filehack="file__"
+      PYVERSION=`($PYTHON -c "import sys,string,operator,os.path; sys.stdout.write(operator.getitem(os.path.split(operator.getitem(os.path.split(string.__$filehack),0)),1))") 2>/dev/null`
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYVERSION" >&5
+printf "%s\n" "$PYVERSION" >&6; }
+
+      # Find the directory for libraries this is necessary to deal with
+      # platforms that can have apps built for multiple archs: e.g. x86_64
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 2.x lib dir" >&5
+printf %s "checking for Python 2.x lib dir... " >&6; }
+      PYLIBDIR=`($PYTHON -c "import sys; sys.stdout.write(sys.lib)") 2>/dev/null`
+      if test -z "$PYLIBDIR"; then
+        # Fedora patch Python to add sys.lib, for other distros we assume "lib".
+        PYLIBDIR="lib"
+      fi
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYLIBDIR" >&5
+printf "%s\n" "$PYLIBDIR" >&6; }
+
+      # Set the include directory
+
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 2.x header files" >&5
+printf %s "checking for Python 2.x header files... " >&6; }
+      if test -r $PYPREFIX/include/$PYVERSION/Python.h; then
+        PYINCLUDE="-I$PYPREFIX/include/$PYVERSION -I$PYEPREFIX/$PYLIBDIR/$PYVERSION/config"
+      fi
+      if test -z "$PYINCLUDE"; then
+        if test -r $PYPREFIX/include/Py/Python.h; then
+          PYINCLUDE="-I$PYPREFIX/include/Py -I$PYEPREFIX/$PYLIBDIR/python/lib"
+        fi
+      fi
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYINCLUDE" >&5
+printf "%s\n" "$PYINCLUDE" >&6; }
+
+      # Set the library directory blindly.   This probably won't work with older versions
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 2.x library directory" >&5
+printf %s "checking for Python 2.x library directory... " >&6; }
+      dirs="$PYVERSION/config $PYVERSION/$PYLIBDIR python/$PYLIBDIR"
+      for i in $dirs; do
+        if test -d $PYEPREFIX/$PYLIBDIR/$i; then
+          PYLIB="$PYEPREFIX/$PYLIBDIR/$i"
+          break
+        fi
+      done
+
+      PYLINK="-l$PYVERSION"
+    fi
+
+    if test -z "$PYLIB"; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
+printf "%s\n" "Not found" >&6; }
+    else
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYLIB" >&5
+printf "%s\n" "$PYLIB" >&6; }
+    fi
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 2.x library" >&5
+printf %s "checking for Python 2.x library... " >&6; }
+    if test -z "$PYLINK"; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
+printf "%s\n" "Not found" >&6; }
+    else
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYLINK" >&5
+printf "%s\n" "$PYLINK" >&6; }
+    fi
+  fi
+
+  # Cygwin (Windows) needs the library for dynamic linking
+  case $host in
+  *-*-cygwin* | *-*-mingw*)
+    PYTHONDYNAMICLINKING="-L$PYLIB $PYLINK"
+    DEFS="-DUSE_DL_IMPORT $DEFS"
+    ;;
+  *-*-aix*)
+    PYTHONDYNAMICLINKING="-L$PYLIB $PYLINK"
+    ;;
+  *)PYTHONDYNAMICLINKING="";;
+  esac
+fi
+
+
+
+
+
+
+
+#----------------------------------------------------------------
+# Look for Python 3.x
+#----------------------------------------------------------------
+
+PY3INCLUDE=
+PY3LIB=
+PY3LINK=
+PY3PACKAGE=
+
+
+# Check whether --with-python3 was given.
+if test ${with_python3+y}
+then :
+  withval=$with_python3; PY3BIN="$withval"
+else $as_nop
+  PY3BIN="$alllang_default"
+fi
+
+
+# First, check for "--without-python3" or "--with-python3=no".
+if test x"${PY3BIN}" = xno; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Disabling Python 3.x probe" >&5
+printf "%s\n" "$as_me: Disabling Python 3.x probe" >&6;}
+else
+  if test -z "$PYVER"; then
+    PYVER=0
+  fi
+  if test "x$PY3BIN" = xyes; then
+    if test x"$PYOSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\" -a $PYVER -ge 3; then
+      PYTHON3="$PYTHON"
+    else
+      for py_ver in 3 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 ""; do
+        for ac_prog in python$py_ver
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_PYTHON3+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$PYTHON3"; then
+  ac_cv_prog_PYTHON3="$PYTHON3" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_PYTHON3="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+PYTHON3=$ac_cv_prog_PYTHON3
+if test -n "$PYTHON3"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYTHON3" >&5
+printf "%s\n" "$PYTHON3" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$PYTHON3" && break
+done
+
+        if test -n "$PYTHON3"; then
+          for ac_prog in $PYTHON3-config
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_PY3CONFIG+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$PY3CONFIG"; then
+  ac_cv_prog_PY3CONFIG="$PY3CONFIG" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_PY3CONFIG="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+PY3CONFIG=$ac_cv_prog_PY3CONFIG
+if test -n "$PY3CONFIG"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PY3CONFIG" >&5
+printf "%s\n" "$PY3CONFIG" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$PY3CONFIG" && break
+done
+
+          if test -n "$PY3CONFIG"; then
+            break
+          fi
+        fi
+      done
+    fi
+  else
+    PYTHON3="$PY3BIN"
+    for ac_prog in $PYTHON3-config
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_PY3CONFIG+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$PY3CONFIG"; then
+  ac_cv_prog_PY3CONFIG="$PY3CONFIG" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_PY3CONFIG="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+PY3CONFIG=$ac_cv_prog_PY3CONFIG
+if test -n "$PY3CONFIG"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PY3CONFIG" >&5
+printf "%s\n" "$PY3CONFIG" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$PY3CONFIG" && break
+done
+
+  fi
+
+  if test -n "$PYTHON3"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $PYTHON3 major version number" >&5
+printf %s "checking for $PYTHON3 major version number... " >&6; }
+    PYVER=`($PYTHON3 -c "import sys; sys.stdout.write(sys.version[0])") 2>/dev/null`
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYVER" >&5
+printf "%s\n" "$PYVER" >&6; }
+    if test -z "$PYVER"; then
+      PYVER=0
+    fi
+  fi
+
+  if test $PYVER -ge 3; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 3.x os.name" >&5
+printf %s "checking for Python 3.x os.name... " >&6; }
+    PY3OSNAME=`($PYTHON3 -c "import sys, os; sys.stdout.write(os.name)") 2>/dev/null`
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PY3OSNAME" >&5
+printf "%s\n" "$PY3OSNAME" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 3.x path separator" >&5
+printf %s "checking for Python 3.x path separator... " >&6; }
+    PYSEPARATOR=`($PYTHON3 -c "import sys, os; sys.stdout.write(os.sep)") 2>/dev/null`
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYSEPARATOR" >&5
+printf "%s\n" "$PYSEPARATOR" >&6; }
+
+    if test x"$PY3OSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\"; then
+      # Windows installations are quite different to posix installations
+      # There is no python-config to use
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 3.x prefix" >&5
+printf %s "checking for Python 3.x prefix... " >&6; }
+      PY3PREFIX=`($PYTHON3 -c "import sys; sys.stdout.write(sys.prefix)") 2>/dev/null`
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PY3PREFIX" >&5
+printf "%s\n" "$PY3PREFIX" >&6; }
+      PY3PREFIX=`echo "$PY3PREFIX" | sed -e 's,\\\\,/,g'` # Forward slashes are easier to use and even work on Windows most of the time
+      PYTHON_SO=.pyd
+
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 3.x header files" >&5
+printf %s "checking for Python 3.x header files... " >&6; }
+      if test -r $PY3PREFIX/include/Python.h; then
+        PY3INCLUDE="-I$PY3PREFIX/include"
+      fi
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PY3INCLUDE" >&5
+printf "%s\n" "$PY3INCLUDE" >&6; }
+
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 3.x library directory" >&5
+printf %s "checking for Python 3.x library directory... " >&6; }
+      if test -d $PY3PREFIX/libs; then
+        PY3LIB=$PY3PREFIX/libs
+        PY3LINKFILE=`ls $PY3LIB/python*.lib | grep "python[0-9][0-9]\+\.lib"`
+        if test -r "$PY3LINKFILE"; then
+          PY3LINK=-l`basename $PY3LINKFILE | sed -e 's/\.lib$//'`
+        else
+          PY3LIB=
+        fi
+      fi
+      if test -z "$PY3LIB"; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
+printf "%s\n" "Not found" >&6; }
+      else
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PY3LIB" >&5
+printf "%s\n" "$PY3LIB" >&6; }
+      fi
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 3.x library" >&5
+printf %s "checking for Python 3.x library... " >&6; }
+      if test -z "$PY3LINK"; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
+printf "%s\n" "Not found" >&6; }
+      else
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PY3LINK" >&5
+printf "%s\n" "$PY3LINK" >&6; }
+      fi
+    elif test -n "$PY3CONFIG"; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 3.x prefix" >&5
+printf %s "checking for Python 3.x prefix... " >&6; }
+      PY3PREFIX=`($PY3CONFIG --prefix) 2>/dev/null`
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PY3PREFIX" >&5
+printf "%s\n" "$PY3PREFIX" >&6; }
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 3.x exec-prefix" >&5
+printf %s "checking for Python 3.x exec-prefix... " >&6; }
+      # Piped through xargs to strip trailing whitespace (bug in msys2 + mingw Python)
+      PY3EPREFIX=`($PY3CONFIG --exec-prefix | xargs) 2>/dev/null`
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PY3EPREFIX" >&5
+printf "%s\n" "$PY3EPREFIX" >&6; }
+
+      # Note: I could not think of a standard way to get the version string from different versions.
+      # This trick pulls it out of the file location for a standard library file.
+
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 3.x version" >&5
+printf %s "checking for Python 3.x version... " >&6; }
+
+      # Need to do this hack since autoconf replaces __file__ with the name of the configure file
+      filehack="file__"
+      PY3VERSION=`($PYTHON3 -c "import string,operator,os.path; print(operator.getitem(os.path.split(operator.getitem(os.path.split(string.__$filehack),0)),1))") 2>/dev/null`
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PY3VERSION" >&5
+printf "%s\n" "$PY3VERSION" >&6; }
+
+      # Find the directory for libraries this is necessary to deal with
+      # platforms that can have apps built for multiple archs: e.g. x86_64
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 3.x lib dir" >&5
+printf %s "checking for Python 3.x lib dir... " >&6; }
+      PY3LIBDIR=`($PYTHON3 -c "import sys; print(sys.lib)") 2>/dev/null`
+      if test -z "$PY3LIBDIR"; then
+        # some dists don't have sys.lib  so the best we can do is assume lib
+        PY3LIBDIR="lib"
+      fi
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PY3LIBDIR" >&5
+printf "%s\n" "$PY3LIBDIR" >&6; }
+
+      # Set the include directory
+
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 3.x header files" >&5
+printf %s "checking for Python 3.x header files... " >&6; }
+      PY3INCLUDE=`($PY3CONFIG --includes) 2>/dev/null`
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PY3INCLUDE" >&5
+printf "%s\n" "$PY3INCLUDE" >&6; }
+
+      # Set the library directory blindly.   This probably won't work with older versions
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 3.x library directory" >&5
+printf %s "checking for Python 3.x library directory... " >&6; }
+      dirs="$PY3VERSION/config $PY3VERSION/$PY3LIBDIR python/$PY3LIBDIR"
+      for i in $dirs; do
+        if test -d $PY3EPREFIX/$PY3LIBDIR/$i; then
+          PY3LIB="$PY3EPREFIX/$PY3LIBDIR/$i"
+          break
+        fi
+      done
+      if test -z "$PY3LIB"; then
+        # Last resort
+        if test -d $PY3EPREFIX/$PY3LIBDIR; then
+          PY3LIB="$PY3EPREFIX/$PY3LIBDIR"
+        fi
+      fi
+      if test -z "$PY3LIB"; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
+printf "%s\n" "Not found" >&6; }
+      else
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PY3LIB" >&5
+printf "%s\n" "$PY3LIB" >&6; }
+      fi
+
+      PY3LINK="-l$PY3VERSION"
+
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Python 3.x library" >&5
+printf %s "checking for Python 3.x library... " >&6; }
+      if test -z "$PY3LINK"; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Not found" >&5
+printf "%s\n" "Not found" >&6; }
+      else
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PY3LINK" >&5
+printf "%s\n" "$PY3LINK" >&6; }
+      fi
+    fi
+  fi
+
+  # Cygwin (Windows) needs the library for dynamic linking
+  case $host in
+  *-*-cygwin* | *-*-mingw*)
+    # PYTHON3DYNAMICLINKING ought to be replaced by $PY3CONFIG --ldflags
+    PYTHON3DYNAMICLINKING="-L$PY3LIB $PY3LINK"
+    DEFS="-DUSE_DL_IMPORT $DEFS"
+    ;;
+  *-*-aix*)
+    PYTHON3DYNAMICLINKING="-L$PY3LIB $PY3LINK"
+    ;;
+  *)PYTHON3DYNAMICLINKING="";;
+  esac
+
+
+
+
+
+fi
+
+if test -n "$PYINCLUDE" || test -n "$PY3INCLUDE" ; then
+  for ac_prog in pycodestyle
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_PYCODESTYLE+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  if test -n "$PYCODESTYLE"; then
+  ac_cv_prog_PYCODESTYLE="$PYCODESTYLE" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_prog_PYCODESTYLE="$ac_prog"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+fi
+fi
+PYCODESTYLE=$ac_cv_prog_PYCODESTYLE
+if test -n "$PYCODESTYLE"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $PYCODESTYLE" >&5
+printf "%s\n" "$PYCODESTYLE" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+  test -n "$PYCODESTYLE" && break
+done
+
+  if test -n "$PYCODESTYLE"; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking pycodestyle version" >&5
+printf %s "checking pycodestyle version... " >&6; }
+    pycodestyle_version=`$PYCODESTYLE --version 2>/dev/null`
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $pycodestyle_version" >&5
+printf "%s\n" "$pycodestyle_version" >&6; }
+  fi
+fi
+
+#----------------------------------------------------------------
+# Look for R
+#----------------------------------------------------------------
+
+RBIN=
+
+
+# Check whether --with-r was given.
+if test ${with_r+y}
+then :
+  withval=$with_r;  RBIN="$withval"
+else $as_nop
+  RBIN="$alllang_default"
+fi
+
+
+# First, check for "--without-r" or "--with-r=no".
+if test x"${RBIN}" = xno; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: Disabling R" >&5
+printf "%s\n" "$as_me: Disabling R" >&6;}
+RBIN=
+else
+
+# can we find R?
+if test "x$RBIN" = xyes; then
+   # Extract the first word of "R", so it can be a program name with args.
+set dummy R; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_RBIN+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  case $RBIN in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_RBIN="$RBIN" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    for ac_exec_ext in '' $ac_executable_extensions; do
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_RBIN="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+  done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+RBIN=$ac_cv_path_RBIN
+if test -n "$RBIN"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RBIN" >&5
+printf "%s\n" "$RBIN" >&6; }
+else
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
+fi
+
+
+fi
+fi
+
+
+
+#----------------------------------------------------------------
 # Look for Ruby
 #----------------------------------------------------------------
 
@@ -9615,9 +14020,10 @@
 
 
 # Check whether --with-ruby was given.
-if test "${with_ruby+set}" = set; then :
+if test ${with_ruby+y}
+then :
   withval=$with_ruby;  RUBYBIN="$withval"
-else
+else $as_nop
   RUBYBIN="$alllang_default"
 fi
 
@@ -9625,8 +14031,8 @@
 # First, check for "--without-ruby" or "--with-ruby=no".
 RUBYSO=$SO
 if test x"${RUBYBIN}" = xno; then
-{ $as_echo "$as_me:${as_lineno-$LINENO}: Disabling Ruby" >&5
-$as_echo "$as_me: Disabling Ruby" >&6;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: Disabling Ruby" >&5
+printf "%s\n" "$as_me: Disabling Ruby" >&6;}
 RUBY=
 else
 
@@ -9637,11 +14043,12 @@
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_RUBY+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_prog_RUBY+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
   if test -n "$RUBY"; then
   ac_cv_prog_RUBY="$RUBY" # Let the user override the test.
 else
@@ -9649,11 +14056,15 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
     ac_cv_prog_RUBY="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -9664,11 +14075,11 @@
 fi
 RUBY=$ac_cv_prog_RUBY
 if test -n "$RUBY"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RUBY" >&5
-$as_echo "$RUBY" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RUBY" >&5
+printf "%s\n" "$RUBY" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
@@ -9679,8 +14090,8 @@
 	RUBY="$RUBYBIN"
 fi
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Ruby header files" >&5
-$as_echo_n "checking for Ruby header files... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Ruby header files" >&5
+printf %s "checking for Ruby header files... " >&6; }
 if test -n "$RUBY"; then
         # Try Ruby1.9+ first
         RUBYDIR=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG["rubyhdrdir"] || $rubyhdrdir') 2>/dev/null`
@@ -9702,19 +14113,19 @@
 				else
 					RUBYINCLUDE="-I$i -I$i/$RUBYARCH"
 				fi
-				{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $RUBYINCLUDE" >&5
-$as_echo "$RUBYINCLUDE" >&6; }
+				{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RUBYINCLUDE" >&5
+printf "%s\n" "$RUBYINCLUDE" >&6; }
 				break
 			fi
 		done
 		if test x"$RUBYINCLUDE" = x""; then
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: could not locate ruby.h" >&5
-$as_echo "could not locate ruby.h" >&6; }
+			{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: could not locate ruby.h" >&5
+printf "%s\n" "could not locate ruby.h" >&6; }
 		fi
 
 		# Find library and path for linking.
-		{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for Ruby library" >&5
-$as_echo_n "checking for Ruby library... " >&6; }
+		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Ruby library" >&5
+printf %s "checking for Ruby library... " >&6; }
 		RUBYLIB=""
 		rb_archlibdir=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG["archlibdir"]') 2>/dev/null`
 		rb_libdir=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG["libdir"]') 2>/dev/null`
@@ -9759,15 +14170,15 @@
 		fi
 		if test "$RUBYLIB" = ""; then
 			RUBYLIB="$RUBYDIR"
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: not found... using $RUBYDIR" >&5
-$as_echo "not found... using $RUBYDIR" >&6; }
+			{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found... using $RUBYDIR" >&5
+printf "%s\n" "not found... using $RUBYDIR" >&6; }
 		else
-			{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $RUBYLINK in $RUBYLIB" >&5
-$as_echo "$RUBYLINK in $RUBYLIB" >&6; }
+			{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RUBYLINK in $RUBYLIB" >&5
+printf "%s\n" "$RUBYLINK in $RUBYLIB" >&6; }
 		fi
 	else
-		{ $as_echo "$as_me:${as_lineno-$LINENO}: result: unable to determine ruby configuration" >&5
-$as_echo "unable to determine ruby configuration" >&6; }
+		{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: unable to determine ruby configuration" >&5
+printf "%s\n" "unable to determine ruby configuration" >&6; }
 	fi
 
 	case $host in
@@ -9778,8 +14189,8 @@
 	RUBYCCDLFLAGS=`($RUBY -rrbconfig -e 'print RbConfig::CONFIG["CCDLFLAGS"]') 2>/dev/null`
 	RUBYSO=.`($RUBY -rrbconfig -e 'print RbConfig::CONFIG["DLEXT"]') 2>/dev/null`
 else
-	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: could not figure out how to run ruby" >&5
-$as_echo "could not figure out how to run ruby" >&6; }
+	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: could not figure out how to run ruby" >&5
+printf "%s\n" "could not figure out how to run ruby" >&6; }
 fi
 
 case $host in
@@ -9795,819 +14206,63 @@
 
 
 
-#-------------------------------------------------------------------------
-# Look for PHP7
-#-------------------------------------------------------------------------
-
-PHPBIN=
-
-
-# Check whether --with-php was given.
-if test "${with_php+set}" = set; then :
-  withval=$with_php;  PHPBIN="$withval"
-else
-  PHPBIN="$alllang_default"
-fi
-
-
-# First, check for "--without-php" or "--with-php=no".
-if test x"${PHPBIN}" = xno; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: Disabling PHP" >&5
-$as_echo "$as_me: Disabling PHP" >&6;}
-    PHP=
-else
-    if test "x$PHPBIN" = xyes; then
-      for ac_prog in php7.3 php7.2 php7.1 php7.0 php
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_PHP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$PHP"; then
-  ac_cv_prog_PHP="$PHP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_PHP="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-PHP=$ac_cv_prog_PHP
-if test -n "$PHP"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PHP" >&5
-$as_echo "$PHP" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$PHP" && break
-done
-
-    else
-      PHP=$PHPBIN
-    fi
-
-    if test -n "$PHP"; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PHP header files" >&5
-$as_echo_n "checking for PHP header files... " >&6; }
-            case $PHP in
-        *7.*)
-          PHPCONFIG=`echo "$PHP"|sed 's/7\...*$/-config&/'` ;;
-        *)
-          PHPCONFIG=$PHP-config ;;
-      esac
-      php_version=`$PHPCONFIG --version 2>/dev/null`
-      case $php_version in
-      7.*)
-        PHPINC=`$PHPCONFIG --includes 2>/dev/null`
-        if test -n "$PHPINC"; then
-          { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PHPINC" >&5
-$as_echo "$PHPINC" >&6; }
-        else
-          { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
-        fi
-        ;;
-      "")
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not find $PHPCONFIG or obtain PHP version from it" >&5
-$as_echo "could not find $PHPCONFIG or obtain PHP version from it" >&6; } ;;
-      *)
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: found PHP $php_version - not PHP 7" >&5
-$as_echo "found PHP $php_version - not PHP 7" >&6; } ;;
-      esac
-    fi
-fi
-
-
-
 #----------------------------------------------------------------
-# Look for OCaml
+# Look for Scilab
 #----------------------------------------------------------------
 
 
-# Check whether --with-ocaml was given.
-if test "${with_ocaml+set}" = set; then :
-  withval=$with_ocaml; with_ocaml="$withval"
-else
-  with_ocaml="$alllang_default"
+# Check whether --with-scilab was given.
+if test ${with_scilab+y}
+then :
+  withval=$with_scilab; SCILABBIN="$withval"
+else $as_nop
+  SCILABBIN="$alllang_default"
 fi
 
 
-# Check whether --with-ocamlc was given.
-if test "${with_ocamlc+set}" = set; then :
-  withval=$with_ocamlc;  OCAMLC="$withval"
-else
-  OCAMLC=
+# Check whether --with-scilab-inc was given.
+if test ${with_scilab_inc+y}
+then :
+  withval=$with_scilab_inc; SCILABINCDIR="$withval"
+else $as_nop
+  SCILABINCDIR=""
 fi
 
 
-# Check whether --with-ocamldlgen was given.
-if test "${with_ocamldlgen+set}" = set; then :
-  withval=$with_ocamldlgen;  OCAMLDLGEN="$withval"
+# First, check for "--without-scilab" or "--with-scilab=no".
+if test x"${SCILABBIN}" = xno; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: Disabling Scilab" >&5
+printf "%s\n" "$as_me: Disabling Scilab" >&6;}
+  SCILAB=
 else
-  OCAMLDLGEN=
-fi
-
-
-# Check whether --with-ocamlfind was given.
-if test "${with_ocamlfind+set}" = set; then :
-  withval=$with_ocamlfind; OCAMLFIND="$withval"
-else
-  OCAMLFIND=
-fi
-
-
-# Check whether --with-ocamlmktop was given.
-if test "${with_ocamlmktop+set}" = set; then :
-  withval=$with_ocamlmktop;  OCAMLMKTOP="$withval"
-else
-  OCAMLMKTOP=
-fi
-
-
-# Check whether --with-camlp4 was given.
-if test "${with_camlp4+set}" = set; then :
-  withval=$with_camlp4;  CAMLP4="$withval"
-else
-  CAMLP4=
-fi
-
-
-# First, check for "--without-ocaml" or "--with-ocaml=no".
-if test x"${with_ocaml}" = xno; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: Disabling OCaml" >&5
-$as_echo "$as_me: Disabling OCaml" >&6;}
-    OCAMLC=
-else
-    # OCaml compiler
-    if test -z "$OCAMLC"; then
-	for ac_prog in ocamlc
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_OCAMLC+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$OCAMLC"; then
-  ac_cv_prog_OCAMLC="$OCAMLC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_OCAMLC="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-OCAMLC=$ac_cv_prog_OCAMLC
-if test -n "$OCAMLC"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLC" >&5
-$as_echo "$OCAMLC" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$OCAMLC" && break
-done
-
-    fi
-
-    # OCaml Pre-Processor-Pretty-Printer
-    if test -z "$CAMLP4"; then
-	for ac_prog in camlp4
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CAMLP4+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CAMLP4"; then
-  ac_cv_prog_CAMLP4="$CAMLP4" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CAMLP4="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CAMLP4=$ac_cv_prog_CAMLP4
-if test -n "$CAMLP4"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CAMLP4" >&5
-$as_echo "$CAMLP4" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$CAMLP4" && break
-done
-
-    fi
-
-    # OCaml DL load generator
-    if test -z "$OCAMLDLGEN"; then
-	for ac_prog in ocamldlgen
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_OCAMLDLGEN+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$OCAMLDLGEN"; then
-  ac_cv_prog_OCAMLDLGEN="$OCAMLDLGEN" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_OCAMLDLGEN="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-OCAMLDLGEN=$ac_cv_prog_OCAMLDLGEN
-if test -n "$OCAMLDLGEN"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLDLGEN" >&5
-$as_echo "$OCAMLDLGEN" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$OCAMLDLGEN" && break
-done
-
-    fi
-
-    # OCaml package tool
-    if test -z "$OCAMLFIND"; then
-	for ac_prog in ocamlfind
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_OCAMLFIND+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$OCAMLFIND"; then
-  ac_cv_prog_OCAMLFIND="$OCAMLFIND" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_OCAMLFIND="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-OCAMLFIND=$ac_cv_prog_OCAMLFIND
-if test -n "$OCAMLFIND"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLFIND" >&5
-$as_echo "$OCAMLFIND" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$OCAMLFIND" && break
-done
-
-    fi
-
-    # OCaml toplevel creator
-    if test -z "$OCAMLMKTOP"; then
-	for ac_prog in ocamlmktop
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_OCAMLMKTOP+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$OCAMLMKTOP"; then
-  ac_cv_prog_OCAMLMKTOP="$OCAMLMKTOP" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_OCAMLMKTOP="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-OCAMLMKTOP=$ac_cv_prog_OCAMLMKTOP
-if test -n "$OCAMLMKTOP"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OCAMLMKTOP" >&5
-$as_echo "$OCAMLMKTOP" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$OCAMLMKTOP" && break
-done
-
-    fi
-fi
-
-
-
-
-
-
-
-#----------------------------------------------------------------
-# Look for C#
-#----------------------------------------------------------------
-
-
-# Check whether --with-csharp was given.
-if test "${with_csharp+set}" = set; then :
-  withval=$with_csharp; with_csharp="$withval"
-else
-  with_csharp="$alllang_default"
-fi
-
-
-# Check whether --with-cil-interpreter was given.
-if test "${with_cil_interpreter+set}" = set; then :
-  withval=$with_cil_interpreter; CSHARPBIN="$withval"
-else
-  CSHARPBIN=
-fi
-
-
-# Check whether --with-csharp-compiler was given.
-if test "${with_csharp_compiler+set}" = set; then :
-  withval=$with_csharp_compiler; CSHARPCOMPILERBIN="$withval"
-else
-  CSHARPCOMPILERBIN=
-fi
-
-
-# First, check for "--without-csharp" or "--with-csharp=no".
-if test x"${with_csharp}" = xno; then
-{ $as_echo "$as_me:${as_lineno-$LINENO}: Disabling CSharp" >&5
-$as_echo "$as_me: Disabling CSharp" >&6;}
-CSHARPCOMPILER=
-else
-
-if test -z "$CSHARPCOMPILERBIN" ; then
-  case $host in
-  *-*-cygwin* | *-*-mingw*)
-    # prefer unified Mono mcs compiler (not to be confused with the ancient .NET 1 mcs) over older/alternative names.
-    for ac_prog in csc mcs mono-csc gmcs cscc
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CSHARPCOMPILER+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CSHARPCOMPILER"; then
-  ac_cv_prog_CSHARPCOMPILER="$CSHARPCOMPILER" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CSHARPCOMPILER="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CSHARPCOMPILER=$ac_cv_prog_CSHARPCOMPILER
-if test -n "$CSHARPCOMPILER"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CSHARPCOMPILER" >&5
-$as_echo "$CSHARPCOMPILER" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$CSHARPCOMPILER" && break
-done
-
-    if test -n "$CSHARPCOMPILER" && test "$CSHARPCOMPILER" = "csc" ; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether csc is the Microsoft CSharp compiler" >&5
-$as_echo_n "checking whether csc is the Microsoft CSharp compiler... " >&6; }
-      csc 2>/dev/null | grep "C#" > /dev/null || CSHARPCOMPILER=""
-      if test -z "$CSHARPCOMPILER" ; then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-        for ac_prog in mcs mono-csc gmcs cscc
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CSHARPCOMPILER+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CSHARPCOMPILER"; then
-  ac_cv_prog_CSHARPCOMPILER="$CSHARPCOMPILER" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CSHARPCOMPILER="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CSHARPCOMPILER=$ac_cv_prog_CSHARPCOMPILER
-if test -n "$CSHARPCOMPILER"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CSHARPCOMPILER" >&5
-$as_echo "$CSHARPCOMPILER" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$CSHARPCOMPILER" && break
-done
-
-      else
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-      fi
-    fi
-    ;;
-  *)for ac_prog in mono-csc gmcs mcs cscc
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CSHARPCOMPILER+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CSHARPCOMPILER"; then
-  ac_cv_prog_CSHARPCOMPILER="$CSHARPCOMPILER" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CSHARPCOMPILER="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CSHARPCOMPILER=$ac_cv_prog_CSHARPCOMPILER
-if test -n "$CSHARPCOMPILER"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CSHARPCOMPILER" >&5
-$as_echo "$CSHARPCOMPILER" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$CSHARPCOMPILER" && break
-done
-;;
-  esac
-else
-  CSHARPCOMPILER="$CSHARPCOMPILERBIN"
-fi
-
-CSHARPCONVERTPATH="Tools/convertpath -u"
-if test -z "$CSHARPBIN" ; then
-  CSHARPCILINTERPRETER=""
-  CSHARPCILINTERPRETER_FLAGS=""
-  if test "cscc" = "$CSHARPCOMPILER" ; then
-    for ac_prog in ilrun
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CSHARPCILINTERPRETER+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CSHARPCILINTERPRETER"; then
-  ac_cv_prog_CSHARPCILINTERPRETER="$CSHARPCILINTERPRETER" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CSHARPCILINTERPRETER="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CSHARPCILINTERPRETER=$ac_cv_prog_CSHARPCILINTERPRETER
-if test -n "$CSHARPCILINTERPRETER"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CSHARPCILINTERPRETER" >&5
-$as_echo "$CSHARPCILINTERPRETER" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$CSHARPCILINTERPRETER" && break
-done
-
-  else
-    if test "mcs" = "$CSHARPCOMPILER"; then
-      # Check that mcs is the C# compiler and not the Unix mcs utility by examining the output of 'mcs --version'
-      # The Mono compiler should emit: Mono C# compiler version a.b.c.d
-      csharp_version_raw=`(mcs --version) 2>/dev/null`
-      csharp_version_searched=`(mcs --version | sed -e "/C#/b" -e "/Mono/b" -e d) 2>/dev/null` # return string if contains 'Mono' or 'C#'
-      CSHARPCOMPILER=""
-      if test -n "$csharp_version_raw" ; then
-        if test "$csharp_version_raw" = "$csharp_version_searched" ; then
-          CSHARPCOMPILER="mcs"
-        fi
-      fi
-      if test "mcs" != "$CSHARPCOMPILER" ; then
-        echo "mcs is not a working Mono C# compiler"
-      fi
-    fi
-    if test "mcs" = "$CSHARPCOMPILER" || test "gmcs" = "$CSHARPCOMPILER" || test "mono-csc" = "$CSHARPCOMPILER"; then
-        for ac_prog in mono
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_CSHARPCILINTERPRETER+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$CSHARPCILINTERPRETER"; then
-  ac_cv_prog_CSHARPCILINTERPRETER="$CSHARPCILINTERPRETER" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_CSHARPCILINTERPRETER="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-CSHARPCILINTERPRETER=$ac_cv_prog_CSHARPCILINTERPRETER
-if test -n "$CSHARPCILINTERPRETER"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CSHARPCILINTERPRETER" >&5
-$as_echo "$CSHARPCILINTERPRETER" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$CSHARPCILINTERPRETER" && break
-done
- # Mono JIT
-        CSHARPCILINTERPRETER_FLAGS="--debug"
-    else
-      if test "csc" = "$CSHARPCOMPILER"; then
-          CSHARPCONVERTPATH="Tools/convertpath -w"
-      fi
-    fi
-  fi
-else
-  CSHARPCILINTERPRETER="$CSHARPBIN"
-fi
-
-# Cygwin requires the Windows standard (Pascal) calling convention as it is a Windows executable and not a Cygwin built executable
-case $host in
-*-*-cygwin* | *-*-mingw*)
-    if test "$GCC" = yes; then
-        CSHARPDYNAMICLINKING="$GCC_MNO_CYGWIN -mthreads -Wl,--add-stdcall-alias"
-        CSHARPCFLAGS="$GCC_MNO_CYGWIN -mthreads"
-    else
-        CSHARPDYNAMICLINKING=""
-        CSHARPCFLAGS=""
-    fi ;;
-*)
-        CSHARPDYNAMICLINKING=""
-        CSHARPCFLAGS=""
-        ;;
-esac
-
-# CSharp on Windows platforms including Cygwin doesn't use libname.dll, rather name.dll when loading dlls
-case $host in
-*-*-cygwin* | *-*-mingw*) CSHARPLIBRARYPREFIX="";;
-*)CSHARPLIBRARYPREFIX="lib";;
-esac
-
-# C#/Mono on Mac OS X tweaks
-case $host in
-*-*-darwin*)
-    CSHARPSO=".so"
-    ;;
-*)
-    CSHARPSO=$SO
-    ;;
-esac
-fi
-
-
-
-
-
-
-
-
-
-
-#----------------------------------------------------------------
-# Look for Lua
-#----------------------------------------------------------------
-
-LUABIN=
-LUAINCLUDE=
-LUALIB=
-LUADYNAMICLOADLIB=
-LUAFLAGS=
-LUALINK=
-# note: if LUABIN is empty then lua tests will not be done
-# LUABIN will be cleared if certain dependencies cannot be found
-
-
-# Check whether --with-lua was given.
-if test "${with_lua+set}" = set; then :
-  withval=$with_lua;  LUABIN="$withval"
-else
-  LUABIN="$alllang_default"
-fi
-
-
-# Check whether --with-luaincl was given.
-if test "${with_luaincl+set}" = set; then :
-  withval=$with_luaincl;
-	LUAINCLUDE="$withval"
-else
-  LUAINCLUDE=
-fi
-
-
-# Check whether --with-lualib was given.
-if test "${with_lualib+set}" = set; then :
-  withval=$with_lualib;
-	LUALIB="$withval"
-else
-  LUALIB=
-fi
-
-
-# First, check for "--without-lua" or "--with-lua=no".
-if test x"${LUABIN}" = xno; then
-{ $as_echo "$as_me:${as_lineno-$LINENO}: Disabling Lua" >&5
-$as_echo "$as_me: Disabling Lua" >&6;}
-else
-
-# can we find lua?
-if test "x$LUABIN" = xyes; then
-   # We look for a versioned Lua binary first, as there can be
-   # multiple versions of Lua installed on some systems (like Debian).
-   for ac_prog in lua5.4 lua5.3 lua5.2 lua5.1 lua
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_LUABIN+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  case $LUABIN in
+  # Check for Scilab executable
+  if test "x$SCILABBIN" = xyes; then
+    # Extract the first word of "scilab", so it can be a program name with args.
+set dummy scilab; ac_word=$2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+printf %s "checking for $ac_word... " >&6; }
+if test ${ac_cv_path_SCILAB+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+  case $SCILAB in
   [\\/]* | ?:[\\/]*)
-  ac_cv_path_LUABIN="$LUABIN" # Let the user override the test with a path.
+  ac_cv_path_SCILAB="$SCILAB" # Let the user override the test with a path.
   ;;
   *)
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_LUABIN="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+  if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then
+    ac_cv_path_SCILAB="$as_dir$ac_word$ac_exec_ext"
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5
     break 2
   fi
 done
@@ -10617,745 +14272,456 @@
   ;;
 esac
 fi
-LUABIN=$ac_cv_path_LUABIN
-if test -n "$LUABIN"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LUABIN" >&5
-$as_echo "$LUABIN" >&6; }
+SCILAB=$ac_cv_path_SCILAB
+if test -n "$SCILAB"; then
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SCILAB" >&5
+printf "%s\n" "$SCILAB" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 fi
 
 
-  test -n "$LUABIN" && break
-done
-
-fi
-
-# check version: we need Lua 5.x
-if test "$LUABIN"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking Lua version" >&5
-$as_echo_n "checking Lua version... " >&6; }
-  LUA_VERSION=`$LUABIN -e 'print(string.match(_VERSION, "%d+[.]%d+"))'`
-  # For 5.0 and 5.1 header and libraries may be named using 50 or 51.
-  LUA_VERSION_NO_DOTS=
-  if test -n "$LUA_VERSION" ; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: Lua $LUA_VERSION.x" >&5
-$as_echo "Lua $LUA_VERSION.x" >&6; }
   else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
-$as_echo "failed" >&6; }
-  fi
-  case $LUA_VERSION in
-    5.0) LUA_VERSION_NO_DOTS=50 ;;
-    5.1) LUA_VERSION_NO_DOTS=51 ;;
-    5.*) ;;
-    *)
-      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Not Lua 5.x, SWIG does not support this version of Lua" >&5
-$as_echo "$as_me: WARNING: Not Lua 5.x, SWIG does not support this version of Lua" >&2;}
-      LUABIN=""
-      ;;
-  esac
-fi
-
-if test "$LUABIN"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether Lua dynamic loading is enabled" >&5
-$as_echo_n "checking whether Lua dynamic loading is enabled... " >&6; }
-  # using Lua to check Lua
-  # lua 5.0 & 5.1 have different fn names
-  if test "$LUA_VERSION" = "5.0"; then
-    LUADYNAMICLOADLIB=`$LUABIN -e '_,_,c=loadlib("no_such_lib","") if c~="absent" then print "1" end'`
-  else
-    LUADYNAMICLOADLIB=`$LUABIN -e '_,_,c=package.loadlib("no_such_lib","") if c~="absent" then print "1" end'`
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for scilab" >&5
+printf %s "checking for scilab... " >&6; }
+    if test -f "$SCILABBIN"; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SCILABBIN" >&5
+printf "%s\n" "$SCILABBIN" >&6; }
+      SCILAB="$SCILABBIN"
+    else
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
+    fi
   fi
 
-  if test -z "$LUADYNAMICLOADLIB"; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-  else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-  fi
+  if test -n "$SCILAB"; then
+    # Check for Scilab version (needs api_scilab so needs version 5.3.3 or higher)
+    SCILAB_VERSION=`$SCILAB -nwni -version | head -1 | sed -e 's|Scilab version \"\(.*\)\"|\1|g'`
 
-  # look for the header files & set LUAFLAGS accordingly
-  # will clear LUABIN if not present
-  if test -n "$LUAINCLUDE"; then
-    as_ac_File=`$as_echo "ac_cv_file_$LUAINCLUDE/lua.h" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LUAINCLUDE/lua.h" >&5
-$as_echo_n "checking for $LUAINCLUDE/lua.h... " >&6; }
-if eval \${$as_ac_File+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  test "$cross_compiling" = yes &&
-  as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
-if test -r "$LUAINCLUDE/lua.h"; then
-  eval "$as_ac_File=yes"
-else
-  eval "$as_ac_File=no"
-fi
-fi
-eval ac_res=\$$as_ac_File
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_File"\" = x"yes"; then :
-  LUAFLAGS="$ISYSTEM$LUAINCLUDE"
-else
-  LUABIN=
-fi
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking Scilab version is higher than 5.3.2" >&5
+printf %s "checking Scilab version is higher than 5.3.2... " >&6; }
+    SCILAB_MAJOR_VERSION=`echo $SCILAB_VERSION | cut -d. -f1`
+    SCILAB_MINOR_VERSION=`echo $SCILAB_VERSION | cut -d. -f2`
+    SCILAB_MAINTENANCE_VERSION=`echo $SCILAB_VERSION | cut -d. -f3`
+    SCILAB_VERSION_NO_DOTS=`printf '%04d%02d%02d' "$SCILAB_MAJOR_VERSION" "$SCILAB_MINOR_VERSION" "$SCILAB_MAINTENANCE_VERSION"`
 
-  else
-    LUA_OK="1"
-    CFLAGS_SAVED=$CFLAGS
-    CFLAGS= # Use empty CFLAGS to avoid failure: "present but cannot be compiled"
-    # On IRIX 5.3, sys/types and inttypes.h are conflicting.
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
-		  inttypes.h stdint.h unistd.h
-do :
-  as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
-"
-if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
+    if test "$SCILAB_VERSION_NO_DOTS" -ge 00050303; then
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes - $SCILAB_VERSION" >&5
+printf "%s\n" "yes - $SCILAB_VERSION" >&6; }
+    else
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no - $SCILAB_VERSION" >&5
+printf "%s\n" "no - $SCILAB_VERSION" >&6; }
+      SCILAB=
+    fi
 
-fi
+    if test -n "$SCILAB"; then
+      # Set Scilab startup options depending on version
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Scilab startup options" >&5
+printf %s "checking for Scilab startup options... " >&6; }
+      SCILABOPT="-nwni -nb"
+      if test "$SCILAB_VERSION_NO_DOTS" -ge 00050400; then
+        SCILABOPT+=" -noatomsautoload"
+      fi
+      if test "$SCILAB_VERSION_NO_DOTS" -ge 00060000; then
+        SCILABOPT+=" -quit"
+      fi
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $SCILABOPT" >&5
+printf "%s\n" "$SCILABOPT" >&6; }
 
-done
-
-
-ac_fn_c_check_header_mongrel "$LINENO" "lua.h" "ac_cv_header_lua_h" "$ac_includes_default"
-if test "x$ac_cv_header_lua_h" = xyes; then :
-  LUAFLAGS=""
-else
-  LUA_OK=""
-fi
-
-
-    CFLAGS=$CFLAGS_SAVED
-    # if we didn't get it, going to have to look elsewhere (the hard way)
-    if test -z "$LUA_OK"; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking for lua.h in other locations" >&5
-$as_echo_n "checking for lua.h in other locations... " >&6; }
-      # note: Debian/Ubuntu seem to like /usr/include/lua5.1/lua.h
-      # The ordering of the include directories to search should match
-      # the ordering of libraries to search in the library test below.
-      inc=/usr/include
-      incloc=/usr/local/include
-      dirs="$inc/lua$LUA_VERSION"
-      test -z "$LUA_VERSION_NO_DOTS" || dirs="$dirs $inc/lua$LUA_VERSION_NO_DOTS"
-      dirs="$dirs $incloc/lua$LUA_VERSION"
-      test -z "$LUA_VERSION_NO_DOTS" || dirs="$dirs $incloc/lua$LUA_VERSION_NO_DOTS"
-      dirs="$dirs $incloc"
+      # Check for Scilab header files
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Scilab header files" >&5
+printf %s "checking for Scilab header files... " >&6; }
+      headers="`$as_dirname -- "$SCILAB" ||
+$as_expr X"$SCILAB" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$SCILAB" : 'X\(//\)[^/]' \| \
+	 X"$SCILAB" : 'X\(//\)$' \| \
+	 X"$SCILAB" : 'X\(/\)' \| . 2>/dev/null ||
+printf "%s\n" X"$SCILAB" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)[^/].*/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\/\)$/{
+	    s//\1/
+	    q
+	  }
+	  /^X\(\/\).*/{
+	    s//\1/
+	    q
+	  }
+	  s/.*/./; q'`/../include"
+      if test "$SCILABINCDIR" != ""; then
+        dirs="$SCILABINCDIR"
+      elif test -d "$SCI"; then
+        dirs="$SCI/include $SCI/../../include"
+      elif test -d "$headers"; then
+        dirs="$headers"
+      elif test -n "$PKG_CONFIG "; then
+        dirs=`$PKG_CONFIG  scilab --cflags-only-I | sed -e 's/-I//g'`
+      else
+        dirs="/usr/include"
+      fi
       for i in $dirs; do
-        #echo "$i"
-        if test -r $i/lua.h; then
-          { $as_echo "$as_me:${as_lineno-$LINENO}: result: $i/lua.h" >&5
-$as_echo "$i/lua.h" >&6; }
-          LUAFLAGS="$ISYSTEM$i"
+        if test -r $i/api_scilab.h; then
+          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $i" >&5
+printf "%s\n" "$i" >&6; }
+          SCILABINCLUDE="-I$i"
+          break
+        fi
+        if test -r $i/scilab/api_scilab.h; then
+          { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $i/scilab" >&5
+printf "%s\n" "$i/scilab" >&6; }
+          SCILABINCLUDE="-I$i/scilab"
           break
         fi
       done
-      if test -z "$LUAFLAGS"; then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: not found" >&5
-$as_echo "not found" >&6; }
-        LUABIN="" # clear the bin
+      if test "$SCILABINCLUDE" = "" ; then
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
+        SCILAB=
       fi
     fi
   fi
+fi
 
-  # look for the library files & set LUALINK accordingly
-  # will clear LUABIN if not present
-  lua_save_LIBS=$LIBS # the code seems to disrupt LIBS, so saving
 
-  if test -n "$LUALIB"; then
-    as_ac_File=`$as_echo "ac_cv_file_$LUALIB/liblua.a" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LUALIB/liblua.a" >&5
-$as_echo_n "checking for $LUALIB/liblua.a... " >&6; }
-if eval \${$as_ac_File+:} false; then :
-  $as_echo_n "(cached) " >&6
+
+
+
+
+#--------------------------------------------------------------------
+# Look for Tcl
+#--------------------------------------------------------------------
+
+TCLINCLUDE=
+TCLLIB=
+TCLPACKAGE=
+TCLLINK=
+
+
+# Check whether --with-tclconfig was given.
+if test ${with_tclconfig+y}
+then :
+  withval=$with_tclconfig; with_tclconfig="$withval"
+else $as_nop
+  with_tclconfig=
+fi
+
+
+# Check whether --with-tcl was given.
+if test ${with_tcl+y}
+then :
+  withval=$with_tcl;
+	TCLPACKAGE="$withval"
+else $as_nop
+  TCLPACKAGE="$alllang_default"
+fi
+
+
+# Check whether --with-tclincl was given.
+if test ${with_tclincl+y}
+then :
+  withval=$with_tclincl;
+	TCLINCLUDE="-I$withval"
+else $as_nop
+  TCLINCLUDE=
+fi
+
+
+# Check whether --with-tcllib was given.
+if test ${with_tcllib+y}
+then :
+  withval=$with_tcllib;
+	TCLLIB="-L$withval"
+else $as_nop
+  TCLLIB=
+fi
+
+
+# First, check for "--without-tcl" or "--with-tcl=no".
+if test x"${TCLPACKAGE}" = xno; then
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: Disabling Tcl" >&5
+printf "%s\n" "$as_me: Disabling Tcl" >&6;}
 else
-  test "$cross_compiling" = yes &&
-  as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5
-if test -r "$LUALIB/liblua.a"; then
-  eval "$as_ac_File=yes"
-else
-  eval "$as_ac_File=no"
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5
+printf %s "checking for Tcl configuration... " >&6; }
+# First check to see if --with-tclconfig was specified.
+if test x"${with_tclconfig}" != x ; then
+   if test -f "${with_tclconfig}/tclConfig.sh" ; then
+      TCLCONFIG=`(cd ${with_tclconfig}; pwd)`
+   else
+      as_fn_error $? "${with_tcl} directory does not contain tclConfig.sh" "$LINENO" 5
+   fi
 fi
-fi
-eval ac_res=\$$as_ac_File
-	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-if eval test \"x\$"$as_ac_File"\" = x"yes"; then :
-  LUALINK="-L$LUALIB -llua"
-else
-  LUABIN=
-fi
-
-  else
-    libs="lua lua$LUA_VERSION"
-    test -z "$LUA_VERSION_NO_DOTS" || libs="$libs lua$LUA_VERSION_NO_DOTS"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing lua_close" >&5
-$as_echo_n "checking for library containing lua_close... " >&6; }
-if ${ac_cv_search_lua_close+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char lua_close ();
-int
-main ()
-{
-return lua_close ();
-  ;
-  return 0;
-}
-_ACEOF
-for ac_lib in '' $libs; do
-  if test -z "$ac_lib"; then
-    ac_res="none required"
-  else
-    ac_res=-l$ac_lib
-    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
-  fi
-  if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_search_lua_close=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext
-  if ${ac_cv_search_lua_close+:} false; then :
-  break
-fi
-done
-if ${ac_cv_search_lua_close+:} false; then :
-
-else
-  ac_cv_search_lua_close=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_lua_close" >&5
-$as_echo "$ac_cv_search_lua_close" >&6; }
-ac_res=$ac_cv_search_lua_close
-if test "$ac_res" != no; then :
-  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-  LUALINK="-l$ac_lib"
-else
-  LUABIN=
-fi
-
-  fi
-
-  # adding lualib for lua 5.0
-  if test "$LUA_VERSION" = "5.0"; then
-    LUALINK="$LUALINK -llualib"
-  fi
-
-  LIBS=$lua_save_LIBS	# restore LIBS
-fi
-
-fi # if not disabled
-
-
-
-
-
-
-#----------------------------------------------------------------
-# Look for GNU R
-#----------------------------------------------------------------
-
-RBIN=
-
-
-# Check whether --with-r was given.
-if test "${with_r+set}" = set; then :
-  withval=$with_r;  RBIN="$withval"
-else
-  RBIN="$alllang_default"
-fi
-
-
-# First, check for "--without-r" or "--with-r=no".
-if test x"${RBIN}" = xno; then
-{ $as_echo "$as_me:${as_lineno-$LINENO}: Disabling R" >&5
-$as_echo "$as_me: Disabling R" >&6;}
-RBIN=
-else
-
-# can we find R?
-if test "x$RBIN" = xyes; then
-   # Extract the first word of "R", so it can be a program name with args.
-set dummy R; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_path_RBIN+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  case $RBIN in
-  [\\/]* | ?:[\\/]*)
-  ac_cv_path_RBIN="$RBIN" # Let the user override the test with a path.
+# check in a few common install locations
+dirs="/usr/lib*/ /usr/lib*/tcl*/ /usr/local/lib*/ /usr/local/lib*/tcl*/"
+case $host in
+*-*-darwin*)
+  tcl_framework="/System/Library/Frameworks/Tcl.framework/"
+  macos_sysroot="$(xcodebuild -version -sdk macosx Path 2>/dev/null)" # For MacOSX10.14 and later
+  dirs="$macos_sysroot$tcl_framework $tcl_framework $dirs"
   ;;
-  *)
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_path_RBIN="$as_dir/$ac_word$ac_exec_ext"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
+*)
   ;;
 esac
-fi
-RBIN=$ac_cv_path_RBIN
-if test -n "$RBIN"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RBIN" >&5
-$as_echo "$RBIN" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-fi
-fi
-
-
-
-#----------------------------------------------------------------
-# Look for Go compilers
-#----------------------------------------------------------------
-
-
-# Check whether --with-go was given.
-if test "${with_go+set}" = set; then :
-  withval=$with_go; GOBIN="$withval"
-else
-  GOBIN="$alllang_default"
-fi
-
-
-if test x"${GOBIN}" = xno; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: Disabling Go" >&5
-$as_echo "$as_me: Disabling Go" >&6;}
-  GO=
-  GOGCC=false
-  GCCGO=
-  GOOPT=
-  GCCGOOPT=
-  GOVERSIONOPTION=
-else
-
-  if test "x$GOBIN" = xyes; then
-    for ac_prog in go
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_GO+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$GO"; then
-  ac_cv_prog_GO="$GO" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_GO="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
+if test x"${TCLCONFIG}" = x ; then
+  for d in $dirs ; do
+    for i in `ls -d -r $d 2>/dev/null` ; do
+      if test -f $i"tclConfig.sh" ; then
+        TCLCONFIG=`(cd $i; pwd)`
+        break
+      fi
+    done
   done
-IFS=$as_save_IFS
-
 fi
-fi
-GO=$ac_cv_prog_GO
-if test -n "$GO"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GO" >&5
-$as_echo "$GO" >&6; }
+if test x"${TCLCONFIG}" = x ; then
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
+printf "%s\n" "no" >&6; }
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: found $TCLCONFIG/tclConfig.sh" >&5
+printf "%s\n" "found $TCLCONFIG/tclConfig.sh" >&6; }
+    . $TCLCONFIG/tclConfig.sh
+    if test -z "$TCLINCLUDE"; then
+        TCLINCLUDE=`echo $TCL_INCLUDE_SPEC`
+    fi
+    if test -z "$TCLLIB"; then
+        TCLLIB=$TCL_LIB_SPEC
+    fi
 fi
 
-
-  test -n "$GO" && break
-done
-
-  else
-    GO="$GOBIN"
-  fi
-
-  GOGCC=false
-  GCCGO=
-  GOOPT=
-  GCCGOOPT=
-  GOVERSIONOPTION=
-
-  if test -n "$GO" ; then
-    GOVERSIONOPTION=version
-    go_version=$($GO $GOVERSIONOPTION | sed -e 's/go version //')
-    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether go version is too old" >&5
-$as_echo_n "checking whether go version is too old... " >&6; }
-    case $go_version in
-    go1.012*)
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes - minimum version is 1.3" >&5
-$as_echo "yes - minimum version is 1.3" >&6; }
-      GO=
-      GOOPT="-intgosize 32"
-      ;;
-    *)
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-      case "$(go env GOARCH)" in
-      amd64 | arm64 | ppc64*)
-        GOOPT="-intgosize 64"
-	;;
-      *)
-        GOOPT="-intgosize 32"
-	;;
-      esac
-      ;;
-    esac
-  fi
-
-  for ac_prog in gccgo
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_GCCGO+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$GCCGO"; then
-  ac_cv_prog_GCCGO="$GCCGO" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_GCCGO="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-GCCGO=$ac_cv_prog_GCCGO
-if test -n "$GCCGO"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $GCCGO" >&5
-$as_echo "$GCCGO" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$GCCGO" && break
-done
-
-
-  if test -n "$GCCGO" ; then
-    if $GCCGO --help 2>/dev/null | grep gccgo >/dev/null 2>&1 ; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gccgo version is too old" >&5
-$as_echo_n "checking whether gccgo version is too old... " >&6; }
-      go_version=`$GO $GOVERSIONOPTION | sed -n '1p' | sed -e 's/^.* \([0-9.]*\) *$/\1/' -e 's/[.]//g'`
-      if test "x$go_version" = x; then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: could not determine gccgo version" >&5
-$as_echo "could not determine gccgo version" >&6; }
-        GCCGO=
-      elif test "$go_version" -lt 470; then
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes - minimum version is 4.7.0" >&5
-$as_echo "yes - minimum version is 4.7.0" >&6; }
-        GCCGO=
-      else
-        { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-        if test "$go_version" -lt 480; then
-          GCCGOOPT="-intgosize 32"
-        else
-          # The cast to long int works around a bug in the HP C Compiler
-# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
-# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'.
-# This bug is HP SR number 8606223364.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of void *" >&5
-$as_echo_n "checking size of void *... " >&6; }
-if ${ac_cv_sizeof_void_p+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (void *))" "ac_cv_sizeof_void_p"        "$ac_includes_default"; then :
-
-else
-  if test "$ac_cv_type_void_p" = yes; then
-     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error 77 "cannot compute sizeof (void *)
-See \`config.log' for more details" "$LINENO" 5; }
-   else
-     ac_cv_sizeof_void_p=0
+if test -z "$TCLINCLUDE"; then
+   if test "x$TCLPACKAGE" != xyes; then
+	TCLINCLUDE="-I$TCLPACKAGE/include"
    fi
 fi
 
+if test -z "$TCLLIB"; then
+   if test "x$TCLPACKAGE" != xyes; then
+	TCLLIB="-L$TCLPACKAGE/lib -ltcl"
+   fi
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_void_p" >&5
-$as_echo "$ac_cv_sizeof_void_p" >&6; }
 
-
-
-cat >>confdefs.h <<_ACEOF
-#define SIZEOF_VOID_P $ac_cv_sizeof_void_p
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Tcl header files" >&5
+printf %s "checking for Tcl header files... " >&6; }
+if test -z "$TCLINCLUDE"; then
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+printf %s "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test ${ac_cv_prog_CPP+y}
+then :
+  printf %s "(cached) " >&6
+else $as_nop
+      # Double quotes because $CC needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" cpp /lib/cpp
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+		     Syntax error
 _ACEOF
+if ac_fn_c_try_cpp "$LINENO"
+then :
 
-
-          if test "$ac_cv_sizeof_void_p" = "8"; then
-            GCCGOOPT="-intgosize 64"
-          else
-            GCCGOOPT="-intgosize 32"
-          fi
-        fi
-      fi
-    fi
-  fi
+else $as_nop
+  # Broken: fails on valid input.
+continue
 fi
+rm -f conftest.err conftest.i conftest.$ac_ext
 
-
-
-
-
-
-
-
-
-
-
-
-
-#----------------------------------------------------------------
-# Look for D
-#----------------------------------------------------------------
-
-
-# Check whether --with-d was given.
-if test "${with_d+set}" = set; then :
-  withval=$with_d; with_d="$withval"
-else
-  with_d="$alllang_default"
-fi
-
-
-# Check whether --with-d1-compiler was given.
-if test "${with_d1_compiler+set}" = set; then :
-  withval=$with_d1_compiler; D1COMPILERBIN="$withval"
-else
-  D1COMPILERBIN=
-fi
-
-
-# Check whether --with-d2-compiler was given.
-if test "${with_d2_compiler+set}" = set; then :
-  withval=$with_d2_compiler; D2COMPILERBIN="$withval"
-else
-  D2COMPILERBIN=
-fi
-
-
-
-# First, check for "--without-d" or "--with-d=no".
-if test x"${with_d}" = xno; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: Disabling D" >&5
-$as_echo "$as_me: Disabling D" >&6;}
-  D1COMPILER=
-  D2COMPILER=
-else
-  old_ac_ext=$ac_ext
-  ac_ext=d
-
-  if test -z "$D1COMPILERBIN" ; then
-    for ac_prog in dmd ldmd gdmd
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_D1COMPILER+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$D1COMPILER"; then
-  ac_cv_prog_D1COMPILER="$D1COMPILER" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_D1COMPILER="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-  done
-IFS=$as_save_IFS
-
-fi
-fi
-D1COMPILER=$ac_cv_prog_D1COMPILER
-if test -n "$D1COMPILER"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $D1COMPILER" >&5
-$as_echo "$D1COMPILER" >&6; }
-else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-fi
-
-
-  test -n "$D1COMPILER" && break
-done
-
-
-    if test -n "$D1COMPILER" ; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the D1/Tango compiler works" >&5
-$as_echo_n "checking whether the D1/Tango compiler works... " >&6; }
-      cat > conftest.$ac_ext <<_ACEOF
-import tango.io.Stdout;
-void main() {
-}
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
 _ACEOF
-      rm -f conftest.$ac_objext
-      if $D1COMPILER conftest.$ac_ext 2>&5 && test ! -s conftest.err && test -s conftest.$ac_objext; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-        D1COMPILER=
-
+if ac_fn_c_try_cpp "$LINENO"
+then :
+  # Broken: success on invalid input.
+continue
+else $as_nop
+  # Passes both tests.
+ac_preproc_ok=:
+break
 fi
-      rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-    fi
-  else
-    D1COMPILER="$D1COMPILERBIN"
-  fi
+rm -f conftest.err conftest.i conftest.$ac_ext
 
-  if test -z "$D2COMPILERBIN" ; then
-    for ac_prog in dmd gdmd
-do
-  # Extract the first word of "$ac_prog", so it can be a program name with args.
-set dummy $ac_prog; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if ${ac_cv_prog_D2COMPILER+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  if test -n "$D2COMPILER"; then
-  ac_cv_prog_D2COMPILER="$D2COMPILER" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    for ac_exec_ext in '' $ac_executable_extensions; do
-  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
-    ac_cv_prog_D2COMPILER="$ac_prog"
-    $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
 done
-  done
-IFS=$as_save_IFS
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok
+then :
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
 
 fi
-fi
-D2COMPILER=$ac_cv_prog_D2COMPILER
-if test -n "$D2COMPILER"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $D2COMPILER" >&5
-$as_echo "$D2COMPILER" >&6; }
+  CPP=$ac_cv_prog_CPP
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
+  ac_cv_prog_CPP=$CPP
 fi
-
-
-  test -n "$D2COMPILER" && break
-done
-
-
-    if test -n "$D2COMPILER" ; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the D2 compiler works" >&5
-$as_echo_n "checking whether the D2 compiler works... " >&6; }
-      cat > conftest.$ac_ext <<_ACEOF
-import std.algorithm;
-void main() {
-}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+printf "%s\n" "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <limits.h>
+		     Syntax error
 _ACEOF
-      rm -f conftest.$ac_objext
-      if $D2COMPILER conftest.$ac_ext 2>&5 && test ! -s conftest.err && test -s conftest.$ac_objext; then :
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
+if ac_fn_c_try_cpp "$LINENO"
+then :
+
+else $as_nop
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether nonexistent headers
+  # can be detected and how.
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"
+then :
+  # Broken: success on invalid input.
+continue
+else $as_nop
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok
+then :
+
+else $as_nop
+  { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <tcl.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"
+then :
+
+else $as_nop
+  TCLINCLUDE=""
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+if test -z "$TCLINCLUDE"; then
+	dirs="/usr/local/include /usr/include /opt/local/include"
+	for i in $dirs ; do
+		if test -r $i/tcl.h; then
+			{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $i" >&5
+printf "%s\n" "$i" >&6; }
+			TCLINCLUDE="-I$i"
+			break
+		fi
+	done
+fi
+if test -z "$TCLINCLUDE"; then
+	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
+fi
 else
-  $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
-$as_echo "no" >&6; }
-        D2COMPILER=
-
-fi
-      rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-    fi
-  else
-    D2COMPILER="$D2COMPILERBIN"
-  fi
-
-  ac_ext=$old_ac_ext
+        { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $TCLINCLUDE" >&5
+printf "%s\n" "$TCLINCLUDE" >&6; }
 fi
 
-if test -n "$D1COMPILER"; then
-  DDEFAULTVERSION=1
-elif test -n "$D2COMPILER"; then
-  DDEFAULTVERSION=2
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for Tcl library" >&5
+printf %s "checking for Tcl library... " >&6; }
+if test -z "$TCLLIB"; then
+dirs="/usr/local/lib /usr/lib /opt/local/lib /opt/freeware/lib"
+for i in $dirs ; do
+	if test -r $i/libtcl.a; then
+	    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $i" >&5
+printf "%s\n" "$i" >&6; }
+	    TCLLIB="-L$i -ltcl"
+	    break
+	fi
+done
+if test -z "$TCLLIB"; then
+	{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: not found" >&5
+printf "%s\n" "not found" >&6; }
+fi
+else
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $TCLLIB" >&5
+printf "%s\n" "$TCLLIB" >&6; }
 fi
 
-# Do not prefix library file names with "lib" on Windows.
+# Cygwin (Windows) needs the library for dynamic linking
 case $host in
-*-*-cygwin* | *-*-mingw*) DLIBPREFIX="";;
-*)DLIBPREFIX="lib";;
+*-*-cygwin* | *-*-mingw*) TCLDYNAMICLINKING="$TCLLIB";;
+*-*-aix*) TCLDYNAMICLINKING="$TCLLIB";;
+*)TCLDYNAMICLINKING="";;
 esac
 
+# AIX needs -ltcl for linking at test time
+case $host in
+*-*-aix*) TCLLINK="-ltcl";;
+*)TCLLINK="";;
+esac
+
+case $host in
+*-*-darwin*)
+    TCLLDSHARED='$(CC) -dynamiclib -undefined suppress -flat_namespace'
+    TCLCXXSHARED='$(CXX) -dynamiclib -undefined suppress -flat_namespace'
+    ;;
+*)
+    TCLLDSHARED='$(LDSHARED)'
+    TCLCXXSHARED='$(CXXSHARED)'
+    ;;
+esac
+
+fi
+
+
+
 
 
 
@@ -11365,87 +14731,6 @@
 # Determine which languages to use for examples/test-suite
 #----------------------------------------------------------------
 
-SKIP_TCL=
-if test -z "$TCLINCLUDE" || test -z "$TCLLIB" ; then
-    SKIP_TCL="1"
-fi
-
-
-
-SKIP_PERL5=
-if test -z "$PERL" || test -z "$PERL5EXT" || test -z "$PERL5TESTMORE"; then
-    SKIP_PERL5="1"
-fi
-
-
-
-SKIP_OCTAVE=
-if test -z "$OCTAVE" ; then
-    SKIP_OCTAVE="1"
-fi
-
-
-
-SKIP_PYTHON=
-if (test -z "$PYINCLUDE" || test -z "$PYLINK") &&
-   (test -z "$PY3INCLUDE" || test -z "$PY3LINK") ; then
-    SKIP_PYTHON="1"
-fi
-
-
-SKIP_PYTHON3=
-if test -z "$PY3INCLUDE" || test -z "$PY3LINK" ; then
-    SKIP_PYTHON3="1"
-fi
-
-
-SKIP_JAVA=
-if test -z "$JAVA" || test -z "$JAVAC" || test -z "$JAVAINC" ; then
-    SKIP_JAVA="1"
-fi
-
-
-SKIP_JAVASCRIPT=
-if test -z "$JAVASCRIPT" || ( test -z "$NODEJS" && test -z "$JSCENABLED" && test -z "$JSV8ENABLED" ) ; then
-    SKIP_JAVASCRIPT="1"
-fi
-
-
-SKIP_GUILE=
-if test -z "$GUILE" || test -z "$GUILE_LIBS" ; then
-    SKIP_GUILE="1"
-fi
-
-
-
-SKIP_MZSCHEME=
-if test -z "$MZC" || test -z "$MZDYNOBJ" ; then
-    SKIP_MZSCHEME="1"
-fi
-
-
-
-SKIP_RUBY=
-if test -z "$RUBY" || test -z "$RUBYINCLUDE" || test -z "$RUBYLIB" ; then
-    SKIP_RUBY="1"
-fi
-
-
-
-SKIP_PHP=
-if test -z "$PHP" || test -z "$PHPINC" ; then
-    SKIP_PHP="1"
-fi
-
-
-
-SKIP_OCAML=
-if test -z "$OCAMLC" || test -z "$CAMLP4" ; then
-    SKIP_OCAML="1"
-fi
-
-
-
 SKIP_CSHARP=
 if test -z "$CSHARPCOMPILER" ; then
     SKIP_CSHARP="1"
@@ -11456,24 +14741,13 @@
 fi
 
 
-SKIP_LUA=
-# we need LUABIN & dynamic loading
-if test -z "$LUABIN" || test -z "$LUADYNAMICLOADLIB"; then
-    SKIP_LUA="1"
+
+SKIP_D=
+if test -z "$D2COMPILER" ; then
+    SKIP_D="1"
 fi
 
 
-SKIP_R=
-if test -z "$RBIN" ; then
-    SKIP_R="1"
-fi
-
-
-SKIP_SCILAB=
-if test -z "$SCILAB"; then
-    SKIP_SCILAB="1"
-fi
-
 
 SKIP_GO=
 if test -z "$GO" ; then
@@ -11481,12 +14755,113 @@
 fi
 
 
-SKIP_D=
-if test -z "$DDEFAULTVERSION" ; then
-    SKIP_D="1"
+
+SKIP_GUILE=
+if test -z "$GUILE" || test -z "$GUILE_LIBS" ; then
+    SKIP_GUILE="1"
 fi
 
 
+SKIP_JAVA=
+if test -z "$JAVA" || test -z "$JAVAC" || test -z "$JAVAINC" ; then
+    SKIP_JAVA="1"
+fi
+
+
+
+SKIP_JAVASCRIPT=
+if test -z "$JAVASCRIPT" || ( test -z "$NODEJS" && test -z "$JSCENABLED" && test -z "$JSV8ENABLED" && test -z "$JSNAPIENABLED" ) ; then
+    SKIP_JAVASCRIPT="1"
+fi
+
+
+
+SKIP_LUA=
+# we need LUABIN & dynamic loading
+if test -z "$LUABIN" || test -z "$LUADYNAMICLOADLIB"; then
+    SKIP_LUA="1"
+fi
+
+
+
+SKIP_MZSCHEME=
+if test -z "$MZC" || test -z "$MZDYNOBJ" ; then
+    SKIP_MZSCHEME="1"
+fi
+
+
+
+SKIP_OCAML=
+if test -z "$OCAMLC" || test -z "$CAMLP4" ; then
+    SKIP_OCAML="1"
+fi
+
+
+
+SKIP_OCTAVE=
+if test -z "$OCTAVE" ; then
+    SKIP_OCTAVE="1"
+fi
+
+
+
+SKIP_PHP=
+if test -z "$PHP" || test -z "$PHPINC" ; then
+    SKIP_PHP="1"
+fi
+
+
+
+SKIP_PERL5=
+if test -z "$PERL" || test -z "$PERL5EXT" || test -z "$PERL5TESTMORE"; then
+    SKIP_PERL5="1"
+fi
+
+
+
+SKIP_PYTHON=
+if (test -z "$PYINCLUDE" || test -z "$PYLINK") &&
+   (test -z "$PY3INCLUDE" || test -z "$PY3LINK") ; then
+    SKIP_PYTHON="1"
+fi
+
+
+
+SKIP_PYTHON3=
+if test -z "$PY3INCLUDE" || test -z "$PY3LINK" ; then
+    SKIP_PYTHON3="1"
+fi
+
+
+
+SKIP_R=
+if test -z "$RBIN" ; then
+    SKIP_R="1"
+fi
+
+
+
+SKIP_RUBY=
+if test -z "$RUBY" || test -z "$RUBYINCLUDE" || test -z "$RUBYLIB" ; then
+    SKIP_RUBY="1"
+fi
+
+
+
+SKIP_SCILAB=
+if test -z "$SCILAB"; then
+    SKIP_SCILAB="1"
+fi
+
+
+
+SKIP_TCL=
+if test -z "$TCLINCLUDE" || test -z "$TCLLIB" ; then
+    SKIP_TCL="1"
+fi
+
+
+
 #----------------------------------------------------------------
 # Additional language dependencies
 #----------------------------------------------------------------
@@ -11536,9 +14911,10 @@
 
 
 # Check whether --with-swiglibdir was given.
-if test "${with_swiglibdir+set}" = set; then :
+if test ${with_swiglibdir+y}
+then :
   withval=$with_swiglibdir; swig_lib="$withval"
-else
+else $as_nop
   swig_lib="${datadir}/swig/${PACKAGE_VERSION}"
 fi
 
@@ -11554,9 +14930,7 @@
   SWIG_LIB="$ac_define_dir"
 
 
-cat >>confdefs.h <<_ACEOF
-#define SWIG_LIB "$ac_define_dir"
-_ACEOF
+printf "%s\n" "#define SWIG_LIB \"$ac_define_dir\"" >>confdefs.h
 
   test "$prefix_NONE" && prefix=NONE
   test "$exec_prefix_NONE" && exec_prefix=NONE
@@ -11569,9 +14943,7 @@
   *) SWIG_LIB_WIN_UNIX="";;
 esac
 
-cat >>confdefs.h <<_ACEOF
-#define SWIG_LIB_WIN_UNIX "$SWIG_LIB_WIN_UNIX"
-_ACEOF
+printf "%s\n" "#define SWIG_LIB_WIN_UNIX \"$SWIG_LIB_WIN_UNIX\"" >>confdefs.h
 
 
 SWIG_LIB_PREINST=$ABS_SRCDIR/Lib
@@ -11587,15 +14959,16 @@
 
 _ACEOF
 if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
-  $EGREP "yes" >/dev/null 2>&1; then :
+  $EGREP "yes" >/dev/null 2>&1
+then :
   SWIG_LIB_SET="env SWIG_LIB="
 fi
-rm -f conftest*
+rm -rf conftest*
 
 fi
 
 
-ac_config_files="$ac_config_files Makefile swig.spec Examples/Makefile Examples/d/example.mk Examples/xml/Makefile Examples/test-suite/errors/Makefile Examples/test-suite/csharp/Makefile Examples/test-suite/d/Makefile Examples/test-suite/guile/Makefile Examples/test-suite/java/Makefile Examples/test-suite/javascript/Makefile Examples/test-suite/mzscheme/Makefile Examples/test-suite/ocaml/Makefile Examples/test-suite/octave/Makefile Examples/test-suite/perl5/Makefile Examples/test-suite/php/Makefile Examples/test-suite/python/Makefile Examples/test-suite/ruby/Makefile Examples/test-suite/scilab/Makefile Examples/test-suite/tcl/Makefile Examples/test-suite/lua/Makefile Examples/test-suite/r/Makefile Examples/test-suite/go/Makefile Source/Makefile Tools/javascript/Makefile"
+ac_config_files="$ac_config_files Makefile Examples/Makefile Examples/xml/Makefile Examples/test-suite/errors/Makefile Examples/test-suite/csharp/Makefile Examples/test-suite/d/Makefile Examples/test-suite/go/Makefile Examples/test-suite/guile/Makefile Examples/test-suite/java/Makefile Examples/test-suite/javascript/Makefile Examples/test-suite/lua/Makefile Examples/test-suite/mzscheme/Makefile Examples/test-suite/ocaml/Makefile Examples/test-suite/octave/Makefile Examples/test-suite/perl5/Makefile Examples/test-suite/php/Makefile Examples/test-suite/python/Makefile Examples/test-suite/r/Makefile Examples/test-suite/ruby/Makefile Examples/test-suite/scilab/Makefile Examples/test-suite/tcl/Makefile Source/Makefile Tools/javascript/Makefile"
 
 ac_config_files="$ac_config_files preinst-swig"
 
@@ -11643,8 +15016,8 @@
     case $ac_val in #(
     *${as_nl}*)
       case $ac_var in #(
-      *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
-$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+      *_cv_*) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+printf "%s\n" "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
       esac
       case $ac_var in #(
       _ | IFS | as_nl) ;; #(
@@ -11674,15 +15047,15 @@
      /^ac_cv_env_/b end
      t clear
      :clear
-     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     s/^\([^=]*\)=\(.*[{}].*\)$/test ${\1+y} || &/
      t end
      s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
      :end' >>confcache
 if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
   if test -w "$cache_file"; then
     if test "x$cache_file" != "x/dev/null"; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
-$as_echo "$as_me: updating cache $cache_file" >&6;}
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+printf "%s\n" "$as_me: updating cache $cache_file" >&6;}
       if test ! -f "$cache_file" || test -h "$cache_file"; then
 	cat confcache >"$cache_file"
       else
@@ -11696,8 +15069,8 @@
       fi
     fi
   else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
-$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+printf "%s\n" "$as_me: not updating unwritable cache $cache_file" >&6;}
   fi
 fi
 rm -f confcache
@@ -11714,7 +15087,7 @@
 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
   # 1. Remove the extension, and $U if already installed.
   ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
-  ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+  ac_i=`printf "%s\n" "$ac_i" | sed "$ac_script"`
   # 2. Prepend LIBOBJDIR.  When used with automake>=1.10 LIBOBJDIR
   #    will be set to the directory where LIBOBJS objects are built.
   as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
@@ -11725,14 +15098,14 @@
 LTLIBOBJS=$ac_ltlibobjs
 
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
-$as_echo_n "checking that generated files are newer than configure... " >&6; }
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking that generated files are newer than configure" >&5
+printf %s "checking that generated files are newer than configure... " >&6; }
    if test -n "$am_sleep_pid"; then
      # Hide warnings about reused PIDs.
      wait $am_sleep_pid 2>/dev/null
    fi
-   { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
-$as_echo "done" >&6; }
+   { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: done" >&5
+printf "%s\n" "done" >&6; }
  if test -n "$EXEEXT"; then
   am__EXEEXT_TRUE=
   am__EXEEXT_FALSE='#'
@@ -11758,8 +15131,8 @@
 ac_write_fail=0
 ac_clean_files_save=$ac_clean_files
 ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
-$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+printf "%s\n" "$as_me: creating $CONFIG_STATUS" >&6;}
 as_write_fail=0
 cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
 #! $SHELL
@@ -11782,14 +15155,16 @@
 
 # Be more Bourne compatible
 DUALCASE=1; export DUALCASE # for MKS sh
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+as_nop=:
+if test ${ZSH_VERSION+y} && (emulate sh) >/dev/null 2>&1
+then :
   emulate sh
   NULLCMD=:
   # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
   # is contrary to our usage.  Disable this feature.
   alias -g '${1+"$@"}'='"$@"'
   setopt NO_GLOB_SUBST
-else
+else $as_nop
   case `(set -o) 2>/dev/null` in #(
   *posix*) :
     set -o posix ;; #(
@@ -11799,46 +15174,46 @@
 fi
 
 
+
+# Reset variables that may have inherited troublesome values from
+# the environment.
+
+# IFS needs to be set, to space, tab, and newline, in precisely that order.
+# (If _AS_PATH_WALK were called with IFS unset, it would have the
+# side effect of setting IFS to empty, thus disabling word splitting.)
+# Quoting is to prevent editors from complaining about space-tab.
 as_nl='
 '
 export as_nl
-# Printing a long string crashes Solaris 7 /usr/bin/printf.
-as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
-as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
-# Prefer a ksh shell builtin over an external printf program on Solaris,
-# but without wasting forks for bash or zsh.
-if test -z "$BASH_VERSION$ZSH_VERSION" \
-    && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='print -r --'
-  as_echo_n='print -rn --'
-elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
-  as_echo='printf %s\n'
-  as_echo_n='printf %s'
-else
-  if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
-    as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
-    as_echo_n='/usr/ucb/echo -n'
-  else
-    as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
-    as_echo_n_body='eval
-      arg=$1;
-      case $arg in #(
-      *"$as_nl"*)
-	expr "X$arg" : "X\\(.*\\)$as_nl";
-	arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
-      esac;
-      expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
-    '
-    export as_echo_n_body
-    as_echo_n='sh -c $as_echo_n_body as_echo'
-  fi
-  export as_echo_body
-  as_echo='sh -c $as_echo_body as_echo'
-fi
+IFS=" ""	$as_nl"
+
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# Ensure predictable behavior from utilities with locale-dependent output.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# We cannot yet rely on "unset" to work, but we need these variables
+# to be unset--not just set to an empty or harmless value--now, to
+# avoid bugs in old shells (e.g. pre-3.0 UWIN ksh).  This construct
+# also avoids known problems related to "unset" and subshell syntax
+# in other old shells (e.g. bash 2.01 and pdksh 5.2.14).
+for as_var in BASH_ENV ENV MAIL MAILPATH CDPATH
+do eval test \${$as_var+y} \
+  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+
+# Ensure that fds 0, 1, and 2 are open.
+if (exec 3>&0) 2>/dev/null; then :; else exec 0</dev/null; fi
+if (exec 3>&1) 2>/dev/null; then :; else exec 1>/dev/null; fi
+if (exec 3>&2)            ; then :; else exec 2>/dev/null; fi
 
 # The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
+if ${PATH_SEPARATOR+false} :; then
   PATH_SEPARATOR=:
   (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
     (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
@@ -11847,13 +15222,6 @@
 fi
 
 
-# IFS
-# We need space, tab and new line, in precisely that order.  Quoting is
-# there to prevent editors from complaining about space-tab.
-# (If _AS_PATH_WALK were called with IFS unset, it would disable word
-# splitting by setting IFS to empty value.)
-IFS=" ""	$as_nl"
-
 # Find who we are.  Look in the path if we contain no directory separator.
 as_myself=
 case $0 in #((
@@ -11862,8 +15230,12 @@
 for as_dir in $PATH
 do
   IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-    test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+  case $as_dir in #(((
+    '') as_dir=./ ;;
+    */) ;;
+    *) as_dir=$as_dir/ ;;
+  esac
+    test -r "$as_dir$0" && as_myself=$as_dir$0 && break
   done
 IFS=$as_save_IFS
 
@@ -11875,30 +15247,10 @@
   as_myself=$0
 fi
 if test ! -f "$as_myself"; then
-  $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+  printf "%s\n" "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
   exit 1
 fi
 
-# Unset variables that we do not need and which cause bugs (e.g. in
-# pre-3.0 UWIN ksh).  But do not cause bugs in bash 2.01; the "|| exit 1"
-# suppresses any "Segmentation fault" message there.  '((' could
-# trigger a bug in pdksh 5.2.14.
-for as_var in BASH_ENV ENV MAIL MAILPATH
-do eval test x\${$as_var+set} = xset \
-  && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
-done
-PS1='$ '
-PS2='> '
-PS4='+ '
-
-# NLS nuisances.
-LC_ALL=C
-export LC_ALL
-LANGUAGE=C
-export LANGUAGE
-
-# CDPATH.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
 
 # as_fn_error STATUS ERROR [LINENO LOG_FD]
@@ -11911,13 +15263,14 @@
   as_status=$1; test $as_status -eq 0 && as_status=1
   if test "$4"; then
     as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-  $as_echo "$as_me: error: $2" >&2
+  printf "%s\n" "$as_me: error: $2" >&2
   as_fn_exit $as_status
 } # as_fn_error
 
 
+
 # as_fn_set_status STATUS
 # -----------------------
 # Set $? to STATUS, without forking.
@@ -11944,18 +15297,20 @@
   { eval $1=; unset $1;}
 }
 as_unset=as_fn_unset
+
 # as_fn_append VAR VALUE
 # ----------------------
 # Append the text in VALUE to the end of the definition contained in VAR. Take
 # advantage of any shell optimizations that allow amortized linear growth over
 # repeated appends, instead of the typical quadratic growth present in naive
 # implementations.
-if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null
+then :
   eval 'as_fn_append ()
   {
     eval $1+=\$2
   }'
-else
+else $as_nop
   as_fn_append ()
   {
     eval $1=\$$1\$2
@@ -11967,12 +15322,13 @@
 # Perform arithmetic evaluation on the ARGs, and store the result in the
 # global $as_val. Take advantage of shells that can avoid forks. The arguments
 # must be portable across $(()) and expr.
-if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null
+then :
   eval 'as_fn_arith ()
   {
     as_val=$(( $* ))
   }'
-else
+else $as_nop
   as_fn_arith ()
   {
     as_val=`expr "$@" || test $? -eq 1`
@@ -12003,7 +15359,7 @@
 $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
 	 X"$0" : 'X\(//\)$' \| \
 	 X"$0" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$0" |
+printf "%s\n" X/"$0" |
     sed '/^.*\/\([^/][^/]*\)\/*$/{
 	    s//\1/
 	    q
@@ -12025,6 +15381,10 @@
 as_cr_digits='0123456789'
 as_cr_alnum=$as_cr_Letters$as_cr_digits
 
+
+# Determine whether it's possible to make 'echo' print without a newline.
+# These variables are no longer used directly by Autoconf, but are AC_SUBSTed
+# for compatibility with existing Makefiles.
 ECHO_C= ECHO_N= ECHO_T=
 case `echo -n x` in #(((((
 -n*)
@@ -12038,6 +15398,12 @@
   ECHO_N='-n';;
 esac
 
+# For backward compatibility with old third-party macros, we provide
+# the shell variables $as_echo and $as_echo_n.  New code should use
+# AS_ECHO(["message"]) and AS_ECHO_N(["message"]), respectively.
+as_echo='printf %s\n'
+as_echo_n='printf %s'
+
 rm -f conf$$ conf$$.exe conf$$.file
 if test -d conf$$.dir; then
   rm -f conf$$.dir/conf$$.file
@@ -12079,7 +15445,7 @@
     as_dirs=
     while :; do
       case $as_dir in #(
-      *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+      *\'*) as_qdir=`printf "%s\n" "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
       *) as_qdir=$as_dir;;
       esac
       as_dirs="'$as_qdir' $as_dirs"
@@ -12088,7 +15454,7 @@
 	 X"$as_dir" : 'X\(//\)[^/]' \| \
 	 X"$as_dir" : 'X\(//\)$' \| \
 	 X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$as_dir" |
+printf "%s\n" X"$as_dir" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
 	    s//\1/
 	    q
@@ -12150,8 +15516,8 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by swig $as_me 4.0.1, which was
-generated by GNU Autoconf 2.69.  Invocation command line was
+This file was extended by swig $as_me 4.2.1, which was
+generated by GNU Autoconf 2.71.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -12210,17 +15576,19 @@
 Configuration commands:
 $config_commands
 
-Report bugs to <http://www.swig.org>."
+Report bugs to <https://www.swig.org>."
 
 _ACEOF
+ac_cs_config=`printf "%s\n" "$ac_configure_args" | sed "$ac_safe_unquote"`
+ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\''/g"`
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
+ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-swig config.status 4.0.1
-configured by $0, generated by GNU Autoconf 2.69,
+swig config.status 4.2.1
+configured by $0, generated by GNU Autoconf 2.71,
   with options \\"\$ac_cs_config\\"
 
-Copyright (C) 2012 Free Software Foundation, Inc.
+Copyright (C) 2021 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
 
@@ -12260,15 +15628,15 @@
   -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
     ac_cs_recheck=: ;;
   --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
-    $as_echo "$ac_cs_version"; exit ;;
+    printf "%s\n" "$ac_cs_version"; exit ;;
   --config | --confi | --conf | --con | --co | --c )
-    $as_echo "$ac_cs_config"; exit ;;
+    printf "%s\n" "$ac_cs_config"; exit ;;
   --debug | --debu | --deb | --de | --d | -d )
     debug=: ;;
   --file | --fil | --fi | --f )
     $ac_shift
     case $ac_optarg in
-    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
     '') as_fn_error $? "missing file argument" ;;
     esac
     as_fn_append CONFIG_FILES " '$ac_optarg'"
@@ -12276,7 +15644,7 @@
   --header | --heade | --head | --hea )
     $ac_shift
     case $ac_optarg in
-    *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *\'*) ac_optarg=`printf "%s\n" "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
     esac
     as_fn_append CONFIG_HEADERS " '$ac_optarg'"
     ac_need_defaults=false;;
@@ -12285,7 +15653,7 @@
     as_fn_error $? "ambiguous option: \`$1'
 Try \`$0 --help' for more information.";;
   --help | --hel | -h )
-    $as_echo "$ac_cs_usage"; exit ;;
+    printf "%s\n" "$ac_cs_usage"; exit ;;
   -q | -quiet | --quiet | --quie | --qui | --qu | --q \
   | -silent | --silent | --silen | --sile | --sil | --si | --s)
     ac_cs_silent=: ;;
@@ -12313,7 +15681,7 @@
 if \$ac_cs_recheck; then
   set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
   shift
-  \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+  \printf "%s\n" "running CONFIG_SHELL=$SHELL \$*" >&6
   CONFIG_SHELL='$SHELL'
   export CONFIG_SHELL
   exec "\$@"
@@ -12327,7 +15695,7 @@
   sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
 ## Running $as_me. ##
 _ASBOX
-  $as_echo "$ac_log"
+  printf "%s\n" "$ac_log"
 } >&5
 
 _ACEOF
@@ -12348,28 +15716,26 @@
     "Source/Include/swigconfig.h") CONFIG_HEADERS="$CONFIG_HEADERS Source/Include/swigconfig.h" ;;
     "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
     "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
-    "swig.spec") CONFIG_FILES="$CONFIG_FILES swig.spec" ;;
     "Examples/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/Makefile" ;;
-    "Examples/d/example.mk") CONFIG_FILES="$CONFIG_FILES Examples/d/example.mk" ;;
     "Examples/xml/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/xml/Makefile" ;;
     "Examples/test-suite/errors/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/errors/Makefile" ;;
     "Examples/test-suite/csharp/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/csharp/Makefile" ;;
     "Examples/test-suite/d/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/d/Makefile" ;;
+    "Examples/test-suite/go/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/go/Makefile" ;;
     "Examples/test-suite/guile/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/guile/Makefile" ;;
     "Examples/test-suite/java/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/java/Makefile" ;;
     "Examples/test-suite/javascript/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/javascript/Makefile" ;;
+    "Examples/test-suite/lua/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/lua/Makefile" ;;
     "Examples/test-suite/mzscheme/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/mzscheme/Makefile" ;;
     "Examples/test-suite/ocaml/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/ocaml/Makefile" ;;
     "Examples/test-suite/octave/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/octave/Makefile" ;;
     "Examples/test-suite/perl5/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/perl5/Makefile" ;;
     "Examples/test-suite/php/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/php/Makefile" ;;
     "Examples/test-suite/python/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/python/Makefile" ;;
+    "Examples/test-suite/r/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/r/Makefile" ;;
     "Examples/test-suite/ruby/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/ruby/Makefile" ;;
     "Examples/test-suite/scilab/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/scilab/Makefile" ;;
     "Examples/test-suite/tcl/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/tcl/Makefile" ;;
-    "Examples/test-suite/lua/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/lua/Makefile" ;;
-    "Examples/test-suite/r/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/r/Makefile" ;;
-    "Examples/test-suite/go/Makefile") CONFIG_FILES="$CONFIG_FILES Examples/test-suite/go/Makefile" ;;
     "Source/Makefile") CONFIG_FILES="$CONFIG_FILES Source/Makefile" ;;
     "Tools/javascript/Makefile") CONFIG_FILES="$CONFIG_FILES Tools/javascript/Makefile" ;;
     "preinst-swig") CONFIG_FILES="$CONFIG_FILES preinst-swig" ;;
@@ -12386,9 +15752,9 @@
 # We use the long form for the default assignment because of an extremely
 # bizarre bug on SunOS 4.1.3.
 if $ac_need_defaults; then
-  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
-  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
-  test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+  test ${CONFIG_FILES+y} || CONFIG_FILES=$config_files
+  test ${CONFIG_HEADERS+y} || CONFIG_HEADERS=$config_headers
+  test ${CONFIG_COMMANDS+y} || CONFIG_COMMANDS=$config_commands
 fi
 
 # Have a temporary directory for convenience.  Make it in the build tree
@@ -12724,7 +16090,7 @@
 	   esac ||
 	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
       esac
-      case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+      case $ac_f in *\'*) ac_f=`printf "%s\n" "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
       as_fn_append ac_file_inputs " '$ac_f'"
     done
 
@@ -12732,17 +16098,17 @@
     # use $as_me), people would be surprised to read:
     #    /* config.h.  Generated by config.status.  */
     configure_input='Generated from '`
-	  $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+	  printf "%s\n" "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
 	`' by configure.'
     if test x"$ac_file" != x-; then
       configure_input="$ac_file.  $configure_input"
-      { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
-$as_echo "$as_me: creating $ac_file" >&6;}
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+printf "%s\n" "$as_me: creating $ac_file" >&6;}
     fi
     # Neutralize special characters interpreted by sed in replacement strings.
     case $configure_input in #(
     *\&* | *\|* | *\\* )
-       ac_sed_conf_input=`$as_echo "$configure_input" |
+       ac_sed_conf_input=`printf "%s\n" "$configure_input" |
        sed 's/[\\\\&|]/\\\\&/g'`;; #(
     *) ac_sed_conf_input=$configure_input;;
     esac
@@ -12759,7 +16125,7 @@
 	 X"$ac_file" : 'X\(//\)[^/]' \| \
 	 X"$ac_file" : 'X\(//\)$' \| \
 	 X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$ac_file" |
+printf "%s\n" X"$ac_file" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
 	    s//\1/
 	    q
@@ -12783,9 +16149,9 @@
 case "$ac_dir" in
 .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
 *)
-  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
   # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
   case $ac_top_builddir_sub in
   "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
   *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
@@ -12847,8 +16213,8 @@
 case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
 *datarootdir*) ac_datarootdir_seen=yes;;
 *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
-$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+printf "%s\n" "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
   ac_datarootdir_hack='
@@ -12892,9 +16258,9 @@
   { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
   { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
       "$ac_tmp/out"`; test -z "$ac_out"; } &&
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
 which seems to be undefined.  Please make sure it is defined" >&5
-$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+printf "%s\n" "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
 which seems to be undefined.  Please make sure it is defined" >&2;}
 
   rm -f "$ac_tmp/stdin"
@@ -12910,20 +16276,20 @@
   #
   if test x"$ac_file" != x-; then
     {
-      $as_echo "/* $configure_input  */" \
+      printf "%s\n" "/* $configure_input  */" >&1 \
       && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
     } >"$ac_tmp/config.h" \
       || as_fn_error $? "could not create $ac_file" "$LINENO" 5
     if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
-      { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
-$as_echo "$as_me: $ac_file is unchanged" >&6;}
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
+printf "%s\n" "$as_me: $ac_file is unchanged" >&6;}
     else
       rm -f "$ac_file"
       mv "$ac_tmp/config.h" "$ac_file" \
 	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
     fi
   else
-    $as_echo "/* $configure_input  */" \
+    printf "%s\n" "/* $configure_input  */" >&1 \
       && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
       || as_fn_error $? "could not create -" "$LINENO" 5
   fi
@@ -12943,7 +16309,7 @@
 	 X"$_am_arg" : 'X\(//\)[^/]' \| \
 	 X"$_am_arg" : 'X\(//\)$' \| \
 	 X"$_am_arg" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$_am_arg" |
+printf "%s\n" X"$_am_arg" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
 	    s//\1/
 	    q
@@ -12963,8 +16329,8 @@
 	  s/.*/./; q'`/stamp-h$_am_stamp_count
  ;;
 
-  :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
-$as_echo "$as_me: executing $ac_file commands" >&6;}
+  :C)  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+printf "%s\n" "$as_me: executing $ac_file commands" >&6;}
  ;;
   esac
 
@@ -12990,7 +16356,7 @@
   for am_mf
   do
     # Strip MF so we end up with the name of the file.
-    am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'`
+    am_mf=`printf "%s\n" "$am_mf" | sed -e 's/:.*$//'`
     # Check whether this is an Automake generated Makefile which includes
     # dependency-tracking related rules and includes.
     # Grep'ing the whole file directly is not great: AIX grep has a line
@@ -13002,7 +16368,7 @@
 	 X"$am_mf" : 'X\(//\)[^/]' \| \
 	 X"$am_mf" : 'X\(//\)$' \| \
 	 X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X"$am_mf" |
+printf "%s\n" X"$am_mf" |
     sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
 	    s//\1/
 	    q
@@ -13024,7 +16390,7 @@
 $as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \
 	 X"$am_mf" : 'X\(//\)$' \| \
 	 X"$am_mf" : 'X\(/\)' \| . 2>/dev/null ||
-$as_echo X/"$am_mf" |
+printf "%s\n" X/"$am_mf" |
     sed '/^.*\/\([^/][^/]*\)\/*$/{
 	    s//\1/
 	    q
@@ -13049,10 +16415,12 @@
    (exit $ac_status); } || am_rc=$?
   done
   if test $am_rc -ne 0; then
-    { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+    { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "Something went wrong bootstrapping makefile fragments
-    for automatic dependency tracking.  Try re-running configure with the
+    for automatic dependency tracking.  If GNU make was not used, consider
+    re-running the configure script with MAKE=\"gmake\" (or whatever is
+    necessary).  You can also try re-running configure with the
     '--disable-dependency-tracking' option to at least be able to build
     the package (albeit without support for automatic dependency tracking).
 See \`config.log' for more details" "$LINENO" 5; }
@@ -13067,8 +16435,8 @@
     "preinst-swig":F) chmod +x preinst-swig ;;
     "Examples":C)
   if test "x${srcdir}" != "x." ; then
-    { $as_echo "$as_me:${as_lineno-$LINENO}: generating Examples build tree" >&5
-$as_echo "$as_me: generating Examples build tree" >&6;}
+    { printf "%s\n" "$as_me:${as_lineno-$LINENO}: generating Examples build tree" >&5
+printf "%s\n" "$as_me: generating Examples build tree" >&6;}
     for mkfile in `cd ${srcdir} && find Examples/ -type f -name Makefile`; do
       dir=`dirname ${mkfile}`
       d=${dir}
@@ -13163,7 +16531,7 @@
       ;;
     *)
       case $ac_arg in
-      *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+      *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
       esac
       as_fn_append ac_sub_configure_args " '$ac_arg'" ;;
     esac
@@ -13173,7 +16541,7 @@
   # in subdir configurations.
   ac_arg="--prefix=$prefix"
   case $ac_arg in
-  *\'*) ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+  *\'*) ac_arg=`printf "%s\n" "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
   esac
   ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args"
 
@@ -13194,17 +16562,17 @@
     test -d "$srcdir/$ac_dir" || continue
 
     ac_msg="=== configuring in $ac_dir (`pwd`/$ac_dir)"
-    $as_echo "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5
-    $as_echo "$ac_msg" >&6
+    printf "%s\n" "$as_me:${as_lineno-$LINENO}: $ac_msg" >&5
+    printf "%s\n" "$ac_msg" >&6
     as_dir="$ac_dir"; as_fn_mkdir_p
     ac_builddir=.
 
 case "$ac_dir" in
 .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
 *)
-  ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+  ac_dir_suffix=/`printf "%s\n" "$ac_dir" | sed 's|^\.[\\/]||'`
   # A ".." for each directory in $ac_dir_suffix.
-  ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+  ac_top_builddir_sub=`printf "%s\n" "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
   case $ac_top_builddir_sub in
   "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
   *)  ac_top_build_prefix=$ac_top_builddir_sub/ ;;
@@ -13234,17 +16602,15 @@
 
     cd "$ac_dir"
 
-    # Check for guested configure; otherwise get Cygnus style configure.
+    # Check for configure.gnu first; this name is used for a wrapper for
+    # Metaconfig's "Configure" on case-insensitive file systems.
     if test -f "$ac_srcdir/configure.gnu"; then
       ac_sub_configure=$ac_srcdir/configure.gnu
     elif test -f "$ac_srcdir/configure"; then
       ac_sub_configure=$ac_srcdir/configure
-    elif test -f "$ac_srcdir/configure.in"; then
-      # This should be Cygnus configure.
-      ac_sub_configure=$ac_aux_dir/configure
     else
-      { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5
-$as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2;}
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: no configuration information is in $ac_dir" >&5
+printf "%s\n" "$as_me: WARNING: no configuration information is in $ac_dir" >&2;}
       ac_sub_configure=
     fi
 
@@ -13257,8 +16623,8 @@
 	ac_sub_cache_file=$ac_top_build_prefix$cache_file ;;
       esac
 
-      { $as_echo "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5
-$as_echo "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;}
+      { printf "%s\n" "$as_me:${as_lineno-$LINENO}: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&5
+printf "%s\n" "$as_me: running $SHELL $ac_sub_configure $ac_sub_configure_args --cache-file=$ac_sub_cache_file --srcdir=$ac_srcdir" >&6;}
       # The eval makes quoting arguments work.
       eval "\$SHELL \"\$ac_sub_configure\" $ac_sub_configure_args \
 	   --cache-file=\"\$ac_sub_cache_file\" --srcdir=\"\$ac_srcdir\"" ||
@@ -13269,8 +16635,8 @@
   done
 fi
 if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
-$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+  { printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+printf "%s\n" "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
 fi
 
 
@@ -13298,3 +16664,4 @@
 $langs
 "
 
+
diff --git a/configure.ac b/configure.ac
index 63509cd..7ab65a8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,8 +2,8 @@
 dnl The macros which aren't shipped with the autotools are stored in the
 dnl Tools/config directory in .m4 files.
 
-AC_INIT([swig],[4.0.1],[http://www.swig.org])
-AC_PREREQ(2.60)
+AC_INIT([swig],[4.2.1],[https://www.swig.org])
+AC_PREREQ([2.60])
 
 AC_CONFIG_SRCDIR([Source/Swig/swig.h])
 AC_CONFIG_AUX_DIR([Tools/config])
@@ -26,63 +26,61 @@
 
 AC_COMPILE_WARNINGS # Increase warning levels
 
+AC_MSG_CHECKING([CFLAGS to compile SWIG executable])
+AC_MSG_RESULT([$CFLAGS])
+AC_MSG_CHECKING([CXXFLAGS to compile SWIG executable])
+AC_MSG_RESULT([$CXXFLAGS])
+
 AC_DEFINE_UNQUOTED(SWIG_CXX, ["$CXX"], [Compiler that built SWIG])
 AC_DEFINE_UNQUOTED(SWIG_PLATFORM, ["$host"], [Platform that SWIG is built for])
 
-dnl Checks for header files.
-AC_HEADER_STDC
-
-dnl Look for popen
-AC_ARG_WITH(popen, AS_HELP_STRING([--without-popen], [Disable popen]), with_popen="$withval")
-if test x"${with_popen}" = xno ; then
-AC_MSG_NOTICE([Disabling popen])
-else
-AC_CHECK_FUNC(popen, AC_DEFINE(HAVE_POPEN, 1, [Define if popen is available]), AC_MSG_NOTICE([Disabling popen]))
-fi
+# For AC_EGREP_CPP
+AC_PROG_EGREP
 
 dnl PCRE
 AC_ARG_WITH([pcre],
   [AS_HELP_STRING([--without-pcre],
-                  [Disable support for regular expressions using PCRE])],
+                  [Disable support for regular expressions using PCRE2])],
   [],
   [with_pcre=yes])
 
-AC_MSG_CHECKING([whether to enable PCRE support])
+AC_MSG_CHECKING([whether to enable PCRE2 support])
 AC_MSG_RESULT([$with_pcre])
 
 dnl To make configuring easier, check for a locally built PCRE using the Tools/pcre-build.sh script
 if test x"${with_pcre}" = xyes ; then
-  AC_MSG_CHECKING([whether to use local PCRE])
+  AC_MSG_CHECKING([whether to use local PCRE2])
   local_pcre_config=no
-  if test -z $PCRE_CONFIG; then
-    if test -f `pwd`/pcre/pcre-swig-install/bin/pcre-config; then
-      PCRE_CONFIG=`pwd`/pcre/pcre-swig-install/bin/pcre-config
-      local_pcre_config=$PCRE_CONFIG
+  if test -z "$PCRE2_CONFIG"; then
+    if test -f `pwd`/pcre/pcre-swig-install/bin/pcre2-config; then
+      PCRE2_CONFIG=`pwd`/pcre/pcre-swig-install/bin/pcre2-config
+      local_pcre_config=$PCRE2_CONFIG
     fi
   fi
   AC_MSG_RESULT([$local_pcre_config])
 fi
 AS_IF([test "x$with_pcre" != xno],
-  [AX_PATH_GENERIC([pcre],
+  [AX_PATH_GENERIC([pcre2],
     [], dnl Minimal version of PCRE we need -- accept any
     [], dnl custom sed script for version parsing is not needed
-    [AC_DEFINE([HAVE_PCRE], [1], [Define if you have PCRE library])
-     LIBS="$LIBS $PCRE_LIBS"
-     CPPFLAGS="$CPPFLAGS $PCRE_CFLAGS"
+    [AC_DEFINE([HAVE_PCRE], [1], [Define if you have PCRE2 library])
+     LIBS="$LIBS $PCRE2_LIBS"
+     CPPFLAGS="$CPPFLAGS $PCRE2_CFLAGS"
     ],
     [AC_MSG_FAILURE([
-        Cannot find pcre-config script from PCRE (Perl Compatible Regular Expressions)
+        Cannot find pcre2-config script from PCRE2 (Perl Compatible Regular Expressions)
         library package. This dependency is needed for configure to complete,
         Either:
-        - Install the PCRE developer package on your system (preferred approach).
-        - Download the PCRE source tarball, build and install on your system
+        - Install the PCRE2 developer package on your system (preferred approach).
+        - Download the PCRE2 source tarball, build and install on your system
           as you would for any package built from source distribution.
-        - Use the Tools/pcre-build.sh script to build PCRE just for SWIG to statically
+        - Use the Tools/pcre-build.sh script to build PCRE2 just for SWIG to statically
           link against. Run 'Tools/pcre-build.sh --help' for instructions.
-          (quite easy and does not require privileges to install PCRE on your system)
+          (quite easy and does not require privileges to install PCRE2 on your system)
         - Use configure --without-pcre to disable regular expressions support in SWIG
           (not recommended).])
-    ])
+    ],
+    [],[],[--libs8])
   ])
 
 
@@ -103,7 +101,7 @@
 echo "Note : None of the following packages are required for users to compile and install SWIG from the distributed tarball"
 echo ""
 
-AC_PROG_YACC
+AC_CHECK_PROGS([BISON], [bison], [$MISSING bison])
 
 echo ""
 echo "Checking for installed target languages and other information in order to compile and run"
@@ -115,15 +113,6 @@
 AX_BOOST_BASE(,,,)
 AC_SUBST(BOOST_CPPFLAGS)
 
-dnl How to specify include directories that may be system directories.
-# -I should not be used on system directories (GCC)
-if test "$GCC" = yes; then
-    ISYSTEM="-isystem "
-else
-    ISYSTEM="-I"
-fi
-AC_MSG_NOTICE(ISYSTEM: $ISYSTEM)
-
 dnl Info for building shared libraries ... in order to run the examples
 
 # SO is the extension of shared libraries (including the dot!)
@@ -147,17 +136,17 @@
 if test -z "$LDSHARED"
 then
 	case $host in
-	*-*-aix*) LDSHARED="\$(srcdir)/ld_so_aix \$(CC)";;
+	*-*-aix*) LDSHARED="$CC -shared";;
 	*-*-cygwin* | *-*-mingw*)
             if test "$GCC" = yes; then
-                LDSHARED="$CC -shared"
+                LDSHARED="\$(CC) -shared"
             else
                 if test "cl" = $CC ;  then
                     # Microsoft Visual C++ (MSVC)
-                    LDSHARED="$CC -nologo -LD"
+                    LDSHARED="\$(CC) -nologo -LD"
                 else
                     # Unknown compiler try gcc approach
-                    LDSHARED="$CC -shared"
+                    LDSHARED="\$(CC) -shared"
                 fi
             fi ;;
 	*-*-irix5*) LDSHARED="ld -shared";;
@@ -169,25 +158,25 @@
 	*-sequent-sysv4) LDSHARED="ld -G";;
 	*-*-next*)
 		if test "$ns_dyld"
-		then LDSHARED='$(CC) $(LDFLAGS) -bundle -prebind'
-		else LDSHARED='$(CC) $(CFLAGS) -nostdlib -r'
+		then LDSHARED="\$(CC) \$(LDFLAGS) -bundle -prebind"
+		else LDSHARED="\$(CC) \$(CFLAGS) -nostdlib -r"
 		fi
                 if test "$with_next_framework" ; then
 		    LDSHARED="$LDSHARED \$(LDLIBRARY)"
 		fi ;;
-	*-*-linux*) LDSHARED="$CC -shared";;
+	*-*-linux*) LDSHARED="\$(CC) -shared";;
 	*-*-dgux*) LDSHARED="ld -G";;
-	*-*-freebsd3*) LDSHARED="$CC -shared";;
+	*-*-freebsd3*) LDSHARED="\$(CC) -shared";;
 	*-*-freebsd* | *-*-openbsd*) LDSHARED="ld -Bshareable";;
 	*-*-netbsd*)
-		if [[ "`$CC -dM -E - </dev/null | grep __ELF__`" != "" ]]
+		if [[ "`\$(CC) -dM -E - </dev/null | grep __ELF__`" != "" ]]
 		then
-			LDSHARED="$CC -shared"
+			LDSHARED="\$(CC) -shared"
 		else
 			LDSHARED="ld -Bshareable"
 		fi;;
-	*-sco-sysv*) LDSHARED="$CC -G -KPIC -Ki486 -belf -Wl,-Bexport";;
-	*-*-darwin*) LDSHARED="$CC -bundle -undefined suppress -flat_namespace";;
+	*-sco-sysv*) LDSHARED="\$(CC) -G -KPIC -Ki486 -belf -Wl,-Bexport";;
+	*-*-darwin*) LDSHARED="\$(CC) -bundle -undefined suppress -flat_namespace";;
 	*)	LDSHARED="ld";;
 	esac
 fi
@@ -209,23 +198,23 @@
 then
 	case $host in
 	*-*-solaris*) if test "$GCC" = yes
-             then TRYLINKINGWITHCXX="CXXSHARED= $CXX -Wl,-G"
-             else TRYLINKINGWITHCXX="CXXSHARED= $CXX -G -L/opt/SUNWspro/lib -lCrun -lCstd"
+             then TRYLINKINGWITHCXX="CXXSHARED= \$(CXX) -Wl,-G"
+             else TRYLINKINGWITHCXX="CXXSHARED= \$(CXX) -G -L/opt/SUNWspro/lib -lCrun -lCstd"
              fi;;
-        *-*-hp*) TRYLINKINGWITHCXX="CXXSHARED= $CXX +z ";;
-        *-*-darwin*) TRYLINKINGWITHCXX="CXXSHARED= $CXX -bundle -undefined suppress -flat_namespace";;
+        *-*-hp*) TRYLINKINGWITHCXX="CXXSHARED= \$(CXX) +z ";;
+        *-*-darwin*) TRYLINKINGWITHCXX="CXXSHARED= \$(CXX) -bundle -undefined suppress -flat_namespace";;
         *-*-cygwin* | *-*-mingw*)
             if test "$GCC" = yes; then
-                TRYLINKINGWITHCXX="CXXSHARED= $CXX -shared "
+                TRYLINKINGWITHCXX="CXXSHARED= \$(CXX) -shared "
             else
                 if test "cl" = $CXX ;  then
                     # Microsoft Visual C++ (MSVC)
-                    TRYLINKINGWITHCXX="CXXSHARED= $CXX -nologo -LD"
+                    TRYLINKINGWITHCXX="CXXSHARED= \$(CXX) -nologo -LD"
                 else
                     TRYLINKINGWITHCXX="#unknown Windows compiler"
                 fi
             fi ;;
-        *)       TRYLINKINGWITHCXX="CXXSHARED= $CXX -shared ";;
+        *)       TRYLINKINGWITHCXX="CXXSHARED= \$(CXX) -shared ";;
         esac
 fi
 AC_MSG_RESULT($TRYLINKINGWITHCXX)
@@ -285,40 +274,87 @@
 AC_MSG_RESULT($LINKFORSHARED)
 
 # Optional CFLAGS used to silence/enhance compiler warnings on some platforms.
-AC_MSG_CHECKING(PLATCFLAGS)
+AC_MSG_CHECKING(CFLAGS to use for testing (PLATCFLAGS))
 case $host in
   *-*-solaris*) if test "$GCC" = yes
     then PLATCFLAGS=
     else PLATCFLAGS=
       #    else PLATCFLAGS="-errtags=yes" # Need more work as C examples use ld for linking
     fi;;
+  *-*-aix*) PLATCFLAGS="$CFLAGS";;
   *) PLATCFLAGS=
 esac
 AC_MSG_RESULT($PLATCFLAGS)
 
 # Add switch if necessary to enable C++11 support - just for tests
-AC_ARG_ENABLE([cpp11-testing], AS_HELP_STRING([--enable-cpp11-testing], [enable C++11 testing if supported by compiler (default disabled)]), [enable_cpp11_testing=$enableval], [enable_cpp11_testing=no])
-AC_MSG_CHECKING([whether to enable C++11 testing])
+AC_ARG_ENABLE([cpp11-testing], AS_HELP_STRING([--disable-cpp11-testing], [disable C++11 and later C++ standards testing even if supported by compiler (default enabled)]), [enable_cpp11_testing=$enableval], [enable_cpp11_testing=yes])
+AC_MSG_CHECKING([whether to attempt to enable C++11 and later C++ standards testing])
 AC_MSG_RESULT([$enable_cpp11_testing])
 
 PLATCXXFLAGS="$PLATCFLAGS"
 if test x"$enable_cpp11_testing" = xyes; then
-  AC_LANG_PUSH([C++])
-  CXXFLAGS_SAVED=$CXXFLAGS
-  CXXFLAGS=
-  AX_CXX_COMPILE_STDCXX_11([noext], [nostop])
-  CXXFLAGS=$CXXFLAGS_SAVED
-  AC_LANG_POP([C++])
-  if test x"$CXX11FLAGS" != x; then
-    PLATCXXFLAGS="$CXX11FLAGS $PLATCXXFLAGS"
-  fi
-  AC_MSG_CHECKING([for C++11 enabled compiler])
-  if test x"$HAVE_CXX11_COMPILER" = x; then
-    AC_MSG_RESULT([no])
+  CXX_SAVED=$CXX
+  CXXCPP_SAVED=$CXXCPP
+
+  # Test for c++20
+  CXXCPP=" "
+  AX_CXX_COMPILE_STDCXX(20, [noext], [optional])
+  AC_MSG_CHECKING([whether C++11 to C++20 testing is enabled])
+  if test "$HAVE_CXX20" = "1"; then
+    AC_MSG_RESULT([yes])
+    PLATCXXFLAGS="$CXXCPP $PLATCXXFLAGS"
+    HAVE_CXX17="1"
+    HAVE_CXX14="1"
+    HAVE_CXX11="1"
   else
-    AC_MSG_RESULT([$HAVE_CXX11_COMPILER])
+    AC_MSG_RESULT([no])
+
+    # Test for c++17
+    CXXCPP=" "
+    AX_CXX_COMPILE_STDCXX(17, [noext], [optional])
+    AC_MSG_CHECKING([whether C++11 to C++17 testing is enabled])
+    if test "$HAVE_CXX17" = "1"; then
+      AC_MSG_RESULT([yes])
+      PLATCXXFLAGS="$CXXCPP $PLATCXXFLAGS"
+      HAVE_CXX14="1"
+      HAVE_CXX11="1"
+    else
+      AC_MSG_RESULT([no])
+
+      # Test for c++14
+      CXXCPP=" "
+      CXX=$CXX_SAVED
+      AX_CXX_COMPILE_STDCXX(14, [noext], [optional])
+      AC_MSG_CHECKING([whether C++11 to C++14 testing is enabled])
+      if test "$HAVE_CXX14" = "1"; then
+        AC_MSG_RESULT([yes])
+        PLATCXXFLAGS="$CXXCPP $PLATCXXFLAGS"
+        HAVE_CXX11="1"
+      else
+        AC_MSG_RESULT([no])
+
+        # Test for c++11
+        CXXCPP=" "
+        CXX=$CXX_SAVED
+        AX_CXX_COMPILE_STDCXX(11, [noext], [optional])
+        AC_MSG_CHECKING([whether C++11 testing is enabled])
+        if test "$HAVE_CXX11" = "1"; then
+          AC_MSG_RESULT([yes])
+          PLATCXXFLAGS="$CXXCPP $PLATCXXFLAGS"
+        else
+          AC_MSG_RESULT([no])
+        fi
+      fi
+    fi
   fi
+
+  CXX=$CXX_SAVED
+  CXXCPP=$CXXCPP_SAVED
 fi
+AC_SUBST(HAVE_CXX11)
+AC_SUBST(HAVE_CXX14)
+AC_SUBST(HAVE_CXX17)
+AC_SUBST(HAVE_CXX20)
 
 # On darwin 10.7,10.8,10.9 using clang++, need to ensure using
 # libc++ for tests and examples to run under mono. May affect
@@ -333,6 +369,43 @@
   *) ;;
 esac
 
+AC_MSG_CHECKING(CXXFLAGS to use for testing (PLATCXXFLAGS))
+PLATCXXFLAGS=$(echo $PLATCXXFLAGS | xargs) # Trim whitespace
+AC_MSG_RESULT([$PLATCXXFLAGS])
+
+# Check for compiler pre-compiled header support
+AC_MSG_CHECKING([if compiler supports pre-compiled headers])
+PCHSUPPORT=no
+if test "$CLANGXX" = "yes"; then
+   PCHINCLUDEARG="-include-pch"
+   PCHINCLUDEEXT=".gch"
+else
+   PCHINCLUDEARG="-include"
+   PCHINCLUDEEXT=""
+fi
+AC_LANG_PUSH([C++])
+echo '#include <cstdlib>' > conftest.hpp
+echo '#include "conftest.hpp"' > conftest.cpp
+$CXX -c conftest.hpp 2>/dev/null
+if test $? -eq 0; then
+   if test -f conftest.hpp.gch; then
+      $CXX -H -c -I. ${PCHINCLUDEARG} ./conftest.hpp${PCHINCLUDEEXT} -o conftest.o conftest.cpp >conftest.out 2>&1
+      if test $? -eq 0; then
+         if test "$CLANGXX" = "yes"; then
+            PCHSUPPORT=yes
+         elif grep -q '^!.*conftest.hpp.gch$' conftest.out; then
+            PCHSUPPORT=yes
+         fi
+      fi
+   fi
+fi
+rm -f conftest.hpp conftest.cpp conftest.out
+AC_LANG_POP([C++])
+AC_MSG_RESULT([$PCHSUPPORT])
+AC_SUBST(PCHSUPPORT)
+AC_SUBST(PCHINCLUDEARG)
+AC_SUBST(PCHINCLUDEEXT)
+
 # Set info about shared libraries.
 AC_SUBST(SO)
 AC_SUBST(LDSHARED)
@@ -342,7 +415,6 @@
 AC_SUBST(RPATH)
 AC_SUBST(PLATCFLAGS)
 AC_SUBST(PLATCXXFLAGS)
-AC_SUBST(HAVE_CXX11_COMPILER)
 AC_SUBST(LINKFORSHARED)
 
 # This variation is needed on OS-X because there is no (apparent) consistency in shared library naming.
@@ -399,10 +471,6 @@
 AC_SEARCH_LIBS(gethostbyname, inet) # Sequent
 AC_SEARCH_LIBS(socket, socket) # SVR4 sockets
 
-AC_CHECK_LIB(swill, swill_init, [SWIGLIBS="-lswill $LIBS" SWILL="-DSWIG_SWILL"])
-AC_SUBST(SWIGLIBS)
-AC_SUBST(SWILL)
-
 # check for --with-libm=...
 AC_SUBST(LIBM)
 LIBM=-lm
@@ -435,810 +503,382 @@
   alllang_default=yes
 fi
 
-AC_CHECK_PROGS(PKGCONFIG, [pkg-config])
-
-#--------------------------------------------------------------------
-# Look for Tcl
-#--------------------------------------------------------------------
-
-TCLINCLUDE=
-TCLLIB=
-TCLPACKAGE=
-
-AC_ARG_WITH(tclconfig, AS_HELP_STRING([--without-tcl], [Disable Tcl])
-AS_HELP_STRING([--with-tclconfig=path], [Set location of tclConfig.sh]), [with_tclconfig="$withval"], [with_tclconfig=])
-AC_ARG_WITH(tcl,
- [  --with-tcl=path         Set location of Tcl package],[
-	TCLPACKAGE="$withval"], [TCLPACKAGE="$alllang_default"])
-AC_ARG_WITH(tclincl,[  --with-tclincl=path     Set location of Tcl include directory],[
-	TCLINCLUDE="$ISYSTEM$withval"], [TCLINCLUDE=])
-AC_ARG_WITH(tcllib,[  --with-tcllib=path      Set location of Tcl library directory],[
-	TCLLIB="-L$withval"], [TCLLIB=])
-
-# First, check for "--without-tcl" or "--with-tcl=no".
-if test x"${TCLPACKAGE}" = xno; then
-AC_MSG_NOTICE([Disabling Tcl])
-else
-AC_MSG_CHECKING([for Tcl configuration])
-# First check to see if --with-tclconfig was specified.
-if test x"${with_tclconfig}" != x ; then
-   if test -f "${with_tclconfig}/tclConfig.sh" ; then
-      TCLCONFIG=`(cd ${with_tclconfig}; pwd)`
-   else
-      AC_MSG_ERROR([${with_tcl} directory does not contain tclConfig.sh])
-   fi
-fi
-# check in a few common install locations
-dirs="/usr/lib*/ /usr/lib*/tcl*/ /usr/local/lib*/ /usr/local/lib*/tcl*/"
-case $host in
-*-*-darwin*)
-  dirs="/System/Library/Frameworks/Tcl.framework/ $dirs"
-  ;;
-*)
-  ;;
-esac
-if test x"${TCLCONFIG}" = x ; then
-  for d in $dirs ; do
-    for i in `ls -d -r $d 2>/dev/null` ; do
-      if test -f $i"tclConfig.sh" ; then
-        TCLCONFIG=`(cd $i; pwd)`
-        break
-      fi
-    done
-  done
-fi
-if test x"${TCLCONFIG}" = x ; then
-    AC_MSG_RESULT(no)
-else
-    AC_MSG_RESULT(found $TCLCONFIG/tclConfig.sh)
-    . $TCLCONFIG/tclConfig.sh
-    if test -z "$TCLINCLUDE"; then
-        TCLINCLUDE=`echo $TCL_INCLUDE_SPEC | sed "s/-I/$ISYSTEM/"`
-    fi
-    if test -z "$TCLLIB"; then
-        TCLLIB=$TCL_LIB_SPEC
-    fi
-fi
-
-if test -z "$TCLINCLUDE"; then
-   if test "x$TCLPACKAGE" != xyes; then
-	TCLINCLUDE="$ISYSTEM$TCLPACKAGE/include"
-   fi
-fi
-
-if test -z "$TCLLIB"; then
-   if test "x$TCLPACKAGE" != xyes; then
-	TCLLIB="-L$TCLPACKAGE/lib -ltcl"
-   fi
-fi
-
-AC_MSG_CHECKING(for Tcl header files)
-if test -z "$TCLINCLUDE"; then
-AC_TRY_CPP([#include <tcl.h>], , TCLINCLUDE="")
-if test -z "$TCLINCLUDE"; then
-	dirs="/usr/local/include /usr/include /opt/local/include"
-	for i in $dirs ; do
-		if test -r $i/tcl.h; then
-			AC_MSG_RESULT($i)
-			TCLINCLUDE="$ISYSTEM$i"
-			break
-		fi
-	done
-fi
-if test -z "$TCLINCLUDE"; then
-    	AC_MSG_RESULT(not found)
-fi
-else
-        AC_MSG_RESULT($TCLINCLUDE)
-fi
-
-AC_MSG_CHECKING(for Tcl library)
-if test -z "$TCLLIB"; then
-dirs="/usr/local/lib /usr/lib /opt/local/lib"
-for i in $dirs ; do
-	if test -r $i/libtcl.a; then
-	    AC_MSG_RESULT($i)
-	    TCLLIB="-L$i -ltcl"
-	    break
-	fi
-done
-if test -z "$TCLLIB"; then
-	AC_MSG_RESULT(not found)
-fi
-else
-AC_MSG_RESULT($TCLLIB)
-fi
-
-# Cygwin (Windows) needs the library for dynamic linking
-case $host in
-*-*-cygwin* | *-*-mingw*) TCLDYNAMICLINKING="$TCLLIB";;
-*)TCLDYNAMICLINKING="";;
-esac
-
-case $host in
-*-*-darwin*)
-    TCLLDSHARED='$(CC) -dynamiclib -undefined suppress -flat_namespace'
-    TCLCXXSHARED='$(CXX) -dynamiclib -undefined suppress -flat_namespace'
-    ;;
-*)
-    TCLLDSHARED='$(LDSHARED)'
-    TCLCXXSHARED='$(CXXSHARED)'
-    ;;
-esac
-
-fi
-
-AC_SUBST(TCLINCLUDE)
-AC_SUBST(TCLLIB)
-AC_SUBST(TCLDYNAMICLINKING)
-AC_SUBST(TCLLDSHARED)
-AC_SUBST(TCLCXXSHARED)
+AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
 
 #----------------------------------------------------------------
-# Look for Python
+# Look for Android
 #----------------------------------------------------------------
 
-PYINCLUDE=
-PYLIB=
-PYLINK=
-PYPACKAGE=
+AC_ARG_WITH(android, AS_HELP_STRING([--without-android], [Disable Android])
+AS_HELP_STRING([--with-android=path], [Set location of android executable]),[ANDROIDBIN="$withval"], [ANDROIDBIN="$alllang_default"])
+AC_ARG_WITH(adb, [  --with-adb=path         Set location of adb executable - Android Debug Bridge],[ADBBIN="$withval"], [ADBBIN=])
+AC_ARG_WITH(ant, [  --with-ant=path         Set location of ant executable for Android],[ANTBIN="$withval"], [ANTBIN=])
+AC_ARG_WITH(ndk-build, [  --with-ndk-build=path   Set location of Android ndk-build executable],[NDKBUILDBIN="$withval"], [NDKBUILDBIN=])
 
-AC_ARG_WITH(python, AS_HELP_STRING([--without-python], [Disable Python])
-AS_HELP_STRING([--with-python=path], [Set location of Python executable]),[ PYBIN="$withval"], [PYBIN="$alllang_default"])
-
-# First, check for "--without-python" or "--with-python=no".
-if test x"${PYBIN}" = xno; then
-  AC_MSG_NOTICE([Disabling Python])
+# First, check for "--without-android" or "--with-android=no".
+if test x"${ANDROIDBIN}" = xno; then
+  AC_MSG_NOTICE([Disabling Android])
+  ANDROID=
 else
-  # First figure out the name of the Python executable
-  if test "x$PYBIN" = xyes; then
-    AC_CHECK_PROGS(PYTHON, [python python2.7])
+  if test "x$ANDROIDBIN" = xyes; then
+    AC_CHECK_PROGS(ANDROID, android)
   else
-    PYTHON="$PYBIN"
+    ANDROID="$ANDROIDBIN"
   fi
 
-  PYVER=0
-  if test -n "$PYTHON"; then
-    AC_MSG_CHECKING([for $PYTHON major version number])
-    PYVER=`($PYTHON -c "import sys; sys.stdout.write(sys.version[[0]])") 2>/dev/null`
-    AC_MSG_RESULT($PYVER)
-    if test -z "$PYVER"; then
-      PYVER=0
-    else
-      AC_MSG_CHECKING(for Python os.name)
-      PYOSNAME=`($PYTHON -c "import sys, os; sys.stdout.write(os.name)") 2>/dev/null`
-      AC_MSG_RESULT($PYOSNAME)
-      AC_MSG_CHECKING(for Python path separator)
-      PYSEPARATOR=`($PYTHON -c "import sys, os; sys.stdout.write(os.sep)") 2>/dev/null`
-      AC_MSG_RESULT($PYSEPARATOR)
-    fi
+  if test -z "$ADBBIN"; then
+    AC_CHECK_PROGS(ADB, adb)
+  else
+    ADB="$ADBBIN"
   fi
 
-  if test $PYVER -eq 1 -o $PYVER -eq 2; then
-    AC_MSG_CHECKING(for Python prefix)
-    PYPREFIX=`($PYTHON -c "import sys; sys.stdout.write(sys.prefix)") 2>/dev/null`
-    AC_MSG_RESULT($PYPREFIX)
-    AC_MSG_CHECKING(for Python exec-prefix)
-    PYEPREFIX=`($PYTHON -c "import sys; sys.stdout.write(sys.exec_prefix)") 2>/dev/null`
-    AC_MSG_RESULT($PYEPREFIX)
-
-    if test x"$PYOSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\"; then
-      # Windows installations are quite different to posix installations (MinGW path separator is a forward slash)
-      PYPREFIX=`echo "$PYPREFIX" | sed -e 's,\\\\,/,g'` # Forward slashes are easier to use and even work on Windows most of the time
-      PYTHON_SO=.pyd
-
-      AC_MSG_CHECKING(for Python header files)
-      if test -r $PYPREFIX/include/Python.h; then
-        PYINCLUDE="-I$PYPREFIX/include"
-      fi
-      AC_MSG_RESULT($PYINCLUDE)
-
-      AC_MSG_CHECKING(for Python library directory)
-      if test -d $PYPREFIX/libs; then
-        PYLIB=$PYPREFIX/libs
-        PYLINKFILE=`ls $PYLIB/python*.lib | grep "python[[0-9]][[0-9]]\.lib"`
-        if test -r "$PYLINKFILE"; then
-          PYLINK=-l`basename $PYLINKFILE | sed -e 's/\.lib$//'`
-        else
-          PYLIB=
-        fi
-      fi
-    else
-      # Note: I could not think of a standard way to get the version string from different versions.
-      # This trick pulls it out of the file location for a standard library file.
-
-      AC_MSG_CHECKING(for Python version)
-
-      # Need to do this hack since autoconf replaces __file__ with the name of the configure file
-      filehack="file__"
-      PYVERSION=`($PYTHON -c "import sys,string,operator,os.path; sys.stdout.write(operator.getitem(os.path.split(operator.getitem(os.path.split(string.__$filehack),0)),1))") 2>/dev/null`
-      AC_MSG_RESULT($PYVERSION)
-
-      # Find the directory for libraries this is necessary to deal with
-      # platforms that can have apps built for multiple archs: e.g. x86_64
-      AC_MSG_CHECKING(for Python lib dir)
-      PYLIBDIR=`($PYTHON -c "import sys; sys.stdout.write(sys.lib)") 2>/dev/null`
-      if test -z "$PYLIBDIR"; then
-        # Fedora patch Python to add sys.lib, for other distros we assume "lib".
-        PYLIBDIR="lib"
-      fi
-      AC_MSG_RESULT($PYLIBDIR)
-
-      # Set the include directory
-
-      AC_MSG_CHECKING(for Python header files)
-      if test -r $PYPREFIX/include/$PYVERSION/Python.h; then
-        PYINCLUDE="-I$PYPREFIX/include/$PYVERSION -I$PYEPREFIX/$PYLIBDIR/$PYVERSION/config"
-      fi
-      if test -z "$PYINCLUDE"; then
-        if test -r $PYPREFIX/include/Py/Python.h; then
-          PYINCLUDE="-I$PYPREFIX/include/Py -I$PYEPREFIX/$PYLIBDIR/python/lib"
-        fi
-      fi
-      AC_MSG_RESULT($PYINCLUDE)
-
-      # Set the library directory blindly.   This probably won't work with older versions
-      AC_MSG_CHECKING(for Python library directory)
-      dirs="$PYVERSION/config $PYVERSION/$PYLIBDIR python/$PYLIBDIR"
-      for i in $dirs; do
-        if test -d $PYEPREFIX/$PYLIBDIR/$i; then
-          PYLIB="$PYEPREFIX/$PYLIBDIR/$i"
-          break
-        fi
-      done
-
-      PYLINK="-l$PYVERSION"
-    fi
-
-    if test -z "$PYLIB"; then
-      AC_MSG_RESULT(Not found)
-    else
-      AC_MSG_RESULT($PYLIB)
-    fi
-    AC_MSG_CHECKING(for Python library)
-    if test -z "$PYLINK"; then
-      AC_MSG_RESULT(Not found)
-    else
-      AC_MSG_RESULT($PYLINK)
-    fi
+  if test -z "$ANTBIN"; then
+    AC_CHECK_PROGS(ANT, ant)
+  else
+    ANT="$ANTBIN"
   fi
 
-  # Cygwin (Windows) needs the library for dynamic linking
+  if test -z "$NDKBUILDBIN"; then
+    AC_CHECK_PROGS(NDKBUILD, ndk-build)
+  else
+    NDKBUILD="$NDKBUILDBIN"
+  fi
+fi
+
+AC_SUBST(ANDROID)
+AC_SUBST(ADB)
+AC_SUBST(ANT)
+AC_SUBST(NDKBUILD)
+
+#----------------------------------------------------------------
+# Look for C#
+#----------------------------------------------------------------
+
+AC_ARG_WITH(csharp, AS_HELP_STRING([--without-csharp], [Disable CSharp]), [with_csharp="$withval"], [with_csharp="$alllang_default"])
+AC_ARG_WITH(cil-interpreter, [  --with-cil-interpreter=path     Set location of CIL interpreter for CSharp],[CSHARPBIN="$withval"], [CSHARPBIN=])
+AC_ARG_WITH(csharp-compiler, [  --with-csharp-compiler=path     Set location of CSharp compiler],[CSHARPCOMPILERBIN="$withval"], [CSHARPCOMPILERBIN=])
+
+# First, check for "--without-csharp" or "--with-csharp=no".
+if test x"${with_csharp}" = xno; then
+AC_MSG_NOTICE([Disabling CSharp])
+CSHARPCOMPILER=
+else
+
+if test -z "$CSHARPCOMPILERBIN" ; then
   case $host in
   *-*-cygwin* | *-*-mingw*)
-    PYTHONDYNAMICLINKING="-L$PYLIB $PYLINK"
-    DEFS="-DUSE_DL_IMPORT $DEFS"
+    # prefer unified Mono mcs compiler (not to be confused with the ancient .NET 1 mcs) over older/alternative names.
+    AC_CHECK_PROGS(CSHARPCOMPILER, csc mcs mono-csc gmcs cscc)
+    if test -n "$CSHARPCOMPILER" && test "$CSHARPCOMPILER" = "csc" ; then
+      AC_MSG_CHECKING(whether csc is the Microsoft CSharp compiler)
+      csc 2>/dev/null | grep "C#" > /dev/null || CSHARPCOMPILER=""
+      if test -z "$CSHARPCOMPILER" ; then
+        AC_MSG_RESULT(no)
+        AC_CHECK_PROGS(CSHARPCOMPILER, mcs mono-csc gmcs cscc)
+      else
+        AC_MSG_RESULT(yes)
+      fi
+    fi
     ;;
-  *)PYTHONDYNAMICLINKING="";;
+  *)AC_CHECK_PROGS(CSHARPCOMPILER, mono-csc gmcs mcs cscc);;
   esac
+else
+  CSHARPCOMPILER="$CSHARPCOMPILERBIN"
 fi
 
-AC_SUBST(PYINCLUDE)
-AC_SUBST(PYLIB)
-AC_SUBST(PYLINK)
-AC_SUBST(PYTHONDYNAMICLINKING)
-
-
-#----------------------------------------------------------------
-# Look for Python 3.x
-#----------------------------------------------------------------
-
-PY3INCLUDE=
-PY3LIB=
-PY3LINK=
-PY3PACKAGE=
-
-AC_ARG_WITH(python3, AS_HELP_STRING([--without-python3], [Disable Python 3.x support])
-AS_HELP_STRING([--with-python3=path], [Set location of Python 3.x executable]),[ PY3BIN="$withval"], [PY3BIN="$alllang_default"])
-
-# First, check for "--without-python3" or "--with-python3=no".
-if test x"${PY3BIN}" = xno; then
-  AC_MSG_NOTICE([Disabling Python 3.x support])
-else
-  if test -z "$PYVER"; then
-    PYVER=0
-  fi
-  if test "x$PY3BIN" = xyes; then
-    if test x"$PYOSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\" -a $PYVER -ge 3; then
-      PYTHON3="$PYTHON"
+CSHARPCONVERTPATH="Tools/convertpath -u"
+if test -z "$CSHARPBIN" ; then
+  CSHARPCILINTERPRETER=""
+  CSHARPCILINTERPRETER_FLAGS=""
+  if test "cscc" = "$CSHARPCOMPILER" ; then
+    AC_CHECK_PROGS(CSHARPCILINTERPRETER, ilrun)
+  else
+    if test "mcs" = "$CSHARPCOMPILER"; then
+      # Check that mcs is the C# compiler and not the Unix mcs utility by examining the output of 'mcs --version'
+      # The Mono compiler should emit: Mono C# compiler version a.b.c.d
+      csharp_version_raw=`(mcs --version) 2>/dev/null`
+      csharp_version_searched=`(mcs --version | sed -e "/C#/b" -e "/Mono/b" -e d) 2>/dev/null` # return string if contains 'Mono' or 'C#'
+      CSHARPCOMPILER=""
+      if test -n "$csharp_version_raw" ; then
+        if test "$csharp_version_raw" = "$csharp_version_searched" ; then
+          CSHARPCOMPILER="mcs"
+        fi
+      fi
+      if test "mcs" != "$CSHARPCOMPILER" ; then
+        echo "mcs is not a working Mono C# compiler"
+      fi
+    fi
+    if test "mcs" = "$CSHARPCOMPILER" || test "gmcs" = "$CSHARPCOMPILER" || test "mono-csc" = "$CSHARPCOMPILER"; then
+        AC_CHECK_PROGS(CSHARPCILINTERPRETER, mono) # Mono JIT
+        CSHARPCILINTERPRETER_FLAGS="--debug"
     else
-      for py_ver in 3 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 ""; do
-        AC_CHECK_PROGS(PYTHON3, [python$py_ver])
-        if test -n "$PYTHON3"; then
-          AC_CHECK_PROGS(PY3CONFIG, [$PYTHON3-config])
-          if test -n "$PY3CONFIG"; then
-            break
-          fi
-        fi
-      done
-    fi
-  else
-    PYTHON3="$PY3BIN"
-    AC_CHECK_PROGS(PY3CONFIG, [$PYTHON3-config])
-  fi
-
-  if test -n "$PYTHON3"; then
-    AC_MSG_CHECKING([for $PYTHON3 major version number])
-    PYVER=`($PYTHON3 -c "import sys; sys.stdout.write(sys.version[[0]])") 2>/dev/null`
-    AC_MSG_RESULT($PYVER)
-    if test -z "$PYVER"; then
-      PYVER=0
-    fi
-  fi
-
-  if test $PYVER -ge 3; then
-    AC_MSG_CHECKING(for Python 3.x os.name)
-    PY3OSNAME=`($PYTHON3 -c "import sys, os; sys.stdout.write(os.name)") 2>/dev/null`
-    AC_MSG_RESULT($PY3OSNAME)
-    AC_MSG_CHECKING(for Python 3.x path separator)
-    PYSEPARATOR=`($PYTHON3 -c "import sys, os; sys.stdout.write(os.sep)") 2>/dev/null`
-    AC_MSG_RESULT($PYSEPARATOR)
-
-    if test x"$PY3OSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\"; then
-      # Windows installations are quite different to posix installations
-      # There is no python-config to use
-      AC_MSG_CHECKING(for Python 3.x prefix)
-      PY3PREFIX=`($PYTHON3 -c "import sys; sys.stdout.write(sys.prefix)") 2>/dev/null`
-      AC_MSG_RESULT($PY3PREFIX)
-      PY3PREFIX=`echo "$PY3PREFIX" | sed -e 's,\\\\,/,g'` # Forward slashes are easier to use and even work on Windows most of the time
-      PYTHON_SO=.pyd
-
-      AC_MSG_CHECKING(for Python 3.x header files)
-      if test -r $PY3PREFIX/include/Python.h; then
-        PY3INCLUDE="-I$PY3PREFIX/include"
-      fi
-      AC_MSG_RESULT($PY3INCLUDE)
-
-      AC_MSG_CHECKING(for Python 3.x library directory)
-      if test -d $PY3PREFIX/libs; then
-        PY3LIB=$PY3PREFIX/libs
-        PY3LINKFILE=`ls $PY3LIB/python*.lib | grep "python[[0-9]][[0-9]]\.lib"`
-        if test -r "$PY3LINKFILE"; then
-          PY3LINK=-l`basename $PY3LINKFILE | sed -e 's/\.lib$//'`
-        else
-          PY3LIB=
-        fi
-      fi
-      if test -z "$PY3LIB"; then
-        AC_MSG_RESULT([Not found])
-      else
-        AC_MSG_RESULT($PY3LIB)
-      fi
-      AC_MSG_CHECKING([for Python 3.x library])
-      if test -z "$PY3LINK"; then
-        AC_MSG_RESULT(Not found)
-      else
-        AC_MSG_RESULT($PY3LINK)
-      fi
-    elif test -n "$PY3CONFIG"; then
-      AC_MSG_CHECKING([for Python 3.x prefix])
-      PY3PREFIX=`($PY3CONFIG --prefix) 2>/dev/null`
-      AC_MSG_RESULT($PY3PREFIX)
-      AC_MSG_CHECKING(for Python 3.x exec-prefix)
-      # Piped through xargs to strip trailing whitespace (bug in msys2 + mingw Python)
-      PY3EPREFIX=`($PY3CONFIG --exec-prefix | xargs) 2>/dev/null`
-      AC_MSG_RESULT($PY3EPREFIX)
-
-      # Note: I could not think of a standard way to get the version string from different versions.
-      # This trick pulls it out of the file location for a standard library file.
-
-      AC_MSG_CHECKING([for Python 3.x version])
-
-      # Need to do this hack since autoconf replaces __file__ with the name of the configure file
-      filehack="file__"
-      PY3VERSION=`($PYTHON3 -c "import string,operator,os.path; print(operator.getitem(os.path.split(operator.getitem(os.path.split(string.__$filehack),0)),1))") 2>/dev/null`
-      AC_MSG_RESULT($PY3VERSION)
-
-      # Find the directory for libraries this is necessary to deal with
-      # platforms that can have apps built for multiple archs: e.g. x86_64
-      AC_MSG_CHECKING([for Python 3.x lib dir])
-      PY3LIBDIR=`($PYTHON3 -c "import sys; print(sys.lib)") 2>/dev/null`
-      if test -z "$PY3LIBDIR"; then
-        # some dists don't have sys.lib  so the best we can do is assume lib
-        PY3LIBDIR="lib"
-      fi
-      AC_MSG_RESULT($PY3LIBDIR)
-
-      # Set the include directory
-
-      AC_MSG_CHECKING([for Python 3.x header files])
-      PY3INCLUDE=`($PY3CONFIG --includes) 2>/dev/null`
-      AC_MSG_RESULT($PY3INCLUDE)
-
-      # Set the library directory blindly.   This probably won't work with older versions
-      AC_MSG_CHECKING([for Python 3.x library directory])
-      dirs="$PY3VERSION/config $PY3VERSION/$PY3LIBDIR python/$PY3LIBDIR"
-      for i in $dirs; do
-        if test -d $PY3EPREFIX/$PY3LIBDIR/$i; then
-          PY3LIB="$PY3EPREFIX/$PY3LIBDIR/$i"
-          break
-        fi
-      done
-      if test -z "$PY3LIB"; then
-        AC_MSG_RESULT([Not found])
-      else
-        AC_MSG_RESULT($PY3LIB)
-      fi
-
-      PY3LINK="-l$PY3VERSION"
-
-      AC_MSG_CHECKING([for Python 3.x library])
-      if test -z "$PY3LINK"; then
-        AC_MSG_RESULT(Not found)
-      else
-        AC_MSG_RESULT($PY3LINK)
+      if test "csc" = "$CSHARPCOMPILER"; then
+          CSHARPCONVERTPATH="Tools/convertpath -w"
       fi
     fi
   fi
-
-  # Cygwin (Windows) needs the library for dynamic linking
-  case $host in
-  *-*-cygwin* | *-*-mingw*)
-    PYTHON3DYNAMICLINKING="-L$PY3LIB $PY3LINK"
-    DEFS="-DUSE_DL_IMPORT $DEFS"
-    ;;
-  *)PYTHON3DYNAMICLINKING="";;
-  esac
-
-  AC_SUBST(PY3INCLUDE)
-  AC_SUBST(PY3LIB)
-  AC_SUBST(PY3LINK)
-  AC_SUBST(PYTHON3DYNAMICLINKING)
-fi
-
-if test -n "$PYINCLUDE" || test -n "$PY3INCLUDE" ; then
-  AC_CHECK_PROGS(PYCODESTYLE, pycodestyle)
-  if test -n "$PYCODESTYLE"; then
-    AC_MSG_CHECKING(pycodestyle version)
-    pycodestyle_version=`$PYCODESTYLE --version 2>/dev/null`
-    AC_MSG_RESULT($pycodestyle_version)
-  fi
-fi
-
-AC_ARG_WITH(2to3, AS_HELP_STRING([--with-2to3=path], [Set location of Python 2to3 tool]), [PY2TO3BIN="$withval"], [PY2TO3BIN="yes"])
-if test -n "$PYTHON3"; then
-  if test "x$PY2TO3BIN" = xyes; then
-    py3to2=`echo $PYTHON3 | sed -e "s/python/2to3-/"`
-    AC_CHECK_PROGS(PY2TO3, $py3to2 2to3)
-    if test -z "$PY2TO3"; then
-      # Windows distributions don't always have the 2to3 executable
-      AC_MSG_CHECKING(for 2to3.py)
-      py2to3script="$PY3PREFIX/Tools/scripts/2to3.py"
-      if test -f "$py2to3script"; then
-        AC_MSG_RESULT($py2to3script)
-        PY2TO3="$PYTHON3 $py2to3script"
-      else
-        AC_MSG_RESULT(Not found)
-      fi
-    fi
-  else
-    PY2TO3="$PY2TO3BIN"
-  fi
-  if test -z "$PY2TO3"; then
-    PYTHON3=
-  fi
-fi
-
-#----------------------------------------------------------------
-# Look for Perl5
-#----------------------------------------------------------------
-
-PERLBIN=
-
-AC_ARG_WITH(perl5, AS_HELP_STRING([--without-perl5], [Disable Perl5])
-AS_HELP_STRING([--with-perl5=path], [Set location of Perl5 executable]),[ PERLBIN="$withval"], [PERLBIN="$alllang_default"])
-
-# First, check for "--without-perl5" or "--with-perl5=no".
-if test x"${PERLBIN}" = xno; then
-AC_MSG_NOTICE([Disabling Perl5])
-PERL=
 else
-
-# First figure out what the name of Perl5 is
-
-if test "x$PERLBIN" = xyes; then
-AC_CHECK_PROGS(PERL, perl perl5.6.1 perl5.6.0 perl5.004 perl5.003 perl5.002 perl5.001 perl5 perl)
-else
-PERL="$PERLBIN"
+  CSHARPCILINTERPRETER="$CSHARPBIN"
 fi
 
-
-# This could probably be simplified as for all platforms and all versions of Perl the following apparently should be run to get the compilation options:
-# perl -MExtUtils::Embed -e ccopts
-AC_MSG_CHECKING(for Perl5 header files)
-if test -n "$PERL"; then
-	PERL5DIR=`($PERL -MConfig -le 'print $Config{archlibexp}') 2>/dev/null`
-	if test -n "$PERL5DIR" ; then
-		dirs="$PERL5DIR $PERL5DIR/CORE"
-		PERL5EXT=none
-		for i in $dirs; do
-			if test -r $i/perl.h; then
-				AC_MSG_RESULT($i)
-				PERL5EXT="$i"
-				break
-			fi
-		done
-		if test "$PERL5EXT" = none; then
-			PERL5EXT="$PERL5DIR/CORE"
-			AC_MSG_RESULT(could not locate perl.h...using $PERL5EXT)
-		fi
-
-		AC_MSG_CHECKING(for Perl5 library)
-		PERL5LIB=`($PERL -e 'use Config; $_=$Config{libperl}; s/^lib//; s/$Config{_a}$//; s/\.$Config{so}.*//; print $_, "\n"') 2>/dev/null`
-		if test -z "$PERL5LIB" ; then
-			AC_MSG_RESULT(not found)
-		else
-			AC_MSG_RESULT($PERL5LIB)
-		fi
-    AC_MSG_CHECKING(for Perl5 ccflags)
- 		PERL5CCFLAGS=`($PERL -e 'use Config; print $Config{ccflags}, "\n"' | sed "s/-Wdeclaration-after-statement//" | sed "s/-I/$ISYSTEM/") 2>/dev/null`
- 		if test -z "$PERL5CCFLAGS" ; then
- 			AC_MSG_RESULT(not found)
- 		else
- 			AC_MSG_RESULT($PERL5CCFLAGS)
- 		fi
-    AC_MSG_CHECKING(for Perl5 ccdlflags)
-    PERL5CCDLFLAGS=`($PERL -e 'use Config; print $Config{ccdlflags}, "\n"') 2>/dev/null`
-    if test -z "$PERL5CCDLFLAGS" ; then
-      AC_MSG_RESULT(not found)
-      else
-      AC_MSG_RESULT($PERL5CCDLFLAGS)
-    fi
-    AC_MSG_CHECKING(for Perl5 cccdlflags)
-    PERL5CCCDLFLAGS=`($PERL -e 'use Config; print $Config{cccdlflags}, "\n"') 2>/dev/null`
-    if test -z "$PERL5CCCDLFLAGS" ; then
-      AC_MSG_RESULT(not found)
-      else
-      AC_MSG_RESULT($PERL5CCCDLFLAGS)
-    fi
-    AC_MSG_CHECKING(for Perl5 ldflags)
-    PERL5LDFLAGS=`($PERL -e 'use Config; print $Config{ldflags}, "\n"') 2>/dev/null`
-    if test -z "$PERL5LDFLAGS" ; then
-      AC_MSG_RESULT(not found)
-      else
-      AC_MSG_RESULT($PERL5LDFLAGS)
-    fi
-    AC_MSG_CHECKING(for Perl5 Test::More module) # For test-suite
-    PERL5TESTMORE=`($PERL -e 'use Test::More; print "good";') 2>/dev/null`
-    if test -z "$PERL5TESTMORE" ; then
-      AC_MSG_RESULT(not found)
-      else
-      AC_MSG_RESULT(found)
-    fi
-	else
-		AC_MSG_RESULT(unable to determine perl5 configuration)
-		PERL5EXT=$PERL5DIR
-	fi
-else
-       	AC_MSG_RESULT(could not figure out how to run perl5)
-fi
-
-# Cygwin (Windows) needs the library for dynamic linking
+# Cygwin requires the Windows standard (Pascal) calling convention as it is a Windows executable and not a Cygwin built executable
 case $host in
-*-*-cygwin* | *-*-mingw*) PERL5DYNAMICLINKING="-L$PERL5EXT -l$PERL5LIB";;
-*)PERL5DYNAMICLINKING="";;
+*-*-cygwin* | *-*-mingw*)
+    if test "$GCC" = yes; then
+        CSHARPDYNAMICLINKING="$GCC_MNO_CYGWIN -mthreads -Wl,--add-stdcall-alias"
+        CSHARPCFLAGS="$GCC_MNO_CYGWIN -mthreads"
+    else
+        CSHARPDYNAMICLINKING=""
+        CSHARPCFLAGS=""
+    fi ;;
+*)
+        CSHARPDYNAMICLINKING=""
+        CSHARPCFLAGS=""
+        ;;
+esac
+
+# CSharp on Windows platforms including Cygwin doesn't use libname.dll, rather name.dll when loading dlls
+case $host in
+*-*-cygwin* | *-*-mingw*) CSHARPLIBRARYPREFIX="";;
+*)CSHARPLIBRARYPREFIX="lib";;
+esac
+
+# C#/Mono on Mac OS X tweaks
+case $host in
+*-*-darwin*)
+    CSHARPSO=".so"
+    ;;
+*)
+    CSHARPSO=$SO
+    ;;
 esac
 fi
 
-AC_SUBST(PERL)
-AC_SUBST(PERL5EXT)
-AC_SUBST(PERL5DYNAMICLINKING)
-AC_SUBST(PERL5LIB)
-AC_SUBST(PERL5CCFLAGS)
-AC_SUBST(PERL5CCDLFLAGS)
-AC_SUBST(PERL5CCCDLFLAGS)
-AC_SUBST(PERL5LDFLAGS)
+AC_SUBST(CSHARPCILINTERPRETER_FLAGS)
+AC_SUBST(CSHARPCILINTERPRETER)
+AC_SUBST(CSHARPCONVERTPATH)
+AC_SUBST(CSHARPCOMPILER)
+AC_SUBST(CSHARPDYNAMICLINKING)
+AC_SUBST(CSHARPLIBRARYPREFIX)
+AC_SUBST(CSHARPCFLAGS)
+AC_SUBST(CSHARPSO)
 
 #----------------------------------------------------------------
-# Look for Octave
+# Look for D
 #----------------------------------------------------------------
 
-OCTAVEBIN=
-OCTAVE_SO=.oct
+AC_ARG_WITH(d, AS_HELP_STRING([--without-d], [Disable D]), [with_d="$withval"], [with_d="$alllang_default"])
+AC_ARG_WITH(d2-compiler, [  --with-d2-compiler=path  Set location of D2 compiler (DMD compatible)],[D2COMPILERBIN="$withval"], [D2COMPILERBIN=])
 
-AC_ARG_WITH(octave, AS_HELP_STRING([--without-octave], [Disable Octave])
-AS_HELP_STRING([--with-octave=path], [Set location of Octave executable]),[OCTAVEBIN="$withval"], [OCTAVEBIN="$alllang_default"])
 
-# Check for "--without-octave" or "--with-octave=no".
-if test x"${OCTAVEBIN}" = xno; then
-   AC_MSG_NOTICE([Disabling Octave])
-   OCTAVE=
-
-# Check for Octave; prefer command-line program "octave-cli" to (in newer versions) GUI program "octave"
-elif test "x$OCTAVEBIN" = xyes; then
-   AC_PATH_PROG(OCTAVE, [octave-cli octave])
-
+# First, check for "--without-d" or "--with-d=no".
+if test x"${with_d}" = xno; then
+  AC_MSG_NOTICE([Disabling D])
+  D2COMPILER=
 else
-   OCTAVE="$OCTAVEBIN"
-fi
 
-# Check if Octave works
-if test -n "$OCTAVE"; then
-   AC_MSG_CHECKING([if ${OCTAVE} works])
-   AS_IF([test "x`${OCTAVE} --version 2>/dev/null | sed -n -e '1p' | sed -n -e '/Octave, version/p'`" != x],[
-      AC_MSG_RESULT([yes])
-   ],[
-      AC_MSG_NOTICE([no])
-      OCTAVE=
-   ])
-fi
-
-# Check for required Octave helper program "mkoctfile"
-if test -n "$OCTAVE"; then
-  AC_MSG_CHECKING([for mkoctfile])
-  version_suffix=["`echo $OCTAVE | sed -e 's|.*\(-[0-9][0-9.]*\)$|\1|'`"]
-  case $version_suffix in
-    -*) ;;
-    *) version_suffix="" ;;
-  esac
-  octave_directory=`dirname $OCTAVE`
-  if test "$octave_directory" = "." ; then
-    mkoctfile="mkoctfile${version_suffix}"
+  if test -z "$D2COMPILERBIN" ; then
+    AC_CHECK_PROGS(D2COMPILER, dmd ldmd2 ldc2 gdmd)
+    if test -n "$D2COMPILER" ; then
+      old_ac_ext=$ac_ext
+      ac_ext=d
+      AC_MSG_CHECKING(whether the D2 compiler works)
+      cat > conftest.$ac_ext <<_ACEOF
+import std.algorithm;
+void main() {
+}
+_ACEOF
+      rm -f conftest.out
+      AS_IF(
+        [$D2COMPILER conftest.$ac_ext -ofconftest.out 2>&AS_MESSAGE_LOG_FD && test ! -s conftest.err && test -s conftest.out],
+        [AC_MSG_RESULT([yes])],
+        [_AC_MSG_LOG_CONFTEST AC_MSG_RESULT([no])
+        D2COMPILER=]
+      )
+      rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext conftest.out
+      ac_ext=$old_ac_ext
+    fi
   else
-    mkoctfile="${octave_directory}/mkoctfile${version_suffix}"
+    D2COMPILER="$D2COMPILERBIN"
   fi
-  AC_MSG_RESULT([${mkoctfile}])
-  AC_MSG_CHECKING([if ${mkoctfile} works])
-  AS_IF([test "x`${mkoctfile} --version 2>/dev/null | sed -n -e '1p' | sed -n -e '/mkoctfile, version/p'`" != x],[
-      AC_MSG_RESULT([yes])
-    ],[
+fi
+
+# Do not prefix library file names with "lib" on Windows.
+case $host in
+*-*-cygwin* | *-*-mingw*) DLIBPREFIX="";;
+*)DLIBPREFIX="lib";;
+esac
+
+AC_SUBST(D2COMPILER)
+AC_SUBST(DLIBPREFIX)
+
+#----------------------------------------------------------------
+# Look for Go compilers
+#----------------------------------------------------------------
+
+AC_ARG_WITH(go, AS_HELP_STRING([--without-go], [Disable Go])
+AS_HELP_STRING([--with-go=path], [Set location of Go compiler]),[GOBIN="$withval"], [GOBIN="$alllang_default"])
+
+if test x"${GOBIN}" = xno; then
+  AC_MSG_NOTICE([Disabling Go])
+  GO=
+  GOGCC=false
+  GCCGO=
+  GOOPT=
+  GCCGOOPT=
+  GOVERSIONOPTION=
+else
+
+  if test "x$GOBIN" = xyes; then
+    AC_CHECK_PROGS(GO, go)
+  else
+    GO="$GOBIN"
+  fi
+
+  GOGCC=false
+  GCCGO=
+  GOOPT=
+  GCCGOOPT=
+  GOVERSIONOPTION=
+
+  if test -n "$GO" ; then
+    GOVERSIONOPTION=version
+    go_version=$($GO $GOVERSIONOPTION | sed -e 's/go version //')
+    AC_MSG_CHECKING([whether go version is too old])
+    case $go_version in
+    go1.[012]*)
+      AC_MSG_RESULT([yes - minimum version is 1.3])
+      GO=
+      ;;
+    *)
       AC_MSG_RESULT([no])
-      OCTAVE=
-    ])
-fi
-
-# Check for Octave preprocessor/compiler/linker flags
-if test -n "$OCTAVE"; then
-
-   AC_MSG_CHECKING([for Octave preprocessor flags])
-   OCTAVE_CPPFLAGS=
-   for var in CPPFLAGS INCFLAGS ALL_CXXFLAGS; do
-      for flag in `env - ${mkoctfile} -p ${var}`; do
-         case ${flag} in
-            -D*|-I*) OCTAVE_CPPFLAGS="${OCTAVE_CPPFLAGS} ${flag}";;
-            *) ;;
-         esac
-      done
-   done
-   AC_MSG_RESULT([$OCTAVE_CPPFLAGS])
-
-   AC_MSG_CHECKING([for Octave compiler flags])
-   OCTAVE_CXXFLAGS=
-   for var in CXX ALL_CXXFLAGS; do
-      for flag in `env - ${mkoctfile} -p ${var}`; do
-         case ${flag} in
-            -std=*|-g*|-W*) OCTAVE_CXXFLAGS="${OCTAVE_CXXFLAGS} ${flag}";;
-            *) ;;
-         esac
-      done
-   done
-   save_CXXFLAGS="${CXXFLAGS}"
-   CXXFLAGS="-Werror -O0"
-   AC_COMPILE_IFELSE([
-      AC_LANG_PROGRAM([],[])
-   ],[
-      OCTAVE_CXXFLAGS="${OCTAVE_CXXFLAGS} -O0"
-   ])
-   CXXFLAGS="${save_CXXFLAGS}"
-   AC_MSG_RESULT([$OCTAVE_CXXFLAGS])
-
-   AC_MSG_CHECKING([for Octave linker flags])
-   OCTAVE_LDFLAGS=
-   for var in OCTLIBDIR; do
-     OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "-L`env - ${mkoctfile} -p ${var}`
-   done
-   for var in RDYNAMIC_FLAG RLD_FLAG OCTAVE_LIBS LIBS; do
-     OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "`env - ${mkoctfile} -p ${var}`
-   done
-   AC_MSG_RESULT([$OCTAVE_LDFLAGS])
-
-fi
-
-# Check for Octave options
-if test -n "$OCTAVE"; then
-   for octave_opt in --no-window-system --silent --norc --no-history; do
-      AC_MSG_CHECKING([if Octave option '${octave_opt}' is supported])
-      octave_out=`${OCTAVE} ${octave_opt} /dev/null 2>&1 | sed -n '1p' | sed -n '/unrecognized/p'`
-      AS_IF([test "x${octave_out}" = x],[
-         AC_MSG_RESULT([yes])
-         OCTAVE="${OCTAVE} ${octave_opt}"
-      ],[
-         AC_MSG_RESULT([no])
-      ])
-   done
-fi
-
-AC_SUBST(OCTAVE)
-AC_SUBST(OCTAVE_SO)
-AC_SUBST(OCTAVE_CPPFLAGS)
-AC_SUBST(OCTAVE_CXXFLAGS)
-AC_SUBST(OCTAVE_LDFLAGS)
-
-#----------------------------------------------------------------
-# Look for Scilab
-#----------------------------------------------------------------
-
-AC_ARG_WITH(scilab, AS_HELP_STRING([--without-scilab], [Disable Scilab])
-AS_HELP_STRING([--with-scilab=path], [Set location of Scilab executable]),[SCILABBIN="$withval"], [SCILABBIN="$alllang_default"])
-AC_ARG_WITH(scilab-inc, [  --with-scilab-inc=path  Set location of Scilab include directory], [SCILABINCDIR="$withval"], [SCILABINCDIR=""])
-
-# First, check for "--without-scilab" or "--with-scilab=no".
-if test x"${SCILABBIN}" = xno; then
-  AC_MSG_NOTICE([Disabling Scilab])
-  SCILAB=
-else
-  # Check for Scilab executable
-  if test "x$SCILABBIN" = xyes; then
-    AC_CHECK_PROGS(SCILAB, scilab)
-  else
-    AC_MSG_CHECKING(for scilab)
-    if test -f "$SCILABBIN"; then
-      AC_MSG_RESULT($SCILABBIN)
-      SCILAB="$SCILABBIN"
-    else
-      AC_MSG_RESULT(not found)
-    fi
+      ;;
+    esac
   fi
 
-  if test -n "$SCILAB"; then
-    # Check for Scilab version (needs api_scilab so needs version 5.3.3 or higher)
-    SCILAB_FULL_VERSION=`$SCILAB -version | head -1 | sed -e 's|Scilab version \"\(.*\)\"|\1|g'`
+  AC_CHECK_PROGS(GCCGO, gccgo)
 
-    AC_MSG_CHECKING(Scilab version is 5.3.3 or higher)
-    SCILAB_MAJOR_VERSION=`echo $SCILAB_FULL_VERSION | cut -d. -f1`
-    SCILAB_MINOR_VERSION=`echo $SCILAB_FULL_VERSION | cut -d. -f2`
-    SCILAB_MAINTENANCE_VERSION=`echo $SCILAB_FULL_VERSION | cut -d. -f3`
-    SCILAB_VERSION="$SCILAB_MAJOR_VERSION$SCILAB_MINOR_VERSION$SCILAB_MAINTENANCE_VERSION"
-
-    if test $SCILAB_VERSION -ge 533; then
-      AC_MSG_RESULT(yes)
-    else
-      AC_MSG_RESULT(no)
-      SCILAB=
-    fi
-
-    if test -n "$SCILAB"; then
-      # Set Scilab startup options depending on version
-      AC_MSG_CHECKING(for Scilab startup options)
-      SCILABOPT="-nwni -nb"
-      if test $SCILAB_VERSION -ge 540; then
-        SCILABOPT+=" -noatomsautoload"
-      fi
-      AC_MSG_RESULT($SCILABOPT)
-
-      # Check for Scilab header files
-      AC_MSG_CHECKING(for Scilab header files)
-      if test "$SCILABINCDIR" != ""; then
-        dirs="$SCILABINCDIR"
-      elif test -n "$PKGCONFIG"; then
-        dirs=`$PKGCONFIG scilab --cflags-only-I | sed -e 's/-I//g'`
+  if test -n "$GCCGO" ; then
+    if $GCCGO --help 2>/dev/null | grep gccgo >/dev/null 2>&1 ; then
+      AC_MSG_CHECKING([whether gccgo version is too old])
+      go_version=[`$GO $GOVERSIONOPTION | sed -n '1p' | sed -e 's/^.* \([0-9.]*\) *$/\1/' -e 's/[.]//g'`]
+      if test "x$go_version" = x; then
+        AC_MSG_RESULT([could not determine gccgo version])
+        GCCGO=
+      elif test "$go_version" -lt 470; then
+        AC_MSG_RESULT([yes - minimum version is 4.7.0])
+        GCCGO=
       else
-        dirs=""
-      fi
-      for i in $dirs; do
-        if test -r $i/api_scilab.h; then
-          AC_MSG_RESULT($i)
-          SCILABINCLUDE="-I$i"
-          break
+        AC_MSG_RESULT([no])
+        if test "$go_version" -lt 480; then
+          GCCGOOPT="-intgosize 32"
         fi
-        if test -r $i/scilab/api_scilab.h; then
-          AC_MSG_RESULT($i/scilab)
-          SCILABINCLUDE="-I$i/scilab"
-          break
-        fi
-      done
-      if test "$SCILABINCLUDE" = "" ; then
-        AC_MSG_RESULT(not found)
-        SCILAB=
       fi
     fi
   fi
 fi
 
-AC_SUBST(SCILAB)
-AC_SUBST(SCILABINCLUDE)
-AC_SUBST(SCILABOPT)
+AC_SUBST(GOGCC)
+AC_SUBST(GCCGO)
+AC_SUBST(GO)
+AC_SUBST(GOC)
+AC_SUBST(GO1)
+AC_SUBST(GO12)
+AC_SUBST(GO13)
+AC_SUBST(GO15)
+AC_SUBST(GOOPT)
+AC_SUBST(GCCGOOPT)
+AC_SUBST(GOVERSIONOPTION)
 
+#----------------------------------------------------------------
+# Look for Guile
+#----------------------------------------------------------------
+
+GUILE=
+GUILE_CFLAGS=
+GUILE_LIBS=
+
+AC_ARG_WITH(guile-config, AS_HELP_STRING([--without-guile], [Disable Guile])
+AS_HELP_STRING([--with-guile-config=path], [Set location of guile-config]),[ GUILE_CONFIG="$withval"], [GUILE_CONFIG=])
+AC_ARG_WITH(guile,[  --with-guile=path       Set location of Guile executable],[
+	GUILE="$withval"], [GUILE="$alllang_default"])
+AC_ARG_WITH(guile-cflags,[  --with-guile-cflags=cflags   Set cflags required to compile against Guile],[
+	GUILE_CFLAGS="$withval"])
+AC_ARG_WITH(guile-libs,[  --with-guile-libs=ldflags    Set ldflags needed to link with Guile],[
+	GUILE_LIBS="$withval"])
+
+# First, check for "--without-guile" or "--with-guile=no".
+if test x"${GUILE}" = xno; then
+  AC_MSG_NOTICE([Disabling Guile])
+else
+  if test -z "$GUILE_CONFIG" ; then
+    AC_PATH_PROG(GUILE_CONFIG, guile-config)
+  fi
+  if test -n "$GUILE_CONFIG" ; then
+    if test x"$GUILE" = xyes; then
+      AC_MSG_CHECKING([for guile executable])
+      # Try extracting it via guile-config first. If it's defined there it's the most reliable result
+      GUILE="`$GUILE_CONFIG info guile 2>/dev/null`"
+      if test -n "$GUILE";  then
+        AC_MSG_RESULT([$GUILE])
+      else
+        AC_MSG_RESULT([not found via guile-config - constructing path])
+        AC_MSG_CHECKING([for guile bindir])
+        guile_bindir="`$GUILE_CONFIG info bindir`"
+        AC_MSG_RESULT([$guile_bindir])
+        GUILE="$guile_bindir/guile"
+      fi
+      if ! test -f "$GUILE" ; then
+        GUILE=
+        AC_PATH_PROG(GUILE, guile)
+      fi
+      if test -z "$GUILE" ; then
+        AC_MSG_WARN([no suitable guile executable found. Disabling Guile])
+      fi
+    fi
+
+    if test -n "$GUILE" ; then
+      AC_MSG_CHECKING([for guile version])
+      guile_version=`$GUILE -c '(display (effective-version))'`
+      AC_MSG_RESULT([$guile_version])
+      AC_MSG_CHECKING([for guile version >= 1.8])
+      guile_good_version=`$GUILE -c '(if (>= (string->number (effective-version)) 1.8) (display "yes") (display "no"))'`
+      AC_MSG_RESULT([$guile_good_version])
+      if test x"$guile_good_version" != xyes ; then
+        AC_MSG_WARN([at least guile version 1.8 is required. Disabling Guile])
+        GUILE=
+      fi
+    fi
+
+    if test -n "$GUILE" ; then
+      # Test if guile-config and guile versions match. They should.
+      gc_version="`$GUILE_CONFIG --version 2>&1 | sed '1 s/.* //;q'`"
+      g_version="`$GUILE --version | sed '1 s/.* //;q'`"
+      if test "$gc_version" != "$g_version"; then
+        AC_MSG_WARN([different versions reported by $GUILE_CONFIG ($gc_version) and $GUILE ($g_version). Disabling Guile])
+        GUILE=
+      fi
+    fi
+
+    if test -n "$GUILE" ; then
+      if test -z "$GUILE_CFLAGS" ; then
+        AC_MSG_CHECKING([for guile compile flags])
+        GUILE_CFLAGS="`$GUILE_CONFIG compile`" # Note that this can sometimes be empty
+        AC_MSG_RESULT([$GUILE_CFLAGS])
+      fi
+
+      if test -z "$GUILE_LIBS" ; then
+        AC_MSG_CHECKING([for guile link flags])
+        GUILE_LIBS="`$GUILE_CONFIG link`"
+        AC_MSG_RESULT([$GUILE_LIBS])
+      fi
+    fi
+  fi
+fi
+
+AC_SUBST(GUILE)
+AC_SUBST(GUILE_CFLAGS)
+AC_SUBST(GUILE_LIBS)
 
 #----------------------------------------------------------------
 # Look for java
@@ -1348,6 +988,33 @@
   JAVAC="$JAVACBIN"
 fi
 
+# Check Java version: we require Java 9 or later for Doxygen tests.
+if test -n "$JAVAC"; then
+    AC_MSG_CHECKING(if java version is 9 or greater)
+    javac_version=`"$JAVAC" -version 2>&1`
+    java_version_num=`echo $javac_version | sed -n 's/^javac //p'`
+    if test -z "$java_version_num"; then
+        AC_MSG_WARN([unknown format for Java version returned by "$JAVAC" ($javac_version)])
+        JAVA_SKIP_DOXYGEN_TEST_CASES=1
+        AC_MSG_RESULT(unknown)
+    else
+        dnl Until Java 8 version number was in format "1.x", starting from
+        dnl Java 9 it's just "x".
+        case $java_version_num in
+            1.*)
+                JAVA_SKIP_DOXYGEN_TEST_CASES=1
+                AC_MSG_RESULT([no, disabling Doxygen tests])
+                ;;
+
+            *)
+                AC_MSG_RESULT(yes)
+                ;;
+        esac
+    fi
+
+    AC_SUBST(JAVA_SKIP_DOXYGEN_TEST_CASES)
+fi
+
 AC_MSG_CHECKING(for java include file jni.h)
 AC_ARG_WITH(javaincl, [  --with-javaincl=path    Set location of Java include directory], [JAVAINCDIR="$withval"], [JAVAINCDIR=])
 
@@ -1408,15 +1075,6 @@
   fi
 fi
 
-# Javadoc support required for the Java test-suite is available by default in jdk9+ and in tools.jar in earlier jdk versions
-AC_MSG_CHECKING(for java tools.jar)
-if test -n "$JAVA_HOME" && test -r "$JAVA_HOME/lib/tools.jar" ; then
-  JAVA_TOOLS_JAR="$JAVA_HOME/lib/tools.jar"
-  AC_MSG_RESULT([$JAVA_TOOLS_JAR])
-else
-  AC_MSG_RESULT(not found)
-fi
-
 case $host in
 *-*-cygwin*)
         # TODO: Only use this flag if the compiler supports it, later versions of gcc no longer have it
@@ -1483,7 +1141,6 @@
 AC_SUBST(JAVAC)
 AC_SUBST(JAVAINC)
 AC_SUBST(JAVA_CLASSPATH_SEP)
-AC_SUBST(JAVA_TOOLS_JAR)
 AC_SUBST(JAVADYNAMICLINKING)
 AC_SUBST(JAVALIBRARYPREFIX)
 AC_SUBST(JAVASO)
@@ -1526,72 +1183,90 @@
   # Look for Node.js which is the default Javascript engine
   #----------------------------------------------------------------
 
-  AC_CHECK_PROGS(NODEJS, [nodejs node])
+  AC_CHECK_PROGS(NODEJS, [node nodejs])
 
   if test -n "$NODEJS"; then
-    # node-gyp is needed to run the test-suite/examples
+    # node-gyp needed to run the test-suite/examples
     AC_CHECK_PROGS(NODEGYP, node-gyp)
     if test -z "$NODEGYP"; then
       NODEJS=
     fi
+    AC_CHECK_PROGS(NODENPM, npm)
+    JSNAPIENABLED=
+    if test -n "$NODENPM"; then
+      AC_MSG_CHECKING([for Node-API (napi) header directory])
+      NODENPM_PREFIX=$($NODENPM config get prefix)
+      if test -n "$NODENPM_PREFIX"; then
+        NODENAPI_DIR=$NODENPM_PREFIX/lib/node_modules/node-addon-api
+        if test -f "$NODENAPI_DIR/napi.h"; then
+          JSNAPIENABLED=1
+          AC_SUBST(NODENAPI_DIR)
+        fi
+      fi
+      if test -n "$JSNAPIENABLED"; then
+        AC_MSG_RESULT([$NODENAPI_DIR])
+      else
+        AC_MSG_RESULT([not found])
+      fi
+    fi
+    AC_SUBST(JSNAPIENABLED)
   fi
 
   #----------------------------------------------------------------
-  # Look for JavascriptCore (Webkit) settings (JSCOREINCDIR, JSCOREDYNAMICLINKING)
+  # Look for JavaScriptCore (Webkit) settings
   #----------------------------------------------------------------
 
   # check for include files
-  AC_MSG_CHECKING(for JavaScriptCore/JavaScript.h)
-  AC_ARG_WITH(jscoreinc, [  --with-jscoreinc=path      Set location of Javascript include directory], [JSCOREINCDIR="$withval"], [JSCOREINCDIR=])
-
-  JSCOREVERSION=
-
-  if test -z "$JSCOREINCDIR"; then
-    JSCOREINCDIR="/usr/include/ /usr/local/include/"
-
-    # Add in default directory for JavaScriptCore headers for Linux and Mac OS X
-    case $host in
-    *-*-linux*)
-      JSCOREINCDIR="/usr/include/webkit-1.0/ /usr/include/webkitgtk-1.0/ /usr/local/include/webkit-1.0/JavaScriptCore/ $JSCOREINCDIR"
-      ;;
-    *-*-darwin*)
-      JSCOREINCDIR="/System/Library/Frameworks/JavaScriptCore.framework/Headers/ $JSCOREINCDIR"
-      ;;
-    *)
-      ;;
-    esac
-  fi
-
-  for d in $JSCOREINCDIR ; do
-    if test -r "$d/JavaScriptCore/JavaScript.h" || test -r "$d/JavaScript.h" ; then
-      AC_MSG_RESULT($d)
-      JSCOREINCDIR=$d
-      JSCOREINC=-I\"$d\"
-      break
-    fi
-  done
-
-  if test "$JSCOREINC" = "" ; then
-    AC_MSG_RESULT(not found)
-  fi
-
+  AC_ARG_WITH(jscoreinc, [  --with-jscoreinc=path      Set location of JavaScriptCore/Webkit include directory], [JSCOREINCDIR="$withval"], [JSCOREINCDIR=])
   # check for JavaScriptCore/Webkit libraries
   AC_ARG_WITH(jscorelib,[  --with-jscorelib=path      Set location of the JavaScriptCore/Webkit library directory],[JSCORELIB="-L$withval"], [JSCORELIB=])
 
-  if test -z "$JSCORELIB" -a -n "$PKGCONFIG"; then
-    AC_MSG_CHECKING(for JavaScriptCore/Webkit library)
-    if pkg-config javascriptcoregtk-1.0; then
-      JSCORELIB=`$PKGCONFIG --libs javascriptcoregtk-1.0`
-      JSCOREVERSION=`$PKGCONFIG --modversion javascriptcoregtk-1.0`
+  JSCOREVERSION=
+
+  if test -z "$JSCOREINCDIR" -a -n "$JSCORELIB"; then
+    AC_MSG_ERROR([Either both or none of --with-jcoreinc --with-jscorelib should be specified])
+  elif test -n "$JSCOREINCDIR" -a -z "$JSCORELIB"; then
+    AC_MSG_ERROR([Either both or none of --with-jcoreinc --with-jscorelib should be specified])
+  elif test -z "$JSCOREINCDIR" -a -z "$JSCORELIB"; then
+    if test -z "$JSCORELIB" -a -n "$PKG_CONFIG "; then
+      AC_MSG_CHECKING(for JavaScriptCore/Webkit)
+      if $PKG_CONFIG  javascriptcoregtk-4.1 2>/dev/null ; then
+        JSCORELIB=`$PKG_CONFIG  --libs javascriptcoregtk-4.1`
+        JSCOREINC=`$PKG_CONFIG  --cflags-only-I javascriptcoregtk-4.1`
+        JSCOREVERSION=`$PKG_CONFIG  --modversion javascriptcoregtk-4.1`
+      elif $PKG_CONFIG  javascriptcoregtk-4.0 2>/dev/null ; then
+        JSCORELIB=`$PKG_CONFIG  --libs javascriptcoregtk-4.0`
+        JSCOREINC=`$PKG_CONFIG  --cflags-only-I javascriptcoregtk-4.0`
+        JSCOREVERSION=`$PKG_CONFIG  --modversion javascriptcoregtk-4.0`
+      elif $PKG_CONFIG  javascriptcoregtk-3.0 2>/dev/null ; then
+        JSCORELIB=`$PKG_CONFIG  --libs javascriptcoregtk-3.0`
+        JSCOREINC=`$PKG_CONFIG  --cflags-only-I javascriptcoregtk-3.0`
+        JSCOREVERSION=`$PKG_CONFIG  --modversion javascriptcoregtk-3.0`
+      elif $PKG_CONFIG  javascriptcoregtk-1.0 2>/dev/null ; then
+        JSCORELIB=`$PKG_CONFIG  --libs javascriptcoregtk-1.0`
+        JSCOREVERSION=`$PKG_CONFIG  --modversion javascriptcoregtk-1.0`
+      fi
+      if test -z "$JSCORELIB"; then
+        AC_MSG_RESULT(not found)
+        JSCENABLED=
+      else
+        AC_MSG_RESULT([version $JSCOREVERSION])
+        AC_MSG_CHECKING(for JavaScriptCore/Webkit include flags)
+        AC_MSG_RESULT([$JSCOREINC])
+        AC_MSG_CHECKING(for JavaScriptCore/Webkit link flags)
+        AC_MSG_RESULT([$JSCORELIB])
+        JSCOREDYNAMICLINKING="$JSCORELIB"
+        JSCENABLED=1
+      fi
     fi
-    if test -z "$JSCORELIB"; then
-      AC_MSG_RESULT(not found)
-      JSCENABLED=
-    else
-      AC_MSG_RESULT([$JSCORELIB])
-      JSCOREDYNAMICLINKING="$JSCORELIB"
-      JSCENABLED=1
-    fi
+  else
+    AC_MSG_CHECKING(for JavaScriptCore/Webkit include flags)
+    JSCOREINC=-I\"$JSCOREINCDIR\"
+    AC_MSG_RESULT([$JSCOREINC])
+    AC_MSG_CHECKING(for JavaScriptCore/Webkit link flags)
+    AC_MSG_RESULT([$JSCORELIB])
+    JSCOREDYNAMICLINKING="$JSCORELIB"
+    JSCENABLED=1
   fi
 
   #----------------------------------------------------------------
@@ -1684,139 +1359,140 @@
 AC_SUBST(NODEGYP)
 
 #----------------------------------------------------------------
-# Look for Android
+# Look for Lua
 #----------------------------------------------------------------
 
-AC_ARG_WITH(android, AS_HELP_STRING([--without-android], [Disable Android])
-AS_HELP_STRING([--with-android=path], [Set location of android executable]),[ANDROIDBIN="$withval"], [ANDROIDBIN="$alllang_default"])
-AC_ARG_WITH(adb, [  --with-adb=path         Set location of adb executable - Android Debug Bridge],[ADBBIN="$withval"], [ADBBIN=])
-AC_ARG_WITH(ant, [  --with-ant=path         Set location of ant executable for Android],[ANTBIN="$withval"], [ANTBIN=])
-AC_ARG_WITH(ndk-build, [  --with-ndk-build=path   Set location of Android ndk-build executable],[NDKBUILDBIN="$withval"], [NDKBUILDBIN=])
+LUABIN=
+LUAINCLUDE=
+LUALIB=
+LUADYNAMICLOADLIB=
+LUAFLAGS=
+LUALINK=
+# note: if LUABIN is empty then lua tests will not be done
+# LUABIN will be cleared if certain dependencies cannot be found
 
-# First, check for "--without-android" or "--with-android=no".
-if test x"${ANDROIDBIN}" = xno; then
-  AC_MSG_NOTICE([Disabling Android])
-  ANDROID=
+AC_ARG_WITH(lua, AS_HELP_STRING([--without-lua], [Disable Lua])
+AS_HELP_STRING([--with-lua=path], [Set location of Lua executable]),[ LUABIN="$withval"], [LUABIN="$alllang_default"])
+AC_ARG_WITH(luaincl,[  --with-luaincl=path     Set location of Lua include directory],[
+	LUAINCLUDE="$withval"], [LUAINCLUDE=])
+AC_ARG_WITH(lualib,[  --with-lualib=path      Set location of Lua library directory],[
+	LUALIB="$withval"], [LUALIB=])
+
+# First, check for "--without-lua" or "--with-lua=no".
+if test x"${LUABIN}" = xno; then
+AC_MSG_NOTICE([Disabling Lua])
 else
-  if test "x$ANDROIDBIN" = xyes; then
-    AC_CHECK_PROGS(ANDROID, android)
-  else
-    ANDROID="$ANDROIDBIN"
-  fi
 
-  if test -z "$ADBBIN"; then
-    AC_CHECK_PROGS(ADB, adb)
-  else
-    ADB="$ADBBIN"
-  fi
-
-  if test -z "$ANTBIN"; then
-    AC_CHECK_PROGS(ANT, ant)
-  else
-    ANT="$ANTBIN"
-  fi
-
-  if test -z "$NDKBUILDBIN"; then
-    AC_CHECK_PROGS(NDKBUILD, ndk-build)
-  else
-    NDKBUILD="$NDKBUILDBIN"
-  fi
+# can we find lua?
+if test "x$LUABIN" = xyes; then
+   # We look for a versioned Lua binary first, as there can be
+   # multiple versions of Lua installed on some systems (like Debian).
+   AC_PATH_PROGS(LUABIN, [lua5.4 lua5.3 lua5.2 lua5.1 lua])
 fi
 
-AC_SUBST(ANDROID)
-AC_SUBST(ADB)
-AC_SUBST(ANT)
-AC_SUBST(NDKBUILD)
-
-#----------------------------------------------------------------
-# Look for Guile
-#----------------------------------------------------------------
-
-GUILE=
-GUILE_CFLAGS=
-GUILE_LIBS=
-
-AC_ARG_WITH(guile-config, AS_HELP_STRING([--without-guile], [Disable Guile])
-AS_HELP_STRING([--with-guile-config=path], [Set location of guile-config]),[ GUILE_CONFIG="$withval"], [GUILE_CONFIG=])
-AC_ARG_WITH(guile,[  --with-guile=path       Set location of Guile executable],[
-	GUILE="$withval"], [GUILE="$alllang_default"])
-AC_ARG_WITH(guile-cflags,[  --with-guile-cflags=cflags   Set cflags required to compile against Guile],[
-	GUILE_CFLAGS="$withval"])
-AC_ARG_WITH(guile-libs,[  --with-guile-libs=ldflags    Set ldflags needed to link with Guile],[
-	GUILE_LIBS="$withval"])
-
-# First, check for "--without-guile" or "--with-guile=no".
-if test x"${GUILE}" = xno; then
-  AC_MSG_NOTICE([Disabling Guile])
-else
-  if test -z "$GUILE_CONFIG" ; then
-    AC_PATH_PROG(GUILE_CONFIG, guile-config)
+# check version: we need Lua 5.x
+if test "$LUABIN"; then
+  AC_MSG_CHECKING(Lua version)
+  [LUA_VERSION=`$LUABIN -e 'print(string.match(_VERSION, "%d+[.]%d+"))'`]
+  # For 5.0 and 5.1 header and libraries may be named using 50 or 51.
+  LUA_VERSION_NO_DOTS=
+  if test -n "$LUA_VERSION" ; then
+    AC_MSG_RESULT([Lua $LUA_VERSION.x])
+  else
+    AC_MSG_RESULT([failed])
   fi
-  if test -n "$GUILE_CONFIG" ; then
-    if test x"$GUILE" = xyes; then
-      AC_MSG_CHECKING([for guile executable])
-      # Try extracting it via guile-config first. If it's defined there it's the most reliable result
-      GUILE="`$GUILE_CONFIG info guile 2>/dev/null`"
-      if test -n "$GUILE";  then
-        AC_MSG_RESULT([$GUILE])
-      else
-        AC_MSG_RESULT([not found via guile-config - constructing path])
-        AC_MSG_CHECKING([for guile bindir])
-        guile_bindir="`$GUILE_CONFIG info bindir`"
-        AC_MSG_RESULT([$guile_bindir])
-        GUILE="$guile_bindir/guile"
-      fi
-      if ! test -f "$GUILE" ; then
-        GUILE=
-        AC_PATH_PROG(GUILE, guile)
-      fi
-      if test -z "$GUILE" ; then
-        AC_MSG_WARN([no suitable guile executable found. Disabling Guile])
-      fi
-    fi
-
-    if test -n "$GUILE" ; then
-      AC_MSG_CHECKING([for guile version])
-      guile_version=`$GUILE -c '(display (effective-version))'`
-      AC_MSG_RESULT([$guile_version])
-      AC_MSG_CHECKING([for guile version >= 1.8])
-      guile_good_version=`$GUILE -c '(if (>= (string->number (effective-version)) 1.8) (display "yes") (display "no"))'`
-      AC_MSG_RESULT([$guile_good_version])
-      if test x"$guile_good_version" != xyes ; then
-        AC_MSG_WARN([at least guile version 1.8 is required. Disabling Guile])
-        GUILE=
-      fi
-    fi
-
-    if test -n "$GUILE" ; then
-      # Test if guile-config and guile versions match. They should.
-      gc_version="`$GUILE_CONFIG --version 2>&1 | sed '1 s/.* //;q'`"
-      g_version="`$GUILE --version | sed '1 s/.* //;q'`"
-      if test "$gc_version" != "$g_version"; then
-        AC_MSG_WARN([different versions reported by $GUILE_CONFIG ($gc_version) and $GUILE ($g_version). Disabling Guile])
-        GUILE=
-      fi
-    fi
-
-    if test -n "$GUILE" ; then
-      if test -z "$GUILE_CFLAGS" ; then
-        AC_MSG_CHECKING([for guile compile flags])
-        GUILE_CFLAGS="`$GUILE_CONFIG compile`" # Note that this can sometimes be empty
-        AC_MSG_RESULT([$GUILE_CFLAGS])
-      fi
-
-      if test -z "$GUILE_LIBS" ; then
-        AC_MSG_CHECKING([for guile link flags])
-        GUILE_LIBS="`$GUILE_CONFIG link`"
-        AC_MSG_RESULT([$GUILE_LIBS])
-      fi
-    fi
-  fi
+  case $LUA_VERSION in
+    5.0) LUA_VERSION_NO_DOTS=50 ;;
+    5.1) LUA_VERSION_NO_DOTS=51 ;;
+    5.*) ;;
+    *)
+      AC_MSG_WARN([Not Lua 5.x, SWIG does not support this version of Lua])
+      LUABIN=""
+      ;;
+  esac
 fi
 
-AC_SUBST(GUILE)
-AC_SUBST(GUILE_CFLAGS)
-AC_SUBST(GUILE_LIBS)
+if test "$LUABIN"; then
+  AC_MSG_CHECKING(whether Lua dynamic loading is enabled)
+  # using Lua to check Lua
+  # lua 5.0 & 5.1 have different fn names
+  if test "$LUA_VERSION" = "5.0"; then
+    LUADYNAMICLOADLIB=`$LUABIN -e '_,_,c=loadlib("no_such_lib","") if c~="absent" then print "1" end'`
+  else
+    LUADYNAMICLOADLIB=`$LUABIN -e '_,_,c=package.loadlib("no_such_lib","") if c~="absent" then print "1" end'`
+  fi
+
+  if test -z "$LUADYNAMICLOADLIB"; then
+    AC_MSG_RESULT(no)
+  else
+    AC_MSG_RESULT(yes)
+  fi
+
+  # look for the header files & set LUAFLAGS accordingly
+  # will clear LUABIN if not present
+  if test -n "$LUAINCLUDE"; then
+    AC_CHECK_FILE($LUAINCLUDE/lua.h,[LUAFLAGS="-I$LUAINCLUDE"],[LUABIN=])
+  else
+    LUA_OK="1"
+    CFLAGS_SAVED=$CFLAGS
+    CFLAGS= # Use empty CFLAGS to avoid failure: "present but cannot be compiled"
+    AC_CHECK_HEADER([lua.h],[LUAFLAGS=""],[LUA_OK=""])
+    CFLAGS=$CFLAGS_SAVED
+    # if we didn't get it, going to have to look elsewhere (the hard way)
+    if test -z "$LUA_OK"; then
+      AC_MSG_CHECKING(for lua.h in other locations)
+      # note: Debian/Ubuntu seem to like /usr/include/lua5.1/lua.h
+      # The ordering of the include directories to search should match
+      # the ordering of libraries to search in the library test below.
+      inc=/usr/include
+      incloc=/usr/local/include
+      dirs="$inc/lua$LUA_VERSION"
+      test -z "$LUA_VERSION_NO_DOTS" || dirs="$dirs $inc/lua$LUA_VERSION_NO_DOTS"
+      dirs="$dirs $incloc/lua$LUA_VERSION"
+      test -z "$LUA_VERSION_NO_DOTS" || dirs="$dirs $incloc/lua$LUA_VERSION_NO_DOTS"
+      dirs="$dirs $incloc"
+      for i in $dirs; do
+        #echo "$i"
+        if test -r $i/lua.h; then
+          AC_MSG_RESULT($i/lua.h)
+          LUAFLAGS="-I$i"
+          break
+        fi
+      done
+      if test -z "$LUAFLAGS"; then
+        AC_MSG_RESULT(not found)
+        LUABIN="" # clear the bin
+      fi
+    fi
+  fi
+
+  # look for the library files & set LUALINK accordingly
+  # will clear LUABIN if not present
+  lua_save_LIBS=$LIBS # the code seems to disrupt LIBS, so saving
+
+  if test -n "$LUALIB"; then
+    AC_CHECK_FILE($LUALIB/liblua.a,[LUALINK="-L$LUALIB -llua"],[LUABIN=])
+  else
+    libs="lua lua$LUA_VERSION"
+    test -z "$LUA_VERSION_NO_DOTS" || libs="$libs lua$LUA_VERSION_NO_DOTS"
+    AC_SEARCH_LIBS(lua_close, [$libs], [LUALINK="-l$ac_lib"],[LUABIN=])
+  fi
+
+  # adding lualib for lua 5.0
+  if test "$LUA_VERSION" = "5.0"; then
+    LUALINK="$LUALINK -llualib"
+  fi
+  LUALINK="$LUALINK -pthread"
+
+  LIBS=$lua_save_LIBS	# restore LIBS
+fi
+
+fi # if not disabled
+
+AC_SUBST(LUADYNAMICLINKING)
+AC_SUBST(LUAFLAGS)
+AC_SUBST(LUALINK)
+AC_SUBST(LUABIN)
 
 #----------------------------------------------------------------
 # Look for MzScheme
@@ -1861,6 +1537,700 @@
 AC_SUBST(MZDYNOBJ)
 
 #----------------------------------------------------------------
+# Look for OCaml
+#----------------------------------------------------------------
+
+AC_ARG_WITH(ocaml, AS_HELP_STRING([--without-ocaml], [Disable OCaml]), [with_ocaml="$withval"], [with_ocaml="$alllang_default"])
+AC_ARG_WITH(ocamlc,[  --with-ocamlc=path      Set location of ocamlc executable],[ OCAMLC="$withval"], [OCAMLC=])
+AC_ARG_WITH(ocamldlgen,[  --with-ocamldlgen=path  Set location of ocamldlgen],[ OCAMLDLGEN="$withval" ], [OCAMLDLGEN=])
+AC_ARG_WITH(ocamlfind,[  --with-ocamlfind=path   Set location of ocamlfind],[OCAMLFIND="$withval"],[OCAMLFIND=])
+AC_ARG_WITH(ocamlmktop,[  --with-ocamlmktop=path  Set location of ocamlmktop executable],[ OCAMLMKTOP="$withval"], [OCAMLMKTOP=])
+AC_ARG_WITH(camlp4,[  --with-camlp4=path  Set location of camlp4 executable],[ CAMLP4="$withval"], [CAMLP4=])
+
+# First, check for "--without-ocaml" or "--with-ocaml=no".
+if test x"${with_ocaml}" = xno; then
+    AC_MSG_NOTICE([Disabling OCaml])
+    OCAMLC=
+else
+    # OCaml compiler
+    if test -z "$OCAMLC"; then
+	AC_CHECK_PROGS(OCAMLC, ocamlc)
+    fi
+
+    # OCaml Pre-Processor-Pretty-Printer
+    if test -z "$CAMLP4"; then
+	AC_CHECK_PROGS(CAMLP4, camlp4)
+    fi
+
+    # OCaml DL load generator
+    if test -z "$OCAMLDLGEN"; then
+	AC_CHECK_PROGS(OCAMLDLGEN, ocamldlgen)
+    fi
+
+    # OCaml package tool
+    if test -z "$OCAMLFIND"; then
+	AC_CHECK_PROGS(OCAMLFIND, ocamlfind)
+    fi
+
+    # OCaml toplevel creator
+    if test -z "$OCAMLMKTOP"; then
+	AC_CHECK_PROGS(OCAMLMKTOP, ocamlmktop)
+    fi
+fi
+
+AC_SUBST(OCAMLC)
+AC_SUBST(CAMLP4)
+AC_SUBST(OCAMLDLGEN)
+AC_SUBST(OCAMLFIND)
+AC_SUBST(OCAMLMKTOP)
+
+#----------------------------------------------------------------
+# Look for Octave
+#----------------------------------------------------------------
+
+OCTAVEBIN=
+OCTAVE_SO=.oct
+
+AC_ARG_WITH(octave, AS_HELP_STRING([--without-octave], [Disable Octave])
+AS_HELP_STRING([--with-octave=path], [Set location of Octave executable]),[OCTAVEBIN="$withval"], [OCTAVEBIN="$alllang_default"])
+
+# Check for "--without-octave" or "--with-octave=no".
+if test x"${OCTAVEBIN}" = xno; then
+   AC_MSG_NOTICE([Disabling Octave])
+   OCTAVE=
+
+# Check for Octave; prefer command-line program "octave-cli" to (in newer versions) GUI program "octave"
+elif test "x$OCTAVEBIN" = xyes; then
+   AC_PATH_PROG(OCTAVE, [octave-cli octave])
+
+else
+   OCTAVE="$OCTAVEBIN"
+fi
+
+# Check if Octave works
+if test -n "$OCTAVE"; then
+   AC_MSG_CHECKING([if ${OCTAVE} works])
+   AS_IF([test "x`${OCTAVE} --version 2>/dev/null | sed -n -e '1p' | sed -n -e '/Octave, version/p'`" != x],[
+      AC_MSG_RESULT([yes])
+   ],[
+      AC_MSG_RESULT([no])
+      OCTAVE=
+   ])
+fi
+
+# Check for required Octave helper program "mkoctfile"
+if test -n "$OCTAVE"; then
+  AC_MSG_CHECKING([for mkoctfile])
+  version_suffix=["`echo $OCTAVE | sed -e 's|.*\(-[0-9][0-9.]*\)$|\1|'`"]
+  case $version_suffix in
+    -*) ;;
+    *) version_suffix="" ;;
+  esac
+  octave_directory=`dirname $OCTAVE`
+  if test "$octave_directory" = "." ; then
+    mkoctfile="mkoctfile${version_suffix}"
+  else
+    mkoctfile="${octave_directory}/mkoctfile${version_suffix}"
+  fi
+  AC_MSG_RESULT([${mkoctfile}])
+  AC_MSG_CHECKING([if ${mkoctfile} works])
+  mkoctfile="env - PATH=$PATH LD_LIBRARY_PATH=$LD_LIBRARY_PATH ${mkoctfile}"
+  AS_IF([test "x`${mkoctfile} --version 2>/dev/null | sed -n -e '1p' | sed -n -e '/mkoctfile, version/p'`" != x],[
+      AC_MSG_RESULT([yes])
+    ],[
+      AC_MSG_RESULT([no])
+      OCTAVE=
+    ])
+fi
+
+# Check for Octave preprocessor/compiler/linker flags
+if test -n "$OCTAVE"; then
+
+   AC_MSG_CHECKING([for Octave preprocessor flags])
+   OCTAVE_CPPFLAGS=
+   for var in CPPFLAGS INCFLAGS ALL_CXXFLAGS; do
+      for flag in `${mkoctfile} -p ${var}`; do
+         case ${flag} in
+            -D*|-I*) OCTAVE_CPPFLAGS="${OCTAVE_CPPFLAGS} ${flag}";;
+            *) ;;
+         esac
+      done
+   done
+   AC_MSG_RESULT([$OCTAVE_CPPFLAGS])
+
+   AC_MSG_CHECKING([for Octave compiler flags])
+   OCTAVE_CXXFLAGS=
+   for var in CXX ALL_CXXFLAGS; do
+      for flag in `${mkoctfile} -p ${var}`; do
+         case ${flag} in
+            -std=*|-g*|-W*) OCTAVE_CXXFLAGS="${OCTAVE_CXXFLAGS} ${flag}";;
+            *) ;;
+         esac
+      done
+   done
+   save_CXXFLAGS="${CXXFLAGS}"
+   CXXFLAGS="-Werror -O0"
+   AC_COMPILE_IFELSE([
+      AC_LANG_PROGRAM([],[])
+   ],[
+      OCTAVE_CXXFLAGS="${OCTAVE_CXXFLAGS} -O0"
+   ])
+   CXXFLAGS="${save_CXXFLAGS}"
+   AC_MSG_RESULT([$OCTAVE_CXXFLAGS])
+
+   AC_MSG_CHECKING([for Octave linker flags])
+   OCTAVE_LDFLAGS=
+   for var in OCTLIBDIR; do
+     OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "-L`${mkoctfile} -p ${var}`
+   done
+   for var in RDYNAMIC_FLAG RLD_FLAG OCTAVE_LIBS LIBS; do
+     # RLD_FLAG gives "mkoctfile: unknown variable 'RLD_FLAG'" on stderr
+     # with Octave 7.3 so just discard stderr here.  Apparently RLD_FLAG has
+     # reported an empty value since somewhere between 3.4.3 and 3.6.1 so
+     # can be removed below once we require Octave 4.
+     OCTAVE_LDFLAGS="${OCTAVE_LDFLAGS} "`${mkoctfile} -p ${var} 2>/dev/null`
+   done
+   AC_MSG_RESULT([$OCTAVE_LDFLAGS])
+
+fi
+
+# Check for Octave options
+if test -n "$OCTAVE"; then
+   for octave_opt in --no-window-system --silent --norc --no-history; do
+      AC_MSG_CHECKING([if Octave option '${octave_opt}' is supported])
+      octave_out=`${OCTAVE} ${octave_opt} /dev/null 2>&1 | sed -n '1p' | sed -n '/unrecognized/p'`
+      AS_IF([test "x${octave_out}" = x],[
+         AC_MSG_RESULT([yes])
+         OCTAVE="${OCTAVE} ${octave_opt}"
+      ],[
+         AC_MSG_RESULT([no])
+      ])
+   done
+fi
+
+AC_SUBST(OCTAVE)
+AC_SUBST(OCTAVE_SO)
+AC_SUBST(OCTAVE_CPPFLAGS)
+AC_SUBST(OCTAVE_CXXFLAGS)
+AC_SUBST(OCTAVE_LDFLAGS)
+
+#----------------------------------------------------------------
+# Look for Perl5
+#----------------------------------------------------------------
+
+PERLBIN=
+
+AC_ARG_WITH(perl5, AS_HELP_STRING([--without-perl5], [Disable Perl5])
+AS_HELP_STRING([--with-perl5=path], [Set location of Perl5 executable]),[ PERLBIN="$withval"], [PERLBIN="$alllang_default"])
+
+# First, check for "--without-perl5" or "--with-perl5=no".
+if test x"${PERLBIN}" = xno; then
+AC_MSG_NOTICE([Disabling Perl5])
+PERL=
+else
+
+# First figure out what the name of Perl5 is
+
+if test "x$PERLBIN" = xyes; then
+AC_CHECK_PROGS(PERL, perl perl5)
+else
+PERL="$PERLBIN"
+fi
+
+
+# This could probably be simplified as for all platforms and all versions of Perl the following apparently should be run to get the compilation options:
+# perl -MExtUtils::Embed -e ccopts
+AC_MSG_CHECKING(for Perl5 header files)
+if test -n "$PERL"; then
+	PERL5DIR=`($PERL -MConfig -le 'print $Config{archlibexp}') 2>/dev/null`
+	if test -n "$PERL5DIR" ; then
+		dirs="$PERL5DIR $PERL5DIR/CORE"
+		PERL5EXT=none
+		for i in $dirs; do
+			if test -r $i/perl.h; then
+				AC_MSG_RESULT($i)
+				PERL5EXT="$i"
+				break
+			fi
+		done
+		if test "$PERL5EXT" = none; then
+			PERL5EXT="$PERL5DIR/CORE"
+			AC_MSG_RESULT(could not locate perl.h...using $PERL5EXT)
+		fi
+
+		AC_MSG_CHECKING(for Perl5 library)
+		PERL5LIB=`($PERL -e 'use Config; $_=$Config{libperl}; s/^lib//; s/$Config{_a}$//; s/\.$Config{so}.*//; print $_, "\n"') 2>/dev/null`
+		if test -z "$PERL5LIB" ; then
+			AC_MSG_RESULT(not found)
+		else
+			AC_MSG_RESULT($PERL5LIB)
+		fi
+    AC_MSG_CHECKING(for Perl5 ccflags)
+		PERL5CCFLAGS=`($PERL -e 'use Config; print $Config{ccflags}, "\n"' | sed "s/-Wdeclaration-after-statement//") 2>/dev/null`
+		if test -z "$PERL5CCFLAGS" ; then
+			AC_MSG_RESULT(not found)
+		else
+			AC_MSG_RESULT($PERL5CCFLAGS)
+		fi
+    AC_MSG_CHECKING(for Perl5 ccdlflags)
+    PERL5CCDLFLAGS=`($PERL -e 'use Config; print $Config{ccdlflags}, "\n"') 2>/dev/null`
+    if test -z "$PERL5CCDLFLAGS" ; then
+      AC_MSG_RESULT(not found)
+      else
+      AC_MSG_RESULT($PERL5CCDLFLAGS)
+    fi
+    AC_MSG_CHECKING(for Perl5 cccdlflags)
+    PERL5CCCDLFLAGS=`($PERL -e 'use Config; print $Config{cccdlflags}, "\n"') 2>/dev/null`
+    if test -z "$PERL5CCCDLFLAGS" ; then
+      AC_MSG_RESULT(not found)
+      else
+      AC_MSG_RESULT($PERL5CCCDLFLAGS)
+    fi
+    AC_MSG_CHECKING(for Perl5 ldflags)
+    PERL5LDFLAGS=`($PERL -e 'use Config; print $Config{ldflags}, "\n"') 2>/dev/null`
+    if test -z "$PERL5LDFLAGS" ; then
+      AC_MSG_RESULT(not found)
+      else
+      AC_MSG_RESULT($PERL5LDFLAGS)
+    fi
+    AC_MSG_CHECKING(for Perl5 Test::More module) # For test-suite
+    PERL5TESTMORE=`($PERL -e 'use Test::More; print "good";') 2>/dev/null`
+    if test -z "$PERL5TESTMORE" ; then
+      AC_MSG_RESULT(not found)
+      else
+      AC_MSG_RESULT(found)
+    fi
+	else
+		AC_MSG_RESULT(unable to determine perl5 configuration)
+		PERL5EXT=$PERL5DIR
+	fi
+else
+	AC_MSG_RESULT(could not figure out how to run perl5)
+fi
+
+# Cygwin (Windows) needs the library for dynamic linking
+case $host in
+*-*-cygwin* | *-*-mingw*) PERL5DYNAMICLINKING="-L$PERL5EXT -l$PERL5LIB";;
+*)PERL5DYNAMICLINKING="";;
+esac
+fi
+
+AC_SUBST(PERL)
+AC_SUBST(PERL5EXT)
+AC_SUBST(PERL5DYNAMICLINKING)
+AC_SUBST(PERL5LIB)
+AC_SUBST(PERL5CCFLAGS)
+AC_SUBST(PERL5CCDLFLAGS)
+AC_SUBST(PERL5CCCDLFLAGS)
+AC_SUBST(PERL5LDFLAGS)
+
+#-------------------------------------------------------------------------
+# Look for PHP
+#-------------------------------------------------------------------------
+
+PHPBIN=
+
+AC_ARG_WITH(php, AS_HELP_STRING([--without-php], [Disable PHP])
+AS_HELP_STRING([--with-php=path], [Set location of PHP executable]),[ PHPBIN="$withval"], [PHPBIN="$alllang_default"])
+
+# First, check for "--without-php" or "--with-php=no".
+if test x"${PHPBIN}" = xno; then
+    AC_MSG_NOTICE([Disabling PHP])
+    PHP=
+else
+    if test "x$PHPBIN" = xyes; then
+      AC_CHECK_PROGS(PHP, [php8.3 php8.2 php8.1 php8.0 php])
+    else
+      PHP=$PHPBIN
+    fi
+
+    if test -n "$PHP"; then
+      AC_MSG_CHECKING(for PHP header files)
+      dnl /usr/bin/php8.0 -> /usr/bin/php-config8.0
+      case $PHP in
+        *8.*)
+          PHPCONFIG=`echo "$PHP"|sed 's/8\...*$/-config&/'` ;;
+        *)
+          PHPCONFIG=$PHP-config ;;
+      esac
+      php_version=`$PHPCONFIG --version 2>/dev/null`
+      case $php_version in
+      8.*)
+        PHPINC=`$PHPCONFIG --includes 2>/dev/null`
+        if test -n "$PHPINC"; then
+          AC_MSG_RESULT($PHPINC)
+        else
+          AC_MSG_RESULT(not found)
+        fi
+        ;;
+      "")
+        AC_MSG_RESULT([could not find $PHPCONFIG or obtain PHP version from it]) ;;
+      *)
+        AC_MSG_RESULT([found PHP $php_version - not PHP 8]) ;;
+      esac
+    fi
+fi
+AC_SUBST(PHP)
+AC_SUBST(PHPINC)
+
+#----------------------------------------------------------------
+# Look for Python
+#----------------------------------------------------------------
+
+PYINCLUDE=
+PYLIB=
+PYLINK=
+PYPACKAGE=
+
+AC_ARG_WITH(python, AS_HELP_STRING([--without-python], [Don't probe for Python 2.x])
+AS_HELP_STRING([--with-python=path], [Set location of Python 2.x executable]), [PYBIN="$withval"], [PYBIN="$alllang_default"])
+
+# First, check for "--without-python" or "--with-python=no".
+if test x"${PYBIN}" = xno; then
+  AC_MSG_NOTICE([Disabling Python 2.x probe])
+else
+  # First figure out the name of the Python 2.x executable
+  if test "x$PYBIN" = xyes; then
+    AC_CHECK_PROGS(PYTHON, [python python2.7])
+  else
+    PYTHON="$PYBIN"
+  fi
+
+  PYVER=0
+  if test -n "$PYTHON"; then
+    AC_MSG_CHECKING([for $PYTHON major version number])
+    PYVER=`($PYTHON -c "import sys; sys.stdout.write(sys.version[[0]])") 2>/dev/null`
+    AC_MSG_RESULT($PYVER)
+    if test -z "$PYVER"; then
+      PYVER=0
+    else
+      AC_MSG_CHECKING(for Python 2.x os.name)
+      PYOSNAME=`($PYTHON -c "import sys, os; sys.stdout.write(os.name)") 2>/dev/null`
+      AC_MSG_RESULT($PYOSNAME)
+      AC_MSG_CHECKING(for Python 2.x path separator)
+      PYSEPARATOR=`($PYTHON -c "import sys, os; sys.stdout.write(os.sep)") 2>/dev/null`
+      AC_MSG_RESULT($PYSEPARATOR)
+    fi
+  fi
+
+  if test $PYVER -eq 1 -o $PYVER -eq 2; then
+    AC_MSG_CHECKING(for Python 2.x prefix)
+    PYPREFIX=`($PYTHON -c "import sys; sys.stdout.write(sys.prefix)") 2>/dev/null`
+    AC_MSG_RESULT($PYPREFIX)
+    AC_MSG_CHECKING(for Python 2.x exec-prefix)
+    PYEPREFIX=`($PYTHON -c "import sys; sys.stdout.write(sys.exec_prefix)") 2>/dev/null`
+    AC_MSG_RESULT($PYEPREFIX)
+
+    if test x"$PYOSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\"; then
+      # Windows installations are quite different to posix installations (MinGW path separator is a forward slash)
+      PYPREFIX=`echo "$PYPREFIX" | sed -e 's,\\\\,/,g'` # Forward slashes are easier to use and even work on Windows most of the time
+      PYTHON_SO=.pyd
+
+      AC_MSG_CHECKING(for Python 2.x header files)
+      if test -r $PYPREFIX/include/Python.h; then
+        PYINCLUDE="-I$PYPREFIX/include"
+      fi
+      AC_MSG_RESULT($PYINCLUDE)
+
+      AC_MSG_CHECKING(for Python 2.x library directory)
+      if test -d $PYPREFIX/libs; then
+        PYLIB=$PYPREFIX/libs
+        PYLINKFILE=`ls $PYLIB/python*.lib | grep "python[[0-9]][[0-9]]\+\.lib"`
+        if test -r "$PYLINKFILE"; then
+          PYLINK=-l`basename $PYLINKFILE | sed -e 's/\.lib$//'`
+        else
+          PYLIB=
+        fi
+      fi
+    else
+      # Note: I could not think of a standard way to get the version string from different versions.
+      # This trick pulls it out of the file location for a standard library file.
+
+      AC_MSG_CHECKING(for Python 2.x version)
+
+      # Need to do this hack since autoconf replaces __file__ with the name of the configure file
+      filehack="file__"
+      PYVERSION=`($PYTHON -c "import sys,string,operator,os.path; sys.stdout.write(operator.getitem(os.path.split(operator.getitem(os.path.split(string.__$filehack),0)),1))") 2>/dev/null`
+      AC_MSG_RESULT($PYVERSION)
+
+      # Find the directory for libraries this is necessary to deal with
+      # platforms that can have apps built for multiple archs: e.g. x86_64
+      AC_MSG_CHECKING(for Python 2.x lib dir)
+      PYLIBDIR=`($PYTHON -c "import sys; sys.stdout.write(sys.lib)") 2>/dev/null`
+      if test -z "$PYLIBDIR"; then
+        # Fedora patch Python to add sys.lib, for other distros we assume "lib".
+        PYLIBDIR="lib"
+      fi
+      AC_MSG_RESULT($PYLIBDIR)
+
+      # Set the include directory
+
+      AC_MSG_CHECKING(for Python 2.x header files)
+      if test -r $PYPREFIX/include/$PYVERSION/Python.h; then
+        PYINCLUDE="-I$PYPREFIX/include/$PYVERSION -I$PYEPREFIX/$PYLIBDIR/$PYVERSION/config"
+      fi
+      if test -z "$PYINCLUDE"; then
+        if test -r $PYPREFIX/include/Py/Python.h; then
+          PYINCLUDE="-I$PYPREFIX/include/Py -I$PYEPREFIX/$PYLIBDIR/python/lib"
+        fi
+      fi
+      AC_MSG_RESULT($PYINCLUDE)
+
+      # Set the library directory blindly.   This probably won't work with older versions
+      AC_MSG_CHECKING(for Python 2.x library directory)
+      dirs="$PYVERSION/config $PYVERSION/$PYLIBDIR python/$PYLIBDIR"
+      for i in $dirs; do
+        if test -d $PYEPREFIX/$PYLIBDIR/$i; then
+          PYLIB="$PYEPREFIX/$PYLIBDIR/$i"
+          break
+        fi
+      done
+
+      PYLINK="-l$PYVERSION"
+    fi
+
+    if test -z "$PYLIB"; then
+      AC_MSG_RESULT(Not found)
+    else
+      AC_MSG_RESULT($PYLIB)
+    fi
+    AC_MSG_CHECKING(for Python 2.x library)
+    if test -z "$PYLINK"; then
+      AC_MSG_RESULT(Not found)
+    else
+      AC_MSG_RESULT($PYLINK)
+    fi
+  fi
+
+  # Cygwin (Windows) needs the library for dynamic linking
+  case $host in
+  *-*-cygwin* | *-*-mingw*)
+    PYTHONDYNAMICLINKING="-L$PYLIB $PYLINK"
+    DEFS="-DUSE_DL_IMPORT $DEFS"
+    ;;
+  *-*-aix*)
+    PYTHONDYNAMICLINKING="-L$PYLIB $PYLINK"
+    ;;
+  *)PYTHONDYNAMICLINKING="";;
+  esac
+fi
+
+AC_SUBST(PYINCLUDE)
+AC_SUBST(PYLIB)
+AC_SUBST(PYLINK)
+AC_SUBST(PYTHONDYNAMICLINKING)
+
+
+#----------------------------------------------------------------
+# Look for Python 3.x
+#----------------------------------------------------------------
+
+PY3INCLUDE=
+PY3LIB=
+PY3LINK=
+PY3PACKAGE=
+
+AC_ARG_WITH(python3, AS_HELP_STRING([--without-python3], [Don't probe for Python 3.x])
+AS_HELP_STRING([--with-python3=path], [Set location of Python 3.x executable]), [PY3BIN="$withval"], [PY3BIN="$alllang_default"])
+
+# First, check for "--without-python3" or "--with-python3=no".
+if test x"${PY3BIN}" = xno; then
+  AC_MSG_NOTICE([Disabling Python 3.x probe])
+else
+  if test -z "$PYVER"; then
+    PYVER=0
+  fi
+  if test "x$PY3BIN" = xyes; then
+    if test x"$PYOSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\" -a $PYVER -ge 3; then
+      PYTHON3="$PYTHON"
+    else
+      for py_ver in 3 3.10 3.9 3.8 3.7 3.6 3.5 3.4 3.3 3.2 ""; do
+        AC_CHECK_PROGS(PYTHON3, [python$py_ver])
+        if test -n "$PYTHON3"; then
+          AC_CHECK_PROGS(PY3CONFIG, [$PYTHON3-config])
+          if test -n "$PY3CONFIG"; then
+            break
+          fi
+        fi
+      done
+    fi
+  else
+    PYTHON3="$PY3BIN"
+    AC_CHECK_PROGS(PY3CONFIG, [$PYTHON3-config])
+  fi
+
+  if test -n "$PYTHON3"; then
+    AC_MSG_CHECKING([for $PYTHON3 major version number])
+    PYVER=`($PYTHON3 -c "import sys; sys.stdout.write(sys.version[[0]])") 2>/dev/null`
+    AC_MSG_RESULT($PYVER)
+    if test -z "$PYVER"; then
+      PYVER=0
+    fi
+  fi
+
+  if test $PYVER -ge 3; then
+    AC_MSG_CHECKING(for Python 3.x os.name)
+    PY3OSNAME=`($PYTHON3 -c "import sys, os; sys.stdout.write(os.name)") 2>/dev/null`
+    AC_MSG_RESULT($PY3OSNAME)
+    AC_MSG_CHECKING(for Python 3.x path separator)
+    PYSEPARATOR=`($PYTHON3 -c "import sys, os; sys.stdout.write(os.sep)") 2>/dev/null`
+    AC_MSG_RESULT($PYSEPARATOR)
+
+    if test x"$PY3OSNAME" = x"nt" -a x"$PYSEPARATOR" = x"\\"; then
+      # Windows installations are quite different to posix installations
+      # There is no python-config to use
+      AC_MSG_CHECKING(for Python 3.x prefix)
+      PY3PREFIX=`($PYTHON3 -c "import sys; sys.stdout.write(sys.prefix)") 2>/dev/null`
+      AC_MSG_RESULT($PY3PREFIX)
+      PY3PREFIX=`echo "$PY3PREFIX" | sed -e 's,\\\\,/,g'` # Forward slashes are easier to use and even work on Windows most of the time
+      PYTHON_SO=.pyd
+
+      AC_MSG_CHECKING(for Python 3.x header files)
+      if test -r $PY3PREFIX/include/Python.h; then
+        PY3INCLUDE="-I$PY3PREFIX/include"
+      fi
+      AC_MSG_RESULT($PY3INCLUDE)
+
+      AC_MSG_CHECKING(for Python 3.x library directory)
+      if test -d $PY3PREFIX/libs; then
+        PY3LIB=$PY3PREFIX/libs
+        PY3LINKFILE=`ls $PY3LIB/python*.lib | grep "python[[0-9]][[0-9]]\+\.lib"`
+        if test -r "$PY3LINKFILE"; then
+          PY3LINK=-l`basename $PY3LINKFILE | sed -e 's/\.lib$//'`
+        else
+          PY3LIB=
+        fi
+      fi
+      if test -z "$PY3LIB"; then
+        AC_MSG_RESULT([Not found])
+      else
+        AC_MSG_RESULT($PY3LIB)
+      fi
+      AC_MSG_CHECKING([for Python 3.x library])
+      if test -z "$PY3LINK"; then
+        AC_MSG_RESULT(Not found)
+      else
+        AC_MSG_RESULT($PY3LINK)
+      fi
+    elif test -n "$PY3CONFIG"; then
+      AC_MSG_CHECKING([for Python 3.x prefix])
+      PY3PREFIX=`($PY3CONFIG --prefix) 2>/dev/null`
+      AC_MSG_RESULT($PY3PREFIX)
+      AC_MSG_CHECKING(for Python 3.x exec-prefix)
+      # Piped through xargs to strip trailing whitespace (bug in msys2 + mingw Python)
+      PY3EPREFIX=`($PY3CONFIG --exec-prefix | xargs) 2>/dev/null`
+      AC_MSG_RESULT($PY3EPREFIX)
+
+      # Note: I could not think of a standard way to get the version string from different versions.
+      # This trick pulls it out of the file location for a standard library file.
+
+      AC_MSG_CHECKING([for Python 3.x version])
+
+      # Need to do this hack since autoconf replaces __file__ with the name of the configure file
+      filehack="file__"
+      PY3VERSION=`($PYTHON3 -c "import string,operator,os.path; print(operator.getitem(os.path.split(operator.getitem(os.path.split(string.__$filehack),0)),1))") 2>/dev/null`
+      AC_MSG_RESULT($PY3VERSION)
+
+      # Find the directory for libraries this is necessary to deal with
+      # platforms that can have apps built for multiple archs: e.g. x86_64
+      AC_MSG_CHECKING([for Python 3.x lib dir])
+      PY3LIBDIR=`($PYTHON3 -c "import sys; print(sys.lib)") 2>/dev/null`
+      if test -z "$PY3LIBDIR"; then
+        # some dists don't have sys.lib  so the best we can do is assume lib
+        PY3LIBDIR="lib"
+      fi
+      AC_MSG_RESULT($PY3LIBDIR)
+
+      # Set the include directory
+
+      AC_MSG_CHECKING([for Python 3.x header files])
+      PY3INCLUDE=`($PY3CONFIG --includes) 2>/dev/null`
+      AC_MSG_RESULT($PY3INCLUDE)
+
+      # Set the library directory blindly.   This probably won't work with older versions
+      AC_MSG_CHECKING([for Python 3.x library directory])
+      dirs="$PY3VERSION/config $PY3VERSION/$PY3LIBDIR python/$PY3LIBDIR"
+      for i in $dirs; do
+        if test -d $PY3EPREFIX/$PY3LIBDIR/$i; then
+          PY3LIB="$PY3EPREFIX/$PY3LIBDIR/$i"
+          break
+        fi
+      done
+      if test -z "$PY3LIB"; then
+        # Last resort
+        if test -d $PY3EPREFIX/$PY3LIBDIR; then
+          PY3LIB="$PY3EPREFIX/$PY3LIBDIR"
+        fi
+      fi
+      if test -z "$PY3LIB"; then
+        AC_MSG_RESULT([Not found])
+      else
+        AC_MSG_RESULT($PY3LIB)
+      fi
+
+      PY3LINK="-l$PY3VERSION"
+
+      AC_MSG_CHECKING([for Python 3.x library])
+      if test -z "$PY3LINK"; then
+        AC_MSG_RESULT(Not found)
+      else
+        AC_MSG_RESULT($PY3LINK)
+      fi
+    fi
+  fi
+
+  # Cygwin (Windows) needs the library for dynamic linking
+  case $host in
+  *-*-cygwin* | *-*-mingw*)
+    # PYTHON3DYNAMICLINKING ought to be replaced by $PY3CONFIG --ldflags
+    PYTHON3DYNAMICLINKING="-L$PY3LIB $PY3LINK"
+    DEFS="-DUSE_DL_IMPORT $DEFS"
+    ;;
+  *-*-aix*)
+    PYTHON3DYNAMICLINKING="-L$PY3LIB $PY3LINK"
+    ;;
+  *)PYTHON3DYNAMICLINKING="";;
+  esac
+
+  AC_SUBST(PY3INCLUDE)
+  AC_SUBST(PY3LIB)
+  AC_SUBST(PY3LINK)
+  AC_SUBST(PYTHON3DYNAMICLINKING)
+fi
+
+if test -n "$PYINCLUDE" || test -n "$PY3INCLUDE" ; then
+  AC_CHECK_PROGS(PYCODESTYLE, pycodestyle)
+  if test -n "$PYCODESTYLE"; then
+    AC_MSG_CHECKING(pycodestyle version)
+    pycodestyle_version=`$PYCODESTYLE --version 2>/dev/null`
+    AC_MSG_RESULT($pycodestyle_version)
+  fi
+fi
+
+#----------------------------------------------------------------
+# Look for R
+#----------------------------------------------------------------
+
+RBIN=
+
+AC_ARG_WITH(r, AS_HELP_STRING([--without-r], [Disable R])
+AS_HELP_STRING([--with-r=path], [Set location of R executable (r)]),[ RBIN="$withval"], [RBIN="$alllang_default"])
+
+# First, check for "--without-r" or "--with-r=no".
+if test x"${RBIN}" = xno; then
+AC_MSG_NOTICE([Disabling R])
+RBIN=
+else
+
+# can we find R?
+if test "x$RBIN" = xyes; then
+   AC_PATH_PROG(RBIN, R)
+fi
+fi
+
+AC_SUBST(RBIN)
+
+#----------------------------------------------------------------
 # Look for Ruby
 #----------------------------------------------------------------
 
@@ -1992,637 +2362,252 @@
 AC_SUBST(RUBYSO)
 AC_SUBST(RUBYDYNAMICLINKING)
 
-#-------------------------------------------------------------------------
-# Look for PHP7
-#-------------------------------------------------------------------------
+#----------------------------------------------------------------
+# Look for Scilab
+#----------------------------------------------------------------
 
-PHPBIN=
+AC_ARG_WITH(scilab, AS_HELP_STRING([--without-scilab], [Disable Scilab])
+AS_HELP_STRING([--with-scilab=path], [Set location of Scilab executable]),[SCILABBIN="$withval"], [SCILABBIN="$alllang_default"])
+AC_ARG_WITH(scilab-inc, [  --with-scilab-inc=path  Set location of Scilab include directory], [SCILABINCDIR="$withval"], [SCILABINCDIR=""])
 
-AC_ARG_WITH(php, AS_HELP_STRING([--without-php], [Disable PHP])
-AS_HELP_STRING([--with-php=path], [Set location of PHP executable]),[ PHPBIN="$withval"], [PHPBIN="$alllang_default"])
-
-# First, check for "--without-php" or "--with-php=no".
-if test x"${PHPBIN}" = xno; then
-    AC_MSG_NOTICE([Disabling PHP])
-    PHP=
+# First, check for "--without-scilab" or "--with-scilab=no".
+if test x"${SCILABBIN}" = xno; then
+  AC_MSG_NOTICE([Disabling Scilab])
+  SCILAB=
 else
-    if test "x$PHPBIN" = xyes; then
-      AC_CHECK_PROGS(PHP, [php7.3 php7.2 php7.1 php7.0 php])
+  # Check for Scilab executable
+  if test "x$SCILABBIN" = xyes; then
+    AC_PATH_PROG(SCILAB, scilab)
+  else
+    AC_MSG_CHECKING(for scilab)
+    if test -f "$SCILABBIN"; then
+      AC_MSG_RESULT($SCILABBIN)
+      SCILAB="$SCILABBIN"
     else
-      PHP=$PHPBIN
+      AC_MSG_RESULT(not found)
+    fi
+  fi
+
+  if test -n "$SCILAB"; then
+    # Check for Scilab version (needs api_scilab so needs version 5.3.3 or higher)
+    SCILAB_VERSION=`$SCILAB -nwni -version | head -1 | sed -e 's|Scilab version \"\(.*\)\"|\1|g'`
+
+    AC_MSG_CHECKING(Scilab version is higher than 5.3.2)
+    SCILAB_MAJOR_VERSION=`echo $SCILAB_VERSION | cut -d. -f1`
+    SCILAB_MINOR_VERSION=`echo $SCILAB_VERSION | cut -d. -f2`
+    SCILAB_MAINTENANCE_VERSION=`echo $SCILAB_VERSION | cut -d. -f3`
+    SCILAB_VERSION_NO_DOTS=`printf '%04d%02d%02d' "$SCILAB_MAJOR_VERSION" "$SCILAB_MINOR_VERSION" "$SCILAB_MAINTENANCE_VERSION"`
+
+    if test "$SCILAB_VERSION_NO_DOTS" -ge 00050303; then
+      AC_MSG_RESULT(yes - $SCILAB_VERSION)
+    else
+      AC_MSG_RESULT(no - $SCILAB_VERSION)
+      SCILAB=
     fi
 
-    if test -n "$PHP"; then
-      AC_MSG_CHECKING(for PHP header files)
-      dnl /usr/bin/php7.0 -> /usr/bin/php-config7.0
-      case $PHP in
-        *7.*)
-          PHPCONFIG=`echo "$PHP"|sed 's/7\...*$/-config&/'` ;;
-        *)
-          PHPCONFIG=$PHP-config ;;
-      esac
-      php_version=`$PHPCONFIG --version 2>/dev/null`
-      case $php_version in
-      7.*)
-        PHPINC=`$PHPCONFIG --includes 2>/dev/null`
-        if test -n "$PHPINC"; then
-          AC_MSG_RESULT($PHPINC)
-        else
-          AC_MSG_RESULT(not found)
-        fi
-        ;;
-      "")
-        AC_MSG_RESULT([could not find $PHPCONFIG or obtain PHP version from it]) ;;
-      *)
-        AC_MSG_RESULT([found PHP $php_version - not PHP 7]) ;;
-      esac
-    fi
-fi
-AC_SUBST(PHP)
-AC_SUBST(PHPINC)
+    if test -n "$SCILAB"; then
+      # Set Scilab startup options depending on version
+      AC_MSG_CHECKING(for Scilab startup options)
+      SCILABOPT="-nwni -nb"
+      if test "$SCILAB_VERSION_NO_DOTS" -ge 00050400; then
+        SCILABOPT+=" -noatomsautoload"
+      fi
+      if test "$SCILAB_VERSION_NO_DOTS" -ge 00060000; then
+        SCILABOPT+=" -quit"
+      fi
+      AC_MSG_RESULT($SCILABOPT)
 
-#----------------------------------------------------------------
-# Look for OCaml
-#----------------------------------------------------------------
-
-AC_ARG_WITH(ocaml, AS_HELP_STRING([--without-ocaml], [Disable OCaml]), [with_ocaml="$withval"], [with_ocaml="$alllang_default"])
-AC_ARG_WITH(ocamlc,[  --with-ocamlc=path      Set location of ocamlc executable],[ OCAMLC="$withval"], [OCAMLC=])
-AC_ARG_WITH(ocamldlgen,[  --with-ocamldlgen=path  Set location of ocamldlgen],[ OCAMLDLGEN="$withval" ], [OCAMLDLGEN=])
-AC_ARG_WITH(ocamlfind,[  --with-ocamlfind=path   Set location of ocamlfind],[OCAMLFIND="$withval"],[OCAMLFIND=])
-AC_ARG_WITH(ocamlmktop,[  --with-ocamlmktop=path  Set location of ocamlmktop executable],[ OCAMLMKTOP="$withval"], [OCAMLMKTOP=])
-AC_ARG_WITH(camlp4,[  --with-camlp4=path  Set location of camlp4 executable],[ CAMLP4="$withval"], [CAMLP4=])
-
-# First, check for "--without-ocaml" or "--with-ocaml=no".
-if test x"${with_ocaml}" = xno; then
-    AC_MSG_NOTICE([Disabling OCaml])
-    OCAMLC=
-else
-    # OCaml compiler
-    if test -z "$OCAMLC"; then
-	AC_CHECK_PROGS(OCAMLC, ocamlc)
-    fi
-
-    # OCaml Pre-Processor-Pretty-Printer
-    if test -z "$CAMLP4"; then
-	AC_CHECK_PROGS(CAMLP4, camlp4)
-    fi
-
-    # OCaml DL load generator
-    if test -z "$OCAMLDLGEN"; then
-	AC_CHECK_PROGS(OCAMLDLGEN, ocamldlgen)
-    fi
-
-    # OCaml package tool
-    if test -z "$OCAMLFIND"; then
-	AC_CHECK_PROGS(OCAMLFIND, ocamlfind)
-    fi
-
-    # OCaml toplevel creator
-    if test -z "$OCAMLMKTOP"; then
-	AC_CHECK_PROGS(OCAMLMKTOP, ocamlmktop)
-    fi
-fi
-
-AC_SUBST(OCAMLC)
-AC_SUBST(CAMLP4)
-AC_SUBST(OCAMLDLGEN)
-AC_SUBST(OCAMLFIND)
-AC_SUBST(OCAMLMKTOP)
-
-#----------------------------------------------------------------
-# Look for C#
-#----------------------------------------------------------------
-
-AC_ARG_WITH(csharp, AS_HELP_STRING([--without-csharp], [Disable CSharp]), [with_csharp="$withval"], [with_csharp="$alllang_default"])
-AC_ARG_WITH(cil-interpreter, [  --with-cil-interpreter=path     Set location of CIL interpreter for CSharp],[CSHARPBIN="$withval"], [CSHARPBIN=])
-AC_ARG_WITH(csharp-compiler, [  --with-csharp-compiler=path     Set location of CSharp compiler],[CSHARPCOMPILERBIN="$withval"], [CSHARPCOMPILERBIN=])
-
-# First, check for "--without-csharp" or "--with-csharp=no".
-if test x"${with_csharp}" = xno; then
-AC_MSG_NOTICE([Disabling CSharp])
-CSHARPCOMPILER=
-else
-
-if test -z "$CSHARPCOMPILERBIN" ; then
-  case $host in
-  *-*-cygwin* | *-*-mingw*)
-    # prefer unified Mono mcs compiler (not to be confused with the ancient .NET 1 mcs) over older/alternative names.
-    AC_CHECK_PROGS(CSHARPCOMPILER, csc mcs mono-csc gmcs cscc)
-    if test -n "$CSHARPCOMPILER" && test "$CSHARPCOMPILER" = "csc" ; then
-      AC_MSG_CHECKING(whether csc is the Microsoft CSharp compiler)
-      csc 2>/dev/null | grep "C#" > /dev/null || CSHARPCOMPILER=""
-      if test -z "$CSHARPCOMPILER" ; then
-        AC_MSG_RESULT(no)
-        AC_CHECK_PROGS(CSHARPCOMPILER, mcs mono-csc gmcs cscc)
+      # Check for Scilab header files
+      AC_MSG_CHECKING(for Scilab header files)
+      headers="`AS_DIRNAME(["$SCILAB"])`/../include"
+      if test "$SCILABINCDIR" != ""; then
+        dirs="$SCILABINCDIR"
+      elif test -d "$SCI"; then
+        dirs="$SCI/include $SCI/../../include"
+      elif test -d "$headers"; then
+        dirs="$headers"
+      elif test -n "$PKG_CONFIG "; then
+        dirs=`$PKG_CONFIG  scilab --cflags-only-I | sed -e 's/-I//g'`
       else
-        AC_MSG_RESULT(yes)
+        dirs="/usr/include"
       fi
-    fi
-    ;;
-  *)AC_CHECK_PROGS(CSHARPCOMPILER, mono-csc gmcs mcs cscc);;
-  esac
-else
-  CSHARPCOMPILER="$CSHARPCOMPILERBIN"
-fi
-
-CSHARPCONVERTPATH="Tools/convertpath -u"
-if test -z "$CSHARPBIN" ; then
-  CSHARPCILINTERPRETER=""
-  CSHARPCILINTERPRETER_FLAGS=""
-  if test "cscc" = "$CSHARPCOMPILER" ; then
-    AC_CHECK_PROGS(CSHARPCILINTERPRETER, ilrun)
-  else
-    if test "mcs" = "$CSHARPCOMPILER"; then
-      # Check that mcs is the C# compiler and not the Unix mcs utility by examining the output of 'mcs --version'
-      # The Mono compiler should emit: Mono C# compiler version a.b.c.d
-      csharp_version_raw=`(mcs --version) 2>/dev/null`
-      csharp_version_searched=`(mcs --version | sed -e "/C#/b" -e "/Mono/b" -e d) 2>/dev/null` # return string if contains 'Mono' or 'C#'
-      CSHARPCOMPILER=""
-      if test -n "$csharp_version_raw" ; then
-        if test "$csharp_version_raw" = "$csharp_version_searched" ; then
-          CSHARPCOMPILER="mcs"
-        fi
-      fi
-      if test "mcs" != "$CSHARPCOMPILER" ; then
-        echo "mcs is not a working Mono C# compiler"
-      fi
-    fi
-    if test "mcs" = "$CSHARPCOMPILER" || test "gmcs" = "$CSHARPCOMPILER" || test "mono-csc" = "$CSHARPCOMPILER"; then
-        AC_CHECK_PROGS(CSHARPCILINTERPRETER, mono) # Mono JIT
-        CSHARPCILINTERPRETER_FLAGS="--debug"
-    else
-      if test "csc" = "$CSHARPCOMPILER"; then
-          CSHARPCONVERTPATH="Tools/convertpath -w"
-      fi
-    fi
-  fi
-else
-  CSHARPCILINTERPRETER="$CSHARPBIN"
-fi
-
-# Cygwin requires the Windows standard (Pascal) calling convention as it is a Windows executable and not a Cygwin built executable
-case $host in
-*-*-cygwin* | *-*-mingw*)
-    if test "$GCC" = yes; then
-        CSHARPDYNAMICLINKING="$GCC_MNO_CYGWIN -mthreads -Wl,--add-stdcall-alias"
-        CSHARPCFLAGS="$GCC_MNO_CYGWIN -mthreads"
-    else
-        CSHARPDYNAMICLINKING=""
-        CSHARPCFLAGS=""
-    fi ;;
-*)
-        CSHARPDYNAMICLINKING=""
-        CSHARPCFLAGS=""
-        ;;
-esac
-
-# CSharp on Windows platforms including Cygwin doesn't use libname.dll, rather name.dll when loading dlls
-case $host in
-*-*-cygwin* | *-*-mingw*) CSHARPLIBRARYPREFIX="";;
-*)CSHARPLIBRARYPREFIX="lib";;
-esac
-
-# C#/Mono on Mac OS X tweaks
-case $host in
-*-*-darwin*)
-    CSHARPSO=".so"
-    ;;
-*)
-    CSHARPSO=$SO
-    ;;
-esac
-fi
-
-AC_SUBST(CSHARPCILINTERPRETER_FLAGS)
-AC_SUBST(CSHARPCILINTERPRETER)
-AC_SUBST(CSHARPCONVERTPATH)
-AC_SUBST(CSHARPCOMPILER)
-AC_SUBST(CSHARPDYNAMICLINKING)
-AC_SUBST(CSHARPLIBRARYPREFIX)
-AC_SUBST(CSHARPCFLAGS)
-AC_SUBST(CSHARPSO)
-
-#----------------------------------------------------------------
-# Look for Lua
-#----------------------------------------------------------------
-
-LUABIN=
-LUAINCLUDE=
-LUALIB=
-LUADYNAMICLOADLIB=
-LUAFLAGS=
-LUALINK=
-# note: if LUABIN is empty then lua tests will not be done
-# LUABIN will be cleared if certain dependencies cannot be found
-
-AC_ARG_WITH(lua, AS_HELP_STRING([--without-lua], [Disable Lua])
-AS_HELP_STRING([--with-lua=path], [Set location of Lua executable]),[ LUABIN="$withval"], [LUABIN="$alllang_default"])
-AC_ARG_WITH(luaincl,[  --with-luaincl=path     Set location of Lua include directory],[
-	LUAINCLUDE="$withval"], [LUAINCLUDE=])
-AC_ARG_WITH(lualib,[  --with-lualib=path      Set location of Lua library directory],[
-	LUALIB="$withval"], [LUALIB=])
-
-# First, check for "--without-lua" or "--with-lua=no".
-if test x"${LUABIN}" = xno; then
-AC_MSG_NOTICE([Disabling Lua])
-else
-
-# can we find lua?
-if test "x$LUABIN" = xyes; then
-   # We look for a versioned Lua binary first, as there can be
-   # multiple versions of Lua installed on some systems (like Debian).
-   AC_PATH_PROGS(LUABIN, [lua5.4 lua5.3 lua5.2 lua5.1 lua])
-fi
-
-# check version: we need Lua 5.x
-if test "$LUABIN"; then
-  AC_MSG_CHECKING(Lua version)
-  [LUA_VERSION=`$LUABIN -e 'print(string.match(_VERSION, "%d+[.]%d+"))'`]
-  # For 5.0 and 5.1 header and libraries may be named using 50 or 51.
-  LUA_VERSION_NO_DOTS=
-  if test -n "$LUA_VERSION" ; then
-    AC_MSG_RESULT([Lua $LUA_VERSION.x])
-  else
-    AC_MSG_RESULT([failed])
-  fi
-  case $LUA_VERSION in
-    5.0) LUA_VERSION_NO_DOTS=50 ;;
-    5.1) LUA_VERSION_NO_DOTS=51 ;;
-    5.*) ;;
-    *)
-      AC_MSG_WARN([Not Lua 5.x, SWIG does not support this version of Lua])
-      LUABIN=""
-      ;;
-  esac
-fi
-
-if test "$LUABIN"; then
-  AC_MSG_CHECKING(whether Lua dynamic loading is enabled)
-  # using Lua to check Lua
-  # lua 5.0 & 5.1 have different fn names
-  if test "$LUA_VERSION" = "5.0"; then
-    LUADYNAMICLOADLIB=`$LUABIN -e '_,_,c=loadlib("no_such_lib","") if c~="absent" then print "1" end'`
-  else
-    LUADYNAMICLOADLIB=`$LUABIN -e '_,_,c=package.loadlib("no_such_lib","") if c~="absent" then print "1" end'`
-  fi
-
-  if test -z "$LUADYNAMICLOADLIB"; then
-    AC_MSG_RESULT(no)
-  else
-    AC_MSG_RESULT(yes)
-  fi
-
-  # look for the header files & set LUAFLAGS accordingly
-  # will clear LUABIN if not present
-  if test -n "$LUAINCLUDE"; then
-    AC_CHECK_FILE($LUAINCLUDE/lua.h,[LUAFLAGS="$ISYSTEM$LUAINCLUDE"],[LUABIN=])
-  else
-    LUA_OK="1"
-    CFLAGS_SAVED=$CFLAGS
-    CFLAGS= # Use empty CFLAGS to avoid failure: "present but cannot be compiled"
-    AC_CHECK_HEADER([lua.h],[LUAFLAGS=""],[LUA_OK=""])
-    CFLAGS=$CFLAGS_SAVED
-    # if we didn't get it, going to have to look elsewhere (the hard way)
-    if test -z "$LUA_OK"; then
-      AC_MSG_CHECKING(for lua.h in other locations)
-      # note: Debian/Ubuntu seem to like /usr/include/lua5.1/lua.h
-      # The ordering of the include directories to search should match
-      # the ordering of libraries to search in the library test below.
-      inc=/usr/include
-      incloc=/usr/local/include
-      dirs="$inc/lua$LUA_VERSION"
-      test -z "$LUA_VERSION_NO_DOTS" || dirs="$dirs $inc/lua$LUA_VERSION_NO_DOTS"
-      dirs="$dirs $incloc/lua$LUA_VERSION"
-      test -z "$LUA_VERSION_NO_DOTS" || dirs="$dirs $incloc/lua$LUA_VERSION_NO_DOTS"
-      dirs="$dirs $incloc"
       for i in $dirs; do
-        #echo "$i"
-        if test -r $i/lua.h; then
-          AC_MSG_RESULT($i/lua.h)
-          LUAFLAGS="$ISYSTEM$i"
+        if test -r $i/api_scilab.h; then
+          AC_MSG_RESULT($i)
+          SCILABINCLUDE="-I$i"
+          break
+        fi
+        if test -r $i/scilab/api_scilab.h; then
+          AC_MSG_RESULT($i/scilab)
+          SCILABINCLUDE="-I$i/scilab"
           break
         fi
       done
-      if test -z "$LUAFLAGS"; then
+      if test "$SCILABINCLUDE" = "" ; then
         AC_MSG_RESULT(not found)
-        LUABIN="" # clear the bin
-      fi
-    fi
-  fi
-
-  # look for the library files & set LUALINK accordingly
-  # will clear LUABIN if not present
-  lua_save_LIBS=$LIBS # the code seems to disrupt LIBS, so saving
-
-  if test -n "$LUALIB"; then
-    AC_CHECK_FILE($LUALIB/liblua.a,[LUALINK="-L$LUALIB -llua"],[LUABIN=])
-  else
-    libs="lua lua$LUA_VERSION"
-    test -z "$LUA_VERSION_NO_DOTS" || libs="$libs lua$LUA_VERSION_NO_DOTS"
-    AC_SEARCH_LIBS(lua_close, [$libs], [LUALINK="-l$ac_lib"],[LUABIN=])
-  fi
-
-  # adding lualib for lua 5.0
-  if test "$LUA_VERSION" = "5.0"; then
-    LUALINK="$LUALINK -llualib"
-  fi
-
-  LIBS=$lua_save_LIBS	# restore LIBS
-fi
-
-fi # if not disabled
-
-AC_SUBST(LUADYNAMICLINKING)
-AC_SUBST(LUAFLAGS)
-AC_SUBST(LUALINK)
-AC_SUBST(LUABIN)
-
-#----------------------------------------------------------------
-# Look for GNU R
-#----------------------------------------------------------------
-
-RBIN=
-
-AC_ARG_WITH(r, AS_HELP_STRING([--without-r], [Disable R])
-AS_HELP_STRING([--with-r=path], [Set location of R executable (r)]),[ RBIN="$withval"], [RBIN="$alllang_default"])
-
-# First, check for "--without-r" or "--with-r=no".
-if test x"${RBIN}" = xno; then
-AC_MSG_NOTICE([Disabling R])
-RBIN=
-else
-
-# can we find R?
-if test "x$RBIN" = xyes; then
-   AC_PATH_PROG(RBIN, R)
-fi
-fi
-
-AC_SUBST(RBIN)
-
-#----------------------------------------------------------------
-# Look for Go compilers
-#----------------------------------------------------------------
-
-AC_ARG_WITH(go, AS_HELP_STRING([--without-go], [Disable Go])
-AS_HELP_STRING([--with-go=path], [Set location of Go compiler]),[GOBIN="$withval"], [GOBIN="$alllang_default"])
-
-if test x"${GOBIN}" = xno; then
-  AC_MSG_NOTICE([Disabling Go])
-  GO=
-  GOGCC=false
-  GCCGO=
-  GOOPT=
-  GCCGOOPT=
-  GOVERSIONOPTION=
-else
-
-  if test "x$GOBIN" = xyes; then
-    AC_CHECK_PROGS(GO, go)
-  else
-    GO="$GOBIN"
-  fi
-
-  GOGCC=false
-  GCCGO=
-  GOOPT=
-  GCCGOOPT=
-  GOVERSIONOPTION=
-
-  if test -n "$GO" ; then
-    GOVERSIONOPTION=version
-    go_version=$($GO $GOVERSIONOPTION | sed -e 's/go version //')
-    AC_MSG_CHECKING([whether go version is too old])
-    case $go_version in
-    go1.[012]*)
-      AC_MSG_RESULT([yes - minimum version is 1.3])
-      GO=
-      GOOPT="-intgosize 32"
-      ;;
-    *)
-      AC_MSG_RESULT([no])
-      case "$(go env GOARCH)" in
-      amd64 | arm64 | ppc64*)
-        GOOPT="-intgosize 64"
-	;;
-      *)
-        GOOPT="-intgosize 32"
-	;;
-      esac
-      ;;
-    esac
-  fi
-
-  AC_CHECK_PROGS(GCCGO, gccgo)
-
-  if test -n "$GCCGO" ; then
-    if $GCCGO --help 2>/dev/null | grep gccgo >/dev/null 2>&1 ; then
-      AC_MSG_CHECKING([whether gccgo version is too old])
-      go_version=[`$GO $GOVERSIONOPTION | sed -n '1p' | sed -e 's/^.* \([0-9.]*\) *$/\1/' -e 's/[.]//g'`]
-      if test "x$go_version" = x; then
-        AC_MSG_RESULT([could not determine gccgo version])
-        GCCGO=
-      elif test "$go_version" -lt 470; then
-        AC_MSG_RESULT([yes - minimum version is 4.7.0])
-        GCCGO=
-      else
-        AC_MSG_RESULT([no])
-        if test "$go_version" -lt 480; then
-          GCCGOOPT="-intgosize 32"
-        else
-          AC_CHECK_SIZEOF([void *], [4])
-          if test "$ac_cv_sizeof_void_p" = "8"; then
-            GCCGOOPT="-intgosize 64"
-          else
-            GCCGOOPT="-intgosize 32"
-          fi
-        fi
+        SCILAB=
       fi
     fi
   fi
 fi
 
-AC_SUBST(GOGCC)
-AC_SUBST(GCCGO)
-AC_SUBST(GO)
-AC_SUBST(GOC)
-AC_SUBST(GO1)
-AC_SUBST(GO12)
-AC_SUBST(GO13)
-AC_SUBST(GO15)
-AC_SUBST(GOOPT)
-AC_SUBST(GCCGOOPT)
-AC_SUBST(GOVERSIONOPTION)
+AC_SUBST(SCILAB)
+AC_SUBST(SCILABINCLUDE)
+AC_SUBST(SCILABOPT)
+AC_SUBST(SCILAB_VERSION)
 
-#----------------------------------------------------------------
-# Look for D
-#----------------------------------------------------------------
+#--------------------------------------------------------------------
+# Look for Tcl
+#--------------------------------------------------------------------
 
-AC_ARG_WITH(d, AS_HELP_STRING([--without-d], [Disable D]), [with_d="$withval"], [with_d="$alllang_default"])
-AC_ARG_WITH(d1-compiler, [  --with-d1-compiler=path  Set location of D1/Tango compiler (DMD compatible)],[D1COMPILERBIN="$withval"], [D1COMPILERBIN=])
-AC_ARG_WITH(d2-compiler, [  --with-d2-compiler=path  Set location of D2 compiler (DMD compatible)],[D2COMPILERBIN="$withval"], [D2COMPILERBIN=])
+TCLINCLUDE=
+TCLLIB=
+TCLPACKAGE=
+TCLLINK=
 
+AC_ARG_WITH(tclconfig, AS_HELP_STRING([--without-tcl], [Disable Tcl])
+AS_HELP_STRING([--with-tclconfig=path], [Set location of tclConfig.sh]), [with_tclconfig="$withval"], [with_tclconfig=])
+AC_ARG_WITH(tcl,
+ [  --with-tcl=path         Set location of Tcl package],[
+	TCLPACKAGE="$withval"], [TCLPACKAGE="$alllang_default"])
+AC_ARG_WITH(tclincl,[  --with-tclincl=path     Set location of Tcl include directory],[
+	TCLINCLUDE="-I$withval"], [TCLINCLUDE=])
+AC_ARG_WITH(tcllib,[  --with-tcllib=path      Set location of Tcl library directory],[
+	TCLLIB="-L$withval"], [TCLLIB=])
 
-# First, check for "--without-d" or "--with-d=no".
-if test x"${with_d}" = xno; then
-  AC_MSG_NOTICE([Disabling D])
-  D1COMPILER=
-  D2COMPILER=
+# First, check for "--without-tcl" or "--with-tcl=no".
+if test x"${TCLPACKAGE}" = xno; then
+AC_MSG_NOTICE([Disabling Tcl])
 else
-  old_ac_ext=$ac_ext
-  ac_ext=d
-
-  if test -z "$D1COMPILERBIN" ; then
-    AC_CHECK_PROGS(D1COMPILER, dmd ldmd gdmd)
-
-    if test -n "$D1COMPILER" ; then
-      AC_MSG_CHECKING(whether the D1/Tango compiler works)
-      cat > conftest.$ac_ext <<_ACEOF
-import tango.io.Stdout;
-void main() {
-}
-_ACEOF
-      rm -f conftest.$ac_objext
-      AS_IF(
-        [$D1COMPILER conftest.$ac_ext 2>&AS_MESSAGE_LOG_FD && test ! -s conftest.err && test -s conftest.$ac_objext],
-        [AC_MSG_RESULT([yes])],
-        [_AC_MSG_LOG_CONFTEST AC_MSG_RESULT([no])
-        D1COMPILER=]
-      )
-      rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-    fi
-  else
-    D1COMPILER="$D1COMPILERBIN"
-  fi
-
-  if test -z "$D2COMPILERBIN" ; then
-    AC_CHECK_PROGS(D2COMPILER, dmd gdmd)
-
-    if test -n "$D2COMPILER" ; then
-      AC_MSG_CHECKING(whether the D2 compiler works)
-      cat > conftest.$ac_ext <<_ACEOF
-import std.algorithm;
-void main() {
-}
-_ACEOF
-      rm -f conftest.$ac_objext
-      AS_IF(
-        [$D2COMPILER conftest.$ac_ext 2>&AS_MESSAGE_LOG_FD && test ! -s conftest.err && test -s conftest.$ac_objext],
-        [AC_MSG_RESULT([yes])],
-        [_AC_MSG_LOG_CONFTEST AC_MSG_RESULT([no])
-        D2COMPILER=]
-      )
-      rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-    fi
-  else
-    D2COMPILER="$D2COMPILERBIN"
-  fi
-
-  ac_ext=$old_ac_ext
+AC_MSG_CHECKING([for Tcl configuration])
+# First check to see if --with-tclconfig was specified.
+if test x"${with_tclconfig}" != x ; then
+   if test -f "${with_tclconfig}/tclConfig.sh" ; then
+      TCLCONFIG=`(cd ${with_tclconfig}; pwd)`
+   else
+      AC_MSG_ERROR([${with_tcl} directory does not contain tclConfig.sh])
+   fi
 fi
-
-if test -n "$D1COMPILER"; then
-  DDEFAULTVERSION=1
-elif test -n "$D2COMPILER"; then
-  DDEFAULTVERSION=2
-fi
-
-# Do not prefix library file names with "lib" on Windows.
+# check in a few common install locations
+dirs="/usr/lib*/ /usr/lib*/tcl*/ /usr/local/lib*/ /usr/local/lib*/tcl*/"
 case $host in
-*-*-cygwin* | *-*-mingw*) DLIBPREFIX="";;
-*)DLIBPREFIX="lib";;
+*-*-darwin*)
+  tcl_framework="/System/Library/Frameworks/Tcl.framework/"
+  macos_sysroot="$(xcodebuild -version -sdk macosx Path 2>/dev/null)" # For MacOSX10.14 and later
+  dirs="$macos_sysroot$tcl_framework $tcl_framework $dirs"
+  ;;
+*)
+  ;;
+esac
+if test x"${TCLCONFIG}" = x ; then
+  for d in $dirs ; do
+    for i in `ls -d -r $d 2>/dev/null` ; do
+      if test -f $i"tclConfig.sh" ; then
+        TCLCONFIG=`(cd $i; pwd)`
+        break
+      fi
+    done
+  done
+fi
+if test x"${TCLCONFIG}" = x ; then
+    AC_MSG_RESULT(no)
+else
+    AC_MSG_RESULT(found $TCLCONFIG/tclConfig.sh)
+    . $TCLCONFIG/tclConfig.sh
+    if test -z "$TCLINCLUDE"; then
+        TCLINCLUDE=`echo $TCL_INCLUDE_SPEC`
+    fi
+    if test -z "$TCLLIB"; then
+        TCLLIB=$TCL_LIB_SPEC
+    fi
+fi
+
+if test -z "$TCLINCLUDE"; then
+   if test "x$TCLPACKAGE" != xyes; then
+	TCLINCLUDE="-I$TCLPACKAGE/include"
+   fi
+fi
+
+if test -z "$TCLLIB"; then
+   if test "x$TCLPACKAGE" != xyes; then
+	TCLLIB="-L$TCLPACKAGE/lib -ltcl"
+   fi
+fi
+
+AC_MSG_CHECKING(for Tcl header files)
+if test -z "$TCLINCLUDE"; then
+AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include <tcl.h>]])],[],[TCLINCLUDE=""])
+if test -z "$TCLINCLUDE"; then
+	dirs="/usr/local/include /usr/include /opt/local/include"
+	for i in $dirs ; do
+		if test -r $i/tcl.h; then
+			AC_MSG_RESULT($i)
+			TCLINCLUDE="-I$i"
+			break
+		fi
+	done
+fi
+if test -z "$TCLINCLUDE"; then
+	AC_MSG_RESULT(not found)
+fi
+else
+        AC_MSG_RESULT($TCLINCLUDE)
+fi
+
+AC_MSG_CHECKING(for Tcl library)
+if test -z "$TCLLIB"; then
+dirs="/usr/local/lib /usr/lib /opt/local/lib /opt/freeware/lib"
+for i in $dirs ; do
+	if test -r $i/libtcl.a; then
+	    AC_MSG_RESULT($i)
+	    TCLLIB="-L$i -ltcl"
+	    break
+	fi
+done
+if test -z "$TCLLIB"; then
+	AC_MSG_RESULT(not found)
+fi
+else
+AC_MSG_RESULT($TCLLIB)
+fi
+
+# Cygwin (Windows) needs the library for dynamic linking
+case $host in
+*-*-cygwin* | *-*-mingw*) TCLDYNAMICLINKING="$TCLLIB";;
+*-*-aix*) TCLDYNAMICLINKING="$TCLLIB";;
+*)TCLDYNAMICLINKING="";;
 esac
 
-AC_SUBST(D1COMPILER)
-AC_SUBST(D2COMPILER)
-AC_SUBST(DDEFAULTVERSION)
-AC_SUBST(DLIBPREFIX)
+# AIX needs -ltcl for linking at test time
+case $host in
+*-*-aix*) TCLLINK="-ltcl";;
+*)TCLLINK="";;
+esac
+
+case $host in
+*-*-darwin*)
+    TCLLDSHARED='$(CC) -dynamiclib -undefined suppress -flat_namespace'
+    TCLCXXSHARED='$(CXX) -dynamiclib -undefined suppress -flat_namespace'
+    ;;
+*)
+    TCLLDSHARED='$(LDSHARED)'
+    TCLCXXSHARED='$(CXXSHARED)'
+    ;;
+esac
+
+fi
+
+AC_SUBST(TCLINCLUDE)
+AC_SUBST(TCLLIB)
+AC_SUBST(TCLDYNAMICLINKING)
+AC_SUBST(TCLLDSHARED)
+AC_SUBST(TCLCXXSHARED)
+AC_SUBST(TCLLINK)
 
 #----------------------------------------------------------------
 # Determine which languages to use for examples/test-suite
 #----------------------------------------------------------------
 
-SKIP_TCL=
-if test -z "$TCLINCLUDE" || test -z "$TCLLIB" ; then
-    SKIP_TCL="1"
-fi
-AC_SUBST(SKIP_TCL)
-
-
-SKIP_PERL5=
-if test -z "$PERL" || test -z "$PERL5EXT" || test -z "$PERL5TESTMORE"; then
-    SKIP_PERL5="1"
-fi
-AC_SUBST(SKIP_PERL5)
-
-
-SKIP_OCTAVE=
-if test -z "$OCTAVE" ; then
-    SKIP_OCTAVE="1"
-fi
-AC_SUBST(SKIP_OCTAVE)
-
-
-SKIP_PYTHON=
-if (test -z "$PYINCLUDE" || test -z "$PYLINK") &&
-   (test -z "$PY3INCLUDE" || test -z "$PY3LINK") ; then
-    SKIP_PYTHON="1"
-fi
-AC_SUBST(SKIP_PYTHON)
-
-SKIP_PYTHON3=
-if test -z "$PY3INCLUDE" || test -z "$PY3LINK" ; then
-    SKIP_PYTHON3="1"
-fi
-AC_SUBST(SKIP_PYTHON3)
-
-SKIP_JAVA=
-if test -z "$JAVA" || test -z "$JAVAC" || test -z "$JAVAINC" ; then
-    SKIP_JAVA="1"
-fi
-AC_SUBST(SKIP_JAVA)
-
-SKIP_JAVASCRIPT=
-if test -z "$JAVASCRIPT" || ( test -z "$NODEJS" && test -z "$JSCENABLED" && test -z "$JSV8ENABLED" ) ; then
-    SKIP_JAVASCRIPT="1"
-fi
-AC_SUBST(SKIP_JAVASCRIPT)
-
-SKIP_GUILE=
-if test -z "$GUILE" || test -z "$GUILE_LIBS" ; then
-    SKIP_GUILE="1"
-fi
-AC_SUBST(SKIP_GUILE)
-
-
-SKIP_MZSCHEME=
-if test -z "$MZC" || test -z "$MZDYNOBJ" ; then
-    SKIP_MZSCHEME="1"
-fi
-AC_SUBST(SKIP_MZSCHEME)
-
-
-SKIP_RUBY=
-if test -z "$RUBY" || test -z "$RUBYINCLUDE" || test -z "$RUBYLIB" ; then
-    SKIP_RUBY="1"
-fi
-AC_SUBST(SKIP_RUBY)
-
-
-SKIP_PHP=
-if test -z "$PHP" || test -z "$PHPINC" ; then
-    SKIP_PHP="1"
-fi
-AC_SUBST(SKIP_PHP)
-
-
-SKIP_OCAML=
-if test -z "$OCAMLC" || test -z "$CAMLP4" ; then
-    SKIP_OCAML="1"
-fi
-AC_SUBST(SKIP_OCAML)
-
-
 SKIP_CSHARP=
 if test -z "$CSHARPCOMPILER" ; then
     SKIP_CSHARP="1"
@@ -2633,24 +2618,13 @@
 fi
 AC_SUBST(SKIP_CSHARP)
 
-SKIP_LUA=
-# we need LUABIN & dynamic loading
-if test -z "$LUABIN" || test -z "$LUADYNAMICLOADLIB"; then
-    SKIP_LUA="1"
-fi
-AC_SUBST(SKIP_LUA)
 
-SKIP_R=
-if test -z "$RBIN" ; then
-    SKIP_R="1"
+SKIP_D=
+if test -z "$D2COMPILER" ; then
+    SKIP_D="1"
 fi
-AC_SUBST(SKIP_R)
+AC_SUBST(SKIP_D)
 
-SKIP_SCILAB=
-if test -z "$SCILAB"; then
-    SKIP_SCILAB="1"
-fi
-AC_SUBST(SKIP_SCILAB)
 
 SKIP_GO=
 if test -z "$GO" ; then
@@ -2658,11 +2632,112 @@
 fi
 AC_SUBST(SKIP_GO)
 
-SKIP_D=
-if test -z "$DDEFAULTVERSION" ; then
-    SKIP_D="1"
+
+SKIP_GUILE=
+if test -z "$GUILE" || test -z "$GUILE_LIBS" ; then
+    SKIP_GUILE="1"
 fi
-AC_SUBST(SKIP_D)
+AC_SUBST(SKIP_GUILE)
+
+SKIP_JAVA=
+if test -z "$JAVA" || test -z "$JAVAC" || test -z "$JAVAINC" ; then
+    SKIP_JAVA="1"
+fi
+AC_SUBST(SKIP_JAVA)
+
+
+SKIP_JAVASCRIPT=
+if test -z "$JAVASCRIPT" || ( test -z "$NODEJS" && test -z "$JSCENABLED" && test -z "$JSV8ENABLED" && test -z "$JSNAPIENABLED" ) ; then
+    SKIP_JAVASCRIPT="1"
+fi
+AC_SUBST(SKIP_JAVASCRIPT)
+
+
+SKIP_LUA=
+# we need LUABIN & dynamic loading
+if test -z "$LUABIN" || test -z "$LUADYNAMICLOADLIB"; then
+    SKIP_LUA="1"
+fi
+AC_SUBST(SKIP_LUA)
+
+
+SKIP_MZSCHEME=
+if test -z "$MZC" || test -z "$MZDYNOBJ" ; then
+    SKIP_MZSCHEME="1"
+fi
+AC_SUBST(SKIP_MZSCHEME)
+
+
+SKIP_OCAML=
+if test -z "$OCAMLC" || test -z "$CAMLP4" ; then
+    SKIP_OCAML="1"
+fi
+AC_SUBST(SKIP_OCAML)
+
+
+SKIP_OCTAVE=
+if test -z "$OCTAVE" ; then
+    SKIP_OCTAVE="1"
+fi
+AC_SUBST(SKIP_OCTAVE)
+
+
+SKIP_PHP=
+if test -z "$PHP" || test -z "$PHPINC" ; then
+    SKIP_PHP="1"
+fi
+AC_SUBST(SKIP_PHP)
+
+
+SKIP_PERL5=
+if test -z "$PERL" || test -z "$PERL5EXT" || test -z "$PERL5TESTMORE"; then
+    SKIP_PERL5="1"
+fi
+AC_SUBST(SKIP_PERL5)
+
+
+SKIP_PYTHON=
+if (test -z "$PYINCLUDE" || test -z "$PYLINK") &&
+   (test -z "$PY3INCLUDE" || test -z "$PY3LINK") ; then
+    SKIP_PYTHON="1"
+fi
+AC_SUBST(SKIP_PYTHON)
+
+
+SKIP_PYTHON3=
+if test -z "$PY3INCLUDE" || test -z "$PY3LINK" ; then
+    SKIP_PYTHON3="1"
+fi
+AC_SUBST(SKIP_PYTHON3)
+
+
+SKIP_R=
+if test -z "$RBIN" ; then
+    SKIP_R="1"
+fi
+AC_SUBST(SKIP_R)
+
+
+SKIP_RUBY=
+if test -z "$RUBY" || test -z "$RUBYINCLUDE" || test -z "$RUBYLIB" ; then
+    SKIP_RUBY="1"
+fi
+AC_SUBST(SKIP_RUBY)
+
+
+SKIP_SCILAB=
+if test -z "$SCILAB"; then
+    SKIP_SCILAB="1"
+fi
+AC_SUBST(SKIP_SCILAB)
+
+
+SKIP_TCL=
+if test -z "$TCLINCLUDE" || test -z "$TCLLIB" ; then
+    SKIP_TCL="1"
+fi
+AC_SUBST(SKIP_TCL)
+
 
 #----------------------------------------------------------------
 # Additional language dependencies
@@ -2748,28 +2823,26 @@
 
 AC_CONFIG_FILES([
     Makefile
-    swig.spec
     Examples/Makefile
-    Examples/d/example.mk
     Examples/xml/Makefile
     Examples/test-suite/errors/Makefile
     Examples/test-suite/csharp/Makefile
     Examples/test-suite/d/Makefile
+    Examples/test-suite/go/Makefile
     Examples/test-suite/guile/Makefile
     Examples/test-suite/java/Makefile
     Examples/test-suite/javascript/Makefile
+    Examples/test-suite/lua/Makefile
     Examples/test-suite/mzscheme/Makefile
     Examples/test-suite/ocaml/Makefile
     Examples/test-suite/octave/Makefile
     Examples/test-suite/perl5/Makefile
     Examples/test-suite/php/Makefile
     Examples/test-suite/python/Makefile
+    Examples/test-suite/r/Makefile
     Examples/test-suite/ruby/Makefile
     Examples/test-suite/scilab/Makefile
     Examples/test-suite/tcl/Makefile
-    Examples/test-suite/lua/Makefile
-    Examples/test-suite/r/Makefile
-    Examples/test-suite/go/Makefile
     Source/Makefile
     Tools/javascript/Makefile
 ])
diff --git a/prebuilt-intermediates/swigconfig.h b/prebuilt-intermediates/swigconfig.h
index 38b5018..48f3a8b 100644
--- a/prebuilt-intermediates/swigconfig.h
+++ b/prebuilt-intermediates/swigconfig.h
@@ -13,7 +13,7 @@
 #define HAVE_POPEN 1
 
 #define PACKAGE_BUGREPORT "http://www.swig.org"
-#define PACKAGE_VERSION "4.0.1"
+#define PACKAGE_VERSION "4.2.1"
 
 #define SWIG_CXX "clang"
 
diff --git a/swig.spec.in b/swig.spec.in
deleted file mode 100644
index 140b962..0000000
--- a/swig.spec.in
+++ /dev/null
@@ -1,70 +0,0 @@
-# You can build the package from Git using something like:
-# tar -czf swig-@PACKAGE_VERSION@.tar.gz swig-@PACKAGE_VERSION@ && rpmbuild -tb swig-@PACKAGE_VERSION@.tar.gz
-# @configure_input@
-
-%define ver          @PACKAGE_VERSION@
-%define rel          1
-%define prefix       /usr
-%define home_page    http://www.swig.org
-%define docprefix    %{prefix}/share
-
-######################################################################
-# Usually, nothing needs to be changed below here between releases
-######################################################################
-Summary: Simplified Wrapper and Interface Generator
-Name: swig
-Version: %{ver}
-Release: %{rel}
-URL: %{home_page}
-Source0: %{name}-%{version}.tar.gz
-License: BSD
-Group: Development/Tools
-BuildRoot: %{_tmppath}/%{name}-root
-
-%description
-SWIG is a software development tool that connects programs written in C and C++
-with a variety of high-level programming languages. SWIG is primarily used with
-common scripting languages such as Perl, Python, Tcl/Tk, and Ruby, however the
-list of supported languages also includes non-scripting languages such as Java,
-OCAML and C#. Also several interpreted and compiled Scheme implementations
-(Guile, MzScheme) are supported. SWIG is most commonly used to create
-high-level interpreted or compiled programming environments, user interfaces,
-and as a tool for testing and prototyping C/C++ software. SWIG can also export
-its parse tree in the form of XML. 
-
-%prep
-%setup -q -n %{name}-%{version}
-
-%build
-# so we can build package from Git source too
-[ ! -r configure ] && ./autogen.sh
-%configure
-make
-
-%install
-rm -rf ${RPM_BUILD_ROOT}
-make DESTDIR=$RPM_BUILD_ROOT install
-
-%clean
-rm -rf ${RPM_BUILD_ROOT}
-
-%files
-%defattr(-,root,root)
-%doc ANNOUNCE CHANGES INSTALL LICENSE LICENSE-GPL LICENSE-UNIVERSITIES README RELEASENOTES
-%doc Doc/*
-%{_bindir}/*
-%{prefix}/share/*
-
-%changelog
-* Thu Sep 16 2004 Marcelo Matus <mmatus@acms.arizona.edu>
-- Small fixes needed after removing the runtime package
-* Tue Jul 20 2004 William Fulton <wsf@fultondesigns.co.uk>
-- Update for SWIG-1.3.22 - Removed runtime package
-* Wed Mar 03 2004 Robert H De Vries
-- Update to work with Fedora Core 1 rpm 4.2.1
-* Wed Jul 24 2002 Sam Liddicott <sam@liddicott.com>
-- Added runtime package of runtime libs
-* Mon Sep 10 2001 Tony Seward <anthony.seward@ieee.org>
-- Merge Red Hat's and Dustin Mitchell's .spec files.
-- Install all of the examples in the documentation directory.
-- Auto create the list of installed files.